Merge "Refactor duplicate code for handling workarounds in the register allocator"
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 45b8055..85e0060 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
@@ -54,6 +54,8 @@
import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeSet;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
/**
* Linear scan register allocator.
@@ -1561,57 +1563,47 @@
return candidate;
}
+ private int handleWorkaround(
+ Predicate<LiveIntervals> workaroundNeeded,
+ BiPredicate<LiveIntervals, Integer> workaroundNeededForCandidate,
+ int candidate, LiveIntervals unhandledInterval, int registerConstraint,
+ boolean needsRegisterPair, RegisterPositions freePositions, RegisterPositions.Type type) {
+ if (workaroundNeeded.test(unhandledInterval)) {
+ int lastCandidate = candidate;
+ while (workaroundNeededForCandidate.test(unhandledInterval, candidate)) {
+ // Make the unusable register unavailable for allocation and try again.
+ freePositions.set(candidate, 0);
+ candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair, type);
+ // If there are only invalid candidates of the give type we will end up with the same
+ // candidate returned again once we have tried them all. In that case we didn't find a
+ // valid register candidate and we need to broaden the search to other types.
+ if (lastCandidate == candidate) {
+ return REGISTER_CANDIDATE_NOT_FOUND;
+ }
+ lastCandidate = candidate;
+ }
+ }
+ return candidate;
+ }
+
private int getLargestValidCandidate(LiveIntervals unhandledInterval, int registerConstraint,
boolean needsRegisterPair, RegisterPositions freePositions, RegisterPositions.Type type) {
int candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair, type);
if (candidate == REGISTER_CANDIDATE_NOT_FOUND) {
return candidate;
}
- if (needsLongResultOverlappingLongOperandsWorkaround(unhandledInterval)) {
- int lastCandidate = candidate;
- while (isLongResultOverlappingLongOperands(unhandledInterval, candidate)) {
- // Make the overlapping register unavailable for allocation and try again.
- freePositions.set(candidate, 0);
- candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair, type);
- // If there are only invalid candidates of the give type we will end up with the same
- // candidate returned again once we have tried them all. In that case we didn't find a
- // valid register candidate and we need to broaden the search to other types.
- if (lastCandidate == candidate) {
- return REGISTER_CANDIDATE_NOT_FOUND;
- }
- lastCandidate = candidate;
- }
- }
- if (needsSingleResultOverlappingLongOperandsWorkaround(unhandledInterval)) {
- int lastCandidate = candidate;
- while (isSingleResultOverlappingLongOperands(unhandledInterval, candidate)) {
- // Make the overlapping register unavailable for allocation and try again.
- freePositions.set(candidate, 0);
- candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair, type);
- // If there are only invalid candidates of the give type we will end up with the same
- // candidate returned again once we have tried them all. In that case we didn't find a
- // valid register candidate and we need to broaden the search to other types.
- if (lastCandidate == candidate) {
- return REGISTER_CANDIDATE_NOT_FOUND;
- }
- lastCandidate = candidate;
- }
- }
- if (needsArrayGetWideWorkaround(unhandledInterval)) {
- int lastCandidate = candidate;
- while (isArrayGetArrayRegister(unhandledInterval, candidate)) {
- // Make the overlapping register unavailable for allocation and try again.
- freePositions.set(candidate, 0);
- candidate = getLargestCandidate(registerConstraint, freePositions, needsRegisterPair, type);
- // If there are only invalid candidates of the give type we will end up with the same
- // candidate returned again once we have tried them all. In that case we didn't find a
- // valid register candidate and we need to broaden the search to other types.
- if (lastCandidate == candidate) {
- return REGISTER_CANDIDATE_NOT_FOUND;
- }
- lastCandidate = candidate;
- }
- }
+ candidate = handleWorkaround(
+ this::needsLongResultOverlappingLongOperandsWorkaround,
+ this::isLongResultOverlappingLongOperands,
+ candidate, unhandledInterval, registerConstraint, needsRegisterPair, freePositions, type);
+ candidate = handleWorkaround(
+ this::needsSingleResultOverlappingLongOperandsWorkaround,
+ this::isSingleResultOverlappingLongOperands,
+ candidate, unhandledInterval, registerConstraint, needsRegisterPair, freePositions, type);
+ candidate = handleWorkaround(
+ this::needsArrayGetWideWorkaround,
+ this::isArrayGetArrayRegister,
+ candidate, unhandledInterval, registerConstraint, needsRegisterPair, freePositions, type);
return candidate;
}