Skip to content

Commit 766d10f

Browse files
committed
[HIP][Clang][Driver] Move BC preference logic into ROCm detection (#149294)
This patch provides a single point for handling the logic behind choosing common bitcode libraries. The intention is that the users of ROCm installation detector will not have to rewrite options handling code each time the bitcode libraries are queried. This is not too distant from detectors for other architecture that encapsulate the similar decision making process, providing cleaner interface. The only flag left in `getCommonBitcodeLibs` (main point of entry) is `NeedsASanRT`, this is deliberate, as in order to calculate it we need to consult `ToolChain`.
1 parent 74dbc1e commit 766d10f

File tree

9 files changed

+120
-89
lines changed

9 files changed

+120
-89
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,9 +1692,8 @@ void ToolChain::addSYCLIncludeArgs(const ArgList &DriverArgs,
16921692
ArgStringList &CC1Args) const {}
16931693

16941694
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
1695-
ToolChain::getDeviceLibs(
1696-
const ArgList &DriverArgs,
1697-
const Action::OffloadKind DeviceOffloadingKind) const {
1695+
ToolChain::getDeviceLibs(const ArgList &DriverArgs,
1696+
const Action::OffloadKind DeviceOffloadingKind) const {
16981697
return {};
16991698
}
17001699

clang/lib/Driver/ToolChains/AMDGPU.cpp

Lines changed: 82 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,68 @@ using namespace clang::driver::toolchains;
3131
using namespace clang;
3232
using namespace llvm::opt;
3333

34+
RocmInstallationDetector::CommonBitcodeLibsPreferences::
35+
CommonBitcodeLibsPreferences(const Driver &D,
36+
const llvm::opt::ArgList &DriverArgs,
37+
StringRef GPUArch,
38+
const Action::OffloadKind DeviceOffloadingKind,
39+
const bool NeedsASanRT)
40+
: ABIVer(DeviceLibABIVersion::fromCodeObjectVersion(
41+
tools::getAMDGPUCodeObjectVersion(D, DriverArgs))) {
42+
const auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
43+
const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind);
44+
45+
IsOpenMP = DeviceOffloadingKind == Action::OFK_OpenMP;
46+
47+
const bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32);
48+
Wave64 =
49+
!HasWave32 || DriverArgs.hasFlag(options::OPT_mwavefrontsize64,
50+
options::OPT_mno_wavefrontsize64, false);
51+
52+
const bool IsKnownOffloading = DeviceOffloadingKind == Action::OFK_OpenMP ||
53+
DeviceOffloadingKind == Action::OFK_HIP;
54+
55+
// Default to enabling f32 denormals on subtargets where fma is fast with
56+
// denormals
57+
const bool DefaultDAZ =
58+
(Kind == llvm::AMDGPU::GK_NONE)
59+
? false
60+
: !((ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) &&
61+
(ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32));
62+
// TODO: There are way too many flags that change this. Do we need to
63+
// check them all?
64+
DAZ = IsKnownOffloading
65+
? DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
66+
options::OPT_fno_gpu_flush_denormals_to_zero,
67+
DefaultDAZ)
68+
: DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || DefaultDAZ;
69+
70+
FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only) ||
71+
DriverArgs.hasFlag(options::OPT_ffinite_math_only,
72+
options::OPT_fno_finite_math_only, false);
73+
74+
UnsafeMathOpt =
75+
DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations) ||
76+
DriverArgs.hasFlag(options::OPT_funsafe_math_optimizations,
77+
options::OPT_fno_unsafe_math_optimizations, false);
78+
79+
FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math) ||
80+
DriverArgs.hasFlag(options::OPT_ffast_math,
81+
options::OPT_fno_fast_math, false);
82+
83+
const bool DefaultSqrt = IsKnownOffloading ? true : false;
84+
CorrectSqrt =
85+
DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt) ||
86+
DriverArgs.hasFlag(
87+
options::OPT_fhip_fp32_correctly_rounded_divide_sqrt,
88+
options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, DefaultSqrt);
89+
// GPU Sanitizer currently only supports ASan and is enabled through host
90+
// ASan.
91+
GPUSan = (DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
92+
options::OPT_fno_gpu_sanitize, true) &&
93+
NeedsASanRT);
94+
}
95+
3496
void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
3597
assert(!Path.empty());
3698

