@@ -69,6 +69,28 @@ static inline bool operator==(const Use & a, const Use & b) {
6969 return a.user == b.user && a.offset == b.offset ;
7070}
7171
72+ // Note [User node does not uniquely identify use]
73+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74+ // A while back, we wrote some code manipulating uses that looked like this:
75+ //
76+ // for (auto& use : used_val->uses_) {
77+ // if (use.user == this_node) {
78+ // use.offset += 1;
79+ // break;
80+ // }
81+ // }
82+ //
83+ // This code is trying to find a particular use (our node's use) to update it.
84+ // However, it's wrong: there may be *multiple* uses of a value %x in a node,
85+ // as might be the case in this IR:
86+ //
87+ // %y = Add %x %x
88+ //
89+ // In this case, there are two uses of %x whose user is the node 'Add %x %x'.
90+ // So, "use induced by this node" is not a well-formed concept.
91+ //
92+ // If you are looking for "use induced by an input", it's best to use
93+ // findUseForInput() to get it.
7294
7395
7496// Scope is a node of a trie that represents the tree of nested scopes.
@@ -406,6 +428,7 @@ struct Node : public Attributes<Node> {
406428 // indices [i, # input). Since we're inserting one input before all of
407429 // these inputs, increment their use offsets for this Node by 1
408430 for (size_t use_itr = i; use_itr < inputs_.size (); ++use_itr) {
431+ // See Note [User node does not uniquely identify use]
409432 auto use = findUseForInput (use_itr);
410433 use->offset += 1 ;
411434 }
0 commit comments