Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(980)

Side by Side Diff: src/hydrogen.cc

Issue 12315005: Constant fold math and string operations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 ElementsKind kind, 962 ElementsKind kind,
963 HValue* capacity) { 963 HValue* capacity) {
964 Zone* zone = this->zone(); 964 Zone* zone = this->zone();
965 965
966 int elements_size = IsFastDoubleElementsKind(kind) 966 int elements_size = IsFastDoubleElementsKind(kind)
967 ? kDoubleSize : kPointerSize; 967 ? kDoubleSize : kPointerSize;
968 HConstant* elements_size_value = 968 HConstant* elements_size_value =
969 new(zone) HConstant(elements_size, Representation::Integer32()); 969 new(zone) HConstant(elements_size, Representation::Integer32());
970 AddInstruction(elements_size_value); 970 AddInstruction(elements_size_value);
971 HValue* mul = AddInstruction( 971 HValue* mul = AddInstruction(
972 new(zone) HMul(context, capacity, elements_size_value)); 972 HMul::New(zone, context, capacity, elements_size_value));
973 mul->ChangeRepresentation(Representation::Integer32()); 973 mul->ChangeRepresentation(Representation::Integer32());
974 mul->ClearFlag(HValue::kCanOverflow); 974 mul->ClearFlag(HValue::kCanOverflow);
975 975
976 HConstant* header_size = 976 HConstant* header_size =
977 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); 977 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
978 AddInstruction(header_size); 978 AddInstruction(header_size);
979 HValue* total_size = AddInstruction( 979 HValue* total_size = AddInstruction(
980 new(zone) HAdd(context, mul, header_size)); 980 HAdd::New(zone, context, mul, header_size));
981 total_size->ChangeRepresentation(Representation::Integer32()); 981 total_size->ChangeRepresentation(Representation::Integer32());
982 total_size->ClearFlag(HValue::kCanOverflow); 982 total_size->ClearFlag(HValue::kCanOverflow);
983 983
984 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 984 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
985 if (IsFastDoubleElementsKind(kind)) { 985 if (IsFastDoubleElementsKind(kind)) {
986 flags = static_cast<HAllocate::Flags>( 986 flags = static_cast<HAllocate::Flags>(
987 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); 987 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
988 } 988 }
989 989
990 HValue* elements = 990 HValue* elements =
(...skipping 6114 matching lines...) Expand 10 before | Expand all | Expand 10 after
7105 if (expr->AsProperty()->IsArrayLength()) { 7105 if (expr->AsProperty()->IsArrayLength()) {
7106 HValue* array = Pop(); 7106 HValue* array = Pop();
7107 AddInstruction(new(zone()) HCheckNonSmi(array)); 7107 AddInstruction(new(zone()) HCheckNonSmi(array));
7108 HInstruction* mapcheck = 7108 HInstruction* mapcheck =
7109 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); 7109 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone()));
7110 instr = new(zone()) HJSArrayLength(array, mapcheck); 7110 instr = new(zone()) HJSArrayLength(array, mapcheck);
7111 } else if (expr->IsStringLength()) { 7111 } else if (expr->IsStringLength()) {
7112 HValue* string = Pop(); 7112 HValue* string = Pop();
7113 AddInstruction(new(zone()) HCheckNonSmi(string)); 7113 AddInstruction(new(zone()) HCheckNonSmi(string));
7114 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7114 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7115 instr = new(zone()) HStringLength(string); 7115 instr = HStringLength::New(zone(), string);
7116 } else if (expr->IsStringAccess()) { 7116 } else if (expr->IsStringAccess()) {
7117 CHECK_ALIVE(VisitForValue(expr->key())); 7117 CHECK_ALIVE(VisitForValue(expr->key()));
7118 HValue* index = Pop(); 7118 HValue* index = Pop();
7119 HValue* string = Pop(); 7119 HValue* string = Pop();
7120 HValue* context = environment()->LookupContext(); 7120 HValue* context = environment()->LookupContext();
7121 HStringCharCodeAt* char_code = 7121 HInstruction* char_code =
7122 BuildStringCharCodeAt(context, string, index); 7122 BuildStringCharCodeAt(context, string, index);
7123 AddInstruction(char_code); 7123 AddInstruction(char_code);
7124 instr = new(zone()) HStringCharFromCode(context, char_code); 7124 instr = HStringCharFromCode::New(zone(), context, char_code);
7125 7125
7126 } else if (expr->IsFunctionPrototype()) { 7126 } else if (expr->IsFunctionPrototype()) {
7127 HValue* function = Pop(); 7127 HValue* function = Pop();
7128 AddInstruction(new(zone()) HCheckNonSmi(function)); 7128 AddInstruction(new(zone()) HCheckNonSmi(function));
7129 instr = new(zone()) HLoadFunctionPrototype(function); 7129 instr = new(zone()) HLoadFunctionPrototype(function);
7130 7130
7131 } else if (expr->key()->IsPropertyName()) { 7131 } else if (expr->key()->IsPropertyName()) {
7132 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7132 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
7133 SmallMapList* types = expr->GetReceiverTypes(); 7133 SmallMapList* types = expr->GetReceiverTypes();
7134 HValue* object = Top(); 7134 HValue* object = Top();
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
7784 7784
7785 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, 7785 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr,
7786 bool drop_extra) { 7786 bool drop_extra) {
7787 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 7787 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
7788 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 7788 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
7789 switch (id) { 7789 switch (id) {
7790 case kMathExp: 7790 case kMathExp:
7791 if (!FLAG_fast_math) break; 7791 if (!FLAG_fast_math) break;
7792 // Fall through if FLAG_fast_math. 7792 // Fall through if FLAG_fast_math.
7793 case kMathRound: 7793 case kMathRound:
7794 case kMathFloor:
7794 case kMathAbs: 7795 case kMathAbs:
7795 case kMathSqrt: 7796 case kMathSqrt:
7796 case kMathLog: 7797 case kMathLog:
7797 case kMathSin: 7798 case kMathSin:
7798 case kMathCos: 7799 case kMathCos:
7799 case kMathTan: 7800 case kMathTan:
7800 if (expr->arguments()->length() == 1) { 7801 if (expr->arguments()->length() == 1) {
7801 HValue* argument = Pop(); 7802 HValue* argument = Pop();
7802 HValue* context = environment()->LookupContext(); 7803 HValue* context = environment()->LookupContext();
7803 Drop(1); // Receiver. 7804 Drop(1); // Receiver.
7804 HUnaryMathOperation* op = 7805 HInstruction* op =
7805 new(zone()) HUnaryMathOperation(context, argument, id); 7806 HUnaryMathOperation::New(zone(), context, argument, id);
7806 op->set_position(expr->position()); 7807 op->set_position(expr->position());
7807 if (drop_extra) Drop(1); // Optionally drop the function. 7808 if (drop_extra) Drop(1); // Optionally drop the function.
7808 ast_context()->ReturnInstruction(op, expr->id()); 7809 ast_context()->ReturnInstruction(op, expr->id());
7809 return true; 7810 return true;
7810 } 7811 }
7811 break; 7812 break;
7812 default: 7813 default:
7813 // Not supported for inlining yet. 7814 // Not supported for inlining yet.
7814 break; 7815 break;
7815 } 7816 }
(...skipping 16 matching lines...) Expand all
7832 case kStringCharAt: 7833 case kStringCharAt:
7833 if (argument_count == 2 && check_type == STRING_CHECK) { 7834 if (argument_count == 2 && check_type == STRING_CHECK) {
7834 HValue* index = Pop(); 7835 HValue* index = Pop();
7835 HValue* string = Pop(); 7836 HValue* string = Pop();
7836 HValue* context = environment()->LookupContext(); 7837 HValue* context = environment()->LookupContext();
7837 ASSERT(!expr->holder().is_null()); 7838 ASSERT(!expr->holder().is_null());
7838 AddInstruction(new(zone()) HCheckPrototypeMaps( 7839 AddInstruction(new(zone()) HCheckPrototypeMaps(
7839 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), 7840 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK),
7840 expr->holder(), 7841 expr->holder(),
7841 zone())); 7842 zone()));
7842 HStringCharCodeAt* char_code = 7843 HInstruction* char_code =
7843 BuildStringCharCodeAt(context, string, index); 7844 BuildStringCharCodeAt(context, string, index);
7844 if (id == kStringCharCodeAt) { 7845 if (id == kStringCharCodeAt) {
7845 ast_context()->ReturnInstruction(char_code, expr->id()); 7846 ast_context()->ReturnInstruction(char_code, expr->id());
7846 return true; 7847 return true;
7847 } 7848 }
7848 AddInstruction(char_code); 7849 AddInstruction(char_code);
7849 HStringCharFromCode* result = 7850 HInstruction* result =
7850 new(zone()) HStringCharFromCode(context, char_code); 7851 HStringCharFromCode::New(zone(), context, char_code);
7851 ast_context()->ReturnInstruction(result, expr->id()); 7852 ast_context()->ReturnInstruction(result, expr->id());
7852 return true; 7853 return true;
7853 } 7854 }
7854 break; 7855 break;
7855 case kMathExp: 7856 case kMathExp:
7856 if (!FLAG_fast_math) break; 7857 if (!FLAG_fast_math) break;
7857 // Fall through if FLAG_fast_math. 7858 // Fall through if FLAG_fast_math.
7858 case kMathRound: 7859 case kMathRound:
7859 case kMathFloor: 7860 case kMathFloor:
7860 case kMathAbs: 7861 case kMathAbs:
7861 case kMathSqrt: 7862 case kMathSqrt:
7862 case kMathLog: 7863 case kMathLog:
7863 case kMathSin: 7864 case kMathSin:
7864 case kMathCos: 7865 case kMathCos:
7865 case kMathTan: 7866 case kMathTan:
7866 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 7867 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
7867 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7868 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7868 HValue* argument = Pop(); 7869 HValue* argument = Pop();
7869 HValue* context = environment()->LookupContext(); 7870 HValue* context = environment()->LookupContext();
7870 Drop(1); // Receiver. 7871 Drop(1); // Receiver.
7871 HUnaryMathOperation* op = 7872 HInstruction* op =
7872 new(zone()) HUnaryMathOperation(context, argument, id); 7873 HUnaryMathOperation::New(zone(), context, argument, id);
7873 op->set_position(expr->position()); 7874 op->set_position(expr->position());
7874 ast_context()->ReturnInstruction(op, expr->id()); 7875 ast_context()->ReturnInstruction(op, expr->id());
7875 return true; 7876 return true;
7876 } 7877 }
7877 break; 7878 break;
7878 case kMathPow: 7879 case kMathPow:
7879 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 7880 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7880 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7881 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7881 HValue* right = Pop(); 7882 HValue* right = Pop();
7882 HValue* left = Pop(); 7883 HValue* left = Pop();
7883 Pop(); // Pop receiver. 7884 Pop(); // Pop receiver.
7884 HValue* context = environment()->LookupContext(); 7885 HValue* context = environment()->LookupContext();
7885 HInstruction* result = NULL; 7886 HInstruction* result = NULL;
7886 // Use sqrt() if exponent is 0.5 or -0.5. 7887 // Use sqrt() if exponent is 0.5 or -0.5.
7887 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 7888 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
7888 double exponent = HConstant::cast(right)->DoubleValue(); 7889 double exponent = HConstant::cast(right)->DoubleValue();
7889 if (exponent == 0.5) { 7890 if (exponent == 0.5) {
7890 result = 7891 result =
7891 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); 7892 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
7892 } else if (exponent == -0.5) { 7893 } else if (exponent == -0.5) {
7893 HConstant* double_one = 7894 HConstant* double_one =
7894 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), 7895 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)),
7895 Representation::Double()); 7896 Representation::Double());
7896 AddInstruction(double_one); 7897 AddInstruction(double_one);
7897 HUnaryMathOperation* square_root = 7898 HInstruction* sqrt =
7898 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); 7899 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
7899 AddInstruction(square_root); 7900 AddInstruction(sqrt);
7900 // MathPowHalf doesn't have side effects so there's no need for 7901 // MathPowHalf doesn't have side effects so there's no need for
7901 // an environment simulation here. 7902 // an environment simulation here.
7902 ASSERT(!square_root->HasObservableSideEffects()); 7903 ASSERT(!sqrt->HasObservableSideEffects());
7903 result = new(zone()) HDiv(context, double_one, square_root); 7904 result = HDiv::New(zone(), context, double_one, sqrt);
7904 } else if (exponent == 2.0) { 7905 } else if (exponent == 2.0) {
7905 result = new(zone()) HMul(context, left, left); 7906 result = HMul::New(zone(), context, left, left);
7906 } 7907 }
7907 } else if (right->IsConstant() && 7908 } else if (right->IsConstant() &&
7908 HConstant::cast(right)->HasInteger32Value() && 7909 HConstant::cast(right)->HasInteger32Value() &&
7909 HConstant::cast(right)->Integer32Value() == 2) { 7910 HConstant::cast(right)->Integer32Value() == 2) {
7910 result = new(zone()) HMul(context, left, left); 7911 result = HMul::New(zone(), context, left, left);
7911 } 7912 }
7912 7913
7913 if (result == NULL) { 7914 if (result == NULL) {
7914 result = new(zone()) HPower(left, right); 7915 result = HPower::New(zone(), left, right);
7915 } 7916 }
7916 ast_context()->ReturnInstruction(result, expr->id()); 7917 ast_context()->ReturnInstruction(result, expr->id());
7917 return true; 7918 return true;
7918 } 7919 }
7919 break; 7920 break;
7920 case kMathRandom: 7921 case kMathRandom:
7921 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 7922 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
7922 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7923 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7923 Drop(1); // Receiver. 7924 Drop(1); // Receiver.
7924 HValue* context = environment()->LookupContext(); 7925 HValue* context = environment()->LookupContext();
7925 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 7926 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
7926 AddInstruction(global_object); 7927 AddInstruction(global_object);
7927 HRandom* result = new(zone()) HRandom(global_object); 7928 HRandom* result = new(zone()) HRandom(global_object);
7928 ast_context()->ReturnInstruction(result, expr->id()); 7929 ast_context()->ReturnInstruction(result, expr->id());
7929 return true; 7930 return true;
7930 } 7931 }
7931 break; 7932 break;
7932 case kMathMax: 7933 case kMathMax:
7933 case kMathMin: 7934 case kMathMin:
7934 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 7935 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7935 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7936 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7936 HValue* right = Pop(); 7937 HValue* right = Pop();
7937 HValue* left = Pop(); 7938 HValue* left = Pop();
7938 Drop(1); // Receiver. 7939 Drop(1); // Receiver.
7939 HValue* context = environment()->LookupContext(); 7940 HValue* context = environment()->LookupContext();
7940 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 7941 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
7941 : HMathMinMax::kMathMax; 7942 : HMathMinMax::kMathMax;
7942 HMathMinMax* result = new(zone()) HMathMinMax(context, left, right, op); 7943 HInstruction* result =
7944 HMathMinMax::New(zone(), context, left, right, op);
7943 ast_context()->ReturnInstruction(result, expr->id()); 7945 ast_context()->ReturnInstruction(result, expr->id());
7944 return true; 7946 return true;
7945 } 7947 }
7946 break; 7948 break;
7947 default: 7949 default:
7948 // Not yet supported for inlining. 7950 // Not yet supported for inlining.
7949 break; 7951 break;
7950 } 7952 }
7951 return false; 7953 return false;
7952 } 7954 }
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
8506 HInstruction* instr = new(zone()) HTypeof(context, value); 8508 HInstruction* instr = new(zone()) HTypeof(context, value);
8507 return ast_context()->ReturnInstruction(instr, expr->id()); 8509 return ast_context()->ReturnInstruction(instr, expr->id());
8508 } 8510 }
8509 8511
8510 8512
8511 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { 8513 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) {
8512 CHECK_ALIVE(VisitForValue(expr->expression())); 8514 CHECK_ALIVE(VisitForValue(expr->expression()));
8513 HValue* value = Pop(); 8515 HValue* value = Pop();
8514 HValue* context = environment()->LookupContext(); 8516 HValue* context = environment()->LookupContext();
8515 HInstruction* instr = 8517 HInstruction* instr =
8516 new(zone()) HMul(context, value, graph()->GetConstant1()); 8518 HMul::New(zone(), context, value, graph()->GetConstant1());
8517 return ast_context()->ReturnInstruction(instr, expr->id()); 8519 return ast_context()->ReturnInstruction(instr, expr->id());
8518 } 8520 }
8519 8521
8520 8522
8521 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 8523 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
8522 CHECK_ALIVE(VisitForValue(expr->expression())); 8524 CHECK_ALIVE(VisitForValue(expr->expression()));
8523 HValue* value = Pop(); 8525 HValue* value = Pop();
8524 HValue* context = environment()->LookupContext(); 8526 HValue* context = environment()->LookupContext();
8525 HInstruction* instr = 8527 HInstruction* instr =
8526 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); 8528 HMul::New(zone(), context, value, graph()->GetConstantMinus1());
8527 TypeInfo info = oracle()->UnaryType(expr); 8529 TypeInfo info = oracle()->UnaryType(expr);
8528 Representation rep = ToRepresentation(info); 8530 Representation rep = ToRepresentation(info);
8529 if (info.IsUninitialized()) { 8531 if (info.IsUninitialized()) {
8530 AddSoftDeoptimize(); 8532 AddSoftDeoptimize();
8531 info = TypeInfo::Unknown(); 8533 info = TypeInfo::Unknown();
8532 } 8534 }
8533 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); 8535 if (instr->IsBinaryOperation()) {
8536 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep);
8537 }
8534 return ast_context()->ReturnInstruction(instr, expr->id()); 8538 return ast_context()->ReturnInstruction(instr, expr->id());
8535 } 8539 }
8536 8540
8537 8541
8538 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { 8542 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
8539 CHECK_ALIVE(VisitForValue(expr->expression())); 8543 CHECK_ALIVE(VisitForValue(expr->expression()));
8540 HValue* value = Pop(); 8544 HValue* value = Pop();
8541 TypeInfo info = oracle()->UnaryType(expr); 8545 TypeInfo info = oracle()->UnaryType(expr);
8542 if (info.IsUninitialized()) { 8546 if (info.IsUninitialized()) {
8543 AddSoftDeoptimize(); 8547 AddSoftDeoptimize();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
8611 Push(number_input); 8615 Push(number_input);
8612 } 8616 }
8613 8617
8614 // The addition has no side effects, so we do not need 8618 // The addition has no side effects, so we do not need
8615 // to simulate the expression stack after this instruction. 8619 // to simulate the expression stack after this instruction.
8616 // Any later failures deopt to the load of the input or earlier. 8620 // Any later failures deopt to the load of the input or earlier.
8617 HConstant* delta = (expr->op() == Token::INC) 8621 HConstant* delta = (expr->op() == Token::INC)
8618 ? graph()->GetConstant1() 8622 ? graph()->GetConstant1()
8619 : graph()->GetConstantMinus1(); 8623 : graph()->GetConstantMinus1();
8620 HValue* context = environment()->LookupContext(); 8624 HValue* context = environment()->LookupContext();
8621 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); 8625 HInstruction* instr = HAdd::New(zone(), context, Top(), delta);
8622 // We can't insert a simulate here, because it would break deoptimization, 8626 // We can't insert a simulate here, because it would break deoptimization,
8623 // so the HAdd must not have side effects, so we must freeze its 8627 // so the HAdd must not have side effects, so we must freeze its
8624 // representation. 8628 // representation.
8625 instr->AssumeRepresentation(rep); 8629 instr->AssumeRepresentation(rep);
8626 instr->ClearAllSideEffects(); 8630 instr->ClearAllSideEffects();
8627 AddInstruction(instr); 8631 AddInstruction(instr);
8628 return instr; 8632 return instr;
8629 } 8633 }
8630 8634
8631 8635
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
8807 ASSERT(has_side_effects); // Stores always have side effects. 8811 ASSERT(has_side_effects); // Stores always have side effects.
8808 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); 8812 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8809 } 8813 }
8810 } 8814 }
8811 8815
8812 Drop(returns_original_input ? 2 : 1); 8816 Drop(returns_original_input ? 2 : 1);
8813 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 8817 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
8814 } 8818 }
8815 8819
8816 8820
8817 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( 8821 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
8818 HValue* context, 8822 HValue* context,
8819 HValue* string, 8823 HValue* string,
8820 HValue* index) { 8824 HValue* index) {
8825 if (string->IsConstant() && index->IsConstant()) {
8826 HConstant* c_string = HConstant::cast(string);
8827 HConstant* c_index = HConstant::cast(index);
8828 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
8829 int32_t i = c_index->NumberValueAsInteger32();
8830 Handle<String> s = c_string->StringValue();
8831 if (i < 0 || i >= s->length()) {
8832 return new(zone()) HConstant(OS::nan_value(), Representation::Double());
8833 }
8834 return new(zone()) HConstant(s->Get(i), Representation::Integer32());
8835 }
8836 }
8821 AddInstruction(new(zone()) HCheckNonSmi(string)); 8837 AddInstruction(new(zone()) HCheckNonSmi(string));
8822 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 8838 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
8823 HStringLength* length = new(zone()) HStringLength(string); 8839 HStringLength* length = new(zone()) HStringLength(string);
8824 AddInstruction(length); 8840 AddInstruction(length);
8825 HInstruction* checked_index = AddBoundsCheck(index, length); 8841 HInstruction* checked_index = AddBoundsCheck(index, length);
8826 return new(zone()) HStringCharCodeAt(context, string, checked_index); 8842 return new(zone()) HStringCharCodeAt(context, string, checked_index);
8827 } 8843 }
8828 8844
8829 // Checks if the given shift amounts have form: (sa) and (32 - sa). 8845 // Checks if the given shift amounts have form: (sa) and (32 - sa).
8830 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8846 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
8901 left_info = right_info = TypeInfo::Unknown(); 8917 left_info = right_info = TypeInfo::Unknown();
8902 } 8918 }
8903 HInstruction* instr = NULL; 8919 HInstruction* instr = NULL;
8904 switch (expr->op()) { 8920 switch (expr->op()) {
8905 case Token::ADD: 8921 case Token::ADD:
8906 if (left_info.IsString() && right_info.IsString()) { 8922 if (left_info.IsString() && right_info.IsString()) {
8907 AddInstruction(new(zone()) HCheckNonSmi(left)); 8923 AddInstruction(new(zone()) HCheckNonSmi(left));
8908 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 8924 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
8909 AddInstruction(new(zone()) HCheckNonSmi(right)); 8925 AddInstruction(new(zone()) HCheckNonSmi(right));
8910 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 8926 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
8911 instr = new(zone()) HStringAdd(context, left, right); 8927 instr = HStringAdd::New(zone(), context, left, right);
8912 } else { 8928 } else {
8913 instr = HAdd::NewHAdd(zone(), context, left, right); 8929 instr = HAdd::New(zone(), context, left, right);
8914 } 8930 }
8915 break; 8931 break;
8916 case Token::SUB: 8932 case Token::SUB:
8917 instr = HSub::NewHSub(zone(), context, left, right); 8933 instr = HSub::New(zone(), context, left, right);
8918 break; 8934 break;
8919 case Token::MUL: 8935 case Token::MUL:
8920 instr = HMul::NewHMul(zone(), context, left, right); 8936 instr = HMul::New(zone(), context, left, right);
8921 break; 8937 break;
8922 case Token::MOD: 8938 case Token::MOD:
8923 instr = HMod::NewHMod(zone(), context, left, right); 8939 instr = HMod::New(zone(), context, left, right);
8924 break; 8940 break;
8925 case Token::DIV: 8941 case Token::DIV:
8926 instr = HDiv::NewHDiv(zone(), context, left, right); 8942 instr = HDiv::New(zone(), context, left, right);
8927 break; 8943 break;
8928 case Token::BIT_XOR: 8944 case Token::BIT_XOR:
8929 case Token::BIT_AND: 8945 case Token::BIT_AND:
8930 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); 8946 instr = HBitwise::New(zone(), expr->op(), context, left, right);
8931 break; 8947 break;
8932 case Token::BIT_OR: { 8948 case Token::BIT_OR: {
8933 HValue* operand, *shift_amount; 8949 HValue* operand, *shift_amount;
8934 if (left_info.IsInteger32() && right_info.IsInteger32() && 8950 if (left_info.IsInteger32() && right_info.IsInteger32() &&
8935 MatchRotateRight(left, right, &operand, &shift_amount)) { 8951 MatchRotateRight(left, right, &operand, &shift_amount)) {
8936 instr = new(zone()) HRor(context, operand, shift_amount); 8952 instr = new(zone()) HRor(context, operand, shift_amount);
8937 } else { 8953 } else {
8938 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); 8954 instr = HBitwise::New(zone(), expr->op(), context, left, right);
8939 } 8955 }
8940 break; 8956 break;
8941 } 8957 }
8942 case Token::SAR: 8958 case Token::SAR:
8943 instr = HSar::NewHSar(zone(), context, left, right); 8959 instr = HSar::New(zone(), context, left, right);
8944 break; 8960 break;
8945 case Token::SHR: 8961 case Token::SHR:
8946 instr = HShr::NewHShr(zone(), context, left, right); 8962 instr = HShr::New(zone(), context, left, right);
8947 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 8963 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
8948 CanBeZero(right)) { 8964 CanBeZero(right)) {
8949 graph()->RecordUint32Instruction(instr); 8965 graph()->RecordUint32Instruction(instr);
8950 } 8966 }
8951 break; 8967 break;
8952 case Token::SHL: 8968 case Token::SHL:
8953 instr = HShl::NewHShl(zone(), context, left, right); 8969 instr = HShl::New(zone(), context, left, right);
8954 break; 8970 break;
8955 default: 8971 default:
8956 UNREACHABLE(); 8972 UNREACHABLE();
8957 } 8973 }
8958 8974
8959 if (instr->IsBinaryOperation()) { 8975 if (instr->IsBinaryOperation()) {
8960 HBinaryOperation* binop = HBinaryOperation::cast(instr); 8976 HBinaryOperation* binop = HBinaryOperation::cast(instr);
8961 binop->set_observed_input_representation(left_rep, right_rep); 8977 binop->set_observed_input_representation(left_rep, right_rep);
8962 binop->initialize_output_representation(result_rep); 8978 binop->initialize_output_representation(result_rep);
8963 } 8979 }
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
9703 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 9719 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar(
9704 CallRuntime* call) { 9720 CallRuntime* call) {
9705 ASSERT(call->arguments()->length() == 3); 9721 ASSERT(call->arguments()->length() == 3);
9706 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9722 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9707 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9708 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 9724 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
9709 HValue* value = Pop(); 9725 HValue* value = Pop();
9710 HValue* index = Pop(); 9726 HValue* index = Pop();
9711 HValue* string = Pop(); 9727 HValue* string = Pop();
9712 HValue* context = environment()->LookupContext(); 9728 HValue* context = environment()->LookupContext();
9713 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); 9729 HInstruction* char_code = BuildStringCharCodeAt(context, string, index);
9714 AddInstruction(char_code); 9730 AddInstruction(char_code);
9715 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( 9731 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar(
9716 String::TWO_BYTE_ENCODING, string, index, value); 9732 String::TWO_BYTE_ENCODING, string, index, value);
9717 return ast_context()->ReturnInstruction(result, call->id()); 9733 return ast_context()->ReturnInstruction(result, call->id());
9718 } 9734 }
9719 9735
9720 9736
9721 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 9737 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
9722 ASSERT(call->arguments()->length() == 2); 9738 ASSERT(call->arguments()->length() == 2);
9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9739 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
9761 9777
9762 9778
9763 // Fast support for charCodeAt(n). 9779 // Fast support for charCodeAt(n).
9764 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 9780 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
9765 ASSERT(call->arguments()->length() == 2); 9781 ASSERT(call->arguments()->length() == 2);
9766 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9782 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9767 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9783 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9768 HValue* index = Pop(); 9784 HValue* index = Pop();
9769 HValue* string = Pop(); 9785 HValue* string = Pop();
9770 HValue* context = environment()->LookupContext(); 9786 HValue* context = environment()->LookupContext();
9771 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); 9787 HInstruction* result = BuildStringCharCodeAt(context, string, index);
9772 return ast_context()->ReturnInstruction(result, call->id()); 9788 return ast_context()->ReturnInstruction(result, call->id());
9773 } 9789 }
9774 9790
9775 9791
9776 // Fast support for string.charAt(n) and string[n]. 9792 // Fast support for string.charAt(n) and string[n].
9777 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 9793 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
9778 ASSERT(call->arguments()->length() == 1); 9794 ASSERT(call->arguments()->length() == 1);
9779 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9795 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9780 HValue* char_code = Pop(); 9796 HValue* char_code = Pop();
9781 HValue* context = environment()->LookupContext(); 9797 HValue* context = environment()->LookupContext();
9782 HStringCharFromCode* result = 9798 HStringCharFromCode* result =
9783 new(zone()) HStringCharFromCode(context, char_code); 9799 new(zone()) HStringCharFromCode(context, char_code);
9784 return ast_context()->ReturnInstruction(result, call->id()); 9800 return ast_context()->ReturnInstruction(result, call->id());
9785 } 9801 }
9786 9802
9787 9803
9788 // Fast support for string.charAt(n) and string[n]. 9804 // Fast support for string.charAt(n) and string[n].
9789 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 9805 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
9790 ASSERT(call->arguments()->length() == 2); 9806 ASSERT(call->arguments()->length() == 2);
9791 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9807 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9792 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9808 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9793 HValue* index = Pop(); 9809 HValue* index = Pop();
9794 HValue* string = Pop(); 9810 HValue* string = Pop();
9795 HValue* context = environment()->LookupContext(); 9811 HValue* context = environment()->LookupContext();
9796 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); 9812 HInstruction* char_code = BuildStringCharCodeAt(context, string, index);
9797 AddInstruction(char_code); 9813 AddInstruction(char_code);
9798 HStringCharFromCode* result = 9814 HStringCharFromCode* result =
9799 new(zone()) HStringCharFromCode(context, char_code); 9815 new(zone()) HStringCharFromCode(context, char_code);
9800 return ast_context()->ReturnInstruction(result, call->id()); 9816 return ast_context()->ReturnInstruction(result, call->id());
9801 } 9817 }
9802 9818
9803 9819
9804 // Fast support for object equality testing. 9820 // Fast support for object equality testing.
9805 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 9821 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
9806 ASSERT(call->arguments()->length() == 2); 9822 ASSERT(call->arguments()->length() == 2);
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
10672 } 10688 }
10673 } 10689 }
10674 10690
10675 #ifdef DEBUG 10691 #ifdef DEBUG
10676 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10692 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10677 if (allocator_ != NULL) allocator_->Verify(); 10693 if (allocator_ != NULL) allocator_->Verify();
10678 #endif 10694 #endif
10679 } 10695 }
10680 10696
10681 } } // namespace v8::internal 10697 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698