could someone help to understand the relationship between them?
Similiar answer could be found for LLVM
however, the answer is LLVM-specific (instruction, function…)
is there understanding inside the MLIR?
could someone help to understand the relationship between them?
Similiar answer could be found for LLVM
however, the answer is LLVM-specific (instruction, function…)
is there understanding inside the MLIR?
In MLIR a value (mlir::Value
in C++`) is any kind of SSA value that is either produced by an operation, or a block argument of a block:
^bb0(%a : i32):
%res = arith.constant 5
Both %a
and %res
are values here. The %a
is a mlir::BlockArgument
, %res
is a OpResult
. Both of these convert to mlir::Value
(you can think of them as subclasses somewhat).
Every value has a list of uses attached to it. Whereever you use a Value
, the use gets recorded in this use-list. In terms of C++, the class representing the use is OpOperand
. An operation has an instance of OpOperand
for every operand it has, which contains the Value
the operand is set to.
The user is then simply the operation owning the OpOperand
which is a Operation*
at the very least (or can be cast to a more specific C++ Op class).
So to summarize:
mlir::Value
is a Value that has a list of usesmlir::OpOperand
represents a use and holds the mlir::Value
mlir::Operation*
(and more concrete Op classes) is the user and contains a list of OpOperand
s for its operands.There is a tutorial for this here: Understanding the IR Structure - MLIR
I included a diagram a the end.
thanks, i’m aware of this figure.
but i still have question about this figure after checking source code:
struct IROperand {
IRObjectWithUseList *value;
IROperand nextUse; // next operand in the use use-chain
IROperand **back; // points to the previous link in the use-chain
};
in your figure , there are 3 OpOperand
s
the leftmost is the first use of Value
, so the nextUse in the rightmost OpOperand
is nullptr
i have two questions regarding this figure:
back
(the comment inside the source code confuses me back = &value->firstUse;
// does it store the address of “address of OpOperand” ?really appriciate for your help.
thanks for your detail answer.
i have one more question if you don’t mind
what is “first use” in the use-chain?
when looking into source code of MLIR, it seems that use-list is updated by inserting in the tail
so the last one inserted is “first use”…
sorry for my silly question, but this really confuses me
I’m not following: why do you think it is null? It links to the next OpOperand
(the one in the middle)
If you look at the picture at the bottom with the 3 OpOperand
s, it includes the nextUse
and back
pointer: they link the 3 operands together. It’s a doubly-linked-list…
A new OpOperand
is created using this value, it is added to the link list of OpOperand
.
The first element of the link-list, again follow the pointer on the picture. Are we talking about the same picture? All the pointers you’re asking are drawn here I believe:
yes, we are talking about the same picture.
maybe, i don’t understand how the doubly-linked-list works.
struct IROperandBase {
/// The next operand in the use-chain.
IROperandBase *nextUse = nullptr;
/// This points to the previous link in the use-chain.
** IROperandBase back = nullptr; // ← it is pointer to pointer
}
Introduction to Doubly Linked List – Data Structure and Algorithm Tutorials - GeeksforGeeks is common
format of doubly-linked-list which i’m familiar with
let’s see the source code (https://github.com/llvm/llvm-project/blob/1b622fff44cac855c79adad3ad78b1f4010a2b96/mlir/include/mlir/IR/UseDefLists.h#L97) in terms of inserting :
/// Insert this operand into the given use list.
template
void insertInto(UseListT *useList) {
back = &useList->firstUse;
nextUse = useList->firstUse;
if (nextUse)
nextUse->back = &nextUse;
useList->firstUse = this;
}
the last inserted operand is marked as firstUse (useList->firstUse = this;)
back pointer doesn’t point to the previous use which is not same with figure
*back = &address_of_current_operand
please correct me if my understanding is wrong.