OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 8714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8725 } | 8725 } |
8726 | 8726 |
8727 | 8727 |
8728 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( | 8728 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
8729 BinaryOperation* expr, | 8729 BinaryOperation* expr, |
8730 HValue* left, | 8730 HValue* left, |
8731 HValue* right) { | 8731 HValue* right) { |
8732 Handle<Type> left_type = expr->left()->bounds().lower; | 8732 Handle<Type> left_type = expr->left()->bounds().lower; |
8733 Handle<Type> right_type = expr->right()->bounds().lower; | 8733 Handle<Type> right_type = expr->right()->bounds().lower; |
8734 Handle<Type> result_type = expr->bounds().lower; | 8734 Handle<Type> result_type = expr->bounds().lower; |
| 8735 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
8735 | 8736 |
8736 HValue* result = HGraphBuilder::BuildBinaryOperation( | 8737 HValue* result = HGraphBuilder::BuildBinaryOperation( |
8737 expr->op(), left, right, left_type, right_type, result_type); | 8738 expr->op(), left, right, left_type, right_type, |
| 8739 result_type, fixed_right_arg); |
8738 // Add a simulate after instructions with observable side effects, and | 8740 // Add a simulate after instructions with observable side effects, and |
8739 // after phis, which are the result of BuildBinaryOperation when we | 8741 // after phis, which are the result of BuildBinaryOperation when we |
8740 // inlined some complex subgraph. | 8742 // inlined some complex subgraph. |
8741 if (result->HasObservableSideEffects() || result->IsPhi()) { | 8743 if (result->HasObservableSideEffects() || result->IsPhi()) { |
8742 Push(result); | 8744 Push(result); |
8743 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8745 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
8744 Drop(1); | 8746 Drop(1); |
8745 } | 8747 } |
8746 return result; | 8748 return result; |
8747 } | 8749 } |
8748 | 8750 |
8749 | 8751 |
8750 HValue* HGraphBuilder::BuildBinaryOperation( | 8752 HValue* HGraphBuilder::BuildBinaryOperation( |
8751 Token::Value op, | 8753 Token::Value op, |
8752 HValue* left, | 8754 HValue* left, |
8753 HValue* right, | 8755 HValue* right, |
8754 Handle<Type> left_type, | 8756 Handle<Type> left_type, |
8755 Handle<Type> right_type, | 8757 Handle<Type> right_type, |
8756 Handle<Type> result_type) { | 8758 Handle<Type> result_type, |
| 8759 Maybe<int> fixed_right_arg) { |
8757 | 8760 |
8758 Representation left_rep = Representation::FromType(left_type); | 8761 Representation left_rep = Representation::FromType(left_type); |
8759 Representation right_rep = Representation::FromType(right_type); | 8762 Representation right_rep = Representation::FromType(right_type); |
8760 | 8763 |
| 8764 bool maybe_string_add = op == Token::ADD && |
| 8765 (left_type->Maybe(Type::String()) || |
| 8766 right_type->Maybe(Type::String())); |
| 8767 |
8761 if (left_type->Is(Type::None())) { | 8768 if (left_type->Is(Type::None())) { |
8762 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", | 8769 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", |
8763 Deoptimizer::SOFT); | 8770 Deoptimizer::SOFT); |
8764 // TODO(rossberg): we should be able to get rid of non-continuous | 8771 // TODO(rossberg): we should be able to get rid of non-continuous |
8765 // defaults. | 8772 // defaults. |
8766 left_type = handle(Type::Any(), isolate()); | 8773 left_type = handle(Type::Any(), isolate()); |
8767 } else if (left_type->IsConstant()) { | 8774 } else { |
8768 HConstant* c_left = Add<HConstant>(left_type->AsConstant()); | 8775 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); |
8769 IfBuilder if_same(this); | 8776 left_rep = Representation::FromType(left_type); |
8770 if (c_left->HasDoubleValue()) { | |
8771 if_same.If<HCompareNumericAndBranch>(left, c_left, Token::EQ); | |
8772 } else { | |
8773 if_same.If<HCompareObjectEqAndBranch>(left, c_left); | |
8774 } | |
8775 if_same.Then(); | |
8776 if_same.ElseDeopt("Unexpected LHS of binary operation"); | |
8777 left = c_left; | |
8778 } | 8777 } |
8779 | 8778 |
8780 if (right_type->Is(Type::None())) { | 8779 if (right_type->Is(Type::None())) { |
8781 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", | 8780 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", |
8782 Deoptimizer::SOFT); | 8781 Deoptimizer::SOFT); |
8783 right_type = handle(Type::Any(), isolate()); | 8782 right_type = handle(Type::Any(), isolate()); |
8784 } else if (right_type->IsConstant()) { | 8783 } else { |
8785 HConstant* c_right = Add<HConstant>(right_type->AsConstant()); | 8784 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); |
8786 IfBuilder if_same(this); | 8785 right_rep = Representation::FromType(right_type); |
8787 if (c_right->HasDoubleValue()) { | |
8788 if_same.If<HCompareNumericAndBranch>(right, c_right, Token::EQ); | |
8789 } else { | |
8790 if_same.If<HCompareObjectEqAndBranch>(right, c_right); | |
8791 } | |
8792 if_same.Then(); | |
8793 if_same.ElseDeopt("Unexpected RHS of binary operation"); | |
8794 right = c_right; | |
8795 } | 8786 } |
8796 | 8787 |
8797 // Special case for string addition here. | 8788 // Special case for string addition here. |
8798 if (op == Token::ADD && | 8789 if (op == Token::ADD && |
8799 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 8790 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
8800 // Validate type feedback for left argument. | 8791 // Validate type feedback for left argument. |
8801 if (left_type->Is(Type::String())) { | 8792 if (left_type->Is(Type::String())) { |
8802 left = BuildCheckString(left); | 8793 left = BuildCheckString(left); |
8803 } | 8794 } |
8804 | 8795 |
(...skipping 22 matching lines...) Expand all Loading... |
8827 ASSERT(left_type->Is(Type::String())); | 8818 ASSERT(left_type->Is(Type::String())); |
8828 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 8819 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
8829 Add<HPushArgument>(left); | 8820 Add<HPushArgument>(left); |
8830 Add<HPushArgument>(right); | 8821 Add<HPushArgument>(right); |
8831 return AddUncasted<HInvokeFunction>(function, 2); | 8822 return AddUncasted<HInvokeFunction>(function, 2); |
8832 } | 8823 } |
8833 | 8824 |
8834 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); | 8825 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); |
8835 } | 8826 } |
8836 | 8827 |
8837 left = TruncateToNumber(left, &left_type); | |
8838 left_rep = Representation::FromType(left_type); | |
8839 right = TruncateToNumber(right, &right_type); | |
8840 right_rep = Representation::FromType(right_type); | |
8841 | |
8842 if (graph()->info()->IsStub()) { | 8828 if (graph()->info()->IsStub()) { |
8843 left = EnforceNumberType(left, left_type); | 8829 left = EnforceNumberType(left, left_type); |
8844 right = EnforceNumberType(right, right_type); | 8830 right = EnforceNumberType(right, right_type); |
8845 } | 8831 } |
8846 | 8832 |
8847 Representation result_rep = Representation::FromType(result_type); | 8833 Representation result_rep = Representation::FromType(result_type); |
8848 | 8834 |
8849 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 8835 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
8850 (right_rep.IsTagged() && !right_rep.IsSmi()); | 8836 (right_rep.IsTagged() && !right_rep.IsSmi()); |
8851 | 8837 |
(...skipping 11 matching lines...) Expand all Loading... |
8863 case Token::ADD: | 8849 case Token::ADD: |
8864 instr = AddUncasted<HAdd>(left, right); | 8850 instr = AddUncasted<HAdd>(left, right); |
8865 break; | 8851 break; |
8866 case Token::SUB: | 8852 case Token::SUB: |
8867 instr = AddUncasted<HSub>(left, right); | 8853 instr = AddUncasted<HSub>(left, right); |
8868 break; | 8854 break; |
8869 case Token::MUL: | 8855 case Token::MUL: |
8870 instr = AddUncasted<HMul>(left, right); | 8856 instr = AddUncasted<HMul>(left, right); |
8871 break; | 8857 break; |
8872 case Token::MOD: { | 8858 case Token::MOD: { |
| 8859 if (fixed_right_arg.has_value) { |
| 8860 if (right->IsConstant()) { |
| 8861 HConstant* c_right = HConstant::cast(right); |
| 8862 if (c_right->HasInteger32Value()) { |
| 8863 ASSERT_EQ(fixed_right_arg.value, c_right->Integer32Value()); |
| 8864 } |
| 8865 } else { |
| 8866 HConstant* fixed_right = Add<HConstant>( |
| 8867 static_cast<int>(fixed_right_arg.value)); |
| 8868 IfBuilder if_same(this); |
| 8869 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); |
| 8870 if_same.Then(); |
| 8871 if_same.ElseDeopt("Unexpected RHS of binary operation"); |
| 8872 right = fixed_right; |
| 8873 } |
| 8874 } |
8873 instr = AddUncasted<HMod>(left, right); | 8875 instr = AddUncasted<HMod>(left, right); |
8874 break; | 8876 break; |
8875 } | 8877 } |
8876 case Token::DIV: | 8878 case Token::DIV: |
8877 instr = AddUncasted<HDiv>(left, right); | 8879 instr = AddUncasted<HDiv>(left, right); |
8878 break; | 8880 break; |
8879 case Token::BIT_XOR: | 8881 case Token::BIT_XOR: |
8880 case Token::BIT_AND: | 8882 case Token::BIT_AND: |
8881 instr = AddUncasted<HBitwise>(op, left, right); | 8883 instr = AddUncasted<HBitwise>(op, left, right); |
8882 break; | 8884 break; |
(...skipping 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10806 if (ShouldProduceTraceOutput()) { | 10808 if (ShouldProduceTraceOutput()) { |
10807 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10809 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10808 } | 10810 } |
10809 | 10811 |
10810 #ifdef DEBUG | 10812 #ifdef DEBUG |
10811 graph_->Verify(false); // No full verify. | 10813 graph_->Verify(false); // No full verify. |
10812 #endif | 10814 #endif |
10813 } | 10815 } |
10814 | 10816 |
10815 } } // namespace v8::internal | 10817 } } // namespace v8::internal |
OLD | NEW |