[Mlir-commits] [mlir] [MLIR][OpenMP] Add `omp.private` op (PR #80955)

Kareem Ergawy llvmlistbot at llvm.org
Wed Feb 7 03:27:05 PST 2024


================
@@ -133,6 +134,84 @@ def DeclareTargetAttr : OpenMP_Attr<"DeclareTarget", "declaretarget"> {
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// 2.19.4 Data-Sharing Attribute Clauses
+//===----------------------------------------------------------------------===//
+
+def PrivateClauseOp : OpenMP_Op<"private", [
+    IsolatedFromAbove, FunctionOpInterface
+  ]> {
+  let summary = "Outline [first]private logic in a separate op.";
+  let description = [{
+    Using this operation, the dialect can model the data-sharing attributes of
+    `private` and `firstprivate` variables on the IR level. This means that of
+    "eagerly" privatizing variables in the frontend, we can instead model which
+    variables should be privatized and only materialze the privatization when
+    necessary; e.g. directly before lowring to LLVM IR.
+
+    Examples:
+    ---------
+    * `private(x)` would be emitted as:
+    ```mlir
+    omp.private @x.privatizer : (!fir.ref<i32>) -> !fir.ref<i32> {
+    ^bb0(%arg0: !fir.ref<i32>):
+      %0 = fir.alloca i32
+      omp.yield(%0 : !fir.ref<i32>)
+    }
+    ```
+
+    * `firstprivate(x)` would be emitted as:
+    ```mlir
+    omp.private @x.privatizer : (!fir.ref<i32>) -> !fir.ref<i32> {
+    ^bb0(%arg0: !fir.ref<i32>):
+      %0 = fir.alloca i32
+      %1 = fir.load %arg0 : !fir.ref<i32>
+      fir.store %1 to %0 : !fir.ref<i32>
+      omp.yield(%0 : !fir.ref<i32>)
+    }
+    ```
----------------
ergawy wrote:

So, for `private`, the op would look something like this:
```mlir
    omp.private @x.privatizer : (!fir.ref<i32>) -> !fir.ref<i32> ({
    ^bb_alloc(%arg0: !fir.ref<i32>):
      %addr = fir.alloca i32
      omp.yiel(%addr: !fir.ref<i32>)
    }, {
    ^bb_init(%arg0: !fir.ref<i32>, %addr_arg: !fir.ref<i32>):
           omp.yield(%addr_arg : !fir.ref<i32>)
    })
```

And, for `firstprivate`, the op would look something like this:
```mlir
    omp.private @x.privatizer : (!fir.ref<i32>) -> !fir.ref<i32> ({
    ^bb_alloc(%arg0: !fir.ref<i32>):
      %addr = fir.alloca i32
      omp.yiel(%addr: !fir.ref<i32>)
    }, {
    ^bb_init(%arg0: !fir.ref<i32>, %addr_arg: !fir.ref<i32>):
            %init_val = fir.load %arg0 : !fir.ref<i32>
            fir.store %init_val to %addr_arg : !fir.ref<i32>
           omp.yield(%addr_arg : !fir.ref<i32>)
    })
```

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


More information about the Mlir-commits mailing list