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