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

Side by Side Diff: src/hydrogen-instructions.h

Issue 10543094: Eliminate redundant smi checks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Delay SMI checks as long as possible Created 8 years, 6 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 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 void ChangeRepresentation(Representation r) { 612 void ChangeRepresentation(Representation r) {
613 // Representation was already set and is allowed to be changed. 613 // Representation was already set and is allowed to be changed.
614 ASSERT(!r.IsNone()); 614 ASSERT(!r.IsNone());
615 ASSERT(CheckFlag(kFlexibleRepresentation)); 615 ASSERT(CheckFlag(kFlexibleRepresentation));
616 RepresentationChanged(r); 616 RepresentationChanged(r);
617 representation_ = r; 617 representation_ = r;
618 } 618 }
619 void AssumeRepresentation(Representation r); 619 void AssumeRepresentation(Representation r);
620 620
621 virtual bool IsConvertibleToInteger() const { return true; } 621 virtual bool IsConvertibleToInteger() const { return true; }
622 virtual bool IsValueTaggedSmi() const { return false; }
Michael Starzinger 2012/06/12 08:10:43 Can't we use HValue::CalculateInferredType instead
danno 2012/06/12 09:59:22 No, unfortunately not. The representation is tagge
Michael Starzinger 2012/06/12 10:48:05 Yes, I agree, the representation has to be tagged.
622 623
623 HType type() const { return type_; } 624 HType type() const { return type_; }
624 void set_type(HType new_type) { 625 void set_type(HType new_type) {
625 ASSERT(new_type.IsSubtypeOf(type_)); 626 ASSERT(new_type.IsSubtypeOf(type_));
626 type_ = new_type; 627 type_ = new_type;
627 } 628 }
628 629
629 // An operation needs to override this function iff: 630 // An operation needs to override this function iff:
630 // 1) it can produce an int32 output. 631 // 1) it can produce an int32 output.
631 // 2) the true value of its output can potentially be minus zero. 632 // 2) the true value of its output can potentially be minus zero.
(...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 DECLARE_CONCRETE_INSTRUCTION(CallRuntime) 1842 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
1842 1843
1843 private: 1844 private:
1844 const Runtime::Function* c_function_; 1845 const Runtime::Function* c_function_;
1845 Handle<String> name_; 1846 Handle<String> name_;
1846 }; 1847 };
1847 1848
1848 1849
1849 class HJSArrayLength: public HTemplateInstruction<2> { 1850 class HJSArrayLength: public HTemplateInstruction<2> {
1850 public: 1851 public:
1851 HJSArrayLength(HValue* value, HValue* typecheck) { 1852 HJSArrayLength(HValue* value, HValue* typecheck,
1853 bool result_is_smi)
Michael Starzinger 2012/06/12 08:10:43 Can we use an enum instead of a bool flag here?
danno 2012/06/12 09:59:22 Done.
1854 : result_is_smi_(result_is_smi) {
1852 // The length of an array is stored as a tagged value in the array 1855 // The length of an array is stored as a tagged value in the array
1853 // object. It is guaranteed to be 32 bit integer, but it can be 1856 // object. It is guaranteed to be 32 bit integer, but it can be
1854 // represented as either a smi or heap number. 1857 // represented as either a smi or heap number.
1855 SetOperandAt(0, value); 1858 SetOperandAt(0, value);
1856 SetOperandAt(1, typecheck); 1859 SetOperandAt(1, typecheck);
1857 set_representation(Representation::Tagged()); 1860 set_representation(Representation::Tagged());
1858 SetFlag(kUseGVN); 1861 SetFlag(kUseGVN);
1859 SetGVNFlag(kDependsOnArrayLengths); 1862 SetGVNFlag(kDependsOnArrayLengths);
1860 SetGVNFlag(kDependsOnMaps); 1863 SetGVNFlag(kDependsOnMaps);
1861 } 1864 }
1862 1865
1863 virtual Representation RequiredInputRepresentation(int index) { 1866 virtual Representation RequiredInputRepresentation(int index) {
1864 return Representation::Tagged(); 1867 return Representation::Tagged();
1865 } 1868 }
1866 1869
1867 virtual void PrintDataTo(StringStream* stream); 1870 virtual void PrintDataTo(StringStream* stream);
1868 1871
1869 HValue* value() { return OperandAt(0); } 1872 HValue* value() { return OperandAt(0); }
1870 HValue* typecheck() { return OperandAt(1); } 1873 HValue* typecheck() { return OperandAt(1); }
1871 1874
1875 virtual bool IsValueTaggedSmi() const {
Michael Starzinger 2012/06/12 08:10:43 See first comment in this file.
danno 2012/06/12 09:59:22 See my reply above. On 2012/06/12 08:10:43, Micha
1876 return result_is_smi_;
1877 }
1878
1872 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength) 1879 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
1873 1880
1874 protected: 1881 protected:
1875 virtual bool DataEquals(HValue* other) { return true; } 1882 virtual bool DataEquals(HValue* other_raw) {
1883 HJSArrayLength* other = HJSArrayLength::cast(other_raw);
1884 return result_is_smi_ == other->result_is_smi_;
1885 }
1886
1887 private:
1888 bool result_is_smi_;
1876 }; 1889 };
1877 1890
1878 1891
1879 class HFixedArrayBaseLength: public HUnaryOperation { 1892 class HFixedArrayBaseLength: public HUnaryOperation {
1880 public: 1893 public:
1881 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) { 1894 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
1882 set_representation(Representation::Tagged()); 1895 set_representation(Representation::Tagged());
1883 SetFlag(kUseGVN); 1896 SetFlag(kUseGVN);
1884 SetGVNFlag(kDependsOnArrayLengths); 1897 SetGVNFlag(kDependsOnArrayLengths);
1885 } 1898 }
(...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 class ArrayInstructionInterface { 3986 class ArrayInstructionInterface {
3974 public: 3987 public:
3975 virtual HValue* GetKey() = 0; 3988 virtual HValue* GetKey() = 0;
3976 virtual void SetKey(HValue* key) = 0; 3989 virtual void SetKey(HValue* key) = 0;
3977 virtual void SetIndexOffset(uint32_t index_offset) = 0; 3990 virtual void SetIndexOffset(uint32_t index_offset) = 0;
3978 virtual bool IsDehoisted() = 0; 3991 virtual bool IsDehoisted() = 0;
3979 virtual void SetDehoisted(bool is_dehoisted) = 0; 3992 virtual void SetDehoisted(bool is_dehoisted) = 0;
3980 virtual ~ArrayInstructionInterface() { }; 3993 virtual ~ArrayInstructionInterface() { };
3981 }; 3994 };
3982 3995
3983
3984 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; 3996 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
3985 3997
3986 class HLoadKeyedFastElement 3998 class HLoadKeyedFastElement
3987 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 3999 : public HTemplateInstruction<2>, public ArrayInstructionInterface {
3988 public: 4000 public:
3989 HLoadKeyedFastElement(HValue* obj, 4001 HLoadKeyedFastElement(HValue* obj,
3990 HValue* key, 4002 HValue* key,
3991 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) 4003 HoleCheckMode mode,
3992 : hole_check_mode_(hole_check_mode), 4004 ElementsKind elements_kind = FAST_ELEMENTS)
3993 index_offset_(0), 4005 : bit_field_(0) {
3994 is_dehoisted_(false) { 4006 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4007 ASSERT(mode == OMIT_HOLE_CHECK ||
4008 IsFastHoleyElementsKind(elements_kind));
4009 bit_field_ = ElementsKindField::encode(elements_kind) |
4010 HoleCheckModeField::encode(mode);
3995 SetOperandAt(0, obj); 4011 SetOperandAt(0, obj);
3996 SetOperandAt(1, key); 4012 SetOperandAt(1, key);
3997 set_representation(Representation::Tagged()); 4013 set_representation(Representation::Tagged());
3998 SetGVNFlag(kDependsOnArrayElements); 4014 SetGVNFlag(kDependsOnArrayElements);
3999 SetFlag(kUseGVN); 4015 SetFlag(kUseGVN);
4000 } 4016 }
4001 4017
4002 HValue* object() { return OperandAt(0); } 4018 HValue* object() { return OperandAt(0); }
4003 HValue* key() { return OperandAt(1); } 4019 HValue* key() { return OperandAt(1); }
4004 uint32_t index_offset() { return index_offset_; } 4020 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4005 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4021 void SetIndexOffset(uint32_t index_offset) {
4022 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4023 }
4006 HValue* GetKey() { return key(); } 4024 HValue* GetKey() { return key(); }
4007 void SetKey(HValue* key) { SetOperandAt(1, key); } 4025 void SetKey(HValue* key) { SetOperandAt(1, key); }
4008 bool IsDehoisted() { return is_dehoisted_; } 4026 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4009 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4027 void SetDehoisted(bool is_dehoisted) {
4028 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4029 }
4030 ElementsKind elements_kind() const {
4031 return ElementsKindField::decode(bit_field_);
4032 }
4033 HoleCheckMode hole_check_mode() const {
4034 return HoleCheckModeField::decode(bit_field_);
4035 }
4036
4037 virtual bool IsValueTaggedSmi() const {
4038 return IsFastSmiElementsKind(elements_kind()) &&
4039 IsFastPackedElementsKind(elements_kind());
4040 }
4010 4041
4011 virtual Representation RequiredInputRepresentation(int index) { 4042 virtual Representation RequiredInputRepresentation(int index) {
4012 // The key is supposed to be Integer32. 4043 // The key is supposed to be Integer32.
4013 return index == 0 4044 return index == 0
4014 ? Representation::Tagged() 4045 ? Representation::Tagged()
4015 : Representation::Integer32(); 4046 : Representation::Integer32();
4016 } 4047 }
4017 4048
4018 virtual void PrintDataTo(StringStream* stream); 4049 virtual void PrintDataTo(StringStream* stream);
4019 4050
4020 bool RequiresHoleCheck(); 4051 bool RequiresHoleCheck();
4021 4052
4022 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) 4053 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
4023 4054
4024 protected: 4055 protected:
4025 virtual bool DataEquals(HValue* other) { 4056 virtual bool DataEquals(HValue* other) {
4026 if (!other->IsLoadKeyedFastElement()) return false; 4057 if (!other->IsLoadKeyedFastElement()) return false;
4027 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); 4058 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other);
4028 if (is_dehoisted_ && index_offset_ != other_load->index_offset_) 4059 if (IsDehoisted() && index_offset() != other_load->index_offset())
4029 return false; 4060 return false;
4030 return hole_check_mode_ == other_load->hole_check_mode_; 4061 return elements_kind() == other_load->elements_kind() &&
4062 hole_check_mode() == other_load->hole_check_mode();
4031 } 4063 }
4032 4064
4033 private: 4065 private:
4034 HoleCheckMode hole_check_mode_; 4066 class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
4035 uint32_t index_offset_; 4067 class IndexOffsetField: public BitField<uint32_t, 4, 25> {};
4036 bool is_dehoisted_; 4068 class HoleCheckModeField: public BitField<HoleCheckMode, 29, 1> {};
4069 class IsDehoistedField: public BitField<bool, 30, 1> {};
4070 uint32_t bit_field_;
4037 }; 4071 };
4038 4072
4039 4073
4040 class HLoadKeyedFastDoubleElement 4074 class HLoadKeyedFastDoubleElement
4041 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4075 : public HTemplateInstruction<2>, public ArrayInstructionInterface {
4042 public: 4076 public:
4043 HLoadKeyedFastDoubleElement( 4077 HLoadKeyedFastDoubleElement(
4044 HValue* elements, 4078 HValue* elements,
4045 HValue* key, 4079 HValue* key,
4046 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) 4080 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
4047 : index_offset_(0), 4081 : index_offset_(0),
4048 is_dehoisted_(false), 4082 is_dehoisted_(false),
4049 hole_check_mode_(hole_check_mode) { 4083 hole_check_mode_(hole_check_mode) {
4050 SetOperandAt(0, elements); 4084 SetOperandAt(0, elements);
4051 SetOperandAt(1, key); 4085 SetOperandAt(1, key);
4052 set_representation(Representation::Double()); 4086 set_representation(Representation::Double());
4053 SetGVNFlag(kDependsOnDoubleArrayElements); 4087 SetGVNFlag(kDependsOnDoubleArrayElements);
4054 SetFlag(kUseGVN); 4088 SetFlag(kUseGVN);
4055 } 4089 }
4056 4090
4057 HValue* elements() { return OperandAt(0); } 4091 HValue* elements() { return OperandAt(0); }
4058 HValue* key() { return OperandAt(1); } 4092 HValue* key() { return OperandAt(1); }
4059 uint32_t index_offset() { return index_offset_; } 4093 uint32_t index_offset() { return index_offset_; }
4060 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4094 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4061 HValue* GetKey() { return key(); } 4095 HValue* GetKey() { return key(); }
4062 void SetKey(HValue* key) { SetOperandAt(1, key); } 4096 void SetKey(HValue* key) { SetOperandAt(1, key); }
4063 bool IsDehoisted() { return is_dehoisted_; } 4097 bool IsDehoisted() { return is_dehoisted_; }
4064 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4098 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4065 4099
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
5088 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5122 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5089 }; 5123 };
5090 5124
5091 5125
5092 #undef DECLARE_INSTRUCTION 5126 #undef DECLARE_INSTRUCTION
5093 #undef DECLARE_CONCRETE_INSTRUCTION 5127 #undef DECLARE_CONCRETE_INSTRUCTION
5094 5128
5095 } } // namespace v8::internal 5129 } } // namespace v8::internal
5096 5130
5097 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5131 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698