Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index 561dbc1d0f826cac6b63ab556f60b84fd9146b49..8d39b69330767095864b899b3df4294217ef3875 100644 |
| --- a/src/hydrogen-instructions.h |
| +++ b/src/hydrogen-instructions.h |
| @@ -403,6 +403,62 @@ class HType { |
| }; |
| +class HUseListNode: public ZoneObject { |
| + public: |
| + HUseListNode(HValue* value, int index, HUseListNode* tail) |
| + : tail_(tail), value_(value), index_(index) { |
| + } |
| + |
| + HUseListNode* tail() const { return tail_; } |
| + HValue* value() const { return value_; } |
| + int index() const { return index_; } |
| + |
| + void set_tail(HUseListNode* list) { tail_ = list; } |
| + |
| +#ifdef DEBUG |
| + void Zap() { |
| + tail_ = reinterpret_cast<HUseListNode*>(1); |
| + value_ = NULL; |
| + index_ = -1; |
| + } |
| +#endif |
| + |
| + private: |
| + HUseListNode* tail_; |
| + HValue* value_; |
| + int index_; |
| +}; |
| + |
| + |
| +// We reuse use list nodes behind the scenes as uses are added and deleted. |
| +// This class is the safe way to iterate uses while deleting them. |
| +class HUseIterator BASE_EMBEDDED { |
| + public: |
| + bool Done() { return current_ == NULL; } |
| + void Advance(); |
| + |
| + HValue* value() { |
| + ASSERT(!Done()); |
| + return value_; |
| + } |
| + |
| + int index() { |
| + ASSERT(!Done()); |
| + return index_; |
| + } |
| + |
| + private: |
| + explicit HUseIterator(HUseListNode* head); |
| + |
| + HUseListNode* current_; |
| + HUseListNode* next_; |
| + HValue* value_; |
| + int index_; |
| + |
| + friend class HValue; |
| +}; |
| + |
| + |
| class HValue: public ZoneObject { |
| public: |
| static const int kNoNumber = -1; |
| @@ -473,6 +529,7 @@ class HValue: public ZoneObject { |
| HValue() : block_(NULL), |
| id_(kNoNumber), |
| type_(HType::Tagged()), |
| + use_list_(NULL), |
| range_(NULL), |
| flags_(0) {} |
| virtual ~HValue() {} |
| @@ -483,7 +540,7 @@ class HValue: public ZoneObject { |
| int id() const { return id_; } |
| void set_id(int id) { id_ = id; } |
| - SmallPointerList<HValue>* uses() { return &uses_; } |
| + HUseIterator uses() const { return HUseIterator(use_list_); } |
| virtual bool EmitAtUses() { return false; } |
| Representation representation() const { return representation_; } |
| @@ -498,7 +555,7 @@ class HValue: public ZoneObject { |
| HType type() const { return type_; } |
| void set_type(HType type) { |
| - ASSERT(uses_.length() == 0); |
| + ASSERT(HasNoUses()); |
| type_ = type; |
| } |
| @@ -524,16 +581,13 @@ class HValue: public ZoneObject { |
| virtual HValue* OperandAt(int index) = 0; |
| void SetOperandAt(int index, HValue* value); |
| - int LookupOperandIndex(int occurrence_index, HValue* op); |
| - bool UsesMultipleTimes(HValue* op); |
| - |
| - void ReplaceAndDelete(HValue* other); |
| - void ReplaceValue(HValue* other); |
| - void ReplaceAtUse(HValue* use, HValue* other); |
| - void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r); |
| - bool HasNoUses() const { return uses_.is_empty(); } |
| + void DeleteAndReplaceWith(HValue* other); |
| + bool HasNoUses() const { return use_list_ == NULL; } |
| + bool HasMultipleUses() const { |
| + return use_list_ != NULL && use_list_->tail() != NULL; |
| + } |
| + int UseCount() const; |
| void ClearOperands(); |
| - void Delete(); |
| int flags() const { return flags_; } |
| void SetFlag(Flag f) { flags_ |= (1 << f); } |
| @@ -611,7 +665,12 @@ class HValue: public ZoneObject { |
| return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); |
| } |
| - void InternalReplaceAtUse(HValue* use, HValue* other); |
| + // Remove the matching use from the use list if present. Returns the |
| + // removed list node or NULL. |
| + HUseListNode* RemoveUse(HValue* value, int index); |
|
danno
2011/04/20 04:25:12
How about wrapping HValue* and int in a HUse struc
|
| + |
| + void ReplaceAllUsesWith(HValue* other); |
| + |
| void RegisterUse(int index, HValue* new_value); |
| HBasicBlock* block_; |
| @@ -622,7 +681,7 @@ class HValue: public ZoneObject { |
| Representation representation_; |
| HType type_; |
| - SmallPointerList<HValue> uses_; |
| + HUseListNode* use_list_; |
| Range* range_; |
| int flags_; |
| @@ -2257,7 +2316,7 @@ class HCompare: public HBinaryOperation { |
| void SetInputRepresentation(Representation r); |
| virtual bool EmitAtUses() { |
| - return !HasSideEffects() && (uses()->length() <= 1); |
| + return !HasSideEffects() && !HasMultipleUses(); |
| } |
| virtual Representation RequiredInputRepresentation(int index) const { |
| @@ -2299,7 +2358,7 @@ class HCompareJSObjectEq: public HBinaryOperation { |
| } |
| virtual bool EmitAtUses() { |
| - return !HasSideEffects() && (uses()->length() <= 1); |
| + return !HasSideEffects() && !HasMultipleUses(); |
| } |
| virtual Representation RequiredInputRepresentation(int index) const { |
| @@ -2322,7 +2381,7 @@ class HUnaryPredicate: public HUnaryOperation { |
| } |
| virtual bool EmitAtUses() { |
| - return !HasSideEffects() && (uses()->length() <= 1); |
| + return !HasSideEffects() && !HasMultipleUses(); |
| } |
| virtual Representation RequiredInputRepresentation(int index) const { |
| @@ -2382,7 +2441,7 @@ class HIsConstructCall: public HTemplateInstruction<0> { |
| } |
| virtual bool EmitAtUses() { |
| - return !HasSideEffects() && (uses()->length() <= 1); |
| + return !HasSideEffects() && !HasMultipleUses(); |
| } |
| virtual Representation RequiredInputRepresentation(int index) const { |
| @@ -2504,7 +2563,7 @@ class HInstanceOf: public HTemplateInstruction<3> { |
| HValue* right() { return OperandAt(2); } |
| virtual bool EmitAtUses() { |
| - return !HasSideEffects() && (uses()->length() <= 1); |
| + return !HasSideEffects() && !HasMultipleUses(); |
| } |
| virtual Representation RequiredInputRepresentation(int index) const { |