Mark instruction blocks with spills (for frame elision).
authorsvenpanne <svenpanne@chromium.org>
Thu, 30 Apr 2015 14:49:32 +0000 (07:49 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 30 Apr 2015 14:49:36 +0000 (14:49 +0000)
Review URL: https://codereview.chromium.org/1119683002

Cr-Commit-Position: refs/heads/master@{#28171}

src/compiler/frame-elider.cc
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/pipeline.cc
src/compiler/register-allocator.cc
src/compiler/register-allocator.h

index 1263c3f..1168467 100644 (file)
@@ -20,6 +20,7 @@ void FrameElider::Run() {
 
 void FrameElider::MarkBlocks() {
   for (auto block : instruction_blocks()) {
+    if (block->needs_frame()) continue;
     for (auto i = block->code_start(); i < block->code_end(); ++i) {
       if (InstructionAt(i)->IsCall()) {
         block->mark_needs_frame();
index 1773f06..cea74a7 100644 (file)
@@ -559,7 +559,7 @@ int InstructionSequence::AddInstruction(Instruction* instr) {
 }
 
 
-const InstructionBlock* InstructionSequence::GetInstructionBlock(
+InstructionBlock* InstructionSequence::GetInstructionBlock(
     int instruction_index) const {
   DCHECK(instruction_blocks_->size() == block_starts_.size());
   auto begin = block_starts_.begin();
@@ -760,6 +760,9 @@ std::ostream& operator<<(std::ostream& os,
     os << "B" << block->rpo_number();
     os << ": AO#" << block->ao_number();
     if (block->IsDeferred()) os << " (deferred)";
+    if (!block->needs_frame()) os << " (no frame)";
+    if (block->must_construct_frame()) os << " (construct frame)";
+    if (block->must_deconstruct_frame()) os << " (deconstruct frame)";
     if (block->IsLoopHeader()) {
       os << " loop blocks: [" << block->rpo_number() << ", "
          << block->loop_end() << ")";
index 637f03c..39fdb2a 100644 (file)
@@ -1052,7 +1052,7 @@ class InstructionSequence final : public ZoneObject {
     return instruction_blocks_->at(rpo_number.ToSize());
   }
 
-  const InstructionBlock* GetInstructionBlock(int instruction_index) const;
+  InstructionBlock* GetInstructionBlock(int instruction_index) const;
 
   static MachineType DefaultRepresentation() {
     return kPointerSize == 8 ? kRepWord64 : kRepWord32;
index 92a0be6..fd8843f 100644 (file)
@@ -779,6 +779,16 @@ struct AllocateDoubleRegistersPhase {
 };
 
 
+struct LocateSpillSlotsPhase {
+  static const char* phase_name() { return "locate spill slots"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SpillSlotLocator locator(data->register_allocation_data());
+    locator.LocateSpillSlots();
+  }
+};
+
+
 struct AssignSpillSlotsPhase {
   static const char* phase_name() { return "assign spill slots"; }
 
@@ -1200,10 +1210,6 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
     return Handle<Code>();
   }
 
-  if (FLAG_turbo_frame_elision) {
-    Run<FrameElisionPhase>();
-  }
-
   BeginPhaseKind("code generation");
 
   // Optimimize jumps.
@@ -1299,6 +1305,12 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
     Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
     Run<AllocateDoubleRegistersPhase<LinearScanAllocator>>();
   }
+
+  if (FLAG_turbo_frame_elision) {
+    Run<LocateSpillSlotsPhase>();
+    Run<FrameElisionPhase>();
+  }
+
   Run<AssignSpillSlotsPhase>();
 
   Run<CommitAssignmentPhase>();
index 1ba456b..0d22346 100644 (file)
@@ -2694,6 +2694,25 @@ bool GreedyAllocator::AllocateBlockedRange(
 }
 
 
+SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
+    : data_(data) {}
+
+
+void SpillSlotLocator::LocateSpillSlots() {
+  auto code = data()->code();
+  for (auto range : data()->live_ranges()) {
+    if (range == nullptr || range->IsEmpty() || range->IsChild()) continue;
+    // We care only about ranges which spill in the frame.
+    if (!range->HasSpillRange()) continue;
+    auto spills = range->spills_at_definition();
+    DCHECK_NOT_NULL(spills);
+    for (; spills != nullptr; spills = spills->next) {
+      code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
+    }
+  }
+}
+
+
 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
 
 
index 16284a2..163dd2c 100644 (file)
@@ -418,9 +418,13 @@ class LiveRange final : public ZoneObject {
   void SetUseHints(int register_index);
   void UnsetUseHints() { SetUseHints(kUnassignedRegister); }
 
- private:
   struct SpillAtDefinitionList;
 
+  SpillAtDefinitionList* spills_at_definition() const {
+    return spills_at_definition_;
+  }
+
+ private:
   void set_spill_type(SpillType value) {
     bits_ = SpillTypeField::update(bits_, value);
   }
@@ -863,6 +867,21 @@ class GreedyAllocator final : public RegisterAllocator {
 };
 
 
+class SpillSlotLocator final : public ZoneObject {
+ public:
+  explicit SpillSlotLocator(RegisterAllocationData* data);
+
+  void LocateSpillSlots();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpillSlotLocator);
+};
+
+
 class OperandAssigner final : public ZoneObject {
  public:
   explicit OperandAssigner(RegisterAllocationData* data);