@@ -884,33 +946,14 @@ void ROCMToolChain::addClangTargetOptions(
884946
ABIVer))
885947
return;
886948

887-
bool Wave64 = isWave64(DriverArgs, Kind);
888-
// TODO: There are way too many flags that change this. Do we need to check
889-
// them all?
890-
bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) ||
891-
getDefaultDenormsAreZeroForTarget(Kind);
892-
bool FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only);
893-
894-
bool UnsafeMathOpt =
895-
DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations);
896-
bool FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math);
897-
bool CorrectSqrt =
898-
DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt);
899-
900-
// GPU Sanitizer currently only supports ASan and is enabled through host
901-
// ASan.
902-
bool GPUSan = DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
903-
options::OPT_fno_gpu_sanitize, true) &&
904-
getSanitizerArgs(DriverArgs).needsAsanRt();
905-
906949
// Add the OpenCL specific bitcode library.
907950
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
908951
BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str());
909952

910953
// Add the generic set of libraries.
911954
BCLibs.append(RocmInstallation->getCommonBitcodeLibs(
912-
DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
913-
FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, false));
955+
DriverArgs, LibDeviceFile, GpuArch, DeviceOffloadingKind,
956+
getSanitizerArgs(DriverArgs).needsAsanRt()));
914957

915958
for (auto [BCFile, Internalize] : BCLibs) {
916959
if (Internalize)
@@ -947,35 +990,37 @@ bool RocmInstallationDetector::checkCommonBitcodeLibs(
947990

948991
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
949992
RocmInstallationDetector::getCommonBitcodeLibs(
950-
const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64,
951-
bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath,
952-
bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool GPUSan,
953-
bool isOpenMP) const {
993+
const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile,
994+
StringRef GPUArch, const Action::OffloadKind DeviceOffloadingKind,
995+
const bool NeedsASanRT) const {
954996
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> BCLibs;
955997

998+
CommonBitcodeLibsPreferences Pref{D, DriverArgs, GPUArch,
999+
DeviceOffloadingKind, NeedsASanRT};
1000+
9561001
auto AddBCLib = [&](ToolChain::BitCodeLibraryInfo BCLib,
9571002
bool Internalize = true) {
9581003
BCLib.ShouldInternalize = Internalize;
9591004
BCLibs.emplace_back(BCLib);
9601005
};
9611006
auto AddSanBCLibs = [&]() {
962-
if (GPUSan)
1007+
if (Pref.GPUSan)
9631008
AddBCLib(getAsanRTLPath(), false);
9641009
};
9651010

9661011
AddSanBCLibs();
9671012
AddBCLib(getOCMLPath());
968-
if (!isOpenMP)
1013+
if (!Pref.IsOpenMP)
9691014
AddBCLib(getOCKLPath());
970-
else if (GPUSan && isOpenMP)
1015+
else if (Pref.GPUSan && Pref.IsOpenMP)
9711016
AddBCLib(getOCKLPath(), false);
972-
AddBCLib(getDenormalsAreZeroPath(DAZ));
973-
AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath));
974-
AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath));
975-
AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt));
976-
AddBCLib(getWavefrontSize64Path(Wave64));
1017+
AddBCLib(getDenormalsAreZeroPath(Pref.DAZ));
1018+
AddBCLib(getUnsafeMathPath(Pref.UnsafeMathOpt || Pref.FastRelaxedMath));
1019+
AddBCLib(getFiniteOnlyPath(Pref.FiniteOnly || Pref.FastRelaxedMath));
1020+
AddBCLib(getCorrectlyRoundedSqrtPath(Pref.CorrectSqrt));
1021+
AddBCLib(getWavefrontSize64Path(Pref.Wave64));
9771022
AddBCLib(LibDeviceFile);
978-
auto ABIVerPath = getABIVersionPath(ABIVer);
1023+
auto ABIVerPath = getABIVersionPath(Pref.ABIVer);
9791024
if (!ABIVerPath.empty())
9801025
AddBCLib(ABIVerPath);
9811026

