From 3aa57730e2aec451bb836918d936c6862598d8d6 Mon Sep 17 00:00:00 2001 From: Jean Christophe Beyler Date: Thu, 17 Apr 2014 12:47:24 -0700 Subject: [PATCH] ART: MIR, SSARepresentation, and BasicBlock Additional API Adding the API calls to the MIR structure to help with higher level code. Some code has been added to BasicBlock as well for the removal. Some code has also been added to SSARepresentation. A constructor has been added to DecodedInstruction. Change-Id: Ie65948d53d83fd8250545c94c88b442a68d702c7 Signed-off-by: Jean Christophe Beyler Signed-off-by: Razvan A Lupusoru Signed-off-by: Yixin Shou Signed-off-by: Chao-ying Fu Signed-off-by: Udayan Banerji --- compiler/dex/mir_graph.cc | 161 ++++++++++++++++++++++++-- compiler/dex/mir_graph.h | 29 ++++- compiler/dex/quick/dex_file_method_inliner.cc | 3 +- compiler/dex/ssa_transformation.cc | 3 +- 4 files changed, 183 insertions(+), 13 deletions(-) diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index 08d1bca9a..4ba66771b 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -196,7 +196,7 @@ BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, } orig_block->last_mir_insn = prev; - prev->next = NULL; + prev->next = nullptr; /* * Update the immediate predecessor block pointer so that outgoing edges @@ -220,6 +220,7 @@ BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, while (p != bottom_block->last_mir_insn) { p = p->next; DCHECK(p != nullptr); + p->bb = bottom_block->id; int opcode = p->dalvikInsn.opcode; /* * Some messiness here to ensure that we only enter real opcodes and only the @@ -543,7 +544,7 @@ BasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, DexOffse new_block->start_offset = insn->offset; cur_block->fall_through = new_block->id; new_block->predecessors->Insert(cur_block->id); - MIR* new_insn = static_cast(arena_->Alloc(sizeof(MIR), kArenaAllocMIR)); + MIR* new_insn = NewMIR(); *new_insn = *insn; insn->dalvikInsn.opcode = static_cast(kMirOpCheck); @@ -629,7 +630,7 @@ void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_ /* Parse all instructions and put them into containing basic blocks */ while (code_ptr < code_end) { - MIR *insn = static_cast(arena_->Alloc(sizeof(MIR), kArenaAllocMIR)); + MIR *insn = NewMIR(); insn->offset = current_offset_; insn->m_unit_index = current_method_; int width = ParseInsn(code_ptr, &insn->dalvikInsn); @@ -923,7 +924,7 @@ void MIRGraph::DumpCFG(const char* dir_prefix, bool all_blocks, const char *suff fclose(file); } -/* Insert an MIR instruction to the end of a basic block */ +/* Insert an MIR instruction to the end of a basic block. */ void BasicBlock::AppendMIR(MIR* mir) { if (first_mir_insn == nullptr) { DCHECK(last_mir_insn == nullptr); @@ -934,9 +935,11 @@ void BasicBlock::AppendMIR(MIR* mir) { mir->next = nullptr; last_mir_insn = mir; } + + mir->bb = id; } -/* Insert an MIR instruction to the head of a basic block */ +/* Insert an MIR instruction to the head of a basic block. */ void BasicBlock::PrependMIR(MIR* mir) { if (first_mir_insn == nullptr) { DCHECK(last_mir_insn == nullptr); @@ -946,17 +949,53 @@ void BasicBlock::PrependMIR(MIR* mir) { mir->next = first_mir_insn; first_mir_insn = mir; } + + mir->bb = id; } -/* Insert a MIR instruction after the specified MIR */ +/* Insert a MIR instruction after the specified MIR. */ void BasicBlock::InsertMIRAfter(MIR* current_mir, MIR* new_mir) { new_mir->next = current_mir->next; current_mir->next = new_mir; if (last_mir_insn == current_mir) { - /* Is the last MIR in the block */ + /* Is the last MIR in the block? */ last_mir_insn = new_mir; } + + new_mir->bb = id; +} + +MIR* BasicBlock::FindPreviousMIR(MIR* mir) { + MIR* current = first_mir_insn; + + while (current != nullptr) { + MIR* next = current->next; + + if (next == mir) { + return current; + } + + current = next; + } + + return nullptr; +} + +void BasicBlock::InsertMIRBefore(MIR* current_mir, MIR* new_mir) { + if (first_mir_insn == current_mir) { + /* Is the first MIR in the block? */ + first_mir_insn = new_mir; + new_mir->bb = id; + } + + MIR* prev = FindPreviousMIR(current_mir); + + if (prev != nullptr) { + prev->next = new_mir; + new_mir->next = current_mir; + new_mir->bb = id; + } } MIR* BasicBlock::GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current) { @@ -1239,6 +1278,12 @@ CallInfo* MIRGraph::NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, return info; } +// Allocate a new MIR. +MIR* MIRGraph::NewMIR() { + MIR* mir = new (arena_) MIR(); + return mir; +} + // Allocate a new basic block. BasicBlock* MIRGraph::NewMemBB(BBType block_type, int block_id) { BasicBlock* bb = static_cast(arena_->Alloc(sizeof(BasicBlock), @@ -1343,4 +1388,106 @@ BasicBlock* ChildBlockIterator::Next() { return nullptr; } +bool BasicBlock::RemoveMIR(MIR* mir) { + if (mir == nullptr) { + return false; + } + + // Find the MIR, and the one before it if they exist. + MIR* current = nullptr; + MIR* prev = nullptr; + + // Find the mir we are looking for. + for (current = first_mir_insn; current != nullptr; prev = current, current = current->next) { + if (current == mir) { + break; + } + } + + // Did we find it? + if (current != nullptr) { + MIR* next = current->next; + + // Just update the links of prev and next and current is almost gone. + if (prev != nullptr) { + prev->next = next; + } + + // Exceptions are if first or last mirs are invoke. + if (first_mir_insn == current) { + first_mir_insn = next; + } + + if (last_mir_insn == current) { + last_mir_insn = prev; + } + + // Found it and removed it. + return true; + } + + // We did not find it. + return false; +} + +MIR* MIR::Copy(MIRGraph* mir_graph) { + MIR* res = mir_graph->NewMIR(); + *res = *this; + + // Remove links + res->next = nullptr; + res->bb = NullBasicBlockId; + res->ssa_rep = nullptr; + + return res; +} + +MIR* MIR::Copy(CompilationUnit* c_unit) { + return Copy(c_unit->mir_graph.get()); +} + +uint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) { + // Default result. + int res = 0; + + // We are basically setting the iputs to their igets counterparts. + switch (opcode) { + case Instruction::IPUT: + case Instruction::IPUT_OBJECT: + case Instruction::IPUT_BOOLEAN: + case Instruction::IPUT_BYTE: + case Instruction::IPUT_CHAR: + case Instruction::IPUT_SHORT: + case Instruction::IPUT_QUICK: + case Instruction::IPUT_OBJECT_QUICK: + case Instruction::APUT: + case Instruction::APUT_OBJECT: + case Instruction::APUT_BOOLEAN: + case Instruction::APUT_BYTE: + case Instruction::APUT_CHAR: + case Instruction::APUT_SHORT: + case Instruction::SPUT: + case Instruction::SPUT_OBJECT: + case Instruction::SPUT_BOOLEAN: + case Instruction::SPUT_BYTE: + case Instruction::SPUT_CHAR: + case Instruction::SPUT_SHORT: + // Skip the VR containing what to store. + res = 1; + break; + case Instruction::IPUT_WIDE: + case Instruction::IPUT_WIDE_QUICK: + case Instruction::APUT_WIDE: + case Instruction::SPUT_WIDE: + // Skip the two VRs containing what to store. + res = 2; + break; + default: + // Do nothing in the general case. + break; + } + + return res; +} + } // namespace art diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index ded1c99e9..0bb82659a 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -242,6 +242,8 @@ struct SSARepresentation { bool* fp_use; int32_t* defs; bool* fp_def; + + static uint32_t GetStartUseIndex(Instruction::Code opcode); }; /* @@ -261,13 +263,15 @@ struct MIR { uint32_t vC; uint32_t arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */ Instruction::Code opcode; + + explicit DecodedInstruction():vA(0), vB(0), vB_wide(0), vC(0), opcode(Instruction::NOP) { + } } dalvikInsn; - // TODO: Add id of parent basic block. - // BasicBlockId parent_bb; // ID of parent basic block. NarrowDexOffset offset; // Offset of the instruction in code units. uint16_t optimization_flags; int16_t m_unit_index; // From which method was this MIR included + BasicBlockId bb; MIR* next; SSARepresentation* ssa_rep; union { @@ -286,6 +290,23 @@ struct MIR { // INVOKE data index, points to MIRGraph::method_lowering_infos_. uint32_t method_lowering_info; } meta; + + explicit MIR():offset(0), optimization_flags(0), m_unit_index(0), bb(NullBasicBlockId), + next(nullptr), ssa_rep(nullptr) { + memset(&meta, 0, sizeof(meta)); + } + + uint32_t GetStartUseIndex() const { + return SSARepresentation::GetStartUseIndex(dalvikInsn.opcode); + } + + MIR* Copy(CompilationUnit *c_unit); + MIR* Copy(MIRGraph* mir_Graph); + + static void* operator new(size_t size, ArenaAllocator* arena) { + return arena->Alloc(sizeof(MIR), kArenaAllocMIR); + } + static void operator delete(void* p) {} // Nop. }; struct SuccessorBlockInfo; @@ -320,6 +341,8 @@ struct BasicBlock { void AppendMIR(MIR* mir); void PrependMIR(MIR* mir); void InsertMIRAfter(MIR* current_mir, MIR* new_mir); + void InsertMIRBefore(MIR* current_mir, MIR* new_mir); + MIR* FindPreviousMIR(MIR* mir); /** * @brief Used to obtain the next MIR that follows unconditionally. @@ -330,6 +353,7 @@ struct BasicBlock { * @return Returns the following MIR if one can be found. */ MIR* GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current); + bool RemoveMIR(MIR* mir); }; /* @@ -837,6 +861,7 @@ class MIRGraph { void DumpMIRGraph(); CallInfo* NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, bool is_range); BasicBlock* NewMemBB(BBType block_type, int block_id); + MIR* NewMIR(); MIR* AdvanceMIR(BasicBlock** p_bb, MIR* mir); BasicBlock* NextDominatedBlock(BasicBlock* bb); bool LayoutBlocks(BasicBlock* bb); diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index 9f98e5599..526c981ae 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -35,8 +35,7 @@ namespace art { namespace { // anonymous namespace MIR* AllocReplacementMIR(MIRGraph* mir_graph, MIR* invoke, MIR* move_return) { - ArenaAllocator* arena = mir_graph->GetArena(); - MIR* insn = static_cast(arena->Alloc(sizeof(MIR), kArenaAllocMIR)); + MIR* insn = mir_graph->NewMIR(); insn->offset = invoke->offset; insn->optimization_flags = MIR_CALLEE; return insn; diff --git a/compiler/dex/ssa_transformation.cc b/compiler/dex/ssa_transformation.cc index 5aa093a49..865311b08 100644 --- a/compiler/dex/ssa_transformation.cc +++ b/compiler/dex/ssa_transformation.cc @@ -557,8 +557,7 @@ void MIRGraph::InsertPhiNodes() { if (!phi_bb->data_flow_info->live_in_v->IsBitSet(dalvik_reg)) { continue; } - MIR *phi = - static_cast(arena_->Alloc(sizeof(MIR), kArenaAllocDFInfo)); + MIR *phi = NewMIR(); phi->dalvikInsn.opcode = static_cast(kMirOpPhi); phi->dalvikInsn.vA = dalvik_reg; phi->offset = phi_bb->start_offset; -- 2.11.0