Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/compiler/frame-elider.cc

Issue 1053123006: Calculate blocks needing a frame and frame (de)construction sites. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added missing files Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/frame-elider.h ('k') | src/compiler/instruction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « src/compiler/frame-elider.h ('k') | src/compiler/instruction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698