diff options
author | 2015-02-06 14:35:25 +0000 | |
---|---|---|
committer | 2015-02-06 17:37:57 +0000 | |
commit | c0572a451944f78397619dec34a38c36c11e9d2a (patch) | |
tree | 2cc6f3c6f5ad45b4b85fb62627e797fe7e7734e1 /compiler/optimizing/code_generator.cc | |
parent | 0f2433bfcb02a662fe739e8e2b068abc2958e4c1 (diff) |
Optimize leaf methods.
Avoid suspend checks and stack changes when not needed.
Change-Id: I0fdb31e8c631e99091b818874a558c9aa04b1628
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index fd4e391470..d0739a6de2 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -41,8 +41,6 @@ size_t CodeGenerator::GetCacheOffset(uint32_t index) { } void CodeGenerator::CompileBaseline(CodeAllocator* allocator, bool is_leaf) { - DCHECK_EQ(frame_size_, kUninitializedFrameSize); - Initialize(); if (!is_leaf) { MarkNotLeaf(); @@ -59,7 +57,6 @@ void CodeGenerator::CompileBaseline(CodeAllocator* allocator, bool is_leaf) { } void CodeGenerator::CompileInternal(CodeAllocator* allocator, bool is_baseline) { - HGraphVisitor* location_builder = GetLocationBuilder(); HGraphVisitor* instruction_visitor = GetInstructionVisitor(); DCHECK_EQ(current_block_index_, 0u); GenerateFrameEntry(); @@ -69,8 +66,7 @@ void CodeGenerator::CompileInternal(CodeAllocator* allocator, bool is_baseline) for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { HInstruction* current = it.Current(); if (is_baseline) { - current->Accept(location_builder); - InitLocations(current); + InitLocationsBaseline(current); } current->Accept(instruction_visitor); } @@ -88,7 +84,6 @@ void CodeGenerator::CompileInternal(CodeAllocator* allocator, bool is_baseline) void CodeGenerator::CompileOptimized(CodeAllocator* allocator) { // The register allocator already called `InitializeCodeGeneration`, // where the frame size has been computed. - DCHECK_NE(frame_size_, kUninitializedFrameSize); DCHECK(block_order_ != nullptr); Initialize(); CompileInternal(allocator, /* is_baseline */ false); @@ -138,13 +133,22 @@ void CodeGenerator::InitializeCodeGeneration(size_t number_of_spill_slots, ComputeSpillMask(); first_register_slot_in_slow_path_ = (number_of_out_slots + number_of_spill_slots) * kVRegSize; - SetFrameSize(RoundUp( - number_of_spill_slots * kVRegSize - + number_of_out_slots * kVRegSize - + maximum_number_of_live_core_registers * GetWordSize() - + maximum_number_of_live_fp_registers * GetFloatingPointSpillSlotSize() - + FrameEntrySpillSize(), - kStackAlignment)); + if (number_of_spill_slots == 0 + && !HasAllocatedCalleeSaveRegisters() + && IsLeafMethod() + && !RequiresCurrentMethod()) { + DCHECK_EQ(maximum_number_of_live_core_registers, 0u); + DCHECK_EQ(maximum_number_of_live_fp_registers, 0u); + SetFrameSize(CallPushesPC() ? GetWordSize() : 0); + } else { + SetFrameSize(RoundUp( + number_of_spill_slots * kVRegSize + + number_of_out_slots * kVRegSize + + maximum_number_of_live_core_registers * GetWordSize() + + maximum_number_of_live_fp_registers * GetFloatingPointSpillSlotSize() + + FrameEntrySpillSize(), + kStackAlignment)); + } } Location CodeGenerator::GetTemporaryLocation(HTemporary* temp) const { @@ -294,7 +298,8 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { } } -void CodeGenerator::InitLocations(HInstruction* instruction) { +void CodeGenerator::InitLocationsBaseline(HInstruction* instruction) { + AllocateLocations(instruction); if (instruction->GetLocations() == nullptr) { if (instruction->IsTemporary()) { HInstruction* previous = instruction->GetPrevious(); @@ -320,6 +325,19 @@ void CodeGenerator::InitLocations(HInstruction* instruction) { } } +void CodeGenerator::AllocateLocations(HInstruction* instruction) { + instruction->Accept(GetLocationBuilder()); + LocationSummary* locations = instruction->GetLocations(); + if (!instruction->IsSuspendCheckEntry()) { + if (locations != nullptr && locations->CanCall()) { + MarkNotLeaf(); + } + if (instruction->NeedsCurrentMethod()) { + SetRequiresCurrentMethod(); + } + } +} + bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const { DCHECK_EQ(block_order_->Get(current_block_index_), current); return (current_block_index_ < block_order_->Size() - 1) |