Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: src/compiler/common-operator-reducer.cc

Issue 1215623002: [turbofan] Add support for pushing returns into merges. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Use NodeProperties::GetControlInput. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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-reducer.h" 5 #include "src/compiler/common-operator-reducer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/compiler/common-operator.h" 9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph.h" 10 #include "src/compiler/graph.h"
11 #include "src/compiler/machine-operator.h" 11 #include "src/compiler/machine-operator.h"
12 #include "src/compiler/node.h" 12 #include "src/compiler/node.h"
13 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
14 #include "src/compiler/node-properties.h"
14 15
15 namespace v8 { 16 namespace v8 {
16 namespace internal { 17 namespace internal {
17 namespace compiler { 18 namespace compiler {
18 19
19 namespace { 20 namespace {
20 21
21 enum class Decision { kUnknown, kTrue, kFalse }; 22 enum class Decision { kUnknown, kTrue, kFalse };
22 23
23 Decision DecideCondition(Node* const cond) { 24 Decision DecideCondition(Node* const cond) {
(...skipping 12 matching lines...) Expand all
36 : Decision::kFalse; 37 : Decision::kFalse;
37 } 38 }
38 default: 39 default:
39 return Decision::kUnknown; 40 return Decision::kUnknown;
40 } 41 }
41 } 42 }
42 43
43 } // namespace 44 } // namespace
44 45
45 46
47 CommonOperatorReducer::CommonOperatorReducer(Editor* editor, Graph* graph,
48 CommonOperatorBuilder* common,
49 MachineOperatorBuilder* machine)
50 : AdvancedReducer(editor),
51 graph_(graph),
52 common_(common),
53 machine_(machine),
54 dead_(graph->NewNode(common->Dead())) {}
55
56
46 Reduction CommonOperatorReducer::Reduce(Node* node) { 57 Reduction CommonOperatorReducer::Reduce(Node* node) {
47 switch (node->opcode()) { 58 switch (node->opcode()) {
48 case IrOpcode::kBranch: 59 case IrOpcode::kBranch:
49 return ReduceBranch(node); 60 return ReduceBranch(node);
50 case IrOpcode::kMerge: 61 case IrOpcode::kMerge:
51 return ReduceMerge(node); 62 return ReduceMerge(node);
52 case IrOpcode::kEffectPhi: 63 case IrOpcode::kEffectPhi:
53 return ReduceEffectPhi(node); 64 return ReduceEffectPhi(node);
54 case IrOpcode::kPhi: 65 case IrOpcode::kPhi:
55 return ReducePhi(node); 66 return ReducePhi(node);
67 case IrOpcode::kReturn:
68 return ReduceReturn(node);
56 case IrOpcode::kSelect: 69 case IrOpcode::kSelect:
57 return ReduceSelect(node); 70 return ReduceSelect(node);
58 default: 71 default:
59 break; 72 break;
60 } 73 }
61 return NoChange(); 74 return NoChange();
62 } 75 }
63 76
64 77
65 Reduction CommonOperatorReducer::ReduceBranch(Node* node) { 78 Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
(...skipping 18 matching lines...) Expand all
84 } 97 }
85 // Update the condition of {branch}. No need to mark the uses for revisit, 98 // Update the condition of {branch}. No need to mark the uses for revisit,
86 // since we tell the graph reducer that the {branch} was changed and the 99 // since we tell the graph reducer that the {branch} was changed and the
87 // graph reduction logic will ensure that the uses are revisited properly. 100 // graph reduction logic will ensure that the uses are revisited properly.
88 node->ReplaceInput(0, cond->InputAt(0)); 101 node->ReplaceInput(0, cond->InputAt(0));
89 return Changed(node); 102 return Changed(node);
90 } 103 }
91 Decision const decision = DecideCondition(cond); 104 Decision const decision = DecideCondition(cond);
92 if (decision == Decision::kUnknown) return NoChange(); 105 if (decision == Decision::kUnknown) return NoChange();
93 Node* const control = node->InputAt(1); 106 Node* const control = node->InputAt(1);
94 if (!dead_.is_set()) dead_.set(graph()->NewNode(common()->Dead()));
95 for (Node* const use : node->uses()) { 107 for (Node* const use : node->uses()) {
96 switch (use->opcode()) { 108 switch (use->opcode()) {
97 case IrOpcode::kIfTrue: 109 case IrOpcode::kIfTrue:
98 Replace(use, (decision == Decision::kTrue) ? control : dead_.get()); 110 Replace(use, (decision == Decision::kTrue) ? control : dead());
99 break; 111 break;
100 case IrOpcode::kIfFalse: 112 case IrOpcode::kIfFalse:
101 Replace(use, (decision == Decision::kFalse) ? control : dead_.get()); 113 Replace(use, (decision == Decision::kFalse) ? control : dead());
102 break; 114 break;
103 default: 115 default:
104 UNREACHABLE(); 116 UNREACHABLE();
105 } 117 }
106 } 118 }
107 return Replace(dead_.get()); 119 return Replace(dead());
108 } 120 }
109 121
110 122
111 Reduction CommonOperatorReducer::ReduceMerge(Node* node) { 123 Reduction CommonOperatorReducer::ReduceMerge(Node* node) {
112 DCHECK_EQ(IrOpcode::kMerge, node->opcode()); 124 DCHECK_EQ(IrOpcode::kMerge, node->opcode());
113 // 125 //
114 // Check if this is a merge that belongs to an unused diamond, which means 126 // Check if this is a merge that belongs to an unused diamond, which means
115 // that: 127 // that:
116 // 128 //
117 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and 129 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 continue; 258 continue;
247 } 259 }
248 if (input != value) return NoChange(); 260 if (input != value) return NoChange();
249 } 261 }
250 // We might now be able to further reduce the {merge} node. 262 // We might now be able to further reduce the {merge} node.
251 Revisit(merge); 263 Revisit(merge);
252 return Replace(value); 264 return Replace(value);
253 } 265 }
254 266
255 267
268 Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
269 DCHECK_EQ(IrOpcode::kReturn, node->opcode());
270 Node* const value = node->InputAt(0);
271 Node* const effect = node->InputAt(1);
272 Node* const control = node->InputAt(2);
273 if (value->opcode() == IrOpcode::kPhi &&
274 NodeProperties::GetControlInput(value) == control &&
275 effect->opcode() == IrOpcode::kEffectPhi &&
276 NodeProperties::GetControlInput(effect) == control &&
277 control->opcode() == IrOpcode::kMerge) {
278 int const control_input_count = control->InputCount();
279 DCHECK_NE(0, control_input_count);
280 DCHECK_EQ(control_input_count, value->InputCount() - 1);
281 DCHECK_EQ(control_input_count, effect->InputCount() - 1);
282 Node* const end = graph()->end();
283 DCHECK_EQ(IrOpcode::kEnd, end->opcode());
284 DCHECK_NE(0, end->InputCount());
285 for (int i = 0; i < control_input_count; ++i) {
286 // Create a new {Return} and connect it to {end}. We don't need to mark
287 // {end} as revisit, because we mark {node} as {Dead} below, which was
288 // previously connected to {end}, so we know for sure that at some point
289 // the reducer logic will visit {end} again.
290 Node* ret = graph()->NewNode(common()->Return(), value->InputAt(i),
291 effect->InputAt(i), control->InputAt(i));
292 end->set_op(common()->End(end->InputCount() + 1));
293 end->AppendInput(graph()->zone(), ret);
294 }
295 // Mark the merge {control} and return {node} as {dead}.
296 Replace(control, dead());
297 return Replace(dead());
298 }
299 return NoChange();
300 }
301
302
256 Reduction CommonOperatorReducer::ReduceSelect(Node* node) { 303 Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
257 DCHECK_EQ(IrOpcode::kSelect, node->opcode()); 304 DCHECK_EQ(IrOpcode::kSelect, node->opcode());
258 Node* const cond = node->InputAt(0); 305 Node* const cond = node->InputAt(0);
259 Node* const vtrue = node->InputAt(1); 306 Node* const vtrue = node->InputAt(1);
260 Node* const vfalse = node->InputAt(2); 307 Node* const vfalse = node->InputAt(2);
261 if (vtrue == vfalse) return Replace(vtrue); 308 if (vtrue == vfalse) return Replace(vtrue);
262 switch (DecideCondition(cond)) { 309 switch (DecideCondition(cond)) {
263 case Decision::kTrue: 310 case Decision::kTrue:
264 return Replace(vtrue); 311 return Replace(vtrue);
265 case Decision::kFalse: 312 case Decision::kFalse:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 node->set_op(op); 372 node->set_op(op);
326 node->ReplaceInput(0, a); 373 node->ReplaceInput(0, a);
327 node->ReplaceInput(1, b); 374 node->ReplaceInput(1, b);
328 node->TrimInputCount(2); 375 node->TrimInputCount(2);
329 return Changed(node); 376 return Changed(node);
330 } 377 }
331 378
332 } // namespace compiler 379 } // namespace compiler
333 } // namespace internal 380 } // namespace internal
334 } // namespace v8 381 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/common-operator-reducer.h ('k') | test/unittests/compiler/common-operator-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698