summaryrefslogtreecommitdiffstats
path: root/dx/src
diff options
context:
space:
mode:
authorjeffhao <jeffhao@google.com>2011-02-28 11:05:08 -0800
committerjeffhao <jeffhao@google.com>2011-02-28 16:20:48 -0800
commitb6f966024be7d6dd260735c9e541e23572f26f37 (patch)
tree11ce83c9e4354caee495f1d25966ea726bf464c5 /dx/src
parent57c4d01d04238b9f99412e96b31583e90fce4caf (diff)
downloadandroid_dalvik-b6f966024be7d6dd260735c9e541e23572f26f37.tar.gz
android_dalvik-b6f966024be7d6dd260735c9e541e23572f26f37.tar.bz2
android_dalvik-b6f966024be7d6dd260735c9e541e23572f26f37.zip
Improved register allocation for check-cast instructions.
Check-cast instructions that don't use the same register for source and destination no longer use an intermediate register due to expansion. This saves a move instruction and, in some cases, a register. Change-Id: Ib704fe51ec172e05efbff708e8b63004457cc8cb
Diffstat (limited to 'dx/src')
-rw-r--r--dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java53
1 files changed, 38 insertions, 15 deletions
diff --git a/dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java b/dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
index d99ad5822..ce4dcca3d 100644
--- a/dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
+++ b/dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
@@ -456,8 +456,9 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
}
/**
- * Handles check cast results to reuse the same source register if
- * possible.
+ * Handles check cast results to reuse the same source register.
+ * Inserts a move if it can't map the same register to both and the
+ * check cast is not caught.
*/
private void handleCheckCastResults() {
for (NormalSsaInsn insn : moveResultPseudoInsns) {
@@ -486,27 +487,49 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0);
int checkReg = checkRegSpec.getReg();
- // Assume none of the register is mapped yet
- int ropReg = 0;
-
/**
* See if either register is already mapped. Most likely the move
* result will be mapped already since the cast result is stored
* in a local variable.
*/
- if (ssaRegsMapped.get(moveReg)) {
- ropReg = mapper.oldToNew(moveReg);
- } else if (ssaRegsMapped.get(checkReg)) {
- ropReg = mapper.oldToNew(checkReg);
+ int category = checkRegSpec.getCategory();
+ boolean moveMapped = ssaRegsMapped.get(moveReg);
+ boolean checkMapped = ssaRegsMapped.get(checkReg);
+ if (moveMapped & !checkMapped) {
+ int moveRopReg = mapper.oldToNew(moveReg);
+ checkMapped = tryMapReg(checkRegSpec, moveRopReg, category);
+ }
+ if (checkMapped & !moveMapped) {
+ int checkRopReg = mapper.oldToNew(checkReg);
+ moveMapped = tryMapReg(moveRegSpec, checkRopReg, category);
}
- ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2);
- ssaRegs.add(moveRegSpec);
- ssaRegs.add(checkRegSpec);
- int category = checkRegSpec.getCategory();
+ // Map any unmapped registers to anything available
+ if (!moveMapped || !checkMapped) {
+ int ropReg = paramRangeEnd;
+ ArrayList<RegisterSpec> ssaRegs =
+ new ArrayList<RegisterSpec>(2);
+ ssaRegs.add(moveRegSpec);
+ ssaRegs.add(checkRegSpec);
- while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
- ropReg = findNextUnreservedRopReg(ropReg + 1, category);
+ while (!tryMapRegs(ssaRegs, ropReg, category, false)) {
+ ropReg = findNextUnreservedRopReg(ropReg + 1, category);
+ }
+ }
+
+ /*
+ * If source and result have a different mapping, insert a move so
+ * they can have the same mapping. Don't do this if the check cast
+ * is caught, since it will overwrite a potentially live value.
+ */
+ boolean hasExceptionHandlers =
+ checkCastInsn.getOriginalRopInsn().getCatches().size() != 0;
+ int moveRopReg = mapper.oldToNew(moveReg);
+ int checkRopReg = mapper.oldToNew(checkReg);
+ if (moveRopReg != checkRopReg && !hasExceptionHandlers) {
+ ((NormalSsaInsn) checkCastInsn).changeOneSource(0,
+ insertMoveBefore(checkCastInsn, checkRegSpec));
+ addMapping(checkCastInsn.getSources().get(0), moveRopReg);
}
}
}