Reg promotion fix; full optimization by default
As anticipated, the register promotion problem was related to type
inference. The Dalvik bytecode definition doesn't explicitly carry
type information on some opcodes. The problem this time was that
invoke results are stored in a magic untyped return location, which is
later accesses via (also untyped) OP_MOVE_RESULT.
Most of the time, the existing type inference mechanism was able to
figure out the result register type, but there was a pattern in which
it could be missed. Fixed (the last type inference bug, I hope).
This CL also re-enables full optimization by default (which will also
result in a quite significant reduction in code size).
Change-Id: I4c13455df7eba5c932e2cc7907b00c8b3b2f85b8
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index ba5bd3d..5855341 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -28,8 +28,8 @@
//(1 << kLoadHoisting) |
//(1 << kSuppressLoads) |
//(1 << kNullCheckElimination) |
- (1 << kPromoteRegs) |
- (1 << kTrackLiveTemps) |
+ //(1 << kPromoteRegs) |
+ //(1 << kTrackLiveTemps) |
0;
uint32_t compilerDebugFlags = 0 | // Enable debug/testing modes
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index 9a50c83..4e90382 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -65,6 +65,20 @@
return false;
}
+// Try to find the next move result which might have an FP target
+STATIC SSARepresentation* findMoveResult(MIR* mir)
+{
+ SSARepresentation* res = NULL;
+ for (; mir; mir = mir->next) {
+ if ((mir->dalvikInsn.opcode == OP_MOVE_RESULT) ||
+ (mir->dalvikInsn.opcode == OP_MOVE_RESULT_WIDE)) {
+ res = mir->ssaRep;
+ break;
+ }
+ }
+ return res;
+}
+
/*
* Infer types and sizes. We don't need to track change on sizes,
* as it doesn't propagate. We're guaranteed at least one pass through
@@ -139,9 +153,9 @@
}
}
- // Special-case handling for format 35c/3rc invokes
- Opcode opcode = mir->dalvikInsn.opcode;
- int flags = (opcode >= kNumPackedOpcodes) ? 0 :
+ // Special-case handling for format 35c/3rc invokes
+ Opcode opcode = mir->dalvikInsn.opcode;
+ int flags = (opcode >= kNumPackedOpcodes) ? 0 :
dexGetFlagsFromOpcode(opcode);
if ((flags & kInstrInvoke) &&
(attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
@@ -149,6 +163,24 @@
int target_idx = mir->dalvikInsn.vB;
const char* shorty =
oatGetShortyFromTargetIdx(cUnit, target_idx);
+ // Handle result type if floating point
+ if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
+ // Find move-result that consumes this result
+ SSARepresentation* tgtRep = findMoveResult(mir->next);
+ // Might be in next basic block
+ if (!tgtRep) {
+ tgtRep = findMoveResult(bb->fallThrough->firstMIRInsn);
+ }
+ // Result might not be used at all, so no move-result
+ if (tgtRep) {
+ tgtRep->fpDef[0] = true;
+ changed |= setFp(cUnit, tgtRep->defs[0], true);
+ if (shorty[0] == 'D') {
+ tgtRep->fpDef[1] = true;
+ changed |= setFp(cUnit, tgtRep->defs[1], true);
+ }
+ }
+ }
int numUses = mir->dalvikInsn.vA;
// If this is a non-static invoke, skip implicit "this"
if (((mir->dalvikInsn.opcode != OP_INVOKE_STATIC) &&