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 |