diff options
Diffstat (limited to 'src/main/java/com/android/tools/r8/ir/optimize')
3 files changed, 18 insertions, 1 deletions
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 6d6981757..4ede5a839 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 @@ -284,6 +284,10 @@ public class Inliner { if (block.hasCatchHandlers() && inlinee.getNormalExitBlock() == null) { continue; } + if (callGraph.isBreaker(method, target)) { + // Make sure we don't inline a call graph breaker. + continue; + } // If this code did not go through the full pipeline, apply inlining to make sure // that force inline targets get processed. if (!target.isProcessed()) { diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java index 4b93d8d77..446b75a63 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java @@ -66,6 +66,7 @@ public class InliningOracle { assert !candidate.getOptimizationInfo().forceInline(); return null; } + if (candidate.accessFlags.isSynchronized()) { // Don't inline if target is synchronized. if (info != null) { @@ -73,6 +74,12 @@ public class InliningOracle { } return null; } + + if (callGraph.isBreaker(method, candidate)) { + // Cycle breaker so abort to preserve compilation order. + return null; + } + if (!inliner.hasInliningAccess(method, candidate)) { if (info != null) { info.exclude(invoke, "Inlinee candidate does not have right access flags"); @@ -154,6 +161,11 @@ public class InliningOracle { return null; } + if (callGraph.isBreaker(method, target)) { + // Cycle breaker so abort to preserve compilation order. + return null; + } + // Abort inlining attempt if method -> target access is not right. if (!inliner.hasInliningAccess(method, target)) { if (info != null) { diff --git a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java index de81dfeff..9a7086453 100644 --- a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java +++ b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java @@ -42,6 +42,7 @@ public class PeepholeOptimizer { private static void shareIdenticalBlockSuffix(IRCode code, RegisterAllocator allocator) { Collection<BasicBlock> blocks = code.blocks; do { + int startNumberOfNewBlock = code.getHighestBlockNumber() + 1; Map<BasicBlock, BasicBlock> newBlocks = new IdentityHashMap<>(); for (BasicBlock block : blocks) { InstructionEquivalence equivalence = new InstructionEquivalence(allocator); @@ -79,7 +80,7 @@ public class PeepholeOptimizer { commonSuffixSize, sharedSuffixSizeExcludingExit(firstPred, pred, allocator)); } assert commonSuffixSize >= 1; - int blockNumber = code.blocks.size() + newBlocks.size(); + int blockNumber = startNumberOfNewBlock + newBlocks.size(); BasicBlock newBlock = createAndInsertBlockForSuffix( blockNumber, commonSuffixSize, predsWithSameLastInstruction, block); newBlocks.put(predsWithSameLastInstruction.get(0), newBlock); |