I have a practical question about traversing the IR via use-chains, as well as better understanding the design of the internal IR structure.
What I’d like to do is walk the uses of a value starting from some OpOperand (that is not necessarily the first or last use of the value).
From my understanding looking at the Understand The IR Structure document and the source code, an OpOperand represents a specific use of a value, and the uses are chained together in a doubly linked-list via previous (‘back’) and next (‘nextUse’) pointers.
What confuses me is two things:
- why is the order of uses inverse to that in the mlir source? I.e. ‘firstUse’ actually points to the last use, iterating through uses starts at the bottom and works upwards, etc.
- why is only one direction of links exposed? I.e. the ‘nextUse’ pointer is accessible via ‘getNextOperandUsingThisValue()’ (although inline documentation suggests it only be used internally), but there is no way to access the ‘back’ pointer.
So the problem I have is that I can’t walk downwards (in the mlir input) to the next use starting from some OpOperand of a specific operation.
On a related note, I’m assuming the order of value uses stems from the order of their associated operations, which, as described in the language ref, are in fact ordered within their block, and the blocks within their regions… Is this order maintained throughout transformations, because I noticed when printing a use-list after a transformation that operations were now partially out-of-order with respect to the mlir output. Or is this a bug on my end?