@@ -985,7 +1030,7 @@ RocmInstallationDetector::getCommonBitcodeLibs(
9851030
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
9861031
ROCMToolChain::getCommonDeviceLibNames(
9871032
const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch,
988-
const Action::OffloadKind DeviceOffloadingKind, bool isOpenMP) const {
1033+
Action::OffloadKind DeviceOffloadingKind) const {
9891034
auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
9901035
const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
9911036

@@ -996,38 +1041,9 @@ ROCMToolChain::getCommonDeviceLibNames(
9961041
ABIVer))
9971042
return {};
9981043

999-
// If --hip-device-lib is not set, add the default bitcode libraries.
1000-
// TODO: There are way too many flags that change this. Do we need to check
1001-
// them all?
1002-
bool DAZ = DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
1003-
options::OPT_fno_gpu_flush_denormals_to_zero,
1004-
getDefaultDenormsAreZeroForTarget(Kind));
1005-
bool FiniteOnly = DriverArgs.hasFlag(
1006-
options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, false);
1007-
bool UnsafeMathOpt =
1008-
DriverArgs.hasFlag(options::OPT_funsafe_math_optimizations,
1009-
options::OPT_fno_unsafe_math_optimizations, false);
1010-
bool FastRelaxedMath = DriverArgs.hasFlag(options::OPT_ffast_math,
1011-
options::OPT_fno_fast_math, false);
1012-
bool CorrectSqrt = false;
1013-
if (DeviceOffloadingKind == Action::OFK_SYCL)
1014-
// When using SYCL, sqrt is only correctly rounded if the flag is specified
1015-
CorrectSqrt = DriverArgs.hasArg(options::OPT_foffload_fp32_prec_sqrt);
1016-
else
1017-
CorrectSqrt = DriverArgs.hasFlag(
1018-
options::OPT_fhip_fp32_correctly_rounded_divide_sqrt,
1019-
options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, true);
1020-
bool Wave64 = isWave64(DriverArgs, Kind);
1021-
1022-
// GPU Sanitizer currently only supports ASan and is enabled through host
1023-
// ASan.
1024-
bool GPUSan = DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
1025-
options::OPT_fno_gpu_sanitize, true) &&
1026-
getSanitizerArgs(DriverArgs).needsAsanRt();
1027-
10281044
return RocmInstallation->getCommonBitcodeLibs(
1029-
DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
1030-
FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, isOpenMP);
1045+
DriverArgs, LibDeviceFile, GPUArch, DeviceOffloadingKind,
1046+
getSanitizerArgs(DriverArgs).needsAsanRt());
10311047
}
10321048

10331049
bool AMDGPUToolChain::shouldSkipSanitizeOption(

clang/lib/Driver/ToolChains/AMDGPU.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
147147
llvm::SmallVector<BitCodeLibraryInfo, 12>
148148
getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
149149
const std::string &GPUArch,
150-
const Action::OffloadKind DeviceOffloadingKind,
151-
bool isOpenMP = false) const;
150+
Action::OffloadKind DeviceOffloadingKind) const;
152151

153152
SanitizerMask getSupportedSanitizers() const override {
154153
return SanitizerKind::Address;

clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ AMDGPUOpenMPToolChain::getDeviceLibs(
360360

361361
SmallVector<BitCodeLibraryInfo, 12> BCLibs;
362362
for (auto BCLib :
363-
getCommonDeviceLibNames(Args, GpuArch.str(), DeviceOffloadingKind,
364-
/*IsOpenMP=*/true))
363+
getCommonDeviceLibNames(Args, GpuArch.str(), DeviceOffloadingKind))
365364
BCLibs.emplace_back(BCLib);
366365

367366
return BCLibs;

clang/lib/Driver/ToolChains/AMDGPUOpenMP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUOpenMPToolChain final
102102

103103
llvm::SmallVector<BitCodeLibraryInfo, 12>
104104
getDeviceLibs(const llvm::opt::ArgList &Args,
105-
const Action::OffloadKind DeviceOffloadingKind) const override;
105+
const Action::OffloadKind DeviceOffloadKind) const override;
106106

107107
const ToolChain &HostTC;
108108

clang/lib/Driver/ToolChains/HIPAMD.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ void HIPAMDToolChain::addClangTargetOptions(
281281
: "-mlink-bitcode-file");
282282
CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
283283
}
284-
285284
}
286285

287286
llvm::opt::DerivedArgList *
@@ -381,9 +380,8 @@ VersionTuple HIPAMDToolChain::computeMSVCVersion(const Driver *D,
381380
}
382381

383382
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
384-
HIPAMDToolChain::getDeviceLibs(
385-
const llvm::opt::ArgList &DriverArgs,
386-
const Action::OffloadKind DeviceOffloadingKind) const {
383+
HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs,
384+
Action::OffloadKind DeviceOffloadingKind) const {
387385
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
388386
if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
389387
true) ||

