Increase simple inlining constraint threshold to allow one instruction

Bug: b/331337747
Change-Id: I1734ff28354e78d9ecd89c971cce23bd3067947b
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
index a207c8d..cbeb329 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraint.java
@@ -64,11 +64,12 @@
     return new SimpleInliningConstraintConjunction(ImmutableList.of(this, other));
   }
 
-  public final SimpleInliningConstraint lazyMeet(Supplier<SimpleInliningConstraint> supplier) {
+  public final SimpleInliningConstraintWithDepth lazyMeet(
+      Supplier<SimpleInliningConstraintWithDepth> supplier) {
     if (isNever()) {
-      return NeverSimpleInliningConstraint.getInstance();
+      return SimpleInliningConstraintWithDepth.getNever();
     }
-    return meet(supplier.get());
+    return supplier.get().meet(this);
   }
 
   public final SimpleInliningConstraint join(SimpleInliningConstraint other) {
@@ -96,4 +97,8 @@
       AppView<AppInfoWithLiveness> appView,
       ArgumentInfoCollection changes,
       SimpleInliningConstraintFactory factory);
+
+  public final SimpleInliningConstraintWithDepth withDepth(int instructionDepth) {
+    return new SimpleInliningConstraintWithDepth(this, instructionDepth);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintAnalysis.java
index 36d43a0..63a2886 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintAnalysis.java
@@ -63,15 +63,15 @@
     this.simpleInliningConstraintThreshold = appView.options().simpleInliningConstraintThreshold;
   }
 
-  public SimpleInliningConstraint analyzeCode(IRCode code) {
+  public SimpleInliningConstraintWithDepth analyzeCode(IRCode code) {
     if (method.getReference().getArity() == 0) {
       // The method does not have any parameters, so there is no need to analyze the method.
-      return NeverSimpleInliningConstraint.getInstance();
+      return SimpleInliningConstraintWithDepth.getNever();
     }
 
     if (options.debug) {
       // Inlining is not enabled in debug mode.
-      return NeverSimpleInliningConstraint.getInstance();
+      return SimpleInliningConstraintWithDepth.getNever();
     }
 
     // Run a bounded depth-first traversal to collect the path constraints that lead to early
@@ -81,15 +81,16 @@
     return analyzeInstructionsInBlock(code.entryBlock(), 0, instructionIterator);
   }
 
-  private SimpleInliningConstraint analyzeInstructionsInBlock(BasicBlock block, int depth) {
+  private SimpleInliningConstraintWithDepth analyzeInstructionsInBlock(
+      BasicBlock block, int depth) {
     return analyzeInstructionsInBlock(block, depth, block.iterator());
   }
 
-  private SimpleInliningConstraint analyzeInstructionsInBlock(
+  private SimpleInliningConstraintWithDepth analyzeInstructionsInBlock(
       BasicBlock block, int instructionDepth, InstructionIterator instructionIterator) {
     // If we reach a block that has already been seen, give up.
     if (!seen.add(block)) {
-      return NeverSimpleInliningConstraint.getInstance();
+      return SimpleInliningConstraintWithDepth.getNever();
     }
 
     // Move the instruction iterator forward to the block's jump instruction, while incrementing the
@@ -114,12 +115,12 @@
     // If we have exceeded the threshold, then all paths from this instruction will not lead to any
     // early exits, so return 'never'.
     if (instructionDepth > simpleInliningConstraintThreshold) {
-      return NeverSimpleInliningConstraint.getInstance();
+      return SimpleInliningConstraintWithDepth.getNever();
     }
 
-    SimpleInliningConstraint jumpConstraint =
+    SimpleInliningConstraintWithDepth jumpConstraint =
         computeConstraintForJumpInstruction(instruction.asJumpInstruction(), instructionDepth);
-    return blockConstraint.meet(jumpConstraint);
+    return jumpConstraint.meet(blockConstraint);
   }
 
   private SimpleInliningConstraint computeConstraintForInstructionNotToMaterialize(
@@ -145,7 +146,7 @@
     return NeverSimpleInliningConstraint.getInstance();
   }
 
-  private SimpleInliningConstraint computeConstraintForJumpInstruction(
+  private SimpleInliningConstraintWithDepth computeConstraintForJumpInstruction(
       JumpInstruction instruction, int instructionDepth) {
     switch (instruction.opcode()) {
       case IF:
@@ -168,7 +169,7 @@
 
         // Compute the constraint for which paths through the true target are guaranteed to exit
         // early.
-        SimpleInliningConstraint trueTargetConstraint =
+        SimpleInliningConstraintWithDepth trueTargetConstraint =
             computeConstraintFromIfTest(
                     argumentIndex, argumentType, otherOperand, ifInstruction.getType())
                 // Only recurse into the true target if the constraint from the if-instruction
@@ -178,7 +179,7 @@
 
         // Compute the constraint for which paths through the false target are guaranteed to
         // exit early.
-        SimpleInliningConstraint fallthroughTargetConstraint =
+        SimpleInliningConstraintWithDepth fallthroughTargetConstraint =
             computeConstraintFromIfTest(
                     argumentIndex, argumentType, otherOperand, ifInstruction.getType().inverted())
                 // Only recurse into the false target if the constraint from the if-instruction
@@ -195,7 +196,7 @@
         return analyzeInstructionsInBlock(instruction.asGoto().getTarget(), instructionDepth);
 
       case RETURN:
-        return AlwaysSimpleInliningConstraint.getInstance();
+        return AlwaysSimpleInliningConstraint.getInstance().withDepth(instructionDepth);
 
       case STRING_SWITCH:
         // Require that all cases including the default case are simple. In that case we can
@@ -203,29 +204,34 @@
         StringSwitch stringSwitch = instruction.asStringSwitch();
         Value valueRoot = stringSwitch.value().getAliasedValue();
         if (!valueRoot.isDefinedByInstructionSatisfying(Instruction::isArgument)) {
-          return NeverSimpleInliningConstraint.getInstance();
+          return SimpleInliningConstraintWithDepth.getNever();
         }
+        int maxInstructionDepth = instructionDepth;
         for (BasicBlock successor : stringSwitch.getBlock().getNormalSuccessors()) {
-          SimpleInliningConstraint successorConstraint =
+          SimpleInliningConstraintWithDepth successorConstraintWithDepth =
               analyzeInstructionsInBlock(successor, instructionDepth);
-          if (!successorConstraint.isAlways()) {
-            return NeverSimpleInliningConstraint.getInstance();
+          if (!successorConstraintWithDepth.getConstraint().isAlways()) {
+            return SimpleInliningConstraintWithDepth.getNever();
           }
+          maxInstructionDepth =
+              Math.max(maxInstructionDepth, successorConstraintWithDepth.getInstructionDepth());
         }
         Argument argument = valueRoot.getDefinition().asArgument();
-        return constraintFactory.createConstConstraint(argument.getIndex());
+        ConstSimpleInliningConstraint simpleConstraint =
+            constraintFactory.createConstConstraint(argument.getIndex());
+        return simpleConstraint.withDepth(maxInstructionDepth);
 
       case THROW:
         return instruction.getBlock().hasCatchHandlers()
-            ? NeverSimpleInliningConstraint.getInstance()
-            : AlwaysSimpleInliningConstraint.getInstance();
+            ? SimpleInliningConstraintWithDepth.getNever()
+            : SimpleInliningConstraintWithDepth.getAlways(instructionDepth);
 
       default:
         break;
     }
 
     // Give up.
-    return NeverSimpleInliningConstraint.getInstance();
+    return SimpleInliningConstraintWithDepth.getNever();
   }
 
   private SimpleInliningConstraint computeConstraintFromIfTest(
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintWithDepth.java b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintWithDepth.java
new file mode 100644
index 0000000..391f5fd
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/analysis/inlining/SimpleInliningConstraintWithDepth.java
@@ -0,0 +1,48 @@
+// Copyright (c) 2024, 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.analysis.inlining;
+
+public class SimpleInliningConstraintWithDepth {
+
+  private static final SimpleInliningConstraintWithDepth NEVER =
+      new SimpleInliningConstraintWithDepth(NeverSimpleInliningConstraint.getInstance(), 0);
+
+  private final SimpleInliningConstraint constraint;
+  private final int instructionDepth;
+
+  public SimpleInliningConstraintWithDepth(
+      SimpleInliningConstraint constraint, int instructionDepth) {
+    this.constraint = constraint;
+    this.instructionDepth = instructionDepth;
+  }
+
+  public static SimpleInliningConstraintWithDepth getAlways(int instructionDepth) {
+    return AlwaysSimpleInliningConstraint.getInstance().withDepth(instructionDepth);
+  }
+
+  public static SimpleInliningConstraintWithDepth getNever() {
+    return NEVER;
+  }
+
+  public SimpleInliningConstraint getConstraint() {
+    return constraint;
+  }
+
+  public SimpleInliningConstraint getNopConstraint() {
+    return instructionDepth == 0 ? constraint : NeverSimpleInliningConstraint.getInstance();
+  }
+
+  public int getInstructionDepth() {
+    return instructionDepth;
+  }
+
+  public SimpleInliningConstraintWithDepth join(SimpleInliningConstraintWithDepth other) {
+    SimpleInliningConstraint joinConstraint = constraint.join(other.constraint);
+    return joinConstraint.withDepth(Math.max(instructionDepth, other.instructionDepth));
+  }
+
+  public SimpleInliningConstraintWithDepth meet(SimpleInliningConstraint other) {
+    return new SimpleInliningConstraintWithDepth(constraint.meet(other), instructionDepth);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
index f22f61a..abe0324 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/MethodOptimizationFeedback.java
@@ -72,6 +72,8 @@
 
   void setNonNullParamOnNormalExits(DexEncodedMethod method, BitSet facts);
 
+  void setNopInliningConstraint(ProgramMethod method, SimpleInliningConstraint constraint);
+
   void setSimpleInliningConstraint(ProgramMethod method, SimpleInliningConstraint constraint);
 
   void classInitializerMayBePostponed(DexEncodedMethod method);
@@ -117,6 +119,8 @@
 
   void unsetReturnValueOnlyDependsOnArguments(ProgramMethod method);
 
+  void unsetNopInliningConstraint(ProgramMethod method);
+
   void unsetSimpleInliningConstraint(ProgramMethod method);
 
   void unsetUnusedArguments(ProgramMethod method);
@@ -139,6 +143,7 @@
       unsetNonNullParamOrThrow(method);
       unsetReturnedArgument(method);
       unsetReturnValueOnlyDependsOnArguments(method);
+      unsetNopInliningConstraint(method);
       unsetSimpleInliningConstraint(method);
       unsetUnusedArguments(method);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index 92da768..a166867 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -221,18 +221,21 @@
       int estimatedSizeForInlining =
           code.getEstimatedSizeForInliningIfLessThanOrEquals(
               instructionLimit + estimatedMaxIncrement);
-      if (estimatedSizeForInlining < 0) {
-        return false;
-      }
-      if (estimatedSizeForInlining <= instructionLimit) {
-        return true;
-      }
-      int actualIncrement =
-          getInliningInstructionLimitIncrement(invoke, target, inliningIRProvider);
-      if (estimatedSizeForInlining <= instructionLimit + actualIncrement) {
-        return true;
+      if (estimatedSizeForInlining >= 0) {
+        if (estimatedSizeForInlining <= instructionLimit) {
+          return true;
+        }
+        int actualIncrement =
+            getInliningInstructionLimitIncrement(invoke, target, inliningIRProvider);
+        if (estimatedSizeForInlining <= instructionLimit + actualIncrement) {
+          return true;
+        }
       }
     }
+    return satisfiesSimpleInliningConstraint(invoke, target);
+  }
+
+  private boolean satisfiesSimpleInliningConstraint(InvokeMethod invoke, ProgramMethod target) {
     // Even if the inlinee is big it may become simple after inlining. We therefore check if the
     // inlinee's simple inlining constraint is satisfied by the invoke.
     SimpleInliningConstraint simpleInliningConstraint =
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
index 6c10cc6..8b2f63d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/DefaultMethodOptimizationInfo.java
@@ -147,7 +147,7 @@
   }
 
   @Override
-  public SimpleInliningConstraint getNopInliningConstraint(InternalOptions options) {
+  public SimpleInliningConstraint getNopInliningConstraint() {
     return NeverSimpleInliningConstraint.getInstance();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
index 9c7fb22..c23876d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfo.java
@@ -87,7 +87,7 @@
 
   public abstract AbstractValue getAbstractReturnValue();
 
-  public abstract SimpleInliningConstraint getNopInliningConstraint(InternalOptions options);
+  public abstract SimpleInliningConstraint getNopInliningConstraint();
 
   public abstract SimpleInliningConstraint getSimpleInliningConstraint();
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 382be09..76616ba 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -57,7 +57,9 @@
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.DeterminismAnalysis;
 import com.android.tools.r8.ir.analysis.InitializedClassesOnNormalExitAnalysis;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraint;
 import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraintAnalysis;
+import com.android.tools.r8.ir.analysis.inlining.SimpleInliningConstraintWithDepth;
 import com.android.tools.r8.ir.analysis.sideeffect.ClassInitializerSideEffectAnalysis;
 import com.android.tools.r8.ir.analysis.sideeffect.ClassInitializerSideEffectAnalysis.ClassInitializerSideEffect;
 import com.android.tools.r8.ir.analysis.type.DynamicType;
@@ -827,8 +829,14 @@
 
   private void computeSimpleInliningConstraint(
       ProgramMethod method, IRCode code, OptimizationFeedback feedback) {
-    feedback.setSimpleInliningConstraint(
-        method, new SimpleInliningConstraintAnalysis(appView, method).analyzeCode(code));
+    SimpleInliningConstraintWithDepth simpleInliningConstraintWithDepth =
+        new SimpleInliningConstraintAnalysis(appView, method).analyzeCode(code);
+    SimpleInliningConstraint nopInliningConstraint =
+        simpleInliningConstraintWithDepth.getNopConstraint();
+    SimpleInliningConstraint simpleInliningConstraint =
+        simpleInliningConstraintWithDepth.getConstraint();
+    feedback.setNopInliningConstraint(method, nopInliningConstraint);
+    feedback.setSimpleInliningConstraint(method, simpleInliningConstraint);
   }
 
   private void computeDynamicReturnType(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
index 06ef441..808f2c9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoFixer.java
@@ -40,6 +40,13 @@
 
   public abstract int fixupReturnedArgumentIndex(int returnedArgumentIndex);
 
+  public final SimpleInliningConstraint fixupNopInliningConstraint(
+      AppView<AppInfoWithLiveness> appView,
+      SimpleInliningConstraint constraint,
+      SimpleInliningConstraintFactory factory) {
+    return fixupSimpleInliningConstraint(appView, constraint, factory);
+  }
+
   public abstract SimpleInliningConstraint fixupSimpleInliningConstraint(
       AppView<AppInfoWithLiveness> appView,
       SimpleInliningConstraint constraint,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodResolutionOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodResolutionOptimizationInfo.java
index 4831f7f..6c59889 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodResolutionOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodResolutionOptimizationInfo.java
@@ -201,7 +201,7 @@
   }
 
   @Override
-  public SimpleInliningConstraint getNopInliningConstraint(InternalOptions options) {
+  public SimpleInliningConstraint getNopInliningConstraint() {
     throw new Unreachable();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
index 3c46cf1..3c03079 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
@@ -78,6 +78,8 @@
   private BitSet nonNullParamOnNormalExits =
       DefaultMethodOptimizationInfo.NO_NULL_PARAMETER_ON_NORMAL_EXITS_FACTS;
 
+  private SimpleInliningConstraint nopInliningConstraint =
+      NeverSimpleInliningConstraint.getInstance();
   private SimpleInliningConstraint simpleInliningConstraint =
       NeverSimpleInliningConstraint.getInstance();
 
@@ -144,6 +146,7 @@
     abstractReturnValue = template.abstractReturnValue;
     setDynamicType(template.dynamicType);
     inlining = template.inlining;
+    nopInliningConstraint = template.nopInliningConstraint;
     simpleInliningConstraint = template.simpleInliningConstraint;
     bridgeInfo = template.bridgeInfo;
     instanceInitializerInfoCollection = template.instanceInitializerInfoCollection;
@@ -169,6 +172,7 @@
         .fixupNonNullParamOrThrow(fixer)
         .fixupReturnedArgumentIndex(fixer)
         .fixupParametersWithBitwiseOperations(fixer)
+        .fixupNopInliningConstraint(appView, fixer)
         .fixupSimpleInliningConstraint(appView, fixer)
         .fixupUnusedArguments(fixer);
   }
@@ -486,12 +490,8 @@
   }
 
   @Override
-  public SimpleInliningConstraint getNopInliningConstraint(InternalOptions options) {
-    // We currently require that having a simple inlining constraint implies that the method becomes
-    // empty after inlining. Therefore, an invoke is a nop if the simple inlining constraint is
-    // satisfied (if the invoke does not trigger other side effects, such as class initialization).
-    assert options.simpleInliningConstraintThreshold == 0;
-    return getSimpleInliningConstraint();
+  public SimpleInliningConstraint getNopInliningConstraint() {
+    return nopInliningConstraint;
   }
 
   @Override
@@ -595,7 +595,7 @@
     if (!mayHaveSideEffects()) {
       return false;
     }
-    if (getNopInliningConstraint(options).isSatisfied(invoke)) {
+    if (getNopInliningConstraint().isSatisfied(invoke)) {
       return false;
     }
     return true;
@@ -606,6 +606,22 @@
     return isFlagSet(RETURN_VALUE_ONLY_DEPENDS_ON_ARGUMENTS_FLAG);
   }
 
+  void setNopInliningConstraint(SimpleInliningConstraint constraint) {
+    this.nopInliningConstraint = constraint;
+  }
+
+  void unsetNopInliningConstraint() {
+    nopInliningConstraint = NeverSimpleInliningConstraint.getInstance();
+  }
+
+  public MutableMethodOptimizationInfo fixupNopInliningConstraint(
+      AppView<AppInfoWithLiveness> appView, MethodOptimizationInfoFixer fixer) {
+    nopInliningConstraint =
+        fixer.fixupNopInliningConstraint(
+            appView, nopInliningConstraint, appView.simpleInliningConstraintFactory());
+    return this;
+  }
+
   void setSimpleInliningConstraint(SimpleInliningConstraint constraint) {
     this.simpleInliningConstraint = constraint;
   }
@@ -811,6 +827,7 @@
         && instanceInitializerInfoCollection.isEmpty()
         && nonNullParamOrThrow == top.getNonNullParamOrThrow()
         && nonNullParamOnNormalExits == top.getNonNullParamOnNormalExits()
+        && nopInliningConstraint == top.getNopInliningConstraint()
         && simpleInliningConstraint == top.getSimpleInliningConstraint()
         && maxRemovedAndroidLogLevel == top.getMaxRemovedAndroidLogLevel()
         && parametersWithBitwiseOperations == top.getParametersWithBitwiseOperations()
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
index 413d343..54a0fc0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackDelayed.java
@@ -271,6 +271,11 @@
   }
 
   @Override
+  public void setNopInliningConstraint(ProgramMethod method, SimpleInliningConstraint constraint) {
+    getMethodOptimizationInfoForUpdating(method).setNopInliningConstraint(constraint);
+  }
+
+  @Override
   public synchronized void setSimpleInliningConstraint(
       ProgramMethod method, SimpleInliningConstraint constraint) {
     getMethodOptimizationInfoForUpdating(method).setSimpleInliningConstraint(constraint);
@@ -381,6 +386,11 @@
   }
 
   @Override
+  public void unsetNopInliningConstraint(ProgramMethod method) {
+    getMethodOptimizationInfoForUpdating(method).unsetNopInliningConstraint();
+  }
+
+  @Override
   public synchronized void unsetSimpleInliningConstraint(ProgramMethod method) {
     getMethodOptimizationInfoForUpdating(method).unsetSimpleInliningConstraint();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
index 61fe21d..3c32b83 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackIgnore.java
@@ -122,6 +122,9 @@
   public void setNonNullParamOnNormalExits(DexEncodedMethod method, BitSet facts) {}
 
   @Override
+  public void setNopInliningConstraint(ProgramMethod method, SimpleInliningConstraint constraint) {}
+
+  @Override
   public void setSimpleInliningConstraint(
       ProgramMethod method, SimpleInliningConstraint constraint) {}
 
@@ -189,6 +192,9 @@
   public void unsetReturnValueOnlyDependsOnArguments(ProgramMethod method) {}
 
   @Override
+  public void unsetNopInliningConstraint(ProgramMethod method) {}
+
+  @Override
   public void unsetSimpleInliningConstraint(ProgramMethod method) {}
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
index 9edabc2..c015121 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationFeedbackSimple.java
@@ -204,6 +204,11 @@
   }
 
   @Override
+  public void setNopInliningConstraint(ProgramMethod method, SimpleInliningConstraint constraint) {
+    method.getDefinition().getMutableOptimizationInfo().setNopInliningConstraint(constraint);
+  }
+
+  @Override
   public void setSimpleInliningConstraint(
       ProgramMethod method, SimpleInliningConstraint constraint) {
     method.getDefinition().getMutableOptimizationInfo().setSimpleInliningConstraint(constraint);
@@ -339,6 +344,12 @@
   }
 
   @Override
+  public void unsetNopInliningConstraint(ProgramMethod method) {
+    withMutableMethodOptimizationInfo(
+        method, MutableMethodOptimizationInfo::unsetNopInliningConstraint);
+  }
+
+  @Override
   public void unsetSimpleInliningConstraint(ProgramMethod method) {
     withMutableMethodOptimizationInfo(
         method, MutableMethodOptimizationInfo::unsetSimpleInliningConstraint);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
index 1ad49fd..db23102 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/OptimizationInfoRemover.java
@@ -59,6 +59,7 @@
     optimizationInfo.unsetDynamicType();
     optimizationInfo.unsetInitializedClassesOnNormalExit();
     optimizationInfo.unsetInstanceInitializerInfoCollection();
+    optimizationInfo.unsetNopInliningConstraint();
     optimizationInfo.unsetSimpleInliningConstraint();
     if (optimizationInfo.isEffectivelyDefault()) {
       method.unsetOptimizationInfo();
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 28f377b..3be695f 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -408,7 +408,7 @@
   public boolean enableDevirtualization = true;
   public boolean enableEnumUnboxing = true;
   public boolean enableSimpleInliningConstraints = true;
-  public final int simpleInliningConstraintThreshold = 0;
+  public final int simpleInliningConstraintThreshold = 1;
   public boolean enableClassInlining = true;
   public boolean enableClassStaticizer = true;
   public boolean enableInitializedClassesAnalysis = true;
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningTest.java
index 44eb259..3d8006e 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SwitchWithSimpleCasesInliningTest.java
@@ -5,7 +5,7 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
 
 import com.android.tools.r8.NeverInline;
 import com.android.tools.r8.TestBase;
@@ -46,8 +46,9 @@
 
               MethodSubject mainMethodSubject = mainClassSubject.mainMethod();
               assertThat(mainMethodSubject, isPresent());
-              // TODO(b/331337747): Should be true.
-              assertFalse(
+              // TODO(b/331337747): Account for constant canonicalization in constraint analysis.
+              assertEquals(
+                  parameters.isCfRuntime(),
                   mainMethodSubject
                       .streamInstructions()
                       .filter(InstructionSubject::isConstString)
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
index 0556718..d4e6cfd 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/b159688129/LambdaSplitByCodeCorrectnessTest.java
@@ -81,8 +81,7 @@
             inspector ->
                 inspector
                     .applyIf(
-                        kotlinParameters.isNewerThanOrEqualTo(KotlinCompilerVersion.KOTLINC_1_8_0)
-                            || splitGroup,
+                        splitGroup,
                         i -> {
                           if (kotlinParameters.getLambdaGeneration().isClass()) {
                             i.assertIsCompleteMergeGroup(
@@ -123,12 +122,7 @@
               ClassSubject mergeTarget =
                   codeInspector.clazz(
                       "com.android.tools.r8.kotlin.lambda.b159688129.SimpleKt$main$1");
-              assertThat(
-                  mergeTarget,
-                  isPresentIf(
-                      kotlinParameters.isNewerThanOrEqualTo(KotlinCompilerVersion.KOTLINC_1_8_0)
-                          || splitGroup));
-
+              assertThat(mergeTarget, isPresentIf(splitGroup));
               if (mergeTarget.isAbsent()) {
                 return;
               }