Merge "DebugLocalsChange instructions after spill moves"
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 cd7b6b6..8ad7a32 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
@@ -298,10 +298,11 @@
ranges.sort(LocalRange::compareTo);
// At each instruction compute the changes to live locals.
- boolean localsChanged = false;
LinkedList<LocalRange> openRanges = new LinkedList<>();
Iterator<LocalRange> rangeIterator = ranges.iterator();
LocalRange nextStartingRange = rangeIterator.next();
+ Int2ReferenceMap<DebugLocalInfo> ending = new Int2ReferenceOpenHashMap<>();
+ Int2ReferenceMap<DebugLocalInfo> starting = new Int2ReferenceOpenHashMap<>();
for (BasicBlock block : blocks) {
// Skip past all spill moves to obtain the instruction number of the actual first instruction.
@@ -347,42 +348,52 @@
instruction.clearDebugValues();
instructionIterator.remove();
}
- if (isSpillInstruction(instruction)) {
+ if (!instructionIterator.hasNext()) {
+ break;
+ }
+ Instruction nextInstruction = instructionIterator.peekNext();
+ if (isSpillInstruction(nextInstruction)) {
+ // No need to insert a DebugLocalsChange instruction before a spill instruction.
continue;
}
- int index = instruction.getNumber();
+ int index = nextInstruction.getNumber();
ListIterator<LocalRange> it = openRanges.listIterator(0);
- Int2ReferenceMap<DebugLocalInfo> ending = new Int2ReferenceOpenHashMap<>();
- Int2ReferenceMap<DebugLocalInfo> starting = new Int2ReferenceOpenHashMap<>();
while (it.hasNext()) {
LocalRange openRange = it.next();
- // Any local change is inserted after the instruction so end is inclusive.
- if (openRange.end <= index) {
+ // Close ranges up-to but excluding the first instruction.
+ if (!isLocalLiveAtInstruction(nextInstruction, openRange)) {
it.remove();
assert currentLocals.get(openRange.register) == openRange.local;
currentLocals.remove(openRange.register);
- localsChanged = true;
ending.put(openRange.register, openRange.local);
}
}
- while (nextStartingRange != null && nextStartingRange.start <= index) {
+ while (nextStartingRange != null && nextStartingRange.start < index) {
// If the range is live at this index open it.
- if (index < nextStartingRange.end) {
+ if (isLocalLiveAtInstruction(nextInstruction, nextStartingRange)) {
openRanges.add(nextStartingRange);
assert !currentLocals.containsKey(nextStartingRange.register);
currentLocals.put(nextStartingRange.register, nextStartingRange.local);
starting.put(nextStartingRange.register, nextStartingRange.local);
- localsChanged = true;
}
nextStartingRange = rangeIterator.hasNext() ? rangeIterator.next() : null;
}
- if (localsChanged && instruction.getBlock().exit() != instruction) {
- DebugLocalsChange change = createLocalsChange(ending, starting);
- if (change != null) {
- instructionIterator.add(change);
+ // Compute the final change in locals and insert it before nextInstruction.
+ boolean localsChanged = !ending.isEmpty() || !starting.isEmpty();
+ if (localsChanged) {
+ boolean skipChange =
+ nextInstruction == nextInstruction.getBlock().exit() && nextInstruction.isGoto();
+ if (!skipChange) {
+ DebugLocalsChange change = createLocalsChange(ending, starting);
+ if (change != null) {
+ // Insert the DebugLocalsChange instruction before nextInstruction.
+ instructionIterator.add(change);
+ }
}
+ // Create new maps for the next DebugLocalsChange instruction.
+ ending = new Int2ReferenceOpenHashMap<>();
+ starting = new Int2ReferenceOpenHashMap<>();
}
- localsChanged = false;
}
}
}
@@ -391,11 +402,6 @@
return isLocalLiveAtInstruction(instruction, range.start, range.end, range.value);
}
- public static boolean isLocalLiveAtInstruction(
- Instruction instruction, LiveRange range, Value value) {
- return isLocalLiveAtInstruction(instruction, range.start, range.end, value);
- }
-
private static boolean isLocalLiveAtInstruction(
Instruction instruction, int start, int end, Value value) {
int number = instruction.getNumber();