Author: sfantao Date: Thu Oct 27 12:39:44 2016 New Revision: 285320 URL: http://llvm.org/viewvc/llvm-project?rev=285320&view=rev Log: [Driver][OpenMP] Add logic for offloading-specific argument translation.
Summary: This patch includes support for argument translation that is specific of a given offloading kind. Additionally, it implements the translation for OpenMP device kinds in the gcc tool chain. With this patch, it is possible to compile a functional OpenMP application with offloading capabilities with no separate compilation. Reviewers: echristo, tra, jlebar, rsmith, ABataev, hfinkel Subscribers: whchung, mehdi_amini, cfe-commits, Hahnfeld, andreybokhanko, arpith-jacob, carlo.bertolli, caomhin Differential Revision: https://reviews.llvm.org/D21848 Modified: cfe/trunk/include/clang/Driver/Compilation.h cfe/trunk/include/clang/Driver/ToolChain.h cfe/trunk/lib/Driver/Compilation.cpp cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/lib/Driver/MSVCToolChain.cpp cfe/trunk/lib/Driver/ToolChains.cpp cfe/trunk/lib/Driver/ToolChains.h cfe/trunk/test/Driver/openmp-offload.c Modified: cfe/trunk/include/clang/Driver/Compilation.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Compilation.h?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Compilation.h (original) +++ cfe/trunk/include/clang/Driver/Compilation.h Thu Oct 27 12:39:44 2016 @@ -67,11 +67,27 @@ class Compilation { /// The root list of jobs. JobList Jobs; - /// Cache of translated arguments for a particular tool chain and bound - /// architecture. - llvm::DenseMap<std::pair<const ToolChain *, StringRef>, - llvm::opt::DerivedArgList *> - TCArgs; + /// Cache of translated arguments for a particular tool chain, bound + /// architecture, and device offload kind. + struct TCArgsKey final { + const ToolChain *TC = nullptr; + StringRef BoundArch; + Action::OffloadKind DeviceOffloadKind = Action::OFK_None; + bool operator<(const TCArgsKey &K) const { + if (TC < K.TC) + return true; + else if (TC == K.TC && BoundArch < K.BoundArch) + return true; + else if (TC == K.TC && BoundArch == K.BoundArch && + DeviceOffloadKind < K.DeviceOffloadKind) + return true; + return false; + } + TCArgsKey(const ToolChain *TC, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) + : TC(TC), BoundArch(BoundArch), DeviceOffloadKind(DeviceOffloadKind) {} + }; + std::map<TCArgsKey, llvm::opt::DerivedArgList *> TCArgs; /// Temporary files which should be removed on exit. llvm::opt::ArgStringList TempFiles; @@ -182,10 +198,15 @@ public: /// getArgsForToolChain - Return the derived argument list for the /// tool chain \p TC (or the default tool chain, if TC is not specified). + /// If a device offloading kind is specified, a translation specific for that + /// kind is performed, if any. /// /// \param BoundArch - The bound architecture name, or 0. - const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC, - StringRef BoundArch); + /// \param DeviceOffloadKind - The offload device kind that should be used in + /// the translation, if any. + const llvm::opt::DerivedArgList & + getArgsForToolChain(const ToolChain *TC, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind); /// addTempFile - Add a file to remove on exit, and returns its /// argument. Modified: cfe/trunk/include/clang/Driver/ToolChain.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/ToolChain.h (original) +++ cfe/trunk/include/clang/Driver/ToolChain.h Thu Oct 27 12:39:44 2016 @@ -190,12 +190,15 @@ public: /// TranslateArgs - Create a new derived argument list for any argument /// translations this ToolChain may wish to perform, or 0 if no tool chain - /// specific translations are needed. + /// specific translations are needed. If \p DeviceOffloadKind is specified + /// the translation specific for that offload kind is performed. /// /// \param BoundArch - The bound architecture name, or 0. + /// \param DeviceOffloadKind - The device offload kind used for the + /// translation. virtual llvm::opt::DerivedArgList * - TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const { + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const { return nullptr; } Modified: cfe/trunk/lib/Driver/Compilation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Compilation.cpp?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Compilation.cpp (original) +++ cfe/trunk/lib/Driver/Compilation.cpp Thu Oct 27 12:39:44 2016 @@ -50,14 +50,15 @@ Compilation::~Compilation() { } } -const DerivedArgList &Compilation::getArgsForToolChain(const ToolChain *TC, - StringRef BoundArch) { +const DerivedArgList & +Compilation::getArgsForToolChain(const ToolChain *TC, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) { if (!TC) TC = &DefaultToolChain; - DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)]; + DerivedArgList *&Entry = TCArgs[{TC, BoundArch, DeviceOffloadKind}]; if (!Entry) { - Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch); + Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch, DeviceOffloadKind); if (!Entry) Entry = TranslatedArgs; } Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Thu Oct 27 12:39:44 2016 @@ -3011,7 +3011,8 @@ InputInfo Driver::BuildJobsForActionNoCa // Set the effective triple of the toolchain for the duration of this job. llvm::Triple EffectiveTriple; const ToolChain &ToolTC = T->getToolChain(); - const ArgList &Args = C.getArgsForToolChain(TC, BoundArch); + const ArgList &Args = + C.getArgsForToolChain(TC, BoundArch, A->getOffloadingDeviceKind()); if (InputInfos.size() != 1) { EffectiveTriple = llvm::Triple(ToolTC.ComputeEffectiveClangTriple(Args)); } else { @@ -3041,8 +3042,10 @@ InputInfo Driver::BuildJobsForActionNoCa } llvm::errs() << "], output: " << Result.getAsString() << "\n"; } else { - T->ConstructJob(C, *JA, Result, InputInfos, - C.getArgsForToolChain(TC, BoundArch), LinkingOutput); + T->ConstructJob( + C, *JA, Result, InputInfos, + C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), + LinkingOutput); } return Result; } Modified: cfe/trunk/lib/Driver/MSVCToolChain.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/MSVCToolChain.cpp?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/lib/Driver/MSVCToolChain.cpp (original) +++ cfe/trunk/lib/Driver/MSVCToolChain.cpp Thu Oct 27 12:39:44 2016 @@ -811,7 +811,7 @@ static void TranslateDArg(Arg *A, llvm:: llvm::opt::DerivedArgList * MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const { + StringRef BoundArch, Action::OffloadKind) const { DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); Modified: cfe/trunk/lib/Driver/ToolChains.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains.cpp Thu Oct 27 12:39:44 2016 @@ -809,7 +809,8 @@ void DarwinClang::AddCCKextLibArgs(const } DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, - StringRef BoundArch) const { + StringRef BoundArch, + Action::OffloadKind) const { DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); @@ -1038,10 +1039,12 @@ void MachO::AddLinkRuntimeLibArgs(const AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); } -DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args, - StringRef BoundArch) const { +DerivedArgList * +Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const { // First get the generic Apple args, before moving onto Darwin-specific ones. - DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch); + DerivedArgList *DAL = + MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); const OptTable &Opts = getDriver().getOpts(); // If no architecture is bound, none of the translations here are relevant. @@ -2866,6 +2869,49 @@ bool Generic_GCC::addLibStdCXXIncludePat return true; } +llvm::opt::DerivedArgList * +Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef, + Action::OffloadKind DeviceOffloadKind) const { + + // If this tool chain is used for an OpenMP offloading device we have to make + // sure we always generate a shared library regardless of the commands the + // user passed to the host. This is required because the runtime library + // is required to load the device image dynamically at run time. + if (DeviceOffloadKind == Action::OFK_OpenMP) { + DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); + const OptTable &Opts = getDriver().getOpts(); + + // Request the shared library. Given that these options are decided + // implicitly, they do not refer to any base argument. + DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared)); + DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC)); + + // Filter all the arguments we don't care passing to the offloading + // toolchain as they can mess up with the creation of a shared library. + for (auto *A : Args) { + switch ((options::ID)A->getOption().getID()) { + default: + DAL->append(A); + break; + case options::OPT_shared: + case options::OPT_dynamic: + case options::OPT_static: + case options::OPT_fPIC: + case options::OPT_fno_PIC: + case options::OPT_fpic: + case options::OPT_fno_pic: + case options::OPT_fPIE: + case options::OPT_fno_PIE: + case options::OPT_fpie: + case options::OPT_fno_pie: + break; + } + } + return DAL; + } + return nullptr; +} + void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, ArgStringList &CC1Args) const { const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); @@ -5032,7 +5078,7 @@ void CudaToolChain::AddCudaIncludeArgs(c llvm::opt::DerivedArgList * CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const { + StringRef BoundArch, Action::OffloadKind) const { DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); Modified: cfe/trunk/lib/Driver/ToolChains.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains.h (original) +++ cfe/trunk/lib/Driver/ToolChains.h Thu Oct 27 12:39:44 2016 @@ -222,6 +222,9 @@ public: bool isPIEDefault() const override; bool isPICDefaultForced() const override; bool IsIntegratedAssemblerDefault() const override; + llvm::opt::DerivedArgList * + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const override; protected: Tool *getTool(Action::ActionClass AC) const override; @@ -317,8 +320,8 @@ public: bool HasNativeLLVMSupport() const override; llvm::opt::DerivedArgList * - TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const override; + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const override; bool IsBlocksDefault() const override { // Always allow blocks on Apple; users interested in versioning are @@ -522,8 +525,8 @@ public: bool isCrossCompiling() const override { return false; } llvm::opt::DerivedArgList * - TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const override; + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const override; CXXStdlibType GetDefaultCXXStdlibType() const override; ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; @@ -855,8 +858,8 @@ public: const llvm::opt::ArgList &Args); llvm::opt::DerivedArgList * - TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const override; + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const override; void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; @@ -1061,8 +1064,8 @@ public: const llvm::opt::ArgList &Args); llvm::opt::DerivedArgList * - TranslateArgs(const llvm::opt::DerivedArgList &Args, - StringRef BoundArch) const override; + TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind) const override; bool IsIntegratedAssemblerDefault() const override; bool IsUnwindTablesDefault() const override; Modified: cfe/trunk/test/Driver/openmp-offload.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/openmp-offload.c?rev=285320&r1=285319&r2=285320&view=diff ============================================================================== --- cfe/trunk/test/Driver/openmp-offload.c (original) +++ cfe/trunk/test/Driver/openmp-offload.c Thu Oct 27 12:39:44 2016 @@ -247,24 +247,24 @@ // // Compile for the powerpc device. // -// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" +// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" // CHK-COMMANDS: ld" {{.*}}"-o" "[[T1BIN]]" {{.*}}"[[T1OBJ]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1PP:.+\.i]]" "-x" "c" "[[INPUT]]" -// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1BC:.+\.bc]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" +// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1BC:.+\.bc]]" "-x" "cpp-output" "[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T1ASM:.+\.s]]" "-x" "ir" "[[T1BC]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T1OBJ:.+\.o]]" "[[T1ASM]]" -// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[T1BIN]]" {{.*}}[[T1OBJ]] +// CHK-COMMANDS-ST: ld" {{.*}}"-shared" {{.*}}"-o" "[[T1BIN]]" {{.*}}[[T1OBJ]] // // Compile for the x86 device. // -// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" +// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "-x" "c" "[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" // CHK-COMMANDS: ld" {{.*}}"-o" "[[T2BIN]]" {{.*}}"[[T2OBJ]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2PP:.+\.i]]" "-x" "c" "[[INPUT]]" -// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2BC:.+\.bc]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" +// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2BC:.+\.bc]]" "-x" "cpp-output" "[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "[[HOSTBC]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "[[T2ASM:.+\.s]]" "-x" "ir" "[[T2BC]]" // CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "[[T2OBJ:.+\.o]]" "[[T2ASM]]" -// CHK-COMMANDS-ST: ld" {{.*}}"-o" "[[T2BIN]]" {{.*}}[[T2OBJ]] +// CHK-COMMANDS-ST: ld" {{.*}}"-shared" {{.*}}"-o" "[[T2BIN]]" {{.*}}[[T2OBJ]] // // Generate host object from the BC file and link using the linker script. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits