summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Action.cpp4
-rw-r--r--clang/lib/Driver/Driver.cpp79
-rw-r--r--clang/lib/Driver/Tools.cpp85
3 files changed, 101 insertions, 67 deletions
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index d30f2cf6569..a351429ad7b 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -87,6 +87,8 @@ std::string Action::getOffloadingKindPrefix() const {
break;
case OFK_Cuda:
return "device-cuda";
+ case OFK_OpenMP:
+ return "device-openmp";
// TODO: Add other programming models here.
}
@@ -97,6 +99,8 @@ std::string Action::getOffloadingKindPrefix() const {
std::string Res("host");
if (ActiveOffloadKindMask & OFK_Cuda)
Res += "-cuda";
+ if (ActiveOffloadKindMask & OFK_OpenMP)
+ Res += "-openmp";
// TODO: Add other programming models here.
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 956cceadae1..bdf3e0ebe85 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -434,6 +434,32 @@ void Driver::setLTOMode(const llvm::opt::ArgList &Args) {
}
}
+/// Compute the desired OpenMP runtime from the flags provided.
+Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
+ StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
+
+ const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
+ if (A)
+ RuntimeName = A->getValue();
+
+ auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
+ .Case("libomp", OMPRT_OMP)
+ .Case("libgomp", OMPRT_GOMP)
+ .Case("libiomp5", OMPRT_IOMP5)
+ .Default(OMPRT_Unknown);
+
+ if (RT == OMPRT_Unknown) {
+ if (A)
+ Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << A->getValue();
+ else
+ // FIXME: We could use a nicer diagnostic here.
+ Diag(diag::err_drv_unsupported_opt) << "-fopenmp";
+ }
+
+ return RT;
+}
+
void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
InputList &Inputs) {
@@ -455,6 +481,59 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
}
//
+ // OpenMP
+ //
+ // We need to generate an OpenMP toolchain if the user specified targets with
+ // the -fopenmp-targets option.
+ if (Arg *OpenMPTargets =
+ C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) {
+ if (OpenMPTargets->getNumValues()) {
+ // We expect that -fopenmp-targets is always used in conjunction with the
+ // option -fopenmp specifying a valid runtime with offloading support,
+ // i.e. libomp or libiomp.
+ bool HasValidOpenMPRuntime = C.getInputArgs().hasFlag(
+ options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+ options::OPT_fno_openmp, false);
+ if (HasValidOpenMPRuntime) {
+ OpenMPRuntimeKind OpenMPKind = getOpenMPRuntime(C.getInputArgs());
+ HasValidOpenMPRuntime =
+ OpenMPKind == OMPRT_OMP || OpenMPKind == OMPRT_IOMP5;
+ }
+
+ if (HasValidOpenMPRuntime) {
+ llvm::StringMap<const char *> FoundNormalizedTriples;
+ for (const char *Val : OpenMPTargets->getValues()) {
+ llvm::Triple TT(Val);
+ std::string NormalizedName = TT.normalize();
+
+ // Make sure we don't have a duplicate triple.
+ auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
+ if (Duplicate != FoundNormalizedTriples.end()) {
+ Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
+ << Val << Duplicate->second;
+ continue;
+ }
+
+ // Store the current triple so that we can check for duplicates in the
+ // following iterations.
+ FoundNormalizedTriples[NormalizedName] = Val;
+
+ // If the specified target is invalid, emit a diagnostic.
+ if (TT.getArch() == llvm::Triple::UnknownArch)
+ Diag(clang::diag::err_drv_invalid_omp_target) << Val;
+ else {
+ const ToolChain &TC = getToolChain(C.getInputArgs(), TT);
+ C.addOffloadDeviceToolChain(&TC, Action::OFK_OpenMP);
+ }
+ }
+ } else
+ Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
+ } else
+ Diag(clang::diag::warn_drv_empty_joined_argument)
+ << OpenMPTargets->getAsString(C.getInputArgs());
+ }
+
+ //
// TODO: Add support for other offloading programming models here.
//
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 36b4c950ae4..848ea5bf1e8 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3009,72 +3009,23 @@ static void addClangRT(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
}
-namespace {
-enum OpenMPRuntimeKind {
- /// An unknown OpenMP runtime. We can't generate effective OpenMP code
- /// without knowing what runtime to target.
- OMPRT_Unknown,
-
- /// The LLVM OpenMP runtime. When completed and integrated, this will become
- /// the default for Clang.
- OMPRT_OMP,
-
- /// The GNU OpenMP runtime. Clang doesn't support generating OpenMP code for
- /// this runtime but can swallow the pragmas, and find and link against the
- /// runtime library itself.
- OMPRT_GOMP,
-
- /// The legacy name for the LLVM OpenMP runtime from when it was the Intel
- /// OpenMP runtime. We support this mode for users with existing dependencies
- /// on this runtime library name.
- OMPRT_IOMP5
-};
-}
-
-/// Compute the desired OpenMP runtime from the flag provided.
-static OpenMPRuntimeKind getOpenMPRuntime(const ToolChain &TC,
- const ArgList &Args) {
- StringRef RuntimeName(CLANG_DEFAULT_OPENMP_RUNTIME);
-
- const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ);
- if (A)
- RuntimeName = A->getValue();
-
- auto RT = llvm::StringSwitch<OpenMPRuntimeKind>(RuntimeName)
- .Case("libomp", OMPRT_OMP)
- .Case("libgomp", OMPRT_GOMP)
- .Case("libiomp5", OMPRT_IOMP5)
- .Default(OMPRT_Unknown);
-
- if (RT == OMPRT_Unknown) {
- if (A)
- TC.getDriver().Diag(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << A->getValue();
- else
- // FIXME: We could use a nicer diagnostic here.
- TC.getDriver().Diag(diag::err_drv_unsupported_opt) << "-fopenmp";
- }
-
- return RT;
-}
-
static void addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
const ArgList &Args) {
if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false))
return;
- switch (getOpenMPRuntime(TC, Args)) {
- case OMPRT_OMP:
+ switch (TC.getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
CmdArgs.push_back("-lomp");
break;
- case OMPRT_GOMP:
+ case Driver::OMPRT_GOMP:
CmdArgs.push_back("-lgomp");
break;
- case OMPRT_IOMP5:
+ case Driver::OMPRT_IOMP5:
CmdArgs.push_back("-liomp5");
break;
- case OMPRT_Unknown:
+ case Driver::OMPRT_Unknown:
// Already diagnosed.
break;
}
@@ -5188,9 +5139,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false) &&
JA.isDeviceOffloading(Action::OFK_None)) {
- switch (getOpenMPRuntime(getToolChain(), Args)) {
- case OMPRT_OMP:
- case OMPRT_IOMP5:
+ switch (getToolChain().getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
+ case Driver::OMPRT_IOMP5:
// Clang can generate useful OpenMP code for these two runtime libraries.
CmdArgs.push_back("-fopenmp");
@@ -9854,21 +9805,21 @@ void gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
WantPthread = true;
// Also link the particular OpenMP runtimes.
- switch (getOpenMPRuntime(ToolChain, Args)) {
- case OMPRT_OMP:
+ switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
CmdArgs.push_back("-lomp");
break;
- case OMPRT_GOMP:
+ case Driver::OMPRT_GOMP:
CmdArgs.push_back("-lgomp");
// FIXME: Exclude this for platforms with libgomp that don't require
// librt. Most modern Linux platforms require it, but some may not.
CmdArgs.push_back("-lrt");
break;
- case OMPRT_IOMP5:
+ case Driver::OMPRT_IOMP5:
CmdArgs.push_back("-liomp5");
break;
- case OMPRT_Unknown:
+ case Driver::OMPRT_Unknown:
// Already diagnosed.
break;
}
@@ -10546,16 +10497,16 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-nodefaultlib:vcompd.lib");
CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
TC.getDriver().Dir + "/../lib"));
- switch (getOpenMPRuntime(getToolChain(), Args)) {
- case OMPRT_OMP:
+ switch (TC.getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
CmdArgs.push_back("-defaultlib:libomp.lib");
break;
- case OMPRT_IOMP5:
+ case Driver::OMPRT_IOMP5:
CmdArgs.push_back("-defaultlib:libiomp5md.lib");
break;
- case OMPRT_GOMP:
+ case Driver::OMPRT_GOMP:
break;
- case OMPRT_Unknown:
+ case Driver::OMPRT_Unknown:
// Already diagnosed.
break;
}
OpenPOWER on IntegriCloud