From: Yaxun Liu Date: Tue, 8 May 2018 21:02:12 +0000 (+0000) Subject: [HIP] Add hip offload kind X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=31df10b0f032b02e4eb2164f6de9855dadcb2c02;p=clang [HIP] Add hip offload kind There are quite differences in HIP action builder and action job creation, which justifies to define a separate offload kind. Differential Revision: https://reviews.llvm.org/D46471 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331811 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h index 4922817450..4a0c36809c 100644 --- a/include/clang/Driver/Action.h +++ b/include/clang/Driver/Action.h @@ -88,6 +88,7 @@ public: // The device offloading tool chains - one bit for each programming model. OFK_Cuda = 0x02, OFK_OpenMP = 0x04, + OFK_HIP = 0x08, }; static const char *getClassName(ActionClass AC); diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index 3e65f9e05f..99d588d9c0 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -96,6 +96,8 @@ std::string Action::getOffloadingKindPrefix() const { return "device-cuda"; case OFK_OpenMP: return "device-openmp"; + case OFK_HIP: + return "device-hip"; // TODO: Add other programming models here. } @@ -104,8 +106,13 @@ std::string Action::getOffloadingKindPrefix() const { return {}; std::string Res("host"); + assert(!((ActiveOffloadKindMask & OFK_Cuda) && + (ActiveOffloadKindMask & OFK_HIP)) && + "Cannot offload CUDA and HIP at the same time"); if (ActiveOffloadKindMask & OFK_Cuda) Res += "-cuda"; + if (ActiveOffloadKindMask & OFK_HIP) + Res += "-hip"; if (ActiveOffloadKindMask & OFK_OpenMP) Res += "-openmp"; @@ -142,6 +149,8 @@ StringRef Action::GetOffloadKindName(OffloadKind Kind) { return "cuda"; case OFK_OpenMP: return "openmp"; + case OFK_HIP: + return "hip"; // TODO: Add other programming models here. } diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 5944936a0a..2369999ce4 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -196,10 +196,10 @@ static bool ActionFailed(const Action *A, if (FailingCommands.empty()) return false; - // CUDA can have the same input source code compiled multiple times so do not - // compiled again if there are already failures. It is OK to abort the CUDA - // pipeline on errors. - if (A->isOffloading(Action::OFK_Cuda)) + // CUDA/HIP can have the same input source code compiled multiple times so do + // not compiled again if there are already failures. It is OK to abort the + // CUDA pipeline on errors. + if (A->isOffloading(Action::OFK_Cuda) || A->isOffloading(Action::OFK_HIP)) return true; for (const auto &CI : FailingCommands) diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index c72c69d144..fe2eae7da4 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -131,6 +131,10 @@ forAllAssociatedToolChains(Compilation &C, const JobAction &JA, Work(*C.getSingleOffloadToolChain()); else if (JA.isDeviceOffloading(Action::OFK_Cuda)) Work(*C.getSingleOffloadToolChain()); + else if (JA.isHostOffloading(Action::OFK_HIP)) + Work(*C.getSingleOffloadToolChain()); + else if (JA.isDeviceOffloading(Action::OFK_HIP)) + Work(*C.getSingleOffloadToolChain()); if (JA.isHostOffloading(Action::OFK_OpenMP)) { auto TCs = C.getOffloadToolChains(); @@ -3105,13 +3109,14 @@ void Clang::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."); const InputInfo &Input = Inputs[0]; - // CUDA compilation may have multiple inputs (source file + results of + // CUDA/HIP compilation may have multiple inputs (source file + results of // device-side compilations). OpenMP device jobs also take the host IR as a // second input. All other jobs are expected to have exactly one // input. bool IsCuda = JA.isOffloading(Action::OFK_Cuda); + bool IsHIP = JA.isOffloading(Action::OFK_HIP); bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); - assert((IsCuda || (IsOpenMPDevice && Inputs.size() == 2) || + assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) || Inputs.size() == 1) && "Unable to handle multiple inputs."); @@ -3123,10 +3128,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment(); bool IsIAMCU = RawTriple.isOSIAMCU(); - // Adjust IsWindowsXYZ for CUDA compilations. Even when compiling in device - // mode (i.e., getToolchain().getTriple() is NVPTX, not Windows), we need to - // pass Windows-specific flags to cc1. - if (IsCuda) { + // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in + // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not + // Windows), we need to pass Windows-specific flags to cc1. + if (IsCuda || IsHIP) { IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment(); IsWindowsGNU |= AuxTriple && AuxTriple->isWindowsGNUEnvironment(); IsWindowsCygnus |= AuxTriple && AuxTriple->isWindowsCygwinEnvironment(); @@ -3150,18 +3155,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.ClaimAllArgs(options::OPT_MJ); } - if (IsCuda) { - // We have to pass the triple of the host if compiling for a CUDA device and - // vice-versa. + if (IsCuda || IsHIP) { + // We have to pass the triple of the host if compiling for a CUDA/HIP device + // and vice-versa. std::string NormalizedTriple; - if (JA.isDeviceOffloading(Action::OFK_Cuda)) + if (JA.isDeviceOffloading(Action::OFK_Cuda) || + JA.isDeviceOffloading(Action::OFK_HIP)) NormalizedTriple = C.getSingleOffloadToolChain() ->getTriple() .normalize(); else - NormalizedTriple = C.getSingleOffloadToolChain() - ->getTriple() - .normalize(); + NormalizedTriple = + (IsCuda ? C.getSingleOffloadToolChain() + : C.getSingleOffloadToolChain()) + ->getTriple() + .normalize(); CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));