Add timing to lens rewriting of AppView

Change-Id: I1c23c2955d92e5a0597c702ac25a15301bb15554
diff --git a/src/main/java/com/android/tools/r8/graph/AppServices.java b/src/main/java/com/android/tools/r8/graph/AppServices.java
index dc557e9..3ef7937 100644
--- a/src/main/java/com/android/tools/r8/graph/AppServices.java
+++ b/src/main/java/com/android/tools/r8/graph/AppServices.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
@@ -129,7 +130,11 @@
     return false;
   }
 
-  public AppServices rewrittenWithLens(GraphLens graphLens) {
+  public AppServices rewrittenWithLens(GraphLens graphLens, Timing timing) {
+    return timing.time("Rewrite AppServices", () -> rewrittenWithLens(graphLens));
+  }
+
+  private AppServices rewrittenWithLens(GraphLens graphLens) {
     ImmutableMap.Builder<DexType, Map<FeatureSplit, List<DexType>>> rewrittenFeatureMappings =
         ImmutableMap.builder();
     for (Entry<DexType, Map<FeatureSplit, List<DexType>>> entry : services.entrySet()) {
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index cda6d1f..cc0041b 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -933,6 +933,8 @@
     assert lens != null;
     assert application != null;
 
+    timing.begin("Rewrite AppView");
+
     boolean changed = appView.setGraphLens(lens);
     assert changed;
     assert application.verifyWithLens(appView.appInfo().app().asDirect(), lens);
@@ -940,6 +942,68 @@
     // The application has already been rewritten with the given applied lens. Therefore, we
     // temporarily replace that lens with a lens that does not have any rewritings to avoid the
     // overhead of traversing the entire lens chain upon each lookup during the rewriting.
+    NonIdentityGraphLens firstUnappliedLens = computeFirstUnappliedLens(appView, lens, appliedLens);
+
+    // Insert a member rebinding lens above the first unapplied lens.
+    // TODO(b/182129249): Once the member rebinding phase has been removed, the MemberRebindingLens
+    //  should be removed and all uses of FieldRebindingIdentityLens should be replaced by
+    //  MemberRebindingIdentityLens.
+    GraphLens newMemberRebindingLens =
+        computeNewMemberRebindingLens(appView, appliedLens, firstUnappliedLens, timing);
+
+    firstUnappliedLens.withAlternativeParentLens(
+        newMemberRebindingLens,
+        () -> {
+          GraphLens appliedLensInModifiedLens = GraphLens.getIdentityLens();
+          if (appView.hasLiveness()) {
+            appView
+                .withLiveness()
+                .setAppInfo(
+                    appView.appInfoWithLiveness().rewrittenWithLens(application, lens, timing));
+          } else {
+            assert appView.hasClassHierarchy();
+            AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy =
+                appView.withClassHierarchy();
+            AppInfoWithClassHierarchy appInfo = appViewWithClassHierarchy.appInfo();
+            MainDexInfo rewrittenMainDexInfo =
+                appInfo
+                    .getMainDexInfo()
+                    .rewrittenWithLens(appView.getSyntheticItems(), lens, timing);
+            appViewWithClassHierarchy.setAppInfo(
+                appInfo.rebuildWithMainDexInfo(rewrittenMainDexInfo));
+          }
+          appView.setAppServices(appView.appServices().rewrittenWithLens(lens, timing));
+          appView.setArtProfileCollection(
+              appView.getArtProfileCollection().rewrittenWithLens(appView, lens, timing));
+          appView.setAssumeInfoCollection(
+              appView
+                  .getAssumeInfoCollection()
+                  .rewrittenWithLens(appView, lens, appliedLensInModifiedLens, timing));
+          if (appView.hasInitClassLens()) {
+            appView.setInitClassLens(appView.initClassLens().rewrittenWithLens(lens, timing));
+          }
+          if (appView.hasProguardCompatibilityActions()) {
+            appView.setProguardCompatibilityActions(
+                appView.getProguardCompatibilityActions().rewrittenWithLens(lens, timing));
+          }
+          if (appView.hasMainDexRootSet()) {
+            appView.setMainDexRootSet(appView.getMainDexRootSet().rewrittenWithLens(lens, timing));
+          }
+          appView.setOpenClosedInterfacesCollection(
+              appView.getOpenClosedInterfacesCollection().rewrittenWithLens(lens, timing));
+          if (appView.hasRootSet()) {
+            appView.setRootSet(appView.rootSet().rewrittenWithLens(lens, timing));
+          }
+          appView.setStartupProfile(appView.getStartupProfile().rewrittenWithLens(lens, timing));
+        });
+
+    timing.end(); // Rewrite AppView
+  }
+
+  private static NonIdentityGraphLens computeFirstUnappliedLens(
+      AppView<? extends AppInfoWithClassHierarchy> appView,
+      NonIdentityGraphLens lens,
+      GraphLens appliedLens) {
     NonIdentityGraphLens firstUnappliedLens = lens;
     while (firstUnappliedLens.getPrevious() != appliedLens) {
       GraphLens previousLens = firstUnappliedLens.getPrevious();
@@ -947,11 +1011,15 @@
       assert previousLens != appView.codeLens();
       firstUnappliedLens = previousLens.asNonIdentityLens();
     }
+    return firstUnappliedLens;
+  }
 
-    // Insert a member rebinding lens above the first unapplied lens.
-    // TODO(b/182129249): Once the member rebinding phase has been removed, the MemberRebindingLens
-    //  should be removed and all uses of FieldRebindingIdentityLens should be replaced by
-    //  MemberRebindingIdentityLens.
+  private static GraphLens computeNewMemberRebindingLens(
+      AppView<? extends AppInfoWithClassHierarchy> appView,
+      GraphLens appliedLens,
+      NonIdentityGraphLens firstUnappliedLens,
+      Timing timing) {
+    timing.begin("Compute new member rebinding lens");
     GraphLens newMemberRebindingLens = GraphLens.getIdentityLens();
     if (!firstUnappliedLens.isMemberRebindingLens()
         && !firstUnappliedLens.isMemberRebindingIdentityLens()) {
@@ -972,62 +1040,21 @@
                         appView, appliedLens, appliedMemberRebindingLens);
       }
     }
-
-    firstUnappliedLens.withAlternativeParentLens(
-        newMemberRebindingLens,
-        () -> {
-          GraphLens appliedLensInModifiedLens = GraphLens.getIdentityLens();
-          if (appView.hasLiveness()) {
-            appView
-                .withLiveness()
-                .setAppInfo(
-                    appView.appInfoWithLiveness().rewrittenWithLens(application, lens, timing));
-          } else {
-            assert appView.hasClassHierarchy();
-            AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy =
-                appView.withClassHierarchy();
-            AppInfoWithClassHierarchy appInfo = appViewWithClassHierarchy.appInfo();
-            MainDexInfo rewrittenMainDexInfo =
-                appInfo.getMainDexInfo().rewrittenWithLens(appView.getSyntheticItems(), lens);
-            appViewWithClassHierarchy.setAppInfo(
-                appInfo.rebuildWithMainDexInfo(rewrittenMainDexInfo));
-          }
-          appView.setAppServices(appView.appServices().rewrittenWithLens(lens));
-          appView.setArtProfileCollection(
-              appView.getArtProfileCollection().rewrittenWithLens(appView, lens));
-          appView.setAssumeInfoCollection(
-              appView
-                  .getAssumeInfoCollection()
-                  .rewrittenWithLens(appView, lens, appliedLensInModifiedLens));
-          if (appView.hasInitClassLens()) {
-            appView.setInitClassLens(appView.initClassLens().rewrittenWithLens(lens));
-          }
-          if (appView.hasProguardCompatibilityActions()) {
-            appView.setProguardCompatibilityActions(
-                appView.getProguardCompatibilityActions().rewrittenWithLens(lens));
-          }
-          if (appView.hasMainDexRootSet()) {
-            appView.setMainDexRootSet(appView.getMainDexRootSet().rewrittenWithLens(lens));
-          }
-          appView.setOpenClosedInterfacesCollection(
-              appView.getOpenClosedInterfacesCollection().rewrittenWithLens(lens));
-          if (appView.hasRootSet()) {
-            appView.setRootSet(appView.rootSet().rewrittenWithLens(lens));
-          }
-          appView.setStartupProfile(appView.getStartupProfile().rewrittenWithLens(lens));
-        });
+    timing.end();
+    return newMemberRebindingLens;
   }
 
