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

Kiran Chandramohan llvmlistbot at llvm.org
Wed Feb 7 04:20:01 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>)
+    }
+    ```
----------------
kiranchandramohan wrote:

I meant something like the following for firstprivate. We could also call the operation as `datasharing` instead of `private`. Not that `type` is an attribute here. and `alloc` and `copy` are regions.

```
    omp.private {type = firstprivate} @x.privatizer : !fir.ref<i32> (
    alloc {
    ^bb_alloc(%arg0: !fir.ref<i32>):
      %addr = fir.alloca i32
      omp.yield(%addr: !fir.ref<i32>)
    }, 
    copy {
    ^bb0(%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>)
    })
    ```
    
    And may be something like the following for `private`.
    
    omp.private {type = private} @x.privatizer : !fir.ref<i32> (
    alloc {
    ^bb_alloc(%arg0: !fir.ref<i32>):
      %addr = fir.alloca i32
      omp.yield(%addr: !fir.ref<i32>)
    })

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


More information about the Mlir-commits mailing list