Refactor computation of free positions to separate method
Change-Id: Ic26179e18dd4c474d7383274d35531dbd4f83339
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 c099750..549930b 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
@@ -1658,76 +1658,7 @@
registerConstraint += numberOfArgumentRegisters;
}
- // Set all free positions for possible registers to max integer.
- RegisterPositions freePositions = new RegisterPositionsImpl(registerConstraint + 1);
-
- if ((options().debug || code.context().isReachabilitySensitive())
- && !code.method().accessFlags.isStatic()) {
- // If we are generating debug information or if the method is reachability sensitive,
- // we pin the this value register. The debugger expects to always be able to find it in
- // the input register.
- assert numberOfArgumentRegisters > 0;
- assert firstArgumentValue != null && firstArgumentValue.requiredRegisters() == 1;
- freePositions.setBlocked(0);
- }
-
- if (mode == ArgumentReuseMode.ALLOW_ARGUMENT_REUSE_U8BIT
- || mode == ArgumentReuseMode.ALLOW_ARGUMENT_REUSE_U16BIT) {
- // Argument reuse is not allowed and we block all the argument registers so that
- // arguments are never free.
- for (int i = 0; i < numberOfArgumentRegisters && i <= registerConstraint; i++) {
- freePositions.setBlocked(i);
- }
- }
-
- // If there is a move exception instruction we block register 0 as the move exception
- // register. If we cannot find a free valid register for the move exception value we have no
- // place to put a spill move (because the move exception instruction has to be the
- // first instruction in the handler block).
- if (overlapsMoveExceptionInterval(unhandledInterval)) {
- int moveExceptionRegister = getMoveExceptionRegister();
- if (moveExceptionRegister <= registerConstraint) {
- freePositions.setBlocked(moveExceptionRegister);
- }
- }
-
- // All the active intervals are not free at this point.
- for (LiveIntervals intervals : active) {
- int activeRegister = intervals.getRegister();
- if (activeRegister <= registerConstraint) {
- for (int i = 0; i < intervals.requiredRegisters(); i++) {
- if (activeRegister + i <= registerConstraint) {
- freePositions.setBlocked(activeRegister + i);
- }
- }
- }
- }
-
- // The register for inactive intervals that overlap with this interval are free until
- // the next overlap.
- for (LiveIntervals intervals : inactive) {
- int inactiveRegister = intervals.getRegister();
- if (inactiveRegister <= registerConstraint && unhandledInterval.overlaps(intervals)) {
- int nextOverlap = unhandledInterval.nextOverlap(intervals);
- for (int i = 0; i < intervals.requiredRegisters(); i++) {
- int register = inactiveRegister + i;
- if (register <= registerConstraint && !freePositions.isBlocked(register)) {
- int unhandledStart = toInstructionPosition(unhandledInterval.getStart());
- if (nextOverlap == unhandledStart) {
- // Don't use the register for an inactive interval that is only free until the next
- // instruction. We can get into this situation when unhandledInterval starts at a
- // gap position.
- freePositions.setBlocked(register);
- } else {
- if (nextOverlap < freePositions.get(register)) {
- freePositions.set(register, nextOverlap, intervals);
- }
- }
- }
- }
- }
- }
-
+ RegisterPositions freePositions = computeFreePositions(unhandledInterval, registerConstraint);
assert freePositionsAreConsistentWithFreeRegisters(freePositions, registerConstraint);
// Attempt to use register hints.
@@ -1800,6 +1731,80 @@
return true;
}
+ private RegisterPositions computeFreePositions(
+ LiveIntervals unhandledInterval, int registerConstraint) {
+ // Set all free positions for possible registers to max integer.
+ RegisterPositions freePositions = new RegisterPositionsImpl(registerConstraint + 1);
+
+ if ((options().debug || code.context().isReachabilitySensitive())
+ && !code.method().accessFlags.isStatic()) {
+ // If we are generating debug information or if the method is reachability sensitive,
+ // we pin the this value register. The debugger expects to always be able to find it in
+ // the input register.
+ assert numberOfArgumentRegisters > 0;
+ assert firstArgumentValue != null && firstArgumentValue.requiredRegisters() == 1;
+ freePositions.setBlocked(0);
+ }
+
+ if (mode == ArgumentReuseMode.ALLOW_ARGUMENT_REUSE_U8BIT
+ || mode == ArgumentReuseMode.ALLOW_ARGUMENT_REUSE_U16BIT) {
+ // Argument reuse is not allowed and we block all the argument registers so that
+ // arguments are never free.
+ for (int i = 0; i < numberOfArgumentRegisters && i <= registerConstraint; i++) {
+ freePositions.setBlocked(i);
+ }
+ }
+
+ // If there is a move exception instruction we block register 0 as the move exception
+ // register. If we cannot find a free valid register for the move exception value we have no
+ // place to put a spill move (because the move exception instruction has to be the
+ // first instruction in the handler block).
+ if (overlapsMoveExceptionInterval(unhandledInterval)) {
+ int moveExceptionRegister = getMoveExceptionRegister();
+ if (moveExceptionRegister <= registerConstraint) {
+ freePositions.setBlocked(moveExceptionRegister);
+ }
+ }
+
+ // All the active intervals are not free at this point.
+ for (LiveIntervals intervals : active) {
+ int activeRegister = intervals.getRegister();
+ if (activeRegister <= registerConstraint) {
+ for (int i = 0; i < intervals.requiredRegisters(); i++) {
+ if (activeRegister + i <= registerConstraint) {
+ freePositions.setBlocked(activeRegister + i);
+ }
+ }
+ }
+ }
+
+ // The register for inactive intervals that overlap with this interval are free until
+ // the next overlap.
+ for (LiveIntervals intervals : inactive) {
+ int inactiveRegister = intervals.getRegister();
+ if (inactiveRegister <= registerConstraint && unhandledInterval.overlaps(intervals)) {
+ int nextOverlap = unhandledInterval.nextOverlap(intervals);
+ for (int i = 0; i < intervals.requiredRegisters(); i++) {
+ int register = inactiveRegister + i;
+ if (register <= registerConstraint && !freePositions.isBlocked(register)) {
+ int unhandledStart = toInstructionPosition(unhandledInterval.getStart());
+ if (nextOverlap == unhandledStart) {
+ // Don't use the register for an inactive interval that is only free until the next
+ // instruction. We can get into this situation when unhandledInterval starts at a
+ // gap position.
+ freePositions.setBlocked(register);
+ } else {
+ if (nextOverlap < freePositions.get(register)) {
+ freePositions.set(register, nextOverlap, intervals);
+ }
+ }
+ }
+ }
+ }
+ }
+ return freePositions;
+ }
+
// Attempt to use the register hint for the unhandled interval in order to avoid generating
// moves.
private boolean useRegisterHint(LiveIntervals unhandledInterval, int registerConstraint,