diff options
-rw-r--r-- | compiler/optimizing/builder.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 53 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 55 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 92 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 38 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 96 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 36 | ||||
-rw-r--r-- | compiler/optimizing/codegen_test.cc | 26 | ||||
-rw-r--r-- | compiler/optimizing/dominator_test.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 51 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 92 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 66 | ||||
-rw-r--r-- | compiler/optimizing/pretty_printer.h | 20 | ||||
-rw-r--r-- | compiler/optimizing/pretty_printer_test.cc | 4 |
14 files changed, 387 insertions, 258 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 8c6a8cb..39535e9 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -56,8 +56,8 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) { entry_block_ = new (arena_) HBasicBlock(graph_); graph_->AddBlock(entry_block_); exit_block_ = new (arena_) HBasicBlock(graph_); - graph_->set_entry_block(entry_block_); - graph_->set_exit_block(exit_block_); + graph_->SetEntryBlock(entry_block_); + graph_->SetExitBlock(exit_block_); InitializeLocals(code_item.registers_size_); @@ -162,7 +162,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ HInstruction* first = LoadLocal(instruction.VRegA()); HInstruction* second = LoadLocal(instruction.VRegB()); current_block_->AddInstruction(new (arena_) HEqual(first, second)); - current_block_->AddInstruction(new (arena_) HIf(current_block_->last_instruction())); + current_block_->AddInstruction(new (arena_) HIf(current_block_->GetLastInstruction())); HBasicBlock* target = FindBlockStartingAt(instruction.GetTargetOffset() + dex_offset); DCHECK(target != nullptr); current_block_->AddSuccessor(target); @@ -243,7 +243,7 @@ void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) c HInstruction* HGraphBuilder::LoadLocal(int register_index) const { HLocal* local = GetLocalAt(register_index); current_block_->AddInstruction(new (arena_) HLoadLocal(local)); - return current_block_->last_instruction(); + return current_block_->GetLastInstruction(); } } // namespace art diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 56342aa..b2a69d8 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -19,38 +19,36 @@ #include "code_generator_arm.h" #include "code_generator_x86.h" #include "utils/assembler.h" -#include "utils/arm/assembler_arm.h" -#include "utils/mips/assembler_mips.h" -#include "utils/x86/assembler_x86.h" namespace art { void CodeGenerator::Compile(CodeAllocator* allocator) { - const GrowableArray<HBasicBlock*>* blocks = graph()->blocks(); - DCHECK(blocks->Get(0) == graph()->entry_block()); - DCHECK(GoesToNextBlock(graph()->entry_block(), blocks->Get(1))); + const GrowableArray<HBasicBlock*>* blocks = GetGraph()->GetBlocks(); + DCHECK(blocks->Get(0) == GetGraph()->GetEntryBlock()); + DCHECK(GoesToNextBlock(GetGraph()->GetEntryBlock(), blocks->Get(1))); CompileEntryBlock(); for (size_t i = 1; i < blocks->Size(); i++) { CompileBlock(blocks->Get(i)); } - size_t code_size = assembler_->CodeSize(); + size_t code_size = GetAssembler()->CodeSize(); uint8_t* buffer = allocator->Allocate(code_size); MemoryRegion code(buffer, code_size); - assembler_->FinalizeInstructions(code); + GetAssembler()->FinalizeInstructions(code); } void CodeGenerator::CompileEntryBlock() { HGraphVisitor* location_builder = GetLocationBuilder(); + HGraphVisitor* instruction_visitor = GetInstructionVisitor(); // The entry block contains all locals for this method. By visiting the entry block, // we're computing the required frame size. - for (HInstructionIterator it(graph()->entry_block()); !it.Done(); it.Advance()) { + for (HInstructionIterator it(GetGraph()->GetEntryBlock()); !it.Done(); it.Advance()) { HInstruction* current = it.Current(); // Instructions in the entry block should not generate code. if (kIsDebugBuild) { current->Accept(location_builder); - DCHECK(current->locations() == nullptr); + DCHECK(current->GetLocations() == nullptr); } - current->Accept(this); + current->Accept(instruction_visitor); } GenerateFrameEntry(); } @@ -58,6 +56,7 @@ void CodeGenerator::CompileEntryBlock() { void CodeGenerator::CompileBlock(HBasicBlock* block) { Bind(GetLabelOf(block)); HGraphVisitor* location_builder = GetLocationBuilder(); + HGraphVisitor* instruction_visitor = GetInstructionVisitor(); for (HInstructionIterator it(block); !it.Done(); it.Advance()) { // For each instruction, we emulate a stack-based machine, where the inputs are popped from // the runtime stack, and the result is pushed on the stack. We currently can do this because @@ -66,17 +65,17 @@ void CodeGenerator::CompileBlock(HBasicBlock* block) { HInstruction* current = it.Current(); current->Accept(location_builder); InitLocations(current); - current->Accept(this); - if (current->locations() != nullptr && current->locations()->Out().IsValid()) { - Push(current, current->locations()->Out()); + current->Accept(instruction_visitor); + if (current->GetLocations() != nullptr && current->GetLocations()->Out().IsValid()) { + Push(current, current->GetLocations()->Out()); } } } void CodeGenerator::InitLocations(HInstruction* instruction) { - if (instruction->locations() == nullptr) return; + if (instruction->GetLocations() == nullptr) return; for (int i = 0; i < instruction->InputCount(); i++) { - Location location = instruction->locations()->InAt(i); + Location location = instruction->GetLocations()->InAt(i); if (location.IsValid()) { // Move the input to the desired location. Move(instruction->InputAt(i), location); @@ -86,32 +85,28 @@ void CodeGenerator::InitLocations(HInstruction* instruction) { bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const { // We currently iterate over the block in insertion order. - return current->block_id() + 1 == next->block_id(); + return current->GetBlockId() + 1 == next->GetBlockId(); } Label* CodeGenerator::GetLabelOf(HBasicBlock* block) const { - return block_labels_.GetRawStorage() + block->block_id(); + return block_labels_.GetRawStorage() + block->GetBlockId(); } -bool CodeGenerator::CompileGraph(HGraph* graph, - InstructionSet instruction_set, - CodeAllocator* allocator) { +CodeGenerator* CodeGenerator::Create(ArenaAllocator* allocator, + HGraph* graph, + InstructionSet instruction_set) { switch (instruction_set) { case kArm: case kThumb2: { - arm::ArmAssembler assembler; - arm::CodeGeneratorARM(&assembler, graph).Compile(allocator); - return true; + return new (allocator) arm::CodeGeneratorARM(graph); } case kMips: - return false; + return nullptr; case kX86: { - x86::X86Assembler assembler; - x86::CodeGeneratorX86(&assembler, graph).Compile(allocator); - return true; + return new (allocator) x86::CodeGeneratorX86(graph); } default: - return false; + return nullptr; } } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index c406378..e95bb21 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -79,7 +79,7 @@ class Location : public ValueObject { class LocationSummary : public ArenaObject { public: explicit LocationSummary(HInstruction* instruction) - : inputs(instruction->block()->graph()->arena(), instruction->InputCount()) { + : inputs(instruction->GetBlock()->GetGraph()->GetArena(), instruction->InputCount()) { inputs.SetSize(instruction->InputCount()); for (int i = 0; i < instruction->InputCount(); i++) { inputs.Put(i, Location()); @@ -107,51 +107,54 @@ class LocationSummary : public ArenaObject { DISALLOW_COPY_AND_ASSIGN(LocationSummary); }; -class CodeGenerator : public HGraphVisitor { +class CodeGenerator : public ArenaObject { public: // Compiles the graph to executable instructions. Returns whether the compilation // succeeded. - static bool CompileGraph(HGraph* graph, InstructionSet instruction_set, CodeAllocator* allocator); - - Assembler* assembler() const { return assembler_; } - - // Visit functions for instruction classes. -#define DECLARE_VISIT_INSTRUCTION(name) \ - virtual void Visit##name(H##name* instr) = 0; - - FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) - -#undef DECLARE_VISIT_INSTRUCTION + void Compile(CodeAllocator* allocator); + static CodeGenerator* Create(ArenaAllocator* allocator, + HGraph* graph, + InstructionSet instruction_set); - protected: - CodeGenerator(Assembler* assembler, HGraph* graph) - : HGraphVisitor(graph), - frame_size_(0), - assembler_(assembler), - block_labels_(graph->arena(), 0) { - block_labels_.SetSize(graph->blocks()->Size()); - } + HGraph* GetGraph() const { return graph_; } Label* GetLabelOf(HBasicBlock* block) const; bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const; - // Frame size required for this method. - uint32_t frame_size_; - virtual void GenerateFrameEntry() = 0; virtual void GenerateFrameExit() = 0; virtual void Bind(Label* label) = 0; virtual void Move(HInstruction* instruction, Location location) = 0; virtual void Push(HInstruction* instruction, Location location) = 0; virtual HGraphVisitor* GetLocationBuilder() = 0; + virtual HGraphVisitor* GetInstructionVisitor() = 0; + virtual Assembler* GetAssembler() = 0; + + uint32_t GetFrameSize() const { return frame_size_; } + void SetFrameSize(uint32_t size) { frame_size_ = size; } + + void BuildMappingTable(std::vector<uint8_t>* vector) const { } + void BuildVMapTable(std::vector<uint8_t>* vector) const { } + void BuildNativeGCMap(std::vector<uint8_t>* vector) const { } + + protected: + explicit CodeGenerator(HGraph* graph) + : frame_size_(0), + graph_(graph), + block_labels_(graph->GetArena(), 0) { + block_labels_.SetSize(graph->GetBlocks()->Size()); + } + ~CodeGenerator() { } private: void InitLocations(HInstruction* instruction); - void Compile(CodeAllocator* allocator); void CompileBlock(HBasicBlock* block); void CompileEntryBlock(); - Assembler* const assembler_; + // Frame size required for this method. + uint32_t frame_size_; + + HGraph* const graph_; // Labels for each block that will be compiled. GrowableArray<Label> block_labels_; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 62bf7ba..04bdc34 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -18,7 +18,7 @@ #include "utils/assembler.h" #include "utils/arm/assembler_arm.h" -#define __ reinterpret_cast<ArmAssembler*>(assembler())-> +#define __ reinterpret_cast<ArmAssembler*>(GetAssembler())-> namespace art { namespace arm { @@ -26,8 +26,8 @@ namespace arm { void CodeGeneratorARM::GenerateFrameEntry() { __ PushList((1 << FP) | (1 << LR)); __ mov(FP, ShifterOperand(SP)); - if (frame_size_ != 0) { - __ AddConstant(SP, -frame_size_); + if (GetFrameSize() != 0) { + __ AddConstant(SP, -GetFrameSize()); } } @@ -47,30 +47,30 @@ void CodeGeneratorARM::Push(HInstruction* instruction, Location location) { void CodeGeneratorARM::Move(HInstruction* instruction, Location location) { HIntConstant* constant = instruction->AsIntConstant(); if (constant != nullptr) { - __ LoadImmediate(location.reg<Register>(), constant->value()); + __ LoadImmediate(location.reg<Register>(), constant->GetValue()); } else { __ Pop(location.reg<Register>()); } } void LocationsBuilderARM::VisitGoto(HGoto* got) { - got->set_locations(nullptr); + got->SetLocations(nullptr); } -void CodeGeneratorARM::VisitGoto(HGoto* got) { +void InstructionCodeGeneratorARM::VisitGoto(HGoto* got) { HBasicBlock* successor = got->GetSuccessor(); - if (graph()->exit_block() == successor) { - GenerateFrameExit(); - } else if (!GoesToNextBlock(got->block(), successor)) { - __ b(GetLabelOf(successor)); + if (GetGraph()->GetExitBlock() == successor) { + codegen_->GenerateFrameExit(); + } else if (!codegen_->GoesToNextBlock(got->GetBlock(), successor)) { + __ b(codegen_->GetLabelOf(successor)); } } void LocationsBuilderARM::VisitExit(HExit* exit) { - exit->set_locations(nullptr); + exit->SetLocations(nullptr); } -void CodeGeneratorARM::VisitExit(HExit* exit) { +void InstructionCodeGeneratorARM::VisitExit(HExit* exit) { if (kIsDebugBuild) { __ Comment("Unreachable"); __ bkpt(0); @@ -78,30 +78,30 @@ void CodeGeneratorARM::VisitExit(HExit* exit) { } void LocationsBuilderARM::VisitIf(HIf* if_instr) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(if_instr); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(if_instr); locations->SetInAt(0, Location(R0)); - if_instr->set_locations(locations); + if_instr->SetLocations(locations); } -void CodeGeneratorARM::VisitIf(HIf* if_instr) { +void InstructionCodeGeneratorARM::VisitIf(HIf* if_instr) { // TODO: Generate the input as a condition, instead of materializing in a register. - __ cmp(if_instr->locations()->InAt(0).reg<Register>(), ShifterOperand(0)); - __ b(GetLabelOf(if_instr->IfFalseSuccessor()), EQ); - if (!GoesToNextBlock(if_instr->block(), if_instr->IfTrueSuccessor())) { - __ b(GetLabelOf(if_instr->IfTrueSuccessor())); + __ cmp(if_instr->GetLocations()->InAt(0).reg<Register>(), ShifterOperand(0)); + __ b(codegen_->GetLabelOf(if_instr->IfFalseSuccessor()), EQ); + if (!codegen_->GoesToNextBlock(if_instr->GetBlock(), if_instr->IfTrueSuccessor())) { + __ b(codegen_->GetLabelOf(if_instr->IfTrueSuccessor())); } } void LocationsBuilderARM::VisitEqual(HEqual* equal) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(equal); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(equal); locations->SetInAt(0, Location(R0)); locations->SetInAt(1, Location(R1)); locations->SetOut(Location(R0)); - equal->set_locations(locations); + equal->SetLocations(locations); } -void CodeGeneratorARM::VisitEqual(HEqual* equal) { - LocationSummary* locations = equal->locations(); +void InstructionCodeGeneratorARM::VisitEqual(HEqual* equal) { + LocationSummary* locations = equal->GetLocations(); __ teq(locations->InAt(0).reg<Register>(), ShifterOperand(locations->InAt(1).reg<Register>())); __ mov(locations->Out().reg<Register>(), ShifterOperand(1), EQ); @@ -109,68 +109,68 @@ void CodeGeneratorARM::VisitEqual(HEqual* equal) { } void LocationsBuilderARM::VisitLocal(HLocal* local) { - local->set_locations(nullptr); + local->SetLocations(nullptr); } -void CodeGeneratorARM::VisitLocal(HLocal* local) { - DCHECK_EQ(local->block(), graph()->entry_block()); - frame_size_ += kWordSize; +void InstructionCodeGeneratorARM::VisitLocal(HLocal* local) { + DCHECK_EQ(local->GetBlock(), GetGraph()->GetEntryBlock()); + codegen_->SetFrameSize(codegen_->GetFrameSize() + kWordSize); } void LocationsBuilderARM::VisitLoadLocal(HLoadLocal* load) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(load); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(load); locations->SetOut(Location(R0)); - load->set_locations(locations); + load->SetLocations(locations); } static int32_t GetStackSlot(HLocal* local) { // We are currently using FP to access locals, so the offset must be negative. - return (local->reg_number() + 1) * -kWordSize; + return (local->GetRegNumber() + 1) * -kWordSize; } -void CodeGeneratorARM::VisitLoadLocal(HLoadLocal* load) { - LocationSummary* locations = load->locations(); +void InstructionCodeGeneratorARM::VisitLoadLocal(HLoadLocal* load) { + LocationSummary* locations = load->GetLocations(); __ LoadFromOffset(kLoadWord, locations->Out().reg<Register>(), FP, GetStackSlot(load->GetLocal())); } void LocationsBuilderARM::VisitStoreLocal(HStoreLocal* store) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(store); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(store); locations->SetInAt(1, Location(R0)); - store->set_locations(locations); + store->SetLocations(locations); } -void CodeGeneratorARM::VisitStoreLocal(HStoreLocal* store) { - LocationSummary* locations = store->locations(); +void InstructionCodeGeneratorARM::VisitStoreLocal(HStoreLocal* store) { + LocationSummary* locations = store->GetLocations(); __ StoreToOffset(kStoreWord, locations->InAt(1).reg<Register>(), FP, GetStackSlot(store->GetLocal())); } void LocationsBuilderARM::VisitIntConstant(HIntConstant* constant) { - constant->set_locations(nullptr); + constant->SetLocations(nullptr); } -void CodeGeneratorARM::VisitIntConstant(HIntConstant* constant) { +void InstructionCodeGeneratorARM::VisitIntConstant(HIntConstant* constant) { // Will be generated at use site. } void LocationsBuilderARM::VisitReturnVoid(HReturnVoid* ret) { - ret->set_locations(nullptr); + ret->SetLocations(nullptr); } -void CodeGeneratorARM::VisitReturnVoid(HReturnVoid* ret) { - GenerateFrameExit(); +void InstructionCodeGeneratorARM::VisitReturnVoid(HReturnVoid* ret) { + codegen_->GenerateFrameExit(); } void LocationsBuilderARM::VisitReturn(HReturn* ret) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(ret); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(ret); locations->SetInAt(0, Location(R0)); - ret->set_locations(locations); + ret->SetLocations(locations); } -void CodeGeneratorARM::VisitReturn(HReturn* ret) { - DCHECK_EQ(ret->locations()->InAt(0).reg<Register>(), R0); - GenerateFrameExit(); +void InstructionCodeGeneratorARM::VisitReturn(HReturn* ret) { + DCHECK_EQ(ret->GetLocations()->InAt(0).reg<Register>(), R0); + codegen_->GenerateFrameExit(); } } // namespace arm diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 33d8e62..52a7bf4 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -19,6 +19,7 @@ #include "code_generator.h" #include "nodes.h" +#include "utils/arm/assembler_arm.h" namespace art { @@ -42,12 +43,13 @@ class LocationsBuilderARM : public HGraphVisitor { DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM); }; -class CodeGeneratorARM : public CodeGenerator { +class InstructionCodeGeneratorARM : public HGraphVisitor { public: - CodeGeneratorARM(Assembler* assembler, HGraph* graph) - : CodeGenerator(assembler, graph), location_builder_(graph) { } + explicit InstructionCodeGeneratorARM(HGraph* graph, CodeGenerator* codegen) + : HGraphVisitor(graph), + assembler_(codegen->GetAssembler()), + codegen_(codegen) { } - // Visit functions for instruction classes. #define DECLARE_VISIT_INSTRUCTION(name) \ virtual void Visit##name(H##name* instr); @@ -55,6 +57,23 @@ class CodeGeneratorARM : public CodeGenerator { #undef DECLARE_VISIT_INSTRUCTION + Assembler* GetAssembler() const { return assembler_; } + + private: + Assembler* const assembler_; + CodeGenerator* const codegen_; + + DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorARM); +}; + +class CodeGeneratorARM : public CodeGenerator { + public: + explicit CodeGeneratorARM(HGraph* graph) + : CodeGenerator(graph), + location_builder_(graph), + instruction_visitor_(graph, this) { } + virtual ~CodeGeneratorARM() { } + protected: virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; @@ -66,8 +85,19 @@ class CodeGeneratorARM : public CodeGenerator { return &location_builder_; } + virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { + return &instruction_visitor_; + } + + virtual Assembler* GetAssembler() OVERRIDE { + return &assembler_; + } + private: LocationsBuilderARM location_builder_; + InstructionCodeGeneratorARM instruction_visitor_; + ArmAssembler assembler_; + DISALLOW_COPY_AND_ASSIGN(CodeGeneratorARM); }; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 81ada4d..c4bda56 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -18,7 +18,7 @@ #include "utils/assembler.h" #include "utils/x86/assembler_x86.h" -#define __ reinterpret_cast<X86Assembler*>(assembler())-> +#define __ reinterpret_cast<X86Assembler*>(GetAssembler())-> namespace art { namespace x86 { @@ -27,8 +27,8 @@ void CodeGeneratorX86::GenerateFrameEntry() { __ pushl(EBP); __ movl(EBP, ESP); - if (frame_size_ != 0) { - __ subl(ESP, Immediate(frame_size_)); + if (GetFrameSize() != 0) { + __ subl(ESP, Immediate(GetFrameSize())); } } @@ -48,30 +48,30 @@ void CodeGeneratorX86::Push(HInstruction* instruction, Location location) { void CodeGeneratorX86::Move(HInstruction* instruction, Location location) { HIntConstant* constant = instruction->AsIntConstant(); if (constant != nullptr) { - __ movl(location.reg<Register>(), Immediate(constant->value())); + __ movl(location.reg<Register>(), Immediate(constant->GetValue())); } else { __ popl(location.reg<Register>()); } } void LocationsBuilderX86::VisitGoto(HGoto* got) { - got->set_locations(nullptr); + got->SetLocations(nullptr); } -void CodeGeneratorX86::VisitGoto(HGoto* got) { +void InstructionCodeGeneratorX86::VisitGoto(HGoto* got) { HBasicBlock* successor = got->GetSuccessor(); - if (graph()->exit_block() == successor) { - GenerateFrameExit(); - } else if (!GoesToNextBlock(got->block(), successor)) { - __ jmp(GetLabelOf(successor)); + if (GetGraph()->GetExitBlock() == successor) { + codegen_->GenerateFrameExit(); + } else if (!codegen_->GoesToNextBlock(got->GetBlock(), successor)) { + __ jmp(codegen_->GetLabelOf(successor)); } } void LocationsBuilderX86::VisitExit(HExit* exit) { - exit->set_locations(nullptr); + exit->SetLocations(nullptr); } -void CodeGeneratorX86::VisitExit(HExit* exit) { +void InstructionCodeGeneratorX86::VisitExit(HExit* exit) { if (kIsDebugBuild) { __ Comment("Unreachable"); __ int3(); @@ -79,96 +79,96 @@ void CodeGeneratorX86::VisitExit(HExit* exit) { } void LocationsBuilderX86::VisitIf(HIf* if_instr) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(if_instr); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(if_instr); locations->SetInAt(0, Location(EAX)); - if_instr->set_locations(locations); + if_instr->SetLocations(locations); } -void CodeGeneratorX86::VisitIf(HIf* if_instr) { +void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) { // TODO: Generate the input as a condition, instead of materializing in a register. - __ cmpl(if_instr->locations()->InAt(0).reg<Register>(), Immediate(0)); - __ j(kEqual, GetLabelOf(if_instr->IfFalseSuccessor())); - if (!GoesToNextBlock(if_instr->block(), if_instr->IfTrueSuccessor())) { - __ jmp(GetLabelOf(if_instr->IfTrueSuccessor())); + __ cmpl(if_instr->GetLocations()->InAt(0).reg<Register>(), Immediate(0)); + __ j(kEqual, codegen_->GetLabelOf(if_instr->IfFalseSuccessor())); + if (!codegen_->GoesToNextBlock(if_instr->GetBlock(), if_instr->IfTrueSuccessor())) { + __ jmp(codegen_->GetLabelOf(if_instr->IfTrueSuccessor())); } } void LocationsBuilderX86::VisitLocal(HLocal* local) { - local->set_locations(nullptr); + local->SetLocations(nullptr); } -void CodeGeneratorX86::VisitLocal(HLocal* local) { - DCHECK_EQ(local->block(), graph()->entry_block()); - frame_size_ += kWordSize; +void InstructionCodeGeneratorX86::VisitLocal(HLocal* local) { + DCHECK_EQ(local->GetBlock(), GetGraph()->GetEntryBlock()); + codegen_->SetFrameSize(codegen_->GetFrameSize() + kWordSize); } void LocationsBuilderX86::VisitLoadLocal(HLoadLocal* local) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(local); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(local); locations->SetOut(Location(EAX)); - local->set_locations(locations); + local->SetLocations(locations); } static int32_t GetStackSlot(HLocal* local) { // We are currently using EBP to access locals, so the offset must be negative. - return (local->reg_number() + 1) * -kWordSize; + return (local->GetRegNumber() + 1) * -kWordSize; } -void CodeGeneratorX86::VisitLoadLocal(HLoadLocal* load) { - __ movl(load->locations()->Out().reg<Register>(), +void InstructionCodeGeneratorX86::VisitLoadLocal(HLoadLocal* load) { + __ movl(load->GetLocations()->Out().reg<Register>(), Address(EBP, GetStackSlot(load->GetLocal()))); } void LocationsBuilderX86::VisitStoreLocal(HStoreLocal* local) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(local); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(local); locations->SetInAt(1, Location(EAX)); - local->set_locations(locations); + local->SetLocations(locations); } -void CodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) { +void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) { __ movl(Address(EBP, GetStackSlot(store->GetLocal())), - store->locations()->InAt(1).reg<Register>()); + store->GetLocations()->InAt(1).reg<Register>()); } void LocationsBuilderX86::VisitEqual(HEqual* equal) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(equal); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(equal); locations->SetInAt(0, Location(EAX)); locations->SetInAt(1, Location(ECX)); locations->SetOut(Location(EAX)); - equal->set_locations(locations); + equal->SetLocations(locations); } -void CodeGeneratorX86::VisitEqual(HEqual* equal) { - __ cmpl(equal->locations()->InAt(0).reg<Register>(), - equal->locations()->InAt(1).reg<Register>()); - __ setb(kEqual, equal->locations()->Out().reg<Register>()); +void InstructionCodeGeneratorX86::VisitEqual(HEqual* equal) { + __ cmpl(equal->GetLocations()->InAt(0).reg<Register>(), + equal->GetLocations()->InAt(1).reg<Register>()); + __ setb(kEqual, equal->GetLocations()->Out().reg<Register>()); } void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) { - constant->set_locations(nullptr); + constant->SetLocations(nullptr); } -void CodeGeneratorX86::VisitIntConstant(HIntConstant* constant) { +void InstructionCodeGeneratorX86::VisitIntConstant(HIntConstant* constant) { // Will be generated at use site. } void LocationsBuilderX86::VisitReturnVoid(HReturnVoid* ret) { - ret->set_locations(nullptr); + ret->SetLocations(nullptr); } -void CodeGeneratorX86::VisitReturnVoid(HReturnVoid* ret) { - GenerateFrameExit(); +void InstructionCodeGeneratorX86::VisitReturnVoid(HReturnVoid* ret) { + codegen_->GenerateFrameExit(); __ ret(); } void LocationsBuilderX86::VisitReturn(HReturn* ret) { - LocationSummary* locations = new (graph()->arena()) LocationSummary(ret); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(ret); locations->SetInAt(0, Location(EAX)); - ret->set_locations(locations); + ret->SetLocations(locations); } -void CodeGeneratorX86::VisitReturn(HReturn* ret) { - DCHECK_EQ(ret->locations()->InAt(0).reg<Register>(), EAX); - GenerateFrameExit(); +void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { + DCHECK_EQ(ret->GetLocations()->InAt(0).reg<Register>(), EAX); + codegen_->GenerateFrameExit(); __ ret(); } diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index dd146b8..ad2a061 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -19,6 +19,7 @@ #include "code_generator.h" #include "nodes.h" +#include "utils/x86/assembler_x86.h" namespace art { @@ -42,10 +43,12 @@ class LocationsBuilderX86 : public HGraphVisitor { DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86); }; -class CodeGeneratorX86 : public CodeGenerator { +class InstructionCodeGeneratorX86 : public HGraphVisitor { public: - CodeGeneratorX86(Assembler* assembler, HGraph* graph) - : CodeGenerator(assembler, graph), location_builder_(graph) { } + explicit InstructionCodeGeneratorX86(HGraph* graph, CodeGenerator* codegen) + : HGraphVisitor(graph), + assembler_(codegen->GetAssembler()), + codegen_(codegen) { } #define DECLARE_VISIT_INSTRUCTION(name) \ virtual void Visit##name(H##name* instr); @@ -54,6 +57,23 @@ class CodeGeneratorX86 : public CodeGenerator { #undef DECLARE_VISIT_INSTRUCTION + Assembler* GetAssembler() const { return assembler_; } + + private: + Assembler* const assembler_; + CodeGenerator* const codegen_; + + DISALLOW_COPY_AND_ASSIGN(InstructionCodeGeneratorX86); +}; + +class CodeGeneratorX86 : public CodeGenerator { + public: + explicit CodeGeneratorX86(HGraph* graph) + : CodeGenerator(graph), + location_builder_(graph), + instruction_visitor_(graph, this) { } + virtual ~CodeGeneratorX86() { } + protected: virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; @@ -65,8 +85,18 @@ class CodeGeneratorX86 : public CodeGenerator { return &location_builder_; } + virtual HGraphVisitor* GetInstructionVisitor() OVERRIDE { + return &instruction_visitor_; + } + + virtual X86Assembler* GetAssembler() OVERRIDE { + return &assembler_; + } + private: LocationsBuilderX86 location_builder_; + InstructionCodeGeneratorX86 instruction_visitor_; + X86Assembler assembler_; DISALLOW_COPY_AND_ASSIGN(CodeGeneratorX86); }; diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc index 5020dd0..ff743d8 100644 --- a/compiler/optimizing/codegen_test.cc +++ b/compiler/optimizing/codegen_test.cc @@ -27,22 +27,24 @@ namespace art { -class ExecutableMemoryAllocator : public CodeAllocator { +class InternalCodeAllocator : public CodeAllocator { public: - ExecutableMemoryAllocator() { } + InternalCodeAllocator() { } virtual uint8_t* Allocate(size_t size) { + size_ = size; memory_.reset(new uint8_t[size]); - CommonCompilerTest::MakeExecutable(memory_.get(), size); return memory_.get(); } - uint8_t* memory() const { return memory_.get(); } + size_t GetSize() const { return size_; } + uint8_t* GetMemory() const { return memory_.get(); } private: + size_t size_; UniquePtr<uint8_t[]> memory_; - DISALLOW_COPY_AND_ASSIGN(ExecutableMemoryAllocator); + DISALLOW_COPY_AND_ASSIGN(InternalCodeAllocator); }; static void TestCode(const uint16_t* data, bool has_result = false, int32_t expected = 0) { @@ -52,18 +54,22 @@ static void TestCode(const uint16_t* data, bool has_result = false, int32_t expe const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); HGraph* graph = builder.BuildGraph(*item); ASSERT_NE(graph, nullptr); - ExecutableMemoryAllocator allocator; - CHECK(CodeGenerator::CompileGraph(graph, kX86, &allocator)); + InternalCodeAllocator allocator; + CodeGenerator* codegen = CodeGenerator::Create(&arena, graph, kX86); + codegen->Compile(&allocator); typedef int32_t (*fptr)(); #if defined(__i386__) - int32_t result = reinterpret_cast<fptr>(allocator.memory())(); + CommonCompilerTest::MakeExecutable(allocator.GetMemory(), allocator.GetSize()); + int32_t result = reinterpret_cast<fptr>(allocator.GetMemory())(); if (has_result) { CHECK_EQ(result, expected); } #endif - CHECK(CodeGenerator::CompileGraph(graph, kArm, &allocator)); + codegen = CodeGenerator::Create(&arena, graph, kArm); + codegen->Compile(&allocator); #if defined(__arm__) - int32_t result = reinterpret_cast<fptr>(allocator.memory())(); + CommonCompilerTest::MakeExecutable(allocator.GetMemory(), allocator.GetSize()); + int32_t result = reinterpret_cast<fptr>(allocator.GetMemory())(); if (has_result) { CHECK_EQ(result, expected); } diff --git a/compiler/optimizing/dominator_test.cc b/compiler/optimizing/dominator_test.cc index 78a9d75..1c30b79 100644 --- a/compiler/optimizing/dominator_test.cc +++ b/compiler/optimizing/dominator_test.cc @@ -32,13 +32,13 @@ static void TestCode(const uint16_t* data, const int* blocks, size_t blocks_leng HGraph* graph = builder.BuildGraph(*item); ASSERT_NE(graph, nullptr); graph->BuildDominatorTree(); - ASSERT_EQ(graph->blocks()->Size(), blocks_length); + ASSERT_EQ(graph->GetBlocks()->Size(), blocks_length); for (size_t i = 0; i < blocks_length; i++) { if (blocks[i] == -1) { - ASSERT_EQ(nullptr, graph->blocks()->Get(i)->dominator()); + ASSERT_EQ(nullptr, graph->GetBlocks()->Get(i)->GetDominator()); } else { - ASSERT_NE(nullptr, graph->blocks()->Get(i)->dominator()); - ASSERT_EQ(blocks[i], graph->blocks()->Get(i)->dominator()->block_id()); + ASSERT_NE(nullptr, graph->GetBlocks()->Get(i)->GetDominator()); + ASSERT_EQ(blocks[i], graph->GetBlocks()->Get(i)->GetDominator()->GetBlockId()); } } } diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index a6f3f5a..b8b4a3b 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -20,7 +20,7 @@ namespace art { void HGraph::AddBlock(HBasicBlock* block) { - block->set_block_id(blocks_.Size()); + block->SetBlockId(blocks_.Size()); blocks_.Add(block); } @@ -33,8 +33,8 @@ void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) const { for (size_t i = 0; i < blocks_.Size(); i++) { if (!visited.IsBitSet(i)) { HBasicBlock* block = blocks_.Get(i); - for (size_t j = 0; j < block->successors()->Size(); j++) { - block->successors()->Get(j)->RemovePredecessor(block); + for (size_t j = 0; j < block->GetSuccessors()->Size(); j++) { + block->GetSuccessors()->Get(j)->RemovePredecessor(block); } } } @@ -43,14 +43,14 @@ void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) const { void HGraph::VisitBlockForBackEdges(HBasicBlock* block, ArenaBitVector* visited, ArenaBitVector* visiting) const { - int id = block->block_id(); + int id = block->GetBlockId(); if (visited->IsBitSet(id)) return; visited->SetBit(id); visiting->SetBit(id); - for (size_t i = 0; i < block->successors()->Size(); i++) { - HBasicBlock* successor = block->successors()->Get(i); - if (visiting->IsBitSet(successor->block_id())) { + for (size_t i = 0; i < block->GetSuccessors()->Size(); i++) { + HBasicBlock* successor = block->GetSuccessors()->Get(i); + if (visiting->IsBitSet(successor->GetBlockId())) { successor->AddBackEdge(block); } else { VisitBlockForBackEdges(successor, visited, visiting); @@ -76,8 +76,8 @@ void HGraph::BuildDominatorTree() { GrowableArray<size_t> visits(arena_, blocks_.Size()); visits.SetSize(blocks_.Size()); dominator_order_.Add(entry_block_); - for (size_t i = 0; i < entry_block_->successors()->Size(); i++) { - VisitBlockForDominatorTree(entry_block_->successors()->Get(i), entry_block_, &visits); + for (size_t i = 0; i < entry_block_->GetSuccessors()->Size(); i++) { + VisitBlockForDominatorTree(entry_block_->GetSuccessors()->Get(i), entry_block_, &visits); } } @@ -85,15 +85,15 @@ HBasicBlock* HGraph::FindCommonDominator(HBasicBlock* first, HBasicBlock* second ArenaBitVector visited(arena_, blocks_.Size(), false); // Walk the dominator tree of the first block and mark the visited blocks. while (first != nullptr) { - visited.SetBit(first->block_id()); - first = first->dominator(); + visited.SetBit(first->GetBlockId()); + first = first->GetDominator(); } // Walk the dominator tree of the second block until a marked block is found. while (second != nullptr) { - if (visited.IsBitSet(second->block_id())) { + if (visited.IsBitSet(second->GetBlockId())) { return second; } - second = second->dominator(); + second = second->GetDominator(); } LOG(ERROR) << "Could not find common dominator"; return nullptr; @@ -102,28 +102,29 @@ HBasicBlock* HGraph::FindCommonDominator(HBasicBlock* first, HBasicBlock* second void HGraph::VisitBlockForDominatorTree(HBasicBlock* block, HBasicBlock* predecessor, GrowableArray<size_t>* visits) { - if (block->dominator() == nullptr) { - block->set_dominator(predecessor); + if (block->GetDominator() == nullptr) { + block->SetDominator(predecessor); } else { - block->set_dominator(FindCommonDominator(block->dominator(), predecessor)); + block->SetDominator(FindCommonDominator(block->GetDominator(), predecessor)); } - visits->Increment(block->block_id()); + visits->Increment(block->GetBlockId()); // Once all the forward edges have been visited, we know the immediate // dominator of the block. We can then start visiting its successors. - if (visits->Get(block->block_id()) == - block->predecessors()->Size() - block->NumberOfBackEdges()) { + if (visits->Get(block->GetBlockId()) == + block->GetPredecessors()->Size() - block->NumberOfBackEdges()) { dominator_order_.Add(block); - for (size_t i = 0; i < block->successors()->Size(); i++) { - VisitBlockForDominatorTree(block->successors()->Get(i), block, visits); + for (size_t i = 0; i < block->GetSuccessors()->Size(); i++) { + VisitBlockForDominatorTree(block->GetSuccessors()->Get(i), block, visits); } } } void HBasicBlock::AddInstruction(HInstruction* instruction) { - DCHECK(instruction->block() == nullptr); - instruction->set_block(this); - instruction->set_id(graph()->GetNextInstructionId()); + DCHECK(instruction->GetBlock() == nullptr); + DCHECK(instruction->GetId() == -1); + instruction->SetBlock(this); + instruction->SetId(GetGraph()->GetNextInstructionId()); if (first_instruction_ == nullptr) { DCHECK(last_instruction_ == nullptr); first_instruction_ = last_instruction_ = instruction; @@ -147,7 +148,7 @@ FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) #undef DEFINE_ACCEPT void HGraphVisitor::VisitInsertionOrder() { - const GrowableArray<HBasicBlock*>* blocks = graph_->blocks(); + const GrowableArray<HBasicBlock*>* blocks = graph_->GetBlocks(); for (size_t i = 0 ; i < blocks->Size(); i++) { VisitBasicBlock(blocks->Get(i)); } diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 9418599..e74ed82 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -43,14 +43,14 @@ class HGraph : public ArenaObject { dominator_order_(arena, kDefaultNumberOfBlocks), current_instruction_id_(0) { } - ArenaAllocator* arena() const { return arena_; } - const GrowableArray<HBasicBlock*>* blocks() const { return &blocks_; } + ArenaAllocator* GetArena() const { return arena_; } + const GrowableArray<HBasicBlock*>* GetBlocks() const { return &blocks_; } - HBasicBlock* entry_block() const { return entry_block_; } - HBasicBlock* exit_block() const { return exit_block_; } + HBasicBlock* GetEntryBlock() const { return entry_block_; } + HBasicBlock* GetExitBlock() const { return exit_block_; } - void set_entry_block(HBasicBlock* block) { entry_block_ = block; } - void set_exit_block(HBasicBlock* block) { exit_block_ = block; } + void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; } + void SetExitBlock(HBasicBlock* block) { exit_block_ = block; } void AddBlock(HBasicBlock* block); void BuildDominatorTree(); @@ -91,7 +91,7 @@ class HLoopInformation : public ArenaObject { public: HLoopInformation(HBasicBlock* header, HGraph* graph) : header_(header), - back_edges_(graph->arena(), kDefaultNumberOfBackEdges) { } + back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges) { } void AddBackEdge(HBasicBlock* back_edge) { back_edges_.Add(back_edge); @@ -115,36 +115,36 @@ class HBasicBlock : public ArenaObject { public: explicit HBasicBlock(HGraph* graph) : graph_(graph), - predecessors_(graph->arena(), kDefaultNumberOfPredecessors), - successors_(graph->arena(), kDefaultNumberOfSuccessors), + predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors), + successors_(graph->GetArena(), kDefaultNumberOfSuccessors), first_instruction_(nullptr), last_instruction_(nullptr), loop_information_(nullptr), dominator_(nullptr), block_id_(-1) { } - const GrowableArray<HBasicBlock*>* predecessors() const { + const GrowableArray<HBasicBlock*>* GetPredecessors() const { return &predecessors_; } - const GrowableArray<HBasicBlock*>* successors() const { + const GrowableArray<HBasicBlock*>* GetSuccessors() const { return &successors_; } void AddBackEdge(HBasicBlock* back_edge) { if (loop_information_ == nullptr) { - loop_information_ = new (graph_->arena()) HLoopInformation(this, graph_); + loop_information_ = new (graph_->GetArena()) HLoopInformation(this, graph_); } loop_information_->AddBackEdge(back_edge); } - HGraph* graph() const { return graph_; } + HGraph* GetGraph() const { return graph_; } - int block_id() const { return block_id_; } - void set_block_id(int id) { block_id_ = id; } + int GetBlockId() const { return block_id_; } + void SetBlockId(int id) { block_id_ = id; } - HBasicBlock* dominator() const { return dominator_; } - void set_dominator(HBasicBlock* dominator) { dominator_ = dominator; } + HBasicBlock* GetDominator() const { return dominator_; } + void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; } int NumberOfBackEdges() const { return loop_information_ == nullptr @@ -152,8 +152,8 @@ class HBasicBlock : public ArenaObject { : loop_information_->NumberOfBackEdges(); } - HInstruction* first_instruction() const { return first_instruction_; } - HInstruction* last_instruction() const { return last_instruction_; } + HInstruction* GetFirstInstruction() const { return first_instruction_; } + HInstruction* GetLastInstruction() const { return last_instruction_; } void AddSuccessor(HBasicBlock* block) { successors_.Add(block); @@ -205,8 +205,8 @@ class HUseListNode : public ArenaObject { HUseListNode(HInstruction* instruction, HUseListNode* tail) : instruction_(instruction), tail_(tail) { } - HUseListNode* tail() const { return tail_; } - HInstruction* instruction() const { return instruction_; } + HUseListNode* GetTail() const { return tail_; } + HInstruction* GetInstruction() const { return instruction_; } private: HInstruction* const instruction_; @@ -227,11 +227,11 @@ class HInstruction : public ArenaObject { virtual ~HInstruction() { } - HInstruction* next() const { return next_; } - HInstruction* previous() const { return previous_; } + HInstruction* GetNext() const { return next_; } + HInstruction* GetPrevious() const { return previous_; } - HBasicBlock* block() const { return block_; } - void set_block(HBasicBlock* block) { block_ = block; } + HBasicBlock* GetBlock() const { return block_; } + void SetBlock(HBasicBlock* block) { block_ = block; } virtual intptr_t InputCount() const = 0; virtual HInstruction* InputAt(intptr_t i) const = 0; @@ -240,18 +240,18 @@ class HInstruction : public ArenaObject { virtual const char* DebugName() const = 0; void AddUse(HInstruction* user) { - uses_ = new (block_->graph()->arena()) HUseListNode(user, uses_); + uses_ = new (block_->GetGraph()->GetArena()) HUseListNode(user, uses_); } - HUseListNode* uses() const { return uses_; } + HUseListNode* GetUses() const { return uses_; } bool HasUses() const { return uses_ != nullptr; } - int id() const { return id_; } - void set_id(int id) { id_ = id; } + int GetId() const { return id_; } + void SetId(int id) { id_ = id; } - LocationSummary* locations() const { return locations_; } - void set_locations(LocationSummary* locations) { locations_ = locations; } + LocationSummary* GetLocations() const { return locations_; } + void SetLocations(LocationSummary* locations) { locations_ = locations; } #define INSTRUCTION_TYPE_CHECK(type) \ virtual H##type* As##type() { return nullptr; } @@ -281,18 +281,18 @@ class HInstruction : public ArenaObject { class HUseIterator : public ValueObject { public: - explicit HUseIterator(HInstruction* instruction) : current_(instruction->uses()) { } + explicit HUseIterator(HInstruction* instruction) : current_(instruction->GetUses()) { } bool Done() const { return current_ == nullptr; } void Advance() { DCHECK(!Done()); - current_ = current_->tail(); + current_ = current_->GetTail(); } HInstruction* Current() const { DCHECK(!Done()); - return current_->instruction(); + return current_->GetInstruction(); } private: @@ -319,15 +319,15 @@ class HInputIterator : public ValueObject { class HInstructionIterator : public ValueObject { public: explicit HInstructionIterator(HBasicBlock* block) - : instruction_(block->first_instruction()) { - next_ = Done() ? nullptr : instruction_->next(); + : instruction_(block->GetFirstInstruction()) { + next_ = Done() ? nullptr : instruction_->GetNext(); } bool Done() const { return instruction_ == nullptr; } HInstruction* Current() const { return instruction_; } void Advance() { instruction_ = next_; - next_ = Done() ? nullptr : instruction_->next(); + next_ = Done() ? nullptr : instruction_->GetNext(); } private: @@ -342,15 +342,15 @@ class EmbeddedArray { public: EmbeddedArray() : elements_() { } - intptr_t length() const { return N; } + intptr_t GetLength() const { return N; } const T& operator[](intptr_t i) const { - DCHECK_LT(i, length()); + DCHECK_LT(i, GetLength()); return elements_[i]; } T& operator[](intptr_t i) { - DCHECK_LT(i, length()); + DCHECK_LT(i, GetLength()); return elements_[i]; } @@ -445,7 +445,7 @@ class HGoto : public HTemplateInstruction<0> { HGoto() { } HBasicBlock* GetSuccessor() const { - return block()->successors()->Get(0); + return GetBlock()->GetSuccessors()->Get(0); } DECLARE_INSTRUCTION(Goto) @@ -463,11 +463,11 @@ class HIf : public HTemplateInstruction<1> { } HBasicBlock* IfTrueSuccessor() const { - return block()->successors()->Get(0); + return GetBlock()->GetSuccessors()->Get(0); } HBasicBlock* IfFalseSuccessor() const { - return block()->successors()->Get(1); + return GetBlock()->GetSuccessors()->Get(1); } DECLARE_INSTRUCTION(If) @@ -497,7 +497,7 @@ class HLocal : public HTemplateInstruction<0> { DECLARE_INSTRUCTION(Local) - uint16_t reg_number() const { return reg_number_; } + uint16_t GetRegNumber() const { return reg_number_; } private: // The Dex register number. @@ -544,7 +544,7 @@ class HIntConstant : public HTemplateInstruction<0> { public: explicit HIntConstant(int32_t value) : value_(value) { } - int32_t value() const { return value_; } + int32_t GetValue() const { return value_; } DECLARE_INSTRUCTION(IntConstant) @@ -564,7 +564,7 @@ class HGraphVisitor : public ValueObject { void VisitInsertionOrder(); - HGraph* graph() const { return graph_; } + HGraph* GetGraph() const { return graph_; } // Visit functions for instruction classes. #define DECLARE_VISIT_INSTRUCTION(name) \ diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 73323a4..cc36bbe 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -14,10 +14,41 @@ * limitations under the License. */ +#include <stdint.h> + +#include "builder.h" +#include "code_generator.h" #include "compilers.h" +#include "driver/compiler_driver.h" +#include "nodes.h" +#include "utils/arena_allocator.h" namespace art { +/** + * Used by the code generator, to allocate the code in a vector. + */ +class CodeVectorAllocator FINAL : public CodeAllocator { + public: + CodeVectorAllocator() { } + + virtual uint8_t* Allocate(size_t size) { + size_ = size; + memory_.reserve(size); + return &memory_[0]; + } + + size_t GetSize() const { return size_; } + std::vector<uint8_t>* GetMemory() { return &memory_; } + + private: + std::vector<uint8_t> memory_; + size_t size_; + + DISALLOW_COPY_AND_ASSIGN(CodeVectorAllocator); +}; + + CompiledMethod* OptimizingCompiler::TryCompile(CompilerDriver& driver, const DexFile::CodeItem* code_item, uint32_t access_flags, @@ -26,7 +57,40 @@ CompiledMethod* OptimizingCompiler::TryCompile(CompilerDriver& driver, uint32_t method_idx, jobject class_loader, const DexFile& dex_file) const { - return nullptr; + ArenaPool pool; + ArenaAllocator arena(&pool); + HGraphBuilder builder(&arena); + HGraph* graph = builder.BuildGraph(*code_item); + if (graph == nullptr) { + return nullptr; + } + + InstructionSet instruction_set = driver.GetInstructionSet(); + CodeGenerator* codegen = CodeGenerator::Create(&arena, graph, instruction_set); + if (codegen == nullptr) { + return nullptr; + } + + CodeVectorAllocator allocator; + codegen->Compile(&allocator); + + std::vector<uint8_t> mapping_table; + codegen->BuildMappingTable(&mapping_table); + std::vector<uint8_t> vmap_table; + codegen->BuildVMapTable(&vmap_table); + std::vector<uint8_t> gc_map; + codegen->BuildNativeGCMap(&gc_map); + + return new CompiledMethod(driver, + instruction_set, + *allocator.GetMemory(), + codegen->GetFrameSize(), + 0, /* GPR spill mask, unused */ + 0, /* FPR spill mask, unused */ + mapping_table, + vmap_table, + gc_map, + nullptr); } } // namespace art diff --git a/compiler/optimizing/pretty_printer.h b/compiler/optimizing/pretty_printer.h index 0c0f702..606c915 100644 --- a/compiler/optimizing/pretty_printer.h +++ b/compiler/optimizing/pretty_printer.h @@ -27,7 +27,7 @@ class HPrettyPrinter : public HGraphVisitor { virtual void VisitInstruction(HInstruction* instruction) { PrintString(" "); - PrintInt(instruction->id()); + PrintInt(instruction->GetId()); PrintString(": "); PrintString(instruction->DebugName()); if (instruction->InputCount() != 0) { @@ -39,7 +39,7 @@ class HPrettyPrinter : public HGraphVisitor { } else { PrintString(", "); } - PrintInt(it.Current()->id()); + PrintInt(it.Current()->GetId()); } PrintString(")"); } @@ -52,7 +52,7 @@ class HPrettyPrinter : public HGraphVisitor { } else { PrintString(", "); } - PrintInt(it.Current()->id()); + PrintInt(it.Current()->GetId()); } PrintString("]"); } @@ -61,24 +61,24 @@ class HPrettyPrinter : public HGraphVisitor { virtual void VisitBasicBlock(HBasicBlock* block) { PrintString("BasicBlock "); - PrintInt(block->block_id()); - const GrowableArray<HBasicBlock*>* blocks = block->predecessors(); + PrintInt(block->GetBlockId()); + const GrowableArray<HBasicBlock*>* blocks = block->GetPredecessors(); if (!blocks->IsEmpty()) { PrintString(", pred: "); for (size_t i = 0; i < blocks->Size() -1; i++) { - PrintInt(blocks->Get(i)->block_id()); + PrintInt(blocks->Get(i)->GetBlockId()); PrintString(", "); } - PrintInt(blocks->Peek()->block_id()); + PrintInt(blocks->Peek()->GetBlockId()); } - blocks = block->successors(); + blocks = block->GetSuccessors(); if (!blocks->IsEmpty()) { PrintString(", succ: "); for (size_t i = 0; i < blocks->Size() - 1; i++) { - PrintInt(blocks->Get(i)->block_id()); + PrintInt(blocks->Get(i)->GetBlockId()); PrintString(", "); } - PrintInt(blocks->Peek()->block_id()); + PrintInt(blocks->Peek()->GetBlockId()); } PrintNewLine(); HGraphVisitor::VisitBasicBlock(block); diff --git a/compiler/optimizing/pretty_printer_test.cc b/compiler/optimizing/pretty_printer_test.cc index b99370d..04db7a6 100644 --- a/compiler/optimizing/pretty_printer_test.cc +++ b/compiler/optimizing/pretty_printer_test.cc @@ -55,9 +55,9 @@ class StringPrettyPrinter : public HPrettyPrinter { virtual void VisitGoto(HGoto* gota) { PrintString(" "); - PrintInt(gota->id()); + PrintInt(gota->GetId()); PrintString(": Goto "); - PrintInt(current_block_->successors()->Get(0)->block_id()); + PrintInt(current_block_->GetSuccessors()->Get(0)->GetBlockId()); PrintNewLine(); } |