Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/compiler/control-reducer.h" | 5 #include "src/compiler/control-reducer.h" |
| 6 #include "src/compiler/graph-visualizer.h" | |
| 6 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 7 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
| 8 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
| 9 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
| 10 #include "test/unittests/compiler/graph-unittest.h" | 11 #include "test/unittests/compiler/graph-unittest.h" |
| 11 #include "test/unittests/compiler/node-test-utils.h" | 12 #include "test/unittests/compiler/node-test-utils.h" |
| 12 #include "testing/gmock-support.h" | 13 #include "testing/gmock-support.h" |
| 13 | 14 |
| 14 using testing::_; | 15 using testing::_; |
| 15 using testing::AllOf; | 16 using testing::AllOf; |
| 16 using testing::Capture; | 17 using testing::Capture; |
| 17 using testing::CaptureEq; | 18 using testing::CaptureEq; |
| 18 | 19 |
| 19 namespace v8 { | 20 namespace v8 { |
| 20 namespace internal { | 21 namespace internal { |
| 21 namespace compiler { | 22 namespace compiler { |
| 22 | 23 |
| 23 class ControlReducerTest : public GraphTest { | 24 class ControlReducerTest : public GraphTest { |
| 25 public: | |
| 26 ControlReducerTest() | |
| 27 : GraphTest(), | |
|
Michael Starzinger
2015/04/02 11:59:34
nit: The default constructor should be implicitly
titzer
2015/04/02 12:35:48
I've taken your suggestion of extending TypeGraphT
| |
| 28 machine_(zone()), | |
| 29 javascript_(zone()), | |
| 30 jsgraph_(isolate(), graph(), common(), &javascript_, &machine_) {} | |
| 31 | |
| 24 protected: | 32 protected: |
| 33 MachineOperatorBuilder machine_; | |
| 34 JSOperatorBuilder javascript_; | |
| 35 JSGraph jsgraph_; | |
| 36 | |
| 25 void ReduceGraph() { | 37 void ReduceGraph() { |
| 26 JSOperatorBuilder javascript(zone()); | 38 if (FLAG_trace_turbo_graph) { |
| 27 MachineOperatorBuilder machine(zone()); | 39 OFStream os(stdout); |
| 28 JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); | 40 os << "-- Graph before control reduction" << std::endl; |
| 29 ControlReducer::ReduceGraph(zone(), &jsgraph, common()); | 41 os << AsRPO(*graph()); |
| 42 } | |
| 43 ControlReducer::ReduceGraph(zone(), jsgraph(), common()); | |
| 44 if (FLAG_trace_turbo_graph) { | |
| 45 OFStream os(stdout); | |
| 46 os << "-- Graph after control reduction" << std::endl; | |
| 47 os << AsRPO(*graph()); | |
| 48 } | |
| 30 } | 49 } |
| 50 | |
| 51 JSGraph* jsgraph() { return &jsgraph_; } | |
| 31 }; | 52 }; |
| 32 | 53 |
| 33 | 54 |
| 34 TEST_F(ControlReducerTest, NonTerminatingLoop) { | 55 TEST_F(ControlReducerTest, NonTerminatingLoop) { |
| 35 Node* loop = graph()->NewNode(common()->Loop(2), graph()->start()); | 56 Node* loop = graph()->NewNode(common()->Loop(2), graph()->start()); |
| 36 loop->AppendInput(graph()->zone(), loop); | 57 loop->AppendInput(graph()->zone(), loop); |
| 37 ReduceGraph(); | 58 ReduceGraph(); |
| 38 Capture<Node*> branch; | 59 Capture<Node*> branch; |
| 39 EXPECT_THAT( | 60 EXPECT_THAT( |
| 40 graph()->end(), | 61 graph()->end(), |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 graph()->end(), | 133 graph()->end(), |
| 113 IsEnd(IsReturn( | 134 IsEnd(IsReturn( |
| 114 IsUndefinedConstant(), graph()->start(), | 135 IsUndefinedConstant(), graph()->start(), |
| 115 IsIfFalse(AllOf( | 136 IsIfFalse(AllOf( |
| 116 CaptureEq(&branch), | 137 CaptureEq(&branch), |
| 117 IsBranch(IsAlways(), | 138 IsBranch(IsAlways(), |
| 118 AllOf(loop, IsLoop(graph()->start(), | 139 AllOf(loop, IsLoop(graph()->start(), |
| 119 IsIfTrue(CaptureEq(&branch)))))))))); | 140 IsIfTrue(CaptureEq(&branch)))))))))); |
| 120 } | 141 } |
| 121 | 142 |
| 143 | |
| 144 TEST_F(ControlReducerTest, PhiAsInputToBranch_true) { | |
| 145 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
| 146 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
| 147 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 148 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 149 Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
| 150 Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 151 jsgraph()->Int32Constant(1), | |
| 152 jsgraph()->Int32Constant(2), merge1); | |
| 153 | |
| 154 Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); | |
| 155 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
| 156 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
| 157 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
| 158 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 159 jsgraph()->Int32Constant(11), | |
| 160 jsgraph()->Int32Constant(22), merge2); | |
| 161 | |
| 162 Node* ret = | |
| 163 graph()->NewNode(common()->Return(), result, graph()->start(), merge2); | |
| 164 graph()->end()->ReplaceInput(0, ret); | |
| 165 | |
| 166 ReduceGraph(); | |
| 167 | |
| 168 // First diamond is not reduced. | |
| 169 EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); | |
| 170 | |
| 171 // Second diamond should be folded away. | |
| 172 EXPECT_THAT(graph()->end(), | |
| 173 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), merge1))); | |
| 174 } | |
| 175 | |
| 176 | |
| 177 TEST_F(ControlReducerTest, PhiAsInputToBranch_false) { | |
| 178 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
| 179 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
| 180 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 181 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 182 Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
| 183 Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 184 jsgraph()->Int32Constant(0), | |
| 185 jsgraph()->BooleanConstant(false), merge1); | |
| 186 | |
| 187 Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); | |
| 188 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
| 189 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
| 190 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
| 191 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 192 jsgraph()->Int32Constant(11), | |
| 193 jsgraph()->Int32Constant(22), merge2); | |
| 194 | |
| 195 Node* ret = | |
| 196 graph()->NewNode(common()->Return(), result, graph()->start(), merge2); | |
| 197 graph()->end()->ReplaceInput(0, ret); | |
| 198 | |
| 199 ReduceGraph(); | |
| 200 | |
| 201 // First diamond is not reduced. | |
| 202 EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); | |
| 203 | |
| 204 // Second diamond should be folded away. | |
| 205 EXPECT_THAT(graph()->end(), | |
| 206 IsEnd(IsReturn(IsInt32Constant(22), graph()->start(), merge1))); | |
| 207 } | |
| 208 | |
| 209 | |
| 210 TEST_F(ControlReducerTest, RangeAsInputToBranch_true1) { | |
| 211 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
|
Michael Starzinger
2015/04/02 11:59:34
nit: If ControlReducerTest would inherit form Type
titzer
2015/04/02 12:35:48
Done.
| |
| 212 NodeProperties::SetBounds(p0, Bounds(Type::Range(1, 2, zone()))); | |
| 213 | |
| 214 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
| 215 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 216 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 217 Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); | |
| 218 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 219 jsgraph()->Int32Constant(11), | |
| 220 jsgraph()->Int32Constant(44), merge1); | |
| 221 | |
| 222 Node* ret = | |
| 223 graph()->NewNode(common()->Return(), result, graph()->start(), merge1); | |
| 224 graph()->end()->ReplaceInput(0, ret); | |
| 225 | |
| 226 ReduceGraph(); | |
| 227 | |
| 228 // Diamond should be folded away. | |
| 229 EXPECT_THAT( | |
| 230 graph()->end(), | |
| 231 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); | |
| 232 } | |
| 233 | |
| 234 | |
| 235 TEST_F(ControlReducerTest, RangeAsInputToBranch_true2) { | |
| 236 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
|
Michael Starzinger
2015/04/02 11:59:34
nit: Likewise.
titzer
2015/04/02 12:35:48
Done.
| |
| 237 NodeProperties::SetBounds(p0, Bounds(Type::Range(-2, -1, zone()))); | |
| 238 | |
| 239 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
| 240 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
| 241 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
| 242 Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); | |
| 243 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
| 244 jsgraph()->Int32Constant(11), | |
| 245 jsgraph()->Int32Constant(44), merge1); | |
| 246 | |
| 247 Node* ret = | |
| 248 graph()->NewNode(common()->Return(), result, graph()->start(), merge1); | |
| 249 graph()->end()->ReplaceInput(0, ret); | |
| 250 | |
| 251 ReduceGraph(); | |
| 252 | |
| 253 // Diamond should be folded away. | |
| 254 EXPECT_THAT( | |
| 255 graph()->end(), | |
| 256 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); | |
| 257 } | |
| 258 | |
| 259 | |
| 122 } // namespace compiler | 260 } // namespace compiler |
| 123 } // namespace internal | 261 } // namespace internal |
| 124 } // namespace v8 | 262 } // namespace v8 |
| OLD | NEW |