summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen
diff options
context:
space:
mode:
authorBen Cheng <bccheng@android.com>2011-03-22 14:09:09 -0700
committerBen Cheng <bccheng@android.com>2011-03-31 13:19:19 -0700
commit32115a971ea00ab2421fab4e4a3afa6c50c82173 (patch)
tree46a022082ba16b413c4978d2d1014b0623a82492 /vm/compiler/codegen
parent9220113edce56372d613f7aba006513ae85a99bc (diff)
downloadandroid_dalvik-32115a971ea00ab2421fab4e4a3afa6c50c82173.tar.gz
android_dalvik-32115a971ea00ab2421fab4e4a3afa6c50c82173.tar.bz2
android_dalvik-32115a971ea00ab2421fab4e4a3afa6c50c82173.zip
Generate code for loops formed with the new builder
Adapt the existing counted loop analysis and range/null check elimination code to work with the new loop building heuristics. Cleaned up the old ad-hoc loop builder. Suspend polling is enabled by default for loops. The backward chaining cell will be used in self-verification and profiling mode. If the loop includes accesses to resolved fields/classes, abort code generation for now and revert to the basic acyclic trace. Added tests/090-loop-formation to make sure the JIT won't choke on such instructions. Change-Id: Idbc57df0a745be3b692f68c1acb6d4861c537f75
Diffstat (limited to 'vm/compiler/codegen')
-rw-r--r--vm/compiler/codegen/arm/ArchUtility.c5
-rw-r--r--vm/compiler/codegen/arm/Assemble.c5
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.c53
-rw-r--r--vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c4
4 files changed, 49 insertions, 18 deletions
diff --git a/vm/compiler/codegen/arm/ArchUtility.c b/vm/compiler/codegen/arm/ArchUtility.c
index fb28e2605..edcbf86a0 100644
--- a/vm/compiler/codegen/arm/ArchUtility.c
+++ b/vm/compiler/codegen/arm/ArchUtility.c
@@ -316,20 +316,25 @@ void dvmDumpLIRInsn(LIR *arg, unsigned char *baseAddr)
DUMP_SSA_REP(LOGD("-------- %s\n", (char *) dest));
break;
case kArmPseudoChainingCellBackwardBranch:
+ LOGD("L%p:\n", lir);
LOGD("-------- chaining cell (backward branch): 0x%04x\n", dest);
break;
case kArmPseudoChainingCellNormal:
+ LOGD("L%p:\n", lir);
LOGD("-------- chaining cell (normal): 0x%04x\n", dest);
break;
case kArmPseudoChainingCellHot:
+ LOGD("L%p:\n", lir);
LOGD("-------- chaining cell (hot): 0x%04x\n", dest);
break;
case kArmPseudoChainingCellInvokePredicted:
+ LOGD("L%p:\n", lir);
LOGD("-------- chaining cell (predicted): %s%s\n",
dest ? ((Method *) dest)->clazz->descriptor : "",
dest ? ((Method *) dest)->name : "N/A");
break;
case kArmPseudoChainingCellInvokeSingleton:
+ LOGD("L%p:\n", lir);
LOGD("-------- chaining cell (invoke singleton): %s%s/%p\n",
((Method *)dest)->clazz->descriptor,
((Method *)dest)->name,
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 0e919c496..dfc68b6f3 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -1001,6 +1001,11 @@ static AssemblerStatus assembleInstructions(CompilationUnit *cUnit,
lir->operands[1] = 0;
lir->generic.target = 0;
dvmCompilerSetupResourceMasks(lir);
+ if (cUnit->printMe) {
+ LOGD("kThumb2Cbnz/kThumb2Cbz@%x: delta=%d",
+ lir->generic.offset, delta);
+ dvmCompilerCodegenDump(cUnit);
+ }
return kRetryAll;
} else {
lir->operands[1] = delta >> 1;
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index 8d8619b22..f020e9c63 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -1356,6 +1356,12 @@ static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir)
int flagsToCheck = kInstrCanBranch | kInstrCanSwitch | kInstrCanReturn |
kInstrCanThrow;
+ // Single stepping is considered loop mode breaker
+ if (cUnit->jitMode == kJitLoop) {
+ cUnit->quitLoopMode = true;
+ return;
+ }
+
//If already optimized out, just ignore
if (mir->dalvikInsn.opcode == OP_NOP)
return;
@@ -1448,7 +1454,8 @@ static bool handleFmt10t_Fmt20t_Fmt30t(CompilationUnit *cUnit, MIR *mir,
/* backward branch? */
bool backwardBranch = (bb->taken->startOffset <= mir->offset);
- if (backwardBranch && gDvmJit.genSuspendPoll) {
+ if (backwardBranch &&
+ (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
genSuspendPoll(cUnit, mir);
}
@@ -1579,6 +1586,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(cUnit->method->clazz->pDvmDex->pResStrings[mir->dalvikInsn.vB]);
if (strPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null string");
dvmAbort();
}
@@ -1595,6 +1603,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
if (classPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null class");
dvmAbort();
}
@@ -1631,6 +1640,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
Opcode opcode = mir->dalvikInsn.opcode;
if (fieldPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null static field");
dvmAbort();
}
@@ -1664,6 +1674,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(method->clazz->pDvmDex->pResFields[mir->dalvikInsn.vB]);
if (fieldPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null static field");
dvmAbort();
}
@@ -1707,6 +1718,12 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(method->clazz->pDvmDex->pResFields[mir->dalvikInsn.vB]);
Opcode opcode = mir->dalvikInsn.opcode;
+ if (fieldPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
+ LOGE("Unexpected null static field");
+ dvmAbort();
+ }
+
isVolatile = (opcode == OP_SPUT_VOLATILE) ||
(opcode == OP_SPUT_VOLATILE_JUMBO) ||
(opcode == OP_SPUT_OBJECT_VOLATILE) ||
@@ -1718,11 +1735,6 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(opcode == OP_SPUT_OBJECT_VOLATILE) ||
(opcode == OP_SPUT_OBJECT_VOLATILE_JUMBO);
- if (fieldPtr == NULL) {
- LOGE("Unexpected null static field");
- dvmAbort();
- }
-
rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
loadConstant(cUnit, tReg, (int) fieldPtr);
@@ -1755,6 +1767,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(method->clazz->pDvmDex->pResFields[mir->dalvikInsn.vB]);
if (fieldPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null static field");
dvmAbort();
}
@@ -1778,6 +1791,7 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
(cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
if (classPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null class");
dvmAbort();
}
@@ -1829,9 +1843,10 @@ static bool handleFmt21c_Fmt31c_Fmt41c(CompilationUnit *cUnit, MIR *mir)
* so that we can tell if it happens frequently.
*/
if (classPtr == NULL) {
- LOGVV("null clazz in OP_CHECK_CAST, single-stepping");
- genInterpSingleStep(cUnit, mir);
- return false;
+ BAIL_LOOP_COMPILATION();
+ LOGVV("null clazz in OP_CHECK_CAST, single-stepping");
+ genInterpSingleStep(cUnit, mir);
+ return false;
}
dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
loadConstant(cUnit, r1, (int) classPtr );
@@ -2093,7 +2108,8 @@ static bool handleFmt21t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
/* backward branch? */
bool backwardBranch = (bb->taken->startOffset <= mir->offset);
- if (backwardBranch && gDvmJit.genSuspendPoll) {
+ if (backwardBranch &&
+ (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
genSuspendPoll(cUnit, mir);
}
@@ -2426,6 +2442,7 @@ static bool handleFmt22c_Fmt52c(CompilationUnit *cUnit, MIR *mir)
method->clazz->pDvmDex->pResFields[mir->dalvikInsn.vC];
if (fieldPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null instance field");
dvmAbort();
}
@@ -2448,6 +2465,7 @@ static bool handleFmt22c_Fmt52c(CompilationUnit *cUnit, MIR *mir)
(cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vC]);
if (classPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGE("Unexpected null class");
dvmAbort();
}
@@ -2499,6 +2517,7 @@ static bool handleFmt22c_Fmt52c(CompilationUnit *cUnit, MIR *mir)
* so that we can tell if it happens frequently.
*/
if (classPtr == NULL) {
+ BAIL_LOOP_COMPILATION();
LOGD("null clazz in OP_INSTANCE_OF, single-stepping");
genInterpSingleStep(cUnit, mir);
break;
@@ -2627,7 +2646,8 @@ static bool handleFmt22t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
/* backward branch? */
bool backwardBranch = (bb->taken->startOffset <= mir->offset);
- if (backwardBranch && gDvmJit.genSuspendPoll) {
+ if (backwardBranch &&
+ (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
genSuspendPoll(cUnit, mir);
}
@@ -4238,7 +4258,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
}
- if (bb->blockType == kTraceEntryBlock) {
+ if (bb->blockType == kEntryBlock) {
labelList[i].opcode = kArmPseudoEntryBlock;
if (bb->firstMIRInsn == NULL) {
continue;
@@ -4246,10 +4266,11 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
setupLoopEntryBlock(cUnit, bb,
&labelList[bb->fallThrough->id]);
}
- } else if (bb->blockType == kTraceExitBlock) {
+ } else if (bb->blockType == kExitBlock) {
labelList[i].opcode = kArmPseudoExitBlock;
goto gen_fallthrough;
} else if (bb->blockType == kDalvikByteCode) {
+ if (bb->hidden == true) continue;
labelList[i].opcode = kArmPseudoNormalBlockLabel;
/* Reset the register state */
dvmCompilerResetRegPool(cUnit);
@@ -4297,8 +4318,8 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
/* Make sure exception handling block is next */
labelList[i].opcode =
kArmPseudoPCReconstructionBlockLabel;
- assert (i == cUnit->numBlocks - 2);
- handlePCReconstruction(cUnit, &labelList[i+1]);
+ handlePCReconstruction(cUnit,
+ &labelList[cUnit->puntBlock->id]);
break;
case kExceptionHandling:
labelList[i].opcode = kArmPseudoEHBlockLabel;
@@ -4510,7 +4531,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
}
}
- if (bb->blockType == kTraceEntryBlock) {
+ if (bb->blockType == kEntryBlock) {
dvmCompilerAppendLIR(cUnit,
(LIR *) cUnit->loopAnalysis->branchToBody);
dvmCompilerAppendLIR(cUnit,
diff --git a/vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c b/vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c
index 5a08b60ac..98d97d871 100644
--- a/vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c
+++ b/vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c
@@ -255,13 +255,13 @@ static bool methodBlockCodeGen(CompilationUnit *cUnit, BasicBlock *bb)
ArmLIR *headLIR = NULL;
- if (bb->blockType == kMethodEntryBlock) {
+ if (bb->blockType == kEntryBlock) {
/* r0 = callsitePC */
opImm(cUnit, kOpPush, (1 << r0 | 1 << r1 | 1 << r5FP | 1 << r14lr));
opRegImm(cUnit, kOpSub, r5FP,
sizeof(StackSaveArea) + cUnit->method->registersSize * 4);
- } else if (bb->blockType == kMethodExitBlock) {
+ } else if (bb->blockType == kExitBlock) {
/* No need to pop r0 and r1 */
opRegImm(cUnit, kOpAdd, r13sp, 8);
opImm(cUnit, kOpPop, (1 << r5FP | 1 << r15pc));