Skip to content

Commit 51c6a6a

Browse files
committed
[flang][flang-driver] atomic control support
1 parent 356dc62 commit 51c6a6a

File tree

11 files changed

+159
-15
lines changed

11 files changed

+159
-15
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,21 +2299,21 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
22992299

23002300
defm atomic_remote_memory : BoolFOption<"atomic-remote-memory",
23012301
LangOpts<"AtomicRemoteMemory">, DefaultFalse,
2302-
PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
2303-
NegFlag<SetFalse, [], [ClangOption], "Assume no">,
2304-
BothFlags<[], [ClangOption], " atomic operations on remote memory">>;
2302+
PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
2303+
NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
2304+
BothFlags<[], [ClangOption, FlangOption], " atomic operations on remote memory">>;
23052305

23062306
defm atomic_fine_grained_memory : BoolFOption<"atomic-fine-grained-memory",
23072307
LangOpts<"AtomicFineGrainedMemory">, DefaultFalse,
2308-
PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
2309-
NegFlag<SetFalse, [], [ClangOption], "Assume no">,
2310-
BothFlags<[], [ClangOption], " atomic operations on fine-grained memory">>;
2308+
PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
2309+
NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
2310+
BothFlags<[], [ClangOption, FlangOption], " atomic operations on fine-grained memory">>;
23112311

23122312
defm atomic_ignore_denormal_mode : BoolFOption<"atomic-ignore-denormal-mode",
23132313
LangOpts<"AtomicIgnoreDenormalMode">, DefaultFalse,
2314-
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Allow">,
2315-
NegFlag<SetFalse, [], [ClangOption], "Disallow">,
2316-
BothFlags<[], [ClangOption], " atomic operations to ignore denormal mode">>;
2314+
PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Allow">,
2315+
NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disallow">,
2316+
BothFlags<[], [ClangOption, FlangOption], " atomic operations to ignore denormal mode">>;
23172317

23182318
defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
23192319
def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
@@ -5270,9 +5270,9 @@ defm amdgpu_precise_memory_op
52705270
" precise memory mode (AMDGPU only)">;
52715271

52725272
def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">,
5273-
Visibility<[ClangOption, CC1Option]>, Alias<fatomic_ignore_denormal_mode>;
5273+
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>;
52745274
def mno_unsafe_fp_atomics : Flag<["-"], "mno-unsafe-fp-atomics">,
5275-
Visibility<[ClangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
5275+
Visibility<[ClangOption, FlangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
52765276

52775277
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>;
52785278
def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>;

flang/include/flang/Frontend/TargetOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ class TargetOptions {
5353

5454
/// Print verbose assembly
5555
bool asmVerbose = false;
56+
57+
/// Atomic Control Options for AMD GPU
58+
bool amdgpuIgnoreDenormalMode = false;
59+
bool amdgpuRemoteMemory = false;
60+
bool amdgpuFineGrainedMemory = false;
5661
};
5762

5863
} // end namespace Fortran::frontend

flang/include/flang/Optimizer/Dialect/Support/FIRContext.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,24 @@ void setTargetCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
5858
/// Get the target CPU string from the Module or return a null reference.
5959
llvm::StringRef getTargetCPU(mlir::ModuleOp mod);
6060

61+
// Setters and Getters for atomic control options
62+
void setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
63+
bool getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
64+
void setAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
65+
bool getAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
66+
void setAmdgpuRemoteMemory(mlir::ModuleOp mod);
67+
bool getAmdgpuRemoteMemory(mlir::ModuleOp mod);
68+
6169
/// Set the tune CPU for the module. `cpu` must not be deallocated while
6270
/// module `mod` is still live.
6371
void setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
6472

73+
// set Atomic control options for amd gpu.
74+
void setAmdgpuAtomicControlOptions(mlir::ModuleOp mod,
75+
bool amdgpuIgnoreDenormalMode,
76+
bool amdgpuNoFineGrainedMemory,
77+
bool amdgpuNoRemoteMemory);
78+
6579
/// Get the tune CPU string from the Module or return a null reference.
6680
llvm::StringRef getTuneCPU(mlir::ModuleOp mod);
6781

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,18 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
494494
args.getLastArg(clang::driver::options::OPT_triple))
495495
opts.triple = a->getValue();
496496

