Revert "CFG rework for explicit exception edges"
This reverts commit 8b503db0432981c6b0b2271723f9bcf9448a554a.
Change-Id: I21d5255d827c63de6a229ef419f372fbcf4d16ed
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index af472b9..088768b 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -129,7 +129,6 @@
kDebugCountOpcodes,
#if defined(ART_USE_QUICK_COMPILER)
kDebugDumpBitcodeFile,
- kDebugVerifyBitcode,
#endif
};
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 43cfa2f..1ecf61a 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -196,10 +196,9 @@
kMirOpFusedCmpgDouble,
kMirOpFusedCmpLong,
kMirOpNop,
- kMirOpNullCheck,
- kMirOpRangeCheck,
- kMirOpDivZeroCheck,
- kMirOpCheck,
+ kMirOpNullNRangeUpCheck,
+ kMirOpNullNRangeDownCheck,
+ kMirOpLowerBound,
kMirOpLast,
};
@@ -246,10 +245,12 @@
int optimizationFlags;
int seqNum;
union {
+ // Used by the inlined insn from the callee to find the mother method
+ const Method* calleeMethod;
+ // Used by the inlined invoke to find the class and method pointers
+ CallsiteInfo* callsiteInfo;
// Used to quickly locate all Phi opcodes
MIR* phiNext;
- // Establish link between two halves of throwing instructions
- MIR* throwInsn;
} meta;
};
@@ -277,6 +278,7 @@
uint16_t nestingDepth;
const Method* containingMethod; // For blocks from the callee
BBType blockType;
+ bool needFallThroughBranch; // For blocks ended due to length limit
bool isFallThroughFromInvoke; // True means the block needs alignment
MIR* firstMIRInsn;
MIR* lastMIRInsn;
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index 99602f7..33ef0ad 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -822,16 +822,13 @@
// 107 MIR_NOP
DF_NOP,
- // 108 MIR_NULL_CHECK
+ // 108 MIR_NULL_RANGE_UP_CHECK
0,
- // 109 MIR_RANGE_CHECK
+ // 109 MIR_NULL_RANGE_DOWN_CHECK
0,
- // 110 MIR_DIV_ZERO_CHECK
- 0,
-
- // 111 MIR_CHECK
+ // 110 MIR_LOWER_BOUND
0,
};
@@ -858,29 +855,27 @@
char* oatGetDalvikDisassembly(CompilationUnit* cUnit,
const DecodedInstruction& insn, const char* note)
{
- std::string str;
- int opcode = insn.opcode;
+ char buffer[256];
+ Instruction::Code opcode = insn.opcode;
int dfAttributes = oatDataFlowAttributes[opcode];
int flags;
char* ret;
- if (opcode >= kMirOpFirst) {
- if (opcode == kMirOpPhi) {
- str.append("PHI");
- } else if (opcode == kMirOpCheck) {
- str.append("Check");
+ buffer[0] = 0;
+ if ((int)opcode >= (int)kMirOpFirst) {
+ if ((int)opcode == (int)kMirOpPhi) {
+ strcpy(buffer, "PHI");
} else {
- str.append(StringPrintf("Opcode %#x", opcode));
+ sprintf(buffer, "Opcode %#x", opcode);
}
flags = 0;
} else {
- str.append(Instruction::Name(insn.opcode));
- flags = Instruction::Flags(insn.opcode);
+ strcpy(buffer, Instruction::Name(opcode));
+ flags = Instruction::Flags(opcode);
}
- if (note) {
- str.append(note);
- }
+ if (note)
+ strcat(buffer, note);
/* For branches, decode the instructions to print out the branch targets */
if (flags & Instruction::kBranch) {
@@ -888,11 +883,11 @@
int offset = 0;
switch (dalvikFormat) {
case Instruction::k21t:
- str.append(StringPrintf(" v%d,", insn.vA));
+ snprintf(buffer + strlen(buffer), 256, " v%d,", insn.vA);
offset = (int) insn.vB;
break;
case Instruction::k22t:
- str.append(StringPrintf(" v%d, v%d,", insn.vA, insn.vB));
+ snprintf(buffer + strlen(buffer), 256, " v%d, v%d,", insn.vA, insn.vB);
offset = (int) insn.vC;
break;
case Instruction::k10t:
@@ -904,43 +899,45 @@
LOG(FATAL) << "Unexpected branch format " << (int)dalvikFormat
<< " / opcode " << (int)opcode;
}
- str.append(StringPrintf(" (%c%x)",
- offset > 0 ? '+' : '-',
- offset > 0 ? offset : -offset));
+ snprintf(buffer + strlen(buffer), 256, " (%c%x)",
+ offset > 0 ? '+' : '-',
+ offset > 0 ? offset : -offset);
} else if (dfAttributes & DF_FORMAT_35C) {
unsigned int i;
for (i = 0; i < insn.vA; i++) {
- if (i != 0) str.append(",");
- str.append(StringPrintf(" v%d", insn.arg[i]));
+ if (i != 0) strcat(buffer, ",");
+ snprintf(buffer + strlen(buffer), 256, " v%d", insn.arg[i]);
}
}
else if (dfAttributes & DF_FORMAT_3RC) {
- str.append(StringPrintf(" v%d..v%d", insn.vC, insn.vC + insn.vA - 1));
+ snprintf(buffer + strlen(buffer), 256,
+ " v%d..v%d", insn.vC, insn.vC + insn.vA - 1);
} else {
if (dfAttributes & DF_A_IS_REG) {
- str.append(StringPrintf(" v%d", insn.vA));
+ snprintf(buffer + strlen(buffer), 256, " v%d", insn.vA);
}
if (dfAttributes & DF_B_IS_REG) {
- str.append(StringPrintf(", v%d", insn.vB));
+ snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vB);
} else if ((int)opcode < (int)kMirOpFirst) {
- str.append(StringPrintf(", (#%d)", insn.vB));
+ snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vB);
}
if (dfAttributes & DF_C_IS_REG) {
- str.append(StringPrintf(", v%d", insn.vC));
+ snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vC);
} else if ((int)opcode < (int)kMirOpFirst) {
- str.append(StringPrintf(", (#%d)", insn.vC));
+ snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vC);
}
}
- int length = str.length() + 1;
+ int length = strlen(buffer) + 1;
ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
- strncpy(ret, str.c_str(), length);
+ memcpy(ret, buffer, length);
return ret;
}
-std::string getSSAName(const CompilationUnit* cUnit, int ssaReg)
+char* getSSAName(const CompilationUnit* cUnit, int ssaReg, char* name)
{
- return StringPrintf("v%d_%d", SRegToVReg(cUnit, ssaReg),
- SRegToSubscript(cUnit, ssaReg));
+ sprintf(name, "v%d_%d", SRegToVReg(cUnit, ssaReg),
+ SRegToSubscript(cUnit, ssaReg));
+ return name;
}
/*
@@ -948,38 +945,32 @@
*/
char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
{
- std::string str;
+ char buffer[256];
+ char operand0[32], operand1[32];
const DecodedInstruction* insn = &mir->dalvikInsn;
- int opcode = insn->opcode;
+ Instruction::Code opcode = insn->opcode;
int dfAttributes = oatDataFlowAttributes[opcode];
char* ret;
int length;
- if (opcode >= kMirOpFirst) {
- if (opcode == kMirOpPhi) {
- int* incoming = (int*)mir->dalvikInsn.vB;
- str.append(StringPrintf("PHI %s = (%s",
- getSSAName(cUnit, mir->ssaRep->defs[0]).c_str(),
- getSSAName(cUnit, mir->ssaRep->uses[0]).c_str()));
- str.append(StringPrintf(":%d",incoming[0]));
+ buffer[0] = 0;
+ if (static_cast<int>(opcode) >= static_cast<int>(kMirOpFirst)) {
+ if (static_cast<int>(opcode) == static_cast<int>(kMirOpPhi)) {
+ snprintf(buffer, 256, "PHI %s = (%s",
+ getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
int i;
for (i = 1; i < mir->ssaRep->numUses; i++) {
- str.append(StringPrintf(", %s:%d",
- getSSAName(cUnit, mir->ssaRep->uses[i]).c_str(),
- incoming[i]));
+ snprintf(buffer + strlen(buffer), 256, ", %s",
+ getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
}
- str.append(")");
- } else if (opcode == kMirOpCheck) {
- str.append("Check ");
- str.append(Instruction::Name(mir->meta.throwInsn->dalvikInsn.opcode));
- } else if (opcode == kMirOpNop) {
- str.append("MirNop");
+ snprintf(buffer + strlen(buffer), 256, ")");
} else {
- str.append(StringPrintf("Opcode %#x", opcode));
+ sprintf(buffer, "Opcode %#x", opcode);
}
goto done;
} else {
- str.append(Instruction::Name(insn->opcode));
+ strcpy(buffer, Instruction::Name(opcode));
}
/* For branches, decode the instructions to print out the branch targets */
@@ -988,14 +979,14 @@
int delta = 0;
switch (dalvikFormat) {
case Instruction::k21t:
- str.append(StringPrintf(" %s, ",
- getSSAName(cUnit, mir->ssaRep->uses[0]).c_str()));
+ snprintf(buffer + strlen(buffer), 256, " %s, ",
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
delta = (int) insn->vB;
break;
case Instruction::k22t:
- str.append(StringPrintf(" %s, %s, ",
- getSSAName(cUnit, mir->ssaRep->uses[0]).c_str(),
- getSSAName(cUnit, mir->ssaRep->uses[1]).c_str()));
+ snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
+ getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
delta = (int) insn->vC;
break;
case Instruction::k10t:
@@ -1006,53 +997,54 @@
default:
LOG(FATAL) << "Unexpected branch format: " << (int)dalvikFormat;
}
- str.append(StringPrintf(" %04x", mir->offset + delta));
+ snprintf(buffer + strlen(buffer), 256, " %04x",
+ mir->offset + delta);
} else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
unsigned int i;
for (i = 0; i < insn->vA; i++) {
- if (i != 0) str.append(",");
- str.append(" ");
- str.append(getSSAName(cUnit, mir->ssaRep->uses[i]));
+ if (i != 0) strcat(buffer, ",");
+ snprintf(buffer + strlen(buffer), 256, " %s",
+ getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
}
} else {
int udIdx;
if (mir->ssaRep->numDefs) {
for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
- str.append(" ");
- str.append(getSSAName(cUnit, mir->ssaRep->defs[udIdx]));
+ snprintf(buffer + strlen(buffer), 256, " %s",
+ getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
}
- str.append(",");
+ strcat(buffer, ",");
}
if (mir->ssaRep->numUses) {
/* No leading ',' for the first use */
- str.append(" ");
- str.append(getSSAName(cUnit, mir->ssaRep->uses[0]));
+ snprintf(buffer + strlen(buffer), 256, " %s",
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
- str.append(", ");
- str.append(getSSAName(cUnit, mir->ssaRep->uses[udIdx]));
+ snprintf(buffer + strlen(buffer), 256, ", %s",
+ getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
}
}
if (static_cast<int>(opcode) < static_cast<int>(kMirOpFirst)) {
- Instruction::Format dalvikFormat = Instruction::FormatOf(insn->opcode);
+ Instruction::Format dalvikFormat = Instruction::FormatOf(opcode);
switch (dalvikFormat) {
case Instruction::k11n: // op vA, #+B
case Instruction::k21s: // op vAA, #+BBBB
case Instruction::k21h: // op vAA, #+BBBB00000[00000000]
case Instruction::k31i: // op vAA, #+BBBBBBBB
case Instruction::k51l: // op vAA, #+BBBBBBBBBBBBBBBB
- str.append(StringPrintf(" #%#x", insn->vB));
+ snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
break;
case Instruction::k21c: // op vAA, thing@BBBB
case Instruction::k31c: // op vAA, thing@BBBBBBBB
- str.append(StringPrintf(" @%#x", insn->vB));
+ snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
break;
case Instruction::k22b: // op vAA, vBB, #+CC
case Instruction::k22s: // op vA, vB, #+CCCC
- str.append(StringPrintf(" #%#x", insn->vC));
+ snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
break;
case Instruction::k22c: // op vA, vB, thing@CCCC
- str.append(StringPrintf(" @%#x", insn->vC));
+ snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
break;
/* No need for special printing */
default:
@@ -1062,38 +1054,44 @@
}
done:
- length = str.length() + 1;
+ length = strlen(buffer) + 1;
ret = (char*) oatNew(cUnit, length, false, kAllocDFInfo);
- strncpy(ret, str.c_str(), length);
+ memcpy(ret, buffer, length);
return ret;
}
char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
{
- std::string str;
+ char buffer[256];
char* ret;
int i;
+ buffer[0] = 0;
for (i = 0; i < ssaRep->numDefs; i++) {
int ssaReg = ssaRep->defs[i];
- str.append(StringPrintf("s%d(v%d_%d) ", ssaReg,
- SRegToVReg(cUnit, ssaReg),
- SRegToSubscript(cUnit, ssaReg)));
+ sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ", ssaReg,
+ SRegToVReg(cUnit, ssaReg), SRegToSubscript(cUnit, ssaReg));
}
if (ssaRep->numDefs) {
- str.append("<- ");
+ strcat(buffer, "<- ");
}
for (i = 0; i < ssaRep->numUses; i++) {
+ int len = strlen(buffer);
int ssaReg = ssaRep->uses[i];
- str.append(StringPrintf("s%d(v%d_%d) ", ssaReg, SRegToVReg(cUnit, ssaReg),
- SRegToSubscript(cUnit, ssaReg)));
+
+ if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ", ssaReg,
+ SRegToVReg(cUnit, ssaReg),
+ SRegToSubscript(cUnit, ssaReg))) {
+ strcat(buffer, "...");
+ break;
+ }
}
- int length = str.length() + 1;
+ int length = strlen(buffer) + 1;
ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
- strncpy(ret, str.c_str(), length);
+ memcpy(ret, buffer, length);
return ret;
}
@@ -1185,10 +1183,8 @@
int ssaReg = cUnit->numSSARegs++;
oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, vReg);
oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, subscript);
- std::string ssaName = getSSAName(cUnit, ssaReg);
- char* name = (char*)oatNew(cUnit, ssaName.length() + 1, false, kAllocDFInfo);
- strncpy(name, ssaName.c_str(), ssaName.length() + 1);
- oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)name);
+ char* name = (char*)oatNew(cUnit, SSA_NAME_MAX, true, kAllocDFInfo);
+ oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)getSSAName(cUnit, ssaReg, name));
DCHECK_EQ(cUnit->ssaBaseVRegs->numUsed, cUnit->ssaSubscripts->numUsed);
return ssaReg;
}
@@ -1496,10 +1492,8 @@
for (i = 0; i < numDalvikReg; i++) {
oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, i);
oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, 0);
- std::string ssaName = getSSAName(cUnit, i);
- char* name = (char*)oatNew(cUnit, ssaName.length() + 1, true, kAllocDFInfo);
- strncpy(name, ssaName.c_str(), ssaName.length() + 1);
- oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)name);
+ char* name = (char*)oatNew(cUnit, SSA_NAME_MAX, true, kAllocDFInfo);
+ oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)getSSAName(cUnit, i, name));
}
/*
@@ -1693,14 +1687,14 @@
BasicBlock* tbb = bb;
mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
while (mir != NULL) {
- int opcode = mir->dalvikInsn.opcode;
if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
(mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) ||
(mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
break;
}
// Keep going if pseudo op, otherwise terminate
- if (opcode < kNumPackedOpcodes) {
+ if (mir->dalvikInsn.opcode <
+ static_cast<Instruction::Code>(kNumPackedOpcodes)) {
mir = NULL;
} else {
mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 932a39f..7585b77 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -54,7 +54,6 @@
//(1 << kDebugCountOpcodes) |
#if defined(ART_USE_QUICK_COMPILER)
//(1 << kDebugDumpBitcodeFile) |
- //(1 << kDebugVerifyBitcode) |
#endif
0;
@@ -155,8 +154,10 @@
}
/* 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 @@
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 @@
}
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 @@
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 @@
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 @@
}
/* 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 @@
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;
+ /*
+ * 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.
+ */
+ 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);
+ }
}
}
-
- /*
- * 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.
- */
- 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;
}
void oatInit(CompilationUnit* cUnit, const Compiler& compiler) {
@@ -773,11 +763,15 @@
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,7 +791,6 @@
}
#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
@@ -965,8 +958,8 @@
}
}
} 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);
}
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index f4e735a..500b1b2 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -89,6 +89,20 @@
return false;
}
+// Try to find the next move result which might have an FP target
+SSARepresentation* findFPMoveResult(MIR* mir)
+{
+ SSARepresentation* res = NULL;
+ for (; mir; mir = mir->next) {
+ if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
+ (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
+ res = mir->ssaRep;
+ break;
+ }
+ }
+ return res;
+}
+
/*
* Infer types and sizes. We don't need to track change on sizes,
* as it doesn't propagate. We're guaranteed at least one pass through
@@ -222,12 +236,14 @@
const char* shorty = oatGetShortyFromTargetIdx(cUnit, target_idx);
// Handle result type if floating point
if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
- MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
+ // Find move-result that consumes this result
+ SSARepresentation* tgtRep = findFPMoveResult(mir->next);
+ // Might be in next basic block
+ if (!tgtRep) {
+ tgtRep = findFPMoveResult(bb->fallThrough->firstMIRInsn);
+ }
// Result might not be used at all, so no move-result
- if (moveResultMIR && (moveResultMIR->dalvikInsn.opcode !=
- Instruction::MOVE_RESULT_OBJECT)) {
- SSARepresentation* tgtRep = moveResultMIR->ssaRep;
- DCHECK(tgtRep != NULL);
+ if (tgtRep) {
tgtRep->fpDef[0] = true;
changed |= setFp(cUnit, tgtRep->defs[0], true);
if (shorty[0] == 'D') {
diff --git a/src/compiler/Utility.cc b/src/compiler/Utility.cc
index c865718..571208f 100644
--- a/src/compiler/Utility.cc
+++ b/src/compiler/Utility.cc
@@ -687,20 +687,19 @@
{
switch (bb->blockType) {
case kEntryBlock:
- snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
+ snprintf(name, BLOCK_NAME_LEN, "entry");
break;
case kExitBlock:
- snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
+ snprintf(name, BLOCK_NAME_LEN, "exit");
break;
case kDalvikByteCode:
- snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->startOffset, bb->id);
+ snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset);
break;
case kExceptionHandling:
- snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->startOffset,
- bb->id);
+ snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset);
break;
default:
- snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
+ snprintf(name, BLOCK_NAME_LEN, "??");
break;
}
}
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index b2cbc69..864372a 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -51,7 +51,7 @@
llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
if (placeholder == NULL) {
// This can happen on instruction rewrite on verification failure
- LOG(WARNING) << "Null placeholder";
+ LOG(WARNING) << "Null placeholder - invalid CFG";
return;
}
placeholder->replaceAllUsesWith(val);
@@ -307,6 +307,7 @@
llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
greenland::IntrinsicHelper::Throw);
cUnit->irb->CreateCall(func, src);
+ cUnit->irb->CreateUnreachable();
}
void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
@@ -811,15 +812,6 @@
bool objectDefinition = false;
- if (cUnit->printMe) {
- if ((int)opcode < kMirOpFirst) {
- LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
- << std::hex << (int)opcode;
- } else {
- LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
- }
- }
-
/* Prep Src and Dest locations */
int nextSreg = 0;
int nextLoc = 0;
@@ -1300,24 +1292,10 @@
case Instruction::THROW:
convertThrow(cUnit, rlSrc[0]);
- /*
- * If this throw is standalone, terminate.
- * If it might rethrow, force termination
- * of the following block.
- */
- if (bb->fallThrough == NULL) {
- cUnit->irb->CreateUnreachable();
- } else {
- bb->fallThrough->fallThrough = NULL;
- bb->fallThrough->taken = NULL;
- }
break;
case Instruction::THROW_VERIFICATION_ERROR:
convertThrowVerificationError(cUnit, vA, vB);
- UNIMPLEMENTED(WARNING) << "Need dead code elimination pass"
- << " - disabling bitcode verification";
- cUnit->enableDebug &= ~(1 << kDebugVerifyBitcode);
break;
case Instruction::MOVE_RESULT_WIDE:
@@ -1328,8 +1306,7 @@
* Instruction rewriting on verification failure can eliminate
* the invoke that feeds this move0result. It won't ever be reached,
* so we can ignore it.
- * TODO: verify that previous instruction is THROW_VERIFICATION_ERROR,
- * or better, add dead-code elimination.
+ * TODO: verify that previous instruction if THROW_VERIFICATION_ERROR
*/
UNIMPLEMENTED(WARNING) << "Need to verify previous inst was rewritten";
#else
@@ -1672,13 +1649,6 @@
UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
break;
}
- case kMirOpNop:
- if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
- (bb->fallThrough == NULL)) {
- cUnit->irb->CreateUnreachable();
- }
- break;
-
#if defined(TARGET_ARM)
case kMirOpFusedCmplFloat:
UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
@@ -1750,16 +1720,6 @@
cUnit->irb->SetInsertPoint(llvmBB);
setDexOffset(cUnit, bb->startOffset);
- if (cUnit->printMe) {
- LOG(INFO) << "................................";
- LOG(INFO) << "Block id " << bb->id;
- if (llvmBB != NULL) {
- LOG(INFO) << "label " << llvmBB->getName().str().c_str();
- } else {
- LOG(INFO) << "llvmBB is NULL";
- }
- }
-
if (bb->blockType == kEntryBlock) {
setMethodInfo(cUnit);
bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
@@ -1799,6 +1759,8 @@
/*
* Because we're deferring null checking, delete the associated empty
* exception block.
+ * TODO: add new block type for exception blocks that we generate
+ * greenland code for.
*/
llvmBB->eraseFromParent();
return false;
@@ -1808,9 +1770,8 @@
setDexOffset(cUnit, mir->offset);
- int opcode = mir->dalvikInsn.opcode;
- Instruction::Format dalvikFormat =
- Instruction::FormatOf(mir->dalvikInsn.opcode);
+ Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
+ Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
/* If we're compiling for the debugger, generate an update callout */
if (cUnit->genDebugger) {
@@ -1818,43 +1779,7 @@
//genDebuggerUpdate(cUnit, mir->offset);
}
- if (opcode == kMirOpCheck) {
- // Combine check and work halves of throwing instruction.
- MIR* workHalf = mir->meta.throwInsn;
- mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
- opcode = mir->dalvikInsn.opcode;
- SSARepresentation* ssaRep = workHalf->ssaRep;
- workHalf->ssaRep = mir->ssaRep;
- mir->ssaRep = ssaRep;
- workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
- if (bb->successorBlockList.blockListType == kCatch) {
- llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
- greenland::IntrinsicHelper::CatchTargets);
- llvm::Value* switchKey =
- cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
- GrowableListIterator iter;
- oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
- // New basic block to use for work half
- llvm::BasicBlock* workBB =
- llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
- llvm::SwitchInst* sw =
- cUnit->irb->CreateSwitch(switchKey, workBB,
- bb->successorBlockList.blocks.numUsed);
- while (true) {
- SuccessorBlockInfo *successorBlockInfo =
- (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
- if (successorBlockInfo == NULL) break;
- llvm::BasicBlock *target =
- getLLVMBlock(cUnit, successorBlockInfo->block->id);
- int typeIndex = successorBlockInfo->key;
- sw->addCase(cUnit->irb->getInt32(typeIndex), target);
- }
- llvmBB = workBB;
- cUnit->irb->SetInsertPoint(llvmBB);
- }
- }
-
- if (opcode >= kMirOpFirst) {
+ if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
convertExtendedMIR(cUnit, bb, mir, llvmBB);
continue;
}
@@ -1862,9 +1787,8 @@
bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
NULL /* labelList */);
if (notHandled) {
- Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
- mir->offset, opcode,
+ mir->offset, dalvikOpcode,
Instruction::Name(dalvikOpcode),
dalvikFormat);
}
@@ -2062,14 +1986,7 @@
cUnit->irb->SetInsertPoint(cUnit->entryBB);
cUnit->irb->CreateBr(cUnit->entryTargetBB);
- if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
- if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
- LOG(INFO) << "Bitcode verification FAILED for "
- << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
- << " of size " << cUnit->insnsSize;
- cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
- }
- }
+ //llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
// Write bitcode to file
@@ -3214,24 +3131,6 @@
cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
break;
- case greenland::IntrinsicHelper::CatchTargets: {
- llvm::SwitchInst* swInst =
- llvm::dyn_cast<llvm::SwitchInst>(nextIt);
- DCHECK(swInst != NULL);
- /*
- * Discard the edges and the following conditional branch.
- * Do a direct branch to the default target (which is the
- * "work" portion of the pair.
- * TODO: awful code layout - rework
- */
- llvm::BasicBlock* targetBB = swInst->getDefaultDest();
- DCHECK(targetBB != NULL);
- opUnconditionalBranch(cUnit,
- cUnit->blockToLabelMap.Get(targetBB));
- ++it;
- }
- break;
-
default:
LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
<< cUnit->intrinsic_helper->GetName(id);
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index d32c9fb..e56e627 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -819,10 +819,9 @@
"kMirFusedCmpgDouble",
"kMirFusedCmpLong",
"kMirNop",
- "kMirOpNullCheck",
- "kMirOpRangeCheck",
- "kMirOpDivZeroCheck",
- "kMirOpCheck",
+ "kMirOpNullNRangeUpCheck",
+ "kMirOpNullNRangeDownCheck",
+ "kMirOpLowerBound",
};
/* Extended MIR instructions like PHI */
@@ -957,17 +956,7 @@
newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
}
- if ((int)dalvikOpcode == (int)kMirOpCheck) {
- // Combine check and work halves of throwing instruction.
- MIR* workHalf = mir->meta.throwInsn;
- mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
- SSARepresentation* ssaRep = workHalf->ssaRep;
- workHalf->ssaRep = mir->ssaRep;
- mir->ssaRep = ssaRep;
- workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
- }
-
- if ((int)dalvikOpcode >= (int)kMirOpFirst) {
+ if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
handleExtendedMethodMIR(cUnit, bb, mir);
continue;
}
diff --git a/src/greenland/intrinsic_func_list.def b/src/greenland/intrinsic_func_list.def
index a0f64d6..0ebebb2 100644
--- a/src/greenland/intrinsic_func_list.def
+++ b/src/greenland/intrinsic_func_list.def
@@ -66,23 +66,11 @@
// Exception
//----------------------------------------------------------------------------
-// Should not expand - introduces the catch targets for a potentially
-// throwing instruction. The result is a switch key and this
-// instruction will be followed by a switch statement. The catch
-// targets will be enumerated as cases of the switch, with the fallthrough
-// designating the block containing the potentially throwing instruction.
-// bool dex_lang_catch_targets(int dex_pc)
-_EVAL_DEF_INTRINSICS_FUNC(CatchTargets,
- dex_lang_catch_targets,
- kAttrReadOnly | kAttrNoThrow,
- kInt32Ty,
- _EXPAND_ARG1(kInt32ConstantTy))
-
// JavaObject* dex_lang_get_current_exception()
_EVAL_DEF_INTRINSICS_FUNC(GetException,
dex_lang_get_current_exception,
kAttrReadOnly | kAttrNoThrow,
- kJavaObjectTy,
+ kJavaObjectTy,
_EXPAND_ARG0())
// bool dex_lang_is_exception_pending()
@@ -1186,28 +1174,28 @@
kInt32Ty,
_EXPAND_ARG1(kInt32Ty))
-// JavaObject* const_obj(int)
+// int const_obj(int)
_EVAL_DEF_INTRINSICS_FUNC(ConstObj,
dex_lang_const_obj,
kAttrReadOnly | kAttrNoThrow,
kJavaObjectTy,
_EXPAND_ARG1(kInt32Ty))
-// long const_long(long)
+// int const_long(long)
_EVAL_DEF_INTRINSICS_FUNC(ConstLong,
dex_lang_const_long,
kAttrReadOnly | kAttrNoThrow,
kInt64Ty,
_EXPAND_ARG1(kInt64Ty))
-// float const_float(int)
+// int const_float(int)
_EVAL_DEF_INTRINSICS_FUNC(ConstFloat,
dex_lang_const_Float,
kAttrReadOnly | kAttrNoThrow,
kFloatTy,
_EXPAND_ARG1(kInt32Ty))
-// double const_double(long)
+// int const_double(long)
_EVAL_DEF_INTRINSICS_FUNC(ConstDouble,
dex_lang_const_Double,
kAttrReadOnly | kAttrNoThrow,