Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 bool IsNone() const { return kind_ == kNone; } | 341 bool IsNone() const { return kind_ == kNone; } |
| 342 bool IsTagged() const { return kind_ == kTagged; } | 342 bool IsTagged() const { return kind_ == kTagged; } |
| 343 bool IsInteger32() const { return kind_ == kInteger32; } | 343 bool IsInteger32() const { return kind_ == kInteger32; } |
| 344 bool IsDouble() const { return kind_ == kDouble; } | 344 bool IsDouble() const { return kind_ == kDouble; } |
| 345 bool IsExternal() const { return kind_ == kExternal; } | 345 bool IsExternal() const { return kind_ == kExternal; } |
| 346 bool IsSpecialization() const { | 346 bool IsSpecialization() const { |
| 347 return kind_ == kInteger32 || kind_ == kDouble; | 347 return kind_ == kInteger32 || kind_ == kDouble; |
| 348 } | 348 } |
| 349 const char* Mnemonic() const; | 349 const char* Mnemonic() const; |
| 350 | 350 |
| 351 Representation KeyedAccessIndexRequirement() { | |
|
Jakob Kummerow
2013/01/10 16:06:47
nit: I'm a bit unhappy about adding instruction-sp
| |
| 352 return IsInteger32() ? Integer32() : Tagged(); | |
| 353 } | |
| 354 | |
| 351 private: | 355 private: |
| 352 explicit Representation(Kind k) : kind_(k) { } | 356 explicit Representation(Kind k) : kind_(k) { } |
| 353 | 357 |
| 354 // Make sure kind fits in int8. | 358 // Make sure kind fits in int8. |
| 355 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); | 359 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); |
| 356 | 360 |
| 357 int8_t kind_; | 361 int8_t kind_; |
| 358 }; | 362 }; |
| 359 | 363 |
| 360 | 364 |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 // If the operation also exists in a form that takes int32 and outputs int32 | 669 // If the operation also exists in a form that takes int32 and outputs int32 |
| 666 // then the operation should return its input value so that we can propagate | 670 // then the operation should return its input value so that we can propagate |
| 667 // back. There are three operations that need to propagate back to more than | 671 // back. There are three operations that need to propagate back to more than |
| 668 // one input. They are phi and binary div and mul. They always return NULL | 672 // one input. They are phi and binary div and mul. They always return NULL |
| 669 // and expect the caller to take care of things. | 673 // and expect the caller to take care of things. |
| 670 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { | 674 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 671 visited->Add(id()); | 675 visited->Add(id()); |
| 672 return NULL; | 676 return NULL; |
| 673 } | 677 } |
| 674 | 678 |
| 679 // There are HInstructions that do not really change a value, they | |
| 680 // only add pieces of information to it (like bounds checks, map checks | |
| 681 // or SSI definitions after conditional branches). | |
| 682 // This method must always return the original HValue SSA definition (the | |
| 683 // register allocator relies on this to avoid allocating multiple registers | |
| 684 // for the same value). | |
| 685 virtual HValue* ActualValue() { return this; } | |
| 686 | |
| 675 bool IsDefinedAfter(HBasicBlock* other) const; | 687 bool IsDefinedAfter(HBasicBlock* other) const; |
| 676 | 688 |
| 677 // Operands. | 689 // Operands. |
| 678 virtual int OperandCount() = 0; | 690 virtual int OperandCount() = 0; |
| 679 virtual HValue* OperandAt(int index) const = 0; | 691 virtual HValue* OperandAt(int index) const = 0; |
| 680 void SetOperandAt(int index, HValue* value); | 692 void SetOperandAt(int index, HValue* value); |
| 681 | 693 |
| 682 void DeleteAndReplaceWith(HValue* other); | 694 void DeleteAndReplaceWith(HValue* other); |
| 683 void ReplaceAllUsesWith(HValue* other); | 695 void ReplaceAllUsesWith(HValue* other); |
| 684 bool HasNoUses() const { return use_list_ == NULL; } | 696 bool HasNoUses() const { return use_list_ == NULL; } |
| (...skipping 2263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2948 | 2960 |
| 2949 enum BoundsCheckKeyMode { | 2961 enum BoundsCheckKeyMode { |
| 2950 DONT_ALLOW_SMI_KEY, | 2962 DONT_ALLOW_SMI_KEY, |
| 2951 ALLOW_SMI_KEY | 2963 ALLOW_SMI_KEY |
| 2952 }; | 2964 }; |
| 2953 | 2965 |
| 2954 | 2966 |
| 2955 class HBoundsCheck: public HTemplateInstruction<2> { | 2967 class HBoundsCheck: public HTemplateInstruction<2> { |
| 2956 public: | 2968 public: |
| 2957 HBoundsCheck(HValue* index, HValue* length, | 2969 HBoundsCheck(HValue* index, HValue* length, |
| 2958 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) | 2970 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, |
| 2971 Representation r = Representation::None()) | |
| 2959 : key_mode_(key_mode) { | 2972 : key_mode_(key_mode) { |
| 2960 SetOperandAt(0, index); | 2973 SetOperandAt(0, index); |
| 2961 SetOperandAt(1, length); | 2974 SetOperandAt(1, length); |
| 2962 set_representation(Representation::Integer32()); | 2975 if (r.IsNone()) { |
| 2976 // In the normal compilation pipeline the representation is flexible | |
| 2977 // (see comment to RequiredInputRepresentation). | |
| 2978 SetFlag(kFlexibleRepresentation); | |
| 2979 } else { | |
| 2980 // When compiling stubs we want to set the representation explicitly | |
| 2981 // so the compilation pipeline can skip the HInferRepresentation phase. | |
| 2982 set_representation(r); | |
| 2983 } | |
| 2963 SetFlag(kUseGVN); | 2984 SetFlag(kUseGVN); |
| 2964 } | 2985 } |
| 2965 | 2986 |
| 2966 virtual Representation RequiredInputRepresentation(int arg_index) { | 2987 virtual Representation RequiredInputRepresentation(int arg_index) { |
| 2967 if (key_mode_ == DONT_ALLOW_SMI_KEY || | 2988 return representation(); |
| 2968 !length()->representation().IsTagged()) { | |
| 2969 return Representation::Integer32(); | |
| 2970 } | |
| 2971 // If the index is tagged and isn't constant, then allow the length | |
| 2972 // to be tagged, since it is usually already tagged from loading it out of | |
| 2973 // the length field of a JSArray. This allows for direct comparison without | |
| 2974 // untagging. | |
| 2975 if (index()->representation().IsTagged() && !index()->IsConstant()) { | |
| 2976 return Representation::Tagged(); | |
| 2977 } | |
| 2978 // Also allow the length to be tagged if the index is constant, because | |
| 2979 // it can be tagged to allow direct comparison. | |
| 2980 if (index()->IsConstant() && | |
| 2981 index()->representation().IsInteger32() && | |
| 2982 arg_index == 1) { | |
| 2983 return Representation::Tagged(); | |
| 2984 } | |
| 2985 return Representation::Integer32(); | |
| 2986 } | 2989 } |
| 2987 virtual Representation observed_input_representation(int index) { | 2990 virtual Representation observed_input_representation(int index) { |
| 2988 return Representation::Integer32(); | 2991 return Representation::Integer32(); |
| 2989 } | 2992 } |
| 2990 | 2993 |
| 2991 virtual void PrintDataTo(StringStream* stream); | 2994 virtual void PrintDataTo(StringStream* stream); |
| 2995 virtual void InferRepresentation(HInferRepresentation* h_infer); | |
| 2992 | 2996 |
| 2993 HValue* index() { return OperandAt(0); } | 2997 HValue* index() { return OperandAt(0); } |
| 2994 HValue* length() { return OperandAt(1); } | 2998 HValue* length() { return OperandAt(1); } |
| 2995 | 2999 |
| 3000 virtual HValue* ActualValue() { | |
| 3001 return index(); | |
| 3002 } | |
| 3003 | |
| 2996 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 3004 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 2997 | 3005 |
| 2998 protected: | 3006 protected: |
| 2999 virtual bool DataEquals(HValue* other) { return true; } | 3007 virtual bool DataEquals(HValue* other) { return true; } |
| 3000 BoundsCheckKeyMode key_mode_; | 3008 BoundsCheckKeyMode key_mode_; |
| 3001 }; | 3009 }; |
| 3002 | 3010 |
| 3003 | 3011 |
| 3004 class HBitwiseBinaryOperation: public HBinaryOperation { | 3012 class HBitwiseBinaryOperation: public HBinaryOperation { |
| 3005 public: | 3013 public: |
| (...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4439 } | 4447 } |
| 4440 | 4448 |
| 4441 virtual Representation RequiredInputRepresentation(int index) { | 4449 virtual Representation RequiredInputRepresentation(int index) { |
| 4442 // kind_fast: tagged[int32] (none) | 4450 // kind_fast: tagged[int32] (none) |
| 4443 // kind_double: tagged[int32] (none) | 4451 // kind_double: tagged[int32] (none) |
| 4444 // kind_external: external[int32] (none) | 4452 // kind_external: external[int32] (none) |
| 4445 if (index == 0) { | 4453 if (index == 0) { |
| 4446 return is_external() ? Representation::External() | 4454 return is_external() ? Representation::External() |
| 4447 : Representation::Tagged(); | 4455 : Representation::Tagged(); |
| 4448 } | 4456 } |
| 4449 if (index == 1) return Representation::Integer32(); | 4457 if (index == 1) { |
| 4458 return OperandAt(1)->representation().KeyedAccessIndexRequirement(); | |
| 4459 } | |
| 4450 return Representation::None(); | 4460 return Representation::None(); |
| 4451 } | 4461 } |
| 4452 | 4462 |
| 4453 virtual Representation observed_input_representation(int index) { | 4463 virtual Representation observed_input_representation(int index) { |
| 4454 return RequiredInputRepresentation(index); | 4464 return RequiredInputRepresentation(index); |
| 4455 } | 4465 } |
| 4456 | 4466 |
| 4457 virtual void PrintDataTo(StringStream* stream); | 4467 virtual void PrintDataTo(StringStream* stream); |
| 4458 | 4468 |
| 4459 bool RequiresHoleCheck() const; | 4469 bool RequiresHoleCheck() const; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4654 } | 4664 } |
| 4655 | 4665 |
| 4656 virtual Representation RequiredInputRepresentation(int index) { | 4666 virtual Representation RequiredInputRepresentation(int index) { |
| 4657 // kind_fast: tagged[int32] = tagged | 4667 // kind_fast: tagged[int32] = tagged |
| 4658 // kind_double: tagged[int32] = double | 4668 // kind_double: tagged[int32] = double |
| 4659 // kind_external: external[int32] = (double | int32) | 4669 // kind_external: external[int32] = (double | int32) |
| 4660 if (index == 0) { | 4670 if (index == 0) { |
| 4661 return is_external() ? Representation::External() | 4671 return is_external() ? Representation::External() |
| 4662 : Representation::Tagged(); | 4672 : Representation::Tagged(); |
| 4663 } else if (index == 1) { | 4673 } else if (index == 1) { |
| 4664 return Representation::Integer32(); | 4674 return OperandAt(1)->representation().KeyedAccessIndexRequirement(); |
| 4665 } | 4675 } |
| 4666 | 4676 |
| 4667 ASSERT_EQ(index, 2); | 4677 ASSERT_EQ(index, 2); |
| 4668 if (IsDoubleOrFloatElementsKind(elements_kind())) { | 4678 if (IsDoubleOrFloatElementsKind(elements_kind())) { |
| 4669 return Representation::Double(); | 4679 return Representation::Double(); |
| 4670 } | 4680 } |
| 4671 | 4681 |
| 4672 return is_external() ? Representation::Integer32() | 4682 return is_external() ? Representation::Integer32() |
| 4673 : Representation::Tagged(); | 4683 : Representation::Tagged(); |
| 4674 } | 4684 } |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5446 virtual bool IsDeletable() const { return true; } | 5456 virtual bool IsDeletable() const { return true; } |
| 5447 }; | 5457 }; |
| 5448 | 5458 |
| 5449 | 5459 |
| 5450 #undef DECLARE_INSTRUCTION | 5460 #undef DECLARE_INSTRUCTION |
| 5451 #undef DECLARE_CONCRETE_INSTRUCTION | 5461 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5452 | 5462 |
| 5453 } } // namespace v8::internal | 5463 } } // namespace v8::internal |
| 5454 | 5464 |
| 5455 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5465 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |