| 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 |