497+
if (llvm::Triple(opts.triple).isAMDGPU()) {
498+
opts.amdgpuIgnoreDenormalMode = args.hasFlag(
499+
clang::driver::options::OPT_fatomic_ignore_denormal_mode,
500+
clang::driver::options::OPT_fno_atomic_ignore_denormal_mode, false);
501+
opts.amdgpuFineGrainedMemory = args.hasFlag(
502+
clang::driver::options::OPT_fatomic_fine_grained_memory,
503+
clang::driver::options::OPT_fno_atomic_fine_grained_memory, false);
504+
opts.amdgpuRemoteMemory = args.hasFlag(
505+
clang::driver::options::OPT_fatomic_remote_memory,
506+
clang::driver::options::OPT_fno_atomic_remote_memory, false);
507+
}
508+
497509
if (const llvm::opt::Arg *a =
498510
args.getLastArg(clang::driver::options::OPT_target_cpu))
499511
opts.cpu = a->getValue();

flang/lib/Lower/Bridge.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6648,6 +6648,12 @@ Fortran::lower::LoweringBridge::LoweringBridge(
66486648
fir::setKindMapping(*module, kindMap);
66496649
fir::setTargetCPU(*module, targetMachine.getTargetCPU());
66506650
fir::setTuneCPU(*module, targetOpts.cpuToTuneFor);
6651+
if (targetOpts.amdgpuIgnoreDenormalMode)
6652+
fir::setAmdgpuIgnoreDenormalMode(*module);
6653+
if (targetOpts.amdgpuFineGrainedMemory)
6654+
fir::setAmdgpuFineGrainedMemory(*module);
6655+
if (targetOpts.amdgpuRemoteMemory)
6656+
fir::setAmdgpuRemoteMemory(*module);
66516657
fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
66526658
fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
66536659
fir::setIdent(*module, Fortran::common::getFlangFullVersion());

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2911,8 +2911,13 @@ static void genAtomicUpdateStatement(
29112911
if (rightHandClauseList)
29122912
genOmpAtomicHintAndMemoryOrderClauses(converter, *rightHandClauseList, hint,
29132913
memoryOrder);
2914+
auto module = firOpBuilder.getModule();
2915+
auto atomicControlAttr = mlir::omp::AtomicControlAttr::get(
2916+
firOpBuilder.getContext(), fir::getAmdgpuIgnoreDenormalMode(module),
2917+
fir::getAmdgpuFineGrainedMemory(module),
2918+
fir::getAmdgpuRemoteMemory(module));
29142919
atomicUpdateOp = firOpBuilder.create<mlir::omp::AtomicUpdateOp>(
2915-
currentLocation, lhsAddr, hint, memoryOrder);
2920+
currentLocation, lhsAddr, atomicControlAttr, hint, memoryOrder);
29162921

29172922
processOmpAtomicTODO(varType, loc);
29182923

flang/lib/Optimizer/Dialect/Support/FIRContext.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,46 @@ void fir::setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu) {
8888
mod->setAttr(tuneCpuName, mlir::StringAttr::get(ctx, cpu));
8989
}
9090

