Skip to content

Commit 717b57a

Browse files
committed
Experiment with supporting delayed privatization for hlfir simple values
1 parent 7db8eb6 commit 717b57a

File tree

5 files changed

+93
-3
lines changed

5 files changed

+93
-3
lines changed

flang/include/flang/Lower/SymbolMap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ class SymMap {
312312
lookupVariableDefinition(semantics::SymbolRef sym) {
313313
if (auto symBox = lookupSymbol(sym))
314314
return symBox.getIfFortranVariableOpInterface();
315+
315316
return std::nullopt;
316317
}
317318

flang/lib/Lower/Bridge.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
10521052
if (sym.detailsIf<Fortran::semantics::CommonBlockDetails>())
10531053
return symMap->lookupSymbol(sym);
10541054

1055-
return {};
1055+
// With delayed privatization, Fortran symbols might now be mapped to
1056+
// simple `mlir::Value`s (arguments to the `omp.private` ops in this
1057+
// case). Therefore, it is possible that none of the above cases applies.
1058+
// return {};
10561059
}
10571060
if (Fortran::lower::SymbolBox v = symMap->lookupSymbol(sym))
10581061
return v;

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3505,6 +3505,18 @@ struct ZeroOpConversion : public FIROpConversion<fir::ZeroOp> {
35053505
}
35063506
};
35073507

3508+
class DeclareOpConversion : public FIROpConversion<fir::DeclareOp> {
3509+
public:
3510+
using FIROpConversion::FIROpConversion;
3511+
3512+
mlir::LogicalResult
3513+
matchAndRewrite(fir::DeclareOp declareOp, OpAdaptor,
3514+
mlir::ConversionPatternRewriter &rewriter) const override {
3515+
rewriter.replaceOp(declareOp, declareOp.getMemref());
3516+
return mlir::success();
3517+
}
3518+
};
3519+
35083520
/// `fir.unreachable` --> `llvm.unreachable`
35093521
struct UnreachableOpConversion : public FIROpConversion<fir::UnreachableOp> {
35103522
using FIROpConversion::FIROpConversion;
@@ -3856,6 +3868,7 @@ class RenameMSVCLibmFuncs
38563868
return mlir::success();
38573869
}
38583870
};
3871+
38593872
} // namespace
38603873

38613874
namespace {
@@ -3949,7 +3962,7 @@ class FIRToLLVMLowering
39493962
UnboxCharOpConversion, UnboxProcOpConversion, UndefOpConversion,
39503963
UnreachableOpConversion, UnrealizedConversionCastOpConversion,
39513964
XArrayCoorOpConversion, XEmboxOpConversion, XReboxOpConversion,
3952-
ZeroOpConversion>(typeConverter, options);
3965+
ZeroOpConversion, DeclareOpConversion>(typeConverter, options);
39533966
mlir::populateFuncToLLVMConversionPatterns(typeConverter, pattern);
39543967
mlir::populateOpenMPToLLVMConversionPatterns(typeConverter, pattern);
39553968
mlir::arith::populateArithToLLVMConversionPatterns(typeConverter, pattern);
@@ -4002,7 +4015,8 @@ class FIRToLLVMLowering
40024015
signalPassFailure();
40034016
}
40044017

