From 787c3076635cf117eb646c5a89a9014b2072fb44 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Mon, 17 Mar 2014 10:20:19 +0000 Subject: Plug new optimizing compiler in compilation pipeline. Also rename accessors to ART's conventions. Change-Id: I344807055b98aa4b27215704ec362191464acecc --- compiler/optimizing/builder.cc | 8 +-- compiler/optimizing/code_generator.cc | 53 ++++++++--------- compiler/optimizing/code_generator.h | 55 +++++++++-------- compiler/optimizing/code_generator_arm.cc | 92 ++++++++++++++-------------- compiler/optimizing/code_generator_arm.h | 38 ++++++++++-- compiler/optimizing/code_generator_x86.cc | 96 +++++++++++++++--------------- compiler/optimizing/code_generator_x86.h | 36 ++++++++++- compiler/optimizing/codegen_test.cc | 26 ++++---- compiler/optimizing/dominator_test.cc | 8 +-- compiler/optimizing/nodes.cc | 51 ++++++++-------- compiler/optimizing/nodes.h | 92 ++++++++++++++-------------- compiler/optimizing/optimizing_compiler.cc | 66 +++++++++++++++++++- compiler/optimizing/pretty_printer.h | 20 +++---- 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* blocks = graph()->blocks(); - DCHECK(blocks->Get(0) == graph()->entry_block()); - DCHECK(GoesToNextBlock(graph()->entry_block(), blocks->Get(1))); + const GrowableArray* 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* vector) const { } + void BuildVMapTable(std::vector* vector) const { } + void BuildNativeGCMap(std::vector* 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