Changeset View
Changeset View
Standalone View
Standalone View
mlir/include/mlir/Dialect/StandardOps/IR/Ops.td
Show First 20 Lines • Show All 478 Lines • ▼ Show 20 Lines | def AtomicRMWOp : Std_Op<"atomic_rmw", [ | ||||
let extraClassDeclaration = [{ | let extraClassDeclaration = [{ | ||||
MemRefType getMemRefType() { | MemRefType getMemRefType() { | ||||
return memref().getType().cast<MemRefType>(); | return memref().getType().cast<MemRefType>(); | ||||
} | } | ||||
}]; | }]; | ||||
} | } | ||||
def GenericAtomicRMWOp : Std_Op<"generic_atomic_rmw", [ | |||||
SingleBlockImplicitTerminator<"AtomicYieldOp">, | |||||
TypesMatchWith<"result type matches element type of memref", | |||||
"memref", "result", | |||||
"$_self.cast<MemRefType>().getElementType()"> | |||||
]> { | |||||
let summary = "atomic read-modify-write operation with a region"; | |||||
let description = [{ | |||||
The `atomic_rmw` operation provides a way to perform a read-modify-write | |||||
sequence that is free from data races. The memref operand represents the | |||||
buffer that the read and write will be performed against, as accessed by | |||||
the specified indices. The arity of the indices is the rank of the memref. | |||||
The result represents the latest value that was stored. The region contains | |||||
the code for the modification itself. The entry block has a single argument | |||||
that represents the value stored in `memref[indices]` before the write is | |||||
performed. | |||||
mehdi_amini: We should mention that no side effecting operation is allowed in the region. | |||||
pifon2a: https://reviews.llvm.org/D78559 | |||||
Example: | |||||
```mlir | |||||
x = generic_atomic_rmw %I[%i] : memref<10xf32> { | |||||
x -> %x herhut: `x` -> `%x` | |||||
^bb0(%current_value : f32): | |||||
%c1 = constant 1.0 : f32 | |||||
%inc = addf %c1, %current_value : f32 | |||||
atomic_yield %inc : f32 | |||||
} | |||||
``` | |||||
}]; | |||||
let arguments = (ins | |||||
MemRefOf<[AnySignlessInteger, AnyFloat]>:$memref, | |||||
Variadic<Index>:$indices); | |||||
let results = (outs | |||||
AnyTypeOf<[AnySignlessInteger, AnyFloat]>:$result); | |||||
let regions = (region AnyRegion:$body); | |||||
let skipDefaultBuilders = 1; | |||||
let builders = [ | |||||
OpBuilder<"Builder *builder, OperationState &result, " | |||||
"Value memref, ValueRange ivs"> | |||||
]; | |||||
let extraClassDeclaration = [{ | |||||
OpBuilder getBodyBuilder() { | |||||
assert(!body().empty() && "Unexpected empty 'body' region."); | |||||
Block &block = body().front(); | |||||
return OpBuilder(&block, block.end()); | |||||
} | |||||
Not Done ReplyInline ActionsThis is the kind of method I expect provided by a Traits otherwise we're losing consistency across all operations with regions. mehdi_amini: This is the kind of method I expect provided by a Traits otherwise we're losing consistency… | |||||
Not Done ReplyInline ActionsDo you have a new trait in mind or should this be supported by the SingleBlockImplicitTerminator trait? The body builder makes only sense if there is a single region. These are somewhat widespread already. I'd rather have it as a separate cleanup. herhut: Do you have a new trait in mind or should this be supported by the… | |||||
I am happy to do the cleanup as soon as there is some consensus. pifon2a: I am happy to do the cleanup as soon as there is some consensus. | |||||
Not Done ReplyInline ActionsAdding it to SingleBlockImplicitTerminator looks fine to me mehdi_amini: Adding it to `SingleBlockImplicitTerminator` looks fine to me | |||||
Will do. pifon2a: Will do. | |||||
// The value stored in memref[ivs]. | |||||
Value getCurrentValue() { | |||||
return body().front().getArgument(0); | |||||
} | |||||
}]; | |||||
} | |||||
def AtomicYieldOp : Std_Op<"atomic_yield", [ | |||||
HasParent<"GenericAtomicRMWOp">, | |||||
NoSideEffect, | |||||
Terminator | |||||
]> { | |||||
let summary = "yield operation for GenericAtomicRMWOp"; | |||||
let description = [{ | |||||
"atomic_yield" yields an SSA value from a GenericAtomicRMWOp region. | |||||
}]; | |||||
let arguments = (ins AnyType:$result); | |||||
let assemblyFormat = "$result attr-dict `:` type($result)"; | |||||
} | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// BranchOp | // BranchOp | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
def BranchOp : Std_Op<"br", | def BranchOp : Std_Op<"br", | ||||
[DeclareOpInterfaceMethods<BranchOpInterface>, NoSideEffect, Terminator]> { | [DeclareOpInterfaceMethods<BranchOpInterface>, NoSideEffect, Terminator]> { | ||||
let summary = "branch operation"; | let summary = "branch operation"; | ||||
let description = [{ | let description = [{ | ||||
▲ Show 20 Lines • Show All 2,351 Lines • Show Last 20 Lines |
We should mention that no side effecting operation is allowed in the region.