Move compose options out of TestingOptions

Change-Id: Ib8f38158549401b3c51d2d3b4e826d34eb50541a
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 85a71d4..e096d1e 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -196,7 +196,7 @@
         timing.time(
             "Compilation context", () -> CompilationContext.createInitialContext(options()));
     this.wholeProgramOptimizations = wholeProgramOptimizations;
-    abstractValueFactory = new AbstractValueFactory(options());
+    abstractValueFactory = new AbstractValueFactory();
     abstractValueConstantPropagationJoiner = new AbstractValueConstantPropagationJoiner(this);
     if (enableWholeProgramOptimizations()) {
       abstractValueFieldJoiner = new AbstractValueFieldJoiner(withClassHierarchy());
@@ -542,7 +542,7 @@
   }
 
   public ComposeReferences getComposeReferences() {
-    assert testing().modelChangedArgumentsToComposableFunctions;
+    assert options().getJetpackComposeOptions().isAnyOptimizationsEnabled();
     if (composeReferences == null) {
       composeReferences = new ComposeReferences(dexItemFactory());
     }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValueFactory.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValueFactory.java
index 2e59422..27534c2 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValueFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValueFactory.java
@@ -14,14 +14,10 @@
 import com.android.tools.r8.ir.analysis.value.objectstate.KnownLengthArrayState;
 import com.android.tools.r8.ir.analysis.value.objectstate.ObjectState;
 import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
-import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.InternalOptions.TestingOptions;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class AbstractValueFactory {
 
-  private final TestingOptions testingOptions;
-
   private final ConcurrentHashMap<DexType, SingleConstClassValue> singleConstClassValues =
       new ConcurrentHashMap<>();
   private final ConcurrentHashMap<Long, SingleNumberValue> singleNumberValues =
@@ -33,10 +29,6 @@
   private final ConcurrentHashMap<Integer, KnownLengthArrayState> knownArrayLengthStates =
       new ConcurrentHashMap<>();
 
-  public AbstractValueFactory(InternalOptions options) {
-    testingOptions = options.testing;
-  }
-
   public SingleBoxedBooleanValue createBoxedBooleanFalse() {
     return SingleBoxedBooleanValue.getFalseInstance();
   }
@@ -83,15 +75,6 @@
     if (definitelySetBits != 0 || definitelyUnsetBits != 0) {
       // If all bits are known, then create a single number value.
       boolean allBitsSet = (definitelySetBits | definitelyUnsetBits) == ALL_BITS_SET_MASK;
-      // Account for the temporary hack in the Compose modeling where we create a
-      // DefiniteBitsNumberValue with set bits=0b1^32 and unset bits = 0b1^(31)0. This value is used
-      // to simulate the effect of `x | 1` in joins.
-      if (testingOptions.modelChangedArgumentsToComposableFunctions) {
-        boolean overlappingSetAndUnsetBits = (definitelySetBits & definitelyUnsetBits) != 0;
-        if (overlappingSetAndUnsetBits) {
-          allBitsSet = false;
-        }
-      }
       if (allBitsSet) {
         return createUncheckedSingleNumberValue(definitelySetBits);
       }
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScannerModeling.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScannerModeling.java
index c5c3476..b4f5f95 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScannerModeling.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScannerModeling.java
@@ -17,7 +17,10 @@
 
   ArgumentPropagatorCodeScannerModeling(AppView<AppInfoWithLiveness> appView) {
     this.composeModeling =
-        appView.testing().modelChangedArgumentsToComposableFunctions
+        appView
+                .options()
+                .getJetpackComposeOptions()
+                .isModelingChangedArgumentsToComposableFunctions()
             ? new ArgumentPropagatorComposeModeling(appView)
             : null;
   }
diff --git a/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorComposeModeling.java b/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorComposeModeling.java
index 8450fe3..6890b1c 100644
--- a/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorComposeModeling.java
+++ b/src/main/java/com/android/tools/r8/optimize/compose/ArgumentPropagatorComposeModeling.java
@@ -38,7 +38,10 @@
   private final DexString invokeName;
 
   public ArgumentPropagatorComposeModeling(AppView<AppInfoWithLiveness> appView) {
-    assert appView.testing().modelChangedArgumentsToComposableFunctions;
+    assert appView
+        .options()
+        .getJetpackComposeOptions()
+        .isModelingChangedArgumentsToComposableFunctions();
     this.appView = appView;
     this.rewrittenComposeReferences =
         appView
diff --git a/src/main/java/com/android/tools/r8/optimize/compose/ComposableOptimizationPass.java b/src/main/java/com/android/tools/r8/optimize/compose/ComposableOptimizationPass.java
index 3da6f3b..c2890d8 100644
--- a/src/main/java/com/android/tools/r8/optimize/compose/ComposableOptimizationPass.java
+++ b/src/main/java/com/android/tools/r8/optimize/compose/ComposableOptimizationPass.java
@@ -6,8 +6,6 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.ir.conversion.PrimaryR8IRConverter;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.InternalOptions.TestingOptions;
 import com.android.tools.r8.utils.SetUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Iterables;
@@ -35,18 +33,11 @@
       ExecutorService executorService,
       Timing timing)
       throws ExecutionException {
-    InternalOptions options = appView.options();
-    if (!options.isOptimizing() || !options.isShrinking()) {
-      return;
+    if (appView.options().getJetpackComposeOptions().isComposableOptimizationPassEnabled()) {
+      timing.time(
+          "ComposableOptimizationPass",
+          () -> new ComposableOptimizationPass(appView, converter).processWaves(executorService));
     }
-    TestingOptions testingOptions = options.getTestingOptions();
-    if (!testingOptions.enableComposableOptimizationPass
-        || !testingOptions.modelChangedArgumentsToComposableFunctions) {
-      return;
-    }
-    timing.time(
-        "ComposableOptimizationPass",
-        () -> new ComposableOptimizationPass(appView, converter).processWaves(executorService));
   }
 
   void processWaves(ExecutorService executorService) throws ExecutionException {
diff --git a/src/main/java/com/android/tools/r8/optimize/compose/JetpackComposeOptions.java b/src/main/java/com/android/tools/r8/optimize/compose/JetpackComposeOptions.java
new file mode 100644
index 0000000..69ec5e6
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/optimize/compose/JetpackComposeOptions.java
@@ -0,0 +1,42 @@
+// 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.optimize.compose;
+
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.SystemPropertyUtils;
+
+public class JetpackComposeOptions {
+
+  private final InternalOptions options;
+
+  public boolean enableComposableOptimizationPass =
+      SystemPropertyUtils.parseSystemPropertyOrDefault(
+          "com.android.tools.r8.jetpackcompose.enableComposableOptimizationPass", false);
+
+  public boolean enableModelingOfChangedArguments =
+      SystemPropertyUtils.parseSystemPropertyOrDefault(
+          "com.android.tools.r8.jetpackcompose.enableModelingOfChangedArguments", false);
+
+  public JetpackComposeOptions(InternalOptions options) {
+    this.options = options;
+  }
+
+  public void enableAllOptimizations(boolean enable) {
+    enableComposableOptimizationPass = enable;
+    enableModelingOfChangedArguments = enable;
+  }
+
+  public boolean isAnyOptimizationsEnabled() {
+    return isComposableOptimizationPassEnabled()
+        || isModelingChangedArgumentsToComposableFunctions();
+  }
+
+  public boolean isComposableOptimizationPassEnabled() {
+    return isModelingChangedArgumentsToComposableFunctions() && enableComposableOptimizationPass;
+  }
+
+  public boolean isModelingChangedArgumentsToComposableFunctions() {
+    return options.isOptimizing() && options.isShrinking() && enableModelingOfChangedArguments;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index 4254412..0fa843d 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -334,7 +334,7 @@
       AnnotatedKind kind,
       Mode mode,
       InternalOptions options) {
-    return options.testing.modelChangedArgumentsToComposableFunctions
+    return options.getJetpackComposeOptions().isAnyOptimizationsEnabled()
         && mode.isInitialTreeShaking()
         && kind.isMethod()
         && annotation
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 a00cd5b..28f377b 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -82,6 +82,7 @@
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.optimize.accessmodification.AccessModifierOptions;
 import com.android.tools.r8.optimize.argumentpropagation.ArgumentPropagatorEventConsumer;
+import com.android.tools.r8.optimize.compose.JetpackComposeOptions;
 import com.android.tools.r8.optimize.redundantbridgeremoval.RedundantBridgeRemovalOptions;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
@@ -931,6 +932,7 @@
   private final CfCodeAnalysisOptions cfCodeAnalysisOptions = new CfCodeAnalysisOptions();
   private final ClassInlinerOptions classInlinerOptions = new ClassInlinerOptions();
   private final InlinerOptions inlinerOptions = new InlinerOptions(this);
+  private final JetpackComposeOptions jetpackComposeOptions = new JetpackComposeOptions(this);
   private final HorizontalClassMergerOptions horizontalClassMergerOptions =
       new HorizontalClassMergerOptions();
   private final VerticalClassMergerOptions verticalClassMergerOptions =
@@ -984,6 +986,10 @@
     return horizontalClassMergerOptions;
   }
 
+  public JetpackComposeOptions getJetpackComposeOptions() {
+    return jetpackComposeOptions;
+  }
+
   public VerticalClassMergerOptions getVerticalClassMergerOptions() {
     return verticalClassMergerOptions;
   }
@@ -2389,12 +2395,6 @@
         System.getProperty("com.android.tools.r8.disableMarkingClassesFinal") != null;
     public boolean testEnableTestAssertions = false;
     public boolean keepMetadataInR8IfNotRewritten = true;
-    public boolean enableComposableOptimizationPass =
-        SystemPropertyUtils.parseSystemPropertyForDevelopmentOrDefault(
-            "com.android.tools.r8.enableComposableOptimizationPass", false);
-    public boolean modelChangedArgumentsToComposableFunctions =
-        SystemPropertyUtils.parseSystemPropertyForDevelopmentOrDefault(
-            "com.android.tools.r8.modelChangedArgumentsToComposableFunctions", false);
 
     // Flag to allow processing of resources in D8. A data resource consumer still needs to be
     // specified.
diff --git a/src/test/java/com/android/tools/r8/compose/NestedComposableArgumentPropagationTest.java b/src/test/java/com/android/tools/r8/compose/NestedComposableArgumentPropagationTest.java
index 7ca99c9..7c40462 100644
--- a/src/test/java/com/android/tools/r8/compose/NestedComposableArgumentPropagationTest.java
+++ b/src/test/java/com/android/tools/r8/compose/NestedComposableArgumentPropagationTest.java
@@ -116,9 +116,9 @@
             .addOptionsModification(
                 options -> {
                   options.getOpenClosedInterfacesOptions().suppressAllOpenInterfaces();
-                  options.testing.enableComposableOptimizationPass = enableComposeOptimizations;
-                  options.testing.modelChangedArgumentsToComposableFunctions =
-                      enableComposeOptimizations;
+                  options
+                      .getJetpackComposeOptions()
+                      .enableAllOptimizations(enableComposeOptimizations);
                 })
             .setMinApi(AndroidApiLevel.N)
             .allowDiagnosticMessages()
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/ArgumentInfoCollectionTest.java b/src/test/java/com/android/tools/r8/enumunboxing/ArgumentInfoCollectionTest.java
index 556a914..4bab75f 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/ArgumentInfoCollectionTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/ArgumentInfoCollectionTest.java
@@ -130,7 +130,7 @@
   public void testCombineRemoveRewritten() {
     InternalOptions options = new InternalOptions();
     DexItemFactory factory = options.dexItemFactory();
-    AbstractValueFactory abstractValueFactory = new AbstractValueFactory(options);
+    AbstractValueFactory abstractValueFactory = new AbstractValueFactory();
 
     ArgumentInfoCollection.Builder builder1 = ArgumentInfoCollection.builder();
     builder1.addArgumentInfo(