diff options
author | Ben Cheng <bccheng@android.com> | 2011-03-22 14:09:09 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@android.com> | 2011-03-31 13:19:19 -0700 |
commit | 32115a971ea00ab2421fab4e4a3afa6c50c82173 (patch) | |
tree | 46a022082ba16b413c4978d2d1014b0623a82492 /vm/compiler/codegen | |
parent | 9220113edce56372d613f7aba006513ae85a99bc (diff) | |
download | android_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.c | 5 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/Assemble.c | 5 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 53 | ||||
-rw-r--r-- | vm/compiler/codegen/arm/armv7-a-neon/MethodCodegenDriver.c | 4 |
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)); |