frame-elider.cc revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/frame-elider.h" 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler { 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFrameElider::FrameElider(InstructionSequence* code) : code_(code) {} 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FrameElider::Run() { 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MarkBlocks(); 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropagateMarks(); 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MarkDeConstruction(); 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FrameElider::MarkBlocks() { 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto block : instruction_blocks()) { 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->needs_frame()) continue; 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto i = block->code_start(); i < block->code_end(); ++i) { 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (InstructionAt(i)->IsCall() || 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionAt(i)->opcode() == ArchOpcode::kArchDeoptimize) { 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->mark_needs_frame(); 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FrameElider::PropagateMarks() { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (PropagateInOrder() && PropagateReversed()) { 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FrameElider::MarkDeConstruction() { 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto block : instruction_blocks()) { 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->needs_frame()) { 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Special case: The start block needs a frame. 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->predecessors().empty()) { 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->mark_must_construct_frame(); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find "frame -> no frame" transitions, inserting frame 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // deconstructions. 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto succ : block->successors()) { 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!InstructionBlockAt(succ)->needs_frame()) { 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1U, block->SuccessorCount()); 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->mark_must_deconstruct_frame(); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find "no frame -> frame" transitions, inserting frame constructions. 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto succ : block->successors()) { 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (InstructionBlockAt(succ)->needs_frame()) { 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(1U, block->SuccessorCount()); 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionBlockAt(succ)->mark_must_construct_frame(); 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool FrameElider::PropagateInOrder() { 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool changed = false; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto block : instruction_blocks()) { 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch changed |= PropagateIntoBlock(block); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return changed; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool FrameElider::PropagateReversed() { 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool changed = false; 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto block : base::Reversed(instruction_blocks())) { 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch changed |= PropagateIntoBlock(block); 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return changed; 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool FrameElider::PropagateIntoBlock(InstructionBlock* block) { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Already marked, nothing to do... 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->needs_frame()) return false; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Never mark the dummy end node, otherwise we might incorrectly decide to 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // put frame deconstruction code there later, 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (block->successors().empty()) return false; 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Propagate towards the end ("downwards") if there is a predecessor needing 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a frame, but don't "bleed" from deferred code to non-deferred code. 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto pred : block->predecessors()) { 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (InstructionBlockAt(pred)->needs_frame() && 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (!InstructionBlockAt(pred)->IsDeferred() || block->IsDeferred())) { 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->mark_needs_frame(); 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Propagate towards start ("upwards") if there are successors and all of 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // them need a frame. 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto succ : block->successors()) { 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!InstructionBlockAt(succ)->needs_frame()) return false; 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch block->mark_needs_frame(); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlocks& FrameElider::instruction_blocks() const { 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code_->instruction_blocks(); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionBlock* FrameElider::InstructionBlockAt(RpoNumber rpo_number) const { 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code_->InstructionBlockAt(rpo_number); 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction* FrameElider::InstructionAt(int index) const { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code_->InstructionAt(index); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace compiler 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 132