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)