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