4005-
// Run pass to add comdats to functions that have weak linkage on relevant platforms
4018+
// Run pass to add comdats to functions that have weak linkage on relevant
4019+
// platforms
40064020
if (fir::getTargetTriple(mod).supportsCOMDAT()) {
40074021
mlir::OpPassManager comdatPM("builtin.module");
40084022
comdatPM.addPass(mlir::LLVM::createLLVMAddComdats());

flang/test/Lower/OpenMP/FIR/delayed_privatization.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
! RUN: bbc -fopenmp -emit-fir --openmp-enable-delayed-privatization -hlfir=false %s -o -
44

55
subroutine delayed_privatization()
6+
implicit none
67
integer :: var1
78
integer :: var2
89

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
! TODO Convert this file into a bunch of lit tests for each conversion step.
2+
3+
! RUN: bbc -fopenmp -emit-hlfir --openmp-enable-delayed-privatization %s -o -
4+
5+
subroutine delayed_privatization()
6+
implicit none
7+
integer :: var1
8+
integer :: var2
9+
10+
var1 = 111
11+
var2 = 222
12+
13+
!$OMP PARALLEL FIRSTPRIVATE(var1, var2)
14+
var1 = var1 + var2 + 2
15+
!$OMP END PARALLEL
16+
17+
end subroutine
18+
19+
20+
! -----------------------------------------
21+
! ## This is what flang emits with the PoC:
22+
! -----------------------------------------
23+
!
24+
! ----------------------------
25+
! ### Conversion to HLFIR + OMP:
26+
! ----------------------------
27+
!module {
28+
! func.func @_QPdelayed_privatization() {
29+
! %0 = fir.alloca i32 {bindc_name = "var1", uniq_name = "_QFdelayed_privatizationEvar1"}
30+
! %1:2 = hlfir.declare %0 {uniq_name = "_QFdelayed_privatizationEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
31+
! %2 = fir.alloca i32 {bindc_name = "var2", uniq_name = "_QFdelayed_privatizationEvar2"}
32+
! %3:2 = hlfir.declare %2 {uniq_name = "_QFdelayed_privatizationEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
33+
! %c111_i32 = arith.constant 111 : i32
34+
! hlfir.assign %c111_i32 to %1#0 : i32, !fir.ref<i32>
35+
! %c222_i32 = arith.constant 222 : i32
36+
! hlfir.assign %c222_i32 to %3#0 : i32, !fir.ref<i32>
37+
! omp.parallel private(@var1.privatizer_0 %1#0, @var2.privatizer_0 %3#0 : !fir.ref<i32>, !fir.ref<i32>) {
38+
! ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>):
39+
! %4:2 = hlfir.declare %arg0 {uniq_name = "_QFdelayed_privatizationEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
40+
! %5:2 = hlfir.declare %arg1 {uniq_name = "_QFdelayed_privatizationEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
41+
! %6 = fir.load %4#0 : !fir.ref<i32>
42+
! %7 = fir.load %5#0 : !fir.ref<i32>
43+
! %8 = arith.addi %6, %7 : i32
44+
! %c2_i32 = arith.constant 2 : i32
45+
! %9 = arith.addi %8, %c2_i32 : i32
46+
! hlfir.assign %9 to %4#0 : i32, !fir.ref<i32>
47+
! omp.terminator
48+
! }
49+
! return
50+
! }
51+
! "omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var1.privatizer_0"}> ({
52+
! ^bb0(%arg0: !fir.ref<i32>):
53+
! %0 = fir.alloca i32 {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatizationEvar1"}
54+
! %1:2 = hlfir.declare %0 {uniq_name = "_QFdelayed_privatizationEvar1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
55+
! %2 = fir.load %arg0 : !fir.ref<i32>
56+
! hlfir.assign %2 to %1#0 temporary_lhs : i32, !fir.ref<i32>
57+
! omp.yield(%1#0 : !fir.ref<i32>)
58+
! }) : () -> ()
59+
! "omp.private"() <{function_type = (!fir.ref<i32>) -> !fir.ref<i32>, sym_name = "var2.privatizer_0"}> ({
60+
! ^bb0(%arg0: !fir.ref<i32>):
61+
! %0 = fir.alloca i32 {bindc_name = "var2", pinned, uniq_name = "_QFdelayed_privatizationEvar2"}
62+
! %1:2 = hlfir.declare %0 {uniq_name = "_QFdelayed_privatizationEvar2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
63+
! %2 = fir.load %arg0 : !fir.ref<i32>
64+
! hlfir.assign %2 to %1#0 temporary_lhs : i32, !fir.ref<i32>
65+
! omp.yield(%1#0 : !fir.ref<i32>)
66+
! }) : () -> ()
67+
!}
68+
!
69+
!
70+
! ### After lowring `hlfir` to `fir`, conversion to LLVM + OMP -> LLVM IR produces the exact same result as for
71+
! `delayed_privatization.f90`.

0 commit comments

Comments
 (0)