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(); | |
8736 | 8735 |
8737 HValue* result = HGraphBuilder::BuildBinaryOperation( | 8736 HValue* result = HGraphBuilder::BuildBinaryOperation( |
8738 expr->op(), left, right, left_type, right_type, | 8737 expr->op(), left, right, left_type, right_type, result_type); |
8739 result_type, fixed_right_arg); | |
8740 // Add a simulate after instructions with observable side effects, and | 8738 // Add a simulate after instructions with observable side effects, and |
8741 // after phis, which are the result of BuildBinaryOperation when we | 8739 // after phis, which are the result of BuildBinaryOperation when we |
8742 // inlined some complex subgraph. | 8740 // inlined some complex subgraph. |
8743 if (result->HasObservableSideEffects() || result->IsPhi()) { | 8741 if (result->HasObservableSideEffects() || result->IsPhi()) { |
8744 Push(result); | 8742 Push(result); |
8745 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8743 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
8746 Drop(1); | 8744 Drop(1); |
8747 } | 8745 } |
8748 return result; | 8746 return result; |
8749 } | 8747 } |
8750 | 8748 |
8751 | 8749 |
8752 HValue* HGraphBuilder::BuildBinaryOperation( | 8750 HValue* HGraphBuilder::BuildBinaryOperation( |
8753 Token::Value op, | 8751 Token::Value op, |
8754 HValue* left, | 8752 HValue* left, |
8755 HValue* right, | 8753 HValue* right, |
8756 Handle<Type> left_type, | 8754 Handle<Type> left_type, |
8757 Handle<Type> right_type, | 8755 Handle<Type> right_type, |
8758 Handle<Type> result_type, | 8756 Handle<Type> result_type) { |
8759 Maybe<int> fixed_right_arg) { | |
8760 | 8757 |
8761 Representation left_rep = Representation::FromType(left_type); | 8758 Representation left_rep = Representation::FromType(left_type); |
8762 Representation right_rep = Representation::FromType(right_type); | 8759 Representation right_rep = Representation::FromType(right_type); |
8763 | 8760 |
8764 bool maybe_string_add = op == Token::ADD && | |
8765 (left_type->Maybe(Type::String()) || | |
8766 right_type->Maybe(Type::String())); | |
8767 | |
8768 if (left_type->Is(Type::None())) { | 8761 if (left_type->Is(Type::None())) { |
8769 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", | 8762 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", |
8770 Deoptimizer::SOFT); | 8763 Deoptimizer::SOFT); |
8771 // TODO(rossberg): we should be able to get rid of non-continuous | 8764 // TODO(rossberg): we should be able to get rid of non-continuous |
8772 // defaults. | 8765 // defaults. |
8773 left_type = handle(Type::Any(), isolate()); | 8766 left_type = handle(Type::Any(), isolate()); |
8774 } else { | 8767 } else if (left_type->IsConstant()) { |
8775 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); | 8768 HConstant* c_left = Add<HConstant>(left_type->AsConstant()); |
8776 left_rep = Representation::FromType(left_type); | 8769 IfBuilder if_same(this); |
| 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; |
8777 } | 8778 } |
8778 | 8779 |
8779 if (right_type->Is(Type::None())) { | 8780 if (right_type->Is(Type::None())) { |
8780 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", | 8781 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", |
8781 Deoptimizer::SOFT); | 8782 Deoptimizer::SOFT); |
8782 right_type = handle(Type::Any(), isolate()); | 8783 right_type = handle(Type::Any(), isolate()); |
8783 } else { | 8784 } else if (right_type->IsConstant()) { |
8784 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); | 8785 HConstant* c_right = Add<HConstant>(right_type->AsConstant()); |
8785 right_rep = Representation::FromType(right_type); | 8786 IfBuilder if_same(this); |
| 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; |
8786 } | 8795 } |
8787 | 8796 |
8788 // Special case for string addition here. | 8797 // Special case for string addition here. |
8789 if (op == Token::ADD && | 8798 if (op == Token::ADD && |
8790 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 8799 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
8791 // Validate type feedback for left argument. | 8800 // Validate type feedback for left argument. |
8792 if (left_type->Is(Type::String())) { | 8801 if (left_type->Is(Type::String())) { |
8793 left = BuildCheckString(left); | 8802 left = BuildCheckString(left); |
8794 } | 8803 } |
8795 | 8804 |
(...skipping 22 matching lines...) Expand all Loading... |
8818 ASSERT(left_type->Is(Type::String())); | 8827 ASSERT(left_type->Is(Type::String())); |
8819 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 8828 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
8820 Add<HPushArgument>(left); | 8829 Add<HPushArgument>(left); |
8821 Add<HPushArgument>(right); | 8830 Add<HPushArgument>(right); |
8822 return AddUncasted<HInvokeFunction>(function, 2); | 8831 return AddUncasted<HInvokeFunction>(function, 2); |
8823 } | 8832 } |
8824 | 8833 |
8825 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); | 8834 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); |
8826 } | 8835 } |
8827 | 8836 |
| 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 |
8828 if (graph()->info()->IsStub()) { | 8842 if (graph()->info()->IsStub()) { |
8829 left = EnforceNumberType(left, left_type); | 8843 left = EnforceNumberType(left, left_type); |
8830 right = EnforceNumberType(right, right_type); | 8844 right = EnforceNumberType(right, right_type); |
8831 } | 8845 } |
8832 | 8846 |
8833 Representation result_rep = Representation::FromType(result_type); | 8847 Representation result_rep = Representation::FromType(result_type); |
8834 | 8848 |
8835 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 8849 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
8836 (right_rep.IsTagged() && !right_rep.IsSmi()); | 8850 (right_rep.IsTagged() && !right_rep.IsSmi()); |
8837 | 8851 |
(...skipping 11 matching lines...) Expand all Loading... |
8849 case Token::ADD: | 8863 case Token::ADD: |
8850 instr = AddUncasted<HAdd>(left, right); | 8864 instr = AddUncasted<HAdd>(left, right); |
8851 break; | 8865 break; |
8852 case Token::SUB: | 8866 case Token::SUB: |
8853 instr = AddUncasted<HSub>(left, right); | 8867 instr = AddUncasted<HSub>(left, right); |
8854 break; | 8868 break; |
8855 case Token::MUL: | 8869 case Token::MUL: |
8856 instr = AddUncasted<HMul>(left, right); | 8870 instr = AddUncasted<HMul>(left, right); |
8857 break; | 8871 break; |
8858 case Token::MOD: { | 8872 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 } | |
8875 instr = AddUncasted<HMod>(left, right); | 8873 instr = AddUncasted<HMod>(left, right); |
8876 break; | 8874 break; |
8877 } | 8875 } |
8878 case Token::DIV: | 8876 case Token::DIV: |
8879 instr = AddUncasted<HDiv>(left, right); | 8877 instr = AddUncasted<HDiv>(left, right); |
8880 break; | 8878 break; |
8881 case Token::BIT_XOR: | 8879 case Token::BIT_XOR: |
8882 case Token::BIT_AND: | 8880 case Token::BIT_AND: |
8883 instr = AddUncasted<HBitwise>(op, left, right); | 8881 instr = AddUncasted<HBitwise>(op, left, right); |
8884 break; | 8882 break; |
(...skipping 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10808 if (ShouldProduceTraceOutput()) { | 10806 if (ShouldProduceTraceOutput()) { |
10809 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10807 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10810 } | 10808 } |
10811 | 10809 |
10812 #ifdef DEBUG | 10810 #ifdef DEBUG |
10813 graph_->Verify(false); // No full verify. | 10811 graph_->Verify(false); // No full verify. |
10814 #endif | 10812 #endif |
10815 } | 10813 } |
10816 | 10814 |
10817 } } // namespace v8::internal | 10815 } } // namespace v8::internal |
OLD | NEW |