diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 073cc8d..3d5f387 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -325,8 +325,7 @@
       List<DexString> forcedStrings,
       Timing timing)
       throws ExecutionException {
-    TimingMerger merger =
-        timing.beginMerger("Write files", ThreadUtils.getNumberOfThreads(executorService));
+    TimingMerger merger = timing.beginMerger("Write files", executorService);
     Collection<Timing> timings =
         ThreadUtils.processItemsWithResults(
             virtualFiles,
@@ -395,8 +394,7 @@
 
       {
         // Compute offsets and rewrite jumbo strings so that code offsets are fixed.
-        TimingMerger merger =
-            timing.beginMerger("Pre-write phase", ThreadUtils.getNumberOfThreads(executorService));
+        TimingMerger merger = timing.beginMerger("Pre-write phase", executorService);
         Collection<Timing> timings =
             rewriteJumboStringsAndComputeDebugRepresentation(
                 executorService, virtualFiles, lazyDexStrings);
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriterExperimental.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriterExperimental.java
index 853d01e..8324c91 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriterExperimental.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriterExperimental.java
@@ -96,8 +96,7 @@
       List<VirtualFile> virtualFiles,
       List<DexString> forcedStrings,
       Timing timing) {
-    TimingMerger merger =
-        timing.beginMerger("Write files", ThreadUtils.getNumberOfThreads(executorService));
+    TimingMerger merger = timing.beginMerger("Write files", executorService);
     Collection<Timing> timings;
     // TODO(b/249922554): Current limitations for the experimental flag.
     assert globalsSyntheticsConsumer == null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index d72358a..9b3ea7c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -833,7 +833,8 @@
         .forEach(
             (key, value) -> {
               assert value == 1;
-              assert value <= basicBlockNumberGenerator.peek();
+              assert key >= 0;
+              assert key <= basicBlockNumberGenerator.peek();
             });
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Inc.java b/src/main/java/com/android/tools/r8/ir/code/Inc.java
index 72b2bf2..5d3a877 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Inc.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Inc.java
@@ -33,6 +33,10 @@
     return Opcodes.INC;
   }
 
+  public int getIncrement() {
+    return increment;
+  }
+
   @Override
   public <T> T accept(InstructionVisitor<T> visitor) {
     return visitor.visit(this);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 81f5c14..16fa00c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -52,7 +52,7 @@
 import com.android.tools.r8.ir.code.UninitializedThisLocalRead;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.Xor;
-import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.ir.conversion.passes.TrivialGotosCollapser;
 import com.android.tools.r8.ir.optimize.DeadCodeRemover;
 import com.android.tools.r8.ir.optimize.PeepholeOptimizer;
 import com.android.tools.r8.ir.optimize.PhiOptimizations;
@@ -193,10 +193,11 @@
     loadStoreHelper.insertPhiMoves(registerAllocator);
     timing.end();
 
+    TrivialGotosCollapser trivialGotosCollapser = new TrivialGotosCollapser(appView);
     timing.begin("BasicBlock peephole optimizations");
     if (code.getConversionOptions().isPeepholeOptimizationsEnabled()) {
       for (int i = 0; i < PEEPHOLE_OPTIMIZATION_PASSES; i++) {
-        CodeRewriter.collapseTrivialGotos(appView, code);
+        trivialGotosCollapser.run(code.context(), code, timing);
         PeepholeOptimizer.removeIdenticalPredecessorBlocks(code, registerAllocator);
         PeepholeOptimizer.shareIdenticalBlockSuffix(
             code, registerAllocator, SUFFIX_SHARING_OVERHEAD);
@@ -206,7 +207,7 @@
 
     timing.time("Rewrite Iinc patterns", this::rewriteIincPatterns);
 
-    CodeRewriter.collapseTrivialGotos(appView, code);
+    trivialGotosCollapser.run(code.context(), code, timing);
     timing.begin("Remove redundant debug positions");
     DexBuilder.removeRedundantDebugPositions(code);
     timing.end();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
index cd7b5b9..1ddfeac 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
@@ -63,7 +63,7 @@
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.Return;
 import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.ir.conversion.passes.TrivialGotosCollapser;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalOutputMode;
@@ -401,7 +401,7 @@
       }
       if (allMatch) {
         currentBlock.removeInstruction(debugPosition);
-        CodeRewriter.unlinkTrivialGotoBlock(currentBlock, exit.getTarget());
+        TrivialGotosCollapser.unlinkTrivialGotoBlock(currentBlock, exit.getTarget());
         code.removeBlocks(Collections.singleton(currentBlock));
         // Having removed the block at blockIndex, the previous block may now be a trivial
         // fallthrough from an if/switch. Rewind to that point and retry. This avoids iterating to
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 7636cbd..55c6a06 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -27,10 +27,14 @@
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.InstructionIterator;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.passes.ArrayConstructionSimplifier;
 import com.android.tools.r8.ir.conversion.passes.BinopRewriter;
+import com.android.tools.r8.ir.conversion.passes.BranchSimplifier;
 import com.android.tools.r8.ir.conversion.passes.CommonSubexpressionElimination;
 import com.android.tools.r8.ir.conversion.passes.ParentConstructorHoistingCodeRewriter;
 import com.android.tools.r8.ir.conversion.passes.SplitBranch;
+import com.android.tools.r8.ir.conversion.passes.TrivialCheckCastAndInstanceOfRemover;
+import com.android.tools.r8.ir.conversion.passes.TrivialPhiSimplifier;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformer;
 import com.android.tools.r8.ir.optimize.AssertionErrorTwoArgsConstructorRewriter;
@@ -538,7 +542,7 @@
 
     if (options.canHaveArtStringNewInitBug()) {
       timing.begin("Check for new-init issue");
-      CodeRewriter.ensureDirectStringNewToInit(code, appView.dexItemFactory());
+      TrivialPhiSimplifier.ensureDirectStringNewToInit(code, appView.dexItemFactory());
       timing.end();
     }
 
@@ -726,8 +730,8 @@
     assert code.verifyTypes(appView);
 
     timing.begin("Remove trivial type checks/casts");
-    codeRewriter.removeTrivialCheckCastAndInstanceOfInstructions(
-        code, context, methodProcessor, methodProcessingContext);
+    new TrivialCheckCastAndInstanceOfRemover(appView)
+        .run(code, context, methodProcessor, methodProcessingContext);
     timing.end();
 
     if (enumValueOptimizer != null) {
@@ -750,9 +754,7 @@
       timing.end();
     }
     commonSubexpressionElimination.run(context, code, timing);
-    timing.begin("Simplify arrays");
-    codeRewriter.simplifyArrayConstruction(code);
-    timing.end();
+    new ArrayConstructionSimplifier(appView).run(context, code, timing);
     timing.begin("Rewrite move result");
     codeRewriter.rewriteMoveResult(code);
     timing.end();
@@ -771,10 +773,10 @@
     codeRewriter.optimizeAlwaysThrowingInstructions(code);
     timing.end();
     timing.begin("Simplify control flow");
-    if (codeRewriter.simplifyControlFlow(code)) {
+    if (new BranchSimplifier(appView).simplifyBranches(code)) {
       timing.begin("Remove trivial type checks/casts");
-      codeRewriter.removeTrivialCheckCastAndInstanceOfInstructions(
-          code, context, methodProcessor, methodProcessingContext);
+      new TrivialCheckCastAndInstanceOfRemover(appView)
+          .run(code, context, methodProcessor, methodProcessingContext);
       timing.end();
     }
     timing.end();
@@ -829,7 +831,6 @@
       assert options.inlinerOptions().enableInlining && inliner != null;
       classInliner.processMethodCode(
           appView.withLiveness(),
-          codeRewriter,
           stringOptimizer,
           enumValueOptimizer,
           code.context(),
@@ -877,7 +878,7 @@
     if (!options.isGeneratingClassFiles()) {
       timing.begin("Canonicalize constants");
       ConstantCanonicalizer constantCanonicalizer =
-          new ConstantCanonicalizer(appView, codeRewriter, context, code);
+          new ConstantCanonicalizer(appView, context, code);
       constantCanonicalizer.canonicalize();
       timing.end();
       previous = printMethod(code, "IR after constant canonicalization (SSA)", previous);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java b/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
index 06f3da8..ddcd9ac 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
 import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.conversion.passes.TrivialGotosCollapser;
 import com.android.tools.r8.ir.desugar.nest.D8NestBasedAccessDesugaring;
 import com.android.tools.r8.ir.optimize.CodeRewriter;
 import com.android.tools.r8.ir.optimize.DeadCodeRemover;
@@ -22,13 +23,10 @@
 public class IRToDexFinalizer extends IRFinalizer<DexCode> {
 
   private static final int PEEPHOLE_OPTIMIZATION_PASSES = 2;
-
-  private final CodeRewriter codeRewriter;
   private final InternalOptions options;
 
   public IRToDexFinalizer(AppView<?> appView, DeadCodeRemover deadCodeRemover) {
     super(appView, deadCodeRemover);
-    this.codeRewriter = deadCodeRemover.getCodeRewriter();
     this.options = appView.options();
   }
 
@@ -44,7 +42,7 @@
     // Workaround massive dex2oat memory use for self-recursive methods.
     RuntimeWorkaroundCodeRewriter.workaroundDex2OatInliningIssue(appView, code);
     // Workaround MAX_INT switch issue.
-    RuntimeWorkaroundCodeRewriter.workaroundSwitchMaxIntBug(code, codeRewriter, options);
+    RuntimeWorkaroundCodeRewriter.workaroundSwitchMaxIntBug(code, appView);
     RuntimeWorkaroundCodeRewriter.workaroundDex2OatLinkedListBug(code, options);
     RuntimeWorkaroundCodeRewriter.workaroundForwardingInitializerBug(code, options);
     RuntimeWorkaroundCodeRewriter.workaroundExceptionTargetingLoopHeaderBug(code, options);
@@ -62,17 +60,18 @@
     LinearScanRegisterAllocator registerAllocator = new LinearScanRegisterAllocator(appView, code);
     registerAllocator.allocateRegisters();
     timing.end();
+    TrivialGotosCollapser trivialGotosCollapser = new TrivialGotosCollapser(appView);
     if (code.getConversionOptions().isPeepholeOptimizationsEnabled()) {
       timing.begin("Peephole optimize");
       for (int i = 0; i < PEEPHOLE_OPTIMIZATION_PASSES; i++) {
-        CodeRewriter.collapseTrivialGotos(appView, code);
+        trivialGotosCollapser.run(code.context(), code, timing);
         PeepholeOptimizer.optimize(appView, code, registerAllocator);
       }
       timing.end();
     }
     timing.begin("Clean up");
     CodeRewriter.removeUnneededMovesOnExitingPaths(code, registerAllocator);
-    CodeRewriter.collapseTrivialGotos(appView, code);
+    trivialGotosCollapser.run(code.context(), code, timing);
     timing.end();
     return registerAllocator;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 1efe772..4c15125 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -104,7 +104,7 @@
 import com.android.tools.r8.ir.code.UnusedArgument;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.ValueType;
-import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.ir.conversion.passes.TrivialPhiSimplifier;
 import com.android.tools.r8.ir.optimize.enums.EnumUnboxer;
 import com.android.tools.r8.optimize.MemberRebindingAnalysis;
 import com.android.tools.r8.optimize.argumentpropagation.lenscoderewriter.NullCheckInserter;
@@ -231,7 +231,7 @@
         if (unusedArgument.outValue().hasPhiUsers()) {
           // See b/240282988: We can end up in situations where the second round of IR processing
           // introduce phis for irreducible control flow, we need to resolve them.
-          CodeRewriter.replaceUnusedArgumentTrivialPhis(unusedArgument);
+          TrivialPhiSimplifier.replaceUnusedArgumentTrivialPhis(unusedArgument);
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
index fe3085a..ab073dd 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PostMethodProcessor.java
@@ -178,8 +178,7 @@
       ExecutorService executorService,
       Timing timing)
       throws ExecutionException {
-    TimingMerger merger =
-        timing.beginMerger("secondary-processor", ThreadUtils.getNumberOfThreads(executorService));
+    TimingMerger merger = timing.beginMerger("secondary-processor", executorService);
     while (!waves.isEmpty()) {
       wave = waves.removeFirst();
       assert !wave.isEmpty();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
index 9da34d4..45450f9 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryMethodProcessor.java
@@ -129,8 +129,7 @@
       Timing timing,
       ExecutorService executorService)
       throws ExecutionException {
-    TimingMerger merger =
-        timing.beginMerger("primary-processor", ThreadUtils.getNumberOfThreads(executorService));
+    TimingMerger merger = timing.beginMerger("primary-processor", executorService);
     while (!waves.isEmpty()) {
       processorContext = appView.createProcessorContext();
       wave = waves.removeFirst();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/callgraph/CallSiteInformation.java b/src/main/java/com/android/tools/r8/ir/conversion/callgraph/CallSiteInformation.java
index c2e13af..e412ed7 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/callgraph/CallSiteInformation.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/callgraph/CallSiteInformation.java
@@ -13,6 +13,8 @@
 import com.android.tools.r8.utils.classhierarchy.MethodOverridesCollector;
 import com.android.tools.r8.utils.collections.ProgramMethodSet;
 import com.google.common.collect.Sets;
+import java.util.IdentityHashMap;
+import java.util.Map;
 import java.util.Set;
 
 public abstract class CallSiteInformation {
@@ -23,6 +25,14 @@
    * <p>For pinned methods (methods kept through Proguard keep rules) this will always answer <code>
    * false</code>.
    */
+  public abstract boolean hasSingleCallSite(ProgramMethod method, ProgramMethod context);
+
+  /**
+   * Checks if the given method only has a single call without considering context.
+   *
+   * <p>For pinned methods (methods kept through Proguard keep rules) and methods that override a
+   * library method this always returns false.
+   */
   public abstract boolean hasSingleCallSite(ProgramMethod method);
 
   public abstract boolean isMultiCallerInlineCandidate(ProgramMethod method);
@@ -38,6 +48,11 @@
     private static final EmptyCallSiteInformation EMPTY_INFO = new EmptyCallSiteInformation();
 
     @Override
+    public boolean hasSingleCallSite(ProgramMethod method, ProgramMethod context) {
+      return false;
+    }
+
+    @Override
     public boolean hasSingleCallSite(ProgramMethod method) {
       return false;
     }
@@ -55,7 +70,9 @@
 
   static class CallGraphBasedCallSiteInformation extends CallSiteInformation {
 
-    private final Set<DexMethod> singleCallerMethods = Sets.newIdentityHashSet();
+    // Single callers track their calling context to ensure that the predicate is stable after
+    // inlining of the caller.
+    private final Map<DexMethod, DexMethod> singleCallerMethods = new IdentityHashMap<>();
     private final Set<DexMethod> multiCallerInlineCandidates = Sets.newIdentityHashSet();
 
     CallGraphBasedCallSiteInformation(AppView<AppInfoWithLiveness> appView, CallGraph graph) {
@@ -94,7 +111,16 @@
 
         int numberOfCallSites = node.getNumberOfCallSites();
         if (numberOfCallSites == 1) {
-          singleCallerMethods.add(reference);
+          Set<Node> callersWithDeterministicOrder = node.getCallersWithDeterministicOrder();
+          DexMethod caller = reference;
+          // We can have recursive methods where the recursive call is the only call site. We do
+          // not track callers for these.
+          if (!callersWithDeterministicOrder.isEmpty()) {
+            assert callersWithDeterministicOrder.size() == 1;
+            caller = callersWithDeterministicOrder.iterator().next().getMethod().getReference();
+          }
+          DexMethod existing = singleCallerMethods.put(reference, caller);
+          assert existing == null;
         } else if (numberOfCallSites > 1) {
           multiCallerInlineCandidates.add(reference);
         }
@@ -102,14 +128,25 @@
     }
 
     /**
-     * Checks if the given method only has a single call site.
+     * Checks if the given method only has a single call site with the given context.
+     *
+     * <p>For pinned methods (methods kept through Proguard keep rules) and methods that override a
+     * library method this always returns false.
+     */
+    @Override
+    public boolean hasSingleCallSite(ProgramMethod method, ProgramMethod context) {
+      return singleCallerMethods.get(method.getReference()) == context.getReference();
+    }
+
+    /**
+     * Checks if the given method only has a single call without considering context.
      *
      * <p>For pinned methods (methods kept through Proguard keep rules) and methods that override a
      * library method this always returns false.
      */
     @Override
     public boolean hasSingleCallSite(ProgramMethod method) {
-      return singleCallerMethods.contains(method.getReference());
+      return singleCallerMethods.containsKey(method.getReference());
     }
 
     /**
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java
new file mode 100644
index 0000000..bc8f8fb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java
@@ -0,0 +1,474 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.conversion.passes;
+
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
+import com.android.tools.r8.ir.code.ArrayPut;
+import com.android.tools.r8.ir.code.BasicBlock;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionListIterator;
+import com.android.tools.r8.ir.code.InvokeNewArray;
+import com.android.tools.r8.ir.code.LinearFlowInstructionListIterator;
+import com.android.tools.r8.ir.code.NewArrayEmpty;
+import com.android.tools.r8.ir.code.NewArrayFilledData;
+import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.InternalOptions.RewriteArrayOptions;
+import com.android.tools.r8.utils.SetUtils;
+import com.android.tools.r8.utils.WorkList;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Replace new-array followed by stores of constants to all entries with new-array and
+ * fill-array-data / filled-new-array.
+ *
+ * <p>The format of the new-array and its puts must be of the form:
+ *
+ * <pre>
+ *   v0 <- new-array T vSize
+ *   ...
+ *   array-put v0 vValue1 vIndex1
+ *   ...
+ *   array-put v0 vValueN vIndexN
+ * </pre>
+ *
+ * <p>The flow between the array v0 and its puts must be linear with no other uses of v0 besides the
+ * array-put instructions, thus any no intermediate instruction (... above) must use v0 and also
+ * cannot have catch handlers that would transfer out control (those could then have uses of v0).
+ *
+ * <p>The allocation of the new-array can itself have catch handlers, in which case, those are to
+ * remain active on the translated code. Translated code can have two forms.
+ *
+ * <p>The first is using the original array allocation and filling in its data if it can be encoded:
+ *
+ * <pre>
+ *   v0 <- new-array T vSize
+ *   filled-array-data v0
+ *   ...
+ *   ...
+ * </pre>
+ *
+ * The data payload is encoded directly in the instruction so no dependencies are needed for filling
+ * the data array. Thus, the fill is inserted at the point of the allocation. If the allocation has
+ * catch handlers its block must be split and the handlers put on the fill instruction too. This is
+ * correct only because there are no exceptional transfers in (...) that could observe the early
+ * initialization of the data.
+ *
+ * <p>The second is using filled-new-array and has the form:
+ *
+ * <pre>
+ * ...
+ * ...
+ * v0 <- filled-new-array T vValue1 ... vValueN
+ * </pre>
+ *
+ * Here the correctness relies on no exceptional transfers in (...) that could observe the missing
+ * allocation of the array. The late allocation ensures that the values are available at allocation
+ * time. If the original allocation has catch handlers then the new allocation needs to link those
+ * too. In general that may require splitting the block twice so that the new allocation is the
+ * single throwing instruction in its block.
+ */
+public class ArrayConstructionSimplifier extends CodeRewriterPass<AppInfo> {
+
+  private final DexItemFactory dexItemFactory;
+
+  public ArrayConstructionSimplifier(AppView<?> appView) {
+    super(appView);
+    this.dexItemFactory = appView.dexItemFactory();
+  }
+
+  @Override
+  String getTimingId() {
+    return "ArrayConstructionSimplifier";
+  }
+
+  @Override
+  void rewriteCode(ProgramMethod method, IRCode code) {
+    WorkList<BasicBlock> worklist = WorkList.newIdentityWorkList(code.blocks);
+    while (worklist.hasNext()) {
+      BasicBlock block = worklist.next();
+      simplifyArrayConstructionBlock(block, worklist, code, appView.options());
+    }
+  }
+
+  @Override
+  boolean shouldRewriteCode(ProgramMethod method, IRCode code) {
+    return appView.options().isGeneratingDex();
+  }
+
+  private void simplifyArrayConstructionBlock(
+      BasicBlock block, WorkList<BasicBlock> worklist, IRCode code, InternalOptions options) {
+    RewriteArrayOptions rewriteOptions = options.rewriteArrayOptions();
+    InstructionListIterator it = block.listIterator(code);
+    while (it.hasNext()) {
+      FilledArrayCandidate candidate = computeFilledArrayCandidate(it.next(), rewriteOptions);
+      if (candidate == null) {
+        continue;
+      }
+      FilledArrayConversionInfo info =
+          computeConversionInfo(
+              candidate, new LinearFlowInstructionListIterator(code, block, it.nextIndex()));
+      if (info == null) {
+        continue;
+      }
+
+      Instruction instructionAfterCandidate = it.peekNext();
+      NewArrayEmpty newArrayEmpty = candidate.newArrayEmpty;
+      DexType arrayType = newArrayEmpty.type;
+      int size = candidate.size;
+      Set<Instruction> instructionsToRemove = SetUtils.newIdentityHashSet(size + 1);
+      if (candidate.useFilledNewArray()) {
+        assert newArrayEmpty.getLocalInfo() == null;
+        Instruction lastArrayPut = info.lastArrayPutIterator.peekPrevious();
+        Value invokeValue = code.createValue(newArrayEmpty.getOutType(), null);
+        InvokeNewArray invoke =
+            new InvokeNewArray(arrayType, invokeValue, Arrays.asList(info.values));
+        invoke.setPosition(lastArrayPut.getPosition());
+        for (Value value : newArrayEmpty.inValues()) {
+          value.removeUser(newArrayEmpty);
+        }
+        newArrayEmpty.outValue().replaceUsers(invokeValue);
+        instructionsToRemove.add(newArrayEmpty);
+
+        boolean originalAllocationPointHasHandlers = block.hasCatchHandlers();
+        boolean insertionPointHasHandlers = lastArrayPut.getBlock().hasCatchHandlers();
+
+        if (!insertionPointHasHandlers && !originalAllocationPointHasHandlers) {
+          info.lastArrayPutIterator.add(invoke);
+        } else {
+          BasicBlock insertionBlock = info.lastArrayPutIterator.split(code);
+          if (originalAllocationPointHasHandlers) {
+            if (!insertionBlock.isTrivialGoto()) {
+              BasicBlock blockAfterInsertion = insertionBlock.listIterator(code).split(code);
+              assert insertionBlock.isTrivialGoto();
+              worklist.addIfNotSeen(blockAfterInsertion);
+            }
+            insertionBlock.moveCatchHandlers(block);
+          } else {
+            worklist.addIfNotSeen(insertionBlock);
+          }
+          insertionBlock.listIterator(code).add(invoke);
+        }
+      } else {
+        assert candidate.useFilledArrayData();
+        int elementSize = arrayType.elementSizeForPrimitiveArrayType();
+        short[] contents = computeArrayFilledData(info.values, size, elementSize);
+        if (contents == null) {
+          continue;
+        }
+        // fill-array-data requires the new-array-empty instruction to remain, as it does not
+        // itself create an array.
+        NewArrayFilledData fillArray =
+            new NewArrayFilledData(newArrayEmpty.outValue(), elementSize, size, contents);
+        fillArray.setPosition(newArrayEmpty.getPosition());
+        BasicBlock newBlock =
+            it.addThrowingInstructionToPossiblyThrowingBlock(code, null, fillArray, options);
+        if (newBlock != null) {
+          worklist.addIfNotSeen(newBlock);
+        }
+      }
+
+      instructionsToRemove.addAll(info.arrayPutsToRemove);
+      Set<BasicBlock> visitedBlocks = Sets.newIdentityHashSet();
+      for (Instruction instruction : instructionsToRemove) {
+        BasicBlock ownerBlock = instruction.getBlock();
+        // If owner block is null, then the instruction has been removed already. We can't rely on
+        // just having the block pointer nulled, so the visited blocks guards reprocessing.
+        if (ownerBlock != null && visitedBlocks.add(ownerBlock)) {
+          InstructionListIterator removeIt = ownerBlock.listIterator(code);
+          while (removeIt.hasNext()) {
+            if (instructionsToRemove.contains(removeIt.next())) {
+              removeIt.removeOrReplaceByDebugLocalRead();
+            }
+          }
+        }
+      }
+
+      // The above has invalidated the block iterator so reset it and continue.
+      it = block.listIterator(code, instructionAfterCandidate);
+    }
+  }
+
+  private short[] computeArrayFilledData(Value[] values, int size, int elementSize) {
+    for (Value v : values) {
+      if (!v.isConstant()) {
+        return null;
+      }
+    }
+    if (elementSize == 1) {
+      short[] result = new short[(size + 1) / 2];
+      for (int i = 0; i < size; i += 2) {
+        short value =
+            (short) (values[i].getConstInstruction().asConstNumber().getIntValue() & 0xFF);
+        if (i + 1 < size) {
+          value |=
+              (short)
+                  ((values[i + 1].getConstInstruction().asConstNumber().getIntValue() & 0xFF) << 8);
+        }
+        result[i / 2] = value;
+      }
+      return result;
+    }
+    assert elementSize == 2 || elementSize == 4 || elementSize == 8;
+    int shortsPerConstant = elementSize / 2;
+    short[] result = new short[size * shortsPerConstant];
+    for (int i = 0; i < size; i++) {
+      long value = values[i].getConstInstruction().asConstNumber().getRawValue();
+      for (int part = 0; part < shortsPerConstant; part++) {
+        result[i * shortsPerConstant + part] = (short) ((value >> (16 * part)) & 0xFFFFL);
+      }
+    }
+    return result;
+  }
+
+  private static class FilledArrayConversionInfo {
+
+    Value[] values;
+    List<ArrayPut> arrayPutsToRemove;
+    LinearFlowInstructionListIterator lastArrayPutIterator;
+
+    public FilledArrayConversionInfo(int size) {
+      values = new Value[size];
+      arrayPutsToRemove = new ArrayList<>(size);
+    }
+  }
+
+  private FilledArrayConversionInfo computeConversionInfo(
+      FilledArrayCandidate candidate, LinearFlowInstructionListIterator it) {
+    NewArrayEmpty newArrayEmpty = candidate.newArrayEmpty;
+    assert it.peekPrevious() == newArrayEmpty;
+    Value arrayValue = newArrayEmpty.outValue();
+    int size = candidate.size;
+
+    // aput-object allows any object for arrays of interfaces, but new-filled-array fails to verify
+    // if types require a cast.
+    // TODO(b/246971330): Check if adding a checked-cast would have the same observable result. E.g.
+    //   if aput-object throws a ClassCastException if given an object that does not implement the
+    //   desired interface, then we could add check-cast instructions for arguments we're not sure
+    //   about.
+    DexType elementType = newArrayEmpty.type.toDimensionMinusOneType(dexItemFactory);
+    boolean needsTypeCheck =
+        !elementType.isPrimitiveType() && elementType != dexItemFactory.objectType;
+
+    FilledArrayConversionInfo info = new FilledArrayConversionInfo(size);
+    Value[] values = info.values;
+    int remaining = size;
+    Set<Instruction> users = newArrayEmpty.outValue().uniqueUsers();
+    while (it.hasNext()) {
+      Instruction instruction = it.next();
+      BasicBlock block = instruction.getBlock();
+      // If we encounter an instruction that can throw an exception we need to bail out of the
+      // optimization so that we do not transform half-initialized arrays into fully initialized
+      // arrays on exceptional edges. If the block has no handlers it is not observable so
+      // we perform the rewriting.
+      if (block.hasCatchHandlers() && instruction.instructionInstanceCanThrow()) {
+        return null;
+      }
+      if (!users.contains(instruction)) {
+        // If any instruction can transfer control between the new-array and the last array put
+        // then it is not safe to move the new array to the point of the last put.
+        if (block.hasCatchHandlers() && instruction.instructionTypeCanThrow()) {
+          return null;
+        }
+        continue;
+      }
+      ArrayPut arrayPut = instruction.asArrayPut();
+      // If the initialization sequence is broken by another use we cannot use a fill-array-data
+      // instruction.
+      if (arrayPut == null || arrayPut.array() != arrayValue) {
+        return null;
+      }
+      if (!arrayPut.index().isConstNumber()) {
+        return null;
+      }
+      if (arrayPut.instructionInstanceCanThrow()) {
+        assert false;
+        return null;
+      }
+      int index = arrayPut.index().getConstInstruction().asConstNumber().getIntValue();
+      if (index < 0 || index >= values.length) {
+        return null;
+      }
+      if (values[index] != null) {
+        return null;
+      }
+      Value value = arrayPut.value();
+      if (needsTypeCheck && !value.isAlwaysNull(appView)) {
+        DexType valueDexType = value.getType().asReferenceType().toDexType(dexItemFactory);
+        if (elementType.isArrayType()) {
+          if (elementType != valueDexType) {
+            return null;
+          }
+        } else if (valueDexType.isArrayType()) {
+          // isSubtype asserts for this case.
+          return null;
+        } else if (valueDexType.isNullValueType()) {
+          // Assume instructions can cause value.isAlwaysNull() == false while the DexType is null.
+          // TODO(b/246971330): Figure out how to write a test in SimplifyArrayConstructionTest
+          //   that hits this case.
+        } else {
+          // TODO(b/246971330): When in d8 mode, we might still be able to see if this is true for
+          //   library types (which this helper does not do).
+          if (appView.isSubtype(valueDexType, elementType).isPossiblyFalse()) {
+            return null;
+          }
+        }
+      }
+      info.arrayPutsToRemove.add(arrayPut);
+      values[index] = value;
+      --remaining;
+      if (remaining == 0) {
+        info.lastArrayPutIterator = it;
+        return info;
+      }
+    }
+    return null;
+  }
+
+  private static class FilledArrayCandidate {
+
+    final NewArrayEmpty newArrayEmpty;
+    final int size;
+    final boolean encodeAsFilledNewArray;
+
+    public FilledArrayCandidate(
+        NewArrayEmpty newArrayEmpty, int size, boolean encodeAsFilledNewArray) {
+      assert size > 0;
+      this.newArrayEmpty = newArrayEmpty;
+      this.size = size;
+      this.encodeAsFilledNewArray = encodeAsFilledNewArray;
+    }
+
+    public boolean useFilledNewArray() {
+      return encodeAsFilledNewArray;
+    }
+
+    public boolean useFilledArrayData() {
+      return !useFilledNewArray();
+    }
+  }
+
+  private FilledArrayCandidate computeFilledArrayCandidate(
+      Instruction instruction, RewriteArrayOptions options) {
+    NewArrayEmpty newArrayEmpty = instruction.asNewArrayEmpty();
+    if (newArrayEmpty == null) {
+      return null;
+    }
+    if (instruction.getLocalInfo() != null) {
+      return null;
+    }
+    if (!newArrayEmpty.size().isConstant()) {
+      return null;
+    }
+    int size = newArrayEmpty.size().getConstInstruction().asConstNumber().getIntValue();
+    if (!options.isPotentialSize(size)) {
+      return null;
+    }
+    DexType arrayType = newArrayEmpty.type;
+    boolean encodeAsFilledNewArray = canUseFilledNewArray(arrayType, size, options);
+    if (!encodeAsFilledNewArray && !canUseFilledArrayData(arrayType, size, options)) {
+      return null;
+    }
+    // Check that all arguments to the array is the array type or that the array is type Object[].
+    if (!options.canUseSubTypesInFilledNewArray()
+        && arrayType != dexItemFactory.objectArrayType
+        && !arrayType.isPrimitiveArrayType()) {
+      DexType elementType = arrayType.toArrayElementType(dexItemFactory);
+      for (Instruction uniqueUser : newArrayEmpty.outValue().uniqueUsers()) {
+        if (uniqueUser.isArrayPut()
+            && uniqueUser.asArrayPut().array() == newArrayEmpty.outValue()
+            && !checkTypeOfArrayPut(uniqueUser.asArrayPut(), elementType)) {
+          return null;
+        }
+      }
+    }
+    return new FilledArrayCandidate(newArrayEmpty, size, encodeAsFilledNewArray);
+  }
+
+  private boolean checkTypeOfArrayPut(ArrayPut arrayPut, DexType elementType) {
+    TypeElement valueType = arrayPut.value().getType();
+    if (!valueType.isPrimitiveType() && elementType == dexItemFactory.objectType) {
+      return true;
+    }
+    if (valueType.isNullType() && !elementType.isPrimitiveType()) {
+      return true;
+    }
+    if (elementType.isArrayType()) {
+      if (valueType.isNullType()) {
+        return true;
+      }
+      ArrayTypeElement arrayTypeElement = valueType.asArrayType();
+      if (arrayTypeElement == null
+          || arrayTypeElement.getNesting() != elementType.getNumberOfLeadingSquareBrackets()) {
+        return false;
+      }
+      valueType = arrayTypeElement.getBaseType();
+      elementType = elementType.toBaseType(dexItemFactory);
+    }
+    assert !valueType.isArrayType();
+    assert !elementType.isArrayType();
+    if (valueType.isPrimitiveType() && !elementType.isPrimitiveType()) {
+      return false;
+    }
+    if (valueType.isPrimitiveType()) {
+      return true;
+    }
+    DexClass clazz = appView.definitionFor(elementType);
+    if (clazz == null) {
+      return false;
+    }
+    return clazz.isInterface() || valueType.isClassType(elementType);
+  }
+
+  private boolean canUseFilledNewArray(DexType arrayType, int size, RewriteArrayOptions options) {
+    if (size < options.minSizeForFilledNewArray) {
+      return false;
+    }
+    // filled-new-array is implemented only for int[] and Object[].
+    // For int[], using filled-new-array is usually smaller than filled-array-data.
+    // filled-new-array supports up to 5 registers before it's filled-new-array/range.
+    if (!arrayType.isPrimitiveArrayType()) {
+      if (size > options.maxSizeForFilledNewArrayOfReferences) {
+        return false;
+      }
+      if (arrayType == dexItemFactory.stringArrayType) {
+        return options.canUseFilledNewArrayOfStrings();
+      }
+      if (!options.canUseFilledNewArrayOfNonStringObjects()) {
+        return false;
+      }
+      if (!options.canUseFilledNewArrayOfArrays()
+          && arrayType.getNumberOfLeadingSquareBrackets() > 1) {
+        return false;
+      }
+      return true;
+    }
+    if (arrayType == dexItemFactory.intArrayType) {
+      return size <= options.maxSizeForFilledNewArrayOfInts;
+    }
+    return false;
+  }
+
+  private boolean canUseFilledArrayData(DexType arrayType, int size, RewriteArrayOptions options) {
+    // If there is only one element it is typically smaller to generate the array put
+    // instruction instead of fill array data.
+    if (size < options.minSizeForFilledArrayData || size > options.maxSizeForFilledArrayData) {
+      return false;
+    }
+    return arrayType.isPrimitiveArrayType();
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/BranchSimplifier.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/BranchSimplifier.java
new file mode 100644
index 0000000..199df62
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/BranchSimplifier.java
@@ -0,0 +1,1231 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.conversion.passes;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.FieldResolutionResult.SingleProgramFieldResolutionResult;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerUtils;
+import com.android.tools.r8.ir.analysis.equivalence.BasicBlockBehavioralSubsumption;
+import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
+import com.android.tools.r8.ir.analysis.value.AbstractValue;
+import com.android.tools.r8.ir.analysis.value.ConstantOrNonConstantNumberValue;
+import com.android.tools.r8.ir.analysis.value.SingleConstClassValue;
+import com.android.tools.r8.ir.analysis.value.SingleFieldValue;
+import com.android.tools.r8.ir.code.BasicBlock;
+import com.android.tools.r8.ir.code.ConstNumber;
+import com.android.tools.r8.ir.code.Goto;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.IRMetadata;
+import com.android.tools.r8.ir.code.If;
+import com.android.tools.r8.ir.code.IfType;
+import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionIterator;
+import com.android.tools.r8.ir.code.InstructionListIterator;
+import com.android.tools.r8.ir.code.IntSwitch;
+import com.android.tools.r8.ir.code.NumericType;
+import com.android.tools.r8.ir.code.Phi;
+import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Switch;
+import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.code.ValueType;
+import com.android.tools.r8.ir.code.Xor;
+import com.android.tools.r8.ir.optimize.controlflow.SwitchCaseAnalyzer;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.InternalOutputMode;
+import com.android.tools.r8.utils.LongInterval;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntIterator;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+public class BranchSimplifier {
+
+  private final AppView<?> appView;
+  private final InternalOptions options;
+
+  public BranchSimplifier(AppView<?> appView) {
+    this.appView = appView;
+    this.options = appView.options();
+  }
+
+  public boolean simplifyBranches(IRCode code) {
+    boolean anyAffectedValues = rewriteSwitch(code);
+    anyAffectedValues |= simplifyIf(code).anyAffectedValues();
+    return anyAffectedValues;
+  }
+
+  public ControlFlowSimplificationResult simplifyIf(IRCode code) {
+    BasicBlockBehavioralSubsumption behavioralSubsumption =
+        new BasicBlockBehavioralSubsumption(appView, code);
+    boolean simplified = false;
+    for (BasicBlock block : code.blocks) {
+      // Skip removed (= unreachable) blocks.
+      if (block.getNumber() != 0 && block.getPredecessors().isEmpty()) {
+        continue;
+      }
+      if (block.exit().isIf()) {
+        flipIfBranchesIfNeeded(code, block);
+        if (rewriteIfWithConstZero(code, block)) {
+          simplified = true;
+        }
+
+        if (simplifyKnownBooleanCondition(code, block)) {
+          simplified = true;
+          if (!block.exit().isIf()) {
+            continue;
+          }
+        }
+
+        // Simplify if conditions when possible.
+        If theIf = block.exit().asIf();
+        if (theIf.isZeroTest()) {
+          if (simplifyIfZeroTest(code, block, theIf)) {
+            simplified = true;
+            continue;
+          }
+        } else {
+          if (simplifyNonIfZeroTest(code, block, theIf)) {
+            simplified = true;
+            continue;
+          }
+        }
+
+        // Unable to determine which branch will be taken. Check if the true target can safely be
+        // rewritten to the false target.
+        if (behavioralSubsumption.isSubsumedBy(
+            theIf.inValues().get(0), theIf.getTrueTarget(), theIf.fallthroughBlock())) {
+          simplifyIfWithKnownCondition(code, block, theIf, theIf.fallthroughBlock());
+          simplified = true;
+        }
+      }
+    }
+    Set<Value> affectedValues = code.removeUnreachableBlocks();
+    if (!affectedValues.isEmpty()) {
+      new TypeAnalysis(appView).narrowing(affectedValues);
+    }
+    assert code.isConsistentSSA(appView);
+    return new ControlFlowSimplificationResult(!affectedValues.isEmpty(), simplified);
+  }
+
+  public static class ControlFlowSimplificationResult {
+
+    private final boolean anyAffectedValues;
+    private final boolean anySimplifications;
+
+    private ControlFlowSimplificationResult(boolean anyAffectedValues, boolean anySimplifications) {
+      assert !anyAffectedValues || anySimplifications;
+      this.anyAffectedValues = anyAffectedValues;
+      this.anySimplifications = anySimplifications;
+    }
+
+    public boolean anyAffectedValues() {
+      return anyAffectedValues;
+    }
+
+    public boolean anySimplifications() {
+      return anySimplifications;
+    }
+  }
+
+  private boolean simplifyIfZeroTest(IRCode code, BasicBlock block, If theIf) {
+    Value lhs = theIf.lhs();
+    Value lhsRoot = lhs.getAliasedValue();
+    if (lhsRoot.isConstNumber()) {
+      ConstNumber cond = lhsRoot.getConstInstruction().asConstNumber();
+      BasicBlock target = theIf.targetFromCondition(cond);
+      simplifyIfWithKnownCondition(code, block, theIf, target);
+      return true;
+    }
+
+    if (theIf.isNullTest()) {
+      assert theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE;
+
+      if (lhs.isAlwaysNull(appView)) {
+        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromNullObject());
+        return true;
+      }
+
+      if (lhs.isNeverNull()) {
+        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromNonNullObject());
+        return true;
+      }
+    }
+
+    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
+      AbstractValue lhsAbstractValue = lhs.getAbstractValue(appView, code.context());
+      if (lhsAbstractValue.isConstantOrNonConstantNumberValue()
+          && !lhsAbstractValue.asConstantOrNonConstantNumberValue().containsInt(0)) {
+        // Value doesn't contain zero at all.
+        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(1));
+        return true;
+      }
+    }
+
+    if (lhs.hasValueRange()) {
+      LongInterval interval = lhs.getValueRange();
+      if (!interval.containsValue(0)) {
+        // Interval doesn't contain zero at all.
+        int sign = Long.signum(interval.getMin());
+        simplifyIfWithKnownCondition(code, block, theIf, sign);
+        return true;
+      }
+
+      // Interval contains zero.
+      switch (theIf.getType()) {
+        case GE:
+        case LT:
+          // [a, b] >= 0 is always true if a >= 0.
+          // [a, b] < 0 is always false if a >= 0.
+          // In both cases a zero condition takes the right branch.
+          if (interval.getMin() == 0) {
+            simplifyIfWithKnownCondition(code, block, theIf, 0);
+            return true;
+          }
+          break;
+
+        case LE:
+        case GT:
+          // [a, b] <= 0 is always true if b <= 0.
+          // [a, b] > 0 is always false if b <= 0.
+          // In both cases a zero condition takes the right branch.
+          if (interval.getMax() == 0) {
+            simplifyIfWithKnownCondition(code, block, theIf, 0);
+            return true;
+          }
+          break;
+
+        case EQ:
+        case NE:
+          // Only a single element interval [0, 0] can be dealt with here.
+          // Such intervals should have been replaced by constants.
+          assert !interval.isSingleValue();
+          break;
+      }
+    }
+    return false;
+  }
+
+  private boolean simplifyNonIfZeroTest(IRCode code, BasicBlock block, If theIf) {
+    Value lhs = theIf.lhs();
+    Value lhsRoot = lhs.getAliasedValue();
+    Value rhs = theIf.rhs();
+    Value rhsRoot = rhs.getAliasedValue();
+    if (lhsRoot == rhsRoot) {
+      // Comparing the same value.
+      simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(0));
+      return true;
+    }
+
+    if (lhsRoot.isDefinedByInstructionSatisfying(Instruction::isCreatingInstanceOrArray)
+        && rhsRoot.isDefinedByInstructionSatisfying(Instruction::isCreatingInstanceOrArray)) {
+      // Comparing two newly created objects.
+      assert theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE;
+      simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(1));
+      return true;
+    }
+
+    if (lhsRoot.isConstNumber() && rhsRoot.isConstNumber()) {
+      // Zero test with a constant of comparison between between two constants.
+      ConstNumber left = lhsRoot.getConstInstruction().asConstNumber();
+      ConstNumber right = rhsRoot.getConstInstruction().asConstNumber();
+      BasicBlock target = theIf.targetFromCondition(left, right);
+      simplifyIfWithKnownCondition(code, block, theIf, target);
+      return true;
+    }
+
+    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
+      AbstractValue lhsAbstractValue = lhs.getAbstractValue(appView, code.context());
+      AbstractValue rhsAbstractValue = rhs.getAbstractValue(appView, code.context());
+      if (lhsAbstractValue.isConstantOrNonConstantNumberValue()
+          && rhsAbstractValue.isConstantOrNonConstantNumberValue()) {
+        ConstantOrNonConstantNumberValue lhsNumberValue =
+            lhsAbstractValue.asConstantOrNonConstantNumberValue();
+        ConstantOrNonConstantNumberValue rhsNumberValue =
+            rhsAbstractValue.asConstantOrNonConstantNumberValue();
+        if (!lhsNumberValue.mayOverlapWith(rhsNumberValue)) {
+          // No overlap.
+          simplifyIfWithKnownCondition(code, block, theIf, 1);
+          return true;
+        }
+      }
+    }
+
+    if (lhs.hasValueRange() && rhs.hasValueRange()) {
+      // Zero test with a value range, or comparison between between two values,
+      // each with a value ranges.
+      LongInterval leftRange = lhs.getValueRange();
+      LongInterval rightRange = rhs.getValueRange();
+      // Two overlapping ranges. Check for single point overlap.
+      if (!leftRange.overlapsWith(rightRange)) {
+        // No overlap.
+        int cond = Long.signum(leftRange.getMin() - rightRange.getMin());
+        simplifyIfWithKnownCondition(code, block, theIf, cond);
+        return true;
+      }
+
+      // The two intervals overlap. We can simplify if they overlap at the end points.
+      switch (theIf.getType()) {
+        case LT:
+        case GE:
+          // [a, b] < [c, d] is always false when a == d.
+          // [a, b] >= [c, d] is always true when a == d.
+          // In both cases 0 condition will choose the right branch.
+          if (leftRange.getMin() == rightRange.getMax()) {
+            simplifyIfWithKnownCondition(code, block, theIf, 0);
+            return true;
+          }
+          break;
+        case GT:
+        case LE:
+          // [a, b] > [c, d] is always false when b == c.
+          // [a, b] <= [c, d] is always true when b == c.
+          // In both cases 0 condition will choose the right branch.
+          if (leftRange.getMax() == rightRange.getMin()) {
+            simplifyIfWithKnownCondition(code, block, theIf, 0);
+            return true;
+          }
+          break;
+        case EQ:
+        case NE:
+          // Since there is overlap EQ and NE cannot be determined.
+          break;
+      }
+    }
+
+    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
+      ProgramMethod context = code.context();
+      AbstractValue abstractValue = lhs.getAbstractValue(appView, context);
+      if (abstractValue.isSingleConstClassValue()) {
+        AbstractValue otherAbstractValue = rhs.getAbstractValue(appView, context);
+        if (otherAbstractValue.isSingleConstClassValue()) {
+          SingleConstClassValue singleConstClassValue = abstractValue.asSingleConstClassValue();
+          SingleConstClassValue otherSingleConstClassValue =
+              otherAbstractValue.asSingleConstClassValue();
+          simplifyIfWithKnownCondition(
+              code,
+              block,
+              theIf,
+              BooleanUtils.intValue(
+                  singleConstClassValue.getType() != otherSingleConstClassValue.getType()));
+          return true;
+        }
+        return false;
+      }
+
+      if (abstractValue.isSingleFieldValue()) {
+        AbstractValue otherAbstractValue = rhs.getAbstractValue(appView, context);
+        if (otherAbstractValue.isSingleFieldValue()) {
+          SingleFieldValue singleFieldValue = abstractValue.asSingleFieldValue();
+          SingleFieldValue otherSingleFieldValue = otherAbstractValue.asSingleFieldValue();
+          if (singleFieldValue.getField() == otherSingleFieldValue.getField()) {
+            simplifyIfWithKnownCondition(code, block, theIf, 0);
+            return true;
+          }
+
+          DexClass holder = appView.definitionForHolder(singleFieldValue.getField());
+          DexEncodedField field = singleFieldValue.getField().lookupOnClass(holder);
+          if (field != null && field.isEnum()) {
+            DexClass otherHolder = appView.definitionForHolder(otherSingleFieldValue.getField());
+            DexEncodedField otherField =
+                otherSingleFieldValue.getField().lookupOnClass(otherHolder);
+            if (otherField != null && otherField.isEnum()) {
+              simplifyIfWithKnownCondition(code, block, theIf, 1);
+              return true;
+            }
+          }
+        }
+      }
+    }
+
+    return false;
+  }
+
+  private void simplifyIfWithKnownCondition(
+      IRCode code, BasicBlock block, If theIf, BasicBlock target) {
+    BasicBlock deadTarget =
+        target == theIf.getTrueTarget() ? theIf.fallthroughBlock() : theIf.getTrueTarget();
+    rewriteIfToGoto(code, block, theIf, target, deadTarget);
+  }
+
+  private void simplifyIfWithKnownCondition(IRCode code, BasicBlock block, If theIf, int cond) {
+    simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(cond));
+  }
+
+  /* Identify simple diamond shapes converting boolean true/false to 1/0. We consider the forms:
+   *
+   * (1)
+   *
+   *      [dbg pos x]             [dbg pos x]
+   *   ifeqz booleanValue       ifnez booleanValue
+   *      /        \              /        \
+   * [dbg pos x][dbg pos x]  [dbg pos x][dbg pos x]
+   *  [const 0]  [const 1]    [const 1]  [const 0]
+   *    goto      goto          goto      goto
+   *      \        /              \        /
+   *      phi(0, 1)                phi(1, 0)
+   *
+   * which can be replaced by a fallthrough and the phi value can be replaced
+   * with the boolean value itself.
+   *
+   * (2)
+   *
+   *      [dbg pos x]              [dbg pos x]
+   *    ifeqz booleanValue       ifnez booleanValue
+   *      /        \              /        \
+   * [dbg pos x][dbg pos x]  [dbg pos x][dbg pos x]
+   *  [const 1]  [const 0]   [const 0]  [const 1]
+   *    goto      goto          goto      goto
+   *      \        /              \        /
+   *      phi(1, 0)                phi(0, 1)
+   *
+   * which can be replaced by a fallthrough and the phi value can be replaced
+   * by an xor instruction which is smaller.
+   */
+  private boolean simplifyKnownBooleanCondition(IRCode code, BasicBlock block) {
+    If theIf = block.exit().asIf();
+    Value testValue = theIf.inValues().get(0);
+    if (theIf.isZeroTest() && testValue.knownToBeBoolean()) {
+      BasicBlock trueBlock = theIf.getTrueTarget();
+      BasicBlock falseBlock = theIf.fallthroughBlock();
+      if (isBlockSupportedBySimplifyKnownBooleanCondition(trueBlock)
+          && isBlockSupportedBySimplifyKnownBooleanCondition(falseBlock)
+          && trueBlock.getSuccessors().get(0) == falseBlock.getSuccessors().get(0)) {
+        BasicBlock targetBlock = trueBlock.getSuccessors().get(0);
+        if (targetBlock.getPredecessors().size() == 2) {
+          int trueIndex = targetBlock.getPredecessors().indexOf(trueBlock);
+          int falseIndex = trueIndex == 0 ? 1 : 0;
+          int deadPhis = 0;
+          // Locate the phis that have the same value as the boolean and replace them
+          // by the boolean in all users.
+          for (Phi phi : targetBlock.getPhis()) {
+            Value trueValue = phi.getOperand(trueIndex);
+            Value falseValue = phi.getOperand(falseIndex);
+            if (trueValue.isConstNumber() && falseValue.isConstNumber()) {
+              ConstNumber trueNumber = trueValue.getConstInstruction().asConstNumber();
+              ConstNumber falseNumber = falseValue.getConstInstruction().asConstNumber();
+              if ((theIf.getType() == IfType.EQ
+                      && trueNumber.isIntegerZero()
+                      && falseNumber.isIntegerOne())
+                  || (theIf.getType() == IfType.NE
+                      && trueNumber.isIntegerOne()
+                      && falseNumber.isIntegerZero())) {
+                phi.replaceUsers(testValue);
+                deadPhis++;
+              } else if ((theIf.getType() == IfType.NE
+                      && trueNumber.isIntegerZero()
+                      && falseNumber.isIntegerOne())
+                  || (theIf.getType() == IfType.EQ
+                      && trueNumber.isIntegerOne()
+                      && falseNumber.isIntegerZero())) {
+                Value newOutValue = code.createValue(phi.getType(), phi.getLocalInfo());
+                ConstNumber cstToUse = trueNumber.isIntegerOne() ? trueNumber : falseNumber;
+                BasicBlock phiBlock = phi.getBlock();
+                Position phiPosition = phiBlock.getPosition();
+                int insertIndex = 0;
+                if (cstToUse.getBlock() == trueBlock || cstToUse.getBlock() == falseBlock) {
+                  // The constant belongs to the block to remove, create a new one.
+                  cstToUse = ConstNumber.copyOf(code, cstToUse);
+                  cstToUse.setBlock(phiBlock);
+                  cstToUse.setPosition(phiPosition);
+                  phiBlock.getInstructions().add(insertIndex++, cstToUse);
+                }
+                phi.replaceUsers(newOutValue);
+                Instruction newInstruction =
+                    Xor.create(NumericType.INT, newOutValue, testValue, cstToUse.outValue());
+                newInstruction.setBlock(phiBlock);
+                // The xor is replacing a phi so it does not have an actual position.
+                newInstruction.setPosition(phiPosition);
+                phiBlock.listIterator(code, insertIndex).add(newInstruction);
+                deadPhis++;
+              }
+            }
+          }
+          // If all phis were removed, there is no need for the diamond shape anymore
+          // and it can be rewritten to a goto to one of the branches.
+          if (deadPhis == targetBlock.getPhis().size()) {
+            rewriteIfToGoto(code, block, theIf, trueBlock, falseBlock);
+            return true;
+          }
+          return deadPhis > 0;
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean isBlockSupportedBySimplifyKnownBooleanCondition(BasicBlock b) {
+    if (b.isTrivialGoto()) {
+      return true;
+    }
+
+    int instructionSize = b.getInstructions().size();
+    if (b.exit().isGoto() && (instructionSize == 2 || instructionSize == 3)) {
+      Instruction constInstruction = b.getInstructions().get(instructionSize - 2);
+      if (constInstruction.isConstNumber()) {
+        if (!constInstruction.asConstNumber().isIntegerOne()
+            && !constInstruction.asConstNumber().isIntegerZero()) {
+          return false;
+        }
+        if (instructionSize == 2) {
+          return true;
+        }
+        Instruction firstInstruction = b.getInstructions().getFirst();
+        if (firstInstruction.isDebugPosition()) {
+          assert b.getPredecessors().size() == 1;
+          BasicBlock predecessorBlock = b.getPredecessors().get(0);
+          InstructionIterator it = predecessorBlock.iterator(predecessorBlock.exit());
+          Instruction previousPosition = null;
+          while (it.hasPrevious() && !(previousPosition = it.previous()).isDebugPosition()) {
+            // Intentionally empty.
+          }
+          if (previousPosition != null) {
+            return previousPosition.getPosition() == firstInstruction.getPosition();
+          }
+        }
+      }
+    }
+
+    return false;
+  }
+
+  private void rewriteIfToGoto(
+      IRCode code, BasicBlock block, If theIf, BasicBlock target, BasicBlock deadTarget) {
+    deadTarget.unlinkSinglePredecessorSiblingsAllowed();
+    assert theIf == block.exit();
+    block.replaceLastInstruction(new Goto(), code);
+    assert block.exit().isGoto();
+    assert block.exit().asGoto().getTarget() == target;
+  }
+
+  private boolean rewriteIfWithConstZero(IRCode code, BasicBlock block) {
+    If theIf = block.exit().asIf();
+    if (theIf.isZeroTest()) {
+      return false;
+    }
+
+    Value leftValue = theIf.lhs();
+    Value rightValue = theIf.rhs();
+    if (leftValue.isConstNumber() || rightValue.isConstNumber()) {
+      if (leftValue.isConstNumber()) {
+        if (leftValue.getConstInstruction().asConstNumber().isZero()) {
+          If ifz = new If(theIf.getType().forSwappedOperands(), rightValue);
+          block.replaceLastInstruction(ifz, code);
+          assert block.exit() == ifz;
+          return true;
+        }
+      } else if (rightValue.getConstInstruction().asConstNumber().isZero()) {
+        If ifz = new If(theIf.getType(), leftValue);
+        block.replaceLastInstruction(ifz, code);
+        assert block.exit() == ifz;
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  private boolean flipIfBranchesIfNeeded(IRCode code, BasicBlock block) {
+    If theIf = block.exit().asIf();
+    BasicBlock trueTarget = theIf.getTrueTarget();
+    BasicBlock fallthrough = theIf.fallthroughBlock();
+    assert trueTarget != fallthrough;
+
+    if (!fallthrough.isSimpleAlwaysThrowingPath() || trueTarget.isSimpleAlwaysThrowingPath()) {
+      return false;
+    }
+
+    // In case fall-through block always throws there is a good chance that it
+    // is created for error checks and 'trueTarget' represents most more common
+    // non-error case. Flipping the if in this case may result in faster code
+    // on older Android versions.
+    List<Value> inValues = theIf.inValues();
+    If newIf = new If(theIf.getType().inverted(), inValues);
+    block.replaceLastInstruction(newIf, code);
+    block.swapSuccessors(trueTarget, fallthrough);
+    return true;
+  }
+
+  private boolean rewriteSwitch(IRCode code) {
+    return rewriteSwitch(code, SwitchCaseAnalyzer.getInstance());
+  }
+
+  private boolean rewriteSwitch(IRCode code, SwitchCaseAnalyzer switchCaseAnalyzer) {
+    if (!options.isSwitchRewritingEnabled()) {
+      return false;
+    }
+    if (!code.metadata().mayHaveSwitch()) {
+      return false;
+    }
+    return rewriteSwitchFull(code, switchCaseAnalyzer);
+  }
+
+  private boolean rewriteSwitchFull(IRCode code, SwitchCaseAnalyzer switchCaseAnalyzer) {
+    boolean needToRemoveUnreachableBlocks = false;
+    ListIterator<BasicBlock> blocksIterator = code.listIterator();
+    while (blocksIterator.hasNext()) {
+      BasicBlock block = blocksIterator.next();
+      InstructionListIterator iterator = block.listIterator(code);
+      while (iterator.hasNext()) {
+        Instruction instruction = iterator.next();
+        if (instruction.isSwitch()) {
+          Switch theSwitch = instruction.asSwitch();
+          if (options.testing.enableDeadSwitchCaseElimination) {
+            SwitchCaseEliminator eliminator =
+                removeUnnecessarySwitchCases(code, theSwitch, iterator, switchCaseAnalyzer);
+            if (eliminator.mayHaveIntroducedUnreachableBlocks()) {
+              needToRemoveUnreachableBlocks = true;
+            }
+
+            iterator.previous();
+            instruction = iterator.next();
+            if (instruction.isGoto()) {
+              continue;
+            }
+
+            assert instruction.isSwitch();
+            theSwitch = instruction.asSwitch();
+          }
+          if (theSwitch.isIntSwitch()) {
+            rewriteIntSwitch(code, blocksIterator, block, iterator, theSwitch.asIntSwitch());
+          }
+        }
+      }
+    }
+
+    // Rewriting of switches introduces new branching structure. It relies on critical edges
+    // being split on the way in but does not maintain this property. We therefore split
+    // critical edges at exit.
+    code.splitCriticalEdges();
+
+    Set<Value> affectedValues =
+        needToRemoveUnreachableBlocks ? code.removeUnreachableBlocks() : ImmutableSet.of();
+    if (!affectedValues.isEmpty()) {
+      new TypeAnalysis(appView).narrowing(affectedValues);
+    }
+    assert code.isConsistentSSA(appView);
+    return !affectedValues.isEmpty();
+  }
+
+  public void rewriteSingleKeySwitchToIf(
+      IRCode code, BasicBlock block, InstructionListIterator iterator, IntSwitch theSwitch) {
+    // Rewrite the switch to an if.
+    int fallthroughBlockIndex = theSwitch.getFallthroughBlockIndex();
+    int caseBlockIndex = theSwitch.targetBlockIndices()[0];
+    if (fallthroughBlockIndex < caseBlockIndex) {
+      block.swapSuccessorsByIndex(fallthroughBlockIndex, caseBlockIndex);
+    }
+    If replacement;
+    if (theSwitch.isIntSwitch() && theSwitch.asIntSwitch().getFirstKey() == 0) {
+      replacement = new If(IfType.EQ, theSwitch.value());
+    } else {
+      Instruction labelConst = theSwitch.materializeFirstKey(appView, code);
+      labelConst.setPosition(theSwitch.getPosition());
+      iterator.previous();
+      iterator.add(labelConst);
+      Instruction dummy = iterator.next();
+      assert dummy == theSwitch;
+      replacement = new If(IfType.EQ, ImmutableList.of(theSwitch.value(), labelConst.outValue()));
+    }
+    iterator.replaceCurrentInstruction(replacement);
+  }
+
+  private void rewriteIntSwitch(
+      IRCode code,
+      ListIterator<BasicBlock> blockIterator,
+      BasicBlock block,
+      InstructionListIterator iterator,
+      IntSwitch theSwitch) {
+    if (disableSwitchToIfRewritingForClassIdComparisons(theSwitch)) {
+      return;
+    }
+
+    if (theSwitch.numberOfKeys() == 1) {
+      rewriteSingleKeySwitchToIf(code, block, iterator, theSwitch);
+      return;
+    }
+
+    // If there are more than 1 key, we use the following algorithm to find keys to combine.
+    // First, scan through the keys forward and combine each packed interval with the
+    // previous interval if it gives a net saving.
+    // Secondly, go through all created intervals and combine the ones without a saving into
+    // a single interval and keep a max number of packed switches.
+    // Finally, go through all intervals and check if the switch or part of the switch
+    // should be transformed to ifs.
+
+    // Phase 1: Combine packed intervals.
+    InternalOutputMode mode = options.getInternalOutputMode();
+    int[] keys = theSwitch.getKeys();
+    int maxNumberOfIfsOrSwitches = 10;
+    PriorityQueue<Interval> biggestPackedSavings =
+        new PriorityQueue<>((x, y) -> Long.compare(y.packedSavings(mode), x.packedSavings(mode)));
+    Set<Interval> biggestPackedSet = new HashSet<>();
+    List<Interval> intervals = new ArrayList<>();
+    int previousKey = keys[0];
+    IntList currentKeys = new IntArrayList();
+    currentKeys.add(previousKey);
+    Interval previousInterval = null;
+    for (int i = 1; i < keys.length; i++) {
+      int key = keys[i];
+      if (((long) key - (long) previousKey) > 1) {
+        Interval current = new Interval(currentKeys);
+        Interval added = combineOrAddInterval(intervals, previousInterval, current);
+        if (added != current && biggestPackedSet.contains(previousInterval)) {
+          biggestPackedSet.remove(previousInterval);
+          biggestPackedSavings.remove(previousInterval);
+        }
+        tryAddToBiggestSavings(
+            biggestPackedSet, biggestPackedSavings, added, maxNumberOfIfsOrSwitches);
+        previousInterval = added;
+        currentKeys = new IntArrayList();
+      }
+      currentKeys.add(key);
+      previousKey = key;
+    }
+    Interval current = new Interval(currentKeys);
+    Interval added = combineOrAddInterval(intervals, previousInterval, current);
+    if (added != current && biggestPackedSet.contains(previousInterval)) {
+      biggestPackedSet.remove(previousInterval);
+      biggestPackedSavings.remove(previousInterval);
+    }
+    tryAddToBiggestSavings(biggestPackedSet, biggestPackedSavings, added, maxNumberOfIfsOrSwitches);
+
+    // Phase 2: combine sparse intervals into a single bin.
+    // Check if we should save a space for a sparse switch, if so, remove the switch with
+    // the smallest savings.
+    if (biggestPackedSet.size() == maxNumberOfIfsOrSwitches
+        && maxNumberOfIfsOrSwitches < intervals.size()) {
+      biggestPackedSet.remove(biggestPackedSavings.poll());
+    }
+    Interval sparse = null;
+    List<Interval> newSwitches = new ArrayList<>(maxNumberOfIfsOrSwitches);
+    for (int i = 0; i < intervals.size(); i++) {
+      Interval interval = intervals.get(i);
+      if (biggestPackedSet.contains(interval)) {
+        newSwitches.add(interval);
+      } else if (sparse == null) {
+        sparse = interval;
+        newSwitches.add(sparse);
+      } else {
+        sparse.addInterval(interval);
+      }
+    }
+
+    // Phase 3: at this point we are guaranteed to have the biggest saving switches
+    // in newIntervals, potentially with a switch combining the remaining intervals.
+    // Now we check to see if we can create any if's to reduce size.
+    IntList outliers = new IntArrayList();
+    int outliersAsIfSize =
+        options.testing.enableSwitchToIfRewriting
+            ? findIfsForCandidates(newSwitches, theSwitch, outliers)
+            : 0;
+
+    long newSwitchesSize = 0;
+    List<IntList> newSwitchSequences = new ArrayList<>(newSwitches.size());
+    for (Interval interval : newSwitches) {
+      newSwitchesSize += interval.estimatedSize(mode);
+      newSwitchSequences.add(interval.keys);
+    }
+
+    long currentSize = IntSwitch.estimatedSize(mode, theSwitch.getKeys());
+    if (newSwitchesSize + outliersAsIfSize + codeUnitMargin() < currentSize) {
+      convertSwitchToSwitchAndIfs(
+          code, blockIterator, block, iterator, theSwitch, newSwitchSequences, outliers);
+    }
+  }
+
+  // TODO(b/181732463): We currently disable switch-to-if rewritings for switches on $r8$classId
+  //  field values (from horizontal class merging. See bug for more details.
+  private boolean disableSwitchToIfRewritingForClassIdComparisons(IntSwitch theSwitch) {
+    Value switchValue = theSwitch.value().getAliasedValue();
+    if (!switchValue.isDefinedByInstructionSatisfying(Instruction::isInstanceGet)) {
+      return false;
+    }
+    AppInfoWithLiveness appInfo = appView.appInfoWithLiveness();
+    if (appInfo == null) {
+      return false;
+    }
+    InstanceGet instanceGet = switchValue.getDefinition().asInstanceGet();
+    SingleProgramFieldResolutionResult resolutionResult =
+        appInfo.resolveField(instanceGet.getField()).asSingleProgramFieldResolutionResult();
+    if (resolutionResult == null) {
+      return false;
+    }
+    DexEncodedField resolvedField = resolutionResult.getResolvedField();
+    return HorizontalClassMergerUtils.isClassIdField(appView, resolvedField);
+  }
+
+  private SwitchCaseEliminator removeUnnecessarySwitchCases(
+      IRCode code,
+      Switch theSwitch,
+      InstructionListIterator iterator,
+      SwitchCaseAnalyzer switchCaseAnalyzer) {
+    BasicBlock defaultTarget = theSwitch.fallthroughBlock();
+    SwitchCaseEliminator eliminator = new SwitchCaseEliminator(theSwitch, iterator);
+    BasicBlockBehavioralSubsumption behavioralSubsumption =
+        new BasicBlockBehavioralSubsumption(appView, code);
+
+    // Compute the set of switch cases that can be removed.
+    boolean hasSwitchCaseToDefaultRewrite = false;
+    AbstractValue switchAbstractValue = theSwitch.value().getAbstractValue(appView, code.context());
+    for (int i = 0; i < theSwitch.numberOfKeys(); i++) {
+      BasicBlock targetBlock = theSwitch.targetBlock(i);
+
+      if (switchCaseAnalyzer.switchCaseIsAlwaysHit(theSwitch, i)) {
+        eliminator.markSwitchCaseAsAlwaysHit(i);
+        break;
+      }
+
+      // This switch case can be removed if the behavior of the target block is equivalent to the
+      // behavior of the default block, or if the switch case is unreachable.
+      if (switchCaseAnalyzer.switchCaseIsUnreachable(theSwitch, switchAbstractValue, i)) {
+        eliminator.markSwitchCaseForRemoval(i);
+      } else if (behavioralSubsumption.isSubsumedBy(
+          theSwitch.value(), targetBlock, defaultTarget)) {
+        eliminator.markSwitchCaseForRemoval(i);
+        hasSwitchCaseToDefaultRewrite = true;
+      }
+    }
+
+    if (eliminator.isFallthroughLive()
+        && !hasSwitchCaseToDefaultRewrite
+        && switchCaseAnalyzer.switchFallthroughIsNeverHit(theSwitch, switchAbstractValue)) {
+      eliminator.markSwitchFallthroughAsNeverHit();
+    }
+
+    eliminator.optimize();
+    return eliminator;
+  }
+
+  private static class Interval {
+
+    private final IntList keys = new IntArrayList();
+
+    public Interval(IntList... allKeys) {
+      assert allKeys.length > 0;
+      for (IntList keys : allKeys) {
+        assert keys.size() > 0;
+        this.keys.addAll(keys);
+      }
+    }
+
+    public int getMin() {
+      return keys.getInt(0);
+    }
+
+    public int getMax() {
+      return keys.getInt(keys.size() - 1);
+    }
+
+    public void addInterval(Interval other) {
+      assert getMax() < other.getMin();
+      keys.addAll(other.keys);
+    }
+
+    public long packedSavings(InternalOutputMode mode) {
+      long packedTargets = (long) getMax() - (long) getMin() + 1;
+      if (!IntSwitch.canBePacked(mode, packedTargets)) {
+        return Long.MIN_VALUE + 1;
+      }
+      long sparseCost =
+          IntSwitch.baseSparseSize(mode) + IntSwitch.sparsePayloadSize(mode, keys.size());
+      long packedCost =
+          IntSwitch.basePackedSize(mode) + IntSwitch.packedPayloadSize(mode, packedTargets);
+      return sparseCost - packedCost;
+    }
+
+    public long estimatedSize(InternalOutputMode mode) {
+      return IntSwitch.estimatedSize(mode, keys.toIntArray());
+    }
+  }
+
+  private Interval combineOrAddInterval(
+      List<Interval> intervals, Interval previous, Interval current) {
+    // As a first iteration, we only combine intervals if their packed size is less than their
+    // sparse counterpart. In CF we will have to add a load and a jump which add to the
+    // stack map table (1 is the size of a same entry).
+    InternalOutputMode mode = options.getInternalOutputMode();
+    int penalty = mode.isGeneratingClassFiles() ? 3 + 1 : 0;
+    if (previous == null) {
+      intervals.add(current);
+      return current;
+    }
+    Interval combined = new Interval(previous.keys, current.keys);
+    long packedSavings = combined.packedSavings(mode);
+    if (packedSavings <= 0
+        || packedSavings < previous.estimatedSize(mode) + current.estimatedSize(mode) - penalty) {
+      intervals.add(current);
+      return current;
+    } else {
+      intervals.set(intervals.size() - 1, combined);
+      return combined;
+    }
+  }
+
+  private void tryAddToBiggestSavings(
+      Set<Interval> biggestPackedSet,
+      PriorityQueue<Interval> intervals,
+      Interval toAdd,
+      int maximumNumberOfSwitches) {
+    assert !biggestPackedSet.contains(toAdd);
+    long savings = toAdd.packedSavings(options.getInternalOutputMode());
+    if (savings <= 0) {
+      return;
+    }
+    if (intervals.size() < maximumNumberOfSwitches) {
+      intervals.add(toAdd);
+      biggestPackedSet.add(toAdd);
+    } else if (savings > intervals.peek().packedSavings(options.getInternalOutputMode())) {
+      intervals.add(toAdd);
+      biggestPackedSet.add(toAdd);
+      biggestPackedSet.remove(intervals.poll());
+    }
+  }
+
+  private int codeUnitMargin() {
+    return options.getInternalOutputMode().isGeneratingClassFiles() ? 3 : 1;
+  }
+
+  private int findIfsForCandidates(
+      List<Interval> newSwitches, IntSwitch theSwitch, IntList outliers) {
+    Set<Interval> switchesToRemove = new HashSet<>();
+    InternalOutputMode mode = options.getInternalOutputMode();
+    int outliersAsIfSize = 0;
+    // The candidateForIfs is either an index to a switch that can be eliminated totally or a sparse
+    // where removing a key may produce a greater saving. It is only if keys are small in the packed
+    // switch that removing the keys makes sense (size wise).
+    for (Interval candidate : newSwitches) {
+      int maxIfBudget = 10;
+      long switchSize = candidate.estimatedSize(mode);
+      int sizeOfAllKeysAsIf = sizeForKeysWrittenAsIfs(theSwitch.value().outType(), candidate.keys);
+      if (candidate.keys.size() <= maxIfBudget
+          && sizeOfAllKeysAsIf < switchSize - codeUnitMargin()) {
+        outliersAsIfSize += sizeOfAllKeysAsIf;
+        switchesToRemove.add(candidate);
+        outliers.addAll(candidate.keys);
+        continue;
+      }
+      // One could do something clever here, but we use a simple algorithm that use the fact that
+      // all keys are sorted in ascending order and that the smallest absolute value will give the
+      // best saving.
+      IntList candidateKeys = candidate.keys;
+      int smallestPosition = -1;
+      long smallest = Long.MAX_VALUE;
+      for (int i = 0; i < candidateKeys.size(); i++) {
+        long current = Math.abs((long) candidateKeys.getInt(i));
+        if (current < smallest) {
+          smallestPosition = i;
+          smallest = current;
+        }
+      }
+      // Add as many keys forward and backward as we have budget and we decrease in size.
+      IntList ifKeys = new IntArrayList();
+      ifKeys.add(candidateKeys.getInt(smallestPosition));
+      long previousSavings = 0;
+      long currentSavings =
+          switchSize
+              - sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys)
+              - IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
+      int minIndex = smallestPosition - 1;
+      int maxIndex = smallestPosition + 1;
+      while (ifKeys.size() < maxIfBudget && currentSavings > previousSavings) {
+        if (minIndex >= 0 && maxIndex < candidateKeys.size()) {
+          long valMin = Math.abs((long) candidateKeys.getInt(minIndex));
+          int valMax = Math.abs(candidateKeys.getInt(maxIndex));
+          if (valMax <= valMin) {
+            ifKeys.add(candidateKeys.getInt(maxIndex++));
+          } else {
+            ifKeys.add(candidateKeys.getInt(minIndex--));
+          }
+        } else if (minIndex >= 0) {
+          ifKeys.add(candidateKeys.getInt(minIndex--));
+        } else if (maxIndex < candidateKeys.size()) {
+          ifKeys.add(candidateKeys.getInt(maxIndex++));
+        } else {
+          // No more elements to add as if's.
+          break;
+        }
+        previousSavings = currentSavings;
+        currentSavings =
+            switchSize
+                - sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys)
+                - IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
+      }
+      if (previousSavings >= currentSavings) {
+        // Remove the last added key since it did not contribute to savings.
+        int lastKey = ifKeys.getInt(ifKeys.size() - 1);
+        ifKeys.removeInt(ifKeys.size() - 1);
+        if (lastKey == candidateKeys.getInt(minIndex + 1)) {
+          minIndex++;
+        } else {
+          maxIndex--;
+        }
+      }
+      // Adjust pointers into the candidate keys.
+      minIndex++;
+      maxIndex--;
+      if (ifKeys.size() > 0) {
+        int ifsSize = sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys);
+        long newSwitchSize =
+            IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
+        if (newSwitchSize + ifsSize + codeUnitMargin() < switchSize) {
+          candidateKeys.removeElements(minIndex, maxIndex);
+          outliers.addAll(ifKeys);
+          outliersAsIfSize += ifsSize;
+        }
+      }
+    }
+    newSwitches.removeAll(switchesToRemove);
+    return outliersAsIfSize;
+  }
+
+  private int sizeForKeysWrittenAsIfs(ValueType type, Collection<Integer> keys) {
+    int ifsSize = If.estimatedSize(options.getInternalOutputMode()) * keys.size();
+    // In Cf we also require a load as well (and a stack map entry)
+    if (options.getInternalOutputMode().isGeneratingClassFiles()) {
+      ifsSize += keys.size() * (3 + 1);
+    }
+    for (int k : keys) {
+      if (k != 0) {
+        ifsSize += ConstNumber.estimatedSize(options.getInternalOutputMode(), type, k);
+      }
+    }
+    return ifsSize;
+  }
+
+  /**
+   * Covert the switch instruction to a sequence of if instructions checking for a specified set of
+   * keys, followed by a new switch with the remaining keys.
+   */
+  // TODO(b/270398965): Replace LinkedList.
+  @SuppressWarnings("JdkObsolete")
+  public void convertSwitchToSwitchAndIfs(
+      IRCode code,
+      ListIterator<BasicBlock> blocksIterator,
+      BasicBlock originalBlock,
+      InstructionListIterator iterator,
+      IntSwitch theSwitch,
+      List<IntList> switches,
+      IntList keysToRemove) {
+
+    Position position = theSwitch.getPosition();
+
+    // Extract the information from the switch before removing it.
+    Int2ReferenceSortedMap<BasicBlock> keyToTarget = theSwitch.getKeyToTargetMap();
+
+    // Keep track of the current fallthrough, starting with the original.
+    BasicBlock fallthroughBlock = theSwitch.fallthroughBlock();
+
+    // Split the switch instruction into its own block and remove it.
+    iterator.previous();
+    BasicBlock originalSwitchBlock = iterator.split(code, blocksIterator);
+    assert !originalSwitchBlock.hasCatchHandlers();
+    assert originalSwitchBlock.getInstructions().size() == 1;
+    assert originalBlock.exit().isGoto();
+    theSwitch.moveDebugValues(originalBlock.exit());
+    blocksIterator.remove();
+    theSwitch.getBlock().detachAllSuccessors();
+    BasicBlock block = theSwitch.getBlock().unlinkSinglePredecessor();
+    assert theSwitch.getBlock().getPredecessors().size() == 0;
+    assert theSwitch.getBlock().getSuccessors().size() == 0;
+    assert block == originalBlock;
+
+    // Collect the new blocks for adding to the block list.
+    LinkedList<BasicBlock> newBlocks = new LinkedList<>();
+
+    // Build the switch-blocks backwards, to always have the fallthrough block in hand.
+    for (int i = switches.size() - 1; i >= 0; i--) {
+      SwitchBuilder switchBuilder = new SwitchBuilder(position);
+      switchBuilder.setValue(theSwitch.value());
+      IntList keys = switches.get(i);
+      for (int j = 0; j < keys.size(); j++) {
+        int key = keys.getInt(j);
+        switchBuilder.addKeyAndTarget(key, keyToTarget.get(key));
+      }
+      switchBuilder.setFallthrough(fallthroughBlock).setBlockNumber(code.getNextBlockNumber());
+      BasicBlock newSwitchBlock = switchBuilder.build(code.metadata());
+      newBlocks.addFirst(newSwitchBlock);
+      fallthroughBlock = newSwitchBlock;
+    }
+
+    // Build the if-blocks backwards, to always have the fallthrough block in hand.
+    for (int i = keysToRemove.size() - 1; i >= 0; i--) {
+      int key = keysToRemove.getInt(i);
+      BasicBlock peeledOffTarget = keyToTarget.get(key);
+      IfBuilder ifBuilder = new IfBuilder(position, code);
+      ifBuilder
+          .setLeft(theSwitch.value())
+          .setRight(key)
+          .setTarget(peeledOffTarget)
+          .setFallthrough(fallthroughBlock)
+          .setBlockNumber(code.getNextBlockNumber());
+      BasicBlock ifBlock = ifBuilder.build();
+      newBlocks.addFirst(ifBlock);
+      fallthroughBlock = ifBlock;
+    }
+
+    // Finally link the block before the original switch to the new block sequence.
+    originalBlock.link(fallthroughBlock);
+
+    // Finally add the blocks.
+    newBlocks.forEach(blocksIterator::add);
+  }
+
+  // TODO(sgjesse); Move this somewhere else, and reuse it for some of the other switch rewritings.
+  private abstract static class InstructionBuilder<T> {
+
+    int blockNumber;
+    final Position position;
+
+    InstructionBuilder(Position position) {
+      this.position = position;
+    }
+
+    abstract T self();
+
+    T setBlockNumber(int blockNumber) {
+      this.blockNumber = blockNumber;
+      return self();
+    }
+  }
+
+  private static class SwitchBuilder extends InstructionBuilder<SwitchBuilder> {
+
+    private Value value;
+    private final Int2ReferenceSortedMap<BasicBlock> keyToTarget = new Int2ReferenceAVLTreeMap<>();
+    private BasicBlock fallthrough;
+
+    SwitchBuilder(Position position) {
+      super(position);
+    }
+
+    @Override
+    SwitchBuilder self() {
+      return this;
+    }
+
+    SwitchBuilder setValue(Value value) {
+      this.value = value;
+      return this;
+    }
+
+    SwitchBuilder addKeyAndTarget(int key, BasicBlock target) {
+      keyToTarget.put(key, target);
+      return this;
+    }
+
+    SwitchBuilder setFallthrough(BasicBlock fallthrough) {
+      this.fallthrough = fallthrough;
+      return this;
+    }
+
+    BasicBlock build(IRMetadata metadata) {
+      final int NOT_FOUND = -1;
+      Object2IntMap<BasicBlock> targetToSuccessorIndex = new Object2IntLinkedOpenHashMap<>();
+      targetToSuccessorIndex.defaultReturnValue(NOT_FOUND);
+
+      int[] keys = new int[keyToTarget.size()];
+      int[] targetBlockIndices = new int[keyToTarget.size()];
+      // Sort keys descending.
+      int count = 0;
+      IntIterator iter = keyToTarget.keySet().iterator();
+      while (iter.hasNext()) {
+        int key = iter.nextInt();
+        BasicBlock target = keyToTarget.get(key);
+        Integer targetIndex =
+            targetToSuccessorIndex.computeIfAbsent(target, b -> targetToSuccessorIndex.size());
+        keys[count] = key;
+        targetBlockIndices[count] = targetIndex;
+        count++;
+      }
+      Integer fallthroughIndex =
+          targetToSuccessorIndex.computeIfAbsent(fallthrough, b -> targetToSuccessorIndex.size());
+      IntSwitch newSwitch = new IntSwitch(value, keys, targetBlockIndices, fallthroughIndex);
+      newSwitch.setPosition(position);
+      BasicBlock newSwitchBlock = BasicBlock.createSwitchBlock(blockNumber, newSwitch, metadata);
+      for (BasicBlock successor : targetToSuccessorIndex.keySet()) {
+        newSwitchBlock.link(successor);
+      }
+      return newSwitchBlock;
+    }
+  }
+
+  private static class IfBuilder extends InstructionBuilder<IfBuilder> {
+
+    private final IRCode code;
+    private Value left;
+    private int right;
+    private BasicBlock target;
+    private BasicBlock fallthrough;
+
+    IfBuilder(Position position, IRCode code) {
+      super(position);
+      this.code = code;
+    }
+
+    @Override
+    IfBuilder self() {
+      return this;
+    }
+
+    IfBuilder setLeft(Value left) {
+      this.left = left;
+      return this;
+    }
+
+    IfBuilder setRight(int right) {
+      this.right = right;
+      return this;
+    }
+
+    IfBuilder setTarget(BasicBlock target) {
+      this.target = target;
+      return this;
+    }
+
+    IfBuilder setFallthrough(BasicBlock fallthrough) {
+      this.fallthrough = fallthrough;
+      return this;
+    }
+
+    BasicBlock build() {
+      assert target != null;
+      assert fallthrough != null;
+      If newIf;
+      BasicBlock ifBlock;
+      if (right != 0) {
+        ConstNumber rightConst = code.createIntConstant(right);
+        rightConst.setPosition(position);
+        newIf = new If(IfType.EQ, ImmutableList.of(left, rightConst.dest()));
+        ifBlock = BasicBlock.createIfBlock(blockNumber, newIf, code.metadata(), rightConst);
+      } else {
+        newIf = new If(IfType.EQ, left);
+        ifBlock = BasicBlock.createIfBlock(blockNumber, newIf, code.metadata());
+      }
+      newIf.setPosition(position);
+      ifBlock.link(target);
+      ifBlock.link(fallthrough);
+      return ifBlock;
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchCaseEliminator.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/SwitchCaseEliminator.java
similarity index 99%
rename from src/main/java/com/android/tools/r8/ir/optimize/SwitchCaseEliminator.java
rename to src/main/java/com/android/tools/r8/ir/conversion/passes/SwitchCaseEliminator.java
index 11e0b51..cbda630 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/SwitchCaseEliminator.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/SwitchCaseEliminator.java
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-package com.android.tools.r8.ir.optimize;
+package com.android.tools.r8.ir.conversion.passes;
 
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.ir.code.BasicBlock;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
new file mode 100644
index 0000000..e19b963
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialCheckCastAndInstanceOfRemover.java
@@ -0,0 +1,384 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.conversion.passes;
+
+import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
+
+import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.graph.AccessControl;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.analysis.type.DynamicTypeWithUpperBound;
+import com.android.tools.r8.ir.analysis.type.Nullability;
+import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
+import com.android.tools.r8.ir.analysis.type.TypeElement;
+import com.android.tools.r8.ir.analysis.type.TypeUtils;
+import com.android.tools.r8.ir.code.CheckCast;
+import com.android.tools.r8.ir.code.ConstNumber;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.IRMetadata;
+import com.android.tools.r8.ir.code.InstanceOf;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionListIterator;
+import com.android.tools.r8.ir.code.InvokeStatic;
+import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.MethodProcessor;
+import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations;
+import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.UtilityMethodForCodeOptimizations;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.InternalOptions;
+import com.google.common.collect.Sets;
+import java.util.Set;
+
+public class TrivialCheckCastAndInstanceOfRemover {
+
+  private final AppView<?> appView;
+  private final InternalOptions options;
+  private final DexItemFactory dexItemFactory;
+
+  public TrivialCheckCastAndInstanceOfRemover(AppView<?> appView) {
+    this.appView = appView;
+    this.options = appView.options();
+    this.dexItemFactory = appView.dexItemFactory();
+  }
+
+  public void run(
+      IRCode code,
+      ProgramMethod context,
+      MethodProcessor methodProcessor,
+      MethodProcessingContext methodProcessingContext) {
+    if (!appView.enableWholeProgramOptimizations()) {
+      return;
+    }
+
+    assert appView.appInfo().hasLiveness();
+    AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+
+    if (!appView.options().testing.enableCheckCastAndInstanceOfRemoval) {
+      return;
+    }
+
+    IRMetadata metadata = code.metadata();
+    if (!metadata.mayHaveCheckCast() && !metadata.mayHaveInstanceOf()) {
+      return;
+    }
+
+    // If we can remove a CheckCast it is due to us having at least as much information about the
+    // type as the CheckCast gives. We then need to propagate that information to the users of
+    // the CheckCast to ensure further optimizations and removals of CheckCast:
+    //
+    //    : 1: NewArrayEmpty        v2 <- v1(1) java.lang.String[]  <-- v2 = String[]
+    // ...
+    //    : 2: CheckCast            v5 <- v2; java.lang.Object[]    <-- v5 = Object[]
+    // ...
+    //    : 3: ArrayGet             v7 <- v5, v6(0)                 <-- v7 = Object
+    //    : 4: CheckCast            v8 <- v7; java.lang.String      <-- v8 = String
+    // ...
+    //
+    // When looking at line 2 we can conclude that the CheckCast is trivial because v2 is String[]
+    // and remove it. However, v7 is still only known to be Object and we cannot remove the
+    // CheckCast at line 4 unless we update v7 with the most precise information by narrowing the
+    // affected values of v5. We therefore have to run the type analysis after each CheckCast
+    // removal.
+    TypeAnalysis typeAnalysis = new TypeAnalysis(appView);
+    Set<Value> affectedValues = Sets.newIdentityHashSet();
+    InstructionListIterator it = code.instructionListIterator();
+    boolean needToRemoveTrivialPhis = false;
+    while (it.hasNext()) {
+      Instruction current = it.next();
+      if (current.isCheckCast()) {
+        boolean hasPhiUsers = current.outValue().hasPhiUsers();
+        RemoveCheckCastInstructionIfTrivialResult removeResult =
+            removeCheckCastInstructionIfTrivial(
+                appViewWithLiveness,
+                current.asCheckCast(),
+                it,
+                code,
+                context,
+                affectedValues,
+                methodProcessor,
+                methodProcessingContext);
+        if (removeResult != RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS) {
+          assert removeResult == RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+          needToRemoveTrivialPhis |= hasPhiUsers;
+          typeAnalysis.narrowing(affectedValues);
+          affectedValues.clear();
+        }
+      } else if (current.isInstanceOf()) {
+        boolean hasPhiUsers = current.outValue().hasPhiUsers();
+        if (removeInstanceOfInstructionIfTrivial(
+            appViewWithLiveness, current.asInstanceOf(), it, code)) {
+          needToRemoveTrivialPhis |= hasPhiUsers;
+        }
+      }
+    }
+    // ... v1
+    // ...
+    // v2 <- check-cast v1, T
+    // v3 <- phi(v1, v2)
+    // Removing check-cast may result in a trivial phi:
+    // v3 <- phi(v1, v1)
+    if (needToRemoveTrivialPhis) {
+      code.removeAllDeadAndTrivialPhis(affectedValues);
+      if (!affectedValues.isEmpty()) {
+        typeAnalysis.narrowing(affectedValues);
+      }
+    }
+    assert code.isConsistentSSA(appView);
+  }
+
+  enum RemoveCheckCastInstructionIfTrivialResult {
+    NO_REMOVALS,
+    REMOVED_CAST_DO_NARROW
+  }
+
+  private enum InstanceOfResult {
+    UNKNOWN,
+    TRUE,
+    FALSE
+  }
+
+  // Returns true if the given check-cast instruction was removed.
+  private RemoveCheckCastInstructionIfTrivialResult removeCheckCastInstructionIfTrivial(
+      AppView<AppInfoWithLiveness> appViewWithLiveness,
+      CheckCast checkCast,
+      InstructionListIterator it,
+      IRCode code,
+      ProgramMethod context,
+      Set<Value> affectedValues,
+      MethodProcessor methodProcessor,
+      MethodProcessingContext methodProcessingContext) {
+    Value inValue = checkCast.object();
+    Value outValue = checkCast.outValue();
+    DexType castType = checkCast.getType();
+    DexType baseCastType = castType.toBaseType(dexItemFactory);
+
+    // If the cast type is not accessible in the current context, we should not remove the cast
+    // in order to preserve runtime errors. Note that JVM and ART behave differently: see
+    // {@link com.android.tools.r8.ir.optimize.checkcast.IllegalAccessErrorTest}.
+    if (baseCastType.isClassType()) {
+      DexClass baseCastClass = appView.definitionFor(baseCastType);
+      if (baseCastClass == null
+          || AccessControl.isClassAccessible(baseCastClass, code.context(), appViewWithLiveness)
+              .isPossiblyFalse()) {
+        return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
+      }
+    }
+
+    if (!appView
+        .getOpenClosedInterfacesCollection()
+        .isDefinitelyInstanceOfStaticType(appViewWithLiveness, inValue)) {
+      return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
+    }
+
+    // If the in-value is `null` and the cast-type is a float-array type, then trivial check-cast
+    // elimination may lead to verification errors. See b/123269162.
+    if (options.canHaveArtCheckCastVerifierBug()) {
+      if (inValue.getType().isNullType()
+          && castType.isArrayType()
+          && castType.toBaseType(dexItemFactory).isFloatType()) {
+        return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
+      }
+    }
+
+    // If casting to an array of an interface type elimination may lead to verification errors.
+    // See b/132420510 and b/223424356.
+    if (options.canHaveIncorrectJoinForArrayOfInterfacesBug()) {
+      if (castType.isArrayType()) {
+        DexType baseType = castType.toBaseType(dexItemFactory);
+        if (baseType.isClassType() && baseType.isInterface(appViewWithLiveness)) {
+          return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
+        }
+      }
+    }
+
+    TypeElement inTypeLattice = inValue.getType();
+    TypeElement outTypeLattice = outValue.getType();
+    TypeElement castTypeLattice = castType.toTypeElement(appView, inTypeLattice.nullability());
+
+    assert inTypeLattice.nullability().lessThanOrEqual(outTypeLattice.nullability());
+
+    if (inTypeLattice.lessThanOrEqual(castTypeLattice, appView)) {
+      // 1) Trivial cast.
+      //   A a = ...
+      //   A a' = (A) a;
+      // 2) Up-cast: we already have finer type info.
+      //   A < B
+      //   A a = ...
+      //   B b = (B) a;
+      assert inTypeLattice.lessThanOrEqual(outTypeLattice, appView);
+      // The removeOrReplaceByDebugLocalWrite will propagate the incoming value for the CheckCast
+      // to the users of the CheckCast's out value.
+      //
+      // v2 = CheckCast A v1  ~~>  DebugLocalWrite $v0 <- v1
+      //
+      // The DebugLocalWrite is not a user of the outvalue, we therefore have to wait and take the
+      // CheckCast invalue users that includes the potential DebugLocalWrite.
+      CodeRewriter.removeOrReplaceByDebugLocalWrite(checkCast, it, inValue, outValue);
+      affectedValues.addAll(inValue.affectedValues());
+      return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+    }
+
+    // If values of cast type are guaranteed to be null, then the out-value must be null if the cast
+    // succeeds. After removing all usages of the out-value, the check-cast instruction is replaced
+    // by a call to throwClassCastExceptionIfNotNull() to allow dead code elimination of the cast
+    // type.
+    if (castType.isClassType()
+        && castType.isAlwaysNull(appViewWithLiveness)
+        && !outValue.hasDebugUsers()) {
+      // Replace all usages of the out-value by null.
+      it.previous();
+      Value nullValue = it.insertConstNullInstruction(code, options);
+      it.next();
+      checkCast.outValue().replaceUsers(nullValue);
+      affectedValues.addAll(nullValue.affectedValues());
+
+      // Replace the check-cast instruction by throwClassCastExceptionIfNotNull().
+      UtilityMethodForCodeOptimizations throwClassCastExceptionIfNotNullMethod =
+          UtilityMethodsForCodeOptimizations.synthesizeThrowClassCastExceptionIfNotNullMethod(
+              appView, methodProcessor.getEventConsumer(), methodProcessingContext);
+      throwClassCastExceptionIfNotNullMethod.optimize(methodProcessor);
+      InvokeStatic replacement =
+          InvokeStatic.builder()
+              .setMethod(throwClassCastExceptionIfNotNullMethod.getMethod())
+              .setSingleArgument(checkCast.object())
+              .setPosition(checkCast)
+              .build();
+      it.replaceCurrentInstruction(replacement);
+      assert replacement.lookupSingleTarget(appView, context) != null;
+      return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+    }
+
+    // If the cast is guaranteed to succeed and only there to ensure the program type checks, then
+    // check if the program would still type check after removing the cast.
+    if (checkCast.isSafeCheckCast()
+        || checkCast
+            .getFirstOperand()
+            .getDynamicType(appViewWithLiveness)
+            .getDynamicUpperBoundType()
+            .lessThanOrEqualUpToNullability(castTypeLattice, appView)) {
+      TypeElement useType =
+          TypeUtils.computeUseType(appViewWithLiveness, context, checkCast.outValue());
+      if (inTypeLattice.lessThanOrEqualUpToNullability(useType, appView)) {
+        return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
+      }
+    }
+
+    // Otherwise, keep the checkcast to preserve verification errors. E.g., down-cast:
+    // A < B < C
+    // c = ...        // Even though we know c is of type A,
+    // a' = (B) c;    // (this could be removed, since chained below.)
+    // a'' = (A) a';  // this should remain for runtime verification.
+    assert !inTypeLattice.isDefinitelyNull() || (inValue.isPhi() && !inTypeLattice.isNullType());
+    assert outTypeLattice.equalUpToNullability(castTypeLattice);
+    return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
+  }
+
+  // Returns true if the given instance-of instruction was removed.
+  private boolean removeInstanceOfInstructionIfTrivial(
+      AppView<AppInfoWithLiveness> appViewWithLiveness,
+      InstanceOf instanceOf,
+      InstructionListIterator it,
+      IRCode code) {
+    ProgramMethod context = code.context();
+
+    // If the instance-of type is not accessible in the current context, we should not remove the
+    // instance-of instruction in order to preserve IllegalAccessError.
+    DexType instanceOfBaseType = instanceOf.type().toBaseType(dexItemFactory);
+    if (instanceOfBaseType.isClassType()) {
+      DexClass instanceOfClass = appView.definitionFor(instanceOfBaseType);
+      if (instanceOfClass == null
+          || AccessControl.isClassAccessible(instanceOfClass, context, appViewWithLiveness)
+              .isPossiblyFalse()) {
+        return false;
+      }
+    }
+
+    Value inValue = instanceOf.value();
+    if (!appView
+        .getOpenClosedInterfacesCollection()
+        .isDefinitelyInstanceOfStaticType(appViewWithLiveness, inValue)) {
+      return false;
+    }
+
+    TypeElement inType = inValue.getType();
+    TypeElement instanceOfType =
+        TypeElement.fromDexType(instanceOf.type(), inType.nullability(), appView);
+    Value aliasValue = inValue.getAliasedValue();
+
+    InstanceOfResult result = InstanceOfResult.UNKNOWN;
+    if (inType.isDefinitelyNull()) {
+      result = InstanceOfResult.FALSE;
+    } else if (inType.lessThanOrEqual(instanceOfType, appView) && !inType.isNullable()) {
+      result = InstanceOfResult.TRUE;
+    } else if (!aliasValue.isPhi()
+        && aliasValue.definition.isCreatingInstanceOrArray()
+        && instanceOfType.strictlyLessThan(inType, appView)) {
+      result = InstanceOfResult.FALSE;
+    } else if (appView.appInfo().hasLiveness()) {
+      if (instanceOf.type().isClassType()
+          && isNeverInstantiatedDirectlyOrIndirectly(instanceOf.type())) {
+        // The type of the instance-of instruction is a program class, and is never instantiated
+        // directly or indirectly. Thus, the in-value must be null, meaning that the instance-of
+        // instruction will always evaluate to false.
+        result = InstanceOfResult.FALSE;
+      }
+
+      if (result == InstanceOfResult.UNKNOWN) {
+        if (inType.isClassType()
+            && isNeverInstantiatedDirectlyOrIndirectly(inType.asClassType().getClassType())) {
+          // The type of the in-value is a program class, and is never instantiated directly or
+          // indirectly. This, the in-value must be null, meaning that the instance-of instruction
+          // will always evaluate to false.
+          result = InstanceOfResult.FALSE;
+        }
+      }
+
+      if (result == InstanceOfResult.UNKNOWN) {
+        Value aliasedValue =
+            inValue.getSpecificAliasedValue(
+                value ->
+                    value.isDefinedByInstructionSatisfying(
+                        Instruction::isAssumeWithDynamicTypeAssumption));
+        if (aliasedValue != null) {
+          DynamicTypeWithUpperBound dynamicType =
+              aliasedValue.getDefinition().asAssume().getDynamicTypeAssumption().getDynamicType();
+          Nullability nullability = dynamicType.getNullability();
+          if (nullability.isDefinitelyNull()) {
+            result = InstanceOfResult.FALSE;
+          } else if (dynamicType.getDynamicUpperBoundType().lessThanOrEqual(instanceOfType, appView)
+              && (!inType.isNullable() || !nullability.isNullable())) {
+            result = InstanceOfResult.TRUE;
+          }
+        }
+      }
+    }
+    if (result != InstanceOfResult.UNKNOWN) {
+      ConstNumber newInstruction =
+          new ConstNumber(
+              new Value(
+                  code.valueNumberGenerator.next(),
+                  TypeElement.getInt(),
+                  instanceOf.outValue().getLocalInfo()),
+              result == InstanceOfResult.TRUE ? 1 : 0);
+      it.replaceCurrentInstruction(newInstruction);
+      return true;
+    }
+    return false;
+  }
+
+  private boolean isNeverInstantiatedDirectlyOrIndirectly(DexType type) {
+    assert appView.appInfo().hasLiveness();
+    assert type.isClassType();
+    DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(type));
+    return clazz != null
+        && !appView.appInfo().withLiveness().isInstantiatedDirectlyOrIndirectly(clazz);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialGotosCollapser.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialGotosCollapser.java
new file mode 100644
index 0000000..7c9b4d0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialGotosCollapser.java
@@ -0,0 +1,204 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.conversion.passes;
+
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.BasicBlock;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.If;
+import com.android.tools.r8.ir.code.Switch;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+/**
+ * Rewrite all branch targets to the destination of trivial goto chains when possible. Does not
+ * rewrite fallthrough targets as that would require block reordering and the transformation only
+ * makes sense after SSA destruction where there are no phis.
+ */
+public class TrivialGotosCollapser extends CodeRewriterPass<AppInfo> {
+
+  public TrivialGotosCollapser(AppView<?> appView) {
+    super(appView);
+  }
+
+  @Override
+  String getTimingId() {
+    return "TrivialGotosCollapser";
+  }
+
+  @Override
+  void rewriteCode(ProgramMethod method, IRCode code) {
+    assert code.isConsistentGraph(appView);
+    List<BasicBlock> blocksToRemove = new ArrayList<>();
+    // Rewrite all non-fallthrough targets to the end of trivial goto chains and remove
+    // first round of trivial goto blocks.
+    ListIterator<BasicBlock> iterator = code.listIterator();
+    assert iterator.hasNext();
+    BasicBlock block = iterator.next();
+    BasicBlock nextBlock;
+
+    do {
+      nextBlock = iterator.hasNext() ? iterator.next() : null;
+      if (block.isTrivialGoto()) {
+        collapseTrivialGoto(code, block, nextBlock, blocksToRemove);
+      }
+      if (block.exit().isIf()) {
+        collapseIfTrueTarget(block);
+      }
+      if (block.exit().isSwitch()) {
+        collapseNonFallthroughSwitchTargets(block);
+      }
+      block = nextBlock;
+    } while (nextBlock != null);
+    code.removeBlocks(blocksToRemove);
+    // Get rid of gotos to the next block.
+    while (!blocksToRemove.isEmpty()) {
+      blocksToRemove = new ArrayList<>();
+      iterator = code.listIterator();
+      block = iterator.next();
+      do {
+        nextBlock = iterator.hasNext() ? iterator.next() : null;
+        if (block.isTrivialGoto()) {
+          collapseTrivialGoto(code, block, nextBlock, blocksToRemove);
+        }
+        block = nextBlock;
+      } while (block != null);
+      code.removeBlocks(blocksToRemove);
+    }
+    assert removedTrivialGotos(code);
+    assert code.isConsistentGraph(appView);
+  }
+
+  @Override
+  boolean shouldRewriteCode(ProgramMethod method, IRCode code) {
+    return true;
+  }
+
+  public static void unlinkTrivialGotoBlock(BasicBlock block, BasicBlock target) {
+    assert block.isTrivialGoto();
+    for (BasicBlock pred : block.getPredecessors()) {
+      pred.replaceSuccessor(block, target);
+    }
+    for (BasicBlock succ : block.getSuccessors()) {
+      succ.getMutablePredecessors().remove(block);
+    }
+    for (BasicBlock pred : block.getPredecessors()) {
+      if (!target.getPredecessors().contains(pred)) {
+        target.getMutablePredecessors().add(pred);
+      }
+    }
+  }
+
+  private boolean isFallthroughBlock(BasicBlock block) {
+    for (BasicBlock pred : block.getPredecessors()) {
+      if (pred.exit().fallthroughBlock() == block) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean removedTrivialGotos(IRCode code) {
+    ListIterator<BasicBlock> iterator = code.listIterator();
+    assert iterator.hasNext();
+    BasicBlock block = iterator.next();
+    BasicBlock nextBlock;
+    do {
+      nextBlock = iterator.hasNext() ? iterator.next() : null;
+      // Trivial goto block are only kept if they are self-targeting or are targeted by
+      // fallthroughs.
+      BasicBlock blk = block; // Additional local for lambda below.
+      assert !block.isTrivialGoto()
+          || block.exit().asGoto().getTarget() == block
+          || code.entryBlock() == block
+          || block.getPredecessors().stream().anyMatch((b) -> b.exit().fallthroughBlock() == blk);
+      // Trivial goto blocks never target the next block (in that case there should just be a
+      // fallthrough).
+      assert !block.isTrivialGoto() || block.exit().asGoto().getTarget() != nextBlock;
+      block = nextBlock;
+    } while (block != null);
+    return true;
+  }
+
+  private void collapseTrivialGoto(
+      IRCode code, BasicBlock block, BasicBlock nextBlock, List<BasicBlock> blocksToRemove) {
+
+    // This is the base case for GOTO loops.
+    if (block.exit().asGoto().getTarget() == block) {
+      return;
+    }
+
+    BasicBlock target = block.endOfGotoChain();
+
+    boolean needed = false;
+
+    if (target == null) {
+      // This implies we are in a loop of GOTOs. In that case, we will iteratively remove each
+      // trivial GOTO one-by-one until the above base case (one block targeting itself) is left.
+      target = block.exit().asGoto().getTarget();
+    }
+
+    if (target != nextBlock) {
+      // Not targeting the fallthrough block, determine if we need this goto. We need it if
+      // a fallthrough can hit this block. That is the case if the block is the entry block
+      // or if one of the predecessors fall through to the block.
+      needed = code.entryBlock() == block || isFallthroughBlock(block);
+    }
+
+    if (!needed) {
+      blocksToRemove.add(block);
+      unlinkTrivialGotoBlock(block, target);
+    }
+  }
+
+  private void collapseIfTrueTarget(BasicBlock block) {
+    If insn = block.exit().asIf();
+    BasicBlock target = insn.getTrueTarget();
+    BasicBlock newTarget = target.endOfGotoChain();
+    BasicBlock fallthrough = insn.fallthroughBlock();
+    BasicBlock newFallthrough = fallthrough.endOfGotoChain();
+    if (newTarget != null && target != newTarget) {
+      insn.getBlock().replaceSuccessor(target, newTarget);
+      target.getMutablePredecessors().remove(block);
+      if (!newTarget.getPredecessors().contains(block)) {
+        newTarget.getMutablePredecessors().add(block);
+      }
+    }
+    if (block.exit().isIf()) {
+      insn = block.exit().asIf();
+      if (insn.getTrueTarget() == newFallthrough) {
+        // Replace if with the same true and fallthrough target with a goto to the fallthrough.
+        block.replaceSuccessor(insn.getTrueTarget(), fallthrough);
+        assert block.exit().isGoto();
+        assert block.exit().asGoto().getTarget() == fallthrough;
+      }
+    }
+  }
+
+  private void collapseNonFallthroughSwitchTargets(BasicBlock block) {
+    Switch insn = block.exit().asSwitch();
+    BasicBlock fallthroughBlock = insn.fallthroughBlock();
+    Set<BasicBlock> replacedBlocks = new HashSet<>();
+    for (int j = 0; j < insn.targetBlockIndices().length; j++) {
+      BasicBlock target = insn.targetBlock(j);
+      if (target != fallthroughBlock) {
+        BasicBlock newTarget = target.endOfGotoChain();
+        if (newTarget != null && target != newTarget && !replacedBlocks.contains(target)) {
+          insn.getBlock().replaceSuccessor(target, newTarget);
+          target.getMutablePredecessors().remove(block);
+          if (!newTarget.getPredecessors().contains(block)) {
+            newTarget.getMutablePredecessors().add(block);
+          }
+          replacedBlocks.add(target);
+        }
+      }
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialPhiSimplifier.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialPhiSimplifier.java
new file mode 100644
index 0000000..6c4c66f
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/TrivialPhiSimplifier.java
@@ -0,0 +1,113 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.conversion.passes;
+
+import com.android.tools.r8.algorithms.scc.SCC;
+import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InvokeDirect;
+import com.android.tools.r8.ir.code.NewInstance;
+import com.android.tools.r8.ir.code.Phi;
+import com.android.tools.r8.ir.code.UnusedArgument;
+import com.android.tools.r8.ir.code.Value;
+import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Set;
+
+public class TrivialPhiSimplifier {
+
+  public static void replaceUnusedArgumentTrivialPhis(UnusedArgument unusedArgument) {
+    replaceTrivialPhis(unusedArgument.outValue());
+    for (Phi phiUser : unusedArgument.outValue().uniquePhiUsers()) {
+      phiUser.removeTrivialPhi();
+    }
+    assert !unusedArgument.outValue().hasPhiUsers();
+  }
+
+  public static void ensureDirectStringNewToInit(IRCode code, DexItemFactory dexItemFactory) {
+    for (Instruction instruction : code.instructions()) {
+      if (instruction.isInvokeDirect()) {
+        InvokeDirect invoke = instruction.asInvokeDirect();
+        DexMethod method = invoke.getInvokedMethod();
+        if (dexItemFactory.isConstructor(method)
+            && method.holder == dexItemFactory.stringType
+            && invoke.getReceiver().isPhi()) {
+          NewInstance newInstance = findNewInstance(invoke.getReceiver().asPhi());
+          replaceTrivialPhis(newInstance.outValue());
+          if (invoke.getReceiver().isPhi()) {
+            throw new CompilationError(
+                "Failed to remove trivial phis between new-instance and <init>");
+          }
+          newInstance.markNoSpilling();
+        }
+      }
+    }
+  }
+
+  private static NewInstance findNewInstance(Phi phi) {
+    Set<Phi> seen = Sets.newIdentityHashSet();
+    Set<Value> values = Sets.newIdentityHashSet();
+    recursiveAddOperands(phi, seen, values);
+    if (values.size() != 1) {
+      throw new CompilationError("Failed to identify unique new-instance for <init>");
+    }
+    Value newInstanceValue = values.iterator().next();
+    if (newInstanceValue.definition == null || !newInstanceValue.definition.isNewInstance()) {
+      throw new CompilationError("Invalid defining value for call to <init>");
+    }
+    return newInstanceValue.definition.asNewInstance();
+  }
+
+  private static void recursiveAddOperands(Phi phi, Set<Phi> seen, Set<Value> values) {
+    for (Value operand : phi.getOperands()) {
+      if (!operand.isPhi()) {
+        values.add(operand);
+      } else {
+        Phi phiOp = operand.asPhi();
+        if (seen.add(phiOp)) {
+          recursiveAddOperands(phiOp, seen, values);
+        }
+      }
+    }
+  }
+
+  // We compute the set of strongly connected phis making use of the out value and replace all
+  // trivial ones by the out value.
+  // This is a simplified variant of the removeRedundantPhis algorithm in Section 3.2 of:
+  // http://compilers.cs.uni-saarland.de/papers/bbhlmz13cc.pdf
+  private static void replaceTrivialPhis(Value outValue) {
+    List<Set<Value>> components = new SCC<Value>(Value::uniquePhiUsers).computeSCC(outValue);
+    for (int i = components.size() - 1; i >= 0; i--) {
+      Set<Value> component = components.get(i);
+      if (component.size() == 1 && component.iterator().next() == outValue) {
+        continue;
+      }
+      Set<Phi> trivialPhis = Sets.newIdentityHashSet();
+      for (Value value : component) {
+        boolean isTrivial = true;
+        Phi p = value.asPhi();
+        for (Value op : p.getOperands()) {
+          if (op != outValue && !component.contains(op)) {
+            isTrivial = false;
+            break;
+          }
+        }
+        if (isTrivial) {
+          trivialPhis.add(p);
+        }
+      }
+      for (Phi trivialPhi : trivialPhis) {
+        for (Value op : trivialPhi.getOperands()) {
+          op.removePhiUser(trivialPhi);
+        }
+        trivialPhi.replaceUsers(outValue);
+        trivialPhi.getBlock().removePhi(trivialPhi);
+      }
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 26da1f1..4ad6534 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.ir.optimize;
 
-import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
 import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
 import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
 import static com.android.tools.r8.ir.code.Opcodes.CONST_CLASS;
@@ -14,47 +13,29 @@
 import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_GET;
 import static com.android.tools.r8.ir.code.Opcodes.STATIC_GET;
 
-import com.android.tools.r8.algorithms.scc.SCC;
-import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
-import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AccessControl;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.FieldResolutionResult.SingleProgramFieldResolutionResult;
 import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerUtils;
-import com.android.tools.r8.ir.analysis.equivalence.BasicBlockBehavioralSubsumption;
-import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
-import com.android.tools.r8.ir.analysis.type.DynamicTypeWithUpperBound;
-import com.android.tools.r8.ir.analysis.type.Nullability;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
-import com.android.tools.r8.ir.analysis.type.TypeUtils;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
-import com.android.tools.r8.ir.analysis.value.ConstantOrNonConstantNumberValue;
-import com.android.tools.r8.ir.analysis.value.SingleConstClassValue;
-import com.android.tools.r8.ir.analysis.value.SingleFieldValue;
 import com.android.tools.r8.ir.code.ArrayLength;
-import com.android.tools.r8.ir.code.ArrayPut;
 import com.android.tools.r8.ir.code.Assume;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.BasicBlockIterator;
 import com.android.tools.r8.ir.code.Binop;
 import com.android.tools.r8.ir.code.CatchHandlers;
 import com.android.tools.r8.ir.code.CatchHandlers.CatchHandler;
-import com.android.tools.r8.ir.code.CheckCast;
 import com.android.tools.r8.ir.code.ConstClass;
 import com.android.tools.r8.ir.code.ConstNumber;
 import com.android.tools.r8.ir.code.ConstString;
@@ -64,85 +45,51 @@
 import com.android.tools.r8.ir.code.DominatorTree;
 import com.android.tools.r8.ir.code.Goto;
 import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.IRMetadata;
 import com.android.tools.r8.ir.code.If;
 import com.android.tools.r8.ir.code.IfType;
 import com.android.tools.r8.ir.code.InstanceFieldInstruction;
 import com.android.tools.r8.ir.code.InstanceGet;
-import com.android.tools.r8.ir.code.InstanceOf;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.Instruction.SideEffectAssumption;
 import com.android.tools.r8.ir.code.InstructionIterator;
 import com.android.tools.r8.ir.code.InstructionListIterator;
 import com.android.tools.r8.ir.code.InstructionOrPhi;
-import com.android.tools.r8.ir.code.IntSwitch;
 import com.android.tools.r8.ir.code.Invoke;
 import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.InvokeInterface;
 import com.android.tools.r8.ir.code.InvokeMethod;
 import com.android.tools.r8.ir.code.InvokeMethodWithReceiver;
-import com.android.tools.r8.ir.code.InvokeNewArray;
-import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.InvokeVirtual;
-import com.android.tools.r8.ir.code.LinearFlowInstructionListIterator;
 import com.android.tools.r8.ir.code.Move;
-import com.android.tools.r8.ir.code.NewArrayEmpty;
-import com.android.tools.r8.ir.code.NewArrayFilledData;
 import com.android.tools.r8.ir.code.NewInstance;
-import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.code.Phi;
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.Position.SyntheticPosition;
 import com.android.tools.r8.ir.code.StaticGet;
-import com.android.tools.r8.ir.code.Switch;
 import com.android.tools.r8.ir.code.Throw;
-import com.android.tools.r8.ir.code.UnusedArgument;
 import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.code.ValueType;
-import com.android.tools.r8.ir.code.Xor;
-import com.android.tools.r8.ir.conversion.MethodProcessor;
-import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.UtilityMethodForCodeOptimizations;
-import com.android.tools.r8.ir.optimize.controlflow.SwitchCaseAnalyzer;
 import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
 import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.InternalOptions.RewriteArrayOptions;
-import com.android.tools.r8.utils.InternalOutputMode;
 import com.android.tools.r8.utils.LazyBox;
-import com.android.tools.r8.utils.LongInterval;
-import com.android.tools.r8.utils.SetUtils;
-import com.android.tools.r8.utils.WorkList;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import com.google.common.collect.Streams;
 import it.unimi.dsi.fastutil.ints.Int2IntMap;
 import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry;
 import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntIterator;
-import it.unimi.dsi.fastutil.ints.IntList;
 import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
 import it.unimi.dsi.fastutil.ints.IntSet;
 import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
 import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
-import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
-import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Reference2IntMap;
 import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.BitSet;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -150,18 +97,11 @@
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
-import java.util.PriorityQueue;
 import java.util.Set;
 import java.util.function.Predicate;
 
 public class CodeRewriter {
 
-  private enum InstanceOfResult {
-    UNKNOWN,
-    TRUE,
-    FALSE
-  }
-
   // This constant was determined by experimentation.
   private static final int STOP_SHARED_CONSTANT_THRESHOLD = 50;
 
@@ -233,28 +173,6 @@
     assert Streams.stream(code.instructions()).noneMatch(Instruction::isAssume);
   }
 
-  private static boolean removedTrivialGotos(IRCode code) {
-    ListIterator<BasicBlock> iterator = code.listIterator();
-    assert iterator.hasNext();
-    BasicBlock block = iterator.next();
-    BasicBlock nextBlock;
-    do {
-      nextBlock = iterator.hasNext() ? iterator.next() : null;
-      // Trivial goto block are only kept if they are self-targeting or are targeted by
-      // fallthroughs.
-      BasicBlock blk = block;  // Additional local for lambda below.
-      assert !block.isTrivialGoto()
-          || block.exit().asGoto().getTarget() == block
-          || code.entryBlock() == block
-          || block.getPredecessors().stream().anyMatch((b) -> b.exit().fallthroughBlock() == blk);
-      // Trivial goto blocks never target the next block (in that case there should just be a
-      // fallthrough).
-      assert !block.isTrivialGoto() || block.exit().asGoto().getTarget() != nextBlock;
-      block = nextBlock;
-    } while (block != null);
-    return true;
-  }
-
   // Rewrite 'throw new NullPointerException()' to 'throw null'.
   public void rewriteThrowNullPointerException(IRCode code) {
     boolean shouldRemoveUnreachableBlocks = false;
@@ -395,815 +313,6 @@
     assert code.isConsistentSSA(appView);
   }
 
-  public static boolean isFallthroughBlock(BasicBlock block) {
-    for (BasicBlock pred : block.getPredecessors()) {
-      if (pred.exit().fallthroughBlock() == block) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private static void collapseTrivialGoto(
-      IRCode code, BasicBlock block, BasicBlock nextBlock, List<BasicBlock> blocksToRemove) {
-
-    // This is the base case for GOTO loops.
-    if (block.exit().asGoto().getTarget() == block) {
-      return;
-    }
-
-    BasicBlock target = block.endOfGotoChain();
-
-    boolean needed = false;
-
-    if (target == null) {
-      // This implies we are in a loop of GOTOs. In that case, we will iteratively remove each
-      // trivial GOTO one-by-one until the above base case (one block targeting itself) is left.
-      target = block.exit().asGoto().getTarget();
-    }
-
-    if (target != nextBlock) {
-      // Not targeting the fallthrough block, determine if we need this goto. We need it if
-      // a fallthrough can hit this block. That is the case if the block is the entry block
-      // or if one of the predecessors fall through to the block.
-      needed = code.entryBlock() == block || isFallthroughBlock(block);
-    }
-
-    if (!needed) {
-      blocksToRemove.add(block);
-      unlinkTrivialGotoBlock(block, target);
-    }
-  }
-
-  public static void unlinkTrivialGotoBlock(BasicBlock block, BasicBlock target) {
-    assert block.isTrivialGoto();
-    for (BasicBlock pred : block.getPredecessors()) {
-      pred.replaceSuccessor(block, target);
-    }
-    for (BasicBlock succ : block.getSuccessors()) {
-      succ.getMutablePredecessors().remove(block);
-    }
-    for (BasicBlock pred : block.getPredecessors()) {
-      if (!target.getPredecessors().contains(pred)) {
-        target.getMutablePredecessors().add(pred);
-      }
-    }
-  }
-
-  private static void collapseIfTrueTarget(BasicBlock block) {
-    If insn = block.exit().asIf();
-    BasicBlock target = insn.getTrueTarget();
-    BasicBlock newTarget = target.endOfGotoChain();
-    BasicBlock fallthrough = insn.fallthroughBlock();
-    BasicBlock newFallthrough = fallthrough.endOfGotoChain();
-    if (newTarget != null && target != newTarget) {
-      insn.getBlock().replaceSuccessor(target, newTarget);
-      target.getMutablePredecessors().remove(block);
-      if (!newTarget.getPredecessors().contains(block)) {
-        newTarget.getMutablePredecessors().add(block);
-      }
-    }
-    if (block.exit().isIf()) {
-      insn = block.exit().asIf();
-      if (insn.getTrueTarget() == newFallthrough) {
-        // Replace if with the same true and fallthrough target with a goto to the fallthrough.
-        block.replaceSuccessor(insn.getTrueTarget(), fallthrough);
-        assert block.exit().isGoto();
-        assert block.exit().asGoto().getTarget() == fallthrough;
-      }
-    }
-  }
-
-  private static void collapseNonFallthroughSwitchTargets(BasicBlock block) {
-    Switch insn = block.exit().asSwitch();
-    BasicBlock fallthroughBlock = insn.fallthroughBlock();
-    Set<BasicBlock> replacedBlocks = new HashSet<>();
-    for (int j = 0; j < insn.targetBlockIndices().length; j++) {
-      BasicBlock target = insn.targetBlock(j);
-      if (target != fallthroughBlock) {
-        BasicBlock newTarget = target.endOfGotoChain();
-        if (newTarget != null && target != newTarget && !replacedBlocks.contains(target)) {
-          insn.getBlock().replaceSuccessor(target, newTarget);
-          target.getMutablePredecessors().remove(block);
-          if (!newTarget.getPredecessors().contains(block)) {
-            newTarget.getMutablePredecessors().add(block);
-          }
-          replacedBlocks.add(target);
-        }
-      }
-    }
-  }
-
-  // TODO(sgjesse); Move this somewhere else, and reuse it for some of the other switch rewritings.
-  public abstract static class InstructionBuilder<T> {
-
-    protected int blockNumber;
-    protected final Position position;
-
-    protected InstructionBuilder(Position position) {
-      this.position = position;
-    }
-
-    public abstract T self();
-
-    public T setBlockNumber(int blockNumber) {
-      this.blockNumber = blockNumber;
-      return self();
-    }
-  }
-
-  public static class SwitchBuilder extends InstructionBuilder<SwitchBuilder> {
-
-    private Value value;
-    private final Int2ReferenceSortedMap<BasicBlock> keyToTarget = new Int2ReferenceAVLTreeMap<>();
-    private BasicBlock fallthrough;
-
-    public SwitchBuilder(Position position) {
-      super(position);
-    }
-
-    @Override
-    public SwitchBuilder self() {
-      return this;
-    }
-
-    public SwitchBuilder setValue(Value value) {
-      this.value = value;
-      return this;
-    }
-
-    public SwitchBuilder addKeyAndTarget(int key, BasicBlock target) {
-      keyToTarget.put(key, target);
-      return this;
-    }
-
-    public SwitchBuilder setFallthrough(BasicBlock fallthrough) {
-      this.fallthrough = fallthrough;
-      return this;
-    }
-
-    public BasicBlock build(IRMetadata metadata) {
-      final int NOT_FOUND = -1;
-      Object2IntMap<BasicBlock> targetToSuccessorIndex = new Object2IntLinkedOpenHashMap<>();
-      targetToSuccessorIndex.defaultReturnValue(NOT_FOUND);
-
-      int[] keys = new int[keyToTarget.size()];
-      int[] targetBlockIndices = new int[keyToTarget.size()];
-      // Sort keys descending.
-      int count = 0;
-      IntIterator iter = keyToTarget.keySet().iterator();
-      while (iter.hasNext()) {
-        int key = iter.nextInt();
-        BasicBlock target = keyToTarget.get(key);
-        Integer targetIndex =
-            targetToSuccessorIndex.computeIfAbsent(target, b -> targetToSuccessorIndex.size());
-        keys[count] = key;
-        targetBlockIndices[count] = targetIndex;
-        count++;
-      }
-      Integer fallthroughIndex =
-          targetToSuccessorIndex.computeIfAbsent(fallthrough, b -> targetToSuccessorIndex.size());
-      IntSwitch newSwitch = new IntSwitch(value, keys, targetBlockIndices, fallthroughIndex);
-      newSwitch.setPosition(position);
-      BasicBlock newSwitchBlock = BasicBlock.createSwitchBlock(blockNumber, newSwitch, metadata);
-      for (BasicBlock successor : targetToSuccessorIndex.keySet()) {
-        newSwitchBlock.link(successor);
-      }
-      return newSwitchBlock;
-    }
-  }
-
-  public static class IfBuilder extends InstructionBuilder<IfBuilder> {
-
-    private final IRCode code;
-    private Value left;
-    private int right;
-    private BasicBlock target;
-    private BasicBlock fallthrough;
-
-    public IfBuilder(Position position, IRCode code) {
-      super(position);
-      this.code = code;
-    }
-
-    @Override
-    public IfBuilder self() {
-      return this;
-    }
-
-    public IfBuilder setLeft(Value left) {
-      this.left = left;
-      return this;
-    }
-
-    public IfBuilder setRight(int right) {
-      this.right = right;
-      return this;
-    }
-
-    public IfBuilder setTarget(BasicBlock target) {
-      this.target = target;
-      return this;
-    }
-
-    public IfBuilder setFallthrough(BasicBlock fallthrough) {
-      this.fallthrough = fallthrough;
-      return this;
-    }
-
-    public BasicBlock build() {
-      assert target != null;
-      assert fallthrough != null;
-      If newIf;
-      BasicBlock ifBlock;
-      if (right != 0) {
-        ConstNumber rightConst = code.createIntConstant(right);
-        rightConst.setPosition(position);
-        newIf = new If(IfType.EQ, ImmutableList.of(left, rightConst.dest()));
-        ifBlock = BasicBlock.createIfBlock(blockNumber, newIf, code.metadata(), rightConst);
-      } else {
-        newIf = new If(IfType.EQ, left);
-        ifBlock = BasicBlock.createIfBlock(blockNumber, newIf, code.metadata());
-      }
-      newIf.setPosition(position);
-      ifBlock.link(target);
-      ifBlock.link(fallthrough);
-      return ifBlock;
-    }
-  }
-
-  /**
-   * Covert the switch instruction to a sequence of if instructions checking for a specified set of
-   * keys, followed by a new switch with the remaining keys.
-   */
-  // TODO(b/270398965): Replace LinkedList.
-  @SuppressWarnings("JdkObsolete")
-  void convertSwitchToSwitchAndIfs(
-      IRCode code,
-      ListIterator<BasicBlock> blocksIterator,
-      BasicBlock originalBlock,
-      InstructionListIterator iterator,
-      IntSwitch theSwitch,
-      List<IntList> switches,
-      IntList keysToRemove) {
-
-    Position position = theSwitch.getPosition();
-
-    // Extract the information from the switch before removing it.
-    Int2ReferenceSortedMap<BasicBlock> keyToTarget = theSwitch.getKeyToTargetMap();
-
-    // Keep track of the current fallthrough, starting with the original.
-    BasicBlock fallthroughBlock = theSwitch.fallthroughBlock();
-
-    // Split the switch instruction into its own block and remove it.
-    iterator.previous();
-    BasicBlock originalSwitchBlock = iterator.split(code, blocksIterator);
-    assert !originalSwitchBlock.hasCatchHandlers();
-    assert originalSwitchBlock.getInstructions().size() == 1;
-    assert originalBlock.exit().isGoto();
-    theSwitch.moveDebugValues(originalBlock.exit());
-    blocksIterator.remove();
-    theSwitch.getBlock().detachAllSuccessors();
-    BasicBlock block = theSwitch.getBlock().unlinkSinglePredecessor();
-    assert theSwitch.getBlock().getPredecessors().size() == 0;
-    assert theSwitch.getBlock().getSuccessors().size() == 0;
-    assert block == originalBlock;
-
-    // Collect the new blocks for adding to the block list.
-    LinkedList<BasicBlock> newBlocks = new LinkedList<>();
-
-    // Build the switch-blocks backwards, to always have the fallthrough block in hand.
-    for (int i = switches.size() - 1; i >= 0; i--) {
-      SwitchBuilder switchBuilder = new SwitchBuilder(position);
-      switchBuilder.setValue(theSwitch.value());
-      IntList keys = switches.get(i);
-      for (int j = 0; j < keys.size(); j++) {
-        int key = keys.getInt(j);
-        switchBuilder.addKeyAndTarget(key, keyToTarget.get(key));
-      }
-      switchBuilder.setFallthrough(fallthroughBlock).setBlockNumber(code.getNextBlockNumber());
-      BasicBlock newSwitchBlock = switchBuilder.build(code.metadata());
-      newBlocks.addFirst(newSwitchBlock);
-      fallthroughBlock = newSwitchBlock;
-    }
-
-    // Build the if-blocks backwards, to always have the fallthrough block in hand.
-    for (int i = keysToRemove.size() - 1; i >= 0; i--) {
-      int key = keysToRemove.getInt(i);
-      BasicBlock peeledOffTarget = keyToTarget.get(key);
-      IfBuilder ifBuilder = new IfBuilder(position, code);
-      ifBuilder
-          .setLeft(theSwitch.value())
-          .setRight(key)
-          .setTarget(peeledOffTarget)
-          .setFallthrough(fallthroughBlock)
-          .setBlockNumber(code.getNextBlockNumber());
-      BasicBlock ifBlock = ifBuilder.build();
-      newBlocks.addFirst(ifBlock);
-      fallthroughBlock = ifBlock;
-    }
-
-    // Finally link the block before the original switch to the new block sequence.
-    originalBlock.link(fallthroughBlock);
-
-    // Finally add the blocks.
-    newBlocks.forEach(blocksIterator::add);
-  }
-
-  private static class Interval {
-
-    private final IntList keys = new IntArrayList();
-
-    public Interval(IntList... allKeys) {
-      assert allKeys.length > 0;
-      for (IntList keys : allKeys) {
-        assert keys.size() > 0;
-        this.keys.addAll(keys);
-      }
-    }
-
-    public int getMin() {
-      return keys.getInt(0);
-    }
-
-    public int getMax() {
-      return keys.getInt(keys.size() - 1);
-    }
-
-    public void addInterval(Interval other) {
-      assert getMax() < other.getMin();
-      keys.addAll(other.keys);
-    }
-
-    public long packedSavings(InternalOutputMode mode) {
-      long packedTargets = (long) getMax() - (long) getMin() + 1;
-      if (!IntSwitch.canBePacked(mode, packedTargets)) {
-        return Long.MIN_VALUE + 1;
-      }
-      long sparseCost =
-          IntSwitch.baseSparseSize(mode) + IntSwitch.sparsePayloadSize(mode, keys.size());
-      long packedCost =
-          IntSwitch.basePackedSize(mode) + IntSwitch.packedPayloadSize(mode, packedTargets);
-      return sparseCost - packedCost;
-    }
-
-    public long estimatedSize(InternalOutputMode mode) {
-      return IntSwitch.estimatedSize(mode, keys.toIntArray());
-    }
-  }
-
-  private Interval combineOrAddInterval(
-      List<Interval> intervals, Interval previous, Interval current) {
-    // As a first iteration, we only combine intervals if their packed size is less than their
-    // sparse counterpart. In CF we will have to add a load and a jump which add to the
-    // stack map table (1 is the size of a same entry).
-    InternalOutputMode mode = options.getInternalOutputMode();
-    int penalty = mode.isGeneratingClassFiles() ? 3 + 1 : 0;
-    if (previous == null) {
-      intervals.add(current);
-      return current;
-    }
-    Interval combined = new Interval(previous.keys, current.keys);
-    long packedSavings = combined.packedSavings(mode);
-    if (packedSavings <= 0
-        || packedSavings < previous.estimatedSize(mode) + current.estimatedSize(mode) - penalty) {
-      intervals.add(current);
-      return current;
-    } else {
-      intervals.set(intervals.size() - 1, combined);
-      return combined;
-    }
-  }
-
-  private void tryAddToBiggestSavings(
-      Set<Interval> biggestPackedSet,
-      PriorityQueue<Interval> intervals,
-      Interval toAdd,
-      int maximumNumberOfSwitches) {
-    assert !biggestPackedSet.contains(toAdd);
-    long savings = toAdd.packedSavings(options.getInternalOutputMode());
-    if (savings <= 0) {
-      return;
-    }
-    if (intervals.size() < maximumNumberOfSwitches) {
-      intervals.add(toAdd);
-      biggestPackedSet.add(toAdd);
-    } else if (savings > intervals.peek().packedSavings(options.getInternalOutputMode())) {
-      intervals.add(toAdd);
-      biggestPackedSet.add(toAdd);
-      biggestPackedSet.remove(intervals.poll());
-    }
-  }
-
-  private int sizeForKeysWrittenAsIfs(ValueType type, Collection<Integer> keys) {
-    int ifsSize = If.estimatedSize(options.getInternalOutputMode()) * keys.size();
-    // In Cf we also require a load as well (and a stack map entry)
-    if (options.getInternalOutputMode().isGeneratingClassFiles()) {
-      ifsSize += keys.size() * (3 + 1);
-    }
-    for (int k : keys) {
-      if (k != 0) {
-        ifsSize += ConstNumber.estimatedSize(options.getInternalOutputMode(), type, k);
-      }
-    }
-    return ifsSize;
-  }
-
-  private int codeUnitMargin() {
-    return options.getInternalOutputMode().isGeneratingClassFiles() ? 3 : 1;
-  }
-
-  private int findIfsForCandidates(
-      List<Interval> newSwitches, IntSwitch theSwitch, IntList outliers) {
-    Set<Interval> switchesToRemove = new HashSet<>();
-    InternalOutputMode mode = options.getInternalOutputMode();
-    int outliersAsIfSize = 0;
-    // The candidateForIfs is either an index to a switch that can be eliminated totally or a sparse
-    // where removing a key may produce a greater saving. It is only if keys are small in the packed
-    // switch that removing the keys makes sense (size wise).
-    for (Interval candidate : newSwitches) {
-      int maxIfBudget = 10;
-      long switchSize = candidate.estimatedSize(mode);
-      int sizeOfAllKeysAsIf = sizeForKeysWrittenAsIfs(theSwitch.value().outType(), candidate.keys);
-      if (candidate.keys.size() <= maxIfBudget
-          && sizeOfAllKeysAsIf < switchSize - codeUnitMargin()) {
-        outliersAsIfSize += sizeOfAllKeysAsIf;
-        switchesToRemove.add(candidate);
-        outliers.addAll(candidate.keys);
-        continue;
-      }
-      // One could do something clever here, but we use a simple algorithm that use the fact that
-      // all keys are sorted in ascending order and that the smallest absolute value will give the
-      // best saving.
-      IntList candidateKeys = candidate.keys;
-      int smallestPosition = -1;
-      long smallest = Long.MAX_VALUE;
-      for (int i = 0; i < candidateKeys.size(); i++) {
-        long current = Math.abs((long) candidateKeys.getInt(i));
-        if (current < smallest) {
-          smallestPosition = i;
-          smallest = current;
-        }
-      }
-      // Add as many keys forward and backward as we have budget and we decrease in size.
-      IntList ifKeys = new IntArrayList();
-      ifKeys.add(candidateKeys.getInt(smallestPosition));
-      long previousSavings = 0;
-      long currentSavings =
-          switchSize
-              - sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys)
-              - IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
-      int minIndex = smallestPosition - 1;
-      int maxIndex = smallestPosition + 1;
-      while (ifKeys.size() < maxIfBudget && currentSavings > previousSavings) {
-        if (minIndex >= 0 && maxIndex < candidateKeys.size()) {
-          long valMin = Math.abs((long) candidateKeys.getInt(minIndex));
-          int valMax = Math.abs(candidateKeys.getInt(maxIndex));
-          if (valMax <= valMin) {
-            ifKeys.add(candidateKeys.getInt(maxIndex++));
-          } else {
-            ifKeys.add(candidateKeys.getInt(minIndex--));
-          }
-        } else if (minIndex >= 0) {
-          ifKeys.add(candidateKeys.getInt(minIndex--));
-        } else if (maxIndex < candidateKeys.size()) {
-          ifKeys.add(candidateKeys.getInt(maxIndex++));
-        } else {
-          // No more elements to add as if's.
-          break;
-        }
-        previousSavings = currentSavings;
-        currentSavings =
-            switchSize
-                - sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys)
-                - IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
-      }
-      if (previousSavings >= currentSavings) {
-        // Remove the last added key since it did not contribute to savings.
-        int lastKey = ifKeys.getInt(ifKeys.size() - 1);
-        ifKeys.removeInt(ifKeys.size() - 1);
-        if (lastKey == candidateKeys.getInt(minIndex + 1)) {
-          minIndex++;
-        } else {
-          maxIndex--;
-        }
-      }
-      // Adjust pointers into the candidate keys.
-      minIndex++;
-      maxIndex--;
-      if (ifKeys.size() > 0) {
-        int ifsSize = sizeForKeysWrittenAsIfs(theSwitch.value().outType(), ifKeys);
-        long newSwitchSize =
-            IntSwitch.estimatedSparseSize(mode, candidateKeys.size() - ifKeys.size());
-        if (newSwitchSize + ifsSize + codeUnitMargin() < switchSize) {
-          candidateKeys.removeElements(minIndex, maxIndex);
-          outliers.addAll(ifKeys);
-          outliersAsIfSize += ifsSize;
-        }
-      }
-    }
-    newSwitches.removeAll(switchesToRemove);
-    return outliersAsIfSize;
-  }
-
-  public boolean rewriteSwitch(IRCode code) {
-    return rewriteSwitch(code, SwitchCaseAnalyzer.getInstance());
-  }
-
-  private boolean rewriteSwitch(IRCode code, SwitchCaseAnalyzer switchCaseAnalyzer) {
-    if (!options.isSwitchRewritingEnabled()) {
-      return false;
-    }
-    if (!code.metadata().mayHaveSwitch()) {
-      return false;
-    }
-    return rewriteSwitchFull(code, switchCaseAnalyzer);
-  }
-
-  private boolean rewriteSwitchFull(IRCode code, SwitchCaseAnalyzer switchCaseAnalyzer) {
-    boolean needToRemoveUnreachableBlocks = false;
-    ListIterator<BasicBlock> blocksIterator = code.listIterator();
-    while (blocksIterator.hasNext()) {
-      BasicBlock block = blocksIterator.next();
-      InstructionListIterator iterator = block.listIterator(code);
-      while (iterator.hasNext()) {
-        Instruction instruction = iterator.next();
-        if (instruction.isSwitch()) {
-          Switch theSwitch = instruction.asSwitch();
-          if (options.testing.enableDeadSwitchCaseElimination) {
-            SwitchCaseEliminator eliminator =
-                removeUnnecessarySwitchCases(code, theSwitch, iterator, switchCaseAnalyzer);
-            if (eliminator.mayHaveIntroducedUnreachableBlocks()) {
-              needToRemoveUnreachableBlocks = true;
-            }
-
-            iterator.previous();
-            instruction = iterator.next();
-            if (instruction.isGoto()) {
-              continue;
-            }
-
-            assert instruction.isSwitch();
-            theSwitch = instruction.asSwitch();
-          }
-          if (theSwitch.isIntSwitch()) {
-            rewriteIntSwitch(code, blocksIterator, block, iterator, theSwitch.asIntSwitch());
-          }
-        }
-      }
-    }
-
-    // Rewriting of switches introduces new branching structure. It relies on critical edges
-    // being split on the way in but does not maintain this property. We therefore split
-    // critical edges at exit.
-    code.splitCriticalEdges();
-
-    Set<Value> affectedValues =
-        needToRemoveUnreachableBlocks ? code.removeUnreachableBlocks() : ImmutableSet.of();
-    if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView).narrowing(affectedValues);
-    }
-    assert code.isConsistentSSA(appView);
-    return !affectedValues.isEmpty();
-  }
-
-  void rewriteSingleKeySwitchToIf(
-      IRCode code, BasicBlock block, InstructionListIterator iterator, IntSwitch theSwitch) {
-    // Rewrite the switch to an if.
-    int fallthroughBlockIndex = theSwitch.getFallthroughBlockIndex();
-    int caseBlockIndex = theSwitch.targetBlockIndices()[0];
-    if (fallthroughBlockIndex < caseBlockIndex) {
-      block.swapSuccessorsByIndex(fallthroughBlockIndex, caseBlockIndex);
-    }
-    If replacement;
-    if (theSwitch.isIntSwitch() && theSwitch.asIntSwitch().getFirstKey() == 0) {
-      replacement = new If(IfType.EQ, theSwitch.value());
-    } else {
-      Instruction labelConst = theSwitch.materializeFirstKey(appView, code);
-      labelConst.setPosition(theSwitch.getPosition());
-      iterator.previous();
-      iterator.add(labelConst);
-      Instruction dummy = iterator.next();
-      assert dummy == theSwitch;
-      replacement = new If(IfType.EQ, ImmutableList.of(theSwitch.value(), labelConst.outValue()));
-    }
-    iterator.replaceCurrentInstruction(replacement);
-  }
-
-  private void rewriteIntSwitch(
-      IRCode code,
-      ListIterator<BasicBlock> blockIterator,
-      BasicBlock block,
-      InstructionListIterator iterator,
-      IntSwitch theSwitch) {
-    if (disableSwitchToIfRewritingForClassIdComparisons(theSwitch)) {
-      return;
-    }
-
-    if (theSwitch.numberOfKeys() == 1) {
-      rewriteSingleKeySwitchToIf(code, block, iterator, theSwitch);
-      return;
-    }
-
-    // If there are more than 1 key, we use the following algorithm to find keys to combine.
-    // First, scan through the keys forward and combine each packed interval with the
-    // previous interval if it gives a net saving.
-    // Secondly, go through all created intervals and combine the ones without a saving into
-    // a single interval and keep a max number of packed switches.
-    // Finally, go through all intervals and check if the switch or part of the switch
-    // should be transformed to ifs.
-
-    // Phase 1: Combine packed intervals.
-    InternalOutputMode mode = options.getInternalOutputMode();
-    int[] keys = theSwitch.getKeys();
-    int maxNumberOfIfsOrSwitches = 10;
-    PriorityQueue<Interval> biggestPackedSavings =
-        new PriorityQueue<>((x, y) -> Long.compare(y.packedSavings(mode), x.packedSavings(mode)));
-    Set<Interval> biggestPackedSet = new HashSet<>();
-    List<Interval> intervals = new ArrayList<>();
-    int previousKey = keys[0];
-    IntList currentKeys = new IntArrayList();
-    currentKeys.add(previousKey);
-    Interval previousInterval = null;
-    for (int i = 1; i < keys.length; i++) {
-      int key = keys[i];
-      if (((long) key - (long) previousKey) > 1) {
-        Interval current = new Interval(currentKeys);
-        Interval added = combineOrAddInterval(intervals, previousInterval, current);
-        if (added != current && biggestPackedSet.contains(previousInterval)) {
-          biggestPackedSet.remove(previousInterval);
-          biggestPackedSavings.remove(previousInterval);
-        }
-        tryAddToBiggestSavings(
-            biggestPackedSet, biggestPackedSavings, added, maxNumberOfIfsOrSwitches);
-        previousInterval = added;
-        currentKeys = new IntArrayList();
-      }
-      currentKeys.add(key);
-      previousKey = key;
-    }
-    Interval current = new Interval(currentKeys);
-    Interval added = combineOrAddInterval(intervals, previousInterval, current);
-    if (added != current && biggestPackedSet.contains(previousInterval)) {
-      biggestPackedSet.remove(previousInterval);
-      biggestPackedSavings.remove(previousInterval);
-    }
-    tryAddToBiggestSavings(biggestPackedSet, biggestPackedSavings, added, maxNumberOfIfsOrSwitches);
-
-    // Phase 2: combine sparse intervals into a single bin.
-    // Check if we should save a space for a sparse switch, if so, remove the switch with
-    // the smallest savings.
-    if (biggestPackedSet.size() == maxNumberOfIfsOrSwitches
-        && maxNumberOfIfsOrSwitches < intervals.size()) {
-      biggestPackedSet.remove(biggestPackedSavings.poll());
-    }
-    Interval sparse = null;
-    List<Interval> newSwitches = new ArrayList<>(maxNumberOfIfsOrSwitches);
-    for (int i = 0; i < intervals.size(); i++) {
-      Interval interval = intervals.get(i);
-      if (biggestPackedSet.contains(interval)) {
-        newSwitches.add(interval);
-      } else if (sparse == null) {
-        sparse = interval;
-        newSwitches.add(sparse);
-      } else {
-        sparse.addInterval(interval);
-      }
-    }
-
-    // Phase 3: at this point we are guaranteed to have the biggest saving switches
-    // in newIntervals, potentially with a switch combining the remaining intervals.
-    // Now we check to see if we can create any if's to reduce size.
-    IntList outliers = new IntArrayList();
-    int outliersAsIfSize =
-        appView.options().testing.enableSwitchToIfRewriting
-            ? findIfsForCandidates(newSwitches, theSwitch, outliers)
-            : 0;
-
-    long newSwitchesSize = 0;
-    List<IntList> newSwitchSequences = new ArrayList<>(newSwitches.size());
-    for (Interval interval : newSwitches) {
-      newSwitchesSize += interval.estimatedSize(mode);
-      newSwitchSequences.add(interval.keys);
-    }
-
-    long currentSize = IntSwitch.estimatedSize(mode, theSwitch.getKeys());
-    if (newSwitchesSize + outliersAsIfSize + codeUnitMargin() < currentSize) {
-      convertSwitchToSwitchAndIfs(
-          code, blockIterator, block, iterator, theSwitch, newSwitchSequences, outliers);
-    }
-  }
-
-  // TODO(b/181732463): We currently disable switch-to-if rewritings for switches on $r8$classId
-  //  field values (from horizontal class merging. See bug for more details.
-  private boolean disableSwitchToIfRewritingForClassIdComparisons(IntSwitch theSwitch) {
-    Value switchValue = theSwitch.value().getAliasedValue();
-    if (!switchValue.isDefinedByInstructionSatisfying(Instruction::isInstanceGet)) {
-      return false;
-    }
-    AppInfoWithLiveness appInfo = appView.appInfoWithLiveness();
-    if (appInfo == null) {
-      return false;
-    }
-    InstanceGet instanceGet = switchValue.getDefinition().asInstanceGet();
-    SingleProgramFieldResolutionResult resolutionResult =
-        appInfo.resolveField(instanceGet.getField()).asSingleProgramFieldResolutionResult();
-    if (resolutionResult == null) {
-      return false;
-    }
-    DexEncodedField resolvedField = resolutionResult.getResolvedField();
-    return HorizontalClassMergerUtils.isClassIdField(appView, resolvedField);
-  }
-
-  private SwitchCaseEliminator removeUnnecessarySwitchCases(
-      IRCode code,
-      Switch theSwitch,
-      InstructionListIterator iterator,
-      SwitchCaseAnalyzer switchCaseAnalyzer) {
-    BasicBlock defaultTarget = theSwitch.fallthroughBlock();
-    SwitchCaseEliminator eliminator = new SwitchCaseEliminator(theSwitch, iterator);
-    BasicBlockBehavioralSubsumption behavioralSubsumption =
-        new BasicBlockBehavioralSubsumption(appView, code);
-
-    // Compute the set of switch cases that can be removed.
-    boolean hasSwitchCaseToDefaultRewrite = false;
-    AbstractValue switchAbstractValue = theSwitch.value().getAbstractValue(appView, code.context());
-    for (int i = 0; i < theSwitch.numberOfKeys(); i++) {
-      BasicBlock targetBlock = theSwitch.targetBlock(i);
-
-      if (switchCaseAnalyzer.switchCaseIsAlwaysHit(theSwitch, i)) {
-        eliminator.markSwitchCaseAsAlwaysHit(i);
-        break;
-      }
-
-      // This switch case can be removed if the behavior of the target block is equivalent to the
-      // behavior of the default block, or if the switch case is unreachable.
-      if (switchCaseAnalyzer.switchCaseIsUnreachable(theSwitch, switchAbstractValue, i)) {
-        eliminator.markSwitchCaseForRemoval(i);
-      } else if (behavioralSubsumption.isSubsumedBy(
-          theSwitch.value(), targetBlock, defaultTarget)) {
-        eliminator.markSwitchCaseForRemoval(i);
-        hasSwitchCaseToDefaultRewrite = true;
-      }
-    }
-
-    if (eliminator.isFallthroughLive()
-        && !hasSwitchCaseToDefaultRewrite
-        && switchCaseAnalyzer.switchFallthroughIsNeverHit(theSwitch, switchAbstractValue)) {
-      eliminator.markSwitchFallthroughAsNeverHit();
-    }
-
-    eliminator.optimize();
-    return eliminator;
-  }
-
-  /**
-   * Rewrite all branch targets to the destination of trivial goto chains when possible. Does not
-   * rewrite fallthrough targets as that would require block reordering and the transformation only
-   * makes sense after SSA destruction where there are no phis.
-   */
-  public static void collapseTrivialGotos(AppView<?> appView, IRCode code) {
-    assert code.isConsistentGraph(appView);
-    List<BasicBlock> blocksToRemove = new ArrayList<>();
-    // Rewrite all non-fallthrough targets to the end of trivial goto chains and remove
-    // first round of trivial goto blocks.
-    ListIterator<BasicBlock> iterator = code.listIterator();
-    assert iterator.hasNext();
-    BasicBlock block = iterator.next();
-    BasicBlock nextBlock;
-
-    do {
-      nextBlock = iterator.hasNext() ? iterator.next() : null;
-      if (block.isTrivialGoto()) {
-        collapseTrivialGoto(code, block, nextBlock, blocksToRemove);
-      }
-      if (block.exit().isIf()) {
-        collapseIfTrueTarget(block);
-      }
-      if (block.exit().isSwitch()) {
-        collapseNonFallthroughSwitchTargets(block);
-      }
-      block = nextBlock;
-    } while (nextBlock != null);
-    code.removeBlocks(blocksToRemove);
-    // Get rid of gotos to the next block.
-    while (!blocksToRemove.isEmpty()) {
-      blocksToRemove = new ArrayList<>();
-      iterator = code.listIterator();
-      block = iterator.next();
-      do {
-        nextBlock = iterator.hasNext() ? iterator.next() : null;
-        if (block.isTrivialGoto()) {
-          collapseTrivialGoto(code, block, nextBlock, blocksToRemove);
-        }
-        block = nextBlock;
-      } while (block != null);
-      code.removeBlocks(blocksToRemove);
-    }
-    assert removedTrivialGotos(code);
-    assert code.isConsistentGraph(appView);
-  }
-
   private boolean checkArgumentType(InvokeMethod invoke, int argumentIndex) {
     // TODO(sgjesse): Insert cast if required.
     TypeElement returnType =
@@ -1309,333 +418,6 @@
     return changed;
   }
 
-  enum RemoveCheckCastInstructionIfTrivialResult {
-    NO_REMOVALS,
-    REMOVED_CAST_DO_NARROW
-  }
-
-  public void removeTrivialCheckCastAndInstanceOfInstructions(
-      IRCode code,
-      ProgramMethod context,
-      MethodProcessor methodProcessor,
-      MethodProcessingContext methodProcessingContext) {
-    if (!appView.enableWholeProgramOptimizations()) {
-      return;
-    }
-
-    assert appView.appInfo().hasLiveness();
-    AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
-
-    if (!appView.options().testing.enableCheckCastAndInstanceOfRemoval) {
-      return;
-    }
-
-    IRMetadata metadata = code.metadata();
-    if (!metadata.mayHaveCheckCast() && !metadata.mayHaveInstanceOf()) {
-      return;
-    }
-
-    // If we can remove a CheckCast it is due to us having at least as much information about the
-    // type as the CheckCast gives. We then need to propagate that information to the users of
-    // the CheckCast to ensure further optimizations and removals of CheckCast:
-    //
-    //    : 1: NewArrayEmpty        v2 <- v1(1) java.lang.String[]  <-- v2 = String[]
-    // ...
-    //    : 2: CheckCast            v5 <- v2; java.lang.Object[]    <-- v5 = Object[]
-    // ...
-    //    : 3: ArrayGet             v7 <- v5, v6(0)                 <-- v7 = Object
-    //    : 4: CheckCast            v8 <- v7; java.lang.String      <-- v8 = String
-    // ...
-    //
-    // When looking at line 2 we can conclude that the CheckCast is trivial because v2 is String[]
-    // and remove it. However, v7 is still only known to be Object and we cannot remove the
-    // CheckCast at line 4 unless we update v7 with the most precise information by narrowing the
-    // affected values of v5. We therefore have to run the type analysis after each CheckCast
-    // removal.
-    TypeAnalysis typeAnalysis = new TypeAnalysis(appView);
-    Set<Value> affectedValues = Sets.newIdentityHashSet();
-    InstructionListIterator it = code.instructionListIterator();
-    boolean needToRemoveTrivialPhis = false;
-    while (it.hasNext()) {
-      Instruction current = it.next();
-      if (current.isCheckCast()) {
-        boolean hasPhiUsers = current.outValue().hasPhiUsers();
-        RemoveCheckCastInstructionIfTrivialResult removeResult =
-            removeCheckCastInstructionIfTrivial(
-                appViewWithLiveness,
-                current.asCheckCast(),
-                it,
-                code,
-                context,
-                affectedValues,
-                methodProcessor,
-                methodProcessingContext);
-        if (removeResult != RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS) {
-          assert removeResult == RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
-          needToRemoveTrivialPhis |= hasPhiUsers;
-          typeAnalysis.narrowing(affectedValues);
-          affectedValues.clear();
-        }
-      } else if (current.isInstanceOf()) {
-        boolean hasPhiUsers = current.outValue().hasPhiUsers();
-        if (removeInstanceOfInstructionIfTrivial(
-            appViewWithLiveness, current.asInstanceOf(), it, code)) {
-          needToRemoveTrivialPhis |= hasPhiUsers;
-        }
-      }
-    }
-    // ... v1
-    // ...
-    // v2 <- check-cast v1, T
-    // v3 <- phi(v1, v2)
-    // Removing check-cast may result in a trivial phi:
-    // v3 <- phi(v1, v1)
-    if (needToRemoveTrivialPhis) {
-      code.removeAllDeadAndTrivialPhis(affectedValues);
-      if (!affectedValues.isEmpty()) {
-        typeAnalysis.narrowing(affectedValues);
-      }
-    }
-    assert code.isConsistentSSA(appView);
-  }
-
-  // Returns true if the given check-cast instruction was removed.
-  private RemoveCheckCastInstructionIfTrivialResult removeCheckCastInstructionIfTrivial(
-      AppView<AppInfoWithLiveness> appViewWithLiveness,
-      CheckCast checkCast,
-      InstructionListIterator it,
-      IRCode code,
-      ProgramMethod context,
-      Set<Value> affectedValues,
-      MethodProcessor methodProcessor,
-      MethodProcessingContext methodProcessingContext) {
-    Value inValue = checkCast.object();
-    Value outValue = checkCast.outValue();
-    DexType castType = checkCast.getType();
-    DexType baseCastType = castType.toBaseType(dexItemFactory);
-
-    // If the cast type is not accessible in the current context, we should not remove the cast
-    // in order to preserve runtime errors. Note that JVM and ART behave differently: see
-    // {@link com.android.tools.r8.ir.optimize.checkcast.IllegalAccessErrorTest}.
-    if (baseCastType.isClassType()) {
-      DexClass baseCastClass = appView.definitionFor(baseCastType);
-      if (baseCastClass == null
-          || AccessControl.isClassAccessible(baseCastClass, code.context(), appViewWithLiveness)
-              .isPossiblyFalse()) {
-        return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
-      }
-    }
-
-    if (!appView
-        .getOpenClosedInterfacesCollection()
-        .isDefinitelyInstanceOfStaticType(appViewWithLiveness, inValue)) {
-      return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
-    }
-
-    // If the in-value is `null` and the cast-type is a float-array type, then trivial check-cast
-    // elimination may lead to verification errors. See b/123269162.
-    if (options.canHaveArtCheckCastVerifierBug()) {
-      if (inValue.getType().isNullType()
-          && castType.isArrayType()
-          && castType.toBaseType(dexItemFactory).isFloatType()) {
-        return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
-      }
-    }
-
-    // If casting to an array of an interface type elimination may lead to verification errors.
-    // See b/132420510 and b/223424356.
-    if (options.canHaveIncorrectJoinForArrayOfInterfacesBug()) {
-      if (castType.isArrayType()) {
-        DexType baseType = castType.toBaseType(dexItemFactory);
-        if (baseType.isClassType() && baseType.isInterface(appViewWithLiveness)) {
-          return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
-        }
-      }
-    }
-
-    TypeElement inTypeLattice = inValue.getType();
-    TypeElement outTypeLattice = outValue.getType();
-    TypeElement castTypeLattice = castType.toTypeElement(appView, inTypeLattice.nullability());
-
-    assert inTypeLattice.nullability().lessThanOrEqual(outTypeLattice.nullability());
-
-    if (inTypeLattice.lessThanOrEqual(castTypeLattice, appView)) {
-      // 1) Trivial cast.
-      //   A a = ...
-      //   A a' = (A) a;
-      // 2) Up-cast: we already have finer type info.
-      //   A < B
-      //   A a = ...
-      //   B b = (B) a;
-      assert inTypeLattice.lessThanOrEqual(outTypeLattice, appView);
-      // The removeOrReplaceByDebugLocalWrite will propagate the incoming value for the CheckCast
-      // to the users of the CheckCast's out value.
-      //
-      // v2 = CheckCast A v1  ~~>  DebugLocalWrite $v0 <- v1
-      //
-      // The DebugLocalWrite is not a user of the outvalue, we therefore have to wait and take the
-      // CheckCast invalue users that includes the potential DebugLocalWrite.
-      removeOrReplaceByDebugLocalWrite(checkCast, it, inValue, outValue);
-      affectedValues.addAll(inValue.affectedValues());
-      return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
-    }
-
-    // If values of cast type are guaranteed to be null, then the out-value must be null if the cast
-    // succeeds. After removing all usages of the out-value, the check-cast instruction is replaced
-    // by a call to throwClassCastExceptionIfNotNull() to allow dead code elimination of the cast
-    // type.
-    if (castType.isClassType()
-        && castType.isAlwaysNull(appViewWithLiveness)
-        && !outValue.hasDebugUsers()) {
-      // Replace all usages of the out-value by null.
-      it.previous();
-      Value nullValue = it.insertConstNullInstruction(code, options);
-      it.next();
-      checkCast.outValue().replaceUsers(nullValue);
-      affectedValues.addAll(nullValue.affectedValues());
-
-      // Replace the check-cast instruction by throwClassCastExceptionIfNotNull().
-      UtilityMethodForCodeOptimizations throwClassCastExceptionIfNotNullMethod =
-          UtilityMethodsForCodeOptimizations.synthesizeThrowClassCastExceptionIfNotNullMethod(
-              appView, methodProcessor.getEventConsumer(), methodProcessingContext);
-      throwClassCastExceptionIfNotNullMethod.optimize(methodProcessor);
-      InvokeStatic replacement =
-          InvokeStatic.builder()
-              .setMethod(throwClassCastExceptionIfNotNullMethod.getMethod())
-              .setSingleArgument(checkCast.object())
-              .setPosition(checkCast)
-              .build();
-      it.replaceCurrentInstruction(replacement);
-      assert replacement.lookupSingleTarget(appView, context) != null;
-      return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
-    }
-
-    // If the cast is guaranteed to succeed and only there to ensure the program type checks, then
-    // check if the program would still type check after removing the cast.
-    if (checkCast.isSafeCheckCast()
-        || checkCast
-            .getFirstOperand()
-            .getDynamicType(appViewWithLiveness)
-            .getDynamicUpperBoundType()
-            .lessThanOrEqualUpToNullability(castTypeLattice, appView)) {
-      TypeElement useType =
-          TypeUtils.computeUseType(appViewWithLiveness, context, checkCast.outValue());
-      if (inTypeLattice.lessThanOrEqualUpToNullability(useType, appView)) {
-        return RemoveCheckCastInstructionIfTrivialResult.REMOVED_CAST_DO_NARROW;
-      }
-    }
-
-    // Otherwise, keep the checkcast to preserve verification errors. E.g., down-cast:
-    // A < B < C
-    // c = ...        // Even though we know c is of type A,
-    // a' = (B) c;    // (this could be removed, since chained below.)
-    // a'' = (A) a';  // this should remain for runtime verification.
-    assert !inTypeLattice.isDefinitelyNull() || (inValue.isPhi() && !inTypeLattice.isNullType());
-    assert outTypeLattice.equalUpToNullability(castTypeLattice);
-    return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
-  }
-
-  // Returns true if the given instance-of instruction was removed.
-  private boolean removeInstanceOfInstructionIfTrivial(
-      AppView<AppInfoWithLiveness> appViewWithLiveness,
-      InstanceOf instanceOf,
-      InstructionListIterator it,
-      IRCode code) {
-    ProgramMethod context = code.context();
-
-    // If the instance-of type is not accessible in the current context, we should not remove the
-    // instance-of instruction in order to preserve IllegalAccessError.
-    DexType instanceOfBaseType = instanceOf.type().toBaseType(dexItemFactory);
-    if (instanceOfBaseType.isClassType()) {
-      DexClass instanceOfClass = appView.definitionFor(instanceOfBaseType);
-      if (instanceOfClass == null
-          || AccessControl.isClassAccessible(instanceOfClass, context, appViewWithLiveness)
-              .isPossiblyFalse()) {
-        return false;
-      }
-    }
-
-    Value inValue = instanceOf.value();
-    if (!appView
-        .getOpenClosedInterfacesCollection()
-        .isDefinitelyInstanceOfStaticType(appViewWithLiveness, inValue)) {
-      return false;
-    }
-
-    TypeElement inType = inValue.getType();
-    TypeElement instanceOfType =
-        TypeElement.fromDexType(instanceOf.type(), inType.nullability(), appView);
-    Value aliasValue = inValue.getAliasedValue();
-
-    InstanceOfResult result = InstanceOfResult.UNKNOWN;
-    if (inType.isDefinitelyNull()) {
-      result = InstanceOfResult.FALSE;
-    } else if (inType.lessThanOrEqual(instanceOfType, appView) && !inType.isNullable()) {
-      result = InstanceOfResult.TRUE;
-    } else if (!aliasValue.isPhi()
-        && aliasValue.definition.isCreatingInstanceOrArray()
-        && instanceOfType.strictlyLessThan(inType, appView)) {
-      result = InstanceOfResult.FALSE;
-    } else if (appView.appInfo().hasLiveness()) {
-      if (instanceOf.type().isClassType()
-          && isNeverInstantiatedDirectlyOrIndirectly(instanceOf.type())) {
-        // The type of the instance-of instruction is a program class, and is never instantiated
-        // directly or indirectly. Thus, the in-value must be null, meaning that the instance-of
-        // instruction will always evaluate to false.
-        result = InstanceOfResult.FALSE;
-      }
-
-      if (result == InstanceOfResult.UNKNOWN) {
-        if (inType.isClassType()
-            && isNeverInstantiatedDirectlyOrIndirectly(inType.asClassType().getClassType())) {
-          // The type of the in-value is a program class, and is never instantiated directly or
-          // indirectly. This, the in-value must be null, meaning that the instance-of instruction
-          // will always evaluate to false.
-          result = InstanceOfResult.FALSE;
-        }
-      }
-
-      if (result == InstanceOfResult.UNKNOWN) {
-        Value aliasedValue =
-            inValue.getSpecificAliasedValue(
-                value ->
-                    value.isDefinedByInstructionSatisfying(
-                        Instruction::isAssumeWithDynamicTypeAssumption));
-        if (aliasedValue != null) {
-          DynamicTypeWithUpperBound dynamicType =
-              aliasedValue.getDefinition().asAssume().getDynamicTypeAssumption().getDynamicType();
-          Nullability nullability = dynamicType.getNullability();
-          if (nullability.isDefinitelyNull()) {
-            result = InstanceOfResult.FALSE;
-          } else if (dynamicType.getDynamicUpperBoundType().lessThanOrEqual(instanceOfType, appView)
-              && (!inType.isNullable() || !nullability.isNullable())) {
-            result = InstanceOfResult.TRUE;
-          }
-        }
-      }
-    }
-    if (result != InstanceOfResult.UNKNOWN) {
-      ConstNumber newInstruction =
-          new ConstNumber(
-              new Value(
-                  code.valueNumberGenerator.next(),
-                  TypeElement.getInt(),
-                  instanceOf.outValue().getLocalInfo()),
-              result == InstanceOfResult.TRUE ? 1 : 0);
-      it.replaceCurrentInstruction(newInstruction);
-      return true;
-    }
-    return false;
-  }
-
-  private boolean isNeverInstantiatedDirectlyOrIndirectly(DexType type) {
-    assert appView.appInfo().hasLiveness();
-    assert type.isClassType();
-    DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(type));
-    return clazz != null
-        && !appView.appInfo().withLiveness().isInstantiatedDirectlyOrIndirectly(clazz);
-  }
-
   public static void removeOrReplaceByDebugLocalWrite(
       Instruction currentInstruction, InstructionListIterator it, Value inValue, Value outValue) {
     if (outValue.hasLocalInfo() && outValue.getLocalInfo() != inValue.getLocalInfo()) {
@@ -1688,6 +470,53 @@
     assert code.isConsistentSSA(appView);
   }
 
+  public void rewriteKnownArrayLengthCalls(IRCode code) {
+    InstructionListIterator iterator = code.instructionListIterator();
+    while (iterator.hasNext()) {
+      Instruction current = iterator.next();
+      if (!current.isArrayLength()) {
+        continue;
+      }
+
+      ArrayLength arrayLength = current.asArrayLength();
+      if (arrayLength.hasOutValue() && arrayLength.outValue().hasLocalInfo()) {
+        continue;
+      }
+
+      Value array = arrayLength.array().getAliasedValue();
+      if (array.isPhi() || !arrayLength.array().isNeverNull() || array.hasLocalInfo()) {
+        continue;
+      }
+
+      AbstractValue abstractValue = array.getAbstractValue(appView, code.context());
+      if (!abstractValue.hasKnownArrayLength() && !array.isNeverNull()) {
+        continue;
+      }
+      Instruction arrayDefinition = array.getDefinition();
+      assert arrayDefinition != null;
+
+      Set<Phi> phiUsers = arrayLength.outValue().uniquePhiUsers();
+      if (arrayDefinition.isNewArrayEmpty()) {
+        Value size = arrayDefinition.asNewArrayEmpty().size();
+        arrayLength.outValue().replaceUsers(size);
+        iterator.removeOrReplaceByDebugLocalRead();
+      } else if (arrayDefinition.isNewArrayFilledData()) {
+        long size = arrayDefinition.asNewArrayFilledData().size;
+        if (size > Integer.MAX_VALUE) {
+          continue;
+        }
+        iterator.replaceCurrentInstructionWithConstInt(code, (int) size);
+      } else if (abstractValue.hasKnownArrayLength()) {
+        iterator.replaceCurrentInstructionWithConstInt(code, abstractValue.getKnownArrayLength());
+      } else {
+        continue;
+      }
+
+      phiUsers.forEach(Phi::removeTrivialPhi);
+    }
+    assert code.isConsistentSSA(appView);
+  }
+
   /**
    * If an instruction is known to be a binop/lit8 or binop//lit16 instruction, update the
    * instruction to use its own constant that will be defined just before the instruction. This
@@ -2105,431 +934,6 @@
     }
   }
 
-  private short[] computeArrayFilledData(Value[] values, int size, int elementSize) {
-    for (Value v : values) {
-      if (!v.isConstant()) {
-        return null;
-      }
-    }
-    if (elementSize == 1) {
-      short[] result = new short[(size + 1) / 2];
-      for (int i = 0; i < size; i += 2) {
-        short value =
-            (short) (values[i].getConstInstruction().asConstNumber().getIntValue() & 0xFF);
-        if (i + 1 < size) {
-          value |=
-              (short)
-                  ((values[i + 1].getConstInstruction().asConstNumber().getIntValue() & 0xFF) << 8);
-        }
-        result[i / 2] = value;
-      }
-      return result;
-    }
-    assert elementSize == 2 || elementSize == 4 || elementSize == 8;
-    int shortsPerConstant = elementSize / 2;
-    short[] result = new short[size * shortsPerConstant];
-    for (int i = 0; i < size; i++) {
-      long value = values[i].getConstInstruction().asConstNumber().getRawValue();
-      for (int part = 0; part < shortsPerConstant; part++) {
-        result[i * shortsPerConstant + part] = (short) ((value >> (16 * part)) & 0xFFFFL);
-      }
-    }
-    return result;
-  }
-
-  private static class FilledArrayConversionInfo {
-
-    Value[] values;
-    List<ArrayPut> arrayPutsToRemove;
-    LinearFlowInstructionListIterator lastArrayPutIterator;
-
-    public FilledArrayConversionInfo(int size) {
-      values = new Value[size];
-      arrayPutsToRemove = new ArrayList<>(size);
-    }
-  }
-
-  private FilledArrayConversionInfo computeConversionInfo(
-      FilledArrayCandidate candidate, LinearFlowInstructionListIterator it) {
-    NewArrayEmpty newArrayEmpty = candidate.newArrayEmpty;
-    assert it.peekPrevious() == newArrayEmpty;
-    Value arrayValue = newArrayEmpty.outValue();
-    int size = candidate.size;
-
-    // aput-object allows any object for arrays of interfaces, but new-filled-array fails to verify
-    // if types require a cast.
-    // TODO(b/246971330): Check if adding a checked-cast would have the same observable result. E.g.
-    //   if aput-object throws a ClassCastException if given an object that does not implement the
-    //   desired interface, then we could add check-cast instructions for arguments we're not sure
-    //   about.
-    DexType elementType = newArrayEmpty.type.toDimensionMinusOneType(dexItemFactory);
-    boolean needsTypeCheck =
-        !elementType.isPrimitiveType() && elementType != dexItemFactory.objectType;
-
-    FilledArrayConversionInfo info = new FilledArrayConversionInfo(size);
-    Value[] values = info.values;
-    int remaining = size;
-    Set<Instruction> users = newArrayEmpty.outValue().uniqueUsers();
-    while (it.hasNext()) {
-      Instruction instruction = it.next();
-      BasicBlock block = instruction.getBlock();
-      // If we encounter an instruction that can throw an exception we need to bail out of the
-      // optimization so that we do not transform half-initialized arrays into fully initialized
-      // arrays on exceptional edges. If the block has no handlers it is not observable so
-      // we perform the rewriting.
-      if (block.hasCatchHandlers() && instruction.instructionInstanceCanThrow()) {
-        return null;
-      }
-      if (!users.contains(instruction)) {
-        // If any instruction can transfer control between the new-array and the last array put
-        // then it is not safe to move the new array to the point of the last put.
-        if (block.hasCatchHandlers() && instruction.instructionTypeCanThrow()) {
-          return null;
-        }
-        continue;
-      }
-      ArrayPut arrayPut = instruction.asArrayPut();
-      // If the initialization sequence is broken by another use we cannot use a fill-array-data
-      // instruction.
-      if (arrayPut == null || arrayPut.array() != arrayValue) {
-        return null;
-      }
-      if (!arrayPut.index().isConstNumber()) {
-        return null;
-      }
-      if (arrayPut.instructionInstanceCanThrow()) {
-        assert false;
-        return null;
-      }
-      int index = arrayPut.index().getConstInstruction().asConstNumber().getIntValue();
-      if (index < 0 || index >= values.length) {
-        return null;
-      }
-      if (values[index] != null) {
-        return null;
-      }
-      Value value = arrayPut.value();
-      if (needsTypeCheck && !value.isAlwaysNull(appView)) {
-        DexType valueDexType = value.getType().asReferenceType().toDexType(dexItemFactory);
-        if (elementType.isArrayType()) {
-          if (elementType != valueDexType) {
-            return null;
-          }
-        } else if (valueDexType.isArrayType()) {
-          // isSubtype asserts for this case.
-          return null;
-        } else if (valueDexType.isNullValueType()) {
-          // Assume instructions can cause value.isAlwaysNull() == false while the DexType is null.
-          // TODO(b/246971330): Figure out how to write a test in SimplifyArrayConstructionTest
-          //   that hits this case.
-        } else {
-          // TODO(b/246971330): When in d8 mode, we might still be able to see if this is true for
-          //   library types (which this helper does not do).
-          if (appView.isSubtype(valueDexType, elementType).isPossiblyFalse()) {
-            return null;
-          }
-        }
-      }
-      info.arrayPutsToRemove.add(arrayPut);
-      values[index] = value;
-      --remaining;
-      if (remaining == 0) {
-        info.lastArrayPutIterator = it;
-        return info;
-      }
-    }
-    return null;
-  }
-
-  private static class FilledArrayCandidate {
-
-    final NewArrayEmpty newArrayEmpty;
-    final int size;
-    final boolean encodeAsFilledNewArray;
-
-    public FilledArrayCandidate(
-        NewArrayEmpty newArrayEmpty, int size, boolean encodeAsFilledNewArray) {
-      assert size > 0;
-      this.newArrayEmpty = newArrayEmpty;
-      this.size = size;
-      this.encodeAsFilledNewArray = encodeAsFilledNewArray;
-    }
-
-    public boolean useFilledNewArray() {
-      return encodeAsFilledNewArray;
-    }
-
-    public boolean useFilledArrayData() {
-      return !useFilledNewArray();
-    }
-  }
-
-  private FilledArrayCandidate computeFilledArrayCandidate(
-      Instruction instruction, RewriteArrayOptions options) {
-    NewArrayEmpty newArrayEmpty = instruction.asNewArrayEmpty();
-    if (newArrayEmpty == null) {
-      return null;
-    }
-    if (instruction.getLocalInfo() != null) {
-      return null;
-    }
-    if (!newArrayEmpty.size().isConstant()) {
-      return null;
-    }
-    int size = newArrayEmpty.size().getConstInstruction().asConstNumber().getIntValue();
-    if (!options.isPotentialSize(size)) {
-      return null;
-    }
-    DexType arrayType = newArrayEmpty.type;
-    boolean encodeAsFilledNewArray = canUseFilledNewArray(arrayType, size, options);
-    if (!encodeAsFilledNewArray && !canUseFilledArrayData(arrayType, size, options)) {
-      return null;
-    }
-    // Check that all arguments to the array is the array type or that the array is type Object[].
-    if (!options.canUseSubTypesInFilledNewArray()
-        && arrayType != dexItemFactory.objectArrayType
-        && !arrayType.isPrimitiveArrayType()) {
-      DexType elementType = arrayType.toArrayElementType(dexItemFactory);
-      for (Instruction uniqueUser : newArrayEmpty.outValue().uniqueUsers()) {
-        if (uniqueUser.isArrayPut()
-            && uniqueUser.asArrayPut().array() == newArrayEmpty.outValue()
-            && !checkTypeOfArrayPut(uniqueUser.asArrayPut(), elementType)) {
-          return null;
-        }
-      }
-    }
-    return new FilledArrayCandidate(newArrayEmpty, size, encodeAsFilledNewArray);
-  }
-
-  private boolean checkTypeOfArrayPut(ArrayPut arrayPut, DexType elementType) {
-    TypeElement valueType = arrayPut.value().getType();
-    if (!valueType.isPrimitiveType() && elementType == dexItemFactory.objectType) {
-      return true;
-    }
-    if (valueType.isNullType() && !elementType.isPrimitiveType()) {
-      return true;
-    }
-    if (elementType.isArrayType()) {
-      if (valueType.isNullType()) {
-        return true;
-      }
-      ArrayTypeElement arrayTypeElement = valueType.asArrayType();
-      if (arrayTypeElement == null
-          || arrayTypeElement.getNesting() != elementType.getNumberOfLeadingSquareBrackets()) {
-        return false;
-      }
-      valueType = arrayTypeElement.getBaseType();
-      elementType = elementType.toBaseType(dexItemFactory);
-    }
-    assert !valueType.isArrayType();
-    assert !elementType.isArrayType();
-    if (valueType.isPrimitiveType() && !elementType.isPrimitiveType()) {
-      return false;
-    }
-    if (valueType.isPrimitiveType()) {
-      return true;
-    }
-    DexClass clazz = appView.definitionFor(elementType);
-    if (clazz == null) {
-      return false;
-    }
-    return clazz.isInterface() || valueType.isClassType(elementType);
-  }
-
-  private boolean canUseFilledNewArray(DexType arrayType, int size, RewriteArrayOptions options) {
-    if (size < options.minSizeForFilledNewArray) {
-      return false;
-    }
-    // filled-new-array is implemented only for int[] and Object[].
-    // For int[], using filled-new-array is usually smaller than filled-array-data.
-    // filled-new-array supports up to 5 registers before it's filled-new-array/range.
-    if (!arrayType.isPrimitiveArrayType()) {
-      if (size > options.maxSizeForFilledNewArrayOfReferences) {
-        return false;
-      }
-      if (arrayType == dexItemFactory.stringArrayType) {
-        return options.canUseFilledNewArrayOfStrings();
-      }
-      if (!options.canUseFilledNewArrayOfNonStringObjects()) {
-        return false;
-      }
-      if (!options.canUseFilledNewArrayOfArrays()
-          && arrayType.getNumberOfLeadingSquareBrackets() > 1) {
-        return false;
-      }
-      return true;
-    }
-    if (arrayType == dexItemFactory.intArrayType) {
-      return size <= options.maxSizeForFilledNewArrayOfInts;
-    }
-    return false;
-  }
-
-  private boolean canUseFilledArrayData(DexType arrayType, int size, RewriteArrayOptions options) {
-    // If there is only one element it is typically smaller to generate the array put
-    // instruction instead of fill array data.
-    if (size < options.minSizeForFilledArrayData || size > options.maxSizeForFilledArrayData) {
-      return false;
-    }
-    return arrayType.isPrimitiveArrayType();
-  }
-
-  /**
-   * Replace new-array followed by stores of constants to all entries with new-array and
-   * fill-array-data / filled-new-array.
-   *
-   * <p>The format of the new-array and its puts must be of the form:
-   *
-   * <pre>
-   *   v0 <- new-array T vSize
-   *   ...
-   *   array-put v0 vValue1 vIndex1
-   *   ...
-   *   array-put v0 vValueN vIndexN
-   * </pre>
-   *
-   * <p>The flow between the array v0 and its puts must be linear with no other uses of v0 besides
-   * the array-put instructions, thus any no intermediate instruction (... above) must use v0 and
-   * also cannot have catch handlers that would transfer out control (those could then have uses of
-   * v0).
-   *
-   * <p>The allocation of the new-array can itself have catch handlers, in which case, those are to
-   * remain active on the translated code. Translated code can have two forms.
-   *
-   * <p>The first is using the original array allocation and filling in its data if it can be
-   * encoded:
-   *
-   * <pre>
-   *   v0 <- new-array T vSize
-   *   filled-array-data v0
-   *   ...
-   *   ...
-   * </pre>
-   *
-   * The data payload is encoded directly in the instruction so no dependencies are needed for
-   * filling the data array. Thus, the fill is inserted at the point of the allocation. If the
-   * allocation has catch handlers its block must be split and the handlers put on the fill
-   * instruction too. This is correct only because there are no exceptional transfers in (...) that
-   * could observe the early initialization of the data.
-   *
-   * <p>The second is using filled-new-array and has the form:
-   *
-   * <pre>
-   * ...
-   * ...
-   * v0 <- filled-new-array T vValue1 ... vValueN
-   * </pre>
-   *
-   * Here the correctness relies on no exceptional transfers in (...) that could observe the missing
-   * allocation of the array. The late allocation ensures that the values are available at
-   * allocation time. If the original allocation has catch handlers then the new allocation needs to
-   * link those too. In general that may require splitting the block twice so that the new
-   * allocation is the single throwing instruction in its block.
-   */
-  public void simplifyArrayConstruction(IRCode code) {
-    if (options.isGeneratingClassFiles()) {
-      return;
-    }
-    WorkList<BasicBlock> worklist = WorkList.newIdentityWorkList(code.blocks);
-    while (worklist.hasNext()) {
-      BasicBlock block = worklist.next();
-      simplifyArrayConstructionBlock(block, worklist, code, options);
-    }
-  }
-
-  private void simplifyArrayConstructionBlock(
-      BasicBlock block, WorkList<BasicBlock> worklist, IRCode code, InternalOptions options) {
-    RewriteArrayOptions rewriteOptions = options.rewriteArrayOptions();
-    InstructionListIterator it = block.listIterator(code);
-    while (it.hasNext()) {
-      FilledArrayCandidate candidate = computeFilledArrayCandidate(it.next(), rewriteOptions);
-      if (candidate == null) {
-        continue;
-      }
-      FilledArrayConversionInfo info =
-          computeConversionInfo(
-              candidate, new LinearFlowInstructionListIterator(code, block, it.nextIndex()));
-      if (info == null) {
-        continue;
-      }
-
-      Instruction instructionAfterCandidate = it.peekNext();
-      NewArrayEmpty newArrayEmpty = candidate.newArrayEmpty;
-      DexType arrayType = newArrayEmpty.type;
-      int size = candidate.size;
-      Set<Instruction> instructionsToRemove = SetUtils.newIdentityHashSet(size + 1);
-      if (candidate.useFilledNewArray()) {
-        assert newArrayEmpty.getLocalInfo() == null;
-        Instruction lastArrayPut = info.lastArrayPutIterator.peekPrevious();
-        Value invokeValue = code.createValue(newArrayEmpty.getOutType(), null);
-        InvokeNewArray invoke =
-            new InvokeNewArray(arrayType, invokeValue, Arrays.asList(info.values));
-        invoke.setPosition(lastArrayPut.getPosition());
-        for (Value value : newArrayEmpty.inValues()) {
-          value.removeUser(newArrayEmpty);
-        }
-        newArrayEmpty.outValue().replaceUsers(invokeValue);
-        instructionsToRemove.add(newArrayEmpty);
-
-        boolean originalAllocationPointHasHandlers = block.hasCatchHandlers();
-        boolean insertionPointHasHandlers = lastArrayPut.getBlock().hasCatchHandlers();
-
-        if (!insertionPointHasHandlers && !originalAllocationPointHasHandlers) {
-          info.lastArrayPutIterator.add(invoke);
-        } else {
-          BasicBlock insertionBlock = info.lastArrayPutIterator.split(code);
-          if (originalAllocationPointHasHandlers) {
-            if (!insertionBlock.isTrivialGoto()) {
-              BasicBlock blockAfterInsertion = insertionBlock.listIterator(code).split(code);
-              assert insertionBlock.isTrivialGoto();
-              worklist.addIfNotSeen(blockAfterInsertion);
-            }
-            insertionBlock.moveCatchHandlers(block);
-          } else {
-            worklist.addIfNotSeen(insertionBlock);
-          }
-          insertionBlock.listIterator(code).add(invoke);
-        }
-      } else {
-        assert candidate.useFilledArrayData();
-        int elementSize = arrayType.elementSizeForPrimitiveArrayType();
-        short[] contents = computeArrayFilledData(info.values, size, elementSize);
-        if (contents == null) {
-          continue;
-        }
-        // fill-array-data requires the new-array-empty instruction to remain, as it does not
-        // itself create an array.
-        NewArrayFilledData fillArray =
-            new NewArrayFilledData(newArrayEmpty.outValue(), elementSize, size, contents);
-        fillArray.setPosition(newArrayEmpty.getPosition());
-        BasicBlock newBlock =
-            it.addThrowingInstructionToPossiblyThrowingBlock(code, null, fillArray, options);
-        if (newBlock != null) {
-          worklist.addIfNotSeen(newBlock);
-        }
-      }
-
-      instructionsToRemove.addAll(info.arrayPutsToRemove);
-      Set<BasicBlock> visitedBlocks = Sets.newIdentityHashSet();
-      for (Instruction instruction : instructionsToRemove) {
-        BasicBlock ownerBlock = instruction.getBlock();
-        // If owner block is null, then the instruction has been removed already. We can't rely on
-        // just having the block pointer nulled, so the visited blocks guards reprocessing.
-        if (ownerBlock != null && visitedBlocks.add(ownerBlock)) {
-          InstructionListIterator removeIt = ownerBlock.listIterator(code);
-          while (removeIt.hasNext()) {
-            if (instructionsToRemove.contains(removeIt.next())) {
-              removeIt.removeOrReplaceByDebugLocalRead();
-            }
-          }
-        }
-      }
-
-      // The above has invalidated the block iterator so reset it and continue.
-      it = block.listIterator(code, instructionAfterCandidate);
-    }
-  }
-
   // TODO(mikaelpeltier) Manage that from and to instruction do not belong to the same block.
   private static boolean hasLocalOrLineChangeBetween(
       Instruction from, Instruction to, DexString localVar) {
@@ -2597,309 +1001,6 @@
     }
   }
 
-  static class ControlFlowSimplificationResult {
-
-    private boolean anyAffectedValues;
-    private boolean anySimplifications;
-
-    private ControlFlowSimplificationResult(boolean anyAffectedValues, boolean anySimplifications) {
-      assert !anyAffectedValues || anySimplifications;
-      this.anyAffectedValues = anyAffectedValues;
-      this.anySimplifications = anySimplifications;
-    }
-
-    public boolean anyAffectedValues() {
-      return anyAffectedValues;
-    }
-
-    public boolean anySimplifications() {
-      return anySimplifications;
-    }
-  }
-
-  public boolean simplifyControlFlow(IRCode code) {
-    boolean anyAffectedValues = rewriteSwitch(code);
-    anyAffectedValues |= simplifyIf(code).anyAffectedValues();
-    return anyAffectedValues;
-  }
-
-  public ControlFlowSimplificationResult simplifyIf(IRCode code) {
-    BasicBlockBehavioralSubsumption behavioralSubsumption =
-        new BasicBlockBehavioralSubsumption(appView, code);
-    boolean simplified = false;
-    for (BasicBlock block : code.blocks) {
-      // Skip removed (= unreachable) blocks.
-      if (block.getNumber() != 0 && block.getPredecessors().isEmpty()) {
-        continue;
-      }
-      if (block.exit().isIf()) {
-        flipIfBranchesIfNeeded(code, block);
-        if (rewriteIfWithConstZero(code, block)) {
-          simplified = true;
-        }
-
-        if (simplifyKnownBooleanCondition(code, block)) {
-          simplified = true;
-          if (!block.exit().isIf()) {
-            continue;
-          }
-        }
-
-        // Simplify if conditions when possible.
-        If theIf = block.exit().asIf();
-        if (theIf.isZeroTest()) {
-          if (simplifyIfZeroTest(code, block, theIf)) {
-            simplified = true;
-            continue;
-          }
-        } else {
-          if (simplifyNonIfZeroTest(code, block, theIf)) {
-            simplified = true;
-            continue;
-          }
-        }
-
-        // Unable to determine which branch will be taken. Check if the true target can safely be
-        // rewritten to the false target.
-        if (behavioralSubsumption.isSubsumedBy(
-            theIf.inValues().get(0), theIf.getTrueTarget(), theIf.fallthroughBlock())) {
-          simplifyIfWithKnownCondition(code, block, theIf, theIf.fallthroughBlock());
-          simplified = true;
-        }
-      }
-    }
-    Set<Value> affectedValues = code.removeUnreachableBlocks();
-    if (!affectedValues.isEmpty()) {
-      new TypeAnalysis(appView).narrowing(affectedValues);
-    }
-    assert code.isConsistentSSA(appView);
-    return new ControlFlowSimplificationResult(!affectedValues.isEmpty(), simplified);
-  }
-
-  private boolean simplifyIfZeroTest(IRCode code, BasicBlock block, If theIf) {
-    Value lhs = theIf.lhs();
-    Value lhsRoot = lhs.getAliasedValue();
-    if (lhsRoot.isConstNumber()) {
-      ConstNumber cond = lhsRoot.getConstInstruction().asConstNumber();
-      BasicBlock target = theIf.targetFromCondition(cond);
-      simplifyIfWithKnownCondition(code, block, theIf, target);
-      return true;
-    }
-
-    if (theIf.isNullTest()) {
-      assert theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE;
-
-      if (lhs.isAlwaysNull(appView)) {
-        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromNullObject());
-        return true;
-      }
-
-      if (lhs.isNeverNull()) {
-        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromNonNullObject());
-        return true;
-      }
-    }
-
-    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
-      AbstractValue lhsAbstractValue = lhs.getAbstractValue(appView, code.context());
-      if (lhsAbstractValue.isConstantOrNonConstantNumberValue()
-          && !lhsAbstractValue.asConstantOrNonConstantNumberValue().containsInt(0)) {
-        // Value doesn't contain zero at all.
-        simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(1));
-        return true;
-      }
-    }
-
-    if (lhs.hasValueRange()) {
-      LongInterval interval = lhs.getValueRange();
-      if (!interval.containsValue(0)) {
-        // Interval doesn't contain zero at all.
-        int sign = Long.signum(interval.getMin());
-        simplifyIfWithKnownCondition(code, block, theIf, sign);
-        return true;
-      }
-
-      // Interval contains zero.
-      switch (theIf.getType()) {
-        case GE:
-        case LT:
-          // [a, b] >= 0 is always true if a >= 0.
-          // [a, b] < 0 is always false if a >= 0.
-          // In both cases a zero condition takes the right branch.
-          if (interval.getMin() == 0) {
-            simplifyIfWithKnownCondition(code, block, theIf, 0);
-            return true;
-          }
-          break;
-
-        case LE:
-        case GT:
-          // [a, b] <= 0 is always true if b <= 0.
-          // [a, b] > 0 is always false if b <= 0.
-          // In both cases a zero condition takes the right branch.
-          if (interval.getMax() == 0) {
-            simplifyIfWithKnownCondition(code, block, theIf, 0);
-            return true;
-          }
-          break;
-
-        case EQ:
-        case NE:
-          // Only a single element interval [0, 0] can be dealt with here.
-          // Such intervals should have been replaced by constants.
-          assert !interval.isSingleValue();
-          break;
-      }
-    }
-    return false;
-  }
-
-  private boolean simplifyNonIfZeroTest(IRCode code, BasicBlock block, If theIf) {
-    Value lhs = theIf.lhs();
-    Value lhsRoot = lhs.getAliasedValue();
-    Value rhs = theIf.rhs();
-    Value rhsRoot = rhs.getAliasedValue();
-    if (lhsRoot == rhsRoot) {
-      // Comparing the same value.
-      simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(0));
-      return true;
-    }
-
-    if (lhsRoot.isDefinedByInstructionSatisfying(Instruction::isCreatingInstanceOrArray)
-        && rhsRoot.isDefinedByInstructionSatisfying(Instruction::isCreatingInstanceOrArray)) {
-      // Comparing two newly created objects.
-      assert theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE;
-      simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(1));
-      return true;
-    }
-
-    if (lhsRoot.isConstNumber() && rhsRoot.isConstNumber()) {
-      // Zero test with a constant of comparison between between two constants.
-      ConstNumber left = lhsRoot.getConstInstruction().asConstNumber();
-      ConstNumber right = rhsRoot.getConstInstruction().asConstNumber();
-      BasicBlock target = theIf.targetFromCondition(left, right);
-      simplifyIfWithKnownCondition(code, block, theIf, target);
-      return true;
-    }
-
-    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
-      AbstractValue lhsAbstractValue = lhs.getAbstractValue(appView, code.context());
-      AbstractValue rhsAbstractValue = rhs.getAbstractValue(appView, code.context());
-      if (lhsAbstractValue.isConstantOrNonConstantNumberValue()
-          && rhsAbstractValue.isConstantOrNonConstantNumberValue()) {
-        ConstantOrNonConstantNumberValue lhsNumberValue =
-            lhsAbstractValue.asConstantOrNonConstantNumberValue();
-        ConstantOrNonConstantNumberValue rhsNumberValue =
-            rhsAbstractValue.asConstantOrNonConstantNumberValue();
-        if (!lhsNumberValue.mayOverlapWith(rhsNumberValue)) {
-          // No overlap.
-          simplifyIfWithKnownCondition(code, block, theIf, 1);
-          return true;
-        }
-      }
-    }
-
-    if (lhs.hasValueRange() && rhs.hasValueRange()) {
-      // Zero test with a value range, or comparison between between two values,
-      // each with a value ranges.
-      LongInterval leftRange = lhs.getValueRange();
-      LongInterval rightRange = rhs.getValueRange();
-      // Two overlapping ranges. Check for single point overlap.
-      if (!leftRange.overlapsWith(rightRange)) {
-        // No overlap.
-        int cond = Long.signum(leftRange.getMin() - rightRange.getMin());
-        simplifyIfWithKnownCondition(code, block, theIf, cond);
-        return true;
-      }
-
-      // The two intervals overlap. We can simplify if they overlap at the end points.
-      switch (theIf.getType()) {
-        case LT:
-        case GE:
-          // [a, b] < [c, d] is always false when a == d.
-          // [a, b] >= [c, d] is always true when a == d.
-          // In both cases 0 condition will choose the right branch.
-          if (leftRange.getMin() == rightRange.getMax()) {
-            simplifyIfWithKnownCondition(code, block, theIf, 0);
-            return true;
-          }
-          break;
-        case GT:
-        case LE:
-          // [a, b] > [c, d] is always false when b == c.
-          // [a, b] <= [c, d] is always true when b == c.
-          // In both cases 0 condition will choose the right branch.
-          if (leftRange.getMax() == rightRange.getMin()) {
-            simplifyIfWithKnownCondition(code, block, theIf, 0);
-            return true;
-          }
-          break;
-        case EQ:
-        case NE:
-          // Since there is overlap EQ and NE cannot be determined.
-          break;
-      }
-    }
-
-    if (theIf.getType() == IfType.EQ || theIf.getType() == IfType.NE) {
-      ProgramMethod context = code.context();
-      AbstractValue abstractValue = lhs.getAbstractValue(appView, context);
-      if (abstractValue.isSingleConstClassValue()) {
-        AbstractValue otherAbstractValue = rhs.getAbstractValue(appView, context);
-        if (otherAbstractValue.isSingleConstClassValue()) {
-          SingleConstClassValue singleConstClassValue = abstractValue.asSingleConstClassValue();
-          SingleConstClassValue otherSingleConstClassValue =
-              otherAbstractValue.asSingleConstClassValue();
-          simplifyIfWithKnownCondition(
-              code,
-              block,
-              theIf,
-              BooleanUtils.intValue(
-                  singleConstClassValue.getType() != otherSingleConstClassValue.getType()));
-          return true;
-        }
-        return false;
-      }
-
-      if (abstractValue.isSingleFieldValue()) {
-        AbstractValue otherAbstractValue = rhs.getAbstractValue(appView, context);
-        if (otherAbstractValue.isSingleFieldValue()) {
-          SingleFieldValue singleFieldValue = abstractValue.asSingleFieldValue();
-          SingleFieldValue otherSingleFieldValue = otherAbstractValue.asSingleFieldValue();
-          if (singleFieldValue.getField() == otherSingleFieldValue.getField()) {
-            simplifyIfWithKnownCondition(code, block, theIf, 0);
-            return true;
-          }
-
-          DexClass holder = appView.definitionForHolder(singleFieldValue.getField());
-          DexEncodedField field = singleFieldValue.getField().lookupOnClass(holder);
-          if (field != null && field.isEnum()) {
-            DexClass otherHolder = appView.definitionForHolder(otherSingleFieldValue.getField());
-            DexEncodedField otherField =
-                otherSingleFieldValue.getField().lookupOnClass(otherHolder);
-            if (otherField != null && otherField.isEnum()) {
-              simplifyIfWithKnownCondition(code, block, theIf, 1);
-              return true;
-            }
-          }
-        }
-      }
-    }
-
-    return false;
-  }
-
-  private void simplifyIfWithKnownCondition(
-      IRCode code, BasicBlock block, If theIf, BasicBlock target) {
-    BasicBlock deadTarget =
-        target == theIf.getTrueTarget() ? theIf.fallthroughBlock() : theIf.getTrueTarget();
-    rewriteIfToGoto(code, block, theIf, target, deadTarget);
-  }
-
-  private void simplifyIfWithKnownCondition(IRCode code, BasicBlock block, If theIf, int cond) {
-    simplifyIfWithKnownCondition(code, block, theIf, theIf.targetFromCondition(cond));
-  }
-
   /**
    * This optimization exploits that we can sometimes learn the constant value of an SSA value that
    * flows into an if-eq of if-neq instruction.
@@ -3380,152 +1481,6 @@
     assert code.isConsistentSSA(appView);
   }
 
-  /* Identify simple diamond shapes converting boolean true/false to 1/0. We consider the forms:
-   *
-   * (1)
-   *
-   *      [dbg pos x]             [dbg pos x]
-   *   ifeqz booleanValue       ifnez booleanValue
-   *      /        \              /        \
-   * [dbg pos x][dbg pos x]  [dbg pos x][dbg pos x]
-   *  [const 0]  [const 1]    [const 1]  [const 0]
-   *    goto      goto          goto      goto
-   *      \        /              \        /
-   *      phi(0, 1)                phi(1, 0)
-   *
-   * which can be replaced by a fallthrough and the phi value can be replaced
-   * with the boolean value itself.
-   *
-   * (2)
-   *
-   *      [dbg pos x]              [dbg pos x]
-   *    ifeqz booleanValue       ifnez booleanValue
-   *      /        \              /        \
-   * [dbg pos x][dbg pos x]  [dbg pos x][dbg pos x]
-   *  [const 1]  [const 0]   [const 0]  [const 1]
-   *    goto      goto          goto      goto
-   *      \        /              \        /
-   *      phi(1, 0)                phi(0, 1)
-   *
-   * which can be replaced by a fallthrough and the phi value can be replaced
-   * by an xor instruction which is smaller.
-   */
-  private boolean simplifyKnownBooleanCondition(IRCode code, BasicBlock block) {
-    If theIf = block.exit().asIf();
-    Value testValue = theIf.inValues().get(0);
-    if (theIf.isZeroTest() && testValue.knownToBeBoolean()) {
-      BasicBlock trueBlock = theIf.getTrueTarget();
-      BasicBlock falseBlock = theIf.fallthroughBlock();
-      if (isBlockSupportedBySimplifyKnownBooleanCondition(trueBlock) &&
-          isBlockSupportedBySimplifyKnownBooleanCondition(falseBlock) &&
-          trueBlock.getSuccessors().get(0) == falseBlock.getSuccessors().get(0)) {
-        BasicBlock targetBlock = trueBlock.getSuccessors().get(0);
-        if (targetBlock.getPredecessors().size() == 2) {
-          int trueIndex = targetBlock.getPredecessors().indexOf(trueBlock);
-          int falseIndex = trueIndex == 0 ? 1 : 0;
-          int deadPhis = 0;
-          // Locate the phis that have the same value as the boolean and replace them
-          // by the boolean in all users.
-          for (Phi phi : targetBlock.getPhis()) {
-            Value trueValue = phi.getOperand(trueIndex);
-            Value falseValue = phi.getOperand(falseIndex);
-            if (trueValue.isConstNumber() && falseValue.isConstNumber()) {
-              ConstNumber trueNumber = trueValue.getConstInstruction().asConstNumber();
-              ConstNumber falseNumber = falseValue.getConstInstruction().asConstNumber();
-              if ((theIf.getType() == IfType.EQ
-                      && trueNumber.isIntegerZero()
-                      && falseNumber.isIntegerOne())
-                  || (theIf.getType() == IfType.NE
-                      && trueNumber.isIntegerOne()
-                      && falseNumber.isIntegerZero())) {
-                phi.replaceUsers(testValue);
-                deadPhis++;
-              } else if ((theIf.getType() == IfType.NE
-                      && trueNumber.isIntegerZero()
-                      && falseNumber.isIntegerOne())
-                  || (theIf.getType() == IfType.EQ
-                      && trueNumber.isIntegerOne()
-                      && falseNumber.isIntegerZero())) {
-                Value newOutValue = code.createValue(phi.getType(), phi.getLocalInfo());
-                ConstNumber cstToUse = trueNumber.isIntegerOne() ? trueNumber : falseNumber;
-                BasicBlock phiBlock = phi.getBlock();
-                Position phiPosition = phiBlock.getPosition();
-                int insertIndex = 0;
-                if (cstToUse.getBlock() == trueBlock || cstToUse.getBlock() == falseBlock) {
-                  // The constant belongs to the block to remove, create a new one.
-                  cstToUse = ConstNumber.copyOf(code, cstToUse);
-                  cstToUse.setBlock(phiBlock);
-                  cstToUse.setPosition(phiPosition);
-                  phiBlock.getInstructions().add(insertIndex++, cstToUse);
-                }
-                phi.replaceUsers(newOutValue);
-                Instruction newInstruction =
-                    Xor.create(NumericType.INT, newOutValue, testValue, cstToUse.outValue());
-                newInstruction.setBlock(phiBlock);
-                // The xor is replacing a phi so it does not have an actual position.
-                newInstruction.setPosition(phiPosition);
-                phiBlock.listIterator(code, insertIndex).add(newInstruction);
-                deadPhis++;
-              }
-            }
-          }
-          // If all phis were removed, there is no need for the diamond shape anymore
-          // and it can be rewritten to a goto to one of the branches.
-          if (deadPhis == targetBlock.getPhis().size()) {
-            rewriteIfToGoto(code, block, theIf, trueBlock, falseBlock);
-            return true;
-          }
-          return deadPhis > 0;
-        }
-      }
-    }
-    return false;
-  }
-
-  private boolean isBlockSupportedBySimplifyKnownBooleanCondition(BasicBlock b) {
-    if (b.isTrivialGoto()) {
-      return true;
-    }
-
-    int instructionSize = b.getInstructions().size();
-    if (b.exit().isGoto() && (instructionSize == 2 || instructionSize == 3)) {
-      Instruction constInstruction = b.getInstructions().get(instructionSize - 2);
-      if (constInstruction.isConstNumber()) {
-        if (!constInstruction.asConstNumber().isIntegerOne() &&
-            !constInstruction.asConstNumber().isIntegerZero()) {
-          return false;
-        }
-        if (instructionSize == 2) {
-          return true;
-        }
-        Instruction firstInstruction = b.getInstructions().getFirst();
-        if (firstInstruction.isDebugPosition()) {
-          assert b.getPredecessors().size() == 1;
-          BasicBlock predecessorBlock = b.getPredecessors().get(0);
-          InstructionIterator it = predecessorBlock.iterator(predecessorBlock.exit());
-          Instruction previousPosition = null;
-          while (it.hasPrevious() && !(previousPosition = it.previous()).isDebugPosition()) {
-            // Intentionally empty.
-          }
-          if (previousPosition != null) {
-            return previousPosition.getPosition() == firstInstruction.getPosition();
-          }
-        }
-      }
-    }
-
-    return false;
-  }
-
-  private void rewriteIfToGoto(
-      IRCode code, BasicBlock block, If theIf, BasicBlock target, BasicBlock deadTarget) {
-    deadTarget.unlinkSinglePredecessorSiblingsAllowed();
-    assert theIf == block.exit();
-    block.replaceLastInstruction(new Goto(), code);
-    assert block.exit().isGoto();
-    assert block.exit().asGoto().getTarget() == target;
-  }
-
   private void insertNotNullCheck(
       BasicBlock block,
       InstructionListIterator iterator,
@@ -3547,101 +1502,6 @@
     assert block.exit().asGoto().getTarget() == target;
   }
 
-  private boolean rewriteIfWithConstZero(IRCode code, BasicBlock block) {
-    If theIf = block.exit().asIf();
-    if (theIf.isZeroTest()) {
-      return false;
-    }
-
-    Value leftValue = theIf.lhs();
-    Value rightValue = theIf.rhs();
-    if (leftValue.isConstNumber() || rightValue.isConstNumber()) {
-      if (leftValue.isConstNumber()) {
-        if (leftValue.getConstInstruction().asConstNumber().isZero()) {
-          If ifz = new If(theIf.getType().forSwappedOperands(), rightValue);
-          block.replaceLastInstruction(ifz, code);
-          assert block.exit() == ifz;
-          return true;
-        }
-      } else if (rightValue.getConstInstruction().asConstNumber().isZero()) {
-        If ifz = new If(theIf.getType(), leftValue);
-        block.replaceLastInstruction(ifz, code);
-        assert block.exit() == ifz;
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  private boolean flipIfBranchesIfNeeded(IRCode code, BasicBlock block) {
-    If theIf = block.exit().asIf();
-    BasicBlock trueTarget = theIf.getTrueTarget();
-    BasicBlock fallthrough = theIf.fallthroughBlock();
-    assert trueTarget != fallthrough;
-
-    if (!fallthrough.isSimpleAlwaysThrowingPath() || trueTarget.isSimpleAlwaysThrowingPath()) {
-      return false;
-    }
-
-    // In case fall-through block always throws there is a good chance that it
-    // is created for error checks and 'trueTarget' represents most more common
-    // non-error case. Flipping the if in this case may result in faster code
-    // on older Android versions.
-    List<Value> inValues = theIf.inValues();
-    If newIf = new If(theIf.getType().inverted(), inValues);
-    block.replaceLastInstruction(newIf, code);
-    block.swapSuccessors(trueTarget, fallthrough);
-    return true;
-  }
-
-  public void rewriteKnownArrayLengthCalls(IRCode code) {
-    InstructionListIterator iterator = code.instructionListIterator();
-    while (iterator.hasNext()) {
-      Instruction current = iterator.next();
-      if (!current.isArrayLength()) {
-        continue;
-      }
-
-      ArrayLength arrayLength = current.asArrayLength();
-      if (arrayLength.hasOutValue() && arrayLength.outValue().hasLocalInfo()) {
-        continue;
-      }
-
-      Value array = arrayLength.array().getAliasedValue();
-      if (array.isPhi() || !arrayLength.array().isNeverNull() || array.hasLocalInfo()) {
-        continue;
-      }
-
-      AbstractValue abstractValue = array.getAbstractValue(appView, code.context());
-      if (!abstractValue.hasKnownArrayLength() && !array.isNeverNull()) {
-        continue;
-      }
-      Instruction arrayDefinition = array.getDefinition();
-      assert arrayDefinition != null;
-
-      Set<Phi> phiUsers = arrayLength.outValue().uniquePhiUsers();
-      if (arrayDefinition.isNewArrayEmpty()) {
-        Value size = arrayDefinition.asNewArrayEmpty().size();
-        arrayLength.outValue().replaceUsers(size);
-        iterator.removeOrReplaceByDebugLocalRead();
-      } else if (arrayDefinition.isNewArrayFilledData()) {
-        long size = arrayDefinition.asNewArrayFilledData().size;
-        if (size > Integer.MAX_VALUE) {
-          continue;
-        }
-        iterator.replaceCurrentInstructionWithConstInt(code, (int) size);
-      } else if (abstractValue.hasKnownArrayLength()) {
-        iterator.replaceCurrentInstructionWithConstInt(code, abstractValue.getKnownArrayLength());
-      } else {
-        continue;
-      }
-
-      phiUsers.forEach(Phi::removeTrivialPhi);
-    }
-    assert code.isConsistentSSA(appView);
-  }
-
   /**
    * Remove moves that are not actually used by instructions in exiting paths. These moves can arise
    * due to debug local info needing a particular value and the live-interval for it then moves it
@@ -3891,34 +1751,6 @@
     iterator.add(new InvokeVirtual(printLn, null, ImmutableList.of(out, empty)));
   }
 
-  public static void replaceUnusedArgumentTrivialPhis(UnusedArgument unusedArgument) {
-    replaceTrivialPhis(unusedArgument.outValue());
-    for (Phi phiUser : unusedArgument.outValue().uniquePhiUsers()) {
-      phiUser.removeTrivialPhi();
-    }
-    assert !unusedArgument.outValue().hasPhiUsers();
-  }
-
-  public static void ensureDirectStringNewToInit(IRCode code, DexItemFactory dexItemFactory) {
-    for (Instruction instruction : code.instructions()) {
-      if (instruction.isInvokeDirect()) {
-        InvokeDirect invoke = instruction.asInvokeDirect();
-        DexMethod method = invoke.getInvokedMethod();
-        if (dexItemFactory.isConstructor(method)
-            && method.holder == dexItemFactory.stringType
-            && invoke.getReceiver().isPhi()) {
-          NewInstance newInstance = findNewInstance(invoke.getReceiver().asPhi());
-          replaceTrivialPhis(newInstance.outValue());
-          if (invoke.getReceiver().isPhi()) {
-            throw new CompilationError(
-                "Failed to remove trivial phis between new-instance and <init>");
-          }
-          newInstance.markNoSpilling();
-        }
-      }
-    }
-  }
-
   // The javac fix for JDK-8272564 has to be rewritten back to invoke-virtual on Object if the
   // method with an Object signature is not defined on the interface. See
   // https://bugs.openjdk.java.net/browse/JDK-8272564
@@ -3943,66 +1775,4 @@
       }
     }
   }
-
-  private static NewInstance findNewInstance(Phi phi) {
-    Set<Phi> seen = Sets.newIdentityHashSet();
-    Set<Value> values = Sets.newIdentityHashSet();
-    recursiveAddOperands(phi, seen, values);
-    if (values.size() != 1) {
-      throw new CompilationError("Failed to identify unique new-instance for <init>");
-    }
-    Value newInstanceValue = values.iterator().next();
-    if (newInstanceValue.definition == null || !newInstanceValue.definition.isNewInstance()) {
-      throw new CompilationError("Invalid defining value for call to <init>");
-    }
-    return newInstanceValue.definition.asNewInstance();
-  }
-
-  private static void recursiveAddOperands(Phi phi, Set<Phi> seen, Set<Value> values) {
-    for (Value operand : phi.getOperands()) {
-      if (!operand.isPhi()) {
-        values.add(operand);
-      } else {
-        Phi phiOp = operand.asPhi();
-        if (seen.add(phiOp)) {
-          recursiveAddOperands(phiOp, seen, values);
-        }
-      }
-    }
-  }
-
-  // We compute the set of strongly connected phis making use of the out value and replace all
-  // trivial ones by the out value.
-  // This is a simplified variant of the removeRedundantPhis algorithm in Section 3.2 of:
-  // http://compilers.cs.uni-saarland.de/papers/bbhlmz13cc.pdf
-  private static void replaceTrivialPhis(Value outValue) {
-    List<Set<Value>> components = new SCC<Value>(Value::uniquePhiUsers).computeSCC(outValue);
-    for (int i = components.size() - 1; i >= 0; i--) {
-      Set<Value> component = components.get(i);
-      if (component.size() == 1 && component.iterator().next() == outValue) {
-        continue;
-      }
-      Set<Phi> trivialPhis = Sets.newIdentityHashSet();
-      for (Value value : component) {
-        boolean isTrivial = true;
-        Phi p = value.asPhi();
-        for (Value op : p.getOperands()) {
-          if (op != outValue && !component.contains(op)) {
-            isTrivial = false;
-            break;
-          }
-        }
-        if (isTrivial) {
-          trivialPhis.add(p);
-        }
-      }
-      for (Phi trivialPhi : trivialPhis) {
-        for (Value op : trivialPhi.getOperands()) {
-          op.removePhiUser(trivialPhi);
-        }
-        trivialPhi.replaceUsers(outValue);
-        trivialPhi.getBlock().removePhi(trivialPhi);
-      }
-    }
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
index 677da9c..b4fa5a6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
@@ -41,6 +41,7 @@
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.StaticGet;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.passes.BranchSimplifier;
 import com.android.tools.r8.utils.OptionalBool;
 import com.android.tools.r8.utils.WorkList;
 import com.google.common.collect.Sets;
@@ -65,17 +66,16 @@
   private static final int MAX_CANONICALIZED_CONSTANT = 22;
 
   private final AppView<?> appView;
-  private final CodeRewriter codeRewriter;
+  private final BranchSimplifier branchSimplifier;
   private final ProgramMethod context;
   private final IRCode code;
 
   private OptionalBool isAccessingVolatileField = OptionalBool.unknown();
   private Set<InstanceGet> ineligibleInstanceGetInstructions;
 
-  public ConstantCanonicalizer(
-      AppView<?> appView, CodeRewriter codeRewriter, ProgramMethod context, IRCode code) {
+  public ConstantCanonicalizer(AppView<?> appView, ProgramMethod context, IRCode code) {
     this.appView = appView;
-    this.codeRewriter = codeRewriter;
+    this.branchSimplifier = new BranchSimplifier(appView);
     this.context = context;
     this.code = code;
   }
@@ -288,7 +288,7 @@
     shouldSimplifyIfs |= code.removeAllDeadAndTrivialPhis();
 
     if (shouldSimplifyIfs) {
-      codeRewriter.simplifyIf(code);
+      branchSimplifier.simplifyIf(code);
     }
 
     assert code.isConsistentSSA(appView);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
index b7d7b10..fcefb79 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.code.Phi;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.code.ValueIsDeadAnalysis;
+import com.android.tools.r8.ir.conversion.passes.BranchSimplifier;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.IterableUtils;
@@ -50,6 +51,8 @@
 
     codeRewriter.rewriteMoveResult(code);
 
+    BranchSimplifier branchSimplifier = new BranchSimplifier(appView);
+
     // We may encounter unneeded catch handlers after each iteration, e.g., if a dead instruction
     // is the only throwing instruction in a block. Removing unneeded catch handlers can lead to
     // more dead instructions.
@@ -62,7 +65,7 @@
         removeDeadInstructions(worklist, code, block, valueIsDeadAnalysis);
         removeDeadPhis(worklist, block, valueIsDeadAnalysis);
       }
-    } while (codeRewriter.simplifyIf(code).anySimplifications()
+    } while (branchSimplifier.simplifyIf(code).anySimplifications()
         || removeUnneededCatchHandlers(code));
     assert code.isConsistentSSA(appView);
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MultiCallerInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/MultiCallerInliner.java
index 54c8f61..4b5f0c9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MultiCallerInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MultiCallerInliner.java
@@ -147,12 +147,11 @@
     // We track up to n call sites, where n is the size of multiCallerInliningInstructionLimits.
     if (callers.size() > multiCallerInliningInstructionLimits.length) {
       stopTrackingCallSitesForMethodIfDefinitelyIneligibleForMultiCallerInlining(
-          method, singleTarget, methodProcessor, callers);
+          singleTarget, methodProcessor, callers);
     }
   }
 
   private void stopTrackingCallSitesForMethodIfDefinitelyIneligibleForMultiCallerInlining(
-      ProgramMethod method,
       ProgramMethod singleTarget,
       MethodProcessor methodProcessor,
       ProgramMethodMultiset callers) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
index afed4c2..370a5d7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.passes.BranchSimplifier;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.LazyBox;
 import com.google.common.collect.ImmutableList;
@@ -68,6 +69,58 @@
     }
   }
 
+  public static void workaroundSwitchMaxIntBug(IRCode code, AppView<?> appView) {
+    if (appView.options().canHaveSwitchMaxIntBug() && code.metadata().mayHaveSwitch()) {
+      // Always rewrite for workaround switch bug.
+      rewriteSwitchForMaxIntOnly(code, appView);
+    }
+  }
+
+  private static void rewriteSwitchForMaxIntOnly(IRCode code, AppView<?> appView) {
+    boolean needToSplitCriticalEdges = false;
+    BranchSimplifier branchSimplifier = new BranchSimplifier(appView);
+    ListIterator<BasicBlock> blocksIterator = code.listIterator();
+    while (blocksIterator.hasNext()) {
+      BasicBlock block = blocksIterator.next();
+      InstructionListIterator iterator = block.listIterator(code);
+      while (iterator.hasNext()) {
+        Instruction instruction = iterator.next();
+        assert !instruction.isStringSwitch();
+        if (instruction.isIntSwitch()) {
+          IntSwitch intSwitch = instruction.asIntSwitch();
+          if (intSwitch.getKey(intSwitch.numberOfKeys() - 1) == Integer.MAX_VALUE) {
+            if (intSwitch.numberOfKeys() == 1) {
+              branchSimplifier.rewriteSingleKeySwitchToIf(code, block, iterator, intSwitch);
+            } else {
+              IntList newSwitchSequences = new IntArrayList(intSwitch.numberOfKeys() - 1);
+              for (int i = 0; i < intSwitch.numberOfKeys() - 1; i++) {
+                newSwitchSequences.add(intSwitch.getKey(i));
+              }
+              IntList outliers = new IntArrayList(1);
+              outliers.add(Integer.MAX_VALUE);
+              branchSimplifier.convertSwitchToSwitchAndIfs(
+                  code,
+                  blocksIterator,
+                  block,
+                  iterator,
+                  intSwitch,
+                  ImmutableList.of(newSwitchSequences),
+                  outliers);
+            }
+            needToSplitCriticalEdges = true;
+          }
+        }
+      }
+    }
+
+    // Rewriting of switches introduces new branching structure. It relies on critical edges
+    // being split on the way in but does not maintain this property. We therefore split
+    // critical edges at exit.
+    if (needToSplitCriticalEdges) {
+      code.splitCriticalEdges();
+    }
+  }
+
   /**
    * For each block, we look to see if the header matches:
    *
@@ -192,58 +245,6 @@
     }
   }
 
-  public static void workaroundSwitchMaxIntBug(
-      IRCode code, CodeRewriter codeRewriter, InternalOptions options) {
-    if (options.canHaveSwitchMaxIntBug() && code.metadata().mayHaveSwitch()) {
-      // Always rewrite for workaround switch bug.
-      rewriteSwitchForMaxIntOnly(code, codeRewriter);
-    }
-  }
-
-  private static void rewriteSwitchForMaxIntOnly(IRCode code, CodeRewriter codeRewriter) {
-    boolean needToSplitCriticalEdges = false;
-    ListIterator<BasicBlock> blocksIterator = code.listIterator();
-    while (blocksIterator.hasNext()) {
-      BasicBlock block = blocksIterator.next();
-      InstructionListIterator iterator = block.listIterator(code);
-      while (iterator.hasNext()) {
-        Instruction instruction = iterator.next();
-        assert !instruction.isStringSwitch();
-        if (instruction.isIntSwitch()) {
-          IntSwitch intSwitch = instruction.asIntSwitch();
-          if (intSwitch.getKey(intSwitch.numberOfKeys() - 1) == Integer.MAX_VALUE) {
-            if (intSwitch.numberOfKeys() == 1) {
-              codeRewriter.rewriteSingleKeySwitchToIf(code, block, iterator, intSwitch);
-            } else {
-              IntList newSwitchSequences = new IntArrayList(intSwitch.numberOfKeys() - 1);
-              for (int i = 0; i < intSwitch.numberOfKeys() - 1; i++) {
-                newSwitchSequences.add(intSwitch.getKey(i));
-              }
-              IntList outliers = new IntArrayList(1);
-              outliers.add(Integer.MAX_VALUE);
-              codeRewriter.convertSwitchToSwitchAndIfs(
-                  code,
-                  blocksIterator,
-                  block,
-                  iterator,
-                  intSwitch,
-                  ImmutableList.of(newSwitchSequences),
-                  outliers);
-            }
-            needToSplitCriticalEdges = true;
-          }
-        }
-      }
-    }
-
-    // Rewriting of switches introduces new branching structure. It relies on critical edges
-    // being split on the way in but does not maintain this property. We therefore split
-    // critical edges at exit.
-    if (needToSplitCriticalEdges) {
-      code.splitCriticalEdges();
-    }
-  }
-
   // See comment for InternalOptions.canHaveNumberConversionRegisterAllocationBug().
   public static void workaroundNumberConversionRegisterAllocationBug(
       IRCode code, InternalOptions options) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index 7607596..889a434 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -19,8 +19,9 @@
 import com.android.tools.r8.ir.code.InstructionOrPhi;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.conversion.MethodProcessor;
+import com.android.tools.r8.ir.conversion.passes.BranchSimplifier;
+import com.android.tools.r8.ir.conversion.passes.TrivialCheckCastAndInstanceOfRemover;
 import com.android.tools.r8.ir.optimize.AssumeRemover;
-import com.android.tools.r8.ir.optimize.CodeRewriter;
 import com.android.tools.r8.ir.optimize.Inliner;
 import com.android.tools.r8.ir.optimize.InliningOracle;
 import com.android.tools.r8.ir.optimize.classinliner.InlineCandidateProcessor.IllegalClassInlinerStateException;
@@ -126,7 +127,6 @@
   //
   public final void processMethodCode(
       AppView<AppInfoWithLiveness> appView,
-      CodeRewriter codeRewriter,
       StringOptimizer stringOptimizer,
       EnumValueOptimizer enumValueOptimizer,
       ProgramMethod method,
@@ -247,10 +247,10 @@
       // If a method was inlined we may be able to remove check-cast instructions because we may
       // have more information about the types of the arguments at the call site. This is
       // particularly important for bridge methods.
-      codeRewriter.removeTrivialCheckCastAndInstanceOfInstructions(
-          code, method, methodProcessor, methodProcessingContext);
+      new TrivialCheckCastAndInstanceOfRemover(appView)
+          .run(code, method, methodProcessor, methodProcessingContext);
       // If a method was inlined we may be able to prune additional branches.
-      codeRewriter.simplifyControlFlow(code);
+      new BranchSimplifier(appView).simplifyBranches(code);
       // If a method was inlined we may see more trivial computation/conversion of String.
       boolean isDebugMode =
           appView.options().debug || method.getOrComputeReachabilitySensitive(appView);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java
index 537150e..02d13dd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/DefaultInliningReasonStrategy.java
@@ -53,7 +53,7 @@
       // program.
       return Reason.SIMPLE;
     }
-    if (isSingleCallerInliningTarget(target)) {
+    if (isSingleCallerInliningTarget(target, context)) {
       return Reason.SINGLE_CALLER;
     }
     if (isMultiCallerInlineCandidate(invoke, target, oracle, methodProcessor)) {
@@ -64,8 +64,8 @@
     return Reason.SIMPLE;
   }
 
-  private boolean isSingleCallerInliningTarget(ProgramMethod method) {
-    if (!callSiteInformation.hasSingleCallSite(method)) {
+  private boolean isSingleCallerInliningTarget(ProgramMethod method, ProgramMethod context) {
+    if (!callSiteInformation.hasSingleCallSite(method, context)) {
       return false;
     }
     if (appView.appInfo().isNeverInlineDueToSingleCallerMethod(method)) {
diff --git a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
index d87e036..502f120 100644
--- a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
+++ b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
@@ -1306,7 +1306,7 @@
       }
       newMappingInformation.forEach(
           info -> {
-            if (!nonCompasableNewInfos.contains(info)) {
+            if (!nonCompasableNewInfos.contains(info) && !info.isFileNameInformation()) {
               consumer.accept(info);
             }
           });
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/ProguardMapPartitionerOnClassNameToText.java b/src/main/java/com/android/tools/r8/retrace/internal/ProguardMapPartitionerOnClassNameToText.java
index 3af7dff..4fdc94a 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/ProguardMapPartitionerOnClassNameToText.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/ProguardMapPartitionerOnClassNameToText.java
@@ -273,7 +273,7 @@
       extends ProguardMapPartitionerBuilderImpl {
 
     private MappingPartitionKeyStrategy mappingPartitionKeyStrategy =
-        MappingPartitionKeyStrategy.OBFUSCATED_TYPE_NAME_AS_KEY_WITH_PARTITIONS;
+        MappingPartitionKeyStrategy.getDefaultStrategy();
 
     public ProguardMapPartitionerBuilderImplInternal(DiagnosticsHandler diagnosticsHandler) {
       super(diagnosticsHandler);
diff --git a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
index 2c6f535..19b4d38 100644
--- a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
@@ -456,8 +456,8 @@
    * @return java package name i.e. "java.lang"
    */
   public static String getPackageNameFromTypeName(String typeName) {
-    return getPackageNameFromBinaryName(
-        getClassBinaryNameFromDescriptor(javaTypeToDescriptor(typeName)));
+    int packageEndIndex = typeName.lastIndexOf(JAVA_PACKAGE_SEPARATOR);
+    return (packageEndIndex < 0) ? "" : typeName.substring(0, packageEndIndex);
   }
 
   /**
diff --git a/src/main/java/com/android/tools/r8/utils/Timing.java b/src/main/java/com/android/tools/r8/utils/Timing.java
index 1e61b88..143bc2f 100644
--- a/src/main/java/com/android/tools/r8/utils/Timing.java
+++ b/src/main/java/com/android/tools/r8/utils/Timing.java
@@ -19,6 +19,7 @@
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.ExecutorService;
 
 public class Timing {
 
@@ -373,6 +374,10 @@
     }
   }
 
+  public final TimingMerger beginMerger(String title, ExecutorService executorService) {
+    return beginMerger(title, ThreadUtils.getNumberOfThreads(executorService));
+  }
+
   public TimingMerger beginMerger(String title, int numberOfThreads) {
     return new TimingMerger(title, numberOfThreads, this);
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamAbstractTests.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamAbstractTests.java
index 5822d2f..9ff2346 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamAbstractTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11StreamAbstractTests.java
@@ -115,12 +115,17 @@
   public static final String[] SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7 =
       new String[] {
         // Require the virtual method isDefault() in class java/lang/reflect/Method.
-        "org/openjdk/tests/java/util/stream/WhileOpTest.java",
         "org/openjdk/tests/java/util/stream/WhileOpStatefulTest.java",
         // Require a Random method not present before Android 7 and not desugared.
         "org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java"
       };
 
+  public static final String[] LONG_RUNNING_SUCCESSFUL_RUNNABLE_TESTS_ON_JDK11_AND_V7 =
+      new String[] {
+        // Require the virtual method isDefault() in class java/lang/reflect/Method.
+        "org/openjdk/tests/java/util/stream/WhileOpTest.java",
+      };
+
   // Disabled because time to run > 1 min for each test.
   // Can be used for experimentation/testing purposes.
   private static String[] LONG_RUNNING_TESTS =
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
index f4fec42..d743010 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest.java
@@ -7,117 +7,132 @@
 import static org.junit.Assert.assertEquals;
 
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.smali.SmaliBuilder;
+import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.google.common.collect.ImmutableList;
-import org.junit.Ignore;
+import java.io.IOException;
+import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.objectweb.asm.Opcodes;
 
 @RunWith(Parameterized.class)
 public class InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest extends TestBase {
 
+  private final TestParameters parameters;
   private final boolean includeInterfaceMethodOnJ;
 
-  @Parameterized.Parameters(name = "Include interface method on J: {0}")
-  public static Boolean[] data() {
-    return BooleanUtils.values();
+  // Note that the expected output is independent of the presence of J.m().
+  private static final String EXPECTED = StringUtils.lines("I.m()", "JImpl.m()");
+
+  @Parameterized.Parameters(name = "{0}, J.m(): {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        TestParameters.builder()
+            .withCfRuntimes()
+            .enableApiLevelsForCf()
+            .withDexRuntimes()
+            .withApiLevel(AndroidApiLevel.B)
+            .build(),
+        BooleanUtils.values());
   }
 
   public InvokeSuperInDefaultInterfaceMethodToNonImmediateInterfaceTest(
-      boolean includeInterfaceMethodOnJ) {
+      TestParameters parameters, boolean includeInterfaceMethodOnJ) {
+    this.parameters = parameters;
     this.includeInterfaceMethodOnJ = includeInterfaceMethodOnJ;
   }
 
   @Test
-  @Ignore("b/197494749 and b/120130831")
-  // TODO(b/197494749): Update this test now that desugaring is moved up. In particular this must
-  //  be rewritten with CF based transformers as R8 does not support interface desugaring on DEX.
-  // TODO(b/120130831): With the move of desugaring this issue should be resolved. The bug indicates
-  //  that a workaround for issues related to the IR implementation can now be reverted.
-  public void test() throws Exception {
-    // Note that the expected output is independent of the presence of J.m().
-    String expectedOutput = StringUtils.lines("I.m()", "JImpl.m()");
-
-    byte[] dex = buildProgramDexFileData();
-    if (ToolHelper.getDexVm().getVersion().isNewerThan(Version.V6_0_1)) {
-      AndroidApp app =
-          AndroidApp.builder()
-              .addDexProgramData(buildProgramDexFileData(), Origin.unknown())
-              .build();
-      assertEquals(expectedOutput, runOnArt(app, "TestClass"));
-    }
-
-    testForR8(Backend.DEX)
-        .addProgramDexFileData(dex)
-        .addKeepMainRule("TestClass")
-        .setMinApi(AndroidApiLevel.M)
-        .run("TestClass")
-        .assertSuccessWithOutput(expectedOutput);
+  public void testJvm() throws Exception {
+    // The rewritten input is invalid on JVM.
+    parameters.assumeJvmTestParameters();
+    testForJvm(parameters)
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertFailureWithErrorThatThrows(VerifyError.class);
   }
 
-  // Using Smali instead of Jasmin because interfaces are broken in Jasmin.
-  private byte[] buildProgramDexFileData() throws Exception {
-    SmaliBuilder smaliBuilder = new SmaliBuilder();
-    smaliBuilder.setMinApi(AndroidApiLevel.N);
+  @Test
+  public void testD8() throws Exception {
+    // Notice that desugaring will map out of the invalid invoke.
+    testForD8(parameters.getBackend())
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
 
-    smaliBuilder.addClass("TestClass");
+  @Test
+  public void testR8() throws Exception {
+    // Notice that desugaring will map out of the invalid invoke.
+    testForR8(parameters.getBackend())
+        .addProgramClasses(getClasses())
+        .addProgramClassFileData(getTransformedClasses())
+        .addKeepMainRule(TestClass.class)
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
 
-    // public void main(String[] args) { new JImpl().m(); }
-    smaliBuilder.addMainMethod(
-        1,
-        "new-instance v0, LJImpl;",
-        "invoke-direct {v0}, LJImpl;-><init>()V",
-        "invoke-virtual {v0}, LJImpl;->m()V",
-        "return-void");
+  private List<Class<?>> getClasses() {
+    return ImmutableList.of(TestClass.class, I.class);
+  }
 
-    smaliBuilder.addInterface("I");
+  private List<byte[]> getTransformedClasses() throws IOException {
+    return ImmutableList.of(
+        transformer(JImpl.class)
+            .transformMethodInsnInMethod(
+                "m",
+                (opcode, owner, name, descriptor, isInterface, visitor) -> {
+                  if (opcode == Opcodes.INVOKESPECIAL) {
+                    assertEquals(owner, binaryName(J.class));
+                    owner = binaryName(I.class);
+                  }
+                  visitor.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+                })
+            .transform(),
+        transformer(J.class)
+            .removeMethods(
+                (access, name, descriptor, signature, exceptions) ->
+                    !includeInterfaceMethodOnJ && name.equals("m"))
+            .transform());
+  }
 
-    // default void m() { System.out.println("In I.m()"); }
-    smaliBuilder.addInstanceMethod(
-        "void",
-        "m",
-        2,
-        "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-        "const-string v1, \"I.m()\"",
-        "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-        "return-void");
+  static class TestClass {
 
-    smaliBuilder.addInterface("J", "java.lang.Object", ImmutableList.of("I"));
-    if (includeInterfaceMethodOnJ) {
-      smaliBuilder.addInstanceMethod(
-          "void",
-          "m",
-          2,
-          "invoke-super {p0}, LI;->m()V",
-          "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-          "const-string v1, \"J.m()\"",
-          "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-          "return-void");
+    public static void main(String[] args) {
+      new JImpl().m();
     }
+  }
 
-    smaliBuilder.addClass("JImpl", "java.lang.Object", ImmutableList.of("J"));
-    smaliBuilder.addDefaultConstructor();
+  interface I {
 
-    // default void m() { I.super.m(); System.out.println("In JImpl.m()"); }
-    smaliBuilder.addInstanceMethod(
-        "void",
-        "m",
-        2,
-        // Note: invoke-super instruction to the non-immediate interface I.
-        "invoke-super {p0}, LI;->m()V",
-        "sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
-        "const-string v1, \"JImpl.m()\"",
-        "invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
-        "return-void");
+    default void m() {
+      System.out.println("I.m()");
+    }
+  }
 
-    return smaliBuilder.compile();
+  interface J extends I {
+
+    @Override
+    default void m() {
+      I.super.m();
+      System.out.println("J.m()");
+    }
+  }
+
+  static class JImpl implements J {
+
+    @Override
+    public void m() {
+      J.super.m(); // Will be rewritten to non-immediate interface: I.super.m();
+      System.out.println("JImpl.m()");
+    }
   }
 }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 019431d..8a8ab51 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -29,6 +29,7 @@
 import com.android.tools.r8.ir.code.Throw;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
+import com.android.tools.r8.ir.conversion.passes.TrivialGotosCollapser;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
@@ -107,7 +108,7 @@
             IRMetadata.unknown(),
             Origin.unknown(),
             new MutableMethodConversionOptions(options));
-    CodeRewriter.collapseTrivialGotos(appView, code);
+    new TrivialGotosCollapser(appView).run(code.context(), code);
     assertTrue(code.entryBlock().isTrivialGoto());
     assertTrue(blocks.contains(block0));
     assertTrue(blocks.contains(block1));
@@ -196,7 +197,7 @@
             IRMetadata.unknown(),
             Origin.unknown(),
             new MutableMethodConversionOptions(options));
-    CodeRewriter.collapseTrivialGotos(appView, code);
+    new TrivialGotosCollapser(appView).run(code.context(), code);
     assertTrue(block0.getInstructions().get(1).isIf());
     assertEquals(block1, block0.getInstructions().get(1).asIf().fallthroughBlock());
     assertTrue(blocks.containsAll(ImmutableList.of(block0, block1, block2, block3)));
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/SingleTargetAfterInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/SingleTargetAfterInliningTest.java
index f5b5a47..706f8f0 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/SingleTargetAfterInliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/SingleTargetAfterInliningTest.java
@@ -75,13 +75,15 @@
     ClassSubject aClassSubject = inspector.clazz(A.class);
     assertThat(aClassSubject, isPresent());
 
-    // B.foo() should be absent if the max inlining depth is 1, because indirection() has been
-    // inlined into main(), which makes B.foo() eligible for inlining into main().
+    // B.foo() could potentially be absent if the max inlining depth is 1, because indirection() has
+    // been inlined into main(), which makes B.foo() eligible for inlining into main() since we can
+    // compute a single target. However, because indirection() can be inlined into multiple callers
+    // we cannot trust the single caller predicate. If indirection() also has a singler caller we
+    // could propagate the single call site property to B.foo().
     ClassSubject bClassSubject = inspector.clazz(B.class);
     assertThat(bClassSubject, isPresent());
-    assertThat(
-        bClassSubject.uniqueMethodWithOriginalName("foo"),
-        notIf(isPresent(), maxInliningDepth == 1));
+    // TODO(b/286058449): We could inline this.
+    assertThat(bClassSubject.uniqueMethodWithOriginalName("foo"), isPresent());
 
     // B.bar() should always be inlined because it is marked as @AlwaysInline.
     assertThat(
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeSourceFileTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeSourceFileTest.java
index b07c55c..434c494 100644
--- a/src/test/java/com/android/tools/r8/mappingcompose/ComposeSourceFileTest.java
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeSourceFileTest.java
@@ -31,22 +31,32 @@
 
   private static final String mappingFoo =
       StringUtils.unixLines(
-          "# {'id':'com.android.tools.r8.mapping','version':'experimental'}",
-          "com.foo -> a:",
-          "    # {'id':'sourceFile','fileName':'Foo.kt'}");
+          "# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
+          "com.foo -> A:",
+          "    # {'id':'sourceFile','fileName':'Foo.kt'}",
+          "com.bar -> B:",
+          "    # {'id':'sourceFile','fileName':'Bar.kt'}",
+          "com.baz -> C:");
   private static final String mappingBar =
       StringUtils.unixLines(
-          "# {'id':'com.android.tools.r8.mapping','version':'experimental'}",
-          "com.bar -> c:",
-          "    # {'id':'sourceFile','fileName':'Bar.kt'}",
-          "a -> b:");
+          "# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
+          "A -> a:",
+          "    # {'id':'sourceFile','fileName':'some-hash-inserted-into-source-file'}",
+          "B -> b:",
+          "C -> c:",
+          "    # {'id':'sourceFile','fileName':'some-other-hash-inserted-into-source-file'}",
+          "com.qux -> d:",
+          "    # {'id':'sourceFile','fileName':'Qux.kt'}");
   private static final String mappingResult =
       StringUtils.unixLines(
-          "# {'id':'com.android.tools.r8.mapping','version':'experimental'}",
-          "com.bar -> c:",
+          "# {'id':'com.android.tools.r8.mapping','version':'2.2'}",
+          "com.bar -> b:",
           "# {'id':'sourceFile','fileName':'Bar.kt'}",
-          "com.foo -> b:",
-          "# {'id':'sourceFile','fileName':'Foo.kt'}");
+          "com.baz -> c:",
+          "com.foo -> a:",
+          "# {'id':'sourceFile','fileName':'Foo.kt'}",
+          "com.qux -> d:",
+          "# {'id':'sourceFile','fileName':'Qux.kt'}");
 
   @Test
   public void testCompose() throws Exception {
diff --git a/src/test/java/com/android/tools/r8/retrace/partition/RetracePartitionWithPrimitiveNameTest.java b/src/test/java/com/android/tools/r8/retrace/partition/RetracePartitionWithPrimitiveNameTest.java
new file mode 100644
index 0000000..e848753
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/partition/RetracePartitionWithPrimitiveNameTest.java
@@ -0,0 +1,77 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.retrace.partition;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.retrace.MappingPartitionMetadata;
+import com.android.tools.r8.retrace.PartitionMappingSupplier;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.RetraceOptions;
+import com.android.tools.r8.retrace.RetraceStackFrameAmbiguousResultWithContext;
+import com.android.tools.r8.retrace.RetraceStackTraceContext;
+import com.android.tools.r8.retrace.StringRetrace;
+import com.android.tools.r8.retrace.internal.MappingPartitionKeyStrategy;
+import com.android.tools.r8.retrace.internal.ProguardMapPartitionerOnClassNameToText.ProguardMapPartitionerBuilderImplInternal;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Regression test for b/286001537. */
+@RunWith(Parameterized.class)
+public class RetracePartitionWithPrimitiveNameTest extends TestBase {
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public RetracePartitionWithPrimitiveNameTest(TestParameters parameters) {
+    parameters.assertNoneRuntime();
+  }
+
+  public final String mapping =
+      StringUtils.unixLines(
+          "# { id: 'com.android.tools.r8.mapping', version: '2.0' }",
+          "some.class1 -> int:",
+          "  void method() -> a");
+
+  @Test
+  public void testPartitionAndRetrace() throws Exception {
+    ProguardMapProducer proguardMapProducer = ProguardMapProducer.fromString(mapping);
+    TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
+    Map<String, byte[]> partitions = new HashMap<>();
+    MappingPartitionMetadata metadata =
+        new ProguardMapPartitionerBuilderImplInternal(diagnosticsHandler)
+            .setMappingPartitionKeyStrategy(MappingPartitionKeyStrategy.getDefaultStrategy())
+            .setProguardMapProducer(proguardMapProducer)
+            .setPartitionConsumer(
+                partition -> partitions.put(partition.getKey(), partition.getPayload()))
+            .build()
+            .run();
+
+    PartitionMappingSupplier mappingSupplier =
+        PartitionMappingSupplier.builder()
+            .setMetadata(metadata.getBytes())
+            .setMappingPartitionFromKeySupplier(partitions::get)
+            .build();
+
+    StringRetrace retracer =
+        StringRetrace.create(RetraceOptions.builder().setMappingSupplier(mappingSupplier).build());
+    RetraceStackFrameAmbiguousResultWithContext<String> result =
+        retracer.retraceFrame("  at int.a()", RetraceStackTraceContext.empty());
+    StringBuilder sb = new StringBuilder();
+    result.forEach(frames -> frames.forEach(sb::append));
+    assertEquals("  at some.class1.method(class1.java)", sb.toString());
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java
index bcacbe7..a09de37 100644
--- a/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java
@@ -13,7 +13,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
-import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.ir.conversion.passes.ArrayConstructionSimplifier;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
@@ -64,7 +64,7 @@
   }
 
   private void transformArray(IRCode irCode, AppView<?> appView) {
-      new CodeRewriter(appView).simplifyArrayConstruction(irCode);
+    new ArrayConstructionSimplifier(appView).run(irCode.context(), irCode);
     String name = irCode.context().getReference().getName().toString();
     if (name.contains("filledArrayData")) {
       assertTrue(irCode.streamInstructions().anyMatch(Instruction::isNewArrayFilledData));
diff --git a/src/test/java/com/android/tools/r8/startup/SingleCallerBridgeStartupTest.java b/src/test/java/com/android/tools/r8/startup/SingleCallerBridgeStartupTest.java
index 4a27e0f..1cb68de 100644
--- a/src/test/java/com/android/tools/r8/startup/SingleCallerBridgeStartupTest.java
+++ b/src/test/java/com/android/tools/r8/startup/SingleCallerBridgeStartupTest.java
@@ -4,6 +4,9 @@
 
 package com.android.tools.r8.startup;
 
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
@@ -12,6 +15,7 @@
 import com.android.tools.r8.startup.profile.ExternalStartupItem;
 import com.android.tools.r8.startup.profile.ExternalStartupMethod;
 import com.android.tools.r8.startup.utils.StartupTestingUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 import org.junit.Test;
@@ -55,9 +59,16 @@
                     (appView, inlinee, inliningDepth) ->
                         inlinee.getMethodReference().equals(barMethod))
         .setMinApi(parameters)
+        .compile()
+        .inspect(
+            inspector -> {
+              // Assert that foo is not inlined.
+              ClassSubject A = inspector.clazz(A.class);
+              assertThat(A, isPresent());
+              assertThat(A.uniqueMethodWithOriginalName("foo"), isPresent());
+            })
         .run(parameters.getRuntime(), Main.class)
-        // TODO(b/285021603): We should not fail here.
-        .assertFailureWithErrorThatThrows(NoSuchMethodError.class);
+        .assertSuccessWithOutputLines("A::foo", "A::foo");
   }
 
   static class Main {
diff --git a/tools/create_maven_release.py b/tools/create_maven_release.py
index ee68e1e..1ca239e 100755
--- a/tools/create_maven_release.py
+++ b/tools/create_maven_release.py
@@ -124,6 +124,12 @@
                       help='Build desugar library configuration (original JDK-8)')
   group.add_argument('--desugar-configuration-jdk11-legacy', action='store_true',
                       help='Build desugar library configuration (JDK-11 legacy)')
+  group.add_argument('--desugar-configuration-jdk11-minimal', action='store_true',
+                      help='Build desugar library configuration (JDK-11 minimal)')
+  group.add_argument('--desugar-configuration-jdk11', action='store_true',
+                      help='Build desugar library configuration (JDK-11)')
+  group.add_argument('--desugar-configuration-jdk11-nio', action='store_true',
+                      help='Build desugar library configuration (JDK-11 nio)')
   return result.parse_args(argv)
 
 def determine_version():
@@ -369,7 +375,7 @@
     with zipfile.ZipFile(conversions, 'r') as conversions_zip:
       conversions_zip.extractall(tmp_dir)
 
-    # Add configuration
+    # Add configuration.
     configuration_dir = join(tmp_dir, 'META-INF', 'desugar', 'd8')
     makedirs(configuration_dir)
     copyfile(configuration, join(configuration_dir, 'desugar.json'))
@@ -388,6 +394,9 @@
     utils.PrintCmd(cmd)
     subprocess.check_call(cmd)
 
+    # Add LICENSE file.
+    copyfile(join(utils.REPO_ROOT, 'LICENSE'), join(tmp_dir, 'LICENSE'))
+
     make_archive(destination, 'zip', tmp_dir)
     move(destination + '.zip', destination)
 
@@ -435,11 +444,34 @@
         'Need to supply output zip with --out.')
   if options.desugar_configuration or options.desugar_configuration_jdk8:
     generate_desugar_configuration_maven_zip(
-      options.out, utils.DESUGAR_CONFIGURATION, utils.DESUGAR_IMPLEMENTATION)
+      options.out,
+      utils.DESUGAR_CONFIGURATION,
+      utils.DESUGAR_IMPLEMENTATION,
+      utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
   elif options.desugar_configuration_jdk11_legacy:
     generate_desugar_configuration_maven_zip(
-      options.out, utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
-      utils.DESUGAR_IMPLEMENTATION_JDK11)
+      options.out,
+      utils.DESUGAR_CONFIGURATION_JDK11_LEGACY,
+      utils.DESUGAR_IMPLEMENTATION_JDK11,
+      utils.LIBRARY_DESUGAR_CONVERSIONS_LEGACY_ZIP)
+  elif options.desugar_configuration_jdk11_minimal:
+    generate_desugar_configuration_maven_zip(
+      options.out,
+      utils.DESUGAR_CONFIGURATION_JDK11_MINIMAL,
+      utils.DESUGAR_IMPLEMENTATION_JDK11,
+      utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
+  elif options.desugar_configuration_jdk11:
+    generate_desugar_configuration_maven_zip(
+      options.out,
+      utils.DESUGAR_CONFIGURATION_JDK11,
+      utils.DESUGAR_IMPLEMENTATION_JDK11,
+      utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
+  elif options.desugar_configuration_jdk11_nio:
+    generate_desugar_configuration_maven_zip(
+      options.out,
+      utils.DESUGAR_CONFIGURATION_JDK11_NIO,
+      utils.DESUGAR_IMPLEMENTATION_JDK11,
+      utils.LIBRARY_DESUGAR_CONVERSIONS_ZIP)
   else:
     generate_r8_maven_zip(options.out, options.r8lib)
 
