From bab4ed7057799a4fadc6283108ab56f389d117d4 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Tue, 11 Mar 2014 17:53:17 +0000 Subject: 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 --- compiler/optimizing/code_generator.cc | 51 ++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'compiler/optimizing/code_generator.cc') diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 01fc23b50c..56342aa684 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -26,9 +26,11 @@ namespace art { void CodeGenerator::Compile(CodeAllocator* allocator) { - GenerateFrameEntry(); const GrowableArray* blocks = graph()->blocks(); - for (size_t i = 0; i < blocks->Size(); i++) { + DCHECK(blocks->Get(0) == graph()->entry_block()); + DCHECK(GoesToNextBlock(graph()->entry_block(), blocks->Get(1))); + CompileEntryBlock(); + for (size_t i = 1; i < blocks->Size(); i++) { CompileBlock(blocks->Get(i)); } size_t code_size = assembler_->CodeSize(); @@ -37,17 +39,54 @@ void CodeGenerator::Compile(CodeAllocator* allocator) { assembler_->FinalizeInstructions(code); } +void CodeGenerator::CompileEntryBlock() { + HGraphVisitor* location_builder = GetLocationBuilder(); + // 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()) { + HInstruction* current = it.Current(); + // Instructions in the entry block should not generate code. + if (kIsDebugBuild) { + current->Accept(location_builder); + DCHECK(current->locations() == nullptr); + } + current->Accept(this); + } + GenerateFrameEntry(); +} + void CodeGenerator::CompileBlock(HBasicBlock* block) { Bind(GetLabelOf(block)); + HGraphVisitor* location_builder = GetLocationBuilder(); for (HInstructionIterator it(block); !it.Done(); it.Advance()) { - it.Current()->Accept(this); + // 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 + // we do not perform any code motion, and the Dex format does not reference individual + // instructions but uses registers instead (our equivalent of HLocal). + 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()); + } + } +} + +void CodeGenerator::InitLocations(HInstruction* instruction) { + if (instruction->locations() == nullptr) return; + for (int i = 0; i < instruction->InputCount(); i++) { + Location location = instruction->locations()->InAt(i); + if (location.IsValid()) { + // Move the input to the desired location. + Move(instruction->InputAt(i), location); + } } } -bool CodeGenerator::GoesToNextBlock(HGoto* goto_instruction) const { - HBasicBlock* successor = goto_instruction->GetSuccessor(); +bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const { // We currently iterate over the block in insertion order. - return goto_instruction->block()->block_id() + 1 == successor->block_id(); + return current->block_id() + 1 == next->block_id(); } Label* CodeGenerator::GetLabelOf(HBasicBlock* block) const { -- cgit v1.2.3-59-g8ed1b