From a803bc55c7934ecde663f5de586be51cd6866e06 Mon Sep 17 00:00:00 2001 From: grypp Date: Fri, 12 Oct 2018 01:53:09 -0700 Subject: [PATCH 1/2] OpenMP NVIDIA offload toolchain integration to Flang. The patch has several purposes. First, it enables OpenMP Offload Toolchain for Flang when "fopenmp-target = " is used. Then, the necessary parameters to create a device code are passed to flang1 and flang2. It also introduces Fortran extensions to the clang-offload-bundler tool because it is being used during unloading. --- lib/Driver/ToolChains/Cuda.cpp | 39 ++++++++++++ lib/Driver/ToolChains/Cuda.h | 3 + lib/Driver/ToolChains/Flang.cpp | 62 ++++++++++++++++++- .../ClangOffloadBundler.cpp | 2 + 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp index 7fb4ae4ea9cf..8d5867d3c594 100644 --- a/lib/Driver/ToolChains/Cuda.cpp +++ b/lib/Driver/ToolChains/Cuda.cpp @@ -830,3 +830,42 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, const ArgList &Args) const { return HostTC.computeMSVCVersion(D, Args); } + +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ":"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const { + path_list IncludePathList; + const Driver &D = getDriver(); + + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + { + SmallString<128> P(D.InstalledDir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.str()); + } + + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h index 01580cb66920..084355a6ee04 100644 --- a/lib/Driver/ToolChains/Cuda.h +++ b/lib/Driver/ToolChains/Cuda.h @@ -186,6 +186,9 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { const ToolChain &HostTC; CudaInstallationDetector CudaInstallation; + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; protected: Tool *buildAssembler() const override; // ptxas Tool *buildLinker() const override; // fatbinary (ok, not really a linker) diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp index c38d4f8a5d12..1aec24c9bde8 100644 --- a/lib/Driver/ToolChains/Flang.cpp +++ b/lib/Driver/ToolChains/Flang.cpp @@ -45,6 +45,7 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList UpperCmdArgs; ArgStringList LowerCmdArgs; SmallString<256> Stem; + SmallString<256> Path; std::string OutFile; bool NeedIEEE = false; bool NeedFastMath = false; @@ -53,6 +54,8 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, // Check number of inputs for sanity. We need at least one input. assert(Inputs.size() >= 1 && "Must have at least one input."); + bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); + /***** Process file arguments to both parts *****/ const InputInfo &Input = Inputs[0]; types::ID InputType = Input.getType(); @@ -792,6 +795,22 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, UpperCmdArgs.push_back("-output"); UpperCmdArgs.push_back(ILMFile); + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + SmallString<128> TargetInfo; + Path = llvm::sys::path::parent_path(Output.getFilename()); + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + } + UpperCmdArgs.push_back("-fopenmp-targets"); + UpperCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + } + C.addCommand(llvm::make_unique(JA, *this, UpperExec, UpperCmdArgs, Inputs)); // For -fsyntax-only or -E that is it @@ -899,7 +918,48 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-stbfile"); LowerCmdArgs.push_back(STBFile); - LowerCmdArgs.push_back("-asm"); LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + /* OpenMP GPU Offload */ + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + //if (isa(JA) && JA.isHostOffloading(Action::OFK_OpenMP)) { + SmallString<128> TargetInfo;//("-fopenmp-targets "); + SmallString<256> TargetInfoAsm;//("-fopenmp-targets-asm "); + Path = llvm::sys::path::parent_path(Output.getFilename()); + + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + // We need to get the string from the triple because it may be not exactly + // the same as the one we get directly from the arguments. + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + // We also need to give a output file + TargetInfoAsm += Path; + TargetInfoAsm += "/"; + TargetInfoAsm += Stem; + TargetInfoAsm += "-"; + TargetInfoAsm += T.getTriple(); + TargetInfoAsm += ".ll"; + } + LowerCmdArgs.push_back("-fopenmp-targets"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + if(IsOpenMPDevice) { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + } else { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } + } else { + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } C.addCommand(llvm::make_unique(JA, *this, LowerExec, LowerCmdArgs, Inputs)); } diff --git a/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/tools/clang-offload-bundler/ClangOffloadBundler.cpp index 29cd9848d111..b5fee9bf8943 100644 --- a/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -742,6 +742,8 @@ static FileHandler *CreateFileHandler(MemoryBuffer &FirstInput) { return new TextFileHandler(/*Comment=*/"//"); if (FilesType == "ll") return new TextFileHandler(/*Comment=*/";"); + if (FilesType == "f95") + return new TextFileHandler(/*Comment=*/"!"); if (FilesType == "bc") return new BinaryFileHandler(); if (FilesType == "s") From 6caf0afa9e8c71067145cfb61a92974ca0431f8b Mon Sep 17 00:00:00 2001 From: grypp Date: Mon, 15 Oct 2018 14:27:48 +0200 Subject: [PATCH 2/2] Fixed comments --- lib/Driver/ToolChains/Cuda.cpp | 12 +++--------- lib/Driver/ToolChains/Flang.cpp | 12 +++++++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp index 8d5867d3c594..b05943dc9a81 100644 --- a/lib/Driver/ToolChains/Cuda.cpp +++ b/lib/Driver/ToolChains/Cuda.cpp @@ -856,16 +856,10 @@ void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverAr llvm::opt::ArgStringList &Flang1Args) const { path_list IncludePathList; const Driver &D = getDriver(); - - if (DriverArgs.hasArg(options::OPT_nostdinc)) return; - - { - SmallString<128> P(D.InstalledDir); - llvm::sys::path::append(P, "../include"); - IncludePathList.push_back(P.str()); - } - + SmallString<128> P(D.InstalledDir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.str()); AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); } diff --git a/lib/Driver/ToolChains/Flang.cpp b/lib/Driver/ToolChains/Flang.cpp index 1aec24c9bde8..67354afd48cc 100644 --- a/lib/Driver/ToolChains/Flang.cpp +++ b/lib/Driver/ToolChains/Flang.cpp @@ -45,7 +45,6 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList UpperCmdArgs; ArgStringList LowerCmdArgs; SmallString<256> Stem; - SmallString<256> Path; std::string OutFile; bool NeedIEEE = false; bool NeedFastMath = false; @@ -54,8 +53,6 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, // Check number of inputs for sanity. We need at least one input. assert(Inputs.size() >= 1 && "Must have at least one input."); - bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); - /***** Process file arguments to both parts *****/ const InputInfo &Input = Inputs[0]; types::ID InputType = Input.getType(); @@ -795,6 +792,7 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, UpperCmdArgs.push_back("-output"); UpperCmdArgs.push_back(ILMFile); + SmallString<256> Path; if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { SmallString<128> TargetInfo; Path = llvm::sys::path::parent_path(Output.getFilename()); @@ -918,12 +916,13 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-stbfile"); LowerCmdArgs.push_back(STBFile); + Path = llvm::sys::path::parent_path(Output.getFilename()); + bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); + /* OpenMP GPU Offload */ if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { - //if (isa(JA) && JA.isHostOffloading(Action::OFK_OpenMP)) { SmallString<128> TargetInfo;//("-fopenmp-targets "); SmallString<256> TargetInfoAsm;//("-fopenmp-targets-asm "); - Path = llvm::sys::path::parent_path(Output.getFilename()); Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); assert(Tgts && Tgts->getNumValues() && @@ -943,6 +942,9 @@ void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA, TargetInfoAsm += T.getTriple(); TargetInfoAsm += ".ll"; } + // The driver is aware that flang2 can generate multiple files at the same time. + // We mimic it here by exchanging the output files. + // The driver always uses the output file of -asm. LowerCmdArgs.push_back("-fopenmp-targets"); LowerCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); if(IsOpenMPDevice) {