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 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3115 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 3115 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
3116 } else { | 3116 } else { |
3117 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 3117 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
3118 } | 3118 } |
3119 } | 3119 } |
3120 } | 3120 } |
3121 } | 3121 } |
3122 } | 3122 } |
3123 | 3123 |
3124 | 3124 |
3125 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 3125 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3126 Push(instr); | 3126 Push(instr); |
3127 AddInstruction(instr); | 3127 AddInstruction(instr); |
3128 } | 3128 } |
3129 | 3129 |
3130 | 3130 |
3131 template <class Instruction> | 3131 template <class Instruction> |
3132 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 3132 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
3133 int count = call->argument_count(); | 3133 int count = call->argument_count(); |
3134 ZoneList<HValue*> arguments(count, zone()); | 3134 ZoneList<HValue*> arguments(count, zone()); |
3135 for (int i = 0; i < count; ++i) { | 3135 for (int i = 0; i < count; ++i) { |
(...skipping 4709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7845 return false; | 7845 return false; |
7846 } | 7846 } |
7847 return (sub->right() == sa); | 7847 return (sub->right() == sa); |
7848 } | 7848 } |
7849 | 7849 |
7850 | 7850 |
7851 // Checks if the left and the right are shift instructions with the oposite | 7851 // Checks if the left and the right are shift instructions with the oposite |
7852 // directions that can be replaced by one rotate right instruction or not. | 7852 // directions that can be replaced by one rotate right instruction or not. |
7853 // Returns the operand and the shift amount for the rotate instruction in the | 7853 // Returns the operand and the shift amount for the rotate instruction in the |
7854 // former case. | 7854 // former case. |
7855 bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left, | 7855 bool HGraphBuilder::MatchRotateRight(HValue* left, |
7856 HValue* right, | 7856 HValue* right, |
7857 HValue** operand, | 7857 HValue** operand, |
7858 HValue** shift_amount) { | 7858 HValue** shift_amount) { |
7859 HShl* shl; | 7859 HShl* shl; |
7860 HShr* shr; | 7860 HShr* shr; |
7861 if (left->IsShl() && right->IsShr()) { | 7861 if (left->IsShl() && right->IsShr()) { |
7862 shl = HShl::cast(left); | 7862 shl = HShl::cast(left); |
7863 shr = HShr::cast(right); | 7863 shr = HShr::cast(right); |
7864 } else if (left->IsShr() && right->IsShl()) { | 7864 } else if (left->IsShr() && right->IsShl()) { |
7865 shl = HShl::cast(right); | 7865 shl = HShl::cast(right); |
(...skipping 18 matching lines...) Expand all Loading... | |
7884 HConstant* right_const = HConstant::cast(right); | 7884 HConstant* right_const = HConstant::cast(right); |
7885 if (right_const->HasInteger32Value() && | 7885 if (right_const->HasInteger32Value() && |
7886 (right_const->Integer32Value() & 0x1f) != 0) { | 7886 (right_const->Integer32Value() & 0x1f) != 0) { |
7887 return false; | 7887 return false; |
7888 } | 7888 } |
7889 } | 7889 } |
7890 return true; | 7890 return true; |
7891 } | 7891 } |
7892 | 7892 |
7893 | 7893 |
7894 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 7894 HValue* HGraphBuilder::ConstantToNumber(HValue* value) { |
Toon Verwaest
2013/07/18 13:57:12
Perhaps you can also handle strings here.
| |
7895 if (value->IsConstant()) { | |
Toon Verwaest
2013/07/18 13:57:12
Move this code together with HConstant::CopyToTrun
| |
7896 HConstant* constant = HConstant::cast(value); | |
7897 if (constant->handle()->IsBoolean()) { | |
7898 return constant->handle()->BooleanValue() | |
7899 ? graph()->GetConstant1() : graph()->GetConstant0(); | |
Jakob Kummerow
2013/07/18 11:56:15
nit: indentation
| |
7900 } else if (constant->handle()->IsUndefined() || | |
7901 constant->handle()->IsTheHole()) { | |
Toon Verwaest
2013/07/18 13:57:12
Remove TheHole case.
| |
7902 return Add<HConstant>(OS::nan_value(), Representation::Double()); | |
7903 } else if (constant->handle()->IsNull()) { | |
7904 return graph()->GetConstant0(); | |
7905 } | |
7906 } | |
7907 return value; | |
7908 } | |
7909 | |
7910 | |
7911 HInstruction* HGraphBuilder::BuildBinaryOperation( | |
7895 BinaryOperation* expr, | 7912 BinaryOperation* expr, |
7896 HValue* left, | 7913 HValue* left, |
7897 HValue* right) { | 7914 HValue* right) { |
7898 HValue* context = environment()->LookupContext(); | 7915 HValue* context = environment()->LookupContext(); |
7899 Handle<Type> left_type = expr->left()->bounds().lower; | 7916 Handle<Type> left_type = expr->left()->bounds().lower; |
7900 Handle<Type> right_type = expr->right()->bounds().lower; | 7917 Handle<Type> right_type = expr->right()->bounds().lower; |
7901 Handle<Type> result_type = expr->bounds().lower; | 7918 Handle<Type> result_type = expr->bounds().lower; |
7902 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 7919 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
7903 Representation left_rep = Representation::FromType(left_type); | 7920 |
7904 Representation right_rep = Representation::FromType(right_type); | 7921 if (expr->op() != Token::ADD || |
7905 Representation result_rep = Representation::FromType(result_type); | 7922 (left->type().IsNoString() && right->type().IsNoString())) { |
7923 left = ConstantToNumber(left); | |
7924 right = ConstantToNumber(right); | |
7925 } | |
7926 | |
7927 left_type = left->type().intersect(left_type, isolate()); | |
7928 right_type = right->type().intersect(right_type, isolate()); | |
7906 | 7929 |
7907 if (left_type->Is(Type::None())) { | 7930 if (left_type->Is(Type::None())) { |
7908 AddSoftDeoptimize(); | 7931 AddSoftDeoptimize(); |
7909 // TODO(rossberg): we should be able to get rid of non-continuous defaults. | 7932 // TODO(rossberg): we should be able to get rid of non-continuous defaults. |
7910 left_type = handle(Type::Any(), isolate()); | 7933 left_type = handle(Type::Any(), isolate()); |
7911 } | 7934 } |
7912 if (right_type->Is(Type::None())) { | 7935 if (right_type->Is(Type::None())) { |
7913 AddSoftDeoptimize(); | 7936 AddSoftDeoptimize(); |
7914 right_type = handle(Type::Any(), isolate()); | 7937 right_type = handle(Type::Any(), isolate()); |
7915 } | 7938 } |
7939 | |
7940 Representation left_rep = left->IsConstant() ? | |
7941 left->KnownOptimalRepresentation() : Representation::FromType(left_type); | |
Jakob Kummerow
2013/07/18 11:56:15
nit: indentation. Also, prefer the '?' on the next
Toon Verwaest
2013/07/18 13:57:12
Could we calculate this in "type" and only at the
| |
7942 Representation right_rep = right->IsConstant() ? | |
7943 right->KnownOptimalRepresentation() : Representation::FromType(right_type); | |
7944 Representation result_rep = Representation::FromType(result_type); | |
7945 | |
7916 HInstruction* instr = NULL; | 7946 HInstruction* instr = NULL; |
7917 switch (expr->op()) { | 7947 switch (expr->op()) { |
7918 case Token::ADD: | 7948 case Token::ADD: |
7919 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 7949 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
7920 BuildCheckHeapObject(left); | 7950 if (!left->type().IsString() || !right->type().IsString()) { |
Jakob Kummerow
2013/07/18 11:56:15
Why is this one atomic block rather than "if (!lef
| |
7921 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 7951 BuildCheckHeapObject(left); |
7922 BuildCheckHeapObject(right); | 7952 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
7923 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 7953 BuildCheckHeapObject(right); |
7954 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | |
Toon Verwaest
2013/07/18 13:57:12
I'd use canonicalization to eliminate CheckInstanc
| |
7955 } | |
7924 instr = HStringAdd::New(zone(), context, left, right); | 7956 instr = HStringAdd::New(zone(), context, left, right); |
7925 } else { | 7957 } else { |
7926 instr = HAdd::New(zone(), context, left, right); | 7958 instr = HAdd::New(zone(), context, left, right); |
7927 } | 7959 } |
7928 break; | 7960 break; |
7929 case Token::SUB: | 7961 case Token::SUB: |
7930 instr = HSub::New(zone(), context, left, right); | 7962 instr = HSub::New(zone(), context, left, right); |
7931 break; | 7963 break; |
7932 case Token::MUL: | 7964 case Token::MUL: |
7933 instr = HMul::New(zone(), context, left, right); | 7965 instr = HMul::New(zone(), context, left, right); |
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9990 if (ShouldProduceTraceOutput()) { | 10022 if (ShouldProduceTraceOutput()) { |
9991 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10023 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9992 } | 10024 } |
9993 | 10025 |
9994 #ifdef DEBUG | 10026 #ifdef DEBUG |
9995 graph_->Verify(false); // No full verify. | 10027 graph_->Verify(false); // No full verify. |
9996 #endif | 10028 #endif |
9997 } | 10029 } |
9998 | 10030 |
9999 } } // namespace v8::internal | 10031 } } // namespace v8::internal |
OLD | NEW |