-  public void rewriteWithD8Lens(NonIdentityGraphLens lens) {
-    rewriteWithD8Lens(lens, withoutClassHierarchy());
+  public void rewriteWithD8Lens(NonIdentityGraphLens lens, Timing timing) {
+    rewriteWithD8Lens(lens, timing, withoutClassHierarchy());
   }
 
-  private static void rewriteWithD8Lens(NonIdentityGraphLens lens, AppView<AppInfo> appView) {
+  private static void rewriteWithD8Lens(
+      NonIdentityGraphLens lens, Timing timing, AppView<AppInfo> appView) {
     boolean changed = appView.setGraphLens(lens);
     assert changed;
 
     appView.setArtProfileCollection(
-        appView.getArtProfileCollection().rewrittenWithLens(appView, lens));
+        appView.getArtProfileCollection().rewrittenWithLens(appView, lens, timing));
   }
 
   public void setAlreadyLibraryDesugared(Set<DexType> alreadyLibraryDesugared) {
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
index 63e4530..53e57f6 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.utils.ObjectUtils;
 import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.Timing;
 import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.function.BiPredicate;
@@ -79,11 +80,12 @@
   }
 
   public FieldAccessInfoCollectionImpl rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLens lens) {
+      DexDefinitionSupplier definitions, GraphLens lens, Timing timing) {
+    timing.begin("Rewrite FieldAccessInfoCollectionImpl");
     FieldAccessInfoCollectionImpl collection = new FieldAccessInfoCollectionImpl();
     Consumer<FieldAccessInfoImpl> rewriteAndMergeFieldInfo =
         info -> {
-          FieldAccessInfoImpl rewrittenInfo = info.rewrittenWithLens(definitions, lens);
+          FieldAccessInfoImpl rewrittenInfo = info.rewrittenWithLens(definitions, lens, timing);
           DexField newField = rewrittenInfo.getField();
           collection.infos.compute(
               newField,
@@ -91,6 +93,7 @@
                   ObjectUtils.mapNotNullOrDefault(oldInfo, rewrittenInfo, rewrittenInfo::join));
         };
     infos.values().forEach(rewriteAndMergeFieldInfo);
+    timing.end();
     return collection;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
index 47b1c27..1bc6ae6 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AbstractAccessContexts.ConcreteAccessContexts;
 import com.android.tools.r8.graph.lens.GraphLens;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.collect.Sets;
 import java.util.IdentityHashMap;
@@ -356,11 +357,14 @@
     writesWithContexts = AbstractAccessContexts.empty();
   }
 
