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
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 5e43513..dda9a39 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 @@
*/
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 e8efb59..a79a5cd 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 @@
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 460fe92..300aece 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 @@
}
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 @@
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 @@
}
}
}
+ 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 65628c3..18f193f 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 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 9cb873e..0d267e9 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 @@
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 cc26729..d3c927c 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 @@
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 643a3c1..cd1d880 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 @@
// 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 @@
// 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()) {