| 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/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
| 6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
| 7 #include "src/compiler/js-builtin-reducer.h" | 7 #include "src/compiler/js-builtin-reducer.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/node-aux-data-inl.h" | 9 #include "src/compiler/node-aux-data-inl.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 520 } |
| 521 // TODO(turbofan): js-typed-lowering of ToString(x:boolean) | 521 // TODO(turbofan): js-typed-lowering of ToString(x:boolean) |
| 522 // TODO(turbofan): js-typed-lowering of ToString(x:number) | 522 // TODO(turbofan): js-typed-lowering of ToString(x:number) |
| 523 return NoChange(); | 523 return NoChange(); |
| 524 } | 524 } |
| 525 | 525 |
| 526 | 526 |
| 527 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { | 527 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { |
| 528 if (input->opcode() == IrOpcode::kJSToBoolean) { | 528 if (input->opcode() == IrOpcode::kJSToBoolean) { |
| 529 // Recursively try to reduce the input first. | 529 // Recursively try to reduce the input first. |
| 530 Reduction result = ReduceJSToBooleanInput(input->InputAt(0)); | 530 Reduction result = ReduceJSToBoolean(input); |
| 531 if (result.Changed()) { | 531 if (result.Changed()) return result; |
| 532 RelaxEffects(input); | |
| 533 return result; | |
| 534 } | |
| 535 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) | 532 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) |
| 536 } | 533 } |
| 537 Type* input_type = NodeProperties::GetBounds(input).upper; | 534 Type* input_type = NodeProperties::GetBounds(input).upper; |
| 538 if (input_type->Is(Type::Boolean())) { | 535 if (input_type->Is(Type::Boolean())) { |
| 539 return Changed(input); // JSToBoolean(x:boolean) => x | 536 return Changed(input); // JSToBoolean(x:boolean) => x |
| 540 } | 537 } |
| 541 if (input_type->Is(Type::Undefined())) { | 538 if (input_type->Is(Type::Undefined())) { |
| 542 // JSToBoolean(undefined) => #false | 539 // JSToBoolean(undefined) => #false |
| 543 return ReplaceWith(jsgraph()->FalseConstant()); | 540 return ReplaceWith(jsgraph()->FalseConstant()); |
| 544 } | 541 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 564 if (input_type->Is(Type::String())) { | 561 if (input_type->Is(Type::String())) { |
| 565 // JSToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0)) | 562 // JSToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0)) |
| 566 FieldAccess access = AccessBuilder::ForStringLength(); | 563 FieldAccess access = AccessBuilder::ForStringLength(); |
| 567 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 564 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 568 graph()->start(), graph()->start()); | 565 graph()->start(), graph()->start()); |
| 569 Node* cmp = graph()->NewNode(simplified()->NumberEqual(), length, | 566 Node* cmp = graph()->NewNode(simplified()->NumberEqual(), length, |
| 570 jsgraph()->ZeroConstant()); | 567 jsgraph()->ZeroConstant()); |
| 571 Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp); | 568 Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp); |
| 572 return ReplaceWith(inv); | 569 return ReplaceWith(inv); |
| 573 } | 570 } |
| 574 // TODO(turbofan): We need some kinda of PrimitiveToBoolean simplified | 571 return NoChange(); |
| 575 // operator, then we can do the pushing in the SimplifiedOperatorReducer | 572 } |
| 576 // and do not need to protect against stack overflow (because of backedges | 573 |
| 577 // in phis) below. | 574 |
| 578 if (input->opcode() == IrOpcode::kPhi && | 575 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 579 input_type->Is( | 576 // Try to reduce the input first. |
| 580 Type::Union(Type::Boolean(), Type::OrderedNumber(), zone()))) { | 577 Node* const input = node->InputAt(0); |
| 581 // JSToBoolean(phi(x1,...,xn):ordered-number|boolean) | 578 Reduction reduction = ReduceJSToBooleanInput(input); |
| 582 // => phi(JSToBoolean(x1),...,JSToBoolean(xn)) | 579 if (reduction.Changed()) { |
| 583 int input_count = input->InputCount() - 1; | 580 NodeProperties::ReplaceWithValue(node, reduction.replacement()); |
| 584 Node** inputs = zone()->NewArray<Node*>(input_count + 1); | 581 return reduction; |
| 582 } |
| 583 Type* const input_type = NodeProperties::GetBounds(input).upper; |
| 584 if (input->opcode() == IrOpcode::kPhi && input_type->Is(Type::Primitive())) { |
| 585 // JSToBoolean(phi(x1,...,xn,control):primitive) |
| 586 // => phi(JSToBoolean(x1),...,JSToBoolean(xn),control):boolean |
| 587 RelaxEffects(node); |
| 588 int const input_count = input->InputCount() - 1; |
| 589 Node* const control = input->InputAt(input_count); |
| 590 DCHECK_LE(0, input_count); |
| 591 DCHECK(NodeProperties::IsControl(control)); |
| 592 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean())); |
| 593 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean())); |
| 594 node->set_op(common()->Phi(kMachAnyTagged, input_count)); |
| 585 for (int i = 0; i < input_count; ++i) { | 595 for (int i = 0; i < input_count; ++i) { |
| 586 Node* value = input->InputAt(i); | 596 Node* value = input->InputAt(i); |
| 587 Type* value_type = NodeProperties::GetBounds(value).upper; | |
| 588 // Recursively try to reduce the value first. | 597 // Recursively try to reduce the value first. |
| 589 Reduction result = (value_type->Is(Type::Boolean()) || | 598 Reduction reduction = ReduceJSToBooleanInput(value); |
| 590 value_type->Is(Type::OrderedNumber())) | 599 if (reduction.Changed()) { |
| 591 ? ReduceJSToBooleanInput(value) | 600 value = reduction.replacement(); |
| 592 : NoChange(); | |
| 593 if (result.Changed()) { | |
| 594 inputs[i] = result.replacement(); | |
| 595 } else { | 601 } else { |
| 596 inputs[i] = graph()->NewNode(javascript()->ToBoolean(), value, | 602 value = graph()->NewNode(javascript()->ToBoolean(), value, |
| 597 jsgraph()->ZeroConstant(), | 603 jsgraph()->ZeroConstant(), graph()->start(), |
| 598 graph()->start(), graph()->start()); | 604 graph()->start()); |
| 605 } |
| 606 if (i < node->InputCount()) { |
| 607 node->ReplaceInput(i, value); |
| 608 } else { |
| 609 node->AppendInput(graph()->zone(), value); |
| 599 } | 610 } |
| 600 } | 611 } |
| 601 inputs[input_count] = input->InputAt(input_count); | 612 if (input_count < node->InputCount()) { |
| 602 Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, input_count), | 613 node->ReplaceInput(input_count, control); |
| 603 input_count + 1, inputs); | 614 } else { |
| 604 return ReplaceWith(phi); | 615 node->AppendInput(graph()->zone(), control); |
| 616 } |
| 617 node->TrimInputCount(input_count + 1); |
| 618 return Changed(node); |
| 605 } | 619 } |
| 606 return NoChange(); | 620 return NoChange(); |
| 607 } | 621 } |
| 608 | 622 |
| 609 | 623 |
| 610 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { | 624 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { |
| 611 Node* key = NodeProperties::GetValueInput(node, 1); | 625 Node* key = NodeProperties::GetValueInput(node, 1); |
| 612 Node* base = NodeProperties::GetValueInput(node, 0); | 626 Node* base = NodeProperties::GetValueInput(node, 0); |
| 613 Type* key_type = NodeProperties::GetBounds(key).upper; | 627 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 614 Type* base_type = NodeProperties::GetBounds(base).upper; | 628 Type* base_type = NodeProperties::GetBounds(base).upper; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 // JSUnaryNot(x) => BooleanNot(JSToBoolean(x)) | 760 // JSUnaryNot(x) => BooleanNot(JSToBoolean(x)) |
| 747 value = graph()->NewNode(simplified()->BooleanNot(), node); | 761 value = graph()->NewNode(simplified()->BooleanNot(), node); |
| 748 node->set_op(javascript()->ToBoolean()); | 762 node->set_op(javascript()->ToBoolean()); |
| 749 NodeProperties::ReplaceWithValue(node, value, node); | 763 NodeProperties::ReplaceWithValue(node, value, node); |
| 750 // Note: ReplaceUses() smashes all uses, so smash it back here. | 764 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 751 value->ReplaceInput(0, node); | 765 value->ReplaceInput(0, node); |
| 752 return Changed(node); | 766 return Changed(node); |
| 753 } | 767 } |
| 754 } | 768 } |
| 755 case IrOpcode::kJSToBoolean: | 769 case IrOpcode::kJSToBoolean: |
| 756 return ReplaceWithReduction(node, | 770 return ReduceJSToBoolean(node); |
| 757 ReduceJSToBooleanInput(node->InputAt(0))); | |
| 758 case IrOpcode::kJSToNumber: | 771 case IrOpcode::kJSToNumber: |
| 759 return ReplaceWithReduction(node, | 772 return ReplaceWithReduction(node, |
| 760 ReduceJSToNumberInput(node->InputAt(0))); | 773 ReduceJSToNumberInput(node->InputAt(0))); |
| 761 case IrOpcode::kJSToString: | 774 case IrOpcode::kJSToString: |
| 762 return ReplaceWithReduction(node, | 775 return ReplaceWithReduction(node, |
| 763 ReduceJSToStringInput(node->InputAt(0))); | 776 ReduceJSToStringInput(node->InputAt(0))); |
| 764 case IrOpcode::kJSLoadProperty: | 777 case IrOpcode::kJSLoadProperty: |
| 765 return ReduceJSLoadProperty(node); | 778 return ReduceJSLoadProperty(node); |
| 766 case IrOpcode::kJSStoreProperty: | 779 case IrOpcode::kJSStoreProperty: |
| 767 return ReduceJSStoreProperty(node); | 780 return ReduceJSStoreProperty(node); |
| 768 case IrOpcode::kJSCallFunction: | 781 case IrOpcode::kJSCallFunction: |
| 769 return JSBuiltinReducer(jsgraph()).Reduce(node); | 782 return JSBuiltinReducer(jsgraph()).Reduce(node); |
| 770 default: | 783 default: |
| 771 break; | 784 break; |
| 772 } | 785 } |
| 773 return NoChange(); | 786 return NoChange(); |
| 774 } | 787 } |
| 775 | 788 |
| 776 } // namespace compiler | 789 } // namespace compiler |
| 777 } // namespace internal | 790 } // namespace internal |
| 778 } // namespace v8 | 791 } // namespace v8 |
| OLD | NEW |