-  public FieldAccessInfoImpl rewrittenWithLens(DexDefinitionSupplier definitions, GraphLens lens) {
+  public FieldAccessInfoImpl rewrittenWithLens(
+      DexDefinitionSupplier definitions, GraphLens lens, Timing timing) {
+    timing.begin("Rewrite FieldAccessInfoImpl");
     FieldAccessInfoImpl rewritten = new FieldAccessInfoImpl(lens.lookupField(field));
     rewritten.flags = flags;
     rewritten.readsWithContexts = readsWithContexts.rewrittenWithLens(definitions, lens);
     rewritten.writesWithContexts = writesWithContexts.rewrittenWithLens(definitions, lens);
+    timing.end();
     return rewritten;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/MethodAccessInfoCollection.java b/src/main/java/com/android/tools/r8/graph/MethodAccessInfoCollection.java
index b4dbc3d..f1fb1b9 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodAccessInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodAccessInfoCollection.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.graph.lens.MethodLookupResult;
 import com.android.tools.r8.ir.code.InvokeType;
 import com.android.tools.r8.utils.ConsumerUtils;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.collect.Sets;
 import java.util.IdentityHashMap;
@@ -90,14 +91,17 @@
   }
 
   public MethodAccessInfoCollection rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLens lens) {
+      DexDefinitionSupplier definitions, GraphLens lens, Timing timing) {
+    timing.begin("Rewrite MethodAccessInfoCollection");
     MethodAccessInfoCollection.Builder<?> builder = identityBuilder();
     rewriteInvokesWithLens(builder, directInvokes, definitions, lens, InvokeType.DIRECT);
     rewriteInvokesWithLens(builder, interfaceInvokes, definitions, lens, InvokeType.INTERFACE);
     rewriteInvokesWithLens(builder, staticInvokes, definitions, lens, InvokeType.STATIC);
     rewriteInvokesWithLens(builder, superInvokes, definitions, lens, InvokeType.SUPER);
     rewriteInvokesWithLens(builder, virtualInvokes, definitions, lens, InvokeType.VIRTUAL);
-    return builder.build();
+    MethodAccessInfoCollection result = builder.build();
+    timing.end();
+    return result;
   }
 
   private static void rewriteInvokesWithLens(
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
index 0edf837..70d1666 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollection.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.ir.desugar.LambdaDescriptor;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.TraversalContinuation;
 import java.util.Set;
 import java.util.function.BiConsumer;
@@ -42,5 +43,5 @@
       AppInfo appInfo);
 
   ObjectAllocationInfoCollection rewrittenWithLens(
-      DexDefinitionSupplier definitions, GraphLens lens);
+      DexDefinitionSupplier definitions, GraphLens lens, Timing timing);
 }
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
index 097aa59..aea1754 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.shaking.KeepReason;
 import com.android.tools.r8.shaking.MissingClasses;
 import com.android.tools.r8.utils.LensUtils;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.TraversalContinuation;
 import com.android.tools.r8.utils.WorkList;
 import com.google.common.collect.Sets;
@@ -143,6 +144,12 @@
 
   @Override
   public ObjectAllocationInfoCollectionImpl rewrittenWithLens(
+      DexDefinitionSupplier definitions, GraphLens lens, Timing timing) {
+    return timing.time(
+        "Rewrite ObjectAllocationInfoCollectionImpl", () -> rewrittenWithLens(definitions, lens));
+  }
+
+  private ObjectAllocationInfoCollectionImpl rewrittenWithLens(
       DexDefinitionSupplier definitions, GraphLens lens) {
     return builder(true, null).rewrittenWithLens(this, definitions, lens).build(definitions);
   }
diff --git a/src/main/java/com/android/tools/r8/graph/lens/FinalInitClassLens.java b/src/main/java/com/android/tools/r8/graph/lens/FinalInitClassLens.java
index 54949fa..9ddac29 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/FinalInitClassLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/FinalInitClassLens.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.Timing;
 import java.util.Map;
 
 public class FinalInitClassLens extends InitClassLens {
@@ -32,7 +33,11 @@
   }
 
   @Override
-  public InitClassLens rewrittenWithLens(GraphLens lens) {
+  public InitClassLens rewrittenWithLens(GraphLens lens, Timing timing) {
+    return timing.time("Rewrite FinalInitClassLens", () -> rewrittenWithLens(lens));
+  }
+
+  private InitClassLens rewrittenWithLens(GraphLens lens) {
     InitClassLens.Builder builder = InitClassLens.builder();
     mapping.forEach(
         (type, field) -> {
diff --git a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
index 1604073..bbd068e 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
@@ -30,6 +30,7 @@
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.collections.BidirectionalManyToOneRepresentativeHashMap;
 import com.android.tools.r8.utils.collections.MutableBidirectionalManyToOneRepresentativeMap;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
@@ -491,7 +492,10 @@
   }
 
   public Map<DexCallSite, ProgramMethodSet> rewriteCallSites(
-      Map<DexCallSite, ProgramMethodSet> callSites, DexDefinitionSupplier definitions) {
+      Map<DexCallSite, ProgramMethodSet> callSites,
+      DexDefinitionSupplier definitions,
+      Timing timing) {
+    timing.begin("Rewrite call sites");
     Map<DexCallSite, ProgramMethodSet> result = new IdentityHashMap<>();
     LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(definitions, this, null);
     callSites.forEach(
@@ -503,6 +507,7 @@
                 .add(context);
           }
         });
+    timing.end();
     return result;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/lens/InitClassLens.java b/src/main/java/com/android/tools/r8/graph/lens/InitClassLens.java
index 8ec8404..e1d4ca6 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/InitClassLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/InitClassLens.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.Timing;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -25,7 +26,7 @@
     return false;
   }
 
-  public abstract InitClassLens rewrittenWithLens(GraphLens lens);
+  public abstract InitClassLens rewrittenWithLens(GraphLens lens, Timing timing);
 
   public static class Builder {
 
diff --git a/src/main/java/com/android/tools/r8/graph/lens/ThrowingInitClassLens.java b/src/main/java/com/android/tools/r8/graph/lens/ThrowingInitClassLens.java
index 66a60d5..113d0b7 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/ThrowingInitClassLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/ThrowingInitClassLens.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.Timing;
 
 public class ThrowingInitClassLens extends InitClassLens {
 
@@ -24,7 +25,7 @@
   }
 
   @Override
-  public InitClassLens rewrittenWithLens(GraphLens lens) {
+  public InitClassLens rewrittenWithLens(GraphLens lens, Timing timing) {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index abc15a8..746dbd5 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -181,12 +181,12 @@
           .setAppInfo(
               new AppInfo(
                   syntheticItems.commitRewrittenWithLens(
-                      newApplication, horizontalClassMergerGraphLens),
+                      newApplication, horizontalClassMergerGraphLens, timing),
                   appView
                       .appInfo()
                       .getMainDexInfo()
-                      .rewrittenWithLens(syntheticItems, horizontalClassMergerGraphLens)));
-      appView.rewriteWithD8Lens(horizontalClassMergerGraphLens);
+                      .rewrittenWithLens(syntheticItems, horizontalClassMergerGraphLens, timing)));
+      appView.rewriteWithD8Lens(horizontalClassMergerGraphLens, timing);
     }
     codeProvider.setGraphLens(horizontalClassMergerGraphLens);
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
index bc67f0e..5b8e1f7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
@@ -674,6 +674,7 @@
       OptimizationFeedbackDelayed feedback,
       Timing timing)
       throws ExecutionException {
+    timing.begin("Unbox enums");
     assert feedback.noUpdatesLeft();
 
     assert candidatesToRemoveInWave.isEmpty();
@@ -687,6 +688,7 @@
 
     if (enumUnboxingCandidatesInfo.isEmpty()) {
       assert enumDataMap.isEmpty();
+      timing.end();
       return;
     }
 
@@ -754,6 +756,8 @@
 
     // Ensure determinism of method-to-reprocess set.
     appView.testing().checkDeterminism(postMethodProcessorBuilder::dump);
+
+    timing.end();
   }
 
   private void updateOptimizationInfos(
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/DefaultOpenClosedInterfacesCollection.java b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/DefaultOpenClosedInterfacesCollection.java
index 6759bca..9e3390b 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/DefaultOpenClosedInterfacesCollection.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/DefaultOpenClosedInterfacesCollection.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
+import com.android.tools.r8.utils.Timing;
 
 /** Default oracle for that answers "maybe open" for each interface. */
 public class DefaultOpenClosedInterfacesCollection extends OpenClosedInterfacesCollection {
@@ -26,7 +27,7 @@
   }
 
   @Override
-  public OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens) {
+  public OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens, Timing timing) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/NonEmptyOpenClosedInterfacesCollection.java b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/NonEmptyOpenClosedInterfacesCollection.java
index 8553b40..b143cc1 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/NonEmptyOpenClosedInterfacesCollection.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/NonEmptyOpenClosedInterfacesCollection.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.Timing;
 import java.util.Set;
 
 public class NonEmptyOpenClosedInterfacesCollection extends OpenClosedInterfacesCollection {
@@ -26,7 +27,12 @@
   }
 
   @Override