clang/lib/Driver/ToolChains/HIPAMD.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ class LLVM_LIBRARY_VISIBILITY HIPAMDToolChain final : public ROCMToolChain {
9494
llvm::opt::ArgStringList &CC1Args) const override;
9595
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
9696
llvm::opt::ArgStringList &CC1Args) const override;
97-
llvm::SmallVector<BitCodeLibraryInfo, 12> getDeviceLibs(
98-
const llvm::opt::ArgList &Args,
99-
const Action::OffloadKind DeviceOffloadingKind) const override;
97+
llvm::SmallVector<BitCodeLibraryInfo, 12>
98+
getDeviceLibs(const llvm::opt::ArgList &Args,
99+
Action::OffloadKind DeviceOffloadKind) const override;
100100

101101
SanitizerMask getSupportedSanitizers() const override;
102102

clang/lib/Driver/ToolChains/HIPSPV.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ class LLVM_LIBRARY_VISIBILITY HIPSPVToolChain final : public ToolChain {
6868
llvm::opt::ArgStringList &CC1Args) const override;
6969
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
7070
llvm::opt::ArgStringList &CC1Args) const override;
71-
llvm::SmallVector<BitCodeLibraryInfo, 12> getDeviceLibs(
72-
const llvm::opt::ArgList &Args,
73-
const Action::OffloadKind DeviceOffloadingKind) const override;
71+
llvm::SmallVector<BitCodeLibraryInfo, 12>
72+
getDeviceLibs(const llvm::opt::ArgList &Args,
73+
const Action::OffloadKind DeviceOffloadKind) const override;
7474

7575
SanitizerMask getSupportedSanitizers() const override;
7676

clang/lib/Driver/ToolChains/ROCm.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111

1212
#include "clang/Basic/Cuda.h"
1313
#include "clang/Basic/LLVM.h"
14+
#include "clang/Driver/CommonArgs.h"
1415
#include "clang/Driver/Driver.h"
1516
#include "clang/Driver/Options.h"
1617
#include "clang/Driver/SanitizerArgs.h"
1718
#include "llvm/ADT/SmallString.h"
1819
#include "llvm/ADT/StringMap.h"
1920
#include "llvm/Option/ArgList.h"
2021
#include "llvm/Support/VersionTuple.h"
22+
#include "llvm/TargetParser/TargetParser.h"
2123
#include "llvm/TargetParser/Triple.h"
2224

2325
namespace clang {
@@ -77,6 +79,24 @@ class RocmInstallationDetector {
7779
SPACKReleaseStr(SPACKReleaseStr.str()) {}
7880
};
7981

82+
struct CommonBitcodeLibsPreferences {
83+
CommonBitcodeLibsPreferences(const Driver &D,
84+
const llvm::opt::ArgList &DriverArgs,
85+
StringRef GPUArch,
86+
const Action::OffloadKind DeviceOffloadingKind,
87+
const bool NeedsASanRT);
88+
89+
DeviceLibABIVersion ABIVer;
90+
bool IsOpenMP;
91+
bool Wave64;
92+
bool DAZ;
93+
bool FiniteOnly;
94+
bool UnsafeMathOpt;
95+
bool FastRelaxedMath;
96+
bool CorrectSqrt;
97+
bool GPUSan;
98+
};
99+
80100
const Driver &D;
81101
bool HasHIPRuntime = false;
82102
bool HasDeviceLibrary = false;
@@ -175,11 +195,11 @@ class RocmInstallationDetector {
175195

176196
/// Get file paths of default bitcode libraries common to AMDGPU based
177197
/// toolchains.
178-
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> getCommonBitcodeLibs(
179-
const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile,
180-
bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt,
181-
bool FastRelaxedMath, bool CorrectSqrt, DeviceLibABIVersion ABIVer,
182-
bool GPUSan, bool isOpenMP) const;
198+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
199+
getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
200+
StringRef LibDeviceFile, StringRef GPUArch,
201+
const Action::OffloadKind DeviceOffloadingKind,
202+
const bool NeedsASanRT) const;
183203
/// Check file paths of default bitcode libraries common to AMDGPU based
184204
/// toolchains. \returns false if there are invalid or missing files.
185205
bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile,

0 commit comments

Comments
 (0)