diff options
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/Compiler.h | 1 | ||||
| -rw-r--r-- | src/compiler/CompilerIR.h | 2 | ||||
| -rw-r--r-- | src/compiler/Frontend.cc | 46 | ||||
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 4 | ||||
| -rw-r--r-- | src/compiler/codegen/RallocUtil.cc | 16 |
5 files changed, 57 insertions, 12 deletions
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h index 68a38a5606..238e3ff42c 100644 --- a/src/compiler/Compiler.h +++ b/src/compiler/Compiler.h @@ -127,6 +127,7 @@ enum debugControlVector { kDebugVerifyDataflow, kDebugShowMemoryUsage, kDebugShowNops, + kDebugCountOpcodes, }; extern uint32_t compilerDebugFlags; diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h index b512c5b8e1..184d4db40e 100644 --- a/src/compiler/CompilerIR.h +++ b/src/compiler/CompilerIR.h @@ -320,6 +320,7 @@ struct CompilationUnit { bool hasLoop; // Contains a loop bool hasInvoke; // Contains an invoke instruction bool heapMemOp; // Mark mem ops for self verification + bool qdMode; // Compile for code size/compile time bool usesLinkRegister; // For self-verification only bool methodTraceSupport; // For TraceView profiling struct RegisterPool* regPool; @@ -425,6 +426,7 @@ struct CompilationUnit { struct ArenaMemBlock* currentArena; int numArenaBlocks; struct Memstats* mstats; + int* opcodeCount; // Count Dalvik opcodes for tuning #ifndef NDEBUG /* * Sanity checking for the register temp tracking. The same ssa diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc index cca891d20b..3e0fd3a00e 100644 --- a/src/compiler/Frontend.cc +++ b/src/compiler/Frontend.cc @@ -51,6 +51,7 @@ uint32_t compilerDebugFlags = 0 | // Enable debug/testing modes //(1 << kDebugVerifyDataflow) | //(1 << kDebugShowMemoryUsage) | //(1 << kDebugShowNops) | + //(1 << kDebugCountOpcodes) | 0; inline bool contentIsInsn(const u2* codePtr) { @@ -803,6 +804,12 @@ CompiledMethod* oatCompileMethod(Compiler& compiler, (1 << kTrackLiveTemps)); } + /* Gathering opcode stats? */ + if (compilerDebugFlags & (1 << kDebugCountOpcodes)) { + cUnit->opcodeCount = (int*)oatNew(cUnit.get(), + kNumPackedOpcodes * sizeof(int), true, kAllocMisc); + } + /* Assume non-throwing leaf */ cUnit->attrs = (METHOD_IS_LEAF | METHOD_IS_THROW_FREE); @@ -867,6 +874,9 @@ CompiledMethod* oatCompileMethod(Compiler& compiler, insn->offset = curOffset; int width = parseInsn(cUnit.get(), codePtr, &insn->dalvikInsn, false); insn->width = width; + if (cUnit->opcodeCount != NULL) { + cUnit->opcodeCount[static_cast<int>(insn->dalvikInsn.opcode)]++; + } /* Terminate when the data section is seen */ if (width == 0) @@ -948,16 +958,21 @@ CompiledMethod* oatCompileMethod(Compiler& compiler, ((cUnit->numBlocks > MANY_BLOCKS_INITIALIZER) && PrettyMethod(method_idx, dex_file).find("init>") != std::string::npos)) { - cUnit->disableDataflow = true; - // Disable optimization which require dataflow/ssa - cUnit->disableOpt |= - (1 << kNullCheckElimination) | - (1 << kBBOpt) | - (1 << kPromoteRegs); - if (cUnit->printMe) { - LOG(INFO) << "Compiler: " << PrettyMethod(method_idx, dex_file) - << " too big: " << cUnit->numBlocks; - } + cUnit->qdMode = true; + } + } + + if (cUnit->qdMode) { + cUnit->disableDataflow = true; + // Disable optimization which require dataflow/ssa + cUnit->disableOpt |= + (1 << kNullCheckElimination) | + (1 << kBBOpt) | + (1 << kPromoteRegs); + if (cUnit->printMe) { + LOG(INFO) << "QD mode enabled: " + << PrettyMethod(method_idx, dex_file) + << " too big: " << cUnit->numBlocks; } } @@ -1011,6 +1026,17 @@ CompiledMethod* oatCompileMethod(Compiler& compiler, if (cUnit->printMe) { oatCodegenDump(cUnit.get()); } + + if (cUnit->opcodeCount != NULL) { + LOG(INFO) << "Opcode Count"; + for (int i = 0; i < kNumPackedOpcodes; i++) { + if (cUnit->opcodeCount[i] != 0) { + LOG(INFO) << "-C- " + <<Instruction::Name(static_cast<Instruction::Code>(i)) + << " " << cUnit->opcodeCount[i]; + } + } + } } // Combine vmap tables - core regs, then fp regs - into vmapTable diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index 52ff3d79a1..cc0d624099 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -1049,6 +1049,9 @@ void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, RegLocation rlSrc, if (isVolatile) { oatGenMemBarrier(cUnit, kSY); } + if (isObject) { + markGCCard(cUnit, rlSrc.lowReg, rlObj.lowReg); + } } } else { int setterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pSet64Instance) : @@ -1434,6 +1437,7 @@ void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray, } storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg, scale, kWord); + markGCCard(cUnit, rlSrc.lowReg, rlArray.lowReg); } /* diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc index ffff7d231c..b3fa739d0e 100644 --- a/src/compiler/codegen/RallocUtil.cc +++ b/src/compiler/codegen/RallocUtil.cc @@ -1100,6 +1100,7 @@ extern void oatDoPromotion(CompilationUnit* cUnit) int regBias = cUnit->numCompilerTemps + 1; int dalvikRegs = cUnit->numDalvikRegisters; int numRegs = dalvikRegs + regBias; + const int promotionThreshold = 2; // Allow target code to add any special registers oatAdjustSpillMask(cUnit); @@ -1164,7 +1165,8 @@ extern void oatDoPromotion(CompilationUnit* cUnit) if (!(cUnit->disableOpt & (1 << kPromoteRegs))) { // Promote fpRegs - for (int i = 0; (i < numRegs) && (fpRegs[i].count > 0); i++) { + for (int i = 0; (i < numRegs) && + (fpRegs[i].count >= promotionThreshold ); i++) { int pMapIdx = SRegToPMap(cUnit, fpRegs[i].sReg); if (cUnit->promotionMap[pMapIdx].fpLocation != kLocPhysReg) { int reg = oatAllocPreservedFPReg(cUnit, fpRegs[i].sReg, @@ -1176,7 +1178,8 @@ extern void oatDoPromotion(CompilationUnit* cUnit) } // Promote core regs - for (int i = 0; (i < numRegs) && (coreRegs[i].count > 0); i++) { + for (int i = 0; (i < numRegs) && + (coreRegs[i].count > promotionThreshold); i++) { int pMapIdx = SRegToPMap(cUnit, coreRegs[i].sReg); if (cUnit->promotionMap[pMapIdx].coreLocation != kLocPhysReg) { @@ -1186,8 +1189,17 @@ extern void oatDoPromotion(CompilationUnit* cUnit) } } } + } else if (cUnit->qdMode) { + oatAllocPreservedCoreReg(cUnit, cUnit->methodSReg); + for (int i = 0; i < numRegs; i++) { + int reg = oatAllocPreservedCoreReg(cUnit, i); + if (reg < 0) { + break; // No more left + } + } } + // Now, update SSA names to new home locations for (int i = 0; i < cUnit->numSSARegs; i++) { RegLocation *curr = &cUnit->regLocation[i]; |