Skip to content

Commit 3b5b55f

Browse files
authored
Merge pull request #48 from ergawy/do_concurrent_1
[flang][OpenMP] Add initial pass to map `do concurrent` to OMP
2 parents 14487b4 + 385768a commit 3b5b55f

File tree

14 files changed

+436
-3
lines changed

14 files changed

+436
-3
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6473,6 +6473,10 @@ defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays",
64736473
defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride",
64746474
PosFlag<SetTrue, [], [ClangOption], "Create unit-strided versions of loops">,
64756475
NegFlag<SetFalse, [], [ClangOption], "Do not create unit-strided loops (default)">>;
6476+
6477+
def do_concurrent_parallel_EQ : Joined<["-"], "fdo-concurrent-parallel=">,
6478+
HelpText<"Try to map `do concurrent` loops to OpenMP (on host or device)">,
6479+
Values<"none,host,device">;
64766480
} // let Visibility = [FC1Option, FlangOption]
64776481

64786482
def J : JoinedOrSeparate<["-"], "J">,

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ void Flang::addCodegenOptions(const ArgList &Args,
150150
options::OPT_flang_deprecated_no_hlfir,
151151
options::OPT_flang_experimental_polymorphism,
152152
options::OPT_fno_ppc_native_vec_elem_order,
153-
options::OPT_fppc_native_vec_elem_order});
153+
options::OPT_fppc_native_vec_elem_order,
154+
options::OPT_do_concurrent_parallel_EQ});
154155
}
155156

156157
void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {

flang/include/flang/Frontend/CodeGenOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,7 @@ ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codeg
4040
ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use
4141
ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::FramePointerKind::None) ///< Enable the usage of frame pointers
4242

43+
ENUM_CODEGENOPT(DoConcurrentMapping, DoConcurrentMappingKind, 2, DoConcurrentMappingKind::DCMK_None) ///< Map `do concurrent` to OpenMP
44+
4345
#undef CODEGENOPT
4446
#undef ENUM_CODEGENOPT

flang/include/flang/Frontend/CodeGenOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ class CodeGenOptions : public CodeGenOptionsBase {
129129
/// transformation.
130130
OptRemark OptimizationRemarkAnalysis;
131131

132+
/// Optionally map `do concurrent` loops to OpenMP. This is only valid of
133+
/// OpenMP is enabled.
134+
enum class DoConcurrentMappingKind {
135+
DCMK_None, // Do not lower `do concurrent` to OpenMP.
136+
DCMK_Host, // Lower to run in parallel on the CPU.
137+
DCMK_Device // Lower to run in parallel on the GPU.
138+
};
139+
132140
// Define accessors/mutators for code generation options of enumeration type.
133141
#define CODEGENOPT(Name, Bits, Default)
134142
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \

flang/include/flang/Optimizer/Transforms/Passes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ createFunctionAttrPass(FunctionAttrTypes &functionAttr, bool noInfsFPMath,
9696
bool noNaNsFPMath, bool approxFuncFPMath,
9797
bool noSignedZerosFPMath, bool unsafeFPMath);
9898

99+
std::unique_ptr<mlir::Pass> createDoConcurrentConversionPass();
100+
99101
// declarative passes
100102
#define GEN_PASS_REGISTRATION
101103
#include "flang/Optimizer/Transforms/Passes.h.inc"

flang/include/flang/Optimizer/Transforms/Passes.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,24 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> {
397397
let constructor = "::fir::createFunctionAttrPass()";
398398
}
399399

400+
def DoConcurrentConversionPass : Pass<"fopenmp-do-concurrent-conversion", "mlir::func::FuncOp"> {
401+
let summary = "Map `DO CONCURRENT` loops to OpenMP worksharing loops.";
402+
403+
let description = [{ This is an experimental pass to map `DO CONCURRENT` loops
404+
to their correspnding equivalent OpenMP worksharing constructs.
405+
406+
For now the following is supported:
407+
- Mapping simple loops to `parallel do`.
408+
409+
Still to TODO:
410+
- More extensive testing.
411+
- Mapping to `target teams distribute parallel do`.
412+
- Allowing the user to control mapping behavior: either to the host or
413+
target.
414+
}];
415+
416+
let constructor = "::fir::createDoConcurrentConversionPass()";
417+
let dependentDialects = ["mlir::omp::OpenMPDialect"];
418+
}
419+
400420
#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,32 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
154154
return true;
155155
}
156156

