| 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/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 #include "src/compiler/common-operator-reducer.h" |
| 6 #include "src/compiler/control-reducer.h" | 7 #include "src/compiler/control-reducer.h" |
| 7 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/graph-reducer.h" | 9 #include "src/compiler/graph-reducer.h" |
| 9 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/node-marker.h" | 11 #include "src/compiler/node-marker.h" |
| 11 #include "src/compiler/node-matchers.h" | 12 #include "src/compiler/node-matchers.h" |
| 12 #include "src/compiler/node-properties.h" | 13 #include "src/compiler/node-properties.h" |
| 13 #include "src/zone-containers.h" | 14 #include "src/zone-containers.h" |
| 14 | 15 |
| 15 namespace v8 { | 16 namespace v8 { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 case IrOpcode::kIfTrue: | 63 case IrOpcode::kIfTrue: |
| 63 result = ReduceIfProjection(node, kTrue); | 64 result = ReduceIfProjection(node, kTrue); |
| 64 break; | 65 break; |
| 65 case IrOpcode::kIfFalse: | 66 case IrOpcode::kIfFalse: |
| 66 result = ReduceIfProjection(node, kFalse); | 67 result = ReduceIfProjection(node, kFalse); |
| 67 break; | 68 break; |
| 68 case IrOpcode::kLoop: // fallthrough | 69 case IrOpcode::kLoop: // fallthrough |
| 69 case IrOpcode::kMerge: | 70 case IrOpcode::kMerge: |
| 70 result = ReduceMerge(node); | 71 result = ReduceMerge(node); |
| 71 break; | 72 break; |
| 72 case IrOpcode::kSelect: | |
| 73 result = ReduceSelect(node); | |
| 74 break; | |
| 75 case IrOpcode::kPhi: | |
| 76 case IrOpcode::kEffectPhi: | |
| 77 result = ReducePhi(node); | |
| 78 break; | |
| 79 case IrOpcode::kEnd: | 73 case IrOpcode::kEnd: |
| 80 result = ReduceEnd(node); | 74 result = ReduceEnd(node); |
| 81 break; | 75 break; |
| 82 default: | 76 default: |
| 83 break; | 77 break; |
| 84 } | 78 } |
| 85 | 79 |
| 86 return result == node ? NoChange() : Replace(result); | 80 return result == node ? NoChange() : Replace(result); |
| 87 } | 81 } |
| 88 | 82 |
| 89 // Try to statically fold a condition. | 83 // Try to statically fold a condition. |
| 90 Decision DecideCondition(Node* cond) { | 84 Decision DecideCondition(Node* cond) { |
| 91 switch (cond->opcode()) { | 85 switch (cond->opcode()) { |
| 92 case IrOpcode::kInt32Constant: | 86 case IrOpcode::kInt32Constant: |
| 93 return Int32Matcher(cond).Is(0) ? kFalse : kTrue; | 87 return Int32Matcher(cond).Is(0) ? kFalse : kTrue; |
| 94 case IrOpcode::kInt64Constant: | 88 case IrOpcode::kInt64Constant: |
| 95 return Int64Matcher(cond).Is(0) ? kFalse : kTrue; | 89 return Int64Matcher(cond).Is(0) ? kFalse : kTrue; |
| 96 case IrOpcode::kHeapConstant: { | 90 case IrOpcode::kHeapConstant: { |
| 97 Handle<Object> object = | 91 Handle<Object> object = |
| 98 HeapObjectMatcher<Object>(cond).Value().handle(); | 92 HeapObjectMatcher<Object>(cond).Value().handle(); |
| 99 return object->BooleanValue() ? kTrue : kFalse; | 93 return object->BooleanValue() ? kTrue : kFalse; |
| 100 } | 94 } |
| 101 default: | 95 default: |
| 102 break; | 96 break; |
| 103 } | 97 } |
| 104 return kUnknown; | 98 return kUnknown; |
| 105 } | 99 } |
| 106 | 100 |
| 107 // Reduce redundant selects. | |
| 108 Node* ReduceSelect(Node* const node) { | |
| 109 Node* const tvalue = node->InputAt(1); | |
| 110 Node* const fvalue = node->InputAt(2); | |
| 111 if (tvalue == fvalue) return tvalue; | |
| 112 Decision result = DecideCondition(node->InputAt(0)); | |
| 113 if (result == kTrue) return tvalue; | |
| 114 if (result == kFalse) return fvalue; | |
| 115 return node; | |
| 116 } | |
| 117 | |
| 118 // Reduce redundant phis. | |
| 119 Node* ReducePhi(Node* node) { | |
| 120 int n = node->InputCount(); | |
| 121 if (n <= 1) return dead(); // No non-control inputs. | |
| 122 if (n == 2) return node->InputAt(0); // Only one non-control input. | |
| 123 | |
| 124 Node* replacement = NULL; | |
| 125 auto const inputs = node->inputs(); | |
| 126 for (auto it = inputs.begin(); n > 1; --n, ++it) { | |
| 127 Node* input = *it; | |
| 128 // Ignore dead inputs. | |
| 129 if (input->opcode() == IrOpcode::kDeadControl) continue; | |
| 130 // Non-redundant input. | |
| 131 if (input != node && input != replacement) { | |
| 132 if (replacement != NULL) return node; | |
| 133 replacement = input; | |
| 134 } | |
| 135 } | |
| 136 return replacement == NULL ? dead() : replacement; | |
| 137 } | |
| 138 | |
| 139 // Reduce branches. | 101 // Reduce branches. |
| 140 Node* ReduceBranch(Node* branch) { | 102 Node* ReduceBranch(Node* branch) { |
| 141 if (DecideCondition(branch->InputAt(0)) != kUnknown) { | 103 if (DecideCondition(branch->InputAt(0)) != kUnknown) { |
| 142 for (Node* use : branch->uses()) Revisit(use); | 104 for (Node* use : branch->uses()) Revisit(use); |
| 143 } | 105 } |
| 144 return branch; | 106 return branch; |
| 145 } | 107 } |
| 146 | 108 |
| 147 // Reduce end by trimming away dead inputs. | 109 // Reduce end by trimming away dead inputs. |
| 148 Node* ReduceEnd(Node* node) { | 110 Node* ReduceEnd(Node* node) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 DCHECK_NE(total, node->InputCount()); | 267 DCHECK_NE(total, node->InputCount()); |
| 306 node->TrimInputCount(total); | 268 node->TrimInputCount(total); |
| 307 node->set_op(common()->ResizeMergeOrPhi(node->op(), live)); | 269 node->set_op(common()->ResizeMergeOrPhi(node->op(), live)); |
| 308 } | 270 } |
| 309 }; | 271 }; |
| 310 | 272 |
| 311 | 273 |
| 312 void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph, | 274 void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph, |
| 313 int max_phis_for_select) { | 275 int max_phis_for_select) { |
| 314 GraphReducer graph_reducer(zone, jsgraph->graph()); | 276 GraphReducer graph_reducer(zone, jsgraph->graph()); |
| 277 CommonOperatorReducer common(&graph_reducer, jsgraph->graph(), |
| 278 jsgraph->common(), jsgraph->machine()); |
| 315 ControlReducerImpl impl(&graph_reducer, zone, jsgraph); | 279 ControlReducerImpl impl(&graph_reducer, zone, jsgraph); |
| 316 impl.max_phis_for_select_ = max_phis_for_select; | 280 impl.max_phis_for_select_ = max_phis_for_select; |
| 317 graph_reducer.AddReducer(&impl); | 281 graph_reducer.AddReducer(&impl); |
| 282 graph_reducer.AddReducer(&common); |
| 318 graph_reducer.ReduceGraph(); | 283 graph_reducer.ReduceGraph(); |
| 319 } | 284 } |
| 320 | 285 |
| 321 | 286 |
| 322 namespace { | 287 namespace { |
| 323 | 288 |
| 324 class DummyEditor final : public AdvancedReducer::Editor { | 289 class DummyEditor final : public AdvancedReducer::Editor { |
| 325 public: | 290 public: |
| 326 void Replace(Node* node, Node* replacement) final { | 291 void Replace(Node* node, Node* replacement) final { |
| 327 node->ReplaceUses(replacement); | 292 node->ReplaceUses(replacement); |
| 328 } | 293 } |
| 329 void Revisit(Node* node) final {} | 294 void Revisit(Node* node) final {} |
| 330 void ReplaceWithValue(Node* node, Node* value, Node* effect, | 295 void ReplaceWithValue(Node* node, Node* value, Node* effect, |
| 331 Node* control) final {} | 296 Node* control) final {} |
| 332 }; | 297 }; |
| 333 | 298 |
| 334 } // namespace | 299 } // namespace |
| 335 | 300 |
| 336 | 301 |
| 337 Node* ControlReducer::ReduceMerge(JSGraph* jsgraph, Node* node, | 302 Node* ControlReducer::ReduceMerge(JSGraph* jsgraph, Node* node, |
| 338 int max_phis_for_select) { | 303 int max_phis_for_select) { |
| 339 Zone zone; | 304 Zone zone; |
| 340 DummyEditor editor; | 305 DummyEditor editor; |
| 341 ControlReducerImpl impl(&editor, &zone, jsgraph); | 306 ControlReducerImpl impl(&editor, &zone, jsgraph); |
| 342 impl.max_phis_for_select_ = max_phis_for_select; | 307 impl.max_phis_for_select_ = max_phis_for_select; |
| 343 return impl.ReduceMerge(node); | 308 return impl.ReduceMerge(node); |
| 344 } | 309 } |
| 345 | 310 |
| 346 | 311 |
| 347 Node* ControlReducer::ReducePhiForTesting(JSGraph* jsgraph, Node* node) { | |
| 348 Zone zone; | |
| 349 DummyEditor editor; | |
| 350 ControlReducerImpl impl(&editor, &zone, jsgraph); | |
| 351 return impl.ReducePhi(node); | |
| 352 } | |
| 353 | |
| 354 | |
| 355 Node* ControlReducer::ReduceIfNodeForTesting(JSGraph* jsgraph, Node* node) { | 312 Node* ControlReducer::ReduceIfNodeForTesting(JSGraph* jsgraph, Node* node) { |
| 356 Zone zone; | 313 Zone zone; |
| 357 DummyEditor editor; | 314 DummyEditor editor; |
| 358 ControlReducerImpl impl(&editor, &zone, jsgraph); | 315 ControlReducerImpl impl(&editor, &zone, jsgraph); |
| 359 switch (node->opcode()) { | 316 switch (node->opcode()) { |
| 360 case IrOpcode::kIfTrue: | 317 case IrOpcode::kIfTrue: |
| 361 return impl.ReduceIfProjection(node, kTrue); | 318 return impl.ReduceIfProjection(node, kTrue); |
| 362 case IrOpcode::kIfFalse: | 319 case IrOpcode::kIfFalse: |
| 363 return impl.ReduceIfProjection(node, kFalse); | 320 return impl.ReduceIfProjection(node, kFalse); |
| 364 default: | 321 default: |
| 365 return node; | 322 return node; |
| 366 } | 323 } |
| 367 } | 324 } |
| 368 | 325 |
| 369 } // namespace compiler | 326 } // namespace compiler |
| 370 } // namespace internal | 327 } // namespace internal |
| 371 } // namespace v8 | 328 } // namespace v8 |
| OLD | NEW |