| 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/control-reducer.h" | 6 #include "src/compiler/control-reducer.h" |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/node-marker.h" | 9 #include "src/compiler/node-marker.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 return ReduceSelect(node); | 426 return ReduceSelect(node); |
| 427 case IrOpcode::kPhi: | 427 case IrOpcode::kPhi: |
| 428 case IrOpcode::kEffectPhi: | 428 case IrOpcode::kEffectPhi: |
| 429 return ReducePhi(node); | 429 return ReducePhi(node); |
| 430 default: | 430 default: |
| 431 return node; | 431 return node; |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 | 434 |
| 435 // Try to statically fold a condition. | 435 // Try to statically fold a condition. |
| 436 Decision DecideCondition(Node* cond) { | 436 Decision DecideCondition(Node* cond, bool recurse = true) { |
| 437 switch (cond->opcode()) { | 437 switch (cond->opcode()) { |
| 438 case IrOpcode::kInt32Constant: | 438 case IrOpcode::kInt32Constant: |
| 439 return Int32Matcher(cond).Is(0) ? kFalse : kTrue; | 439 return Int32Matcher(cond).Is(0) ? kFalse : kTrue; |
| 440 case IrOpcode::kInt64Constant: | 440 case IrOpcode::kInt64Constant: |
| 441 return Int64Matcher(cond).Is(0) ? kFalse : kTrue; | 441 return Int64Matcher(cond).Is(0) ? kFalse : kTrue; |
| 442 case IrOpcode::kNumberConstant: | 442 case IrOpcode::kNumberConstant: |
| 443 return NumberMatcher(cond).Is(0) ? kFalse : kTrue; | 443 return NumberMatcher(cond).Is(0) ? kFalse : kTrue; |
| 444 case IrOpcode::kHeapConstant: { | 444 case IrOpcode::kHeapConstant: { |
| 445 Handle<Object> object = | 445 Handle<Object> object = |
| 446 HeapObjectMatcher<Object>(cond).Value().handle(); | 446 HeapObjectMatcher<Object>(cond).Value().handle(); |
| 447 if (object->IsTrue()) return kTrue; | 447 return object->BooleanValue() ? kTrue : kFalse; |
| 448 if (object->IsFalse()) return kFalse; | 448 } |
| 449 // TODO(turbofan): decide more conditions for heap constants. | 449 case IrOpcode::kPhi: { |
| 450 break; | 450 if (!recurse) return kUnknown; // Only go one level deep checking phis. |
| 451 Decision result = kUnknown; |
| 452 // Check if all inputs to a phi result in the same decision. |
| 453 for (int i = cond->op()->ValueInputCount() - 1; i >= 0; i--) { |
| 454 // Recurse only one level, since phis can be involved in cycles. |
| 455 Decision decision = DecideCondition(cond->InputAt(i), false); |
| 456 if (decision == kUnknown) return kUnknown; |
| 457 if (result == kUnknown) result = decision; |
| 458 if (result != decision) return kUnknown; |
| 459 } |
| 460 return result; |
| 451 } | 461 } |
| 452 default: | 462 default: |
| 453 break; | 463 break; |
| 454 } | 464 } |
| 465 if (NodeProperties::IsTyped(cond)) { |
| 466 // If the node has a range type, check whether the range excludes 0. |
| 467 Type* type = NodeProperties::GetBounds(cond).upper; |
| 468 if (type->IsRange() && (type->Min() > 0 || type->Max() < 0)) return kTrue; |
| 469 } |
| 455 return kUnknown; | 470 return kUnknown; |
| 456 } | 471 } |
| 457 | 472 |
| 458 // Reduce redundant selects. | 473 // Reduce redundant selects. |
| 459 Node* ReduceSelect(Node* const node) { | 474 Node* ReduceSelect(Node* const node) { |
| 460 Node* const tvalue = node->InputAt(1); | 475 Node* const tvalue = node->InputAt(1); |
| 461 Node* const fvalue = node->InputAt(2); | 476 Node* const fvalue = node->InputAt(2); |
| 462 if (tvalue == fvalue) return tvalue; | 477 if (tvalue == fvalue) return tvalue; |
| 463 Decision result = DecideCondition(node->InputAt(0)); | 478 Decision result = DecideCondition(node->InputAt(0)); |
| 464 if (result == kTrue) return tvalue; | 479 if (result == kTrue) return tvalue; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 return impl.ReduceIfProjection(node, kTrue); | 685 return impl.ReduceIfProjection(node, kTrue); |
| 671 case IrOpcode::kIfFalse: | 686 case IrOpcode::kIfFalse: |
| 672 return impl.ReduceIfProjection(node, kFalse); | 687 return impl.ReduceIfProjection(node, kFalse); |
| 673 default: | 688 default: |
| 674 return node; | 689 return node; |
| 675 } | 690 } |
| 676 } | 691 } |
| 677 } | 692 } |
| 678 } | 693 } |
| 679 } // namespace v8::internal::compiler | 694 } // namespace v8::internal::compiler |
| OLD | NEW |