Keep methods with code for for -configurationdebugging

The CF code generated for methods - which would otherwise be removed -
when -configurationdebugging is turned on is simple throwing code. They
they will be processed during IR processing. To avoid optimizations
like unused argument removal to change these methods mark them as
pinned.

Change-Id: I01f97c1e7587bc4fb3078d101d1f4e50b3a990c6
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 9843e2b..f757f20 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -372,7 +372,10 @@
               appView
                   .appInfo()
                   .withLiveness()
-                  .prunedCopyFrom(application, pruner.getRemovedClasses()));
+                  .prunedCopyFrom(
+                      application,
+                      pruner.getRemovedClasses(),
+                      pruner.getMethodsToKeepForConfigurationDebugging()));
           new AbstractMethodRemover(appView.appInfo().withLiveness()).run();
 
           // Mark dead proto extensions fields as neither being read nor written.
@@ -664,7 +667,8 @@
                     .appInfo()
                     .prunedCopyFrom(
                         application,
-                        CollectionUtils.mergeSets(prunedTypes, pruner.getRemovedClasses())));
+                        CollectionUtils.mergeSets(prunedTypes, pruner.getRemovedClasses()),
+                        pruner.getMethodsToKeepForConfigurationDebugging()));
 
             // TODO(b/130721661): Enable this assert.
             // assert Inliner.verifyNoMethodsInlinedDueToSingleCallSite(appView);
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index f48b72b..d11adc8 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -318,13 +318,14 @@
   }
 
   private AppInfoWithLiveness(AppInfoWithLiveness previous) {
-    this(previous, previous.app(), null);
+    this(previous, previous.app(), null, null);
   }
 
   private AppInfoWithLiveness(
       AppInfoWithLiveness previous,
       DexApplication application,
-      Collection<DexType> removedClasses) {
+      Collection<DexType> removedClasses,
+      Collection<DexReference> additionalPinnedItems) {
     this(
         application,
         previous.liveTypes,
@@ -345,7 +346,9 @@
         previous.staticInvokes,
         previous.callSites,
         previous.brokenSuperInvokes,
-        previous.pinnedItems,
+        additionalPinnedItems == null
+            ? previous.pinnedItems
+            : CollectionUtils.mergeSets(previous.pinnedItems, additionalPinnedItems),
         previous.mayHaveSideEffects,
         previous.noSideEffects,
         previous.assumedValues,
@@ -736,9 +739,11 @@
    * DexApplication object.
    */
   public AppInfoWithLiveness prunedCopyFrom(
-      DexApplication application, Collection<DexType> removedClasses) {
+      DexApplication application,
+      Collection<DexType> removedClasses,
+      Collection<DexReference> additionalPinnedItems) {
     assert checkIfObsolete();
-    return new AppInfoWithLiveness(this, application, removedClasses);
+    return new AppInfoWithLiveness(this, application, removedClasses, additionalPinnedItems);
   }
 
   public AppInfoWithLiveness rewrittenWithLense(
diff --git a/src/main/java/com/android/tools/r8/shaking/TreePruner.java b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
index 594f32d..6130112 100644
--- a/src/main/java/com/android/tools/r8/shaking/TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
@@ -8,7 +8,9 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.EnclosingMethodAttribute;
@@ -32,6 +34,7 @@
   private final AppView<AppInfoWithLiveness> appView;
   private final UsagePrinter usagePrinter;
   private final Set<DexType> prunedTypes = Sets.newIdentityHashSet();
+  private final Set<DexMethod> methodsToKeepForConfigurationDebugging = Sets.newIdentityHashSet();
 
   public TreePruner(DexApplication application, AppView<AppInfoWithLiveness> appView) {
     this.application = application;
@@ -255,6 +258,7 @@
             method.shouldNotHaveCode() && !method.hasCode()
                 ? method
                 : method.toMethodThatLogsError(appView));
+        methodsToKeepForConfigurationDebugging.add(method.method);
       } else if (appInfo.targetedMethods.contains(method.getKey())) {
         // If the method is already abstract, and doesn't have code, let it be.
         if (method.shouldNotHaveCode() && !method.hasCode()) {
@@ -330,4 +334,8 @@
   public Collection<DexType> getRemovedClasses() {
     return Collections.unmodifiableCollection(prunedTypes);
   }
+
+  public Collection<DexReference> getMethodsToKeepForConfigurationDebugging() {
+    return Collections.unmodifiableCollection(methodsToKeepForConfigurationDebugging);
+  }
 }