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

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

Issue 17914002: First simplistic implementation of escape analysis. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed offline comments by Ben Titzer. Created 7 years, 5 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 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 bool HasRange() const { return range_ != NULL; } 1051 bool HasRange() const { return range_ != NULL; }
1052 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); } 1052 bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); }
1053 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); } 1053 bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); }
1054 bool RangeCanInclude(int value) const { 1054 bool RangeCanInclude(int value) const {
1055 return !HasRange() || range()->Includes(value); 1055 return !HasRange() || range()->Includes(value);
1056 } 1056 }
1057 void AddNewRange(Range* r, Zone* zone); 1057 void AddNewRange(Range* r, Zone* zone);
1058 void RemoveLastAddedRange(); 1058 void RemoveLastAddedRange();
1059 void ComputeInitialRange(Zone* zone); 1059 void ComputeInitialRange(Zone* zone);
1060 1060
1061 // Escape analysis helpers.
1062 virtual bool HasEscapingOperandAt(int index) { return true; }
1063
1061 // Representation helpers. 1064 // Representation helpers.
1062 virtual Representation observed_input_representation(int index) { 1065 virtual Representation observed_input_representation(int index) {
1063 return Representation::None(); 1066 return Representation::None();
1064 } 1067 }
1065 virtual Representation RequiredInputRepresentation(int index) = 0; 1068 virtual Representation RequiredInputRepresentation(int index) = 0;
1066 virtual void InferRepresentation(HInferRepresentation* h_infer); 1069 virtual void InferRepresentation(HInferRepresentation* h_infer);
1067 1070
1068 // This gives the instruction an opportunity to replace itself with an 1071 // This gives the instruction an opportunity to replace itself with an
1069 // instruction that does the same in some better way. To replace an 1072 // instruction that does the same in some better way. To replace an
1070 // instruction with a new one, first add the new instruction to the graph, 1073 // instruction with a new one, first add the new instruction to the graph,
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 explicit HDummyUse(HValue* value) { 1425 explicit HDummyUse(HValue* value) {
1423 SetOperandAt(0, value); 1426 SetOperandAt(0, value);
1424 // Pretend to be a Smi so that the HChange instructions inserted 1427 // Pretend to be a Smi so that the HChange instructions inserted
1425 // before any use generate as little code as possible. 1428 // before any use generate as little code as possible.
1426 set_representation(Representation::Tagged()); 1429 set_representation(Representation::Tagged());
1427 set_type(HType::Smi()); 1430 set_type(HType::Smi());
1428 } 1431 }
1429 1432
1430 HValue* value() { return OperandAt(0); } 1433 HValue* value() { return OperandAt(0); }
1431 1434
1435 virtual bool HasEscapingOperandAt(int index) { return false; }
1432 virtual Representation RequiredInputRepresentation(int index) { 1436 virtual Representation RequiredInputRepresentation(int index) {
1433 return Representation::None(); 1437 return Representation::None();
1434 } 1438 }
1435 1439
1436 virtual void PrintDataTo(StringStream* stream); 1440 virtual void PrintDataTo(StringStream* stream);
1437 1441
1438 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1442 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1439 }; 1443 };
1440 1444
1441 1445
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 } 1885 }
1882 int ToOperandIndex(int environment_index) { 1886 int ToOperandIndex(int environment_index) {
1883 for (int i = 0; i < assigned_indexes_.length(); ++i) { 1887 for (int i = 0; i < assigned_indexes_.length(); ++i) {
1884 if (assigned_indexes_[i] == environment_index) return i; 1888 if (assigned_indexes_[i] == environment_index) return i;
1885 } 1889 }
1886 return -1; 1890 return -1;
1887 } 1891 }
1888 virtual int OperandCount() { return values_.length(); } 1892 virtual int OperandCount() { return values_.length(); }
1889 virtual HValue* OperandAt(int index) const { return values_[index]; } 1893 virtual HValue* OperandAt(int index) const { return values_[index]; }
1890 1894
1895 virtual bool HasEscapingOperandAt(int index) { return false; }
1891 virtual Representation RequiredInputRepresentation(int index) { 1896 virtual Representation RequiredInputRepresentation(int index) {
1892 return Representation::None(); 1897 return Representation::None();
1893 } 1898 }
1894 1899
1895 void MergeWith(ZoneList<HSimulate*>* list); 1900 void MergeWith(ZoneList<HSimulate*>* list);
1896 bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; } 1901 bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
1897 1902
1898 DECLARE_CONCRETE_INSTRUCTION(Simulate) 1903 DECLARE_CONCRETE_INSTRUCTION(Simulate)
1899 1904
1900 #ifdef DEBUG 1905 #ifdef DEBUG
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
2790 Map* transitioned_map = 2795 Map* transitioned_map =
2791 map->LookupElementsTransitionMap(kind); 2796 map->LookupElementsTransitionMap(kind);
2792 if (transitioned_map) { 2797 if (transitioned_map) {
2793 check_map->map_set_.Add(Handle<Map>(transitioned_map), zone); 2798 check_map->map_set_.Add(Handle<Map>(transitioned_map), zone);
2794 } 2799 }
2795 }; 2800 };
2796 check_map->map_set_.Sort(); 2801 check_map->map_set_.Sort();
2797 return check_map; 2802 return check_map;
2798 } 2803 }
2799 2804
2805 virtual bool HasEscapingOperandAt(int index) { return false; }
2800 virtual Representation RequiredInputRepresentation(int index) { 2806 virtual Representation RequiredInputRepresentation(int index) {
2801 return Representation::Tagged(); 2807 return Representation::Tagged();
2802 } 2808 }
2803 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator); 2809 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator);
2804 virtual void PrintDataTo(StringStream* stream); 2810 virtual void PrintDataTo(StringStream* stream);
2805 virtual HType CalculateInferredType(); 2811 virtual HType CalculateInferredType();
2806 2812
2807 HValue* value() { return OperandAt(0); } 2813 HValue* value() { return OperandAt(0); }
2808 SmallMapList* map_set() { return &map_set_; } 2814 SmallMapList* map_set() { return &map_set_; }
2809 2815
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 int arguments_count() const { return values_.length(); } 3227 int arguments_count() const { return values_.length(); }
3222 3228
3223 void AddArgument(HValue* argument, Zone* zone) { 3229 void AddArgument(HValue* argument, Zone* zone) {
3224 values_.Add(NULL, zone); // Resize list. 3230 values_.Add(NULL, zone); // Resize list.
3225 SetOperandAt(values_.length() - 1, argument); 3231 SetOperandAt(values_.length() - 1, argument);
3226 } 3232 }
3227 3233
3228 virtual int OperandCount() { return values_.length(); } 3234 virtual int OperandCount() { return values_.length(); }
3229 virtual HValue* OperandAt(int index) const { return values_[index]; } 3235 virtual HValue* OperandAt(int index) const { return values_[index]; }
3230 3236
3237 virtual bool HasEscapingOperandAt(int index) { return false; }
3231 virtual Representation RequiredInputRepresentation(int index) { 3238 virtual Representation RequiredInputRepresentation(int index) {
3232 return Representation::None(); 3239 return Representation::None();
3233 } 3240 }
3234 3241
3235 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) 3242 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
3236 3243
3237 protected: 3244 protected:
3238 virtual void InternalSetOperandAt(int index, HValue* value) { 3245 virtual void InternalSetOperandAt(int index, HValue* value) {
3239 values_[index] = value; 3246 values_[index] = value;
3240 } 3247 }
(...skipping 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after
5424 HValue* object() { return OperandAt(0); } 5431 HValue* object() { return OperandAt(0); }
5425 HValue* typecheck() { 5432 HValue* typecheck() {
5426 ASSERT(HasTypeCheck()); 5433 ASSERT(HasTypeCheck());
5427 return OperandAt(1); 5434 return OperandAt(1);
5428 } 5435 }
5429 5436
5430 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } 5437 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5431 HObjectAccess access() const { return access_; } 5438 HObjectAccess access() const { return access_; }
5432 Representation field_representation() const { return representation_; } 5439 Representation field_representation() const { return representation_; }
5433 5440
5441 virtual bool HasEscapingOperandAt(int index) { return false; }
5434 virtual Representation RequiredInputRepresentation(int index) { 5442 virtual Representation RequiredInputRepresentation(int index) {
5435 return Representation::Tagged(); 5443 return Representation::Tagged();
5436 } 5444 }
5437 virtual void PrintDataTo(StringStream* stream); 5445 virtual void PrintDataTo(StringStream* stream);
5438 5446
5439 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 5447 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5440 5448
5441 protected: 5449 protected:
5442 virtual bool DataEquals(HValue* other) { 5450 virtual bool DataEquals(HValue* other) {
5443 HLoadNamedField* b = HLoadNamedField::cast(other); 5451 HLoadNamedField* b = HLoadNamedField::cast(other);
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
5756 transition_(), 5764 transition_(),
5757 transition_unique_id_(), 5765 transition_unique_id_(),
5758 new_space_dominator_(NULL) { 5766 new_space_dominator_(NULL) {
5759 SetOperandAt(0, obj); 5767 SetOperandAt(0, obj);
5760 SetOperandAt(1, val); 5768 SetOperandAt(1, val);
5761 access.SetGVNFlags(this, true); 5769 access.SetGVNFlags(this, true);
5762 } 5770 }
5763 5771
5764 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 5772 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
5765 5773
5774 virtual bool HasEscapingOperandAt(int index) { return index == 1; }
5766 virtual Representation RequiredInputRepresentation(int index) { 5775 virtual Representation RequiredInputRepresentation(int index) {
5767 if (FLAG_track_double_fields && 5776 if (FLAG_track_double_fields &&
5768 index == 1 && field_representation_.IsDouble()) { 5777 index == 1 && field_representation_.IsDouble()) {
5769 return field_representation_; 5778 return field_representation_;
5770 } else if (FLAG_track_fields && 5779 } else if (FLAG_track_fields &&
5771 index == 1 && field_representation_.IsSmi()) { 5780 index == 1 && field_representation_.IsSmi()) {
5772 return field_representation_; 5781 return field_representation_;
5773 } 5782 }
5774 return Representation::Tagged(); 5783 return Representation::Tagged();
5775 } 5784 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
5858 Handle<String> name_; 5867 Handle<String> name_;
5859 StrictModeFlag strict_mode_flag_; 5868 StrictModeFlag strict_mode_flag_;
5860 }; 5869 };
5861 5870
5862 5871
5863 class HStoreKeyed 5872 class HStoreKeyed
5864 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 5873 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
5865 public: 5874 public:
5866 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 5875 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
5867 ElementsKind elements_kind) 5876 ElementsKind elements_kind)
5868 : elements_kind_(elements_kind), 5877 : elements_kind_(elements_kind),
titzer 2013/06/28 12:40:55 Perhaps: HasEscapingOperandAt(int index) { return
Michael Starzinger 2013/06/28 13:37:27 Done. As discussed offline: This will only work of
5869 index_offset_(0), 5878 index_offset_(0),
5870 is_dehoisted_(false), 5879 is_dehoisted_(false),
5871 new_space_dominator_(NULL) { 5880 new_space_dominator_(NULL) {
5872 SetOperandAt(0, obj); 5881 SetOperandAt(0, obj);
5873 SetOperandAt(1, key); 5882 SetOperandAt(1, key);
5874 SetOperandAt(2, val); 5883 SetOperandAt(2, val);
5875 5884
5876 if (IsFastObjectElementsKind(elements_kind)) { 5885 if (IsFastObjectElementsKind(elements_kind)) {
5877 SetFlag(kTrackSideEffectDominators); 5886 SetFlag(kTrackSideEffectDominators);
5878 SetGVNFlag(kDependsOnNewSpacePromotion); 5887 SetGVNFlag(kDependsOnNewSpacePromotion);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5981 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) 5990 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
5982 5991
5983 private: 5992 private:
5984 ElementsKind elements_kind_; 5993 ElementsKind elements_kind_;
5985 uint32_t index_offset_; 5994 uint32_t index_offset_;
5986 bool is_dehoisted_; 5995 bool is_dehoisted_;
5987 HValue* new_space_dominator_; 5996 HValue* new_space_dominator_;
5988 }; 5997 };
5989 5998
5990 5999
5991 class HStoreKeyedGeneric: public HTemplateInstruction<4> { 6000 class HStoreKeyedGeneric: public HTemplateInstruction<4> {
titzer 2013/06/28 12:40:55 Also here...
Michael Starzinger 2013/06/28 13:37:27 For a generic store I think this won't work as the
5992 public: 6001 public:
5993 HStoreKeyedGeneric(HValue* context, 6002 HStoreKeyedGeneric(HValue* context,
5994 HValue* object, 6003 HValue* object,
5995 HValue* key, 6004 HValue* key,
5996 HValue* value, 6005 HValue* value,
5997 StrictModeFlag strict_mode_flag) 6006 StrictModeFlag strict_mode_flag)
5998 : strict_mode_flag_(strict_mode_flag) { 6007 : strict_mode_flag_(strict_mode_flag) {
5999 SetOperandAt(0, object); 6008 SetOperandAt(0, object);
6000 SetOperandAt(1, key); 6009 SetOperandAt(1, key);
6001 SetOperandAt(2, value); 6010 SetOperandAt(2, value);
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
6641 virtual bool IsDeletable() const { return true; } 6650 virtual bool IsDeletable() const { return true; }
6642 }; 6651 };
6643 6652
6644 6653
6645 #undef DECLARE_INSTRUCTION 6654 #undef DECLARE_INSTRUCTION
6646 #undef DECLARE_CONCRETE_INSTRUCTION 6655 #undef DECLARE_CONCRETE_INSTRUCTION
6647 6656
6648 } } // namespace v8::internal 6657 } } // namespace v8::internal
6649 6658
6650 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6659 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698