157+
static bool parseDoConcurrentMapping(Fortran::frontend::CodeGenOptions &opts,
158+
llvm::opt::ArgList &args,
159+
clang::DiagnosticsEngine &diags) {
160+
llvm::opt::Arg *arg =
161+
args.getLastArg(clang::driver::options::OPT_do_concurrent_parallel_EQ);
162+
if (!arg)
163+
return true;
164+
165+
using DoConcurrentMappingKind = Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
166+
std::optional<DoConcurrentMappingKind> val =
167+
llvm::StringSwitch<std::optional<DoConcurrentMappingKind>>(
168+
arg->getValue())
169+
.Case("none", DoConcurrentMappingKind::DCMK_None)
170+
.Case("host", DoConcurrentMappingKind::DCMK_Host)
171+
.Case("device", DoConcurrentMappingKind::DCMK_Device)
172+
.Default(std::nullopt);
173+
174+
if (!val.has_value()) {
175+
diags.Report(clang::diag::err_drv_invalid_value)
176+
<< arg->getAsString(args) << arg->getValue();
177+
return false;
178+
}
179+
opts.setDoConcurrentMapping(val.value());
180+
return true;
181+
}
182+
157183
static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts,
158184
llvm::opt::ArgList &args,
159185
clang::DiagnosticsEngine &diags) {
@@ -385,6 +411,8 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
385411
clang::driver::options::OPT_funderscoring, false)) {
386412
opts.Underscoring = 0;
387413
}
414+
415+
parseDoConcurrentMapping(opts, args, diags);
388416
}
389417

390418
/// Parses all target input arguments and populates the target

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,9 @@ bool CodeGenAction::beginSourceFileAction() {
320320
// Add OpenMP-related passes
321321
// WARNING: These passes must be run immediately after the lowering to ensure
322322
// that the FIR is correct with respect to OpenMP operations/attributes.
323-
if (ci.getInvocation().getFrontendOpts().features.IsEnabled(
324-
Fortran::common::LanguageFeature::OpenMP)) {
323+
bool isOpenMPEnabled = ci.getInvocation().getFrontendOpts().features.IsEnabled(
324+
Fortran::common::LanguageFeature::OpenMP);
325+
if (isOpenMPEnabled) {
325326
bool isDevice = false;
326327
if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
327328
mlirModule->getOperation()))
@@ -332,6 +333,30 @@ bool CodeGenAction::beginSourceFileAction() {
332333
fir::createOpenMPFIRPassPipeline(pm, isDevice);
333334
}
334335

336+
using DoConcurrentMappingKind =
337+
Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
338+
DoConcurrentMappingKind selectedKind = ci.getInvocation().getCodeGenOpts().getDoConcurrentMapping();
339+
if (selectedKind != DoConcurrentMappingKind::DCMK_None) {
340+
if (!isOpenMPEnabled) {
341+
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
342+
clang::DiagnosticsEngine::Warning,
343+
"lowering `do concurrent` loops to OpenMP is only supported if "
344+
"OpenMP is enabled");
345+
ci.getDiagnostics().Report(diagID);
346+
} else {
347+
bool mapToDevice = selectedKind == DoConcurrentMappingKind::DCMK_Device;
348+
349+
if (mapToDevice) {
350+
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
351+
clang::DiagnosticsEngine::Warning,
352+
"TODO: lowering `do concurrent` loops to OpenMP device is not "
353+
"supported yet");
354+
ci.getDiagnostics().Report(diagID);
355+
} else
356+
pm.addPass(fir::createDoConcurrentConversionPass());
357+
}
358+
}
359+
335360
pm.enableVerifier(/*verifyPasses=*/true);
336361
pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
337362

flang/lib/Optimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_flang_library(FIRTransforms
2222
OMPMarkDeclareTarget.cpp
2323
VScaleAttr.cpp
2424
FunctionAttr.cpp
25+
DoConcurrentConversion.cpp
2526

2627
DEPENDS
2728
FIRDialect

0 commit comments

Comments
 (0)