summaryrefslogtreecommitdiffstats
path: root/vm/compiler/Dataflow.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/compiler/Dataflow.c')
-rw-r--r--vm/compiler/Dataflow.c394
1 files changed, 338 insertions, 56 deletions
diff --git a/vm/compiler/Dataflow.c b/vm/compiler/Dataflow.c
index 82f52b931..411f456e7 100644
--- a/vm/compiler/Dataflow.c
+++ b/vm/compiler/Dataflow.c
@@ -809,7 +809,7 @@ int dvmCompilerDataFlowAttributes[kMirOpLast] = {
};
/* Return the Dalvik register/subscript pair of a given SSA register */
-int dvmConvertSSARegToDalvik(CompilationUnit *cUnit, int ssaReg)
+int dvmConvertSSARegToDalvik(const CompilationUnit *cUnit, int ssaReg)
{
return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
}
@@ -819,21 +819,58 @@ int dvmConvertSSARegToDalvik(CompilationUnit *cUnit, int ssaReg)
* and subscript pair. Each SSA register can be used to index the
* ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
*/
-char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn,
+char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
char *note)
{
char buffer[256];
int opcode = insn->opcode;
int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
+ int flags = dexGetFlagsFromOpcode(insn->opcode);
char *ret;
buffer[0] = 0;
- strcpy(buffer, dexGetOpcodeName(opcode));
+ if (opcode >= kMirOpFirst) {
+ if (opcode == kMirOpPhi) {
+ strcpy(buffer, "PHI");
+ }
+ else {
+ sprintf(buffer, "Opcode 0x%x", opcode);
+ }
+ } else {
+ strcpy(buffer, dexGetOpcodeName(opcode));
+ }
if (note)
strcat(buffer, note);
- if (dfAttributes & DF_FORMAT_35C) {
+ /* For branches, decode the instructions to print out the branch targets */
+ if (flags & kInstrCanBranch) {
+ InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
+ int offset = 0;
+ switch (dalvikFormat) {
+ case kFmt21t:
+ snprintf(buffer + strlen(buffer), 256, " v%d,", insn->vA);
+ offset = (int) insn->vB;
+ break;
+ case kFmt22t:
+ snprintf(buffer + strlen(buffer), 256, " v%d, v%d,",
+ insn->vA, insn->vB);
+ offset = (int) insn->vC;
+ break;
+ case kFmt10t:
+ case kFmt20t:
+ case kFmt30t:
+ offset = (int) insn->vA;
+ break;
+ default:
+ LOGE("Unexpected branch format: %d", dalvikFormat);
+ dvmAbort();
+ break;
+ }
+ 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) strcat(buffer, ",");
@@ -851,18 +888,153 @@ char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn,
if (dfAttributes & DF_B_IS_REG) {
snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
}
- else {
+ else if (opcode < kMirOpFirst) {
snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
}
if (dfAttributes & DF_C_IS_REG) {
snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
}
- else {
+ else if (opcode < kMirOpFirst) {
snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
}
}
int length = strlen(buffer) + 1;
- ret = dvmCompilerNew(length, false);
+ ret = (char *)dvmCompilerNew(length, false);
+ memcpy(ret, buffer, length);
+ return ret;
+}
+
+char *getSSAName(const CompilationUnit *cUnit, int ssaReg, char *name)
+{
+ int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaReg);
+
+ sprintf(name, "v%d_%d",
+ DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
+ return name;
+}
+
+/*
+ * Dalvik instruction disassembler with optional SSA printing.
+ */
+char *dvmCompilerFullDisassembler(const CompilationUnit *cUnit,
+ const MIR *mir)
+{
+ char buffer[256];
+ char operand0[256], operand1[256];
+ const DecodedInstruction *insn = &mir->dalvikInsn;
+ int opcode = insn->opcode;
+ int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
+ int flags = dexGetFlagsFromOpcode(insn->opcode);
+ char *ret;
+ int length;
+
+ buffer[0] = 0;
+ if (opcode >= kMirOpFirst) {
+ if (opcode == 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++) {
+ snprintf(buffer + strlen(buffer), 256, ", %s",
+ getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
+ }
+ snprintf(buffer + strlen(buffer), 256, ")");
+ }
+ else {
+ sprintf(buffer, "Opcode 0x%x", opcode);
+ }
+ goto done;
+ } else {
+ strcpy(buffer, dexGetOpcodeName(opcode));
+ }
+
+ /* For branches, decode the instructions to print out the branch targets */
+ if (flags & kInstrCanBranch) {
+ InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
+ int delta = 0;
+ switch (dalvikFormat) {
+ case kFmt21t:
+ snprintf(buffer + strlen(buffer), 256, " %s, ",
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
+ delta = (int) insn->vB;
+ break;
+ case kFmt22t:
+ 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 kFmt10t:
+ case kFmt20t:
+ case kFmt30t:
+ delta = (int) insn->vA;
+ break;
+ default:
+ LOGE("Unexpected branch format: %d", dalvikFormat);
+ dvmAbort();
+ break;
+ }
+ 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) 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++) {
+ snprintf(buffer + strlen(buffer), 256, " %s",
+ getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
+ }
+ strcat(buffer, ",");
+ }
+ if (mir->ssaRep->numUses) {
+ /* No leading ',' for the first use */
+ snprintf(buffer + strlen(buffer), 256, " %s",
+ getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
+ for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
+ snprintf(buffer + strlen(buffer), 256, ", %s",
+ getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
+ }
+ }
+ if (opcode < kMirOpFirst) {
+ InstructionFormat dalvikFormat = dexGetFormatFromOpcode(opcode);
+ switch (dalvikFormat) {
+ case kFmt11n: // op vA, #+B
+ case kFmt21s: // op vAA, #+BBBB
+ case kFmt21h: // op vAA, #+BBBB00000[00000000]
+ case kFmt31i: // op vAA, #+BBBBBBBB
+ case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
+ snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
+ break;
+ case kFmt21c: // op vAA, thing@BBBB
+ case kFmt31c: // op vAA, thing@BBBBBBBB
+ snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
+ break;
+ case kFmt22b: // op vAA, vBB, #+CC
+ case kFmt22s: // op vA, vB, #+CCCC
+ snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
+ break;
+ case kFmt22c: // op vA, vB, thing@CCCC
+ case kFmt22cs: // [opt] op vA, vB, field offset CCCC
+ snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
+ break;
+ /* No need for special printing */
+ default:
+ break;
+ }
+ }
+ }
+
+done:
+ length = strlen(buffer) + 1;
+ ret = (char *) dvmCompilerNew(length, false);
memcpy(ret, buffer, length);
return ret;
}
@@ -904,7 +1076,7 @@ char *dvmCompilerGetSSAString(CompilationUnit *cUnit, SSARepresentation *ssaRep)
}
int length = strlen(buffer) + 1;
- ret = dvmCompilerNew(length, false);
+ ret = (char *)dvmCompilerNew(length, false);
memcpy(ret, buffer, length);
return ret;
}
@@ -920,7 +1092,7 @@ static inline void handleLiveInUse(BitVector *useV, BitVector *defV,
}
/* Mark a reg as being defined */
-static inline void handleLiveInDef(BitVector *defV, int dalvikRegId)
+static inline void handleDef(BitVector *defV, int dalvikRegId)
{
dvmCompilerSetBit(defV, dalvikRegId);
}
@@ -929,22 +1101,19 @@ static inline void handleLiveInDef(BitVector *defV, int dalvikRegId)
* Find out live-in variables for natural loops. Variables that are live-in in
* the main loop body are considered to be defined in the entry block.
*/
-void dvmCompilerFindLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
+bool dvmCompilerFindLocalLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
{
MIR *mir;
BitVector *useV, *defV, *liveInV;
- if (bb->blockType != kDalvikByteCode &&
- bb->blockType != kTraceEntryBlock) {
- return;
- }
+ if (bb->dataFlowInfo == NULL) return false;
useV = bb->dataFlowInfo->useV =
- dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
+ dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
defV = bb->dataFlowInfo->defV =
- dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
+ dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
liveInV = bb->dataFlowInfo->liveInV =
- dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
+ dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
int dfAttributes =
@@ -972,12 +1141,13 @@ void dvmCompilerFindLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
}
}
if (dfAttributes & DF_HAS_DEFS) {
- handleLiveInDef(defV, dInsn->vA);
+ handleDef(defV, dInsn->vA);
if (dfAttributes & DF_DA_WIDE) {
- handleLiveInDef(defV, dInsn->vA+1);
+ handleDef(defV, dInsn->vA+1);
}
}
}
+ return true;
}
/* Find out the latest SSA register for a given Dalvik register */
@@ -1002,7 +1172,7 @@ static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
- dvmInsertGrowableList(cUnit->ssaToDalvikMap, (void *) newS2DMapping);
+ dvmInsertGrowableList(cUnit->ssaToDalvikMap, newS2DMapping);
defs[regIndex] = ssaReg;
}
@@ -1015,7 +1185,7 @@ static void dataFlowSSAFormat35C(CompilationUnit *cUnit, MIR *mir)
int i;
mir->ssaRep->numUses = numUses;
- mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
+ mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
for (i = 0; i < numUses; i++) {
handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
@@ -1030,7 +1200,7 @@ static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
int i;
mir->ssaRep->numUses = numUses;
- mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
+ mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
for (i = 0; i < numUses; i++) {
handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
@@ -1038,16 +1208,15 @@ static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
}
/* Entry function to convert a block into SSA representation */
-void dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
+bool dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
{
MIR *mir;
- if (bb->blockType != kDalvikByteCode && bb->blockType != kTraceEntryBlock) {
- return;
- }
+ if (bb->dataFlowInfo == NULL) return false;
for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
- mir->ssaRep = dvmCompilerNew(sizeof(SSARepresentation), true);
+ mir->ssaRep = (struct SSARepresentation *)
+ dvmCompilerNew(sizeof(SSARepresentation), true);
int dfAttributes =
dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
@@ -1084,8 +1253,10 @@ void dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
if (numUses) {
mir->ssaRep->numUses = numUses;
- mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
- mir->ssaRep->fpUse = dvmCompilerNew(sizeof(bool) * numUses, false);
+ mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses,
+ false);
+ mir->ssaRep->fpUse = (bool *)dvmCompilerNew(sizeof(bool) * numUses,
+ false);
}
int numDefs = 0;
@@ -1099,8 +1270,10 @@ void dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
if (numDefs) {
mir->ssaRep->numDefs = numDefs;
- mir->ssaRep->defs = dvmCompilerNew(sizeof(int) * numDefs, false);
- mir->ssaRep->fpDef = dvmCompilerNew(sizeof(bool) * numDefs, false);
+ mir->ssaRep->defs = (int *)dvmCompilerNew(sizeof(int) * numDefs,
+ false);
+ mir->ssaRep->fpDef = (bool *)dvmCompilerNew(sizeof(bool) * numDefs,
+ false);
}
DecodedInstruction *dInsn = &mir->dalvikInsn;
@@ -1145,12 +1318,18 @@ void dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
}
}
+ /*
+ * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
+ * input to PHI nodes can be derived from the snapshot of all predecessor
+ * blocks.
+ */
bb->dataFlowInfo->dalvikToSSAMap =
- dvmCompilerNew(sizeof(int) * cUnit->method->registersSize, false);
+ (int *)dvmCompilerNew(sizeof(int) * cUnit->method->registersSize,
+ false);
- /* Take a snapshot of Dalvik->SSA mapping at the end of each block */
memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
sizeof(int) * cUnit->method->registersSize);
+ return true;
}
/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
@@ -1160,7 +1339,7 @@ static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
cUnit->constantValues[ssaReg] = value;
}
-void dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
+bool dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
{
MIR *mir;
BitVector *isConstantV = cUnit->isConstantV;
@@ -1230,9 +1409,10 @@ void dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
}
}
/* TODO: implement code to handle arithmetic operations */
+ return true;
}
-void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
+bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
struct BasicBlock *bb)
{
BitVector *isIndVarV = cUnit->loopAnalysis->isIndVarV;
@@ -1242,13 +1422,13 @@ void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
if (bb->blockType != kDalvikByteCode &&
bb->blockType != kTraceEntryBlock) {
- return;
+ return false;
}
/* If the bb doesn't have a phi it cannot contain an induction variable */
if (bb->firstMIRInsn == NULL ||
bb->firstMIRInsn->dalvikInsn.opcode != kMirOpPhi) {
- return;
+ return false;
}
/* Find basic induction variable first */
@@ -1299,7 +1479,7 @@ void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
}
if (deltaIsConstant) {
dvmSetBit(isIndVarV, mir->ssaRep->uses[0]);
- InductionVariableInfo *ivInfo =
+ InductionVariableInfo *ivInfo = (InductionVariableInfo *)
dvmCompilerNew(sizeof(InductionVariableInfo),
false);
@@ -1308,7 +1488,7 @@ void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
ivInfo->m = 1; // always 1 to basic iv
ivInfo->c = 0; // N/A to basic iv
ivInfo->inc = deltaValue;
- dvmInsertGrowableList(ivList, (void *) ivInfo);
+ dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
cUnit->loopAnalysis->numBasicIV++;
break;
}
@@ -1372,13 +1552,13 @@ void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
if (cIsConstant) {
unsigned int i;
dvmSetBit(isIndVarV, mir->ssaRep->defs[0]);
- InductionVariableInfo *ivInfo =
+ InductionVariableInfo *ivInfo = (InductionVariableInfo *)
dvmCompilerNew(sizeof(InductionVariableInfo),
false);
InductionVariableInfo *ivInfoOld = NULL ;
for (i = 0; i < ivList->numUsed; i++) {
- ivInfoOld = ivList->elemList[i];
+ ivInfoOld = (InductionVariableInfo *) ivList->elemList[i];
if (ivInfoOld->ssaReg == mir->ssaRep->uses[0]) break;
}
@@ -1390,10 +1570,11 @@ void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
ivInfo->m = ivInfoOld->m;
ivInfo->c = c + ivInfoOld->c;
ivInfo->inc = ivInfoOld->inc;
- dvmInsertGrowableList(ivList, (void *) ivInfo);
+ dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
}
}
}
+ return true;
}
/* Setup the basic data structures for SSA conversion */
@@ -1402,7 +1583,8 @@ void dvmInitializeSSAConversion(CompilationUnit *cUnit)
int i;
int numDalvikReg = cUnit->method->registersSize;
- cUnit->ssaToDalvikMap = dvmCompilerNew(sizeof(GrowableList), false);
+ cUnit->ssaToDalvikMap = (GrowableList *)dvmCompilerNew(sizeof(GrowableList),
+ false);
dvmInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
/*
@@ -1417,8 +1599,7 @@ void dvmInitializeSSAConversion(CompilationUnit *cUnit)
* into "(0 << 16) | i"
*/
for (i = 0; i < numDalvikReg; i++) {
- dvmInsertGrowableList(cUnit->ssaToDalvikMap,
- (void *) ENCODE_REG_SUB(i, 0));
+ dvmInsertGrowableList(cUnit->ssaToDalvikMap, ENCODE_REG_SUB(i, 0));
}
/*
@@ -1426,7 +1607,8 @@ void dvmInitializeSSAConversion(CompilationUnit *cUnit)
* while the high 16 bit is the current subscript. The original Dalvik
* register N is mapped to SSA register N with subscript 0.
*/
- cUnit->dalvikToSSAMap = dvmCompilerNew(sizeof(int) * numDalvikReg, false);
+ cUnit->dalvikToSSAMap = (int *)dvmCompilerNew(sizeof(int) * numDalvikReg,
+ false);
for (i = 0; i < numDalvikReg; i++) {
cUnit->dalvikToSSAMap[i] = i;
}
@@ -1434,27 +1616,127 @@ void dvmInitializeSSAConversion(CompilationUnit *cUnit)
/*
* Allocate the BasicBlockDataFlow structure for the entry and code blocks
*/
- for (i = 0; i < cUnit->numBlocks; i++) {
- BasicBlock *bb = cUnit->blockList[i];
+ GrowableListIterator iterator;
+
+ dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
+
+ while (true) {
+ BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
+ if (bb == NULL) break;
if (bb->blockType == kDalvikByteCode ||
- bb->blockType == kTraceEntryBlock) {
- bb->dataFlowInfo = dvmCompilerNew(sizeof(BasicBlockDataFlow), true);
+ bb->blockType == kTraceEntryBlock ||
+ bb->blockType == kMethodEntryBlock ||
+ bb->blockType == kMethodExitBlock) {
+ bb->dataFlowInfo = (BasicBlockDataFlow *)
+ dvmCompilerNew(sizeof(BasicBlockDataFlow),
+ true);
}
}
}
+/* Clear the visited flag for each BB */
+bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
+ struct BasicBlock *bb)
+{
+ bb->visited = false;
+ return true;
+}
+
void dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit *cUnit,
- void (*func)(CompilationUnit *, BasicBlock *))
+ bool (*func)(CompilationUnit *, BasicBlock *),
+ DataFlowAnalysisMode dfaMode,
+ bool isIterative)
{
- int i;
- for (i = 0; i < cUnit->numBlocks; i++) {
- BasicBlock *bb = cUnit->blockList[i];
- (*func)(cUnit, bb);
+ bool change = true;
+
+ while (change) {
+ change = false;
+
+ /* Scan all blocks and perform the operations specified in func */
+ if (dfaMode == kAllNodes) {
+ GrowableListIterator iterator;
+ dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
+ while (true) {
+ BasicBlock *bb =
+ (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
+ if (bb == NULL) break;
+ change |= (*func)(cUnit, bb);
+ }
+ }
+ /*
+ * Scan all reachable blocks and perform the operations specified in
+ * func.
+ */
+ else if (dfaMode == kReachableNodes) {
+ int numReachableBlocks = cUnit->numReachableBlocks;
+ int idx;
+ const GrowableList *blockList = &cUnit->blockList;
+
+ for (idx = 0; idx < numReachableBlocks; idx++) {
+ int blockIdx = cUnit->dfsOrder.elemList[idx];
+ BasicBlock *bb =
+ (BasicBlock *) dvmGrowableListGetElement(blockList,
+ blockIdx);
+ change |= (*func)(cUnit, bb);
+ }
+ }
+ /*
+ * Scan all reachable blocks by the pre-order in the depth-first-search
+ * CFG and perform the operations specified in func.
+ */
+ else if (dfaMode == kPreOrderDFSTraversal) {
+ int numReachableBlocks = cUnit->numReachableBlocks;
+ int idx;
+ const GrowableList *blockList = &cUnit->blockList;
+
+ for (idx = 0; idx < numReachableBlocks; idx++) {
+ int dfsIdx = cUnit->dfsOrder.elemList[idx];
+ BasicBlock *bb =
+ (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
+ change |= (*func)(cUnit, bb);
+ }
+ }
+ /*
+ * Scan all reachable blocks by the post-order in the depth-first-search
+ * CFG and perform the operations specified in func.
+ */
+ else if (dfaMode == kPostOrderDFSTraversal) {
+ int numReachableBlocks = cUnit->numReachableBlocks;
+ int idx;
+ const GrowableList *blockList = &cUnit->blockList;
+
+ for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
+ int dfsIdx = cUnit->dfsOrder.elemList[idx];
+ BasicBlock *bb =
+ (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
+ change |= (*func)(cUnit, bb);
+ }
+ }
+ /*
+ * Scan all reachable blocks by the post-order in the dominator tree
+ * and perform the operations specified in func.
+ */
+ else if (dfaMode == kPostOrderDOMTraversal) {
+ int numReachableBlocks = cUnit->numReachableBlocks;
+ int idx;
+ const GrowableList *blockList = &cUnit->blockList;
+
+ for (idx = 0; idx < numReachableBlocks; idx++) {
+ int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
+ BasicBlock *bb =
+ (BasicBlock *) dvmGrowableListGetElement(blockList, domIdx);
+ change |= (*func)(cUnit, bb);
+ }
+ }
+ /* If isIterative is false, exit the loop after the first iteration */
+ change &= isIterative;
}
}
/* Main entry point to do SSA conversion for non-loop traces */
void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
{
- dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion);
+ dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion,
+ kAllNodes,
+ false /* isIterative */);
}