Refine api checks for inlining
Bug: b/382017168
Change-Id: I7ad1878b76db1957e70d7837ab2afabe49c23086
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 fea6435..e811b72 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
@@ -156,7 +156,7 @@
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 (!isApiSafeForInlining(method, singleTarget, options, whyAreYouNotInliningReporter)) {
+ if (!isApiSafeForInlining(method, singleTarget, appView, whyAreYouNotInliningReporter)) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 8b213c7..e7fc8c5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -988,7 +988,7 @@
return null;
}
// Check the api level is allowed to be inlined.
- if (!isApiSafeForInlining(method, singleTarget, appView.options())) {
+ if (!isApiSafeForInlining(method, singleTarget, appView)) {
return null;
}
// Check that the entire constructor chain can be inlined into the current context.
@@ -1015,7 +1015,7 @@
return null;
}
// Check the api level is allowed to be inlined.
- if (!isApiSafeForInlining(method, encodedParent, appView.options())) {
+ if (!isApiSafeForInlining(method, encodedParent, appView)) {
return null;
}
parent =
diff --git a/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java b/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
index 26b85ed..690724e 100644
--- a/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
@@ -49,7 +49,7 @@
(callee, caller) ->
callee.getDefinition().isLibraryMethodOverride().isPossiblyTrue()
|| !appView.getKeepInfo(callee).isSingleCallerInliningAllowed(options, callee)
- || !AndroidApiLevelUtils.isApiSafeForInlining(caller, callee, appView.options()));
+ || !AndroidApiLevelUtils.isApiSafeForInlining(caller, callee, appView));
return traceInstructions(singleCallerMethodCandidates, executorService);
}
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 8c483f7..cf855e7 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -34,30 +34,34 @@
public class AndroidApiLevelUtils {
public static boolean isApiSafeForInlining(
- ProgramMethod caller, ProgramMethod inlinee, InternalOptions options) {
+ ProgramMethod caller,
+ ProgramMethod inlinee,
+ AppView<? extends AppInfoWithClassHierarchy> appView) {
return isApiSafeForInlining(
- caller, inlinee, options, NopWhyAreYouNotInliningReporter.getInstance());
+ caller, inlinee, appView, NopWhyAreYouNotInliningReporter.getInstance());
}
- @SuppressWarnings("ReferenceEquality")
public static boolean isApiSafeForInlining(
ProgramMethod caller,
ProgramMethod inlinee,
- InternalOptions options,
+ AppView<? extends AppInfoWithClassHierarchy> appView,
WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
- if (!options.apiModelingOptions().isApiCallerIdentificationEnabled()) {
+ if (!appView.options().apiModelingOptions().isApiCallerIdentificationEnabled()) {
return true;
}
- if (caller.getHolderType() == inlinee.getHolderType()) {
+ if (caller.getHolder() == inlinee.getHolder()) {
return true;
}
ComputedApiLevel callerApiLevelForCode = caller.getDefinition().getApiLevelForCode();
+ ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
if (callerApiLevelForCode.isUnknownApiLevel()) {
+ if (inlineeApiLevelForCode.isEqualTo(appView.computedMinApiLevel())) {
+ return true;
+ }
whyAreYouNotInliningReporter.reportCallerHasUnknownApiLevel();
return false;
}
// For inlining we only measure if the code has invokes into the library.
- ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
if (!caller
.getDefinition()
.getApiLevelForCode()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
index dac6de6..9f42bbf 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
@@ -28,7 +28,9 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ // Always use the min API level to prohibit constructor inlining so that the constructors of
+ // interest are still present at the time of horizontal class merging.
+ return getTestParameters().withAllRuntimes().withMinimumApiLevel().build();
}
@Test