diff options
Diffstat (limited to 'src/compiler/codegen')
| -rw-r--r-- | src/compiler/codegen/arm/ArchUtility.cc | 3 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/ArmLIR.h | 7 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/MethodCodegenDriver.cc | 38 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 22 |
5 files changed, 62 insertions, 14 deletions
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc index 1d6bb41b8a..45e1b19ee7 100644 --- a/src/compiler/codegen/arm/ArchUtility.cc +++ b/src/compiler/codegen/arm/ArchUtility.cc @@ -354,6 +354,9 @@ void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr) case kArmPseudoThrowTarget: LOG(INFO) << "LT" << (intptr_t)lir << ":"; break; + case kArmPseudoSuspendTarget: + LOG(INFO) << "LS" << (intptr_t)lir << ":"; + break; case kArmPseudoCaseLabel: LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" << std::hex << lir->operands[0] << "|" << std::dec << diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h index 07e2e97661..e436eea6ed 100644 --- a/src/compiler/codegen/arm/ArmLIR.h +++ b/src/compiler/codegen/arm/ArmLIR.h @@ -28,7 +28,7 @@ * pointer in r0 as a hidden arg0. Otherwise used as codegen scratch * registers. * r0-r1: As in C/C++ r0 is 32-bit return register and r0/r1 is 64-bit - * r4 : Callee save (promotion target) + * r4 : (rSUSPEND) is reserved (suspend check assist) * r5 : Callee save (promotion target) * r6 : Callee save (promotion target) * r7 : Callee save (promotion target) @@ -243,7 +243,7 @@ typedef enum OpKind { /* * Annotate special-purpose core registers: - * - VM: r4PC, r5FP, and r6SELF + * - VM: r6SELF * - ARM architecture: r13sp, r14lr, and r15pc * * rPC, rFP, and rSELF are for architecture-independent code to use. @@ -253,7 +253,7 @@ typedef enum NativeRegisterPool { r1 = 1, r2 = 2, r3 = 3, - r4 = 4, + rSUSPEND = 4, r5 = 5, r6 = 6, r7 = 7, @@ -366,6 +366,7 @@ typedef enum ArmThrowKind { * Assemble.c. */ typedef enum ArmOpcode { + kArmPseudoSuspendTarget = -15, kArmPseudoThrowTarget = -14, kArmPseudoCaseLabel = -13, kArmPseudoMethodEntry = -12, diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc index ce658033ea..41053a2def 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -1113,10 +1113,12 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, case OP_RETURN: case OP_RETURN_OBJECT: + genSuspendPoll(cUnit, mir); storeValue(cUnit, retLoc, rlSrc[0]); break; case OP_RETURN_WIDE: + genSuspendPoll(cUnit, mir); rlDest = retLocWide; rlDest.fp = rlSrc[0].fp; storeValueWide(cUnit, rlDest, rlSrc[0]); @@ -1277,11 +1279,8 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, case OP_GOTO: case OP_GOTO_16: case OP_GOTO_32: - // TUNING: add MIR flag to disable when unnecessary - bool backwardBranch; - backwardBranch = (bb->taken->startOffset <= mir->offset); - if (backwardBranch) { - genSuspendPoll(cUnit, mir); + if (bb->taken->startOffset <= mir->offset) { + genSuspendTest(cUnit, mir); } genUnconditionalBranch(cUnit, &labelList[bb->taken->id]); break; @@ -1315,7 +1314,7 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, ArmConditionCode cond; backwardBranch = (bb->taken->startOffset <= mir->offset); if (backwardBranch) { - genSuspendPoll(cUnit, mir); + genSuspendTest(cUnit, mir); } rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg); rlSrc[1] = loadValue(cUnit, rlSrc[1], kCoreReg); @@ -1358,7 +1357,7 @@ static bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir, ArmConditionCode cond; backwardBranch = (bb->taken->startOffset <= mir->offset); if (backwardBranch) { - genSuspendPoll(cUnit, mir); + genSuspendTest(cUnit, mir); } rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg); opRegImm(cUnit, kOpCmp, rlSrc[0].lowReg, 0); @@ -1999,6 +1998,27 @@ void removeRedundantBranches(CompilationUnit* cUnit) } } +static void handleSuspendLaunchpads(CompilationUnit *cUnit) +{ + ArmLIR** suspendLabel = + (ArmLIR **) cUnit->suspendLaunchpads.elemList; + int numElems = cUnit->suspendLaunchpads.numUsed; + + for (int i = 0; i < numElems; i++) { + /* TUNING: move suspend count load into helper */ + ArmLIR* lab = suspendLabel[i]; + ArmLIR* resumeLab = (ArmLIR*)lab->operands[0]; + cUnit->currentDalvikOffset = lab->operands[1]; + oatAppendLIR(cUnit, (LIR *)lab); + loadWordDisp(cUnit, rSELF, + OFFSETOF_MEMBER(Thread, pTestSuspendFromCode), rLR); + loadWordDisp(cUnit, rSELF, + art::Thread::SuspendCountOffset().Int32Value(), rSUSPEND); + opReg(cUnit, kOpBlx, rLR); + genUnconditionalBranch(cUnit, resumeLab); + } +} + static void handleThrowLaunchpads(CompilationUnit *cUnit) { ArmLIR** throwLabel = @@ -2084,9 +2104,11 @@ void oatMethodMIR2LIR(CompilationUnit* cUnit) oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen, kPreOrderDFSTraversal, false /* Iterative */); - removeRedundantBranches(cUnit); + handleSuspendLaunchpads(cUnit); handleThrowLaunchpads(cUnit); + + removeRedundantBranches(cUnit); } /* Common initialization routine for an architecture family */ diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc index 254802d032..9321753da7 100644 --- a/src/compiler/codegen/arm/Thumb2/Factory.cc +++ b/src/compiler/codegen/arm/Thumb2/Factory.cc @@ -22,9 +22,9 @@ * */ -static int coreRegs[] = {r0, r1, r2, r3, r4, r5, r6, r7, rSELF, r8, r10, r11, - r12, rSP, rLR, rPC}; -static int reservedRegs[] = {rSELF, rSP, rLR, rPC}; +static int coreRegs[] = {r0, r1, r2, r3, rSUSPEND, r5, r6, r7, rSELF, r8, r10, + r11, r12, rSP, rLR, rPC}; +static int reservedRegs[] = {rSUSPEND, rSELF, rSP, rLR, rPC}; static int fpRegs[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7, fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15, fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23, diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index 2404ca7524..76d8b45b3f 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -1683,9 +1683,31 @@ static bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, return false; } +/* Check if we need to check for pending suspend request */ +static void genSuspendTest(CompilationUnit* cUnit, MIR* mir) +{ + if (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK) { + return; + } + newLIR2(cUnit, kThumbSubRI8, rSUSPEND, 1); + ArmLIR* branch = opCondBranch(cUnit, kArmCondEq); + ArmLIR* retLab = newLIR0(cUnit, kArmPseudoTargetLabel); + retLab->defMask = ENCODE_ALL; + ArmLIR* target = (ArmLIR*)oatNew(sizeof(ArmLIR), true); + target->generic.dalvikOffset = cUnit->currentDalvikOffset; + target->opcode = kArmPseudoSuspendTarget; + target->operands[0] = (intptr_t)retLab; + target->operands[1] = mir->offset; + branch->generic.target = (LIR*)target; + oatInsertGrowableList(&cUnit->suspendLaunchpads, (intptr_t)target); +} + /* Check for pending suspend request. */ static void genSuspendPoll(CompilationUnit* cUnit, MIR* mir) { + if (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK) { + return; + } oatLockCallTemps(cUnit); // Explicit register usage int rSuspendCount = r1; ArmLIR* ld; |