[mlir][docs] Add usage/example of OpAsmOpInterface (#123610)
This is part of https://discourse.llvm.org/t/rfc-introduce-opasm-type-attr-interface-for-pretty-print-in-asmprinter/83792. OpAsmOpInterface controls the SSA Name/Block Name and Default Dialect Prefix. This PR adds the usage of them by existing examples in MLIR.
This commit is contained in:
parent
091741a880
commit
70d7c847fd
@ -48,4 +48,79 @@ void MyDialect::initialize() {
|
||||
```
|
||||
|
||||
* If `getAlias` provides an alias with a trailing digit, `AsmPrinter` appends an underscore to avoid conflicts with autogenerated IDs.
|
||||
* If multiple types/attributes have the same alias from `getAlias`, a number is appended to the alias to avoid conflicts.
|
||||
* If multiple types/attributes have the same alias from `getAlias`, a number is appended to the alias to avoid conflicts.
|
||||
|
||||
## Suggesting SSA/Block Names
|
||||
|
||||
An `Operation` can suggest the SSA name prefix using `OpAsmOpInterface`.
|
||||
|
||||
For example, `arith.constant` will suggest a name like `%c42_i32` for its result:
|
||||
|
||||
```tablegen
|
||||
include "mlir/IR/OpAsmInterface.td"
|
||||
|
||||
def Arith_ConstantOp : Op<Arith_Dialect, "constant",
|
||||
[ConstantLike, Pure,
|
||||
DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
And the corresponding method:
|
||||
|
||||
```cpp
|
||||
// from https://github.com/llvm/llvm-project/blob/5ce271ef74dd3325993c827f496e460ced41af11/mlir/lib/Dialect/Arith/IR/ArithOps.cpp#L184
|
||||
void arith::ConstantOp::getAsmResultNames(
|
||||
function_ref<void(Value, StringRef)> setNameFn) {
|
||||
auto type = getType();
|
||||
if (auto intCst = llvm::dyn_cast<IntegerAttr>(getValue())) {
|
||||
auto intType = llvm::dyn_cast<IntegerType>(type);
|
||||
|
||||
// Sugar i1 constants with 'true' and 'false'.
|
||||
if (intType && intType.getWidth() == 1)
|
||||
return setNameFn(getResult(), (intCst.getInt() ? "true" : "false"));
|
||||
|
||||
// Otherwise, build a complex name with the value and type.
|
||||
SmallString<32> specialNameBuffer;
|
||||
llvm::raw_svector_ostream specialName(specialNameBuffer);
|
||||
specialName << 'c' << intCst.getValue();
|
||||
if (intType)
|
||||
specialName << '_' << type;
|
||||
setNameFn(getResult(), specialName.str());
|
||||
} else {
|
||||
setNameFn(getResult(), "cst");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, an `Operation` can suggest the name for its block arguments using `getAsmBlockArgumentNames` method in `OpAsmOpInterface`.
|
||||
|
||||
For custom block names, `OpAsmOpInterface` has a method `getAsmBlockNames` so that
|
||||
the operation can suggest a custom prefix instead of a generic `^bb0`.
|
||||
|
||||
## Defining Default Dialect
|
||||
|
||||
An `Operation` can indicate that the nested region in it has a default dialect prefix, and the operations in the region could elide the dialect prefix.
|
||||
|
||||
For example, in a `func.func` op all `func` prefix could be omitted:
|
||||
|
||||
```tablegen
|
||||
include "mlir/IR/OpAsmInterface.td"
|
||||
|
||||
def FuncOp : Func_Op<"func", [
|
||||
OpAsmOpInterface
|
||||
...
|
||||
]> {
|
||||
let extraClassDeclaration = [{
|
||||
/// Allow the dialect prefix to be omitted.
|
||||
static StringRef getDefaultDialect() { return "func"; }
|
||||
}];
|
||||
}
|
||||
```
|
||||
|
||||
```mlir
|
||||
func.func @main() {
|
||||
// actually func.call
|
||||
call @another()
|
||||
}
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user