OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
7 | 7 |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/compiler/all-nodes.h" |
9 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
10 #include "src/compiler/control-reducer.h" | 11 #include "src/compiler/control-reducer.h" |
11 #include "src/compiler/graph.h" | 12 #include "src/compiler/graph.h" |
12 #include "src/compiler/js-graph.h" | 13 #include "src/compiler/js-graph.h" |
13 #include "src/compiler/node-properties.h" | 14 #include "src/compiler/node-properties.h" |
14 | 15 |
15 using namespace v8::internal; | 16 using namespace v8::internal; |
16 using namespace v8::internal::compiler; | 17 using namespace v8::internal::compiler; |
17 | 18 |
18 static const size_t kNumLeafs = 4; | 19 static const size_t kNumLeafs = 4; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 } | 136 } |
136 return node; | 137 return node; |
137 } | 138 } |
138 | 139 |
139 const Operator* op(int count, bool effect) { | 140 const Operator* op(int count, bool effect) { |
140 return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count); | 141 return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count); |
141 } | 142 } |
142 | 143 |
143 void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); } | 144 void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); } |
144 | 145 |
145 void ReduceGraph() { | 146 void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); } |
146 ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common); | |
147 } | |
148 | 147 |
149 // Checks one-step reduction of a phi. | 148 // Checks one-step reduction of a phi. |
150 void ReducePhi(Node* expect, Node* phi) { | 149 void ReducePhi(Node* expect, Node* phi) { |
151 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, &common, phi); | 150 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi); |
152 CHECK_EQ(expect, result); | 151 CHECK_EQ(expect, result); |
153 ReducePhiIterative(expect, phi); // iterative should give the same result. | 152 ReducePhiIterative(expect, phi); // iterative should give the same result. |
154 } | 153 } |
155 | 154 |
156 // Checks one-step reduction of a phi. | 155 // Checks one-step reduction of a phi. |
157 void ReducePhiNonIterative(Node* expect, Node* phi) { | 156 void ReducePhiNonIterative(Node* expect, Node* phi) { |
158 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, &common, phi); | 157 Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi); |
159 CHECK_EQ(expect, result); | 158 CHECK_EQ(expect, result); |
160 } | 159 } |
161 | 160 |
162 void ReducePhiIterative(Node* expect, Node* phi) { | 161 void ReducePhiIterative(Node* expect, Node* phi) { |
163 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. | 162 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. |
164 Node* ret = graph.NewNode(common.Return(), phi, start, start); | 163 Node* ret = graph.NewNode(common.Return(), phi, start, start); |
165 Node* end = graph.NewNode(common.End(), ret); | 164 Node* end = graph.NewNode(common.End(), ret); |
166 graph.SetEnd(end); | 165 graph.SetEnd(end); |
167 ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common); | 166 ControlReducer::ReduceGraph(main_zone(), &jsgraph); |
168 CheckInputs(end, ret); | 167 CheckInputs(end, ret); |
169 CheckInputs(ret, expect, start, start); | 168 CheckInputs(ret, expect, start, start); |
170 } | 169 } |
171 | 170 |
172 void ReduceMerge(Node* expect, Node* merge) { | 171 void ReduceMerge(Node* expect, Node* merge) { |
173 Node* result = ControlReducer::ReduceMerge(&jsgraph, &common, merge); | 172 Node* result = ControlReducer::ReduceMerge(&jsgraph, merge); |
174 CHECK_EQ(expect, result); | 173 CHECK_EQ(expect, result); |
175 } | 174 } |
176 | 175 |
177 void ReduceMergeIterative(Node* expect, Node* merge) { | 176 void ReduceMergeIterative(Node* expect, Node* merge) { |
178 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. | 177 p0->ReplaceInput(0, start); // hack: parameters may be trimmed. |
179 Node* end = graph.NewNode(common.End(), merge); | 178 Node* end = graph.NewNode(common.End(), merge); |
180 graph.SetEnd(end); | 179 graph.SetEnd(end); |
181 ReduceGraph(); | 180 ReduceGraph(); |
182 CheckInputs(end, expect); | 181 CheckInputs(end, expect); |
183 } | 182 } |
184 | 183 |
185 void ReduceBranch(Decision expected, Node* branch) { | 184 void ReduceBranch(Decision expected, Node* branch) { |
186 Node* control = branch->InputAt(1); | 185 Node* control = branch->InputAt(1); |
187 for (Node* use : branch->uses()) { | 186 for (Node* use : branch->uses()) { |
188 if (use->opcode() == IrOpcode::kIfTrue) { | 187 if (use->opcode() == IrOpcode::kIfTrue) { |
189 Node* result = | 188 Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use); |
190 ControlReducer::ReduceIfNodeForTesting(&jsgraph, &common, use); | |
191 if (expected == kTrue) CHECK_EQ(control, result); | 189 if (expected == kTrue) CHECK_EQ(control, result); |
192 if (expected == kFalse) CHECK_EQ(IrOpcode::kDead, result->opcode()); | 190 if (expected == kFalse) CHECK_EQ(IrOpcode::kDead, result->opcode()); |
193 if (expected == kUnknown) CHECK_EQ(use, result); | 191 if (expected == kUnknown) CHECK_EQ(use, result); |
194 } else if (use->opcode() == IrOpcode::kIfFalse) { | 192 } else if (use->opcode() == IrOpcode::kIfFalse) { |
195 Node* result = | 193 Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use); |
196 ControlReducer::ReduceIfNodeForTesting(&jsgraph, &common, use); | |
197 if (expected == kFalse) CHECK_EQ(control, result); | 194 if (expected == kFalse) CHECK_EQ(control, result); |
198 if (expected == kTrue) CHECK_EQ(IrOpcode::kDead, result->opcode()); | 195 if (expected == kTrue) CHECK_EQ(IrOpcode::kDead, result->opcode()); |
199 if (expected == kUnknown) CHECK_EQ(use, result); | 196 if (expected == kUnknown) CHECK_EQ(use, result); |
200 } else { | 197 } else { |
201 UNREACHABLE(); | 198 UNREACHABLE(); |
202 } | 199 } |
203 } | 200 } |
204 } | 201 } |
205 | 202 |
206 Node* Return(Node* val, Node* effect, Node* control) { | 203 Node* Return(Node* val, Node* effect, Node* control) { |
207 Node* ret = graph.NewNode(common.Return(), val, effect, control); | 204 Node* ret = graph.NewNode(common.Return(), val, effect, control); |
208 end->ReplaceInput(0, ret); | 205 end->ReplaceInput(0, ret); |
209 return ret; | 206 return ret; |
210 } | 207 } |
211 }; | 208 }; |
212 | 209 |
213 | 210 |
| 211 struct Branch { |
| 212 Node* branch; |
| 213 Node* if_true; |
| 214 Node* if_false; |
| 215 |
| 216 Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) { |
| 217 if (control == NULL) control = R.start; |
| 218 branch = R.graph.NewNode(R.common.Branch(), cond, control); |
| 219 if_true = R.graph.NewNode(R.common.IfTrue(), branch); |
| 220 if_false = R.graph.NewNode(R.common.IfFalse(), branch); |
| 221 } |
| 222 }; |
| 223 |
| 224 |
| 225 // TODO(titzer): use the diamonds from src/compiler/diamond.h here. |
| 226 struct Diamond { |
| 227 Node* branch; |
| 228 Node* if_true; |
| 229 Node* if_false; |
| 230 Node* merge; |
| 231 Node* phi; |
| 232 |
| 233 Diamond(ControlReducerTester& R, Node* cond) { |
| 234 branch = R.graph.NewNode(R.common.Branch(), cond, R.start); |
| 235 if_true = R.graph.NewNode(R.common.IfTrue(), branch); |
| 236 if_false = R.graph.NewNode(R.common.IfFalse(), branch); |
| 237 merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false); |
| 238 phi = NULL; |
| 239 } |
| 240 |
| 241 Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) { |
| 242 branch = R.graph.NewNode(R.common.Branch(), cond, R.start); |
| 243 if_true = R.graph.NewNode(R.common.IfTrue(), branch); |
| 244 if_false = R.graph.NewNode(R.common.IfFalse(), branch); |
| 245 merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false); |
| 246 phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge); |
| 247 } |
| 248 |
| 249 void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); } |
| 250 |
| 251 // Nest {this} into either the if_true or if_false branch of {that}. |
| 252 void nest(Diamond& that, bool if_true) { |
| 253 if (if_true) { |
| 254 branch->ReplaceInput(1, that.if_true); |
| 255 that.merge->ReplaceInput(0, merge); |
| 256 } else { |
| 257 branch->ReplaceInput(1, that.if_false); |
| 258 that.merge->ReplaceInput(1, merge); |
| 259 } |
| 260 } |
| 261 }; |
| 262 |
| 263 |
| 264 struct While { |
| 265 Node* branch; |
| 266 Node* if_true; |
| 267 Node* exit; |
| 268 Node* loop; |
| 269 |
| 270 While(ControlReducerTester& R, Node* cond) { |
| 271 loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start); |
| 272 branch = R.graph.NewNode(R.common.Branch(), cond, loop); |
| 273 if_true = R.graph.NewNode(R.common.IfTrue(), branch); |
| 274 exit = R.graph.NewNode(R.common.IfFalse(), branch); |
| 275 loop->ReplaceInput(1, if_true); |
| 276 } |
| 277 |
| 278 void chain(Node* control) { loop->ReplaceInput(0, control); } |
| 279 }; |
| 280 |
| 281 |
| 282 // Helper for checking that nodes are *not* reachable from end. |
| 283 struct DeadChecker { |
| 284 Zone zone; |
| 285 AllNodes nodes; |
| 286 explicit DeadChecker(Graph* graph) : zone(), nodes(&zone, graph) {} |
| 287 |
| 288 void Check(Node* node) { CHECK(!nodes.IsLive(node)); } |
| 289 |
| 290 void Check(Diamond& d) { |
| 291 Check(d.branch); |
| 292 Check(d.if_true); |
| 293 Check(d.if_false); |
| 294 Check(d.merge); |
| 295 if (d.phi != NULL) Check(d.phi); |
| 296 } |
| 297 |
| 298 void CheckLive(Diamond& d, bool live_phi = true) { |
| 299 CheckInputs(d.merge, d.if_true, d.if_false); |
| 300 CheckInputs(d.if_true, d.branch); |
| 301 CheckInputs(d.if_false, d.branch); |
| 302 if (d.phi != NULL) { |
| 303 if (live_phi) { |
| 304 CHECK_EQ(3, d.phi->InputCount()); |
| 305 CHECK_EQ(d.merge, d.phi->InputAt(2)); |
| 306 } else { |
| 307 Check(d.phi); |
| 308 } |
| 309 } |
| 310 } |
| 311 }; |
| 312 |
| 313 |
214 TEST(Trim1_live) { | 314 TEST(Trim1_live) { |
215 ControlReducerTester T; | 315 ControlReducerTester T; |
216 CHECK(IsUsedBy(T.start, T.p0)); | 316 CHECK(IsUsedBy(T.start, T.p0)); |
217 T.graph.SetEnd(T.p0); | 317 T.graph.SetEnd(T.p0); |
218 T.Trim(); | 318 T.Trim(); |
219 CHECK(IsUsedBy(T.start, T.p0)); | 319 CHECK(IsUsedBy(T.start, T.p0)); |
220 CheckInputs(T.p0, T.start); | 320 CheckInputs(T.p0, T.start); |
221 } | 321 } |
222 | 322 |
223 | 323 |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 Node* phi_use = | 990 Node* phi_use = |
891 R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start); | 991 R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start); |
892 Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start); | 992 Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start); |
893 | 993 |
894 Selector selector(mask); | 994 Selector selector(mask); |
895 | 995 |
896 for (int i = 0; i < kSelectorSize; i++) { // set up dead merge inputs. | 996 for (int i = 0; i < kSelectorSize; i++) { // set up dead merge inputs. |
897 if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead); | 997 if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead); |
898 } | 998 } |
899 | 999 |
900 Node* result = ControlReducer::ReduceMerge(&R.jsgraph, &R.common, merge); | 1000 Node* result = ControlReducer::ReduceMerge(&R.jsgraph, merge); |
901 | 1001 |
902 int count = selector.count; | 1002 int count = selector.count; |
903 if (count == 0) { | 1003 if (count == 0) { |
904 // result should be dead. | 1004 // result should be dead. |
905 CHECK_EQ(IrOpcode::kDead, result->opcode()); | 1005 CHECK_EQ(IrOpcode::kDead, result->opcode()); |
906 } else if (count == 1) { | 1006 } else if (count == 1) { |
907 // merge should be replaced with one of the controls. | 1007 // merge should be replaced with one of the controls. |
908 CHECK_EQ(controls[selector.single_index()], result); | 1008 CHECK_EQ(controls[selector.single_index()], result); |
909 // Phis should have been directly replaced. | 1009 // Phis should have been directly replaced. |
910 CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0)); | 1010 CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 for (int i = 0; i < 5; i++) { | 1086 for (int i = 0; i < 5; i++) { |
987 Node* merge = R.graph.NewNode(R.common.Merge(1), R.start); | 1087 Node* merge = R.graph.NewNode(R.common.Merge(1), R.start); |
988 for (int j = 0; j < i; j++) { | 1088 for (int j = 0; j < i; j++) { |
989 merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead); | 1089 merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead); |
990 } | 1090 } |
991 R.ReduceMergeIterative(R.start, merge); | 1091 R.ReduceMergeIterative(R.start, merge); |
992 } | 1092 } |
993 } | 1093 } |
994 | 1094 |
995 | 1095 |
996 struct Branch { | |
997 Node* branch; | |
998 Node* if_true; | |
999 Node* if_false; | |
1000 | |
1001 Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) { | |
1002 if (control == NULL) control = R.start; | |
1003 branch = R.graph.NewNode(R.common.Branch(), cond, control); | |
1004 if_true = R.graph.NewNode(R.common.IfTrue(), branch); | |
1005 if_false = R.graph.NewNode(R.common.IfFalse(), branch); | |
1006 } | |
1007 }; | |
1008 | |
1009 | |
1010 // TODO(titzer): use the diamonds from src/compiler/diamond.h here. | |
1011 struct Diamond { | |
1012 Node* branch; | |
1013 Node* if_true; | |
1014 Node* if_false; | |
1015 Node* merge; | |
1016 Node* phi; | |
1017 | |
1018 Diamond(ControlReducerTester& R, Node* cond) { | |
1019 branch = R.graph.NewNode(R.common.Branch(), cond, R.start); | |
1020 if_true = R.graph.NewNode(R.common.IfTrue(), branch); | |
1021 if_false = R.graph.NewNode(R.common.IfFalse(), branch); | |
1022 merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false); | |
1023 phi = NULL; | |
1024 } | |
1025 | |
1026 Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) { | |
1027 branch = R.graph.NewNode(R.common.Branch(), cond, R.start); | |
1028 if_true = R.graph.NewNode(R.common.IfTrue(), branch); | |
1029 if_false = R.graph.NewNode(R.common.IfFalse(), branch); | |
1030 merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false); | |
1031 phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge); | |
1032 } | |
1033 | |
1034 void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); } | |
1035 | |
1036 // Nest {this} into either the if_true or if_false branch of {that}. | |
1037 void nest(Diamond& that, bool if_true) { | |
1038 if (if_true) { | |
1039 branch->ReplaceInput(1, that.if_true); | |
1040 that.merge->ReplaceInput(0, merge); | |
1041 } else { | |
1042 branch->ReplaceInput(1, that.if_false); | |
1043 that.merge->ReplaceInput(1, merge); | |
1044 } | |
1045 } | |
1046 }; | |
1047 | |
1048 | |
1049 struct While { | |
1050 Node* branch; | |
1051 Node* if_true; | |
1052 Node* exit; | |
1053 Node* loop; | |
1054 | |
1055 While(ControlReducerTester& R, Node* cond) { | |
1056 loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start); | |
1057 branch = R.graph.NewNode(R.common.Branch(), cond, loop); | |
1058 if_true = R.graph.NewNode(R.common.IfTrue(), branch); | |
1059 exit = R.graph.NewNode(R.common.IfFalse(), branch); | |
1060 loop->ReplaceInput(1, if_true); | |
1061 } | |
1062 | |
1063 void chain(Node* control) { loop->ReplaceInput(0, control); } | |
1064 }; | |
1065 | |
1066 | |
1067 TEST(CBranchReduce_none1) { | 1096 TEST(CBranchReduce_none1) { |
1068 ControlReducerTester R; | 1097 ControlReducerTester R; |
1069 Diamond d(R, R.p0); | 1098 Diamond d(R, R.p0); |
1070 R.ReduceBranch(kUnknown, d.branch); | 1099 R.ReduceBranch(kUnknown, d.branch); |
1071 } | 1100 } |
1072 | 1101 |
1073 | 1102 |
1074 TEST(CBranchReduce_none2) { | 1103 TEST(CBranchReduce_none2) { |
1075 ControlReducerTester R; | 1104 ControlReducerTester R; |
1076 Diamond d1(R, R.p0); | 1105 Diamond d1(R, R.p0); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 | 1259 |
1231 | 1260 |
1232 TEST(CDeadLoop1) { | 1261 TEST(CDeadLoop1) { |
1233 ControlReducerTester R; | 1262 ControlReducerTester R; |
1234 | 1263 |
1235 Node* loop = R.graph.NewNode(R.common.Loop(1), R.start); | 1264 Node* loop = R.graph.NewNode(R.common.Loop(1), R.start); |
1236 Branch b(R, R.p0, loop); | 1265 Branch b(R, R.p0, loop); |
1237 loop->ReplaceInput(0, b.if_true); // loop is not connected to start. | 1266 loop->ReplaceInput(0, b.if_true); // loop is not connected to start. |
1238 Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false); | 1267 Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false); |
1239 R.ReduceMergeIterative(R.start, merge); | 1268 R.ReduceMergeIterative(R.start, merge); |
1240 CHECK(b.if_true->IsDead()); | 1269 |
1241 CHECK(b.if_false->IsDead()); | 1270 DeadChecker dead(&R.graph); |
| 1271 dead.Check(b.if_true); |
| 1272 dead.Check(b.if_false); |
| 1273 dead.Check(b.branch); |
| 1274 dead.Check(loop); |
1242 } | 1275 } |
1243 | 1276 |
1244 | 1277 |
1245 TEST(CDeadLoop2) { | 1278 TEST(CDeadLoop2) { |
1246 ControlReducerTester R; | 1279 ControlReducerTester R; |
1247 | 1280 |
1248 While w(R, R.p0); | 1281 While w(R, R.p0); |
1249 Diamond d(R, R.zero); | 1282 Diamond d(R, R.zero); |
1250 // if (0) { while (p0) ; } else { } | 1283 // if (0) { while (p0) ; } else { } |
1251 w.branch->ReplaceInput(1, d.if_true); | 1284 w.branch->ReplaceInput(1, d.if_true); |
1252 d.merge->ReplaceInput(0, w.exit); | 1285 d.merge->ReplaceInput(0, w.exit); |
1253 | 1286 |
1254 R.ReduceMergeIterative(R.start, d.merge); | 1287 R.ReduceMergeIterative(R.start, d.merge); |
1255 CHECK(d.if_true->IsDead()); | 1288 |
1256 CHECK(d.if_false->IsDead()); | 1289 DeadChecker dead(&R.graph); |
| 1290 dead.Check(d); |
| 1291 dead.Check(w.loop); |
1257 } | 1292 } |
1258 | 1293 |
1259 | 1294 |
1260 TEST(Return1) { | 1295 TEST(Return1) { |
1261 ControlReducerTester R; | 1296 ControlReducerTester R; |
1262 Node* ret = R.Return(R.one, R.start, R.start); | 1297 Node* ret = R.Return(R.one, R.start, R.start); |
1263 R.ReduceGraph(); | 1298 R.ReduceGraph(); |
1264 CheckInputs(R.graph.end(), ret); | 1299 CheckInputs(R.graph.end(), ret); |
1265 CheckInputs(ret, R.one, R.start, R.start); | 1300 CheckInputs(ret, R.one, R.start, R.start); |
1266 } | 1301 } |
1267 | 1302 |
1268 | 1303 |
1269 TEST(Return2) { | 1304 TEST(Return2) { |
1270 ControlReducerTester R; | 1305 ControlReducerTester R; |
1271 Diamond d(R, R.one); | 1306 Diamond d(R, R.one); |
1272 Node* ret = R.Return(R.half, R.start, d.merge); | 1307 Node* ret = R.Return(R.half, R.start, d.merge); |
1273 R.ReduceGraph(); | 1308 R.ReduceGraph(); |
1274 CHECK(d.branch->IsDead()); | 1309 |
1275 CHECK(d.if_true->IsDead()); | 1310 DeadChecker dead(&R.graph); |
1276 CHECK(d.if_false->IsDead()); | 1311 dead.Check(d.branch); |
1277 CHECK(d.merge->IsDead()); | 1312 dead.Check(d.if_true); |
| 1313 dead.Check(d.if_false); |
| 1314 dead.Check(d.merge); |
1278 | 1315 |
1279 CheckInputs(R.graph.end(), ret); | 1316 CheckInputs(R.graph.end(), ret); |
1280 CheckInputs(ret, R.half, R.start, R.start); | 1317 CheckInputs(ret, R.half, R.start, R.start); |
1281 } | 1318 } |
1282 | 1319 |
1283 | 1320 |
1284 TEST(Return_true1) { | 1321 TEST(Return_true1) { |
1285 ControlReducerTester R; | 1322 ControlReducerTester R; |
1286 Diamond d(R, R.one, R.half, R.zero); | 1323 Diamond d(R, R.one, R.half, R.zero); |
1287 Node* ret = R.Return(d.phi, R.start, d.merge); | 1324 Node* ret = R.Return(d.phi, R.start, d.merge); |
1288 R.ReduceGraph(); | 1325 R.ReduceGraph(); |
1289 CHECK(d.branch->IsDead()); | 1326 |
1290 CHECK(d.if_true->IsDead()); | 1327 DeadChecker dead(&R.graph); |
1291 CHECK(d.if_false->IsDead()); | 1328 dead.Check(d.branch); |
1292 CHECK(d.merge->IsDead()); | 1329 dead.Check(d.if_true); |
1293 CHECK(d.phi->IsDead()); | 1330 dead.Check(d.if_false); |
| 1331 dead.Check(d.merge); |
| 1332 dead.Check(d.phi); |
1294 | 1333 |
1295 CheckInputs(R.graph.end(), ret); | 1334 CheckInputs(R.graph.end(), ret); |
1296 CheckInputs(ret, R.half, R.start, R.start); | 1335 CheckInputs(ret, R.half, R.start, R.start); |
1297 } | 1336 } |
1298 | 1337 |
1299 | 1338 |
1300 TEST(Return_false1) { | 1339 TEST(Return_false1) { |
1301 ControlReducerTester R; | 1340 ControlReducerTester R; |
1302 Diamond d(R, R.zero, R.one, R.half); | 1341 Diamond d(R, R.zero, R.one, R.half); |
1303 Node* ret = R.Return(d.phi, R.start, d.merge); | 1342 Node* ret = R.Return(d.phi, R.start, d.merge); |
1304 R.ReduceGraph(); | 1343 R.ReduceGraph(); |
1305 CHECK(d.branch->IsDead()); | 1344 |
1306 CHECK(d.if_true->IsDead()); | 1345 DeadChecker dead(&R.graph); |
1307 CHECK(d.if_false->IsDead()); | 1346 dead.Check(d.branch); |
1308 CHECK(d.merge->IsDead()); | 1347 dead.Check(d.if_true); |
1309 CHECK(d.phi->IsDead()); | 1348 dead.Check(d.if_false); |
| 1349 dead.Check(d.merge); |
| 1350 dead.Check(d.phi); |
1310 | 1351 |
1311 CheckInputs(R.graph.end(), ret); | 1352 CheckInputs(R.graph.end(), ret); |
1312 CheckInputs(ret, R.half, R.start, R.start); | 1353 CheckInputs(ret, R.half, R.start, R.start); |
1313 } | 1354 } |
1314 | 1355 |
1315 | 1356 |
1316 void CheckDeadDiamond(Diamond& d) { | |
1317 CHECK(d.branch->IsDead()); | |
1318 CHECK(d.if_true->IsDead()); | |
1319 CHECK(d.if_false->IsDead()); | |
1320 CHECK(d.merge->IsDead()); | |
1321 if (d.phi != NULL) CHECK(d.phi->IsDead()); | |
1322 } | |
1323 | |
1324 | |
1325 void CheckLiveDiamond(Diamond& d, bool live_phi = true) { | |
1326 CheckInputs(d.merge, d.if_true, d.if_false); | |
1327 CheckInputs(d.if_true, d.branch); | |
1328 CheckInputs(d.if_false, d.branch); | |
1329 if (d.phi != NULL) { | |
1330 if (live_phi) { | |
1331 CHECK_EQ(3, d.phi->InputCount()); | |
1332 CHECK_EQ(d.merge, d.phi->InputAt(2)); | |
1333 } else { | |
1334 CHECK(d.phi->IsDead()); | |
1335 } | |
1336 } | |
1337 } | |
1338 | |
1339 | |
1340 TEST(Return_effect1) { | 1357 TEST(Return_effect1) { |
1341 ControlReducerTester R; | 1358 ControlReducerTester R; |
1342 Diamond d(R, R.one); | 1359 Diamond d(R, R.one); |
1343 Node* e1 = R.jsgraph.Float64Constant(-100.1); | 1360 Node* e1 = R.jsgraph.Float64Constant(-100.1); |
1344 Node* e2 = R.jsgraph.Float64Constant(+100.1); | 1361 Node* e2 = R.jsgraph.Float64Constant(+100.1); |
1345 Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge); | 1362 Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge); |
1346 Node* ret = R.Return(R.p0, effect, d.merge); | 1363 Node* ret = R.Return(R.p0, effect, d.merge); |
1347 R.ReduceGraph(); | 1364 R.ReduceGraph(); |
1348 CheckDeadDiamond(d); | 1365 |
1349 CHECK(effect->IsDead()); | 1366 DeadChecker dead(&R.graph); |
| 1367 dead.Check(d); |
| 1368 dead.Check(effect); |
1350 | 1369 |
1351 CheckInputs(R.graph.end(), ret); | 1370 CheckInputs(R.graph.end(), ret); |
1352 CheckInputs(ret, R.p0, e1, R.start); | 1371 CheckInputs(ret, R.p0, e1, R.start); |
1353 } | 1372 } |
1354 | 1373 |
1355 | 1374 |
1356 TEST(Return_nested_diamonds1) { | 1375 TEST(Return_nested_diamonds1) { |
1357 ControlReducerTester R; | 1376 ControlReducerTester R; |
1358 Diamond d1(R, R.p0, R.one, R.zero); | 1377 Diamond d2(R, R.p0, R.one, R.zero); |
1359 Diamond d2(R, R.p0); | 1378 Diamond d3(R, R.p0, R.one, R.zero); |
1360 Diamond d3(R, R.p0); | 1379 Diamond d1(R, R.p0, d2.phi, d3.phi); |
1361 | 1380 |
1362 d2.nest(d1, true); | 1381 d2.nest(d1, true); |
1363 d3.nest(d1, false); | 1382 d3.nest(d1, false); |
1364 | 1383 |
1365 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1384 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1366 | 1385 |
1367 R.ReduceGraph(); // nothing should happen. | 1386 R.ReduceGraph(); // nothing should happen. |
1368 | 1387 |
1369 CheckInputs(ret, d1.phi, R.start, d1.merge); | 1388 CheckInputs(ret, d1.phi, R.start, d1.merge); |
| 1389 CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge); |
| 1390 CheckInputs(d1.merge, d2.merge, d3.merge); |
| 1391 |
| 1392 DeadChecker dead(&R.graph); |
| 1393 dead.CheckLive(d2); |
| 1394 dead.CheckLive(d3); |
| 1395 } |
| 1396 |
| 1397 |
| 1398 TEST(Return_nested_diamonds1_dead1) { |
| 1399 ControlReducerTester R; |
| 1400 Diamond d2(R, R.p0); // dead diamond |
| 1401 Diamond d3(R, R.p0, R.one, R.zero); |
| 1402 Diamond d1(R, R.p0, R.one, d3.phi); |
| 1403 |
| 1404 d2.nest(d1, true); |
| 1405 d3.nest(d1, false); |
| 1406 |
| 1407 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
| 1408 |
| 1409 R.ReduceGraph(); |
| 1410 |
| 1411 CheckInputs(ret, d1.phi, R.start, d1.merge); |
| 1412 CheckInputs(d1.phi, R.one, d3.phi, d1.merge); |
| 1413 CheckInputs(d1.merge, d1.if_true, d3.merge); |
| 1414 |
| 1415 DeadChecker dead(&R.graph); |
| 1416 dead.Check(d2); // d2 was a dead diamond. |
| 1417 dead.CheckLive(d3); |
| 1418 } |
| 1419 |
| 1420 |
| 1421 TEST(Return_nested_diamonds1_dead2) { |
| 1422 ControlReducerTester R; |
| 1423 Diamond d2(R, R.p0); // dead diamond |
| 1424 Diamond d3(R, R.p0); // dead diamond |
| 1425 Diamond d1(R, R.p0, R.one, R.zero); |
| 1426 |
| 1427 d2.nest(d1, true); |
| 1428 d3.nest(d1, false); |
| 1429 |
| 1430 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
| 1431 |
| 1432 R.ReduceGraph(); |
| 1433 |
| 1434 CheckInputs(ret, d1.phi, R.start, d1.merge); |
1370 CheckInputs(d1.phi, R.one, R.zero, d1.merge); | 1435 CheckInputs(d1.phi, R.one, R.zero, d1.merge); |
1371 CheckInputs(d1.merge, d1.if_true, d1.if_false); | 1436 CheckInputs(d1.merge, d1.if_true, d1.if_false); |
| 1437 |
| 1438 DeadChecker dead(&R.graph); |
| 1439 dead.Check(d2); |
| 1440 dead.Check(d3); |
1372 } | 1441 } |
1373 | 1442 |
1374 | 1443 |
1375 TEST(Return_nested_diamonds_true1) { | 1444 TEST(Return_nested_diamonds_true1) { |
1376 ControlReducerTester R; | 1445 ControlReducerTester R; |
1377 Diamond d1(R, R.one, R.one, R.zero); | 1446 Diamond d2(R, R.p0, R.one, R.zero); |
1378 Diamond d2(R, R.p0); | 1447 Diamond d1(R, R.one, d2.phi, R.zero); |
1379 Diamond d3(R, R.p0); | 1448 Diamond d3(R, R.p0); |
1380 | 1449 |
1381 d2.nest(d1, true); | 1450 d2.nest(d1, true); |
1382 d3.nest(d1, false); | 1451 d3.nest(d1, false); |
1383 | 1452 |
1384 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1453 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1385 | 1454 |
1386 R.ReduceGraph(); // d1 gets folded true. | 1455 R.ReduceGraph(); // d1 gets folded true. |
1387 | 1456 |
1388 CheckInputs(ret, R.one, R.start, R.start); | 1457 CheckInputs(ret, d2.phi, R.start, d2.merge); |
| 1458 CheckInputs(d2.branch, R.p0, R.start); |
| 1459 |
| 1460 DeadChecker dead(&R.graph); |
| 1461 dead.Check(d1); |
| 1462 dead.CheckLive(d2); |
| 1463 dead.Check(d3); |
1389 } | 1464 } |
1390 | 1465 |
1391 | 1466 |
1392 TEST(Return_nested_diamonds_false1) { | 1467 TEST(Return_nested_diamonds_false1) { |
1393 ControlReducerTester R; | 1468 ControlReducerTester R; |
1394 Diamond d1(R, R.zero, R.one, R.zero); | 1469 Diamond d3(R, R.p0, R.one, R.zero); |
| 1470 Diamond d1(R, R.zero, R.one, d3.phi); |
1395 Diamond d2(R, R.p0); | 1471 Diamond d2(R, R.p0); |
1396 Diamond d3(R, R.p0); | |
1397 | 1472 |
1398 d2.nest(d1, true); | 1473 d2.nest(d1, true); |
1399 d3.nest(d1, false); | 1474 d3.nest(d1, false); |
1400 | 1475 |
1401 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1476 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1402 | 1477 |
1403 R.ReduceGraph(); // d1 gets folded false. | 1478 R.ReduceGraph(); // d1 gets folded false. |
1404 | 1479 |
1405 CheckInputs(ret, R.zero, R.start, R.start); | 1480 CheckInputs(ret, d3.phi, R.start, d3.merge); |
| 1481 CheckInputs(d3.branch, R.p0, R.start); |
| 1482 |
| 1483 DeadChecker dead(&R.graph); |
| 1484 dead.Check(d1); |
| 1485 dead.Check(d2); |
| 1486 dead.CheckLive(d3); |
1406 } | 1487 } |
1407 | 1488 |
1408 | 1489 |
1409 TEST(Return_nested_diamonds_true_true1) { | 1490 TEST(Return_nested_diamonds_true_true1) { |
1410 ControlReducerTester R; | 1491 ControlReducerTester R; |
1411 Diamond d1(R, R.one, R.one, R.zero); | 1492 Diamond d1(R, R.one, R.one, R.zero); |
1412 Diamond d2(R, R.one); | 1493 Diamond d2(R, R.one); |
1413 Diamond d3(R, R.p0); | 1494 Diamond d3(R, R.p0); |
1414 | 1495 |
1415 d2.nest(d1, true); | 1496 d2.nest(d1, true); |
1416 d3.nest(d1, false); | 1497 d3.nest(d1, false); |
1417 | 1498 |
1418 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1499 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1419 | 1500 |
1420 R.ReduceGraph(); // d1 and d2 both get folded true. | 1501 R.ReduceGraph(); // d1 and d2 both get folded true. |
1421 | 1502 |
1422 CheckInputs(ret, R.one, R.start, R.start); | 1503 CheckInputs(ret, R.one, R.start, R.start); |
1423 CheckDeadDiamond(d1); | 1504 |
1424 CheckDeadDiamond(d2); | 1505 DeadChecker dead(&R.graph); |
1425 CheckDeadDiamond(d3); | 1506 dead.Check(d1); |
| 1507 dead.Check(d2); |
| 1508 dead.Check(d3); |
1426 } | 1509 } |
1427 | 1510 |
1428 | 1511 |
1429 TEST(Return_nested_diamonds_true_false1) { | 1512 TEST(Return_nested_diamonds_true_false1) { |
1430 ControlReducerTester R; | 1513 ControlReducerTester R; |
1431 Diamond d1(R, R.one, R.one, R.zero); | 1514 Diamond d1(R, R.one, R.one, R.zero); |
1432 Diamond d2(R, R.zero); | 1515 Diamond d2(R, R.zero); |
1433 Diamond d3(R, R.p0); | 1516 Diamond d3(R, R.p0); |
1434 | 1517 |
1435 d2.nest(d1, true); | 1518 d2.nest(d1, true); |
1436 d3.nest(d1, false); | 1519 d3.nest(d1, false); |
1437 | 1520 |
1438 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1521 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1439 | 1522 |
1440 R.ReduceGraph(); // d1 gets folded true and d2 gets folded false. | 1523 R.ReduceGraph(); // d1 gets folded true and d2 gets folded false. |
1441 | 1524 |
1442 CheckInputs(ret, R.one, R.start, R.start); | 1525 CheckInputs(ret, R.one, R.start, R.start); |
1443 CheckDeadDiamond(d1); | 1526 |
1444 CheckDeadDiamond(d2); | 1527 DeadChecker dead(&R.graph); |
1445 CheckDeadDiamond(d3); | 1528 dead.Check(d1); |
| 1529 dead.Check(d2); |
| 1530 dead.Check(d3); |
1446 } | 1531 } |
1447 | 1532 |
1448 | 1533 |
1449 TEST(Return_nested_diamonds2) { | 1534 TEST(Return_nested_diamonds2) { |
1450 ControlReducerTester R; | 1535 ControlReducerTester R; |
1451 Node* x2 = R.jsgraph.Float64Constant(11.1); | 1536 Node* x2 = R.jsgraph.Float64Constant(11.1); |
1452 Node* y2 = R.jsgraph.Float64Constant(22.2); | 1537 Node* y2 = R.jsgraph.Float64Constant(22.2); |
1453 Node* x3 = R.jsgraph.Float64Constant(33.3); | 1538 Node* x3 = R.jsgraph.Float64Constant(33.3); |
1454 Node* y3 = R.jsgraph.Float64Constant(44.4); | 1539 Node* y3 = R.jsgraph.Float64Constant(44.4); |
1455 | 1540 |
1456 Diamond d2(R, R.p0, x2, y2); | 1541 Diamond d2(R, R.p0, x2, y2); |
1457 Diamond d3(R, R.p0, x3, y3); | 1542 Diamond d3(R, R.p0, x3, y3); |
1458 Diamond d1(R, R.p0, d2.phi, d3.phi); | 1543 Diamond d1(R, R.p0, d2.phi, d3.phi); |
1459 | 1544 |
1460 d2.nest(d1, true); | 1545 d2.nest(d1, true); |
1461 d3.nest(d1, false); | 1546 d3.nest(d1, false); |
1462 | 1547 |
1463 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1548 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1464 | 1549 |
1465 R.ReduceGraph(); // nothing should happen. | 1550 R.ReduceGraph(); // nothing should happen. |
1466 | 1551 |
1467 CheckInputs(ret, d1.phi, R.start, d1.merge); | 1552 CheckInputs(ret, d1.phi, R.start, d1.merge); |
1468 CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge); | 1553 CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge); |
1469 CheckInputs(d1.merge, d2.merge, d3.merge); | 1554 CheckInputs(d1.merge, d2.merge, d3.merge); |
1470 CheckLiveDiamond(d2); | 1555 |
1471 CheckLiveDiamond(d3); | 1556 DeadChecker dead(&R.graph); |
| 1557 dead.CheckLive(d2); |
| 1558 dead.CheckLive(d3); |
1472 } | 1559 } |
1473 | 1560 |
1474 | 1561 |
1475 TEST(Return_nested_diamonds_true2) { | 1562 TEST(Return_nested_diamonds_true2) { |
1476 ControlReducerTester R; | 1563 ControlReducerTester R; |
1477 Node* x2 = R.jsgraph.Float64Constant(11.1); | 1564 Node* x2 = R.jsgraph.Float64Constant(11.1); |
1478 Node* y2 = R.jsgraph.Float64Constant(22.2); | 1565 Node* y2 = R.jsgraph.Float64Constant(22.2); |
1479 Node* x3 = R.jsgraph.Float64Constant(33.3); | 1566 Node* x3 = R.jsgraph.Float64Constant(33.3); |
1480 Node* y3 = R.jsgraph.Float64Constant(44.4); | 1567 Node* y3 = R.jsgraph.Float64Constant(44.4); |
1481 | 1568 |
1482 Diamond d2(R, R.p0, x2, y2); | 1569 Diamond d2(R, R.p0, x2, y2); |
1483 Diamond d3(R, R.p0, x3, y3); | 1570 Diamond d3(R, R.p0, x3, y3); |
1484 Diamond d1(R, R.one, d2.phi, d3.phi); | 1571 Diamond d1(R, R.one, d2.phi, d3.phi); |
1485 | 1572 |
1486 d2.nest(d1, true); | 1573 d2.nest(d1, true); |
1487 d3.nest(d1, false); | 1574 d3.nest(d1, false); |
1488 | 1575 |
1489 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1576 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1490 | 1577 |
1491 R.ReduceGraph(); // d1 gets folded true. | 1578 R.ReduceGraph(); // d1 gets folded true. |
1492 | 1579 |
1493 CheckInputs(ret, d2.phi, R.start, d2.merge); | 1580 CheckInputs(ret, d2.phi, R.start, d2.merge); |
1494 CheckInputs(d2.branch, R.p0, R.start); | 1581 CheckInputs(d2.branch, R.p0, R.start); |
1495 CheckDeadDiamond(d1); | 1582 |
1496 CheckLiveDiamond(d2); | 1583 DeadChecker dead(&R.graph); |
1497 CheckDeadDiamond(d3); | 1584 dead.Check(d1); |
| 1585 dead.CheckLive(d2); |
| 1586 dead.Check(d3); |
1498 } | 1587 } |
1499 | 1588 |
1500 | 1589 |
1501 TEST(Return_nested_diamonds_true_true2) { | 1590 TEST(Return_nested_diamonds_true_true2) { |
1502 ControlReducerTester R; | 1591 ControlReducerTester R; |
1503 Node* x2 = R.jsgraph.Float64Constant(11.1); | 1592 Node* x2 = R.jsgraph.Float64Constant(11.1); |
1504 Node* y2 = R.jsgraph.Float64Constant(22.2); | 1593 Node* y2 = R.jsgraph.Float64Constant(22.2); |
1505 Node* x3 = R.jsgraph.Float64Constant(33.3); | 1594 Node* x3 = R.jsgraph.Float64Constant(33.3); |
1506 Node* y3 = R.jsgraph.Float64Constant(44.4); | 1595 Node* y3 = R.jsgraph.Float64Constant(44.4); |
1507 | 1596 |
1508 Diamond d2(R, R.one, x2, y2); | 1597 Diamond d2(R, R.one, x2, y2); |
1509 Diamond d3(R, R.p0, x3, y3); | 1598 Diamond d3(R, R.p0, x3, y3); |
1510 Diamond d1(R, R.one, d2.phi, d3.phi); | 1599 Diamond d1(R, R.one, d2.phi, d3.phi); |
1511 | 1600 |
1512 d2.nest(d1, true); | 1601 d2.nest(d1, true); |
1513 d3.nest(d1, false); | 1602 d3.nest(d1, false); |
1514 | 1603 |
1515 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1604 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1516 | 1605 |
1517 R.ReduceGraph(); // d1 gets folded true. | 1606 R.ReduceGraph(); // d1 gets folded true. |
1518 | 1607 |
1519 CheckInputs(ret, x2, R.start, R.start); | 1608 CheckInputs(ret, x2, R.start, R.start); |
1520 CheckDeadDiamond(d1); | 1609 |
1521 CheckDeadDiamond(d2); | 1610 DeadChecker dead(&R.graph); |
1522 CheckDeadDiamond(d3); | 1611 dead.Check(d1); |
| 1612 dead.Check(d2); |
| 1613 dead.Check(d3); |
1523 } | 1614 } |
1524 | 1615 |
1525 | 1616 |
1526 TEST(Return_nested_diamonds_true_false2) { | 1617 TEST(Return_nested_diamonds_true_false2) { |
1527 ControlReducerTester R; | 1618 ControlReducerTester R; |
1528 Node* x2 = R.jsgraph.Float64Constant(11.1); | 1619 Node* x2 = R.jsgraph.Float64Constant(11.1); |
1529 Node* y2 = R.jsgraph.Float64Constant(22.2); | 1620 Node* y2 = R.jsgraph.Float64Constant(22.2); |
1530 Node* x3 = R.jsgraph.Float64Constant(33.3); | 1621 Node* x3 = R.jsgraph.Float64Constant(33.3); |
1531 Node* y3 = R.jsgraph.Float64Constant(44.4); | 1622 Node* y3 = R.jsgraph.Float64Constant(44.4); |
1532 | 1623 |
1533 Diamond d2(R, R.zero, x2, y2); | 1624 Diamond d2(R, R.zero, x2, y2); |
1534 Diamond d3(R, R.p0, x3, y3); | 1625 Diamond d3(R, R.p0, x3, y3); |
1535 Diamond d1(R, R.one, d2.phi, d3.phi); | 1626 Diamond d1(R, R.one, d2.phi, d3.phi); |
1536 | 1627 |
1537 d2.nest(d1, true); | 1628 d2.nest(d1, true); |
1538 d3.nest(d1, false); | 1629 d3.nest(d1, false); |
1539 | 1630 |
1540 Node* ret = R.Return(d1.phi, R.start, d1.merge); | 1631 Node* ret = R.Return(d1.phi, R.start, d1.merge); |
1541 | 1632 |
1542 R.ReduceGraph(); // d1 gets folded true. | 1633 R.ReduceGraph(); // d1 gets folded true. |
1543 | 1634 |
1544 CheckInputs(ret, y2, R.start, R.start); | 1635 CheckInputs(ret, y2, R.start, R.start); |
1545 CheckDeadDiamond(d1); | 1636 |
1546 CheckDeadDiamond(d2); | 1637 DeadChecker dead(&R.graph); |
1547 CheckDeadDiamond(d3); | 1638 dead.Check(d1); |
| 1639 dead.Check(d2); |
| 1640 dead.Check(d3); |
1548 } | 1641 } |
OLD | NEW |