Compiler: GBC fix, CFG dump enhancements
Repaired some GBC generation bit rot, fixed a syntax error in
.dot cfg file generation, enhanced cfg generation to work before
SSA renaming and added new cfg dump points.
Change-Id: Id73b479209ea4d963810f67bde0ed502ed7361d3
diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc
index d896e5b..9d30b6a 100644
--- a/src/compiler/frontend.cc
+++ b/src/compiler/frontend.cc
@@ -269,7 +269,7 @@
}
/* Dump the CFG into a DOT graph */
-void DumpCFG(CompilationUnit* cu, const char* dir_prefix)
+void DumpCFG(CompilationUnit* cu, const char* dir_prefix, bool all_blocks)
{
FILE* file;
std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
@@ -284,12 +284,12 @@
fprintf(file, " rankdir=TB\n");
- int num_reachable_blocks = cu->num_reachable_blocks;
+ int num_blocks = all_blocks ? cu->num_blocks : cu->num_reachable_blocks;
int idx;
const GrowableList *block_list = &cu->block_list;
- for (idx = 0; idx < num_reachable_blocks; idx++) {
- int block_idx = cu->dfs_order.elem_list[idx];
+ for (idx = 0; idx < num_blocks; idx++) {
+ int block_idx = all_blocks ? idx : cu->dfs_order.elem_list[idx];
BasicBlock *bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(block_list, block_idx));
if (bb == NULL) break;
if (bb->block_type == kDead) continue;
@@ -304,9 +304,13 @@
fprintf(file, " {block id %d\\l}%s\\\n", bb->id,
bb->first_mir_insn ? " | " : " ");
for (mir = bb->first_mir_insn; mir; mir = mir->next) {
- fprintf(file, " {%04x %s\\l}%s\\\n", mir->offset,
+ int opcode = mir->dalvikInsn.opcode;
+ fprintf(file, " {%04x %s %s %s\\l}%s\\\n", mir->offset,
mir->ssa_rep ? GetDalvikDisassembly(cu, mir) :
- Instruction::Name(mir->dalvikInsn.opcode),
+ (opcode < kMirOpFirst) ? Instruction::Name(mir->dalvikInsn.opcode) :
+ extended_mir_op_names[opcode - kMirOpFirst],
+ (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0 ? " no_rangecheck" : " ",
+ (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0 ? " no_nullcheck" : " ",
mir->next ? " | " : " ");
}
fprintf(file, " }\"];\n\n");
@@ -386,13 +390,15 @@
}
fprintf(file, "\n");
- /* Display the dominator tree */
- GetBlockName(bb, block_name1);
- fprintf(file, " cfg%s [label=\"%s\", shape=none];\n",
- block_name1, block_name1);
- if (bb->i_dom) {
- GetBlockName(bb->i_dom, block_name2);
- fprintf(file, " cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1);
+ if (cu->verbose) {
+ /* Display the dominator tree */
+ GetBlockName(bb, block_name1);
+ fprintf(file, " cfg%s [label=\"%s\", shape=none];\n",
+ block_name1, block_name1);
+ if (bb->i_dom) {
+ GetBlockName(bb->i_dom, block_name2);
+ fprintf(file, " cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1);
+ }
}
}
fprintf(file, "}\n");
@@ -432,7 +438,7 @@
char block_name1[BLOCK_NAME_LEN], block_name2[BLOCK_NAME_LEN];
GetBlockName(bb, block_name1);
GetBlockName(pred_bb, block_name2);
- DumpCFG(cu, "/sdcard/cfg/");
+ DumpCFG(cu, "/sdcard/cfg/", false);
LOG(FATAL) << "Successor " << block_name1 << "not found from "
<< block_name2;
}
@@ -804,10 +810,6 @@
cu->gen_bitcode = true;
}
DCHECK_NE(compiler_backend, kIceland); // TODO: remove when Portable/Iceland merge complete
- // TODO: remove this once x86 is tested
- if (cu->gen_bitcode && (cu->instruction_set != kThumb2)) {
- UNIMPLEMENTED(WARNING) << "GBC generation untested for non-Thumb targets";
- }
cu->llvm_info = llvm_info;
/* Adjust this value accordingly once inlining is performed */
cu->num_dalvik_registers = code_item->registers_size_;
@@ -1025,6 +1027,10 @@
}
}
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/1_post_parse_cfg/", true);
+ }
+
if (!(cu->disable_opt & (1 << kSkipLargeMethodOptimization))) {
if ((cu->num_blocks > MANY_BLOCKS) ||
((cu->num_blocks > MANY_BLOCKS_INITIALIZER) &&
@@ -1053,6 +1059,10 @@
/* Do a code layout pass */
CodeLayout(cu.get());
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/2_post_layout_cfg/", true);
+ }
+
if (cu->enable_debug & (1 << kDebugVerifyDataflow)) {
/* Verify if all blocks are connected as claimed */
DataFlowAnalysisDispatcher(cu.get(), VerifyPredInfo, kAllNodes,
@@ -1062,6 +1072,10 @@
/* Perform SSA transformation for the whole method */
SSATransformation(cu.get());
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/3_post_ssa_cfg/", false);
+ }
+
/* Do constant propagation */
// TODO: Probably need to make these expandable to support new ssa names
// introducted during MIR optimization passes
@@ -1082,12 +1096,25 @@
/* Perform null check elimination */
NullCheckElimination(cu.get());
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/4_post_nce_cfg/", false);
+ }
+
/* Combine basic blocks where possible */
BasicBlockCombine(cu.get());
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/5_post_bbcombine_cfg/", false);
+ }
+
/* Do some basic block optimizations */
BasicBlockOptimization(cu.get());
+ // Debugging only
+ if (cu->enable_debug & (1 << kDebugDumpCFG)) {
+ DumpCFG(cu.get(), "/sdcard/6_post_bbo_cfg/", false);
+ }
+
if (cu->enable_debug & (1 << kDebugDumpCheckStats)) {
DumpCheckStats(cu.get());
}
@@ -1124,11 +1151,6 @@
}
}
- // Debugging only
- if (cu->enable_debug & (1 << kDebugDumpCFG)) {
- DumpCFG(cu.get(), "/sdcard/cfg/");
- }
-
/* Method is not empty */
if (cu->first_lir_insn) {