Optimize leaf methods.
Avoid suspend checks and stack changes when not needed.
Change-Id: I0fdb31e8c631e99091b818874a558c9aa04b1628
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index fd4e391..d0739a6 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -41,8 +41,6 @@
}
void CodeGenerator::CompileBaseline(CodeAllocator* allocator, bool is_leaf) {
- DCHECK_EQ(frame_size_, kUninitializedFrameSize);
-
Initialize();
if (!is_leaf) {
MarkNotLeaf();
@@ -59,7 +57,6 @@
}
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 @@
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::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 @@
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::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::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)