Support for -whyareyounotinlining in InliningStrategy.willExceedBudget()

Bug: 142108662
Change-Id: I137f0316812be4cfe6208882acea6d42840df24e
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 3cc3788..2692240 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
@@ -492,13 +492,23 @@
           numberOfThrowingInstructionsInInlinee * block.numberOfCatchHandlers();
       // Abort if inlining could lead to an explosion in the number of control flow
       // resolution blocks that setup the register state before the actual catch handler.
-      if (estimatedNumberOfControlFlowResolutionBlocks
-          >= appView.options().inliningControlFlowResolutionBlocksThreshold) {
+      int threshold = appView.options().inliningControlFlowResolutionBlocksThreshold;
+      if (estimatedNumberOfControlFlowResolutionBlocks >= threshold) {
+        whyAreYouNotInliningReporter
+            .reportPotentialExplosionInExceptionalControlFlowResolutionBlocks(
+                estimatedNumberOfControlFlowResolutionBlocks, threshold);
         return true;
       }
     }
 
-    return instructionAllowance < Inliner.numberOfInstructions(inlinee.code);
+    int numberOfInstructions = Inliner.numberOfInstructions(inlinee.code);
+    if (instructionAllowance < Inliner.numberOfInstructions(inlinee.code)) {
+      whyAreYouNotInliningReporter.reportWillExceedInstructionBudget(
+          numberOfInstructions, instructionAllowance);
+      return true;
+    }
+
+    return false;
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 03afa7b..73dbddb 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -841,8 +841,7 @@
                   getPositionForInlining(invoke, context),
                   lensCodeRewriter);
           if (strategy.willExceedBudget(inlinee, block, whyAreYouNotInliningReporter)) {
-            // TODO(b/142108662): Enable assertion once reporting is complete.
-            // assert whyAreYouNotInliningReporter.verifyReasonHasBeenReported();
+            assert whyAreYouNotInliningReporter.verifyReasonHasBeenReported();
             continue;
           }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotKeepingReporter.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotKeepingReporter.java
index 7951526..56f97b1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotKeepingReporter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/NopWhyAreYouNotKeepingReporter.java
@@ -16,9 +16,16 @@
   }
 
   @Override
+  public void reportPotentialExplosionInExceptionalControlFlowResolutionBlocks(
+      int estimatedNumberOfControlFlowResolutionBlocks, int threshold) {}
+
+  @Override
   public void reportUnknownTarget() {}
 
   @Override
+  public void reportWillExceedInstructionBudget(int numberOfInstructions, int threshold) {}
+
+  @Override
   public boolean verifyReasonHasBeenReported() {
     return true;
   }
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 a4f63fd..a86ab56 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
@@ -41,7 +41,12 @@
     }
   }
 
+  public abstract void reportPotentialExplosionInExceptionalControlFlowResolutionBlocks(
+      int estimatedNumberOfControlFlowResolutionBlocks, int threshold);
+
   abstract void reportUnknownTarget();
 
+  public abstract void reportWillExceedInstructionBudget(int numberOfInstructions, int threshold);
+
   public abstract boolean verifyReasonHasBeenReported();
 }
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 a629bf9..9d469d0 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
@@ -32,12 +32,36 @@
     reasonHasBeenReported = true;
   }
 
+  private void printWithExceededThreshold(
+      String reason, String description, int value, int threshold) {
+    print(reason + " (" + description + ": " + value + ", threshold: " + threshold + ").");
+  }
+
+  @Override
+  public void reportPotentialExplosionInExceptionalControlFlowResolutionBlocks(
+      int estimatedNumberOfControlFlowResolutionBlocks, int threshold) {
+    printWithExceededThreshold(
+        "could lead to an explosion in the number of moves due to the exceptional control flow",
+        "estimated number of control flow resolution blocks",
+        estimatedNumberOfControlFlowResolutionBlocks,
+        threshold);
+  }
+
   @Override
   public void reportUnknownTarget() {
     print("could not find a single target.");
   }
 
   @Override
+  public void reportWillExceedInstructionBudget(int numberOfInstructions, int threshold) {
+    printWithExceededThreshold(
+        "would exceed the caller's instruction budget",
+        "number of instructions in inlinee",
+        numberOfInstructions,
+        threshold);
+  }
+
+  @Override
   public boolean verifyReasonHasBeenReported() {
     assert reasonHasBeenReported;
     return true;