diff options
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/CompilerIR.h | 3 | ||||
| -rw-r--r-- | src/compiler/Dataflow.cc | 4 | ||||
| -rw-r--r-- | src/compiler/Frontend.cc | 3 | ||||
| -rw-r--r-- | src/compiler/SSATransformation.cc | 8 | ||||
| -rw-r--r-- | src/compiler/Utility.cc | 10 | ||||
| -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 | 40 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Factory.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 22 |
10 files changed, 86 insertions, 20 deletions
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h index b6972920d3..0965c14218 100644 --- a/src/compiler/CompilerIR.h +++ b/src/compiler/CompilerIR.h @@ -87,6 +87,7 @@ typedef enum { kMIRInlined, // Invoke is inlined (ie dead) kMIRInlinedPred, // Invoke is inlined via prediction kMIRCallee, // Instruction is inlined from callee + kMIRIgnoreSuspendCheck, } MIROptimizationFlagPositons; #define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck) @@ -96,6 +97,7 @@ typedef enum { #define MIR_INLINED (1 << kMIRInlined) #define MIR_INLINED_PRED (1 << kMIRInlinedPred) #define MIR_CALLEE (1 << kMIRCallee) +#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck) typedef struct CallsiteInfo { const char* classDescriptor; @@ -239,6 +241,7 @@ typedef struct CompilationUnit { GrowableList dfsOrder; GrowableList domPostOrderTraversal; GrowableList throwLaunchpads; + GrowableList suspendLaunchpads; ArenaBitVector* tryBlockAddr; ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks ArenaBitVector* tempBlockV; diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc index 827470e2e4..d4b5339e0b 100644 --- a/src/compiler/Dataflow.cc +++ b/src/compiler/Dataflow.cc @@ -2405,6 +2405,10 @@ static bool eliminateNullChecks( struct CompilationUnit* cUnit, if (predBBIdx == -1) break; predBB = (BasicBlock*)oatGrowableListGetElement( blockList, predBBIdx); + if ((predBB->dataFlowInfo == NULL) || + (predBB->dataFlowInfo->endingNullCheckV == NULL)) { + continue; + } oatIntersectBitVectors(cUnit->tempSSARegisterV, cUnit->tempSSARegisterV, predBB->dataFlowInfo->endingNullCheckV); diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc index fdcce9cd46..6a01e36481 100644 --- a/src/compiler/Frontend.cc +++ b/src/compiler/Frontend.cc @@ -725,6 +725,9 @@ bool oatCompileMethod(const Compiler& compiler, Method* method, art::Instruction /* Intialize the throwLaunchpads list */ oatInitGrowableList(&cUnit.throwLaunchpads, 4); + /* Intialize the suspendLaunchpads list */ + oatInitGrowableList(&cUnit.suspendLaunchpads, 4); + /* Allocate the bit-vector to track the beginning of basic blocks */ ArenaBitVector *tryBlockAddr = oatAllocBitVector(cUnit.insnsSize, true /* expandable */); diff --git a/src/compiler/SSATransformation.cc b/src/compiler/SSATransformation.cc index dea197112a..1a488bb1fd 100644 --- a/src/compiler/SSATransformation.cc +++ b/src/compiler/SSATransformation.cc @@ -247,7 +247,9 @@ static bool computeBlockDominators(CompilationUnit* cUnit, BasicBlock* bb) BasicBlock* predBB = (BasicBlock* ) oatGrowableListGetElement( blockList, predIdx); /* tempBlockV = tempBlockV ^ dominators */ - oatIntersectBitVectors(tempBlockV, tempBlockV, predBB->dominators); + if (predBB->dominators != NULL) { + oatIntersectBitVectors(tempBlockV, tempBlockV, predBB->dominators); + } } oatSetBit(tempBlockV, bb->id); if (oatCompareBitVectors(tempBlockV, bb->dominators)) { @@ -452,7 +454,9 @@ static void insertPhiNodes(CompilationUnit* cUnit) (BasicBlock* ) oatGrowableListGetElement(blockList, idx); /* Merge the dominance frontier to tmpBlocks */ - oatUnifyBitVectors(tmpBlocks, tmpBlocks, defBB->domFrontier); + if (defBB->domFrontier != NULL) { + oatUnifyBitVectors(tmpBlocks, tmpBlocks, defBB->domFrontier); + } } if (oatCompareBitVectors(phiBlocks, tmpBlocks)) { change = true; diff --git a/src/compiler/Utility.cc b/src/compiler/Utility.cc index 7d3a887d98..7b99966759 100644 --- a/src/compiler/Utility.cc +++ b/src/compiler/Utility.cc @@ -373,8 +373,9 @@ void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src) bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1, const ArenaBitVector* src2) { - if (src2 == NULL || - dest->storageSize != src1->storageSize || + DCHECK(src1 != NULL); + DCHECK(src2 != NULL); + if (dest->storageSize != src1->storageSize || dest->storageSize != src2->storageSize || dest->expandable != src1->expandable || dest->expandable != src2->expandable) @@ -393,8 +394,9 @@ bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1, bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1, const ArenaBitVector* src2) { - if (src2 == NULL || - dest->storageSize != src1->storageSize || + DCHECK(src1 != NULL); + DCHECK(src2 != NULL); + if (dest->storageSize != src1->storageSize || dest->storageSize != src2->storageSize || dest->expandable != src1->expandable || dest->expandable != src2->expandable) 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 8dc388c7e3..41053a2def 100644 --- a/src/compiler/codegen/arm/MethodCodegenDriver.cc +++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc @@ -849,6 +849,8 @@ static int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir, loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pMemcpy), rLR); loadConstant(cUnit, r2, (numArgs - 3) * 4); callNoUnwindHelper(cUnit, rLR); + // Restore Method* + loadCurrMethodDirect(cUnit, r0); } else { // Use vldm/vstm pair using r3 as a temp int regsLeft = std::min(numArgs - 3, 16); @@ -1111,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]); @@ -1275,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; @@ -1313,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); @@ -1356,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); @@ -1997,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 = @@ -2082,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; |