Prioritize lib method modeling in side-effect analysis of invocations.

Change-Id: I11364edfcf4396bc1b6f1c46b044e9d79f93b620
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index c1004de..ef8cae6 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -402,9 +402,12 @@
   public final Set<DexMethod> libraryMethodsReturningNonNull =
       ImmutableSet.of(classMethods.getName, classMethods.getSimpleName, stringMethods.valueOf);
 
+  // We assume library methods listed here are `public`, i.e., free from visibility side effects.
+  // If not, that library method should not be added here because it literally has side effects.
   public Set<DexMethod> libraryMethodsWithoutSideEffects =
       ImmutableSet.<DexMethod>builder()
           .add(objectMethods.constructor)
+          .addAll(classMethods.getNames)
           .addAll(stringBufferMethods.constructorMethods)
           .addAll(stringBuilderMethods.constructorMethods)
           .build();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index bddfc6a..9be25b6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -162,6 +162,11 @@
       return true;
     }
 
+    // Check if it is a call to one of library methods that are known to be side-effect free.
+    if (appView.dexItemFactory().libraryMethodsWithoutSideEffects.contains(getInvokedMethod())) {
+      return false;
+    }
+
     // Find the target and check if the invoke may have side effects.
     if (appView.appInfo().hasLiveness()) {
       AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
@@ -176,8 +181,7 @@
         return true;
       }
 
-      // Verify that the target method does not have side-effects. For program methods, we use
-      // optimization info, and for library methods, we use modeling.
+      // Verify that the target method does not have side-effects.
       DexClass clazz = appView.definitionFor(target.method.holder);
       if (clazz == null) {
         assert false : "Expected to be able to find the enclosing class of a method definition";
@@ -186,12 +190,8 @@
       boolean targetMayHaveSideEffects;
       if (appViewWithLiveness.appInfo().noSideEffects.containsKey(target.method)) {
         targetMayHaveSideEffects = false;
-      } else if (clazz.isProgramClass()) {
-        targetMayHaveSideEffects = target.getOptimizationInfo().mayHaveSideEffects();
       } else {
-        assert clazz.isLibraryClass();
-        targetMayHaveSideEffects =
-            !appView.dexItemFactory().libraryMethodsWithoutSideEffects.contains(target.method);
+        targetMayHaveSideEffects = target.getOptimizationInfo().mayHaveSideEffects();
       }
 
       return targetMayHaveSideEffects;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index e659c39..93e98db 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -149,6 +149,11 @@
       return true;
     }
 
+    // Check if it is a call to one of library methods that are known to be side-effect free.
+    if (appView.dexItemFactory().libraryMethodsWithoutSideEffects.contains(getInvokedMethod())) {
+      return false;
+    }
+
     // Find the target and check if the invoke may have side effects.
     if (appView.appInfo().hasLiveness()) {
       AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
index 3bc7380..a2ce1bc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
@@ -137,8 +137,8 @@
       return true;
     }
 
-    // Check if it is a call to one of java.lang.Class.get*Name().
-    if (appView.dexItemFactory().classMethods.isReflectiveNameLookup(getInvokedMethod())) {
+    // Check if it is a call to one of library methods that are known to be side-effect free.
+    if (appView.dexItemFactory().libraryMethodsWithoutSideEffects.contains(getInvokedMethod())) {
       return false;
     }