OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/frame-elider.h" |
| 7 |
| 8 namespace v8 { |
| 9 namespace internal { |
| 10 namespace compiler { |
| 11 |
| 12 FrameElider::FrameElider(InstructionSequence* code) : code_(code) {} |
| 13 |
| 14 void FrameElider::Run() { |
| 15 MarkBlocks(); |
| 16 PropagateMarks(); |
| 17 MarkDeConstruction(); |
| 18 } |
| 19 |
| 20 |
| 21 void FrameElider::MarkBlocks() { |
| 22 for (auto block : instruction_blocks()) { |
| 23 for (auto i = block->code_start(); i < block->code_end(); ++i) { |
| 24 if (InstructionAt(i)->IsCall()) { |
| 25 block->mark_needs_frame(); |
| 26 break; |
| 27 } |
| 28 } |
| 29 } |
| 30 } |
| 31 |
| 32 |
| 33 void FrameElider::PropagateMarks() { |
| 34 while (PropagateInOrder() && PropagateReversed()) { |
| 35 } |
| 36 } |
| 37 |
| 38 |
| 39 void FrameElider::MarkDeConstruction() { |
| 40 for (auto block : instruction_blocks()) { |
| 41 if (block->needs_frame()) { |
| 42 // Special case: The start block needs a frame. |
| 43 if (block->predecessors().empty()) { |
| 44 block->mark_must_construct_frame(); |
| 45 } |
| 46 // Find "frame -> no frame" transitions, inserting frame |
| 47 // deconstructions. |
| 48 for (auto succ : block->successors()) { |
| 49 if (!InstructionBlockAt(succ)->needs_frame()) { |
| 50 DCHECK_EQ(1, block->SuccessorCount()); |
| 51 block->mark_must_deconstruct_frame(); |
| 52 } |
| 53 } |
| 54 } else { |
| 55 // Find "no frame -> frame" transitions, inserting frame constructions. |
| 56 for (auto succ : block->successors()) { |
| 57 if (InstructionBlockAt(succ)->needs_frame()) { |
| 58 DCHECK_NE(1, block->SuccessorCount()); |
| 59 InstructionBlockAt(succ)->mark_must_construct_frame(); |
| 60 } |
| 61 } |
| 62 } |
| 63 } |
| 64 } |
| 65 |
| 66 |
| 67 bool FrameElider::PropagateInOrder() { |
| 68 bool changed = false; |
| 69 for (auto block : instruction_blocks()) { |
| 70 changed |= PropagateIntoBlock(block); |
| 71 } |
| 72 return changed; |
| 73 } |
| 74 |
| 75 |
| 76 bool FrameElider::PropagateReversed() { |
| 77 bool changed = false; |
| 78 for (auto block : base::Reversed(instruction_blocks())) { |
| 79 changed |= PropagateIntoBlock(block); |
| 80 } |
| 81 return changed; |
| 82 } |
| 83 |
| 84 |
| 85 bool FrameElider::PropagateIntoBlock(InstructionBlock* block) { |
| 86 // Already marked, nothing to do... |
| 87 if (block->needs_frame()) return false; |
| 88 |
| 89 // Never mark the dummy end node, otherwise we might incorrectly decide to |
| 90 // put frame deconstruction code there later, |
| 91 if (block->successors().empty()) return false; |
| 92 |
| 93 // Propagate towards the end ("downwards") if there is a predecessor needing |
| 94 // a frame, but don't "bleed" from deferred code to non-deferred code. |
| 95 for (auto pred : block->predecessors()) { |
| 96 if (InstructionBlockAt(pred)->needs_frame() && |
| 97 (!InstructionBlockAt(pred)->IsDeferred() || block->IsDeferred())) { |
| 98 block->mark_needs_frame(); |
| 99 return true; |
| 100 } |
| 101 } |
| 102 |
| 103 // Propagate towards start ("upwards") if there are successors and all of |
| 104 // them need a frame. |
| 105 for (auto succ : block->successors()) { |
| 106 if (!InstructionBlockAt(succ)->needs_frame()) return false; |
| 107 } |
| 108 block->mark_needs_frame(); |
| 109 return true; |
| 110 } |
| 111 |
| 112 |
| 113 const InstructionBlocks& FrameElider::instruction_blocks() const { |
| 114 return code_->instruction_blocks(); |
| 115 } |
| 116 |
| 117 |
| 118 InstructionBlock* FrameElider::InstructionBlockAt(RpoNumber rpo_number) const { |
| 119 return code_->InstructionBlockAt(rpo_number); |
| 120 } |
| 121 |
| 122 |
| 123 Instruction* FrameElider::InstructionAt(int index) const { |
| 124 return code_->InstructionAt(index); |
| 125 } |
| 126 |
| 127 } // namespace compiler |
| 128 } // namespace internal |
| 129 } // namespace v8 |
OLD | NEW |