Compiler: LIR restructuring
Continuing restructuring of the compiler. In this installment,
all LIR reverences are moved from compiler_ir down to quick. Further,
all Portable data is moved to from compiler_ir down to portable.
In short, the great dumping ground of CompilationUnit has been
split into three smaller dumping grounds of MIRGraph, Codegen
and MIRConverter. From here, subsequent CLs will repartition
those smaller dumping grounds into (hopefully) more coherent classes.
As a result, most function signatures have been altered to remove
the passing around of a CompilationUnit* pointer.
Change-Id: I7195f7baecd81e87786a952e18bbce0b6ceeaac4
diff --git a/src/compiler/dex/compiler_utility.cc b/src/compiler/dex/compiler_utility.cc
index 82a156d..71c9713 100644
--- a/src/compiler/dex/compiler_utility.cc
+++ b/src/compiler/dex/compiler_utility.cc
@@ -19,23 +19,6 @@
namespace art {
-const char* extended_mir_op_names[kMirOpLast - kMirOpFirst] = {
- "Phi",
- "Copy",
- "FusedCmplFloat",
- "FusedCmpgFloat",
- "FusedCmplDouble",
- "FusedCmpgDouble",
- "FusedCmpLong",
- "Nop",
- "OpNullCheck",
- "OpRangeCheck",
- "OpDivZeroCheck",
- "Check1",
- "Check2",
- "Select",
-};
-
#ifdef WITH_MEMSTATS
struct Memstats {
uint32_t alloc_stats[kNumAllocKinds];
@@ -301,9 +284,6 @@
LOG(INFO) << "MEMUSAGE: " << total << " : "
<< PrettyMethod(cu->method_idx, *cu->dex_file);
LOG(INFO) << "insns_size: " << cu->code_item->insns_size_in_code_units_;
- if (cu->disable_dataflow) {
- LOG(INFO) << " ** Dataflow disabled ** ";
- }
LOG(INFO) << "===== Overall allocations";
for (int i = 0; i < kNumAllocKinds; i++) {
LOG(INFO) << alloc_names[i] << std::setw(10) <<
@@ -328,43 +308,6 @@
}
#endif
-/* Debug Utility - dump a compilation unit */
-void DumpCompilationUnit(CompilationUnit* cu)
-{
- BasicBlock* bb;
- const char* block_type_names[] = {
- "Entry Block",
- "Code Block",
- "Exit Block",
- "Exception Handling",
- "Catch Block"
- };
-
- LOG(INFO) << "Compiling " << PrettyMethod(cu->method_idx, *cu->dex_file);
- LOG(INFO) << cu->insns << " insns";
- LOG(INFO) << cu->mir_graph->GetNumBlocks() << " blocks in total";
- GrowableListIterator iterator = cu->mir_graph->GetBasicBlockIterator();
-
- while (true) {
- bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
- if (bb == NULL) break;
- LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
- bb->id,
- block_type_names[bb->block_type],
- bb->start_offset,
- bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
- bb->last_mir_insn ? "" : " empty");
- if (bb->taken) {
- LOG(INFO) << " Taken branch: block " << bb->taken->id
- << "(0x" << std::hex << bb->taken->start_offset << ")";
- }
- if (bb->fall_through) {
- LOG(INFO) << " Fallthrough : block " << bb->fall_through->id
- << " (0x" << std::hex << bb->fall_through->start_offset << ")";
- }
- }
-}
-
static uint32_t check_masks[32] = {
0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
@@ -669,34 +612,6 @@
}
}
-void GetBlockName(BasicBlock* bb, char* name)
-{
- switch (bb->block_type) {
- case kEntryBlock:
- snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
- break;
- case kExitBlock:
- snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
- break;
- case kDalvikByteCode:
- snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
- break;
- case kExceptionHandling:
- snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
- bb->id);
- break;
- default:
- snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id);
- break;
- }
-}
-
-const char* GetShortyFromTargetIdx(CompilationUnit *cu, int target_idx)
-{
- const DexFile::MethodId& method_id = cu->dex_file->GetMethodId(target_idx);
- return cu->dex_file->GetShorty(method_id.proto_idx_);
-}
-
/* Allocate a new basic block */
BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
{
@@ -708,270 +623,8 @@
CompilerInitGrowableList(cu, bb->predecessors,
(block_type == kExitBlock) ? 2048 : 2,
kListPredecessors);
- cu->block_id_map.Put(block_id, block_id);
+ cu->mir_graph->block_id_map_.Put(block_id, block_id);
return bb;
}
-/* Insert an MIR instruction to the end of a basic block */
-void AppendMIR(BasicBlock* bb, MIR* mir)
-{
- if (bb->first_mir_insn == NULL) {
- DCHECK(bb->last_mir_insn == NULL);
- bb->last_mir_insn = bb->first_mir_insn = mir;
- mir->prev = mir->next = NULL;
- } else {
- bb->last_mir_insn->next = mir;
- mir->prev = bb->last_mir_insn;
- mir->next = NULL;
- bb->last_mir_insn = mir;
- }
-}
-
-/* Insert an MIR instruction to the head of a basic block */
-void PrependMIR(BasicBlock* bb, MIR* mir)
-{
- if (bb->first_mir_insn == NULL) {
- DCHECK(bb->last_mir_insn == NULL);
- bb->last_mir_insn = bb->first_mir_insn = mir;
- mir->prev = mir->next = NULL;
- } else {
- bb->first_mir_insn->prev = mir;
- mir->next = bb->first_mir_insn;
- mir->prev = NULL;
- bb->first_mir_insn = mir;
- }
-}
-
-/* Insert a MIR instruction after the specified MIR */
-void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir)
-{
- new_mir->prev = current_mir;
- new_mir->next = current_mir->next;
- current_mir->next = new_mir;
-
- if (new_mir->next) {
- /* Is not the last MIR in the block */
- new_mir->next->prev = new_mir;
- } else {
- /* Is the last MIR in the block */
- bb->last_mir_insn = new_mir;
- }
-}
-
-/*
- * Append an LIR instruction to the LIR list maintained by a compilation
- * unit
- */
-void AppendLIR(CompilationUnit *cu, LIR* lir)
-{
- if (cu->first_lir_insn == NULL) {
- DCHECK(cu->last_lir_insn == NULL);
- cu->last_lir_insn = cu->first_lir_insn = lir;
- lir->prev = lir->next = NULL;
- } else {
- cu->last_lir_insn->next = lir;
- lir->prev = cu->last_lir_insn;
- lir->next = NULL;
- cu->last_lir_insn = lir;
- }
-}
-
-/*
- * Insert an LIR instruction before the current instruction, which cannot be the
- * first instruction.
- *
- * prev_lir <-> new_lir <-> current_lir
- */
-void InsertLIRBefore(LIR* current_lir, LIR* new_lir)
-{
- DCHECK(current_lir->prev != NULL);
- LIR *prev_lir = current_lir->prev;
-
- prev_lir->next = new_lir;
- new_lir->prev = prev_lir;
- new_lir->next = current_lir;
- current_lir->prev = new_lir;
-}
-
-/*
- * Insert an LIR instruction after the current instruction, which cannot be the
- * first instruction.
- *
- * current_lir -> new_lir -> old_next
- */
-void InsertLIRAfter(LIR* current_lir, LIR* new_lir)
-{
- new_lir->prev = current_lir;
- new_lir->next = current_lir->next;
- current_lir->next = new_lir;
- new_lir->next->prev = new_lir;
-}
-
-/* Turn method name into a legal Linux file name */
-void ReplaceSpecialChars(std::string& str)
-{
- static const struct { const char before; const char after; } match[] =
- {{'/','-'}, {';','#'}, {' ','#'}, {'$','+'},
- {'(','@'}, {')','@'}, {'<','='}, {'>','='}};
- for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
- std::replace(str.begin(), str.end(), match[i].before, match[i].after);
- }
-}
-
-std::string GetSSAName(const CompilationUnit* cu, int ssa_reg)
-{
- return StringPrintf("v%d_%d", cu->mir_graph->SRegToVReg(ssa_reg), cu->mir_graph->GetSSASubscript(ssa_reg));
-}
-
-// Similar to GetSSAName, but if ssa name represents an immediate show that as well.
-std::string GetSSANameWithConst(const CompilationUnit* cu, int ssa_reg, bool singles_only)
-{
- if (cu->reg_location == NULL) {
- // Pre-SSA - just use the standard name
- return GetSSAName(cu, ssa_reg);
- }
- if (cu->mir_graph->IsConst(cu->reg_location[ssa_reg])) {
- if (!singles_only && cu->reg_location[ssa_reg].wide) {
- return StringPrintf("v%d_%d#0x%llx", cu->mir_graph->SRegToVReg(ssa_reg),
- cu->mir_graph->GetSSASubscript(ssa_reg),
- cu->mir_graph->ConstantValueWide(cu->reg_location[ssa_reg]));
- } else {
- return StringPrintf("v%d_%d#0x%x", cu->mir_graph->SRegToVReg(ssa_reg),
- cu->mir_graph->GetSSASubscript(ssa_reg),
- cu->mir_graph->ConstantValue(cu->reg_location[ssa_reg]));
- }
- } else {
- return StringPrintf("v%d_%d", cu->mir_graph->SRegToVReg(ssa_reg),
- cu->mir_graph->GetSSASubscript(ssa_reg));
- }
-}
-
-char* GetDalvikDisassembly(CompilationUnit* cu, const MIR* mir)
-{
- DecodedInstruction insn = mir->dalvikInsn;
- std::string str;
- int flags = 0;
- int opcode = insn.opcode;
- char* ret;
- bool nop = false;
- SSARepresentation* ssa_rep = mir->ssa_rep;
- Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format
- int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
- int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
-
- // Handle special cases.
- if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
- str.append(extended_mir_op_names[opcode - kMirOpFirst]);
- str.append(": ");
- // Recover the original Dex instruction
- insn = mir->meta.throw_insn->dalvikInsn;
- ssa_rep = mir->meta.throw_insn->ssa_rep;
- defs = ssa_rep->num_defs;
- uses = ssa_rep->num_uses;
- opcode = insn.opcode;
- } else if (opcode == kMirOpNop) {
- str.append("[");
- insn.opcode = mir->meta.original_opcode;
- opcode = mir->meta.original_opcode;
- nop = true;
- }
-
- if (opcode >= kMirOpFirst) {
- str.append(extended_mir_op_names[opcode - kMirOpFirst]);
- } else {
- dalvik_format = Instruction::FormatOf(insn.opcode);
- flags = Instruction::FlagsOf(insn.opcode);
- str.append(Instruction::Name(insn.opcode));
- }
-
- if (opcode == kMirOpPhi) {
- int* incoming = reinterpret_cast<int*>(insn.vB);
- str.append(StringPrintf(" %s = (%s",
- GetSSANameWithConst(cu, ssa_rep->defs[0], true).c_str(),
- GetSSANameWithConst(cu, ssa_rep->uses[0], true).c_str()));
- str.append(StringPrintf(":%d",incoming[0]));
- int i;
- for (i = 1; i < uses; i++) {
- str.append(StringPrintf(", %s:%d",
- GetSSANameWithConst(cu, ssa_rep->uses[i], true).c_str(),
- incoming[i]));
- }
- str.append(")");
- } else if ((flags & Instruction::kBranch) != 0) {
- // For branches, decode the instructions to print out the branch targets.
- int offset = 0;
- switch (dalvik_format) {
- case Instruction::k21t:
- str.append(StringPrintf(" %s,", GetSSANameWithConst(cu, ssa_rep->uses[0], false).c_str()));
- offset = insn.vB;
- break;
- case Instruction::k22t:
- str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(cu, ssa_rep->uses[0], false).c_str(),
- GetSSANameWithConst(cu, ssa_rep->uses[1], false).c_str()));
- offset = insn.vC;
- break;
- case Instruction::k10t:
- case Instruction::k20t:
- case Instruction::k30t:
- offset = insn.vA;
- break;
- default:
- LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
- }
- str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
- offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
- } else {
- // For invokes-style formats, treat wide regs as a pair of singles
- bool show_singles = ((dalvik_format == Instruction::k35c) ||
- (dalvik_format == Instruction::k3rc));
- if (defs != 0) {
- str.append(StringPrintf(" %s", GetSSANameWithConst(cu, ssa_rep->defs[0], false).c_str()));
- if (uses != 0) {
- str.append(", ");
- }
- }
- 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 != NULL) && cu->reg_location[i].wide) {
- // For the listing, skip the high sreg.
- i++;
- }
- if (i != (uses -1)) {
- str.append(",");
- }
- }
- switch (dalvik_format) {
- case Instruction::k11n: // Add one immediate from vB
- case Instruction::k21s:
- case Instruction::k31i:
- case Instruction::k21h:
- str.append(StringPrintf(", #%d", insn.vB));
- break;
- case Instruction::k51l: // Add one wide immediate
- str.append(StringPrintf(", #%lld", insn.vB_wide));
- break;
- case Instruction::k21c: // One register, one string/type/method index
- case Instruction::k31c:
- str.append(StringPrintf(", index #%d", insn.vB));
- break;
- case Instruction::k22c: // Two registers, one string/type/method index
- str.append(StringPrintf(", index #%d", insn.vC));
- break;
- case Instruction::k22s: // Add one immediate from vC
- case Instruction::k22b:
- str.append(StringPrintf(", #%d", insn.vC));
- break;
- default:
- ; // Nothing left to print
- }
- }
- if (nop) {
- str.append("]--optimized away");
- }
- int length = str.length() + 1;
- ret = static_cast<char*>(NewMem(cu, length, false, kAllocDFInfo));
- strncpy(ret, str.c_str(), length);
- return ret;
-}
} // namespace art