diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -128,6 +128,9 @@ /// The Offloading architecture associated with this action. const char *OffloadingArch = nullptr; + /// The Offloading toolchain associated with this device action. + const ToolChain *OffloadingToolChain = nullptr; + Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {} Action(ActionClass Kind, Action *Input, types::ID Type) : Action(Kind, ActionList({Input}), Type) {} @@ -184,7 +187,8 @@ /// Set the device offload info of this action and propagate it to its /// dependences. - void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch); + void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, + const ToolChain *OToolChain); /// Append the host offload info of this action and propagate it to its /// dependences. @@ -205,10 +209,13 @@ OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; } const char *getOffloadingArch() const { return OffloadingArch; } + const ToolChain *getOffloadingToolChain() const { + return OffloadingToolChain; + } /// Check if this action have any offload kinds. Note that host offload kinds /// are only set if the action is a dependence to a host offload action. - bool isHostOffloading(OffloadKind OKind) const { + bool isHostOffloading(unsigned int OKind) const { return ActiveOffloadKindMask & OKind; } bool isDeviceOffloading(OffloadKind OKind) const { diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -54,7 +54,8 @@ llvm_unreachable("invalid class"); } -void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch) { +void Action::propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch, + const ToolChain *OToolChain) { // Offload action set its own kinds on their dependences. if (Kind == OffloadClass) return; @@ -67,9 +68,10 @@ assert(!ActiveOffloadKindMask && "Setting a device kind in a host action??"); OffloadingDeviceKind = OKind; OffloadingArch = OArch; + OffloadingToolChain = OToolChain; for (auto *A : Inputs) - A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch); + A->propagateDeviceOffloadInfo(OffloadingDeviceKind, OArch, OToolChain); } void Action::propagateHostOffloadInfo(unsigned OKinds, const char *OArch) { @@ -91,7 +93,8 @@ propagateHostOffloadInfo(HK, A->getOffloadingArch()); else propagateDeviceOffloadInfo(A->getOffloadingDeviceKind(), - A->getOffloadingArch()); + A->getOffloadingArch(), + A->getOffloadingToolChain()); } std::string Action::getOffloadingKindPrefix() const { @@ -192,6 +195,7 @@ DevToolChains(DDeps.getToolChains()) { auto &OKinds = DDeps.getOffloadKinds(); auto &BArchs = DDeps.getBoundArchs(); + auto &OTCs = DDeps.getToolChains(); // If all inputs agree on the same kind, use it also for this action. if (llvm::all_of(OKinds, [&](OffloadKind K) { return K == OKinds.front(); })) @@ -203,7 +207,7 @@ // Propagate info to the dependencies. for (unsigned i = 0, e = getInputs().size(); i != e; ++i) - getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i]); + getInputs()[i]->propagateDeviceOffloadInfo(OKinds[i], BArchs[i], OTCs[i]); } OffloadAction::OffloadAction(const HostDependence &HDep, @@ -222,7 +226,8 @@ if (auto *A = DDeps.getActions()[i]) { getInputs().push_back(A); A->propagateDeviceOffloadInfo(DDeps.getOffloadKinds()[i], - DDeps.getBoundArchs()[i]); + DDeps.getBoundArchs()[i], + DDeps.getToolChains()[i]); } } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4376,11 +4376,13 @@ bool IsHIP = JA.isOffloading(Action::OFK_HIP); bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP); bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); - bool IsOpenMPHost = JA.isHostOffloading(Action::OFK_OpenMP); bool IsHeaderModulePrecompile = isa(JA); bool IsExtractAPI = isa(JA); bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) || JA.isDeviceOffloading(Action::OFK_Host)); + bool IsHostOffloadingAction = + JA.isHostOffloading(Action::OFK_OpenMP) && + !Args.hasArg(options::OPT_fno_openmp_new_driver); bool IsUsingLTO = D.isUsingLTO(IsDeviceOffloadAction); auto LTOMode = D.getLTOMode(IsDeviceOffloadAction); @@ -4407,7 +4409,7 @@ InputInfoList ModuleHeaderInputs; InputInfoList ExtractAPIInputs; - InputInfoList OpenMPHostInputs; + InputInfoList HostOffloadingInputs; const InputInfo *CudaDeviceInput = nullptr; const InputInfo *OpenMPDeviceInput = nullptr; for (const InputInfo &I : Inputs) { @@ -4430,12 +4432,12 @@ << types::getTypeName(ExpectedInputType); } ExtractAPIInputs.push_back(I); + } else if (IsHostOffloadingAction) { + HostOffloadingInputs.push_back(I); } else if ((IsCuda || IsHIP) && !CudaDeviceInput) { CudaDeviceInput = &I; } else if (IsOpenMPDevice && !OpenMPDeviceInput) { OpenMPDeviceInput = &I; - } else if (IsOpenMPHost) { - OpenMPHostInputs.push_back(I); } else { llvm_unreachable("unexpectedly given multiple inputs"); } @@ -6931,24 +6933,23 @@ } } - // Host-side OpenMP offloading recieves the device object files and embeds it - // in a named section including the associated target triple and architecture. - if (IsOpenMPHost && !OpenMPHostInputs.empty()) { - auto InputFile = OpenMPHostInputs.begin(); - auto OpenMPTCs = C.getOffloadToolChains(); - for (auto TI = OpenMPTCs.first, TE = OpenMPTCs.second; TI != TE; - ++TI, ++InputFile) { - const ToolChain *TC = TI->second; - const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP); - StringRef File = - C.getArgs().MakeArgString(TC->getInputFilename(*InputFile)); + // Host-side offloading recieves the device object files and embeds it in a + // named section including the associated target triple and architecture. + for (const InputInfo Input : HostOffloadingInputs) { + const Action *OffloadAction = Input.getAction(); + const ToolChain *TC = OffloadAction->getOffloadingToolChain(); + const ArgList &TCArgs = + C.getArgsForToolChain(TC, OffloadAction->getOffloadingArch(), + OffloadAction->getOffloadingDeviceKind()); + StringRef File = C.getArgs().MakeArgString(TC->getInputFilename(Input)); + StringRef Arch = (OffloadAction->getOffloadingArch()) + ? OffloadAction->getOffloadingArch() + : TCArgs.getLastArgValue(options::OPT_march_EQ); - CmdArgs.push_back( - Args.MakeArgString("-fembed-offload-object=" + File + "," + - Action::GetOffloadKindName(Action::OFK_OpenMP) + - "," + TC->getTripleString() + "," + - TCArgs.getLastArgValue(options::OPT_march_EQ))); - } + CmdArgs.push_back(Args.MakeArgString( + "-fembed-offload-object=" + File + "," + + Action::GetOffloadKindName(OffloadAction->getOffloadingDeviceKind()) + + "," + TC->getTripleString() + "," + Arch)); } if (Triple.isAMDGPU()) {