91+
static constexpr const char *amdgpuIgnoreDenormalModeName =
92+
"fir.amdgpu.ignore.denormal.mode";
93+
void fir::setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
94+
auto *ctx = mod.getContext();
95+
mod->setAttr(amdgpuIgnoreDenormalModeName, mlir::UnitAttr::get(ctx));
96+
}
97+
98+
bool fir::getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
99+
if (auto attr =
100+
mod->getAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName))
101+
return true;
102+
return false;
103+
}
104+
105+
static constexpr const char *amdgpuFineGrainedMemoryName =
106+
"fir.amdgpu.fine.grained.memory";
107+
void fir::setAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
108+
auto *ctx = mod.getContext();
109+
mod->setAttr(amdgpuFineGrainedMemoryName, mlir::UnitAttr::get(ctx));
110+
}
111+
112+
bool fir::getAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
113+
if (auto attr =
114+
mod->getAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName))
115+
return true;
116+
return false;
117+
}
118+
static constexpr const char *amdgpuRemoteMemoryName =
119+
"fir.amdgpu.remote.memory";
120+
void fir::setAmdgpuRemoteMemory(mlir::ModuleOp mod) {
121+
auto *ctx = mod.getContext();
122+
mod->setAttr(amdgpuRemoteMemoryName, mlir::UnitAttr::get(ctx));
123+
}
124+
125+
bool fir::getAmdgpuRemoteMemory(mlir::ModuleOp mod) {
126+
if (auto attr = mod->getAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName))
127+
return true;
128+
return false;
129+
}
130+
91131
llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
92132
if (auto attr = mod->getAttrOfType<mlir::StringAttr>(tuneCpuName))
93133
return attr.getValue();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics %s -o - | FileCheck -check-prefix=UNSAFE-FP-ATOMICS %s
2+
! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-ignore-denormal-mode %s -o - | FileCheck -check-prefix=IGNORE-DENORMAL %s
3+
! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-fine-grained-memory %s -o - | FileCheck -check-prefix=FINE-GRAINED-MEMORY %s
4+
! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-remote-memory %s -o - | FileCheck -check-prefix=REMOTE-MEMORY %s
5+
program test
6+
implicit none
7+
integer :: A, B, threads
8+
threads = 128
9+
A = 0
10+
B = 0
11+
!UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
12+
!UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
13+
!IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
14+
!IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
15+
!FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
16+
!FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
17+
!REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
18+
!REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
19+
!$omp target parallel num_threads(threads)
20+
!$omp atomic
21+
A = A + 1
22+
!$omp end target parallel
23+
!UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
24+
!UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
25+
!IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
26+
!IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
27+
!FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
28+
!FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
29+
!REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
30+
!REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
31+
!$omp target parallel num_threads(threads)
32+
!$omp atomic capture
33+
A = A + B
34+
B = A
35+
!$omp end atomic
36+
!$omp end target parallel
37+
end program test

mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
5454
let assemblyFormat = "`<` struct(params) `>`";
5555
}
5656

57+
//===----------------------------------------------------------------------===//
58+
// AtomicControlAttr
59+
//===----------------------------------------------------------------------===//
60+
61+
// Runtime library flags attribute that holds information for lowering to LLVM.
62+
def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
63+
let parameters =
64+
(ins DefaultValuedParameter<"bool", "false">:$amdgpu_ignore_denormal_mode,
65+
DefaultValuedParameter<"bool", "false">:$amdgpu_fine_grained_memory,
66+
DefaultValuedParameter<"bool", "false">:$amdgpu_remote_memory);
67+
68+
let assemblyFormat = "`<` struct(params) `>`";
69+
}
70+
5771
//===----------------------------------------------------------------------===//
5872
// TaskDependArrayAttr
5973
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,9 +1543,11 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [
15431543
operations.
15441544
}] # clausesDescription;
15451545

1546-
let arguments = !con((ins Arg<OpenMP_PointerLikeType,
1547-
"Address of variable to be updated",
1548-
[MemRead, MemWrite]>:$x), clausesArgs);
1546+
let arguments = !con(
1547+
(ins Arg<OpenMP_PointerLikeType,
1548+
"Address of variable to be updated", [MemRead, MemWrite]>:$x,
1549+
OptionalAttr<AtomicControlAttr>:$atomic_control),
1550+
clausesArgs);
15491551

15501552
// Override region definition.
15511553
let regions = (region SizedRegion<1>:$region);

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,15 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
15621562
omp.yield(%newval : i32)
15631563
}
15641564

1565+
// CHECK: omp.atomic.update %[[X]] : memref<i32> {
1566+
// CHECK-NEXT: (%[[XVAL:.*]]: i32):
1567+
// CHECK-NEXT: omp.yield(%{{.+}} : i32)
1568+
// CHECK-NEXT: } {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
1569+
omp.atomic.update %x : memref<i32> {
1570+
^bb0(%xval:i32):
1571+
omp.yield(%const:i32)
1572+
} {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
1573+
15651574
return
15661575
}
15671576

0 commit comments

Comments
 (0)