Chromium Code Reviews| 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-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" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 : Decision::kFalse; | 36 : Decision::kFalse; |
| 37 } | 37 } |
| 38 default: | 38 default: |
| 39 return Decision::kUnknown; | 39 return Decision::kUnknown; |
| 40 } | 40 } |
| 41 } | 41 } |
| 42 | 42 |
| 43 } // namespace | 43 } // namespace |
| 44 | 44 |
| 45 | 45 |
| 46 CommonOperatorReducer::CommonOperatorReducer(Editor* editor, Graph* graph, | |
| 47 CommonOperatorBuilder* common, | |
| 48 MachineOperatorBuilder* machine) | |
| 49 : AdvancedReducer(editor), | |
| 50 graph_(graph), | |
| 51 common_(common), | |
| 52 machine_(machine), | |
| 53 dead_(graph->NewNode(common->Dead())) {} | |
| 54 | |
| 55 | |
| 46 Reduction CommonOperatorReducer::Reduce(Node* node) { | 56 Reduction CommonOperatorReducer::Reduce(Node* node) { |
| 47 switch (node->opcode()) { | 57 switch (node->opcode()) { |
| 48 case IrOpcode::kBranch: | 58 case IrOpcode::kBranch: |
| 49 return ReduceBranch(node); | 59 return ReduceBranch(node); |
| 50 case IrOpcode::kMerge: | 60 case IrOpcode::kMerge: |
| 51 return ReduceMerge(node); | 61 return ReduceMerge(node); |
| 52 case IrOpcode::kEffectPhi: | 62 case IrOpcode::kEffectPhi: |
| 53 return ReduceEffectPhi(node); | 63 return ReduceEffectPhi(node); |
| 54 case IrOpcode::kPhi: | 64 case IrOpcode::kPhi: |
| 55 return ReducePhi(node); | 65 return ReducePhi(node); |
| 66 case IrOpcode::kReturn: | |
| 67 return ReduceReturn(node); | |
| 56 case IrOpcode::kSelect: | 68 case IrOpcode::kSelect: |
| 57 return ReduceSelect(node); | 69 return ReduceSelect(node); |
| 58 default: | 70 default: |
| 59 break; | 71 break; |
| 60 } | 72 } |
| 61 return NoChange(); | 73 return NoChange(); |
| 62 } | 74 } |
| 63 | 75 |
| 64 | 76 |
| 65 Reduction CommonOperatorReducer::ReduceBranch(Node* node) { | 77 Reduction CommonOperatorReducer::ReduceBranch(Node* node) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 84 } | 96 } |
| 85 // Update the condition of {branch}. No need to mark the uses for revisit, | 97 // 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 | 98 // 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. | 99 // graph reduction logic will ensure that the uses are revisited properly. |
| 88 node->ReplaceInput(0, cond->InputAt(0)); | 100 node->ReplaceInput(0, cond->InputAt(0)); |
| 89 return Changed(node); | 101 return Changed(node); |
| 90 } | 102 } |
| 91 Decision const decision = DecideCondition(cond); | 103 Decision const decision = DecideCondition(cond); |
| 92 if (decision == Decision::kUnknown) return NoChange(); | 104 if (decision == Decision::kUnknown) return NoChange(); |
| 93 Node* const control = node->InputAt(1); | 105 Node* const control = node->InputAt(1); |
| 94 if (!dead_.is_set()) dead_.set(graph()->NewNode(common()->Dead())); | |
| 95 for (Node* const use : node->uses()) { | 106 for (Node* const use : node->uses()) { |
| 96 switch (use->opcode()) { | 107 switch (use->opcode()) { |
| 97 case IrOpcode::kIfTrue: | 108 case IrOpcode::kIfTrue: |
| 98 Replace(use, (decision == Decision::kTrue) ? control : dead_.get()); | 109 Replace(use, (decision == Decision::kTrue) ? control : dead()); |
| 99 break; | 110 break; |
| 100 case IrOpcode::kIfFalse: | 111 case IrOpcode::kIfFalse: |
| 101 Replace(use, (decision == Decision::kFalse) ? control : dead_.get()); | 112 Replace(use, (decision == Decision::kFalse) ? control : dead()); |
| 102 break; | 113 break; |
| 103 default: | 114 default: |
| 104 UNREACHABLE(); | 115 UNREACHABLE(); |
| 105 } | 116 } |
| 106 } | 117 } |
| 107 return Replace(dead_.get()); | 118 return Replace(dead()); |
| 108 } | 119 } |
| 109 | 120 |
| 110 | 121 |
| 111 Reduction CommonOperatorReducer::ReduceMerge(Node* node) { | 122 Reduction CommonOperatorReducer::ReduceMerge(Node* node) { |
| 112 DCHECK_EQ(IrOpcode::kMerge, node->opcode()); | 123 DCHECK_EQ(IrOpcode::kMerge, node->opcode()); |
| 113 // | 124 // |
| 114 // Check if this is a merge that belongs to an unused diamond, which means | 125 // Check if this is a merge that belongs to an unused diamond, which means |
| 115 // that: | 126 // that: |
| 116 // | 127 // |
| 117 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and | 128 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 continue; | 257 continue; |
| 247 } | 258 } |
| 248 if (input != value) return NoChange(); | 259 if (input != value) return NoChange(); |
| 249 } | 260 } |
| 250 // We might now be able to further reduce the {merge} node. | 261 // We might now be able to further reduce the {merge} node. |
| 251 Revisit(merge); | 262 Revisit(merge); |
| 252 return Replace(value); | 263 return Replace(value); |
| 253 } | 264 } |
| 254 | 265 |
| 255 | 266 |
| 267 Reduction CommonOperatorReducer::ReduceReturn(Node* node) { | |
| 268 DCHECK_EQ(IrOpcode::kReturn, node->opcode()); | |
| 269 Node* const value = node->InputAt(0); | |
| 270 Node* const effect = node->InputAt(1); | |
| 271 Node* const control = node->InputAt(2); | |
| 272 if (value->opcode() == IrOpcode::kPhi && | |
| 273 value->InputAt(value->InputCount() - 1) == control && | |
|
Jarin
2015/06/26 07:55:31
Please use NodeProperties::GetControlInput here.
Benedikt Meurer
2015/06/26 07:56:59
Done.
| |
| 274 effect->opcode() == IrOpcode::kEffectPhi && | |
| 275 effect->InputAt(effect->InputCount() - 1) == control && | |
| 276 control->opcode() == IrOpcode::kMerge) { | |
| 277 int const control_input_count = control->InputCount(); | |
| 278 DCHECK_NE(0, control_input_count); | |
| 279 DCHECK_EQ(control_input_count, value->InputCount() - 1); | |
| 280 DCHECK_EQ(control_input_count, effect->InputCount() - 1); | |
| 281 Node* const end = graph()->end(); | |
| 282 DCHECK_EQ(IrOpcode::kEnd, end->opcode()); | |
| 283 DCHECK_NE(0, end->InputCount()); | |
| 284 for (int i = 0; i < control_input_count; ++i) { | |
| 285 // Create a new {Return} and connect it to {end}. We don't need to mark | |
| 286 // {end} as revisit, because we mark {node} as {Dead} below, which was | |
| 287 // previously connected to {end}, so we know for sure that at some point | |
| 288 // the reducer logic will visit {end} again. | |
| 289 Node* ret = graph()->NewNode(common()->Return(), value->InputAt(i), | |
| 290 effect->InputAt(i), control->InputAt(i)); | |
| 291 end->set_op(common()->End(end->InputCount() + 1)); | |
| 292 end->AppendInput(graph()->zone(), ret); | |
| 293 } | |
| 294 // Mark the merge {control} and return {node} as {dead}. | |
| 295 Replace(control, dead()); | |
| 296 return Replace(dead()); | |
| 297 } | |
| 298 return NoChange(); | |
| 299 } | |
| 300 | |
| 301 | |
| 256 Reduction CommonOperatorReducer::ReduceSelect(Node* node) { | 302 Reduction CommonOperatorReducer::ReduceSelect(Node* node) { |
| 257 DCHECK_EQ(IrOpcode::kSelect, node->opcode()); | 303 DCHECK_EQ(IrOpcode::kSelect, node->opcode()); |
| 258 Node* const cond = node->InputAt(0); | 304 Node* const cond = node->InputAt(0); |
| 259 Node* const vtrue = node->InputAt(1); | 305 Node* const vtrue = node->InputAt(1); |
| 260 Node* const vfalse = node->InputAt(2); | 306 Node* const vfalse = node->InputAt(2); |
| 261 if (vtrue == vfalse) return Replace(vtrue); | 307 if (vtrue == vfalse) return Replace(vtrue); |
| 262 switch (DecideCondition(cond)) { | 308 switch (DecideCondition(cond)) { |
| 263 case Decision::kTrue: | 309 case Decision::kTrue: |
| 264 return Replace(vtrue); | 310 return Replace(vtrue); |
| 265 case Decision::kFalse: | 311 case Decision::kFalse: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 node->set_op(op); | 371 node->set_op(op); |
| 326 node->ReplaceInput(0, a); | 372 node->ReplaceInput(0, a); |
| 327 node->ReplaceInput(1, b); | 373 node->ReplaceInput(1, b); |
| 328 node->TrimInputCount(2); | 374 node->TrimInputCount(2); |
| 329 return Changed(node); | 375 return Changed(node); |
| 330 } | 376 } |
| 331 | 377 |
| 332 } // namespace compiler | 378 } // namespace compiler |
| 333 } // namespace internal | 379 } // namespace internal |
| 334 } // namespace v8 | 380 } // namespace v8 |
| OLD | NEW |