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 |