Print computed api levels to -whyareyounotinlining

Bug: 216801769
Change-Id: I1fb8b0c859a42f7edfa87a8da5d4a15a25c4ae5f
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 a39688a..8182229 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
@@ -130,8 +130,9 @@
       WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
     // Do not inline if the inlinee is greater than the api caller level.
     // TODO(b/188498051): We should not force inline lower api method calls.
-    if (reason != Reason.FORCE && !isApiSafeForInlining(method, singleTarget, appView.options())) {
-      whyAreYouNotInliningReporter.reportInlineeHigherApiCall();
+    if (reason != Reason.FORCE
+        && !isApiSafeForInlining(
+            method, singleTarget, appView.options(), whyAreYouNotInliningReporter)) {
       return false;
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotInliningReporter.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotInliningReporter.java
index cc7d4ec..d3d3735 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotInliningReporter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotInliningReporter.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.optimize.inliner;
 
+import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.ir.code.InstancePut;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.InvokeDirect;
@@ -34,6 +35,9 @@
   public void reportCallerNotSubtype() {}
 
   @Override
+  public void reportCallerHasUnknownApiLevel() {}
+
+  @Override
   public void reportClasspathMethod() {}
 
   @Override
@@ -55,7 +59,8 @@
   public void reportInlineeNotSimple() {}
 
   @Override
-  public void reportInlineeHigherApiCall() {}
+  public void reportInlineeHigherApiCall(
+      ComputedApiLevel callerApiLevel, ComputedApiLevel inlineeApiLevel) {}
 
   @Override
   public void reportInlineeRefersToClassesNotInMainDex() {}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
index 66d6108..7c3e5da 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.optimize.inliner;
 
+import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.InstancePut;
@@ -53,6 +54,8 @@
 
   public abstract void reportCallerNotSubtype();
 
+  public abstract void reportCallerHasUnknownApiLevel();
+
   public abstract void reportClasspathMethod();
 
   public abstract void reportInaccessible();
@@ -67,7 +70,8 @@
 
   public abstract void reportInlineeNotSimple();
 
-  public abstract void reportInlineeHigherApiCall();
+  public abstract void reportInlineeHigherApiCall(
+      ComputedApiLevel callerApiLevel, ComputedApiLevel inlineeApiLevel);
 
   public abstract void reportInlineeRefersToClassesNotInMainDex();
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
index 94632b6..f5807dd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.optimize.inliner;
 
+import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.InstancePut;
 import com.android.tools.r8.ir.code.Instruction;
@@ -73,6 +74,11 @@
   }
 
   @Override
+  public void reportCallerHasUnknownApiLevel() {
+    print("computed API level for caller is unknown");
+  }
+
+  @Override
   public void reportClasspathMethod() {
     print("inlinee is on the classpath.");
   }
@@ -115,8 +121,20 @@
   }
 
   @Override
-  public void reportInlineeHigherApiCall() {
-    print("inlinee having a higher api call than caller context.");
+  public void reportInlineeHigherApiCall(
+      ComputedApiLevel callerApiLevel, ComputedApiLevel inlineeApiLevel) {
+    assert callerApiLevel.isKnownApiLevel();
+    if (inlineeApiLevel.isUnknownApiLevel()) {
+      print("computed API level for inlinee is unknown");
+    } else {
+      assert inlineeApiLevel.isKnownApiLevel();
+      print(
+          "computed API level for inlinee ("
+              + inlineeApiLevel.asKnownApiLevel().getApiLevel()
+              + ") is higher than caller's ("
+              + callerApiLevel.asKnownApiLevel().getApiLevel()
+              + ")");
+    }
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
index 72ae4c0..8eb6b51 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -11,26 +11,44 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.LibraryMethod;
 import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.optimize.inliner.NopWhyAreYouNotInliningReporter;
+import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
 
 public class AndroidApiLevelUtils {
 
   public static boolean isApiSafeForInlining(
       ProgramMethod caller, ProgramMethod inlinee, InternalOptions options) {
+    return isApiSafeForInlining(
+        caller, inlinee, options, NopWhyAreYouNotInliningReporter.getInstance());
+  }
+
+  public static boolean isApiSafeForInlining(
+      ProgramMethod caller,
+      ProgramMethod inlinee,
+      InternalOptions options,
+      WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
     if (!options.apiModelingOptions().enableApiCallerIdentification) {
       return true;
     }
     if (caller.getHolderType() == inlinee.getHolderType()) {
       return true;
     }
-    ComputedApiLevel apiLevelForCode = caller.getDefinition().getApiLevelForCode();
-    if (apiLevelForCode.isUnknownApiLevel()) {
+    ComputedApiLevel callerApiLevelForCode = caller.getDefinition().getApiLevelForCode();
+    if (callerApiLevelForCode.isUnknownApiLevel()) {
+      whyAreYouNotInliningReporter.reportCallerHasUnknownApiLevel();
       return false;
     }
     // For inlining we only measure if the code has invokes into the library.
-    return caller
+    ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
+    if (!caller
         .getDefinition()
         .getApiLevelForCode()
-        .isGreaterThanOrEqualTo(inlinee.getDefinition().getApiLevelForCode());
+        .isGreaterThanOrEqualTo(inlineeApiLevelForCode)) {
+      whyAreYouNotInliningReporter.reportInlineeHigherApiCall(
+          callerApiLevelForCode, inlineeApiLevelForCode);
+      return false;
+    }
+    return true;
   }
 
   public static ComputedApiLevel getApiReferenceLevelForMerging(