summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-03-11 17:53:17 +0000
committerNicolas Geoffray <ngeoffray@google.com>2014-03-13 09:23:12 +0000
commitbab4ed7057799a4fadc6283108ab56f389d117d4 (patch)
treeea1bf495458fd9f7a3ffbed0ea4e1dda5a0b8184 /compiler/optimizing/builder.cc
parent37d4c1db4d705f5a28001f65afdd68d0527948d8 (diff)
downloadart-bab4ed7057799a4fadc6283108ab56f389d117d4.zip
art-bab4ed7057799a4fadc6283108ab56f389d117d4.tar.gz
art-bab4ed7057799a4fadc6283108ab56f389d117d4.tar.bz2
More code generation for the optimizing compiler.
- Add HReturn instruction - Generate code for locals/if/return - Setup infrastructure for register allocation. Currently emulate a stack. Change-Id: Ib28c2dba80f6c526177ed9a7b09c0689ac8122fb
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc60
1 files changed, 48 insertions, 12 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 190c925..8c6a8cb 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -28,19 +28,25 @@ void HGraphBuilder::InitializeLocals(int count) {
for (int i = 0; i < count; i++) {
HLocal* local = new (arena_) HLocal(i);
entry_block_->AddInstruction(local);
- locals_.Put(0, local);
+ locals_.Put(i, local);
}
}
static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) {
- if (code_item.tries_size_ > 0) return false;
- if (code_item.outs_size_ > 0) return false;
- if (code_item.ins_size_ > 0) return false;
+ if (code_item.tries_size_ > 0) {
+ return false;
+ } else if (code_item.outs_size_ > 0) {
+ return false;
+ } else if (code_item.ins_size_ > 0) {
+ return false;
+ }
return true;
}
HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
- if (!CanHandleCodeItem(code_item)) return nullptr;
+ if (!CanHandleCodeItem(code_item)) {
+ return nullptr;
+ }
const uint16_t* code_ptr = code_item.insns_;
const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
@@ -78,7 +84,9 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
HBasicBlock* block = FindBlockStartingAt(index);
- if (block == nullptr) return;
+ if (block == nullptr) {
+ return;
+ }
if (current_block_ != nullptr) {
// Branching instructions clear current_block, so we know
@@ -131,7 +139,9 @@ HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t index) const {
}
bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_t dex_offset) {
- if (current_block_ == nullptr) return true; // Dead code
+ if (current_block_ == nullptr) {
+ return true; // Dead code
+ }
switch (instruction.Opcode()) {
case Instruction::CONST_4: {
@@ -140,11 +150,14 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
UpdateLocal(register_index, constant);
break;
}
- case Instruction::RETURN_VOID:
+
+ case Instruction::RETURN_VOID: {
current_block_->AddInstruction(new (arena_) HReturnVoid());
current_block_->AddSuccessor(exit_block_);
current_block_ = nullptr;
break;
+ }
+
case Instruction::IF_EQ: {
HInstruction* first = LoadLocal(instruction.VRegA());
HInstruction* second = LoadLocal(instruction.VRegB());
@@ -159,6 +172,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
current_block_ = nullptr;
break;
}
+
case Instruction::GOTO:
case Instruction::GOTO_16:
case Instruction::GOTO_32: {
@@ -169,8 +183,18 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
current_block_ = nullptr;
break;
}
+
+ case Instruction::RETURN: {
+ HInstruction* value = LoadLocal(instruction.VRegA());
+ current_block_->AddInstruction(new (arena_) HReturn(value));
+ current_block_->AddSuccessor(exit_block_);
+ current_block_ = nullptr;
+ break;
+ }
+
case Instruction::NOP:
break;
+
default:
return false;
}
@@ -178,15 +202,27 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_
}
HIntConstant* HGraphBuilder::GetConstant0() {
- if (constant0_ != nullptr) return constant0_;
- HIntConstant* constant = new(arena_) HIntConstant(0);
- entry_block_->AddInstruction(constant);
- return constant;
+ if (constant0_ != nullptr) {
+ return constant0_;
+ }
+ constant0_ = new(arena_) HIntConstant(0);
+ entry_block_->AddInstruction(constant0_);
+ return constant0_;
+}
+
+HIntConstant* HGraphBuilder::GetConstant1() {
+ if (constant1_ != nullptr) {
+ return constant1_;
+ }
+ constant1_ = new(arena_) HIntConstant(1);
+ entry_block_->AddInstruction(constant1_);
+ return constant1_;
}
HIntConstant* HGraphBuilder::GetConstant(int constant) {
switch (constant) {
case 0: return GetConstant0();
+ case 1: return GetConstant1();
default: {
HIntConstant* instruction = new (arena_) HIntConstant(constant);
entry_block_->AddInstruction(instruction);