summaryrefslogtreecommitdiff
path: root/src/compiler/Frontend.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/Frontend.cc')
-rw-r--r--src/compiler/Frontend.cc125
1 files changed, 57 insertions, 68 deletions
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 6b45f0d2cd..7585b77d02 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -54,7 +54,6 @@ static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
//(1 << kDebugCountOpcodes) |
#if defined(ART_USE_QUICK_COMPILER)
//(1 << kDebugDumpBitcodeFile) |
- //(1 << kDebugVerifyBitcode) |
#endif
0;
@@ -155,8 +154,10 @@ BasicBlock *splitBlock(CompilationUnit* cUnit, unsigned int codeOffset,
}
/* Handle the fallthrough path */
+ bottomBlock->needFallThroughBranch = origBlock->needFallThroughBranch;
bottomBlock->fallThrough = origBlock->fallThrough;
origBlock->fallThrough = bottomBlock;
+ origBlock->needFallThroughBranch = true;
oatInsertGrowableList(cUnit, bottomBlock->predecessors,
(intptr_t)origBlock);
if (bottomBlock->fallThrough) {
@@ -288,12 +289,12 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
blockIdx);
if (bb == NULL) break;
if (bb->blockType == kEntryBlock) {
- fprintf(file, " entry_%d [shape=Mdiamond];\n", bb->id);
+ fprintf(file, " entry [shape=Mdiamond];\n");
} else if (bb->blockType == kExitBlock) {
- fprintf(file, " exit_%d [shape=Mdiamond];\n", bb->id);
+ fprintf(file, " exit [shape=Mdiamond];\n");
} else if (bb->blockType == kDalvikByteCode) {
- fprintf(file, " block%04x_%d [shape=record,label = \"{ \\\n",
- bb->startOffset, bb->id);
+ fprintf(file, " block%04x [shape=record,label = \"{ \\\n",
+ bb->startOffset);
const MIR *mir;
fprintf(file, " {block id %d\\l}%s\\\n", bb->id,
bb->firstMIRInsn ? " | " : " ");
@@ -326,8 +327,8 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
}
if (bb->successorBlockList.blockListType != kNotUsed) {
- fprintf(file, " succ%04x_%d [shape=%s,label = \"{ \\\n",
- bb->startOffset, bb->id,
+ fprintf(file, " succ%04x [shape=%s,label = \"{ \\\n",
+ bb->startOffset,
(bb->successorBlockList.blockListType == kCatch) ?
"Mrecord" : "record");
GrowableListIterator iterator;
@@ -355,8 +356,8 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
fprintf(file, " }\"];\n\n");
oatGetBlockName(bb, blockName1);
- fprintf(file, " %s:s -> succ%04x_%d:n [style=dashed]\n",
- blockName1, bb->startOffset, bb->id);
+ fprintf(file, " %s:s -> succ%04x:n [style=dashed]\n",
+ blockName1, bb->startOffset);
if (bb->successorBlockList.blockListType == kPackedSwitch ||
bb->successorBlockList.blockListType == kSparseSwitch) {
@@ -373,8 +374,8 @@ void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
BasicBlock *destBlock = successorBlockInfo->block;
oatGetBlockName(destBlock, blockName2);
- fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->startOffset,
- bb->id, succId++, blockName2);
+ fprintf(file, " succ%04x:f%d:e -> %s:n\n", bb->startOffset,
+ succId++, blockName2);
}
}
}
@@ -643,20 +644,18 @@ void processCanSwitch(CompilationUnit* cUnit, BasicBlock* curBlock,
}
/* Process instructions with the kThrow flag */
-BasicBlock* processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock,
- MIR* insn, int curOffset, int width, int flags,
- ArenaBitVector* tryBlockAddr, const u2* codePtr,
- const u2* codeEnd)
+void processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock, MIR* insn,
+ int curOffset, int width, int flags,
+ ArenaBitVector* tryBlockAddr, const u2* codePtr,
+ const u2* codeEnd)
{
const DexFile::CodeItem* code_item = cUnit->code_item;
- bool inTryBlock = oatIsBitSet(tryBlockAddr, curOffset);
/* In try block */
- if (inTryBlock) {
+ if (oatIsBitSet(tryBlockAddr, curOffset)) {
CatchHandlerIterator iterator(*code_item, curOffset);
if (curBlock->successorBlockList.blockListType != kNotUsed) {
- LOG(INFO) << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
LOG(FATAL) << "Successor block list already in use: "
<< (int)curBlock->successorBlockList.blockListType;
}
@@ -689,46 +688,37 @@ BasicBlock* processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock,
oatInsertGrowableList(cUnit, ehBlock->predecessors, (intptr_t)curBlock);
}
- if (insn->dalvikInsn.opcode == Instruction::THROW){
- if ((codePtr < codeEnd) && contentIsInsn(codePtr)) {
- // Force creation of new block following THROW via side-effect
- findBlock(cUnit, curOffset + width, /* split */ false,
- /* create */ true, /* immedPredBlockP */ NULL);
- }
- if (!inTryBlock) {
- // Don't split a THROW that can't rethrow - we're done.
- return curBlock;
- }
- }
-
/*
- * Split the potentially-throwing instruction into two parts.
- * The first half will be a pseudo-op that captures the exception
- * edges and terminates the basic block. It always falls through.
- * Then, create a new basic block that begins with the throwing instruction
- * (minus exceptions). Note: this new basic block must NOT be entered into
- * the blockMap. If the potentially-throwing instruction is the target of a
- * future branch, we need to find the check psuedo half. The new
- * basic block containing the work portion of the instruction should
- * only be entered via fallthrough from the block containing the
- * pseudo exception edge MIR. Note also that this new block is
- * not automatically terminated after the work portion, and may
- * contain following instructions.
+ * Force the current block to terminate.
+ *
+ * Data may be present before codeEnd, so we need to parse it to know
+ * whether it is code or data.
*/
- BasicBlock *newBlock = oatNewBB(cUnit, kDalvikByteCode, cUnit->numBlocks++);
- oatInsertGrowableList(cUnit, &cUnit->blockList, (intptr_t)newBlock);
- newBlock->startOffset = insn->offset;
- curBlock->fallThrough = newBlock;
- oatInsertGrowableList(cUnit, newBlock->predecessors, (intptr_t)curBlock);
- MIR* newInsn = (MIR*)oatNew(cUnit, sizeof(MIR), true, kAllocMIR);
- *newInsn = *insn;
- insn->dalvikInsn.opcode =
- static_cast<Instruction::Code>(kMirOpCheck);
- // Associate the two halves
- insn->meta.throwInsn = newInsn;
- newInsn->meta.throwInsn = insn;
- oatAppendMIR(newBlock, newInsn);
- return newBlock;
+ if (codePtr < codeEnd) {
+ /* Create a fallthrough block for real instructions (incl. NOP) */
+ if (contentIsInsn(codePtr)) {
+ BasicBlock *fallthroughBlock = findBlock(cUnit,
+ curOffset + width,
+ /* split */
+ false,
+ /* create */
+ true,
+ /* immedPredBlockP */
+ NULL);
+ /*
+ * THROW is an unconditional branch. NOTE:
+ * THROW_VERIFICATION_ERROR is also an unconditional
+ * branch, but we shouldn't treat it as such until we have
+ * a dead code elimination pass (which won't be important
+ * until inlining w/ constant propagation is implemented.
+ */
+ if (insn->dalvikInsn.opcode != Instruction::THROW) {
+ curBlock->fallThrough = fallthroughBlock;
+ oatInsertGrowableList(cUnit, fallthroughBlock->predecessors,
+ (intptr_t)curBlock);
+ }
+ }
+ }
}
void oatInit(CompilationUnit* cUnit, const Compiler& compiler) {
@@ -773,11 +763,15 @@ CompiledMethod* oatCompileMethod(Compiler& compiler,
cUnit->numRegs = code_item->registers_size_ - cUnit->numIns;
cUnit->numOuts = code_item->outs_size_;
#if defined(ART_USE_QUICK_COMPILER)
- DCHECK((cUnit->instructionSet == kThumb2) ||
- (cUnit->instructionSet == kX86) ||
- (cUnit->instructionSet == kMips));
- if (cUnit->instructionSet == kThumb2) {
- // TODO: remove this once x86 is tested
+ // TODO: fix bug and remove this workaround
+ std::string methodName = PrettyMethod(method_idx, dex_file);
+ if ((methodName.find("gdata2.AndroidGDataClient.createAndExecuteMethod")
+ != std::string::npos) || (methodName.find("hG.a") != std::string::npos)
+ || (methodName.find("hT.a(hV, java.lang.String, java.lang.String, java")
+ != std::string::npos) || (methodName.find("AndroidHttpTransport.exchange")
+ != std::string::npos)) {
+ LOG(INFO) << "Skipping bitcode generation for " << methodName;
+ } else {
cUnit->genBitcode = true;
}
#endif
@@ -797,17 +791,12 @@ CompiledMethod* oatCompileMethod(Compiler& compiler,
}
#if defined(ART_USE_QUICK_COMPILER)
if (cUnit->genBitcode) {
- //cUnit->enableDebug |= (1 << kDebugVerifyBitcode);
//cUnit->printMe = true;
//cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
// Disable non-safe optimizations for now
cUnit->disableOpt |= ~(1 << kSafeOptimizations);
}
#endif
- if (cUnit->instructionSet == kX86) {
- // Disable some optimizations on X86 for now
- cUnit->disableOpt |= (1 << kLoadStoreElimination);
- }
/* Are we generating code for the debugger? */
if (compiler.IsDebuggingSupported()) {
cUnit->genDebugger = true;
@@ -969,8 +958,8 @@ CompiledMethod* oatCompileMethod(Compiler& compiler,
}
}
} else if (flags & Instruction::kThrow) {
- curBlock = processCanThrow(cUnit.get(), curBlock, insn, curOffset,
- width, flags, tryBlockAddr, codePtr, codeEnd);
+ processCanThrow(cUnit.get(), curBlock, insn, curOffset, width, flags,
+ tryBlockAddr, codePtr, codeEnd);
} else if (flags & Instruction::kSwitch) {
processCanSwitch(cUnit.get(), curBlock, insn, curOffset, width, flags);
}