diff options
author | 2014-06-04 11:12:39 +0100 | |
---|---|---|
committer | 2014-06-12 10:02:06 +0100 | |
commit | 86dbb9a12119273039ce272b41c809fa548b37b6 (patch) | |
tree | a4626e21ae16a9a5e133ea3e5e95b58d2ea4d8e5 /compiler/optimizing/code_generator.cc | |
parent | c936622863a50bdda9b10062515dfc02a8c8b652 (diff) |
Final CL to enable register allocation on x86.
This CL implements:
1) Resolution after allocation: connecting the locations
allocated to an interval within a block and between blocks.
2) Handling of fixed registers: some instructions require
inputs/output to be at a specific location, and the allocator
needs to deal with them in a special way.
3) ParallelMoveResolver::EmitNativeCode for x86.
Change-Id: I0da6bd7eb66877987148b87c3be6a983b4e3f858
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index beafbcc386..f05cb66aba 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -29,30 +29,60 @@ namespace art { -void CodeGenerator::Compile(CodeAllocator* allocator) { +void CodeGenerator::CompileBaseline(CodeAllocator* allocator) { const GrowableArray<HBasicBlock*>& blocks = GetGraph()->GetBlocks(); DCHECK(blocks.Get(0) == GetGraph()->GetEntryBlock()); DCHECK(GoesToNextBlock(GetGraph()->GetEntryBlock(), blocks.Get(1))); + block_labels_.SetSize(blocks.Size()); + + DCHECK_EQ(frame_size_, kUninitializedFrameSize); + ComputeFrameSize(GetGraph()->GetMaximumNumberOfOutVRegs() + + GetGraph()->GetNumberOfVRegs() + + 1 /* filler */); GenerateFrameEntry(); + for (size_t i = 0, e = blocks.Size(); i < e; ++i) { - CompileBlock(blocks.Get(i)); + HBasicBlock* block = blocks.Get(i); + Bind(GetLabelOf(block)); + HGraphVisitor* location_builder = GetLocationBuilder(); + HGraphVisitor* instruction_visitor = GetInstructionVisitor(); + for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { + HInstruction* current = it.Current(); + current->Accept(location_builder); + InitLocations(current); + current->Accept(instruction_visitor); + } } + size_t code_size = GetAssembler()->CodeSize(); uint8_t* buffer = allocator->Allocate(code_size); MemoryRegion code(buffer, code_size); GetAssembler()->FinalizeInstructions(code); } -void CodeGenerator::CompileBlock(HBasicBlock* block) { - Bind(GetLabelOf(block)); - HGraphVisitor* location_builder = GetLocationBuilder(); - HGraphVisitor* instruction_visitor = GetInstructionVisitor(); - for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { - HInstruction* current = it.Current(); - current->Accept(location_builder); - InitLocations(current); - current->Accept(instruction_visitor); +void CodeGenerator::CompileOptimized(CodeAllocator* allocator) { + // The frame size has already been computed during register allocation. + DCHECK_NE(frame_size_, kUninitializedFrameSize); + const GrowableArray<HBasicBlock*>& blocks = GetGraph()->GetBlocks(); + DCHECK(blocks.Get(0) == GetGraph()->GetEntryBlock()); + DCHECK(GoesToNextBlock(GetGraph()->GetEntryBlock(), blocks.Get(1))); + block_labels_.SetSize(blocks.Size()); + + GenerateFrameEntry(); + for (size_t i = 0, e = blocks.Size(); i < e; ++i) { + HBasicBlock* block = blocks.Get(i); + Bind(GetLabelOf(block)); + HGraphVisitor* instruction_visitor = GetInstructionVisitor(); + for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { + HInstruction* current = it.Current(); + current->Accept(instruction_visitor); + } } + + size_t code_size = GetAssembler()->CodeSize(); + uint8_t* buffer = allocator->Allocate(code_size); + MemoryRegion code(buffer, code_size); + GetAssembler()->FinalizeInstructions(code); } size_t CodeGenerator::AllocateFreeRegisterInternal( |