1 // Copyright 2013 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/compiler/control-builders.h"
6
7 #include "src/objects-inl.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12
13
If(Node * condition,BranchHint hint)14 void IfBuilder::If(Node* condition, BranchHint hint) {
15 builder_->NewBranch(condition, hint);
16 else_environment_ = environment()->CopyForConditional();
17 }
18
19
Then()20 void IfBuilder::Then() { builder_->NewIfTrue(); }
21
22
Else()23 void IfBuilder::Else() {
24 builder_->NewMerge();
25 then_environment_ = environment();
26 set_environment(else_environment_);
27 builder_->NewIfFalse();
28 }
29
30
End()31 void IfBuilder::End() {
32 then_environment_->Merge(environment());
33 set_environment(then_environment_);
34 }
35
36
BeginLoop(BitVector * assigned,bool is_osr)37 void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) {
38 loop_environment_ = environment()->CopyForLoop(assigned, is_osr);
39 continue_environment_ = environment()->CopyAsUnreachable();
40 break_environment_ = environment()->CopyAsUnreachable();
41 assigned_ = assigned;
42 }
43
44
Continue()45 void LoopBuilder::Continue() {
46 continue_environment_->Merge(environment());
47 environment()->MarkAsUnreachable();
48 }
49
50
Break()51 void LoopBuilder::Break() {
52 break_environment_->Merge(environment());
53 environment()->MarkAsUnreachable();
54 }
55
56
EndBody()57 void LoopBuilder::EndBody() {
58 continue_environment_->Merge(environment());
59 set_environment(continue_environment_);
60 }
61
62
EndLoop()63 void LoopBuilder::EndLoop() {
64 loop_environment_->Merge(environment());
65 set_environment(break_environment_);
66 ExitLoop();
67 }
68
69
BreakUnless(Node * condition)70 void LoopBuilder::BreakUnless(Node* condition) {
71 IfBuilder control_if(builder_);
72 control_if.If(condition);
73 control_if.Then();
74 control_if.Else();
75 Break();
76 control_if.End();
77 }
78
79
BreakWhen(Node * condition)80 void LoopBuilder::BreakWhen(Node* condition) {
81 IfBuilder control_if(builder_);
82 control_if.If(condition);
83 control_if.Then();
84 Break();
85 control_if.Else();
86 control_if.End();
87 }
88
ExitLoop(Node ** extra_value_to_rename)89 void LoopBuilder::ExitLoop(Node** extra_value_to_rename) {
90 if (extra_value_to_rename) {
91 environment()->Push(*extra_value_to_rename);
92 }
93 environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(),
94 assigned_);
95 if (extra_value_to_rename) {
96 *extra_value_to_rename = environment()->Pop();
97 }
98 }
99
BeginSwitch()100 void SwitchBuilder::BeginSwitch() {
101 body_environment_ = environment()->CopyAsUnreachable();
102 label_environment_ = environment()->CopyAsUnreachable();
103 break_environment_ = environment()->CopyAsUnreachable();
104 }
105
106
BeginLabel(int index,Node * condition)107 void SwitchBuilder::BeginLabel(int index, Node* condition) {
108 builder_->NewBranch(condition);
109 label_environment_ = environment()->CopyForConditional();
110 builder_->NewIfTrue();
111 body_environments_[index] = environment();
112 }
113
114
EndLabel()115 void SwitchBuilder::EndLabel() {
116 set_environment(label_environment_);
117 builder_->NewIfFalse();
118 }
119
120
DefaultAt(int index)121 void SwitchBuilder::DefaultAt(int index) {
122 label_environment_ = environment()->CopyAsUnreachable();
123 body_environments_[index] = environment();
124 }
125
126
BeginCase(int index)127 void SwitchBuilder::BeginCase(int index) {
128 set_environment(body_environments_[index]);
129 environment()->Merge(body_environment_);
130 }
131
132
Break()133 void SwitchBuilder::Break() {
134 break_environment_->Merge(environment());
135 environment()->MarkAsUnreachable();
136 }
137
138
EndCase()139 void SwitchBuilder::EndCase() { body_environment_ = environment(); }
140
141
EndSwitch()142 void SwitchBuilder::EndSwitch() {
143 break_environment_->Merge(label_environment_);
144 break_environment_->Merge(environment());
145 set_environment(break_environment_);
146 }
147
148
BeginBlock()149 void BlockBuilder::BeginBlock() {
150 break_environment_ = environment()->CopyAsUnreachable();
151 }
152
153
Break()154 void BlockBuilder::Break() {
155 break_environment_->Merge(environment());
156 environment()->MarkAsUnreachable();
157 }
158
159
BreakWhen(Node * condition,BranchHint hint)160 void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) {
161 IfBuilder control_if(builder_);
162 control_if.If(condition, hint);
163 control_if.Then();
164 Break();
165 control_if.Else();
166 control_if.End();
167 }
168
169
BreakUnless(Node * condition,BranchHint hint)170 void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) {
171 IfBuilder control_if(builder_);
172 control_if.If(condition, hint);
173 control_if.Then();
174 control_if.Else();
175 Break();
176 control_if.End();
177 }
178
179
EndBlock()180 void BlockBuilder::EndBlock() {
181 break_environment_->Merge(environment());
182 set_environment(break_environment_);
183 }
184
185 } // namespace compiler
186 } // namespace internal
187 } // namespace v8
188