| 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 NodeProperties::ChangeOp(branch, common()->Dead()); | 188 NodeProperties::ChangeOp(branch, common()->Dead()); |
| 189 return Replace(control); | 189 return Replace(control); |
| 190 } | 190 } |
| 191 } | 191 } |
| 192 return NoChange(); | 192 return NoChange(); |
| 193 } | 193 } |
| 194 | 194 |
| 195 | 195 |
| 196 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { | 196 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { |
| 197 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); | 197 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); |
| 198 int const input_count = node->InputCount() - 1; | 198 Node::Inputs inputs = node->inputs(); |
| 199 DCHECK_LE(1, input_count); | 199 int const effect_input_count = inputs.count() - 1; |
| 200 Node* const merge = node->InputAt(input_count); | 200 DCHECK_LE(1, effect_input_count); |
| 201 Node* const merge = inputs[effect_input_count]; |
| 201 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); | 202 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
| 202 DCHECK_EQ(input_count, merge->InputCount()); | 203 DCHECK_EQ(effect_input_count, merge->InputCount()); |
| 203 Node* const effect = node->InputAt(0); | 204 Node* const effect = inputs[0]; |
| 204 DCHECK_NE(node, effect); | 205 DCHECK_NE(node, effect); |
| 205 for (int i = 1; i < input_count; ++i) { | 206 for (int i = 1; i < effect_input_count; ++i) { |
| 206 Node* const input = node->InputAt(i); | 207 Node* const input = inputs[i]; |
| 207 if (input == node) { | 208 if (input == node) { |
| 208 // Ignore redundant inputs. | 209 // Ignore redundant inputs. |
| 209 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); | 210 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); |
| 210 continue; | 211 continue; |
| 211 } | 212 } |
| 212 if (input != effect) return NoChange(); | 213 if (input != effect) return NoChange(); |
| 213 } | 214 } |
| 214 // We might now be able to further reduce the {merge} node. | 215 // We might now be able to further reduce the {merge} node. |
| 215 Revisit(merge); | 216 Revisit(merge); |
| 216 return Replace(effect); | 217 return Replace(effect); |
| 217 } | 218 } |
| 218 | 219 |
| 219 | 220 |
| 220 Reduction CommonOperatorReducer::ReducePhi(Node* node) { | 221 Reduction CommonOperatorReducer::ReducePhi(Node* node) { |
| 221 DCHECK_EQ(IrOpcode::kPhi, node->opcode()); | 222 DCHECK_EQ(IrOpcode::kPhi, node->opcode()); |
| 222 int const input_count = node->InputCount() - 1; | 223 Node::Inputs inputs = node->inputs(); |
| 223 DCHECK_LE(1, input_count); | 224 int const value_input_count = inputs.count() - 1; |
| 224 Node* const merge = node->InputAt(input_count); | 225 DCHECK_LE(1, value_input_count); |
| 226 Node* const merge = inputs[value_input_count]; |
| 225 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); | 227 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
| 226 DCHECK_EQ(input_count, merge->InputCount()); | 228 DCHECK_EQ(value_input_count, merge->InputCount()); |
| 227 if (input_count == 2) { | 229 if (value_input_count == 2) { |
| 228 Node* vtrue = node->InputAt(0); | 230 Node* vtrue = inputs[0]; |
| 229 Node* vfalse = node->InputAt(1); | 231 Node* vfalse = inputs[1]; |
| 230 Node* if_true = merge->InputAt(0); | 232 Node::Inputs merge_inputs = merge->inputs(); |
| 231 Node* if_false = merge->InputAt(1); | 233 Node* if_true = merge_inputs[0]; |
| 234 Node* if_false = merge_inputs[1]; |
| 232 if (if_true->opcode() != IrOpcode::kIfTrue) { | 235 if (if_true->opcode() != IrOpcode::kIfTrue) { |
| 233 std::swap(if_true, if_false); | 236 std::swap(if_true, if_false); |
| 234 std::swap(vtrue, vfalse); | 237 std::swap(vtrue, vfalse); |
| 235 } | 238 } |
| 236 if (if_true->opcode() == IrOpcode::kIfTrue && | 239 if (if_true->opcode() == IrOpcode::kIfTrue && |
| 237 if_false->opcode() == IrOpcode::kIfFalse && | 240 if_false->opcode() == IrOpcode::kIfFalse && |
| 238 if_true->InputAt(0) == if_false->InputAt(0)) { | 241 if_true->InputAt(0) == if_false->InputAt(0)) { |
| 239 Node* const branch = if_true->InputAt(0); | 242 Node* const branch = if_true->InputAt(0); |
| 240 // Check that the branch is not dead already. | 243 // Check that the branch is not dead already. |
| 241 if (branch->opcode() != IrOpcode::kBranch) return NoChange(); | 244 if (branch->opcode() != IrOpcode::kBranch) return NoChange(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 258 Float64BinopMatcher mvfalse(vfalse); | 261 Float64BinopMatcher mvfalse(vfalse); |
| 259 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { | 262 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { |
| 260 // We might now be able to further reduce the {merge} node. | 263 // We might now be able to further reduce the {merge} node. |
| 261 Revisit(merge); | 264 Revisit(merge); |
| 262 return Change(node, machine()->Float64Abs(), vtrue); | 265 return Change(node, machine()->Float64Abs(), vtrue); |
| 263 } | 266 } |
| 264 } | 267 } |
| 265 } | 268 } |
| 266 } | 269 } |
| 267 } | 270 } |
| 268 Node* const value = node->InputAt(0); | 271 Node* const value = inputs[0]; |
| 269 DCHECK_NE(node, value); | 272 DCHECK_NE(node, value); |
| 270 for (int i = 1; i < input_count; ++i) { | 273 for (int i = 1; i < value_input_count; ++i) { |
| 271 Node* const input = node->InputAt(i); | 274 Node* const input = inputs[i]; |
| 272 if (input == node) { | 275 if (input == node) { |
| 273 // Ignore redundant inputs. | 276 // Ignore redundant inputs. |
| 274 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); | 277 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); |
| 275 continue; | 278 continue; |
| 276 } | 279 } |
| 277 if (input != value) return NoChange(); | 280 if (input != value) return NoChange(); |
| 278 } | 281 } |
| 279 // We might now be able to further reduce the {merge} node. | 282 // We might now be able to further reduce the {merge} node. |
| 280 Revisit(merge); | 283 Revisit(merge); |
| 281 return Replace(value); | 284 return Replace(value); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 293 // hence checkpoints can be cut out of the effect chain flowing into it. | 296 // hence checkpoints can be cut out of the effect chain flowing into it. |
| 294 effect = NodeProperties::GetEffectInput(effect); | 297 effect = NodeProperties::GetEffectInput(effect); |
| 295 NodeProperties::ReplaceEffectInput(node, effect); | 298 NodeProperties::ReplaceEffectInput(node, effect); |
| 296 changed = true; | 299 changed = true; |
| 297 } | 300 } |
| 298 if (value->opcode() == IrOpcode::kPhi && | 301 if (value->opcode() == IrOpcode::kPhi && |
| 299 NodeProperties::GetControlInput(value) == control && | 302 NodeProperties::GetControlInput(value) == control && |
| 300 effect->opcode() == IrOpcode::kEffectPhi && | 303 effect->opcode() == IrOpcode::kEffectPhi && |
| 301 NodeProperties::GetControlInput(effect) == control && | 304 NodeProperties::GetControlInput(effect) == control && |
| 302 control->opcode() == IrOpcode::kMerge) { | 305 control->opcode() == IrOpcode::kMerge) { |
| 303 int const control_input_count = control->InputCount(); | 306 Node::Inputs control_inputs = control->inputs(); |
| 304 DCHECK_NE(0, control_input_count); | 307 Node::Inputs value_inputs = value->inputs(); |
| 305 DCHECK_EQ(control_input_count, value->InputCount() - 1); | 308 Node::Inputs effect_inputs = effect->inputs(); |
| 306 DCHECK_EQ(control_input_count, effect->InputCount() - 1); | 309 DCHECK_NE(0, control_inputs.count()); |
| 310 DCHECK_EQ(control_inputs.count(), value_inputs.count() - 1); |
| 311 DCHECK_EQ(control_inputs.count(), effect_inputs.count() - 1); |
| 307 DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode()); | 312 DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode()); |
| 308 DCHECK_NE(0, graph()->end()->InputCount()); | 313 DCHECK_NE(0, graph()->end()->InputCount()); |
| 309 for (int i = 0; i < control_input_count; ++i) { | 314 for (int i = 0; i < control_inputs.count(); ++i) { |
| 310 // Create a new {Return} and connect it to {end}. We don't need to mark | 315 // Create a new {Return} and connect it to {end}. We don't need to mark |
| 311 // {end} as revisit, because we mark {node} as {Dead} below, which was | 316 // {end} as revisit, because we mark {node} as {Dead} below, which was |
| 312 // previously connected to {end}, so we know for sure that at some point | 317 // previously connected to {end}, so we know for sure that at some point |
| 313 // the reducer logic will visit {end} again. | 318 // the reducer logic will visit {end} again. |
| 314 Node* ret = graph()->NewNode(common()->Return(), node->InputAt(0), | 319 Node* ret = graph()->NewNode(common()->Return(), node->InputAt(0), |
| 315 value->InputAt(i), effect->InputAt(i), | 320 value_inputs[i], effect_inputs[i], |
| 316 control->InputAt(i)); | 321 control_inputs[i]); |
| 317 NodeProperties::MergeControlToEnd(graph(), common(), ret); | 322 NodeProperties::MergeControlToEnd(graph(), common(), ret); |
| 318 } | 323 } |
| 319 // Mark the merge {control} and return {node} as {dead}. | 324 // Mark the merge {control} and return {node} as {dead}. |
| 320 Replace(control, dead()); | 325 Replace(control, dead()); |
| 321 return Replace(dead()); | 326 return Replace(dead()); |
| 322 } | 327 } |
| 323 return changed ? Changed(node) : NoChange(); | 328 return changed ? Changed(node) : NoChange(); |
| 324 } | 329 } |
| 325 | 330 |
| 326 | 331 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 node->ReplaceInput(0, a); | 387 node->ReplaceInput(0, a); |
| 383 node->ReplaceInput(1, b); | 388 node->ReplaceInput(1, b); |
| 384 node->TrimInputCount(2); | 389 node->TrimInputCount(2); |
| 385 NodeProperties::ChangeOp(node, op); | 390 NodeProperties::ChangeOp(node, op); |
| 386 return Changed(node); | 391 return Changed(node); |
| 387 } | 392 } |
| 388 | 393 |
| 389 } // namespace compiler | 394 } // namespace compiler |
| 390 } // namespace internal | 395 } // namespace internal |
| 391 } // namespace v8 | 396 } // namespace v8 |
| OLD | NEW |