[Mlir-commits] [mlir] [OpenMP][MLIR] Add omp.canonical_loop operation, !omp.cli type, omp.new_cli operation (PR #71712)

Michael Kruse llvmlistbot at llvm.org
Mon Mar 11 06:17:53 PDT 2024


Meinersbur wrote:

> The way we thought about it was that omp.new_cli was like an alloca, and the loop operations like loads and stores. Maybe we need model this as a resource and add side effects to the ops?

I'd agree with this characterization. There is an analogy to `mlir::Value`:

|                | `mlir::Value` | `mlir::omp::CanonicalLoopInfo` |
|--------------|-----------|------------|
| Value-semantics  | Returned by operation: <br>`%val = op(%args : type) : type` , immutable afterwards<br>Used via passing as argument: `op(%val)`    | Returned by `omp.canonical_loop` and transformations, immutable afterwards<br>Used via passing as argument: `omp.workshare_this_loop(%cli : !omp.cli)` |
| Reference-semantics      | Allocated via `%p = memref.alloca() : memref<type>`<br>Defined via store: `memref.store %val,%p : memref<type>` <br>Used via load: `%val = load %p: memref<type>` | Allocated via `%cli = omp.new_cli : !omp.cli` <br>Defined as literal loop via `omp.canonical_loop(%cli : !omp.cli)` or as result of a transformation e.g. `omp.tile(%generated_outer : !omp.cli, %generated_inner : !omp.cli, ...)`<br>Used via passing as argument, e.g. `omp.workshare_this_loop(%cli : !omp.cli, ...)` |

Each `!omp.cli` should have exactly one allocation, one definition, and at most one use. After a use it should count as "consumed", like `free` does to pointers. The reason is to make the order of transformations unambiguous. If there are two transformations using the same `%cli`, we would need to evaluate control flow to determine the order in which we apply them. We cannot reliably evaluate control-flow at compile-time as it may depend on runtime-values. Thus, like the transform dialect, these are "meta-operations".

Personally, I think that the "value-semantics" row better fits the intended semantics (e.g. exactly one definition), but would come at the cost of having to pass it out of scopes in nested loops. I talked with @jsjodin about this at the last DevMtg, he prefers the reference-semantics, so that's what we are going with. 

https://github.com/llvm/llvm-project/pull/71712


More information about the Mlir-commits mailing list