aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMads Ager <ager@google.com>2017-09-06 12:31:14 +0200
committerMads Ager <ager@google.com>2017-09-06 12:31:14 +0200
commitbfabe8e9865804be4233819245046ee6b3cc391e (patch)
tree49e33b1bfd3167c34db9a3b2eeee2a6ead952ccc
parenta87c232958cbd8f89af46351df57153be64feb73 (diff)
downloadr8-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
-rw-r--r--src/main/java/com/android/tools/r8/D8.java2
-rw-r--r--src/main/java/com/android/tools/r8/R8.java2
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java16
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java3
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java2
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/RegisterMoveScheduler.java10
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java6
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()) {