summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/mir_graph.cc161
-rw-r--r--compiler/dex/mir_graph.h29
-rw-r--r--compiler/dex/quick/dex_file_method_inliner.cc3
-rw-r--r--compiler/dex/ssa_transformation.cc3
4 files changed, 183 insertions, 13 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 08d1bca..4ba6677 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<MIR*>(arena_->Alloc(sizeof(MIR), kArenaAllocMIR));
+ MIR* new_insn = NewMIR();
*new_insn = *insn;
insn->dalvikInsn.opcode =
static_cast<Instruction::Code>(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<MIR *>(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<BasicBlock*>(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 ded1c99..0bb8265 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 9f98e55..526c981 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<MIR*>(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 5aa093a..865311b 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<MIR*>(arena_->Alloc(sizeof(MIR), kArenaAllocDFInfo));
+ MIR *phi = NewMIR();
phi->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpPhi);
phi->dalvikInsn.vA = dalvik_reg;
phi->offset = phi_bb->start_offset;