OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 2563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2574 length->set_type(HType::Smi()); | 2574 length->set_type(HType::Smi()); |
2575 HValue* checked_key = NULL; | 2575 HValue* checked_key = NULL; |
2576 if (IsFixedTypedArrayElementsKind(elements_kind)) { | 2576 if (IsFixedTypedArrayElementsKind(elements_kind)) { |
2577 checked_object = Add<HCheckArrayBufferNotNeutered>(checked_object); | 2577 checked_object = Add<HCheckArrayBufferNotNeutered>(checked_object); |
2578 | 2578 |
2579 HValue* external_pointer = Add<HLoadNamedField>( | 2579 HValue* external_pointer = Add<HLoadNamedField>( |
2580 elements, nullptr, | 2580 elements, nullptr, |
2581 HObjectAccess::ForFixedTypedArrayBaseExternalPointer()); | 2581 HObjectAccess::ForFixedTypedArrayBaseExternalPointer()); |
2582 HValue* base_pointer = Add<HLoadNamedField>( | 2582 HValue* base_pointer = Add<HLoadNamedField>( |
2583 elements, nullptr, HObjectAccess::ForFixedTypedArrayBaseBasePointer()); | 2583 elements, nullptr, HObjectAccess::ForFixedTypedArrayBaseBasePointer()); |
2584 HValue* backing_store = AddUncasted<HAdd>( | 2584 HValue* backing_store = AddUncasted<HAdd>(external_pointer, base_pointer, |
2585 external_pointer, base_pointer, Strength::WEAK, AddOfExternalAndTagged); | 2585 AddOfExternalAndTagged); |
2586 | 2586 |
2587 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2587 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
2588 NoObservableSideEffectsScope no_effects(this); | 2588 NoObservableSideEffectsScope no_effects(this); |
2589 IfBuilder length_checker(this); | 2589 IfBuilder length_checker(this); |
2590 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2590 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
2591 length_checker.Then(); | 2591 length_checker.Then(); |
2592 IfBuilder negative_checker(this); | 2592 IfBuilder negative_checker(this); |
2593 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2593 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
2594 key, graph()->GetConstant0(), Token::GTE); | 2594 key, graph()->GetConstant0(), Token::GTE); |
2595 negative_checker.Then(); | 2595 negative_checker.Then(); |
(...skipping 7697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10293 elements, HObjectAccess::ForFixedTypedArrayBaseExternalPointer(), | 10293 elements, HObjectAccess::ForFixedTypedArrayBaseExternalPointer(), |
10294 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset())); | 10294 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset())); |
10295 | 10295 |
10296 HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); | 10296 HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); |
10297 | 10297 |
10298 if (initialize) { | 10298 if (initialize) { |
10299 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); | 10299 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
10300 | 10300 |
10301 HValue* backing_store = AddUncasted<HAdd>( | 10301 HValue* backing_store = AddUncasted<HAdd>( |
10302 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), | 10302 Add<HConstant>(ExternalReference::fixed_typed_array_base_data_offset()), |
10303 elements, Strength::WEAK, AddOfExternalAndTagged); | 10303 elements, AddOfExternalAndTagged); |
10304 | 10304 |
10305 HValue* key = builder.BeginBody( | 10305 HValue* key = builder.BeginBody( |
10306 Add<HConstant>(static_cast<int32_t>(0)), | 10306 Add<HConstant>(static_cast<int32_t>(0)), |
10307 length, Token::LT); | 10307 length, Token::LT); |
10308 Add<HStoreKeyed>(backing_store, key, filler, elements, fixed_elements_kind); | 10308 Add<HStoreKeyed>(backing_store, key, filler, elements, fixed_elements_kind); |
10309 | 10309 |
10310 builder.EndBody(); | 10310 builder.EndBody(); |
10311 } | 10311 } |
10312 return elements; | 10312 return elements; |
10313 } | 10313 } |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10678 } | 10678 } |
10679 Push(number_input); | 10679 Push(number_input); |
10680 } | 10680 } |
10681 | 10681 |
10682 // The addition has no side effects, so we do not need | 10682 // The addition has no side effects, so we do not need |
10683 // to simulate the expression stack after this instruction. | 10683 // to simulate the expression stack after this instruction. |
10684 // Any later failures deopt to the load of the input or earlier. | 10684 // Any later failures deopt to the load of the input or earlier. |
10685 HConstant* delta = (expr->op() == Token::INC) | 10685 HConstant* delta = (expr->op() == Token::INC) |
10686 ? graph()->GetConstant1() | 10686 ? graph()->GetConstant1() |
10687 : graph()->GetConstantMinus1(); | 10687 : graph()->GetConstantMinus1(); |
10688 HInstruction* instr = | 10688 HInstruction* instr = AddUncasted<HAdd>(Top(), delta); |
10689 AddUncasted<HAdd>(Top(), delta, strength(function_language_mode())); | |
10690 if (instr->IsAdd()) { | 10689 if (instr->IsAdd()) { |
10691 HAdd* add = HAdd::cast(instr); | 10690 HAdd* add = HAdd::cast(instr); |
10692 add->set_observed_input_representation(1, rep); | 10691 add->set_observed_input_representation(1, rep); |
10693 add->set_observed_input_representation(2, Representation::Smi()); | 10692 add->set_observed_input_representation(2, Representation::Smi()); |
10694 } | 10693 } |
10695 if (!is_strong(function_language_mode())) { | 10694 if (!is_strong(function_language_mode())) { |
10696 instr->ClearAllSideEffects(); | 10695 instr->ClearAllSideEffects(); |
10697 } else { | 10696 } else { |
10698 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE); | 10697 Add<HSimulate>(expr->ToNumberId(), REMOVABLE_SIMULATE); |
10699 } | 10698 } |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10973 Type* result_type = expr->bounds().lower; | 10972 Type* result_type = expr->bounds().lower; |
10974 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 10973 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
10975 Handle<AllocationSite> allocation_site = expr->allocation_site(); | 10974 Handle<AllocationSite> allocation_site = expr->allocation_site(); |
10976 | 10975 |
10977 HAllocationMode allocation_mode; | 10976 HAllocationMode allocation_mode; |
10978 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { | 10977 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { |
10979 allocation_mode = HAllocationMode(allocation_site); | 10978 allocation_mode = HAllocationMode(allocation_site); |
10980 } | 10979 } |
10981 HValue* result = HGraphBuilder::BuildBinaryOperation( | 10980 HValue* result = HGraphBuilder::BuildBinaryOperation( |
10982 expr->op(), left, right, left_type, right_type, result_type, | 10981 expr->op(), left, right, left_type, right_type, result_type, |
10983 fixed_right_arg, allocation_mode, strength(function_language_mode()), | 10982 fixed_right_arg, allocation_mode, expr->id()); |
10984 expr->id()); | |
10985 // Add a simulate after instructions with observable side effects, and | 10983 // Add a simulate after instructions with observable side effects, and |
10986 // after phis, which are the result of BuildBinaryOperation when we | 10984 // after phis, which are the result of BuildBinaryOperation when we |
10987 // inlined some complex subgraph. | 10985 // inlined some complex subgraph. |
10988 if (result->HasObservableSideEffects() || result->IsPhi()) { | 10986 if (result->HasObservableSideEffects() || result->IsPhi()) { |
10989 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 10987 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
10990 Push(result); | 10988 Push(result); |
10991 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10989 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10992 Drop(1); | 10990 Drop(1); |
10993 } else { | 10991 } else { |
10994 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10992 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10995 } | 10993 } |
10996 } | 10994 } |
10997 return result; | 10995 return result; |
10998 } | 10996 } |
10999 | 10997 |
11000 | 10998 HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left, |
11001 HValue* HGraphBuilder::BuildBinaryOperation( | 10999 HValue* right, Type* left_type, |
11002 Token::Value op, HValue* left, HValue* right, Type* left_type, | 11000 Type* right_type, Type* result_type, |
11003 Type* right_type, Type* result_type, Maybe<int> fixed_right_arg, | 11001 Maybe<int> fixed_right_arg, |
11004 HAllocationMode allocation_mode, Strength strength, BailoutId opt_id) { | 11002 HAllocationMode allocation_mode, |
| 11003 BailoutId opt_id) { |
11005 bool maybe_string_add = false; | 11004 bool maybe_string_add = false; |
11006 if (op == Token::ADD) { | 11005 if (op == Token::ADD) { |
11007 // If we are adding constant string with something for which we don't have | 11006 // If we are adding constant string with something for which we don't have |
11008 // a feedback yet, assume that it's also going to be a string and don't | 11007 // a feedback yet, assume that it's also going to be a string and don't |
11009 // generate deopt instructions. | 11008 // generate deopt instructions. |
11010 if (!left_type->IsInhabited() && right->IsConstant() && | 11009 if (!left_type->IsInhabited() && right->IsConstant() && |
11011 HConstant::cast(right)->HasStringValue()) { | 11010 HConstant::cast(right)->HasStringValue()) { |
11012 left_type = Type::String(); | 11011 left_type = Type::String(); |
11013 } | 11012 } |
11014 | 11013 |
(...skipping 22 matching lines...) Expand all Loading... |
11037 | 11036 |
11038 if (!right_type->IsInhabited()) { | 11037 if (!right_type->IsInhabited()) { |
11039 Add<HDeoptimize>( | 11038 Add<HDeoptimize>( |
11040 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 11039 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
11041 Deoptimizer::SOFT); | 11040 Deoptimizer::SOFT); |
11042 right_type = Type::Any(); | 11041 right_type = Type::Any(); |
11043 right_rep = RepresentationFor(right_type); | 11042 right_rep = RepresentationFor(right_type); |
11044 maybe_string_add = op == Token::ADD; | 11043 maybe_string_add = op == Token::ADD; |
11045 } | 11044 } |
11046 | 11045 |
11047 if (!maybe_string_add && !is_strong(strength)) { | 11046 if (!maybe_string_add) { |
11048 left = TruncateToNumber(left, &left_type); | 11047 left = TruncateToNumber(left, &left_type); |
11049 right = TruncateToNumber(right, &right_type); | 11048 right = TruncateToNumber(right, &right_type); |
11050 } | 11049 } |
11051 | 11050 |
11052 // Special case for string addition here. | 11051 // Special case for string addition here. |
11053 if (op == Token::ADD && | 11052 if (op == Token::ADD && |
11054 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 11053 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
11055 if (is_strong(strength)) { | 11054 // Validate type feedback for left argument. |
11056 // In strong mode, if the one side of an addition is a string, | 11055 if (left_type->Is(Type::String())) { |
11057 // the other side must be a string too. | |
11058 left = BuildCheckString(left); | 11056 left = BuildCheckString(left); |
| 11057 } |
| 11058 |
| 11059 // Validate type feedback for right argument. |
| 11060 if (right_type->Is(Type::String())) { |
11059 right = BuildCheckString(right); | 11061 right = BuildCheckString(right); |
11060 } else { | 11062 } |
11061 // Validate type feedback for left argument. | |
11062 if (left_type->Is(Type::String())) { | |
11063 left = BuildCheckString(left); | |
11064 } | |
11065 | 11063 |
11066 // Validate type feedback for right argument. | 11064 // Convert left argument as necessary. |
11067 if (right_type->Is(Type::String())) { | 11065 if (left_type->Is(Type::Number())) { |
11068 right = BuildCheckString(right); | 11066 DCHECK(right_type->Is(Type::String())); |
11069 } | 11067 left = BuildNumberToString(left, left_type); |
| 11068 } else if (!left_type->Is(Type::String())) { |
| 11069 DCHECK(right_type->Is(Type::String())); |
| 11070 return AddUncasted<HStringAdd>( |
| 11071 left, right, allocation_mode.GetPretenureMode(), |
| 11072 STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); |
| 11073 } |
11070 | 11074 |
11071 // Convert left argument as necessary. | 11075 // Convert right argument as necessary. |
11072 if (left_type->Is(Type::Number())) { | 11076 if (right_type->Is(Type::Number())) { |
11073 DCHECK(right_type->Is(Type::String())); | 11077 DCHECK(left_type->Is(Type::String())); |
11074 left = BuildNumberToString(left, left_type); | 11078 right = BuildNumberToString(right, right_type); |
11075 } else if (!left_type->Is(Type::String())) { | 11079 } else if (!right_type->Is(Type::String())) { |
11076 DCHECK(right_type->Is(Type::String())); | 11080 DCHECK(left_type->Is(Type::String())); |
11077 return AddUncasted<HStringAdd>( | 11081 return AddUncasted<HStringAdd>( |
11078 left, right, allocation_mode.GetPretenureMode(), | 11082 left, right, allocation_mode.GetPretenureMode(), |
11079 STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); | 11083 STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); |
11080 } | |
11081 | |
11082 // Convert right argument as necessary. | |
11083 if (right_type->Is(Type::Number())) { | |
11084 DCHECK(left_type->Is(Type::String())); | |
11085 right = BuildNumberToString(right, right_type); | |
11086 } else if (!right_type->Is(Type::String())) { | |
11087 DCHECK(left_type->Is(Type::String())); | |
11088 return AddUncasted<HStringAdd>( | |
11089 left, right, allocation_mode.GetPretenureMode(), | |
11090 STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); | |
11091 } | |
11092 } | 11084 } |
11093 | 11085 |
11094 // Fast paths for empty constant strings. | 11086 // Fast paths for empty constant strings. |
11095 Handle<String> left_string = | 11087 Handle<String> left_string = |
11096 left->IsConstant() && HConstant::cast(left)->HasStringValue() | 11088 left->IsConstant() && HConstant::cast(left)->HasStringValue() |
11097 ? HConstant::cast(left)->StringValue() | 11089 ? HConstant::cast(left)->StringValue() |
11098 : Handle<String>(); | 11090 : Handle<String>(); |
11099 Handle<String> right_string = | 11091 Handle<String> right_string = |
11100 right->IsConstant() && HConstant::cast(right)->HasStringValue() | 11092 right->IsConstant() && HConstant::cast(right)->HasStringValue() |
11101 ? HConstant::cast(right)->StringValue() | 11093 ? HConstant::cast(right)->StringValue() |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11150 HInstruction* instr = NULL; | 11142 HInstruction* instr = NULL; |
11151 // Only the stub is allowed to call into the runtime, since otherwise we would | 11143 // Only the stub is allowed to call into the runtime, since otherwise we would |
11152 // inline several instructions (including the two pushes) for every tagged | 11144 // inline several instructions (including the two pushes) for every tagged |
11153 // operation in optimized code, which is more expensive, than a stub call. | 11145 // operation in optimized code, which is more expensive, than a stub call. |
11154 if (graph()->info()->IsStub() && is_non_primitive) { | 11146 if (graph()->info()->IsStub() && is_non_primitive) { |
11155 Runtime::FunctionId function_id; | 11147 Runtime::FunctionId function_id; |
11156 switch (op) { | 11148 switch (op) { |
11157 default: | 11149 default: |
11158 UNREACHABLE(); | 11150 UNREACHABLE(); |
11159 case Token::ADD: | 11151 case Token::ADD: |
11160 function_id = | 11152 function_id = Runtime::kAdd; |
11161 is_strong(strength) ? Runtime::kAdd_Strong : Runtime::kAdd; | |
11162 break; | 11153 break; |
11163 case Token::SUB: | 11154 case Token::SUB: |
11164 function_id = is_strong(strength) ? Runtime::kSubtract_Strong | 11155 function_id = Runtime::kSubtract; |
11165 : Runtime::kSubtract; | |
11166 break; | 11156 break; |
11167 case Token::MUL: | 11157 case Token::MUL: |
11168 function_id = is_strong(strength) ? Runtime::kMultiply_Strong | 11158 function_id = Runtime::kMultiply; |
11169 : Runtime::kMultiply; | |
11170 break; | 11159 break; |
11171 case Token::DIV: | 11160 case Token::DIV: |
11172 function_id = | 11161 function_id = Runtime::kDivide; |
11173 is_strong(strength) ? Runtime::kDivide_Strong : Runtime::kDivide; | |
11174 break; | 11162 break; |
11175 case Token::MOD: | 11163 case Token::MOD: |
11176 function_id = | 11164 function_id = Runtime::kModulus; |
11177 is_strong(strength) ? Runtime::kModulus_Strong : Runtime::kModulus; | |
11178 break; | 11165 break; |
11179 case Token::BIT_OR: | 11166 case Token::BIT_OR: |
11180 function_id = is_strong(strength) ? Runtime::kBitwiseOr_Strong | 11167 function_id = Runtime::kBitwiseOr; |
11181 : Runtime::kBitwiseOr; | |
11182 break; | 11168 break; |
11183 case Token::BIT_AND: | 11169 case Token::BIT_AND: |
11184 function_id = is_strong(strength) ? Runtime::kBitwiseAnd_Strong | 11170 function_id = Runtime::kBitwiseAnd; |
11185 : Runtime::kBitwiseAnd; | |
11186 break; | 11171 break; |
11187 case Token::BIT_XOR: | 11172 case Token::BIT_XOR: |
11188 function_id = is_strong(strength) ? Runtime::kBitwiseXor_Strong | 11173 function_id = Runtime::kBitwiseXor; |
11189 : Runtime::kBitwiseXor; | |
11190 break; | 11174 break; |
11191 case Token::SAR: | 11175 case Token::SAR: |
11192 function_id = is_strong(strength) ? Runtime::kShiftRight_Strong | 11176 function_id = Runtime::kShiftRight; |
11193 : Runtime::kShiftRight; | |
11194 break; | 11177 break; |
11195 case Token::SHR: | 11178 case Token::SHR: |
11196 function_id = is_strong(strength) ? Runtime::kShiftRightLogical_Strong | 11179 function_id = Runtime::kShiftRightLogical; |
11197 : Runtime::kShiftRightLogical; | |
11198 break; | 11180 break; |
11199 case Token::SHL: | 11181 case Token::SHL: |
11200 function_id = is_strong(strength) ? Runtime::kShiftLeft_Strong | 11182 function_id = Runtime::kShiftLeft; |
11201 : Runtime::kShiftLeft; | |
11202 break; | 11183 break; |
11203 } | 11184 } |
11204 Add<HPushArguments>(left, right); | 11185 Add<HPushArguments>(left, right); |
11205 instr = AddUncasted<HCallRuntime>(Runtime::FunctionForId(function_id), 2); | 11186 instr = AddUncasted<HCallRuntime>(Runtime::FunctionForId(function_id), 2); |
11206 } else { | 11187 } else { |
11207 if (is_strong(strength) && Token::IsBitOp(op)) { | |
11208 // TODO(conradw): This is not efficient, but is necessary to prevent | |
11209 // conversion of oddball values to numbers in strong mode. It would be | |
11210 // better to prevent the conversion rather than adding a runtime check. | |
11211 IfBuilder if_builder(this); | |
11212 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE); | |
11213 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE); | |
11214 if_builder.Then(); | |
11215 Add<HCallRuntime>( | |
11216 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), | |
11217 0); | |
11218 if (!graph()->info()->IsStub()) { | |
11219 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE); | |
11220 } | |
11221 if_builder.End(); | |
11222 } | |
11223 switch (op) { | 11188 switch (op) { |
11224 case Token::ADD: | 11189 case Token::ADD: |
11225 instr = AddUncasted<HAdd>(left, right, strength); | 11190 instr = AddUncasted<HAdd>(left, right); |
11226 break; | 11191 break; |
11227 case Token::SUB: | 11192 case Token::SUB: |
11228 instr = AddUncasted<HSub>(left, right, strength); | 11193 instr = AddUncasted<HSub>(left, right); |
11229 break; | 11194 break; |
11230 case Token::MUL: | 11195 case Token::MUL: |
11231 instr = AddUncasted<HMul>(left, right, strength); | 11196 instr = AddUncasted<HMul>(left, right); |
11232 break; | 11197 break; |
11233 case Token::MOD: { | 11198 case Token::MOD: { |
11234 if (fixed_right_arg.IsJust() && | 11199 if (fixed_right_arg.IsJust() && |
11235 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { | 11200 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { |
11236 HConstant* fixed_right = | 11201 HConstant* fixed_right = |
11237 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); | 11202 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); |
11238 IfBuilder if_same(this); | 11203 IfBuilder if_same(this); |
11239 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); | 11204 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); |
11240 if_same.Then(); | 11205 if_same.Then(); |
11241 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); | 11206 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); |
11242 right = fixed_right; | 11207 right = fixed_right; |
11243 } | 11208 } |
11244 instr = AddUncasted<HMod>(left, right, strength); | 11209 instr = AddUncasted<HMod>(left, right); |
11245 break; | 11210 break; |
11246 } | 11211 } |
11247 case Token::DIV: | 11212 case Token::DIV: |
11248 instr = AddUncasted<HDiv>(left, right, strength); | 11213 instr = AddUncasted<HDiv>(left, right); |
11249 break; | 11214 break; |
11250 case Token::BIT_XOR: | 11215 case Token::BIT_XOR: |
11251 case Token::BIT_AND: | 11216 case Token::BIT_AND: |
11252 instr = AddUncasted<HBitwise>(op, left, right, strength); | 11217 instr = AddUncasted<HBitwise>(op, left, right); |
11253 break; | 11218 break; |
11254 case Token::BIT_OR: { | 11219 case Token::BIT_OR: { |
11255 HValue *operand, *shift_amount; | 11220 HValue *operand, *shift_amount; |
11256 if (left_type->Is(Type::Signed32()) && | 11221 if (left_type->Is(Type::Signed32()) && |
11257 right_type->Is(Type::Signed32()) && | 11222 right_type->Is(Type::Signed32()) && |
11258 MatchRotateRight(left, right, &operand, &shift_amount)) { | 11223 MatchRotateRight(left, right, &operand, &shift_amount)) { |
11259 instr = AddUncasted<HRor>(operand, shift_amount, strength); | 11224 instr = AddUncasted<HRor>(operand, shift_amount); |
11260 } else { | 11225 } else { |
11261 instr = AddUncasted<HBitwise>(op, left, right, strength); | 11226 instr = AddUncasted<HBitwise>(op, left, right); |
11262 } | 11227 } |
11263 break; | 11228 break; |
11264 } | 11229 } |
11265 case Token::SAR: | 11230 case Token::SAR: |
11266 instr = AddUncasted<HSar>(left, right, strength); | 11231 instr = AddUncasted<HSar>(left, right); |
11267 break; | 11232 break; |
11268 case Token::SHR: | 11233 case Token::SHR: |
11269 instr = AddUncasted<HShr>(left, right, strength); | 11234 instr = AddUncasted<HShr>(left, right); |
11270 if (instr->IsShr() && CanBeZero(right)) { | 11235 if (instr->IsShr() && CanBeZero(right)) { |
11271 graph()->RecordUint32Instruction(instr); | 11236 graph()->RecordUint32Instruction(instr); |
11272 } | 11237 } |
11273 break; | 11238 break; |
11274 case Token::SHL: | 11239 case Token::SHL: |
11275 instr = AddUncasted<HShl>(left, right, strength); | 11240 instr = AddUncasted<HShl>(left, right); |
11276 break; | 11241 break; |
11277 default: | 11242 default: |
11278 UNREACHABLE(); | 11243 UNREACHABLE(); |
11279 } | 11244 } |
11280 } | 11245 } |
11281 | 11246 |
11282 if (instr->IsBinaryOperation()) { | 11247 if (instr->IsBinaryOperation()) { |
11283 HBinaryOperation* binop = HBinaryOperation::cast(instr); | 11248 HBinaryOperation* binop = HBinaryOperation::cast(instr); |
11284 binop->set_observed_input_representation(1, left_rep); | 11249 binop->set_observed_input_representation(1, left_rep); |
11285 binop->set_observed_input_representation(2, right_rep); | 11250 binop->set_observed_input_representation(2, right_rep); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11723 left, nullptr, | 11688 left, nullptr, |
11724 HObjectAccess::ForOddballToNumber(Representation::Smi())); | 11689 HObjectAccess::ForOddballToNumber(Representation::Smi())); |
11725 right = Add<HLoadNamedField>( | 11690 right = Add<HLoadNamedField>( |
11726 right, nullptr, | 11691 right, nullptr, |
11727 HObjectAccess::ForOddballToNumber(Representation::Smi())); | 11692 HObjectAccess::ForOddballToNumber(Representation::Smi())); |
11728 HCompareNumericAndBranch* result = | 11693 HCompareNumericAndBranch* result = |
11729 New<HCompareNumericAndBranch>(left, right, op); | 11694 New<HCompareNumericAndBranch>(left, right, op); |
11730 return result; | 11695 return result; |
11731 } else { | 11696 } else { |
11732 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 11697 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
11733 HCompareGeneric* result = Add<HCompareGeneric>( | 11698 HCompareGeneric* result = Add<HCompareGeneric>(left, right, op); |
11734 left, right, op, strength(function_language_mode())); | |
11735 result->set_observed_input_representation(1, left_rep); | 11699 result->set_observed_input_representation(1, left_rep); |
11736 result->set_observed_input_representation(2, right_rep); | 11700 result->set_observed_input_representation(2, right_rep); |
11737 if (result->HasObservableSideEffects()) { | 11701 if (result->HasObservableSideEffects()) { |
11738 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 11702 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
11739 Push(result); | 11703 Push(result); |
11740 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11704 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
11741 Drop(1); | 11705 Drop(1); |
11742 } else { | 11706 } else { |
11743 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11707 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
11744 } | 11708 } |
11745 } | 11709 } |
11746 // TODO(jkummerow): Can we make this more efficient? | 11710 // TODO(jkummerow): Can we make this more efficient? |
11747 HBranch* branch = New<HBranch>(result); | 11711 HBranch* branch = New<HBranch>(result); |
11748 return branch; | 11712 return branch; |
11749 } else { | 11713 } else { |
11750 HCompareNumericAndBranch* result = New<HCompareNumericAndBranch>( | 11714 HCompareNumericAndBranch* result = |
11751 left, right, op, strength(function_language_mode())); | 11715 New<HCompareNumericAndBranch>(left, right, op); |
11752 result->set_observed_input_representation(left_rep, right_rep); | 11716 result->set_observed_input_representation(left_rep, right_rep); |
11753 if (top_info()->is_tracking_positions()) { | 11717 if (top_info()->is_tracking_positions()) { |
11754 result->SetOperandPositions(zone(), left_position, right_position); | 11718 result->SetOperandPositions(zone(), left_position, right_position); |
11755 } | 11719 } |
11756 return result; | 11720 return result; |
11757 } | 11721 } |
11758 } | 11722 } |
11759 } | 11723 } |
11760 | 11724 |
11761 | 11725 |
(...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13613 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13577 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13614 } | 13578 } |
13615 | 13579 |
13616 #ifdef DEBUG | 13580 #ifdef DEBUG |
13617 graph_->Verify(false); // No full verify. | 13581 graph_->Verify(false); // No full verify. |
13618 #endif | 13582 #endif |
13619 } | 13583 } |
13620 | 13584 |
13621 } // namespace internal | 13585 } // namespace internal |
13622 } // namespace v8 | 13586 } // namespace v8 |
OLD | NEW |