-  public OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens) {
+  public OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens, Timing timing) {
+    return timing.time(
+        "Rewrite NonEmptyOpenClosedInterfacesCollection", () -> rewrittenWithLens(graphLens));
+  }
+
+  private OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens) {
     Set<DexType> rewrittenOpenInterfaceTypes =
         SetUtils.newIdentityHashSet(openInterfaceTypes.size());
     for (DexType openInterfaceType : openInterfaceTypes) {
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/OpenClosedInterfacesCollection.java b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/OpenClosedInterfacesCollection.java
index 648c8a3..de5075e 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/collection/OpenClosedInterfacesCollection.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/collection/OpenClosedInterfacesCollection.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.Timing;
 import java.util.function.Supplier;
 
 /**
@@ -93,7 +94,8 @@
     return false;
   }
 
-  public abstract OpenClosedInterfacesCollection rewrittenWithLens(GraphLens graphLens);
+  public abstract OpenClosedInterfacesCollection rewrittenWithLens(
+      GraphLens graphLens, Timing timing);
 
   public abstract OpenClosedInterfacesCollection withoutPrunedItems(PrunedItems prunedItems);
 }
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
index cc12b86..784adbf 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
@@ -140,7 +140,8 @@
         });
   }
 
-  public ArtProfile rewrittenWithLens(NamingLens lens, DexItemFactory dexItemFactory) {
+  public ArtProfile rewrittenWithLens(AppView<?> appView, NamingLens lens) {
+    DexItemFactory dexItemFactory = appView.dexItemFactory();
     assert !lens.isIdentityLens();
     return transform(
         (classRule, classRuleBuilderFactory) ->
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
index 6bb861a..2a3f889 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileCollection.java
@@ -6,13 +6,13 @@
 
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Timing;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -70,10 +70,10 @@
 
   public abstract NonEmptyArtProfileCollection asNonEmpty();
 
-  public abstract ArtProfileCollection rewrittenWithLens(AppView<?> appView, GraphLens lens);
-
   public abstract ArtProfileCollection rewrittenWithLens(
-      NamingLens lens, DexItemFactory dexItemFactory);
+      AppView<?> appView, GraphLens lens, Timing timing);
+
+  public abstract ArtProfileCollection rewrittenWithLens(AppView<?> appView, NamingLens lens);
 
   public abstract void supplyConsumers(AppView<?> appView);
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
index 2c63d2e..fcd6d41 100644
--- a/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/EmptyArtProfileCollection.java
@@ -5,10 +5,10 @@
 package com.android.tools.r8.profile.art;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.utils.Timing;
 
 public class EmptyArtProfileCollection extends ArtProfileCollection {
 
@@ -36,12 +36,12 @@
   }
 
   @Override
-  public ArtProfileCollection rewrittenWithLens(AppView<?> appView, GraphLens lens) {
+  public ArtProfileCollection rewrittenWithLens(AppView<?> appView, GraphLens lens, Timing timing) {
     return this;
   }
 
   @Override
-  public ArtProfileCollection rewrittenWithLens(NamingLens lens, DexItemFactory dexItemFactory) {
+  public ArtProfileCollection rewrittenWithLens(AppView<?> appView, NamingLens lens) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
index d91ebae..51ee7e6 100644
--- a/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
+++ b/src/main/java/com/android/tools/r8/profile/art/NonEmptyArtProfileCollection.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.profile.art;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ListUtils;
+import com.android.tools.r8.utils.Timing;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -51,15 +51,20 @@
   }
 
   @Override
-  public NonEmptyArtProfileCollection rewrittenWithLens(AppView<?> appView, GraphLens lens) {
+  public NonEmptyArtProfileCollection rewrittenWithLens(
+      AppView<?> appView, GraphLens lens, Timing timing) {
+    return timing.time(
+        "Rewrite NonEmptyArtProfileCollection", () -> rewrittenWithLens(appView, lens));
+  }
+
+  private NonEmptyArtProfileCollection rewrittenWithLens(AppView<?> appView, GraphLens lens) {
     return map(artProfile -> artProfile.rewrittenWithLens(appView, lens));
   }
 
   @Override
-  public NonEmptyArtProfileCollection rewrittenWithLens(
-      NamingLens lens, DexItemFactory dexItemFactory) {
+  public NonEmptyArtProfileCollection rewrittenWithLens(AppView<?> appView, NamingLens lens) {
     assert !lens.isIdentityLens();
-    return map(artProfile -> artProfile.rewrittenWithLens(lens, dexItemFactory));
+    return map(artProfile -> artProfile.rewrittenWithLens(appView, lens));
   }
 
   @Override
@@ -75,7 +80,7 @@
     NonEmptyArtProfileCollection collection =
         appView.getNamingLens().isIdentityLens()
             ? this
-            : rewrittenWithLens(appView.getNamingLens(), appView.dexItemFactory());
+            : rewrittenWithLens(appView, appView.getNamingLens());
     InternalOptions options = appView.options();
     Collection<ArtProfileForRewriting> inputs =
         options.getArtProfileOptions().getArtProfilesForRewriting();
diff --git a/src/main/java/com/android/tools/r8/profile/startup/profile/EmptyStartupProfile.java b/src/main/java/com/android/tools/r8/profile/startup/profile/EmptyStartupProfile.java
index e585fe6..0030057 100644
--- a/src/main/java/com/android/tools/r8/profile/startup/profile/EmptyStartupProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/startup/profile/EmptyStartupProfile.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.Timing;
 
 public class EmptyStartupProfile extends StartupProfile {
 
@@ -60,7 +61,7 @@
   }
 
   @Override
-  public EmptyStartupProfile rewrittenWithLens(GraphLens graphLens) {
+  public EmptyStartupProfile rewrittenWithLens(GraphLens graphLens, Timing timing) {
     return this;
   }
 
diff --git a/src/main/java/com/android/tools/r8/profile/startup/profile/NonEmptyStartupProfile.java b/src/main/java/com/android/tools/r8/profile/startup/profile/NonEmptyStartupProfile.java
index 8f047a4..34576c3 100644
--- a/src/main/java/com/android/tools/r8/profile/startup/profile/NonEmptyStartupProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/startup/profile/NonEmptyStartupProfile.java
@@ -17,6 +17,7 @@
 import com.android.tools.r8.utils.MapUtils;
 import com.android.tools.r8.utils.SetUtils;
 import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.Timing;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -82,7 +83,11 @@
   }
 
   @Override
-  public StartupProfile rewrittenWithLens(GraphLens graphLens) {
+  public StartupProfile rewrittenWithLens(GraphLens graphLens, Timing timing) {
+    return timing.time("Rewrite NonEmptyStartupProfile", () -> rewrittenWithLens(graphLens));
+  }
+
+  private StartupProfile rewrittenWithLens(GraphLens graphLens) {
     return transform(
         (classRule, builder) ->
             builder.addClassRule(
diff --git a/src/main/java/com/android/tools/r8/profile/startup/profile/StartupProfile.java b/src/main/java/com/android/tools/r8/profile/startup/profile/StartupProfile.java
index 7a517de..cee5637 100644
--- a/src/main/java/com/android/tools/r8/profile/startup/profile/StartupProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/startup/profile/StartupProfile.java
@@ -27,6 +27,7 @@
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.Timing;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
@@ -135,7 +136,7 @@
 
   public abstract boolean isEmpty();
 
-  public abstract StartupProfile rewrittenWithLens(GraphLens graphLens);
+  public abstract StartupProfile rewrittenWithLens(GraphLens graphLens, Timing timing);
 
   public abstract StartupProfile toStartupProfileForWriting(AppView<?> appView);
 
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index ed40807..a3ef43f 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -1125,13 +1125,14 @@
             .map(FieldResolutionResult::getResolvedField)
             .collect(Collectors.toList()));
 
-    CommittedItems committedItems = getSyntheticItems().commitRewrittenWithLens(application, lens);
+    CommittedItems committedItems =
+        getSyntheticItems().commitRewrittenWithLens(application, lens, timing);
     DexDefinitionSupplier definitionSupplier =
         committedItems.getApplication().getDefinitionsSupplier(committedItems);
     return new AppInfoWithLiveness(
         committedItems,
         getClassToFeatureSplitMap().rewrittenWithLens(lens, timing),
-        getMainDexInfo().rewrittenWithLens(getSyntheticItems(), lens),
+        getMainDexInfo().rewrittenWithLens(getSyntheticItems(), lens, timing),
         getMissingClasses(),
         deadProtoTypes,
         lens.rewriteReferences(liveTypes),
@@ -1141,11 +1142,11 @@
         lens.rewriteReferences(bootstrapMethods),
         lens.rewriteReferences(virtualMethodsTargetedByInvokeDirect),
         lens.rewriteReferences(liveMethods),
-        fieldAccessInfoCollection.rewrittenWithLens(definitionSupplier, lens),
-        methodAccessInfoCollection.rewrittenWithLens(definitionSupplier, lens),
-        objectAllocationInfoCollection.rewrittenWithLens(definitionSupplier, lens),
-        lens.rewriteCallSites(callSites, definitionSupplier),
-        keepInfo.rewrite(definitionSupplier, lens, application.options),
+        fieldAccessInfoCollection.rewrittenWithLens(definitionSupplier, lens, timing),
+        methodAccessInfoCollection.rewrittenWithLens(definitionSupplier, lens, timing),
+        objectAllocationInfoCollection.rewrittenWithLens(definitionSupplier, lens, timing),
+        lens.rewriteCallSites(callSites, definitionSupplier, timing),
+        keepInfo.rewrite(definitionSupplier, lens, application.options, timing),
         // Take any rule in case of collisions.
         lens.rewriteReferenceKeys(mayHaveSideEffects, (reference, rules) -> ListUtils.first(rules)),
         lens.rewriteReferences(alwaysInline),
diff --git a/src/main/java/com/android/tools/r8/shaking/AssumeInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/AssumeInfoCollection.java
index 75d7671..d9aba6c 100644
--- a/src/main/java/com/android/tools/r8/shaking/AssumeInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/AssumeInfoCollection.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
 import com.android.tools.r8.utils.MapUtils;
+import com.android.tools.r8.utils.Timing;
 import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -61,6 +62,12 @@
   }
 
   public AssumeInfoCollection rewrittenWithLens(
+      AppView<?> appView, GraphLens graphLens, GraphLens appliedLens, Timing timing) {
+    return timing.time(
+        "Rewrite AssumeInfoCollection", () -> rewrittenWithLens(appView, graphLens, appliedLens));
+  }
+
+  private AssumeInfoCollection rewrittenWithLens(
       AppView<?> appView, GraphLens graphLens, GraphLens appliedLens) {
     Map<DexMember<?, ?>, AssumeInfo> rewrittenCollection = new IdentityHashMap<>();
     backing.forEach(
diff --git a/src/main/java/com/android/tools/r8/shaking/DependentMinimumKeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/DependentMinimumKeepInfoCollection.java
index a1129346d..92ba7ff 100644
--- a/src/main/java/com/android/tools/r8/shaking/DependentMinimumKeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/DependentMinimumKeepInfoCollection.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.shaking.EnqueuerEvent.UnconditionalKeepInfoEvent;
 import com.android.tools.r8.shaking.KeepInfo.Joiner;
 import com.android.tools.r8.utils.MapUtils;
+import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.TriConsumer;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -148,7 +149,8 @@
     return minimumKeepInfoForReference;
   }
 
-  public DependentMinimumKeepInfoCollection rewrittenWithLens(GraphLens graphLens) {
+  public DependentMinimumKeepInfoCollection rewrittenWithLens(GraphLens graphLens, Timing timing) {
+    timing.begin("Rewrite DependentMinimumKeepInfoCollection");
     DependentMinimumKeepInfoCollection rewrittenDependentMinimumKeepInfo =
         new DependentMinimumKeepInfoCollection();
     forEach(
@@ -160,6 +162,7 @@
                 .merge(minimumKeepInfo.rewrittenWithLens(graphLens));
           }
         });
+    timing.end();
     return rewrittenDependentMinimumKeepInfo;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
index fda4b97..f9c2474 100644
--- a/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/shaking/KeepInfoCollection.java
@@ -29,6 +29,7 @@
 import com.android.tools.r8.shaking.KeepFieldInfo.Joiner;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.MapUtils;
+import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Streams;
 import java.util.IdentityHashMap;
 import java.util.Map;
@@ -243,7 +244,10 @@
   public abstract void forEachPinnedField(Consumer<DexField> consumer, InternalOptions options);
 
   public abstract KeepInfoCollection rewrite(
-      DexDefinitionSupplier definitions, NonIdentityGraphLens lens, InternalOptions options);
+      DexDefinitionSupplier definitions,
+      NonIdentityGraphLens lens,
+      InternalOptions options,
+      Timing timing);
 
   public abstract KeepInfoCollection mutate(Consumer<MutableKeepInfoCollection> mutator);
 
@@ -312,7 +316,45 @@
 
     @Override
     public KeepInfoCollection rewrite(
-        DexDefinitionSupplier definitions, NonIdentityGraphLens lens, InternalOptions options) {
+        DexDefinitionSupplier definitions,
+        NonIdentityGraphLens lens,
+        InternalOptions options,
+        Timing timing) {
+      timing.begin("Rewrite KeepInfoCollection");
+      Map<DexType, KeepClassInfo> newClassInfo = rewriteClassInfo(lens, options, timing);
+      Map<DexMethod, KeepMethodInfo> newMethodInfo = rewriteMethodInfo(lens, options, timing);
+      Map<DexField, KeepFieldInfo> newFieldInfo = rewriteFieldInfo(lens, options, timing);
+      MutableKeepInfoCollection result =
+          new MutableKeepInfoCollection(
+              newClassInfo,
+              newMethodInfo,
+              newFieldInfo,
+              rewriteRuleInstances(
+                  classRuleInstances,
+                  clazz -> {
+                    DexType rewritten = lens.lookupType(clazz);
+                    if (rewritten.isClassType()) {
+                      return rewritten;
+                    }
+                    assert rewritten.isIntType();
+                    return null;
+                  },
+                  KeepClassInfo::newEmptyJoiner),
+              rewriteRuleInstances(
+                  fieldRuleInstances,
+                  lens::getRenamedFieldSignature,
+                  KeepFieldInfo::newEmptyJoiner),
+              rewriteRuleInstances(
+                  methodRuleInstances,
+                  lens::getRenamedMethodSignature,
+                  KeepMethodInfo::newEmptyJoiner));
+      timing.end();
+      return result;
+    }
+
+    private Map<DexType, KeepClassInfo> rewriteClassInfo(
+        NonIdentityGraphLens lens, InternalOptions options, Timing timing) {
+      timing.begin("Rewrite class info");
       Map<DexType, KeepClassInfo> newClassInfo = new IdentityHashMap<>(keepClassInfo.size());
       keepClassInfo.forEach(
           (type, info) -> {
@@ -328,6 +370,30 @@
             KeepClassInfo previous = newClassInfo.put(newType, info);
             assert previous == null;
           });
+      timing.end();
+      return newClassInfo;
+    }
+
+    private Map<DexField, KeepFieldInfo> rewriteFieldInfo(
+        NonIdentityGraphLens lens, InternalOptions options, Timing timing) {
+      timing.begin("Rewrite field info");
+      Map<DexField, KeepFieldInfo> newFieldInfo = new IdentityHashMap<>(keepFieldInfo.size());
+      keepFieldInfo.forEach(
+          (field, info) -> {
+            DexField newField = lens.getRenamedFieldSignature(field);
+            assert newField.name == field.name
+                || !info.isPinned(options)
+                || info.isMinificationAllowed(options);
+            KeepFieldInfo previous = newFieldInfo.put(newField, info);
+            assert previous == null;
+          });
+      timing.end();
+      return newFieldInfo;
+    }
+
+    private Map<DexMethod, KeepMethodInfo> rewriteMethodInfo(
+        NonIdentityGraphLens lens, InternalOptions options, Timing timing) {
+      timing.begin("Rewrite method info");
       Map<DexMethod, KeepMethodInfo> newMethodInfo = new IdentityHashMap<>(keepMethodInfo.size());
       keepMethodInfo.forEach(
           (method, info) -> {
@@ -348,37 +414,8 @@
             // TODO(b/169927809): Avoid collisions.
             // assert previous == null;
           });
-      Map<DexField, KeepFieldInfo> newFieldInfo = new IdentityHashMap<>(keepFieldInfo.size());
-      keepFieldInfo.forEach(
-          (field, info) -> {
-            DexField newField = lens.getRenamedFieldSignature(field);
-            assert newField.name == field.name
-                || !info.isPinned(options)
-                || info.isMinificationAllowed(options);
-            KeepFieldInfo previous = newFieldInfo.put(newField, info);
-            assert previous == null;
-          });
-      return new MutableKeepInfoCollection(
-          newClassInfo,
-          newMethodInfo,
-          newFieldInfo,
-          rewriteRuleInstances(
-              classRuleInstances,
-              clazz -> {
-                DexType rewritten = lens.lookupType(clazz);
-                if (rewritten.isClassType()) {
-                  return rewritten;
-                }
-                assert rewritten.isIntType();
-                return null;
-              },
-              KeepClassInfo::newEmptyJoiner),
-          rewriteRuleInstances(
-              fieldRuleInstances, lens::getRenamedFieldSignature, KeepFieldInfo::newEmptyJoiner),
-          rewriteRuleInstances(
-              methodRuleInstances,
-              lens::getRenamedMethodSignature,
-              KeepMethodInfo::newEmptyJoiner));
+      timing.end();
+      return newMethodInfo;
     }
 
     private static <R, J extends KeepInfo.Joiner<J, ?, ?>> Map<R, J> rewriteRuleInstances(
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexInfo.java b/src/main/java/com/android/tools/r8/shaking/MainDexInfo.java
index 69bc36a..a961e10 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexInfo.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexInfo.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.ConsumerUtils;
+import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.Set;
@@ -273,7 +274,12 @@
     }
   }
 
-  public MainDexInfo rewrittenWithLens(SyntheticItems syntheticItems, GraphLens lens) {
+  public MainDexInfo rewrittenWithLens(
+      SyntheticItems syntheticItems, GraphLens lens, Timing timing) {
+    return timing.time("Rewrite MainDexInfo", () -> rewrittenWithLens(syntheticItems, lens));
+  }
+
+  private MainDexInfo rewrittenWithLens(SyntheticItems syntheticItems, GraphLens lens) {
     Set<DexType> modifiedClassList = Sets.newIdentityHashSet();
     classList.forEach(
         type -> rewriteAndApplyIfNotPrimitiveType(lens, type, modifiedClassList::add));
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardCompatibilityActions.java b/src/main/java/com/android/tools/r8/shaking/ProguardCompatibilityActions.java
index b1ec100..04098a2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardCompatibilityActions.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardCompatibilityActions.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.graph.lens.GraphLens;
+import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Sets;
 import java.util.Set;
 
@@ -37,7 +38,11 @@
     return builder.build();
   }
 
-  public ProguardCompatibilityActions rewrittenWithLens(GraphLens lens) {
+  public ProguardCompatibilityActions rewrittenWithLens(GraphLens lens, Timing timing) {
+    return timing.time("Rewrite ProguardCompatibilityActions", () -> rewrittenWithLens(lens));
+  }
+
+  private ProguardCompatibilityActions rewrittenWithLens(GraphLens lens) {
     Builder builder = builder();
     for (DexType compatInstantiatedType : compatInstantiatedTypes) {
       builder.addCompatInstantiatedType(lens.lookupType(compatInstantiatedType));
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index a8fa6fb..58567a6 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -1959,34 +1959,40 @@
       }
     }
 
-    public RootSet rewrittenWithLens(GraphLens graphLens) {
+    public RootSet rewrittenWithLens(GraphLens graphLens, Timing timing) {
+      timing.begin("Rewrite RootSet");
+      RootSet rewrittenRootSet;
       if (graphLens.isIdentityLens()) {
-        return this;
+        rewrittenRootSet = this;
+      } else {
+        // TODO(b/164019179): If rules can now reference dead items. These should be pruned or
+        //  rewritten
+        ifRules.forEach(ProguardIfRule::canReferenceDeadTypes);
+        rewrittenRootSet =
+            new RootSet(
+                getDependentMinimumKeepInfo().rewrittenWithLens(graphLens, timing),
+                reasonAsked,
+                alwaysInline,
+                neverInlineDueToSingleCaller,
+                bypassClinitForInlining,
+                whyAreYouNotInlining,
+                reprocess,
+                neverReprocess,
+                alwaysClassInline,
+                neverClassInline,
+                noUnusedInterfaceRemoval,
+                noVerticalClassMerging,
+                noHorizontalClassMerging,
+                neverPropagateValue,
+                mayHaveSideEffects,
+                dependentKeepClassCompatRule,
+                identifierNameStrings,
+                ifRules,
+                delayedRootSetActionItems,
+                pendingMethodMoveInverse);
       }
-      // TODO(b/164019179): If rules can now reference dead items. These should be pruned or
-      //  rewritten
-      ifRules.forEach(ProguardIfRule::canReferenceDeadTypes);
-      return new RootSet(
-          getDependentMinimumKeepInfo().rewrittenWithLens(graphLens),
-          reasonAsked,
-          alwaysInline,
-          neverInlineDueToSingleCaller,
-          bypassClinitForInlining,
-          whyAreYouNotInlining,
-          reprocess,
-          neverReprocess,
-          alwaysClassInline,
-          neverClassInline,
-          noUnusedInterfaceRemoval,
-          noVerticalClassMerging,
-          noHorizontalClassMerging,
-          neverPropagateValue,
-          mayHaveSideEffects,
-          dependentKeepClassCompatRule,
-          identifierNameStrings,
-          ifRules,
-          delayedRootSetActionItems,
-          pendingMethodMoveInverse);
+      timing.end();
+      return rewrittenRootSet;
     }
 
     void shouldNotBeMinified(ProgramDefinition definition) {
@@ -2311,25 +2317,30 @@
     }
 
     @Override
-    public MainDexRootSet rewrittenWithLens(GraphLens graphLens) {
+    public MainDexRootSet rewrittenWithLens(GraphLens graphLens, Timing timing) {
+      timing.begin("Rewrite MainDexRootSet");
+      MainDexRootSet rewrittenMainDexRootSet;
       if (graphLens.isIdentityLens()) {
-        return this;
+        rewrittenMainDexRootSet = this;
+      } else {
+        ImmutableList.Builder<DexReference> rewrittenReasonAsked = ImmutableList.builder();
+        reasonAsked.forEach(
+            reference ->
+                rewriteAndApplyIfNotPrimitiveType(graphLens, reference, rewrittenReasonAsked::add));
+        // TODO(b/164019179): If rules can now reference dead items. These should be pruned or
+        //  rewritten
+        ifRules.forEach(ProguardIfRule::canReferenceDeadTypes);
+        // All delayed root set actions should have been processed at this point.
+        assert delayedRootSetActionItems.isEmpty();
+        rewrittenMainDexRootSet =
+            new MainDexRootSet(
+                getDependentMinimumKeepInfo().rewrittenWithLens(graphLens, timing),
+                rewrittenReasonAsked.build(),
+                ifRules,
+                delayedRootSetActionItems);
       }
-
-      ImmutableList.Builder<DexReference> rewrittenReasonAsked = ImmutableList.builder();
-      reasonAsked.forEach(
-          reference ->
-              rewriteAndApplyIfNotPrimitiveType(graphLens, reference, rewrittenReasonAsked::add));
-      // TODO(b/164019179): If rules can now reference dead items. These should be pruned or
-      //  rewritten
-      ifRules.forEach(ProguardIfRule::canReferenceDeadTypes);
-      // All delayed root set actions should have been processed at this point.
-      assert delayedRootSetActionItems.isEmpty();
-      return new MainDexRootSet(
-          getDependentMinimumKeepInfo().rewrittenWithLens(graphLens),
-          rewrittenReasonAsked.build(),
-          ifRules,
-          delayedRootSetActionItems);
+      timing.end();
+      return rewrittenMainDexRootSet;
     }
 
     public MainDexRootSet withoutPrunedItems(PrunedItems prunedItems) {
diff --git a/src/main/java/com/android/tools/r8/synthesis/CommittedSyntheticsCollection.java b/src/main/java/com/android/tools/r8/synthesis/CommittedSyntheticsCollection.java
index c4152fa..162be3d 100644
--- a/src/main/java/com/android/tools/r8/synthesis/CommittedSyntheticsCollection.java
+++ b/src/main/java/com/android/tools/r8/synthesis/CommittedSyntheticsCollection.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import com.android.tools.r8.utils.IterableUtils;
 import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -307,7 +308,7 @@
     return changed ? builder.build() : this;
   }
 
-  CommittedSyntheticsCollection rewriteWithLens(NonIdentityGraphLens lens) {
+  CommittedSyntheticsCollection rewriteWithLens(NonIdentityGraphLens lens, Timing timing) {
     ImmutableSet.Builder<DexType> syntheticInputsBuilder = ImmutableSet.builder();
     return new CommittedSyntheticsCollection(
         naming,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index 7f08a93..cf3d627 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -179,8 +179,8 @@
                   appView
                       .appInfo()
                       .getMainDexInfo()
-                      .rewrittenWithLens(appView.getSyntheticItems(), result.lens)));
-      appView.rewriteWithD8Lens(result.lens);
+                      .rewrittenWithLens(appView.getSyntheticItems(), result.lens, timing)));
+      appView.rewriteWithD8Lens(result.lens, timing);
     }
     appView.pruneItems(result.prunedItems, executorService);
   }
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 9f7b7f2..e7dc070 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -1081,15 +1081,19 @@
   }
 
   public CommittedItems commitRewrittenWithLens(
-      DexApplication application, NonIdentityGraphLens lens) {
+      DexApplication application, NonIdentityGraphLens lens, Timing timing) {
+    timing.begin("Rewrite SyntheticItems");
     assert pending.verifyNotRewritten(lens);
-    return commit(
-        PrunedItems.empty(application),
-        pending,
-        globalContexts,
-        committed.rewriteWithLens(lens),
-        state,
-        globalSyntheticsStrategy);
+    CommittedItems committedItems =
+        commit(
+            PrunedItems.empty(application),
+            pending,
+            globalContexts,
+            committed.rewriteWithLens(lens, timing),
+            state,
+            globalSyntheticsStrategy);
+    timing.end();
+    return committedItems;
   }
 
   private static CommittedItems commit(