|
| 1 | +! TODO Convert this file into a bunch of lit tests for each conversion step. |
| 2 | + |
1 | 3 | subroutine delayed_privatization()
|
2 | 4 | integer :: var1
|
3 | 5 | integer :: var2
|
4 | 6 |
|
| 7 | + var1 = 111 |
| 8 | + var2 = 222 |
| 9 | + |
5 | 10 | !$OMP PARALLEL FIRSTPRIVATE(var1, var2)
|
6 | 11 | var1 = var1 + var2 + 2
|
7 | 12 | !$OMP END PARALLEL
|
8 | 13 |
|
9 | 14 | end subroutine
|
10 | 15 |
|
11 |
| -! This is what flang emits with the PoC: |
12 |
| -! -------------------------------------- |
| 16 | +! ----------------------------------------- |
| 17 | +! ## This is what flang emits with the PoC: |
| 18 | +! ----------------------------------------- |
13 | 19 | !
|
14 |
| -!func.func @_QPdelayed_privatization() { |
15 |
| -! %0 = fir.alloca i32 {bindc_name = "var1", uniq_name = "_QFdelayed_privatizationEvar1"} |
16 |
| -! %1 = fir.alloca i32 {bindc_name = "var2", uniq_name = "_QFdelayed_privatizationEvar2"} |
17 |
| -! omp.parallel private(@var1.privatizer %0, @var2.privatizer %1 : !fir.ref<i32>, !fir.ref<i32>) { |
18 |
| -! %2 = fir.load %0 : !fir.ref<i32> |
19 |
| -! %3 = fir.load %1 : !fir.ref<i32> |
20 |
| -! %4 = arith.addi %2, %3 : i32 |
21 |
| -! %c2_i32 = arith.constant 2 : i32 |
22 |
| -! %5 = arith.addi %4, %c2_i32 : i32 |
23 |
| -! fir.store %5 to %0 : !fir.ref<i32> |
24 |
| -! omp.terminator |
| 20 | +! ---------------------------- |
| 21 | +! ### Conversion to FIR + OMP: |
| 22 | +! ---------------------------- |
| 23 | +!module { |
| 24 | +! func.func @_QPdelayed_privatization() { |
| 25 | +! %0 = fir.alloca i32 {bindc_name = "var1", uniq_name = "_QFdelayed_privatizationEvar1"} |
| 26 | +! %1 = fir.alloca i32 {bindc_name = "var2", uniq_name = "_QFdelayed_privatizationEvar2"} |
| 27 | +! %c111_i32 = arith.constant 111 : i32 |
| 28 | +! fir.store %c111_i32 to %0 : !fir.ref<i32> |
| 29 | +! %c222_i32 = arith.constant 222 : i32 |
| 30 | +! fir.store %c222_i32 to %1 : !fir.ref<i32> |
| 31 | +! omp.parallel private(@var1.privatizer %0, @var2.privatizer %1 : !fir.ref<i32>, !fir.ref<i32>) { |
| 32 | +! %2 = fir.load %0 : !fir.ref<i32> |
| 33 | +! %3 = fir.load %1 : !fir.ref<i32> |
| 34 | +! %4 = arith.addi %2, %3 : i32 |
| 35 | +! %c2_i32 = arith.constant 2 : i32 |
| 36 | +! %5 = arith.addi %4, %c2_i32 : i32 |
| 37 | +! fir.store %5 to %0 : !fir.ref<i32> |
| 38 | +! omp.terminator |
| 39 | +! } |
| 40 | +! return |
25 | 41 | ! }
|
26 |
| -! return |
| 42 | +! "omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var1.privatizer"}> ({ |
| 43 | +! ^bb0(%arg0: !fir.ref<i32>): |
| 44 | +! %0 = fir.alloca i32 {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatizationEvar1"} |
| 45 | +! %1 = fir.load %arg0 : !fir.ref<i32> |
| 46 | +! fir.store %1 to %0 : !fir.ref<i32> |
| 47 | +! omp.yield(%0 : !fir.ref<i32>) |
| 48 | +! }) : () -> () |
| 49 | +! "omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var2.privatizer"}> ({ |
| 50 | +! ^bb0(%arg0: !fir.ref<i32>): |
| 51 | +! %0 = fir.alloca i32 {bindc_name = "var2", pinned, uniq_name = "_QFdelayed_privatizationEvar2"} |
| 52 | +! %1 = fir.load %arg0 : !fir.ref<i32> |
| 53 | +! fir.store %1 to %0 : !fir.ref<i32> |
| 54 | +! omp.yield(%0 : !fir.ref<i32>) |
| 55 | +! }) : () -> () |
27 | 56 | !}
|
28 | 57 | !
|
29 |
| -!"omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var1.privatizer"}> ({ |
30 |
| -!^bb0(%arg0: !fir.ref<i32>): |
31 |
| -! %0 = fir.alloca i32 {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatizationEvar1"} |
32 |
| -! %1 = fir.load %arg0 : !fir.ref<i32> |
33 |
| -! fir.store %1 to %0 : !fir.ref<i32> |
34 |
| -! omp.yield(%0 : !fir.ref<i32>) |
35 |
| -!}) : () -> () |
| 58 | +! ----------------------------- |
| 59 | +! ### Conversion to LLVM + OMP: |
| 60 | +! ----------------------------- |
| 61 | +!module { |
| 62 | +! llvm.func @_QPdelayed_privatization() { |
| 63 | +! %0 = llvm.mlir.constant(1 : i64) : i64 |
| 64 | +! %1 = llvm.alloca %0 x i32 {bindc_name = "var1"} : (i64) -> !llvm.ptr |
| 65 | +! %2 = llvm.mlir.constant(1 : i64) : i64 |
| 66 | +! %3 = llvm.alloca %2 x i32 {bindc_name = "var2"} : (i64) -> !llvm.ptr |
| 67 | +! %4 = llvm.mlir.constant(111 : i32) : i32 |
| 68 | +! llvm.store %4, %1 : i32, !llvm.ptr |
| 69 | +! %5 = llvm.mlir.constant(222 : i32) : i32 |
| 70 | +! llvm.store %5, %3 : i32, !llvm.ptr |
| 71 | +! omp.parallel private(@var1.privatizer %1, @var2.privatizer %3 : !llvm.ptr, !llvm.ptr) { |
| 72 | +! %6 = llvm.load %1 : !llvm.ptr -> i32 |
| 73 | +! %7 = llvm.load %3 : !llvm.ptr -> i32 |
| 74 | +! %8 = llvm.add %6, %7 : i32 |
| 75 | +! %9 = llvm.mlir.constant(2 : i32) : i32 |
| 76 | +! %10 = llvm.add %8, %9 : i32 |
| 77 | +! llvm.store %10, %1 : i32, !llvm.ptr |
| 78 | +! omp.terminator |
| 79 | +! } |
| 80 | +! llvm.return |
| 81 | +! } |
| 82 | +! "omp.private"() <{function_type = (!llvm.ptr) -> !llvm.ptr, sym_name = "var1.privatizer"}> ({ |
| 83 | +! ^bb0(%arg0: !llvm.ptr): |
| 84 | +! %0 = llvm.mlir.constant(1 : i64) : i64 |
| 85 | +! %1 = llvm.alloca %0 x i32 {bindc_name = "var1", pinned} : (i64) -> !llvm.ptr |
| 86 | +! %2 = llvm.load %arg0 : !llvm.ptr -> i32 |
| 87 | +! llvm.store %2, %1 : i32, !llvm.ptr |
| 88 | +! omp.yield(%1 : !llvm.ptr) |
| 89 | +! }) : () -> () |
| 90 | +! "omp.private"() <{function_type = (!llvm.ptr) -> !llvm.ptr, sym_name = "var2.privatizer"}> ({ |
| 91 | +! ^bb0(%arg0: !llvm.ptr): |
| 92 | +! %0 = llvm.mlir.constant(1 : i64) : i64 |
| 93 | +! %1 = llvm.alloca %0 x i32 {bindc_name = "var2", pinned} : (i64) -> !llvm.ptr |
| 94 | +! %2 = llvm.load %arg0 : !llvm.ptr -> i32 |
| 95 | +! llvm.store %2, %1 : i32, !llvm.ptr |
| 96 | +! omp.yield(%1 : !llvm.ptr) |
| 97 | +! }) : () -> () |
| 98 | +!} |
36 | 99 | !
|
37 |
| -!"omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var2.privatizer"}> ({ |
38 |
| -!^bb0(%arg0: !fir.ref<i32>): |
39 |
| -! %0 = fir.alloca i32 {bindc_name = "var2", pinned, uniq_name = "_QFdelayed_privatizationEvar2"} |
40 |
| -! %1 = fir.load %arg0 : !fir.ref<i32> |
41 |
| -! fir.store %1 to %0 : !fir.ref<i32> |
42 |
| -! omp.yield(%0 : !fir.ref<i32>) |
43 |
| -!}) : () -> () |
| 100 | +! -------------------------- |
| 101 | +! ### Conversion to LLVM IR: |
| 102 | +! -------------------------- |
| 103 | +!%struct.ident_t = type { i32, i32, i32, i32, ptr } |
| 104 | + |
| 105 | +!@0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 |
| 106 | +!@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8 |
| 107 | + |
| 108 | +!define void @_QPdelayed_privatization() { |
| 109 | +! %structArg = alloca { ptr, ptr }, align 8 |
| 110 | +! %1 = alloca i32, i64 1, align 4 |
| 111 | +! %2 = alloca i32, i64 1, align 4 |
| 112 | +! store i32 111, ptr %1, align 4 |
| 113 | +! store i32 222, ptr %2, align 4 |
| 114 | +! br label %entry |
| 115 | + |
| 116 | +!entry: ; preds = %0 |
| 117 | +! %omp_global_thread_num = call i32 @__kmpc_global_thread_num(ptr @1) |
| 118 | +! br label %omp_parallel |
| 119 | + |
| 120 | +!omp_parallel: ; preds = %entry |
| 121 | +! %gep_ = getelementptr { ptr, ptr }, ptr %structArg, i32 0, i32 0 |
| 122 | +! store ptr %1, ptr %gep_, align 8 |
| 123 | +! %gep_2 = getelementptr { ptr, ptr }, ptr %structArg, i32 0, i32 1 |
| 124 | +! store ptr %2, ptr %gep_2, align 8 |
| 125 | +! call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @_QPdelayed_privatization..omp_par, ptr %structArg) |
| 126 | +! br label %omp.par.outlined.exit |
| 127 | + |
| 128 | +!omp.par.outlined.exit: ; preds = %omp_parallel |
| 129 | +! br label %omp.par.exit.split |
| 130 | + |
| 131 | +!omp.par.exit.split: ; preds = %omp.par.outlined.exit |
| 132 | +! ret void |
| 133 | +!} |
| 134 | + |
| 135 | +!; Function Attrs: nounwind |
| 136 | +!define internal void @_QPdelayed_privatization..omp_par(ptr noalias %tid.addr, ptr noalias %zero.addr, ptr %0) #0 { |
| 137 | +!omp.par.entry: |
| 138 | +! %gep_ = getelementptr { ptr, ptr }, ptr %0, i32 0, i32 0 |
| 139 | +! %loadgep_ = load ptr, ptr %gep_, align 8 |
| 140 | +! %gep_1 = getelementptr { ptr, ptr }, ptr %0, i32 0, i32 1 |
| 141 | +! %loadgep_2 = load ptr, ptr %gep_1, align 8 |
| 142 | +! %tid.addr.local = alloca i32, align 4 |
| 143 | +! %1 = load i32, ptr %tid.addr, align 4 |
| 144 | +! store i32 %1, ptr %tid.addr.local, align 4 |
| 145 | +! %tid = load i32, ptr %tid.addr.local, align 4 |
| 146 | +! %2 = alloca i32, i64 1, align 4 |
| 147 | +! %3 = load i32, ptr %loadgep_, align 4 |
| 148 | +! store i32 %3, ptr %2, align 4 |
| 149 | +! %4 = alloca i32, i64 1, align 4 |
| 150 | +! %5 = load i32, ptr %loadgep_2, align 4 |
| 151 | +! store i32 %5, ptr %4, align 4 |
| 152 | +! br label %omp.par.region |
| 153 | + |
| 154 | +!omp.par.region: ; preds = %omp.par.entry |
| 155 | +! br label %omp.par.region1 |
| 156 | + |
| 157 | +!omp.par.region1: ; preds = %omp.par.region |
| 158 | +! %6 = load i32, ptr %2, align 4 |
| 159 | +! %7 = load i32, ptr %4, align 4 |
| 160 | +! %8 = add i32 %6, %7 |
| 161 | +! %9 = add i32 %8, 2 |
| 162 | +! store i32 %9, ptr %2, align 4 |
| 163 | +! br label %omp.region.cont |
| 164 | + |
| 165 | +!omp.region.cont: ; preds = %omp.par.region1 |
| 166 | +! br label %omp.par.pre_finalize |
| 167 | + |
| 168 | +!omp.par.pre_finalize: ; preds = %omp.region.cont |
| 169 | +! br label %omp.par.outlined.exit.exitStub |
| 170 | + |
| 171 | +!omp.par.outlined.exit.exitStub: ; preds = %omp.par.pre_finalize |
| 172 | +! ret void |
| 173 | +!} |
| 174 | + |
| 175 | +!; Function Attrs: nounwind |
| 176 | +!declare i32 @__kmpc_global_thread_num(ptr) #0 |
| 177 | + |
| 178 | +!; Function Attrs: nounwind |
| 179 | +!declare !callback !2 void @__kmpc_fork_call(ptr, i32, ptr, ...) #0 |
0 commit comments