22#include "llvm/Support/Regex.h"
25#define GEN_PASS_DEF_GPUROCDLATTACHTARGET
26#include "mlir/Dialect/GPU/Transforms/Passes.h.inc"
33struct ROCDLAttachTarget
34 :
public impl::GpuROCDLAttachTargetBase<ROCDLAttachTarget> {
37 DictionaryAttr getFlags(OpBuilder &builder,
bool isWave64)
const;
39 void runOnOperation()
override;
41 void getDependentDialects(DialectRegistry ®istry)
const override {
42 registry.
insert<ROCDL::ROCDLDialect>();
47DictionaryAttr ROCDLAttachTarget::getFlags(
OpBuilder &builder,
48 bool isWave64)
const {
50 SmallVector<NamedAttribute, 6> flags;
51 auto addFlag = [&](StringRef flag) {
61 addFlag(
"finite_only");
63 addFlag(
"unsafe_math");
65 addFlag(
"unsafe_sqrt");
71void ROCDLAttachTarget::runOnOperation() {
77 std::string resolvedTriple = triple;
78 std::string resolvedChip = chip;
79 std::string resolvedFeatures = features;
83 bool resolvedWave64 = waveSize != 32;
86 std::optional<ROCDL::TargetInfo> targetInfo;
88 std::optional<llvm::AMDGPU::TargetID>
id =
92 <<
"'" << arch <<
"' is not a valid AMDGPU architecture";
93 return signalPassFailure();
97 if (id->getGPUKind() == llvm::AMDGPU::GK_NONE) {
100 <<
"' names no GPU; a chip is required to attach a "
102 return signalPassFailure();
105 llvm::Triple parsed(id->getTargetTripleString());
107 StringRef archName = parsed.getArchName();
108 llvm::Triple::SubArchType subArch =
109 llvm::AMDGPU::getSubArch(id->getGPUKind());
110 if (StringRef subArchName = llvm::AMDGPU::getSubArchName(subArch);
111 !subArchName.empty())
112 archName = subArchName;
117 (parsed.getEnvironment() == llvm::Triple::UnknownEnvironment
118 ? llvm::Triple(archName, parsed.getVendorName(),
120 : llvm::Triple(archName, parsed.getVendorName(),
121 parsed.getOSName(), parsed.getEnvironmentName()))
123 resolvedChip = llvm::AMDGPU::getArchNameAMDGCN(id->getGPUKind()).str();
127 FailureOr<ROCDL::TargetInfo> info =
132 return signalPassFailure();
134 resolvedWave64 = info->getWavefrontSize() == 64;
139 if (info->supportsBothWavefrontSizes()) {
140 if (!resolvedFeatures.empty())
141 resolvedFeatures +=
",";
143 resolvedWave64 ?
"+wavefrontsize64" :
"+wavefrontsize32";
145 }
else if (waveSize != 0 && waveSize != 32 && waveSize != 64) {
147 <<
"wavefront size must be 32 or 64, got " << waveSize;
148 return signalPassFailure();
151 ArrayRef<std::string> libs(linkLibs);
152 SmallVector<StringRef> filesToLink(libs);
154 optLevel, resolvedTriple, resolvedChip, resolvedFeatures, abiVersion,
155 getFlags(builder, resolvedWave64),
157 llvm::Regex matcher(moduleMatcher);
158 for (Region ®ion : getOperation()->getRegions())
159 for (
Block &block : region.getBlocks())
160 for (
auto module : block.getOps<gpu::GPUModuleOp>()) {
162 if (!moduleMatcher.empty() && !matcher.match(module.getName()))
165 SmallVector<Attribute> targets;
166 if (std::optional<ArrayAttr> attrs = module.getTargets())
167 targets.append(attrs->getValue().begin(), attrs->getValue().end());
168 targets.push_back(
target);
170 targets.erase(llvm::unique(targets), targets.end());
172 module.setTargetsAttr(builder.getArrayAttr(targets));
174 targetInfo->migrateArchFeaturesToModuleFlags(module);
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
ArrayAttr getStrArrayAttr(ArrayRef< StringRef > values)
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
This class helps build Operations.
static FailureOr< TargetInfo > get(StringRef arch, unsigned waveSize=0, function_ref< InFlightDiagnostic()> emitError=nullptr)
Resolves a target description.
static std::optional<::llvm::AMDGPU::TargetID > parseTargetID(StringRef arch)
Parses arch into a target ID, accepting the spellings get() documents, or returns nullopt if it names...
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.