Fix inadequate type propagation in class inliner Bug: 160818086 Change-Id: I7ca426a114162352541fd52e23c5e86fc9232c8a
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java index e7104f3..f172fa9 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -253,8 +253,10 @@ } // Inline the class instance. + Set<Value> affectedValues = Sets.newIdentityHashSet(); try { - anyInlinedMethods |= processor.processInlining(code, defaultOracle, inliningIRProvider); + anyInlinedMethods |= + processor.processInlining(code, affectedValues, defaultOracle, inliningIRProvider); } catch (IllegalClassInlinerStateException e) { // We introduced a user that we cannot handle in the class inliner as a result of force // inlining. Abort gracefully from class inlining without removing the instance. @@ -270,7 +272,6 @@ assert inliningIRProvider.verifyIRCacheIsEmpty(); // Restore normality. - Set<Value> affectedValues = Sets.newIdentityHashSet(); code.removeAllDeadAndTrivialPhis(affectedValues); if (!affectedValues.isEmpty()) { new TypeAnalysis(appView).narrowing(affectedValues);
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 acd7477..ec1f830 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
@@ -392,7 +392,10 @@ // // Returns `true` if at least one method was inlined. boolean processInlining( - IRCode code, Supplier<InliningOracle> defaultOracle, InliningIRProvider inliningIRProvider) + IRCode code, + Set<Value> affectedValues, + Supplier<InliningOracle> defaultOracle, + InliningIRProvider inliningIRProvider) throws IllegalClassInlinerStateException { // Verify that `eligibleInstance` is not aliased. assert eligibleInstance == eligibleInstance.getAliasedValue(); @@ -417,7 +420,7 @@ anyInlinedMethods |= forceInlineDirectMethodInvocations(code, inliningIRProvider); anyInlinedMethods |= forceInlineIndirectMethodInvocations(code, inliningIRProvider); removeAliasIntroducingInstructionsLinkedToEligibleInstance(); - removeMiscUsages(code); + removeMiscUsages(code, affectedValues); removeFieldReads(code); removeFieldWrites(); removeInstruction(root); @@ -625,7 +628,7 @@ } // Remove miscellaneous users before handling field reads. - private void removeMiscUsages(IRCode code) { + private void removeMiscUsages(IRCode code, Set<Value> affectedValues) { boolean needToRemoveUnreachableBlocks = false; for (Instruction user : eligibleInstance.uniqueUsers()) { if (user.isInvokeMethod()) { @@ -702,7 +705,7 @@ } if (needToRemoveUnreachableBlocks) { - code.removeUnreachableBlocks(); + affectedValues.addAll(code.removeUnreachableBlocks()); } }