diff options
author | Mads Ager <ager@google.com> | 2017-09-06 12:31:14 +0200 |
---|---|---|
committer | Mads Ager <ager@google.com> | 2017-09-06 12:31:14 +0200 |
commit | bfabe8e9865804be4233819245046ee6b3cc391e (patch) | |
tree | 49e33b1bfd3167c34db9a3b2eeee2a6ead952ccc | |
parent | a87c232958cbd8f89af46351df57153be64feb73 (diff) | |
download | r8-bfabe8e9865804be4233819245046ee6b3cc391e.tar.gz |
Version 0.1.9.
R=sgjesse@google.com
Merge: Fix register allocation bug triggering in rare situations in
debug mode.
CL: https://r8-review.googlesource.com/c/r8/+/5841
Change-Id: If049d5e99f08efab6716251a175dba54864f1e29
7 files changed, 26 insertions, 15 deletions
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java index 5e43513d3..dda9a3954 100644 --- a/src/main/java/com/android/tools/r8/D8.java +++ b/src/main/java/com/android/tools/r8/D8.java @@ -55,7 +55,7 @@ import java.util.concurrent.ExecutorService; */ public final class D8 { - private static final String VERSION = "v0.1.8"; + private static final String VERSION = "v0.1.9"; private static final int STATUS_ERROR = 1; private D8() {} diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java index e8efb59d9..a79a5cda3 100644 --- a/src/main/java/com/android/tools/r8/R8.java +++ b/src/main/java/com/android/tools/r8/R8.java @@ -71,7 +71,7 @@ import java.util.concurrent.Executors; public class R8 { - private static final String VERSION = "v0.1.8"; + private static final String VERSION = "v0.1.9"; private final Timing timing = new Timing("R8"); private final InternalOptions options; diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java index 460fe9231..300aece4b 100644 --- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java +++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java @@ -992,9 +992,6 @@ public class LinearScanRegisterAllocator implements RegisterAllocator { } private int getSpillRegister(LiveIntervals intervals) { - if (intervals.isArgumentInterval()) { - return intervals.getSplitParent().getRegister(); - } int registerNumber = nextUnusedRegisterNumber++; maxRegisterNumber = registerNumber; if (intervals.getType() == MoveType.WIDE) { @@ -1546,17 +1543,19 @@ public class LinearScanRegisterAllocator implements RegisterAllocator { LiveIntervals unhandledInterval, boolean needsRegisterPair, int candidate) { + List<LiveIntervals> newInactive = new ArrayList<>(); Iterator<LiveIntervals> inactiveIterator = inactive.iterator(); while (inactiveIterator.hasNext()) { LiveIntervals intervals = inactiveIterator.next(); if ((intervals.usesRegister(candidate) || (needsRegisterPair && intervals.usesRegister(candidate + 1))) && intervals.overlaps(unhandledInterval)) { - // If these assertions trigger we have changed the way blocked parts of intervals - // are handled. If we ever get intervals with fixed registers in here, we need - // to split them before the first use in the same way that we do when spilling - // overlapping active intervals. - assert !intervals.isLinked() || intervals.isArgumentInterval(); + if (intervals.isLinked() && !intervals.isArgumentInterval()) { + int nextUsePosition = intervals.firstUseAfter(unhandledInterval.getStart()); + LiveIntervals split = intervals.splitBefore(nextUsePosition); + split.setRegister(intervals.getRegister()); + newInactive.add(split); + } if (intervals.getStart() > unhandledInterval.getStart()) { // The inactive live intervals hasn't started yet. Clear the temporary register // assignment and move back to unhandled for register reassignment. @@ -1571,6 +1570,7 @@ public class LinearScanRegisterAllocator implements RegisterAllocator { } } } + inactive.addAll(newInactive); } private void spillOverlappingActiveIntervals( diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java index 65628c37e..18f193f52 100644 --- a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java +++ b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java @@ -88,6 +88,9 @@ public class LiveIntervals { } public boolean isRematerializable(LinearScanRegisterAllocator registerAllocator) { + if (value.isArgument()) { + return true; + } // TODO(ager): rematerialize const string as well. if (!value.isConstNumber()) { return false; diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java index 9cb873e99..0d267e94a 100644 --- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java +++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java @@ -26,7 +26,7 @@ public class RegisterMove { this.dst = dst; this.src = LinearScanRegisterAllocator.NO_REGISTER; this.type = type; - assert definition.isConstInstruction(); + assert definition.isConstInstruction() || definition.isArgument(); this.definition = definition; } diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveScheduler.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveScheduler.java index cc26729f2..d3c927c98 100644 --- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveScheduler.java +++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveScheduler.java @@ -121,8 +121,14 @@ public class RegisterMoveScheduler { Instruction instruction; Value to = new FixedRegisterValue(move.type, move.dst); if (move.definition != null) { - ConstNumber number = move.definition.asConstNumber(); - instruction = new ConstNumber(number.type, to, number.getRawValue()); + if (move.definition.isArgument()) { + int argumentRegister = move.definition.outValue().getLiveIntervals().getRegister(); + Value from = new FixedRegisterValue(move.type, argumentRegister); + instruction = new Move(to, from); + } else { + ConstNumber number = move.definition.asConstNumber(); + instruction = new ConstNumber(number.type, to, number.getRawValue()); + } } else { Value from = new FixedRegisterValue(move.type, valueMap.get(move.src)); instruction = new Move(to, from); diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java b/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java index 643a3c121..cd1d88014 100644 --- a/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java +++ b/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java @@ -31,8 +31,6 @@ class SpillMoveSet { // The register allocator generating moves. private LinearScanRegisterAllocator allocator; // All registers below this number are arguments. - // TODO(ager): Get rid of this field, we should deal with arguments and other values that can - // be rematerialized differently. private final int argumentRegisterLimit; // Mapping from instruction numbers to the block that start with that instruction if any. private final Map<Integer, BasicBlock> blockStartMap = new HashMap<>(); @@ -257,6 +255,10 @@ class SpillMoveSet { // disallowed at this point we know that argument registers do not change value and // therefore we don't have to perform spill moves. Performing spill moves will also // make art reject the code because it loses type information for the argument. + // + // TODO(ager): We are dealing with some of these moves as rematerialization. However, + // we are still generating actual moves back to the original argument register. + // We should get rid of this method and avoid generating the moves in the first place. private void removeArgumentRestores(Set<SpillMove> moves) { Iterator<SpillMove> moveIterator = moves.iterator(); while (moveIterator.hasNext()) { |