aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorSergio Afonso <safonsof@amd.com>2024-08-02 10:54:15 +0100
committerGitHub <noreply@github.com>2024-08-02 10:54:15 +0100
commit9dadb1f62bb8086a53ba39d188665c4fe3a9c6ec (patch)
tree190a5c143307c1d0acdf576473479f8349df68ad /flang/lib/Frontend/CompilerInvocation.cpp
parent6d2bbba187cd8fdc3e6e46cb753d4d9c6c276103 (diff)
downloadllvm-9dadb1f62bb8086a53ba39d188665c4fe3a9c6ec.zip
llvm-9dadb1f62bb8086a53ba39d188665c4fe3a9c6ec.tar.gz
llvm-9dadb1f62bb8086a53ba39d188665c4fe3a9c6ec.tar.bz2
[Flang][OpenMP] Add frontend support for -fopenmp-targets (#100155)
This patch adds support for the `-fopenmp-targets` option to the `bbc` and `flang -fc1` tools. It adds an `OMPTargetTriples` property to the `LangOptions` structure, which is filled with the triples represented by the compiler option. This is used to initialize the `omp.target_triples` module attribute for later use by lowering stages.
Diffstat (limited to 'flang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp206
1 files changed, 126 insertions, 80 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 7c7f003..1d73397 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -929,90 +929,11 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
Fortran::common::LanguageFeature::CUDA);
}
- // -fopenmp and -fopenacc
+ // -fopenacc
if (args.hasArg(clang::driver::options::OPT_fopenacc)) {
res.getFrontendOpts().features.Enable(
Fortran::common::LanguageFeature::OpenACC);
}
- if (args.hasArg(clang::driver::options::OPT_fopenmp)) {
- // By default OpenMP is set to 1.1 version
- res.getLangOpts().OpenMPVersion = 11;
- res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::OpenMP);
- if (int Version = getLastArgIntValue(
- args, clang::driver::options::OPT_fopenmp_version_EQ,
- res.getLangOpts().OpenMPVersion, diags)) {
- res.getLangOpts().OpenMPVersion = Version;
- }
- if (args.hasArg(clang::driver::options::OPT_fopenmp_force_usm)) {
- res.getLangOpts().OpenMPForceUSM = 1;
- }
- if (args.hasArg(clang::driver::options::OPT_fopenmp_is_target_device)) {
- res.getLangOpts().OpenMPIsTargetDevice = 1;
-
- // Get OpenMP host file path if any and report if a non existent file is
- // found
- if (auto *arg = args.getLastArg(
- clang::driver::options::OPT_fopenmp_host_ir_file_path)) {
- res.getLangOpts().OMPHostIRFile = arg->getValue();
- if (!llvm::sys::fs::exists(res.getLangOpts().OMPHostIRFile))
- diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found)
- << res.getLangOpts().OMPHostIRFile;
- }
-
- if (args.hasFlag(
- clang::driver::options::OPT_fopenmp_assume_teams_oversubscription,
- clang::driver::options::
- OPT_fno_openmp_assume_teams_oversubscription,
- /*Default=*/false))
- res.getLangOpts().OpenMPTeamSubscription = true;
-
- if (args.hasArg(
- clang::driver::options::OPT_fopenmp_assume_no_thread_state))
- res.getLangOpts().OpenMPNoThreadState = 1;
-
- if (args.hasArg(
- clang::driver::options::OPT_fopenmp_assume_no_nested_parallelism))
- res.getLangOpts().OpenMPNoNestedParallelism = 1;
-
- if (args.hasFlag(clang::driver::options::
- OPT_fopenmp_assume_threads_oversubscription,
- clang::driver::options::
- OPT_fno_openmp_assume_threads_oversubscription,
- /*Default=*/false))
- res.getLangOpts().OpenMPThreadSubscription = true;
-
- if ((args.hasArg(clang::driver::options::OPT_fopenmp_target_debug) ||
- args.hasArg(clang::driver::options::OPT_fopenmp_target_debug_EQ))) {
- res.getLangOpts().OpenMPTargetDebug = getLastArgIntValue(
- args, clang::driver::options::OPT_fopenmp_target_debug_EQ,
- res.getLangOpts().OpenMPTargetDebug, diags);
-
- if (!res.getLangOpts().OpenMPTargetDebug &&
- args.hasArg(clang::driver::options::OPT_fopenmp_target_debug))
- res.getLangOpts().OpenMPTargetDebug = 1;
- }
- if (args.hasArg(clang::driver::options::OPT_nogpulib))
- res.getLangOpts().NoGPULib = 1;
- }
-
- switch (llvm::Triple(res.getTargetOpts().triple).getArch()) {
- case llvm::Triple::nvptx:
- case llvm::Triple::nvptx64:
- case llvm::Triple::amdgcn:
- if (!res.getLangOpts().OpenMPIsTargetDevice) {
- const unsigned diagID = diags.getCustomDiagID(
- clang::DiagnosticsEngine::Error,
- "OpenMP AMDGPU/NVPTX is only prepared to deal with device code.");
- diags.Report(diagID);
- }
- res.getLangOpts().OpenMPIsGPU = 1;
- break;
- default:
- res.getLangOpts().OpenMPIsGPU = 0;
- break;
- }
- }
// -pedantic
if (args.hasArg(clang::driver::options::OPT_pedantic)) {
@@ -1042,6 +963,130 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
return diags.getNumErrors() == numErrorsBefore;
}
+/// Parses all OpenMP related arguments if the -fopenmp option is present,
+/// populating the \c res object accordingly. Returns false if new errors are
+/// generated.
+static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
+ clang::DiagnosticsEngine &diags) {
+ if (!args.hasArg(clang::driver::options::OPT_fopenmp))
+ return true;
+
+ unsigned numErrorsBefore = diags.getNumErrors();
+ llvm::Triple t(res.getTargetOpts().triple);
+
+ // By default OpenMP is set to 1.1 version
+ res.getLangOpts().OpenMPVersion = 11;
+ res.getFrontendOpts().features.Enable(
+ Fortran::common::LanguageFeature::OpenMP);
+ if (int Version = getLastArgIntValue(
+ args, clang::driver::options::OPT_fopenmp_version_EQ,
+ res.getLangOpts().OpenMPVersion, diags)) {
+ res.getLangOpts().OpenMPVersion = Version;
+ }
+ if (args.hasArg(clang::driver::options::OPT_fopenmp_force_usm)) {
+ res.getLangOpts().OpenMPForceUSM = 1;
+ }
+ if (args.hasArg(clang::driver::options::OPT_fopenmp_is_target_device)) {
+ res.getLangOpts().OpenMPIsTargetDevice = 1;
+
+ // Get OpenMP host file path if any and report if a non existent file is
+ // found
+ if (auto *arg = args.getLastArg(
+ clang::driver::options::OPT_fopenmp_host_ir_file_path)) {
+ res.getLangOpts().OMPHostIRFile = arg->getValue();
+ if (!llvm::sys::fs::exists(res.getLangOpts().OMPHostIRFile))
+ diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found)
+ << res.getLangOpts().OMPHostIRFile;
+ }
+
+ if (args.hasFlag(
+ clang::driver::options::OPT_fopenmp_assume_teams_oversubscription,
+ clang::driver::options::
+ OPT_fno_openmp_assume_teams_oversubscription,
+ /*Default=*/false))
+ res.getLangOpts().OpenMPTeamSubscription = true;
+
+ if (args.hasArg(clang::driver::options::OPT_fopenmp_assume_no_thread_state))
+ res.getLangOpts().OpenMPNoThreadState = 1;
+
+ if (args.hasArg(
+ clang::driver::options::OPT_fopenmp_assume_no_nested_parallelism))
+ res.getLangOpts().OpenMPNoNestedParallelism = 1;
+
+ if (args.hasFlag(
+ clang::driver::options::OPT_fopenmp_assume_threads_oversubscription,
+ clang::driver::options::
+ OPT_fno_openmp_assume_threads_oversubscription,
+ /*Default=*/false))
+ res.getLangOpts().OpenMPThreadSubscription = true;
+
+ if ((args.hasArg(clang::driver::options::OPT_fopenmp_target_debug) ||
+ args.hasArg(clang::driver::options::OPT_fopenmp_target_debug_EQ))) {
+ res.getLangOpts().OpenMPTargetDebug = getLastArgIntValue(
+ args, clang::driver::options::OPT_fopenmp_target_debug_EQ,
+ res.getLangOpts().OpenMPTargetDebug, diags);
+
+ if (!res.getLangOpts().OpenMPTargetDebug &&
+ args.hasArg(clang::driver::options::OPT_fopenmp_target_debug))
+ res.getLangOpts().OpenMPTargetDebug = 1;
+ }
+ if (args.hasArg(clang::driver::options::OPT_nogpulib))
+ res.getLangOpts().NoGPULib = 1;
+ }
+
+ switch (llvm::Triple(res.getTargetOpts().triple).getArch()) {
+ case llvm::Triple::nvptx:
+ case llvm::Triple::nvptx64:
+ case llvm::Triple::amdgcn:
+ if (!res.getLangOpts().OpenMPIsTargetDevice) {
+ const unsigned diagID = diags.getCustomDiagID(
+ clang::DiagnosticsEngine::Error,
+ "OpenMP AMDGPU/NVPTX is only prepared to deal with device code.");
+ diags.Report(diagID);
+ }
+ res.getLangOpts().OpenMPIsGPU = 1;
+ break;
+ default:
+ res.getLangOpts().OpenMPIsGPU = 0;
+ break;
+ }
+
+ // Get the OpenMP target triples if any.
+ if (auto *arg =
+ args.getLastArg(clang::driver::options::OPT_fopenmp_targets_EQ)) {
+ enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
+ auto getArchPtrSize = [](const llvm::Triple &triple) {
+ if (triple.isArch16Bit())
+ return Arch16Bit;
+ if (triple.isArch32Bit())
+ return Arch32Bit;
+ assert(triple.isArch64Bit() && "Expected 64-bit architecture");
+ return Arch64Bit;
+ };
+
+ for (unsigned i = 0; i < arg->getNumValues(); ++i) {
+ llvm::Triple tt(arg->getValue(i));
+
+ if (tt.getArch() == llvm::Triple::UnknownArch ||
+ !(tt.getArch() == llvm::Triple::aarch64 || tt.isPPC() ||
+ tt.getArch() == llvm::Triple::systemz ||
+ tt.getArch() == llvm::Triple::nvptx ||
+ tt.getArch() == llvm::Triple::nvptx64 ||
+ tt.getArch() == llvm::Triple::amdgcn ||
+ tt.getArch() == llvm::Triple::x86 ||
+ tt.getArch() == llvm::Triple::x86_64))
+ diags.Report(clang::diag::err_drv_invalid_omp_target)
+ << arg->getValue(i);
+ else if (getArchPtrSize(t) != getArchPtrSize(tt))
+ diags.Report(clang::diag::err_drv_incompatible_omp_arch)
+ << arg->getValue(i) << t.str();
+ else
+ res.getLangOpts().OMPTargetTriples.push_back(tt);
+ }
+ }
+ return diags.getNumErrors() == numErrorsBefore;
+}
+
/// Parses all floating point related arguments and populates the
/// CompilerInvocation accordingly.
/// Returns false if new errors are generated.
@@ -1277,6 +1322,7 @@ bool CompilerInvocation::createFromArgs(
success &= parseVectorLibArg(invoc.getCodeGenOpts(), args, diags);
success &= parseSemaArgs(invoc, args, diags);
success &= parseDialectArgs(invoc, args, diags);
+ success &= parseOpenMPArgs(invoc, args, diags);
success &= parseDiagArgs(invoc, args, diags);
// Collect LLVM (-mllvm) and MLIR (-mmlir) options.