diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler/codegen/gen_loadstore.cc | 19 | ||||
| -rw-r--r-- | src/compiler/codegen/mir_to_gbc.cc | 9 | ||||
| -rw-r--r-- | src/compiler/compiler_utility.cc | 2 | ||||
| -rw-r--r-- | src/compiler/dataflow.cc | 9 | ||||
| -rw-r--r-- | src/compiler/frontend.cc | 68 |
5 files changed, 69 insertions, 38 deletions
diff --git a/src/compiler/codegen/gen_loadstore.cc b/src/compiler/codegen/gen_loadstore.cc index eec74af2da..6c16d40849 100644 --- a/src/compiler/codegen/gen_loadstore.cc +++ b/src/compiler/codegen/gen_loadstore.cc @@ -46,15 +46,18 @@ void Codegen::Workaround7250540(CompilationUnit* cu, RegLocation rl_dest, int ze int pmap_index = SRegToPMap(cu, rl_dest.s_reg_low); if (cu->promotion_map[pmap_index].fp_location == kLocPhysReg) { // Now, determine if this vreg is ever used as a reference. If not, we're done. - bool used_as_reference = false; - int base_vreg = SRegToVReg(cu, rl_dest.s_reg_low); - for (int i = 0; !used_as_reference && (i < cu->num_ssa_regs); i++) { - if (SRegToVReg(cu, cu->reg_location[i].s_reg_low) == base_vreg) { - used_as_reference |= cu->reg_location[i].ref; + if (!cu->gen_bitcode) { + // TUNING: We no longer have this info for QuickGBC - assume the worst + bool used_as_reference = false; + int base_vreg = SRegToVReg(cu, rl_dest.s_reg_low); + for (int i = 0; !used_as_reference && (i < cu->num_ssa_regs); i++) { + if (SRegToVReg(cu, cu->reg_location[i].s_reg_low) == base_vreg) { + used_as_reference |= cu->reg_location[i].ref; + } + } + if (!used_as_reference) { + return; } - } - if (!used_as_reference) { - return; } if (cu->promotion_map[pmap_index].core_location == kLocPhysReg) { // Promoted - just copy in a zero diff --git a/src/compiler/codegen/mir_to_gbc.cc b/src/compiler/codegen/mir_to_gbc.cc index 6758bb9f69..e1e1fb16a5 100644 --- a/src/compiler/codegen/mir_to_gbc.cc +++ b/src/compiler/codegen/mir_to_gbc.cc @@ -1643,6 +1643,9 @@ static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir, if (rl_dest.high_word) { return; // No Phi node - handled via low word } + // LLVM requires that all Phi nodes are at the beginning of the block + llvm::IRBuilderBase::InsertPoint ip = cu->irb->saveAndClearIP(); + cu->irb->SetInsertPoint(llvm_bb); int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB); llvm::Type* phi_type = LlvmTypeFromLocRec(cu, rl_dest); @@ -1662,6 +1665,8 @@ static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir, phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg), GetLLVMBlock(cu, it->second)); } + // Now that Phi node is emitted, add definition at old insert point + cu->irb->restoreIP(ip); DefineValue(cu, phi, rl_dest.orig_sreg); break; } @@ -1789,9 +1794,7 @@ static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb) greenland::IntrinsicHelper::AllocaShadowFrame; llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id); llvm::Value* entries = cu->irb->getInt32(cu->num_shadow_frame_entries); - llvm::Value* dalvik_regs = cu->irb->getInt32(cu->num_dalvik_registers); - llvm::Value* args[] = { entries, dalvik_regs }; - cu->irb->CreateCall(func, args); + cu->irb->CreateCall(func, entries); } else if (bb->block_type == kExitBlock) { /* * Because of the differences between how MIR/LIR and llvm handle exit diff --git a/src/compiler/compiler_utility.cc b/src/compiler/compiler_utility.cc index 2e67902e34..0bce17c03c 100644 --- a/src/compiler/compiler_utility.cc +++ b/src/compiler/compiler_utility.cc @@ -674,7 +674,7 @@ void GetBlockName(BasicBlock* bb, char* name) bb->id); break; default: - snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id); + snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id); break; } } diff --git a/src/compiler/dataflow.cc b/src/compiler/dataflow.cc index 22135b1990..03ede70453 100644 --- a/src/compiler/dataflow.cc +++ b/src/compiler/dataflow.cc @@ -862,6 +862,10 @@ static std::string GetSSAName(const CompilationUnit* cu, int ssa_reg) // Similar to GetSSAName, but if ssa name represents an immediate show that as well. static std::string GetSSANameWithConst(const CompilationUnit* cu, int ssa_reg, bool singles_only) { + if (cu->reg_location == NULL) { + // Pre-SSA - just use the Dalvik vreg + return StringPrintf("v%d", ssa_reg); + } if (cu->reg_location[ssa_reg].is_const) { if (!singles_only && cu->reg_location[ssa_reg].wide) { int64_t immval = cu->constant_values[ssa_reg + 1]; @@ -940,8 +944,7 @@ char* GetDalvikDisassembly(CompilationUnit* cu, const MIR* mir) break; case Instruction::k22t: str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(cu, ssa_rep->uses[0], false).c_str(), - GetSSANameWithConst(cu, ssa_rep->uses[cu->reg_location[ssa_rep->uses[0]].wide - ? 2 : 1], false).c_str())); + GetSSANameWithConst(cu, ssa_rep->uses[1], false).c_str())); offset = insn.vC; break; case Instruction::k10t: @@ -967,7 +970,7 @@ char* GetDalvikDisassembly(CompilationUnit* cu, const MIR* mir) for (int i = 0; i < uses; i++) { str.append( StringPrintf(" %s", GetSSANameWithConst(cu, ssa_rep->uses[i], show_singles).c_str())); - if (!show_singles && cu->reg_location[i].wide) { + if (!show_singles && (cu->reg_location != NULL) && cu->reg_location[i].wide) { // For the listing, skip the high sreg. i++; } diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc index d896e5b621..9d30b6ad0b 100644 --- a/src/compiler/frontend.cc +++ b/src/compiler/frontend.cc @@ -269,7 +269,7 @@ void ReplaceSpecialChars(std::string& str) } /* 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 @@ void DumpCFG(CompilationUnit* cu, const char* dir_prefix) 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 @@ void DumpCFG(CompilationUnit* cu, const char* dir_prefix) 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 @@ void DumpCFG(CompilationUnit* cu, const char* dir_prefix) } 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 @@ static bool VerifyPredInfo(CompilationUnit* cu, BasicBlock* bb) 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, } } + 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, /* 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, /* 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, /* 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 @@ static CompiledMethod* CompileMethod(Compiler& compiler, } } - // Debugging only - if (cu->enable_debug & (1 << kDebugDumpCFG)) { - DumpCFG(cu.get(), "/sdcard/cfg/"); - } - /* Method is not empty */ if (cu->first_lir_insn) { |