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 { |