MLIR 23.0.0git
Target.cpp
Go to the documentation of this file.
1//===- Target.cpp - MLIR LLVM ROCDL target compilation ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This files defines ROCDL target related functions including registration
10// calls for the `#rocdl.target` compilation attribute.
11//
12//===----------------------------------------------------------------------===//
13
15
21
22#include "llvm/Config/Targets.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/MC/MCAsmBackend.h"
25#include "llvm/MC/MCAsmInfo.h"
26#include "llvm/MC/MCCodeEmitter.h"
27#include "llvm/MC/MCContext.h"
28#include "llvm/MC/MCInstrInfo.h"
29#include "llvm/MC/MCObjectFileInfo.h"
30#include "llvm/MC/MCObjectWriter.h"
31#include "llvm/MC/MCParser/MCTargetAsmParser.h"
32#include "llvm/MC/MCRegisterInfo.h"
33#include "llvm/MC/MCStreamer.h"
34#include "llvm/MC/MCSubtargetInfo.h"
35#include "llvm/MC/TargetRegistry.h"
36#include "llvm/Support/FileSystem.h"
37#include "llvm/Support/FileUtilities.h"
38#include "llvm/Support/Path.h"
39#include "llvm/Support/Program.h"
40#include "llvm/Support/SourceMgr.h"
41#include "llvm/Support/TargetSelect.h"
42#include "llvm/TargetParser/TargetParser.h"
43
44#include <cstdlib>
45#include <optional>
46
47using namespace mlir;
48using namespace mlir::ROCDL;
49
50#ifndef __DEFAULT_ROCM_PATH__
51#define __DEFAULT_ROCM_PATH__ ""
52#endif
53
54namespace {
55// Implementation of the `TargetAttrInterface` model.
56class ROCDLTargetAttrImpl
57 : public gpu::TargetAttrInterface::FallbackModel<ROCDLTargetAttrImpl> {
58public:
59 std::optional<mlir::gpu::SerializedObject>
60 serializeToObject(Attribute attribute, Operation *module,
61 const gpu::TargetOptions &options) const;
62
63 Attribute createObject(Attribute attribute, Operation *module,
64 const mlir::gpu::SerializedObject &object,
65 const gpu::TargetOptions &options) const;
66};
67} // namespace
68
69// Register the ROCDL dialect, the ROCDL translation and the target interface.
71 DialectRegistry &registry) {
72 registry.addExtension(+[](MLIRContext *ctx, ROCDL::ROCDLDialect *dialect) {
73 ROCDLTargetAttr::attachInterface<ROCDLTargetAttrImpl>(*ctx);
74 });
75}
76
83
84// Search for the ROCM path.
86 if (const char *var = std::getenv("ROCM_PATH"))
87 return var;
88 if (const char *var = std::getenv("ROCM_ROOT"))
89 return var;
90 if (const char *var = std::getenv("ROCM_HOME"))
91 return var;
93}
94
96 Operation &module, ROCDLTargetAttr target,
97 const gpu::TargetOptions &targetOptions)
98 : ModuleToObject(module, target.getTriple(), target.getChip(),
99 target.getFeatures(), target.getO()),
100 target(target), toolkitPath(targetOptions.getToolkitPath()),
101 librariesToLink(targetOptions.getLibrariesToLink()) {
102
103 // If `targetOptions` has an empty toolkitPath use `getROCMPath`
104 if (toolkitPath.empty())
106
107 // Append the files in the target attribute.
108 if (target.getLink())
109 librariesToLink.append(target.getLink().begin(), target.getLink().end());
110}
111
113 static llvm::once_flag initializeBackendOnce;
114 llvm::call_once(initializeBackendOnce, []() {
115 // If the `AMDGPU` LLVM target was built, initialize it.
116#if LLVM_HAS_AMDGPU_TARGET
117 LLVMInitializeAMDGPUTarget();
118 LLVMInitializeAMDGPUTargetInfo();
119 LLVMInitializeAMDGPUTargetMC();
120 LLVMInitializeAMDGPUAsmParser();
121 LLVMInitializeAMDGPUAsmPrinter();
122#endif
123 });
124}
125
126ROCDLTargetAttr SerializeGPUModuleBase::getTarget() const { return target; }
127
129
133
135 if (libs == AMDGCNLibraries::None)
136 return success();
137 StringRef pathRef = getToolkitPath();
138
139 // Get the path for the device libraries
140 SmallString<256> path;
141 path.insert(path.begin(), pathRef.begin(), pathRef.end());
142 llvm::sys::path::append(path, "amdgcn", "bitcode");
143 pathRef = StringRef(path.data(), path.size());
144
145 // Fail if the path is invalid.
146 if (!llvm::sys::fs::is_directory(pathRef)) {
147 getOperation().emitError() << "ROCm amdgcn bitcode path: " << pathRef
148 << " does not exist or is not a directory";
149 return failure();
150 }
151
152 // Helper function for adding a library.
153 auto addLib = [&](const Twine &lib) -> bool {
154 auto baseSize = path.size();
155 llvm::sys::path::append(path, lib);
156 StringRef pathRef(path.data(), path.size());
157 if (!llvm::sys::fs::is_regular_file(pathRef)) {
158 getOperation().emitRemark() << "bitcode library path: " << pathRef
159 << " does not exist or is not a file";
160 return true;
161 }
162 librariesToLink.push_back(StringAttr::get(target.getContext(), pathRef));
163 path.truncate(baseSize);
164 return false;
165 };
166
167 // Add ROCm device libraries. Fail if any of the libraries is not found, ie.
168 // if any of the `addLib` failed.
169 if ((any(libs & AMDGCNLibraries::Ocml) && addLib("ocml.bc")) ||
170 (any(libs & AMDGCNLibraries::Ockl) && addLib("ockl.bc")) ||
171 (any(libs & AMDGCNLibraries::Hip) && addLib("hip.bc")) ||
172 (any(libs & AMDGCNLibraries::OpenCL) && addLib("opencl.bc")))
173 return failure();
174 return success();
175}
176
177std::optional<SmallVector<std::unique_ptr<llvm::Module>>>
179 // Return if there are no libs to load.
182 if (failed(appendStandardLibs(deviceLibs)))
183 return std::nullopt;
185 if (failed(loadBitcodeFilesFromList(module.getContext(), librariesToLink,
186 bcFiles, true)))
187 return std::nullopt;
188 return std::move(bcFiles);
189}
190
192 // Some ROCM builds don't strip this like they should
193 if (auto *openclVersion = module.getNamedMetadata("opencl.ocl.version"))
194 module.eraseNamedMetadata(openclVersion);
195 // Stop spamming us with clang version numbers
196 if (auto *ident = module.getNamedMetadata("llvm.ident"))
197 module.eraseNamedMetadata(ident);
198 // Override the libModules datalayout and target triple with the compiler's
199 // data layout should there be a discrepency.
201 return success();
202}
203
205 // If all libraries are not set, traverse the module to determine which
206 // libraries are required.
208 for (llvm::Function &f : module.functions()) {
209 if (f.hasExternalLinkage() && f.hasName() && !f.hasExactDefinition()) {
210 StringRef funcName = f.getName();
211 if ("printf" == funcName)
214 if (funcName.starts_with("__ockl_"))
216 if (funcName.starts_with("__ocml_"))
218 if (funcName == "__atomic_work_item_fence")
220 }
221 }
222 }
223 addControlVariables(module, deviceLibs, target.hasWave64(), target.hasDaz(),
224 target.hasFiniteOnly(), target.hasUnsafeMath(),
225 target.hasFastMath(), target.hasCorrectSqrt(),
226 target.getAbi());
227}
228
230 llvm::Module &module, AMDGCNLibraries libs, bool wave64, bool daz,
231 bool finiteOnly, bool unsafeMath, bool fastMath, bool correctSqrt,
232 StringRef abiVer) {
233 // Helper function for adding control variables.
234 auto addControlVariable = [&module](StringRef name, uint32_t value,
235 uint32_t bitwidth) {
236 if (module.getNamedGlobal(name))
237 return;
238 llvm::IntegerType *type =
239 llvm::IntegerType::getIntNTy(module.getContext(), bitwidth);
240 llvm::GlobalVariable *controlVariable = new llvm::GlobalVariable(
241 module, /*isConstant=*/type, true,
242 llvm::GlobalValue::LinkageTypes::LinkOnceODRLinkage,
243 llvm::ConstantInt::get(type, value), name, /*before=*/nullptr,
244 /*threadLocalMode=*/llvm::GlobalValue::ThreadLocalMode::NotThreadLocal,
245 /*addressSpace=*/4);
246 controlVariable->setVisibility(
247 llvm::GlobalValue::VisibilityTypes::ProtectedVisibility);
248 controlVariable->setAlignment(llvm::MaybeAlign(bitwidth / 8));
249 controlVariable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
250 };
251
252 // Note that COV6 requires ROCm 6.3+.
253 int abi = 600;
254 abiVer.getAsInteger(0, abi);
255 module.addModuleFlag(llvm::Module::Error, "amdhsa_code_object_version", abi);
256 // Return if no device libraries are required.
257 if (libs == AMDGCNLibraries::None)
258 return;
259 // Add ocml related control variables.
260 if (any(libs & AMDGCNLibraries::Ocml)) {
261 addControlVariable("__oclc_finite_only_opt", finiteOnly || fastMath, 8);
262 addControlVariable("__oclc_daz_opt", daz || fastMath, 8);
263 addControlVariable("__oclc_correctly_rounded_sqrt32",
264 correctSqrt && !fastMath, 8);
265 addControlVariable("__oclc_unsafe_math_opt", unsafeMath || fastMath, 8);
266 }
267 // Add ocml or ockl related control variables.
268 if (any(libs & (AMDGCNLibraries::Ocml | AMDGCNLibraries::Ockl))) {
269 addControlVariable("__oclc_wavefrontsize64", wave64, 8);
270 // Get the ISA version.
271 llvm::AMDGPU::IsaVersion isaVersion = llvm::AMDGPU::getIsaVersion(chip);
272 // Add the ISA control variable.
273 addControlVariable("__oclc_ISA_version",
274 isaVersion.Minor + 100 * isaVersion.Stepping +
275 1000 * isaVersion.Major,
276 32);
277 addControlVariable("__oclc_ABI_version", abi, 32);
278 }
279}
280
281FailureOr<SmallVector<char, 0>>
282mlir::ROCDL::assembleIsa(StringRef isa, StringRef targetTriple, StringRef chip,
283 StringRef features,
286 llvm::raw_svector_ostream os(result);
287
288 llvm::Triple triple(llvm::Triple::normalize(targetTriple));
289 std::string error;
290 const llvm::Target *target =
291 llvm::TargetRegistry::lookupTarget(triple, error);
292 if (!target)
293 return emitError() << "failed to lookup target: " << error;
294
295 llvm::SourceMgr srcMgr;
296 // Copy buffer to ensure it's null terminated.
297 srcMgr.AddNewSourceBuffer(llvm::MemoryBuffer::getMemBufferCopy(isa), SMLoc());
298
299 const llvm::MCTargetOptions mcOptions;
300 std::unique_ptr<llvm::MCRegisterInfo> mri(target->createMCRegInfo(triple));
301 std::unique_ptr<llvm::MCAsmInfo> mai(
302 target->createMCAsmInfo(*mri, triple, mcOptions));
303 std::unique_ptr<llvm::MCSubtargetInfo> sti(
304 target->createMCSubtargetInfo(triple, chip, features));
305
306 llvm::MCContext ctx(triple, mai.get(), mri.get(), sti.get(), &srcMgr,
307 &mcOptions);
308 std::unique_ptr<llvm::MCObjectFileInfo> mofi(target->createMCObjectFileInfo(
309 ctx, /*PIC=*/false, /*LargeCodeModel=*/false));
310 ctx.setObjectFileInfo(mofi.get());
311
313 if (!llvm::sys::fs::current_path(cwd))
314 ctx.setCompilationDir(cwd);
315
316 std::unique_ptr<llvm::MCStreamer> mcStreamer;
317 std::unique_ptr<llvm::MCInstrInfo> mcii(target->createMCInstrInfo());
318
319 llvm::MCCodeEmitter *ce = target->createMCCodeEmitter(*mcii, ctx);
320 llvm::MCAsmBackend *mab = target->createMCAsmBackend(*sti, *mri, mcOptions);
321 mcStreamer.reset(target->createMCObjectStreamer(
322 triple, ctx, std::unique_ptr<llvm::MCAsmBackend>(mab),
323 mab->createObjectWriter(os), std::unique_ptr<llvm::MCCodeEmitter>(ce),
324 *sti));
325
326 std::unique_ptr<llvm::MCAsmParser> parser(
327 createMCAsmParser(srcMgr, ctx, *mcStreamer, *mai));
328 std::unique_ptr<llvm::MCTargetAsmParser> tap(
329 target->createMCAsmParser(*sti, *parser, *mcii, mcOptions));
330
331 if (!tap)
332 return emitError() << "assembler initialization error";
333
334 parser->setTargetParser(*tap);
335 parser->Run(false);
336 return std::move(result);
337}
338
339FailureOr<SmallVector<char, 0>>
340mlir::ROCDL::linkObjectCode(ArrayRef<char> objectCode, StringRef lldPath,
342 // Save the ISA binary to a temp file.
343 int tempIsaBinaryFd = -1;
344 SmallString<128> tempIsaBinaryFilename;
345 if (llvm::sys::fs::createTemporaryFile("kernel%%", "o", tempIsaBinaryFd,
346 tempIsaBinaryFilename))
347 return emitError()
348 << "failed to create a temporary file for dumping the ISA binary";
349
350 llvm::FileRemover cleanupIsaBinary(tempIsaBinaryFilename);
351 {
352 llvm::raw_fd_ostream tempIsaBinaryOs(tempIsaBinaryFd, true);
353 tempIsaBinaryOs << StringRef(objectCode.data(), objectCode.size());
354 tempIsaBinaryOs.flush();
355 }
356
357 // Create a temp file for HSA code object.
358 SmallString<128> tempHsacoFilename;
359 if (llvm::sys::fs::createTemporaryFile("kernel", "hsaco", tempHsacoFilename))
360 return emitError()
361 << "failed to create a temporary file for the HSA code object";
362
363 llvm::FileRemover cleanupHsaco(tempHsacoFilename);
364
365 int lldResult = llvm::sys::ExecuteAndWait(
366 lldPath,
367 {"ld.lld", "-shared", tempIsaBinaryFilename, "-o", tempHsacoFilename});
368 if (lldResult != 0)
369 return emitError() << "lld invocation failed";
370
371 // Load the HSA code object.
372 auto hsacoFile =
373 llvm::MemoryBuffer::getFile(tempHsacoFilename, /*IsText=*/false);
374 if (!hsacoFile)
375 return emitError()
376 << "failed to read the HSA code object from the temp file";
377
378 StringRef buffer = (*hsacoFile)->getBuffer();
379
380 return SmallVector<char, 0>(buffer.begin(), buffer.end());
381}
382
383FailureOr<SmallVector<char, 0>>
385 auto errCallback = [&]() { return getOperation().emitError(); };
386 // Assemble the ISA.
387 FailureOr<SmallVector<char, 0>> isaBinary = ROCDL::assembleIsa(
388 serializedISA, this->triple, this->chip, this->features, errCallback);
389
390 if (failed(isaBinary))
391 return failure();
392
393 // Link the object code.
395 llvm::sys::path::append(lldPath, "llvm", "bin", "ld.lld");
396 FailureOr<SmallVector<char, 0>> linkedCode =
397 ROCDL::linkObjectCode(*isaBinary, lldPath, errCallback);
398 if (failed(linkedCode))
399 return failure();
400
401 return linkedCode;
402}
403
404FailureOr<SmallVector<char, 0>> SerializeGPUModuleBase::moduleToObjectImpl(
405 const gpu::TargetOptions &targetOptions, llvm::Module &llvmModule) {
406 // Return LLVM IR if the compilation target is offload.
407#define DEBUG_TYPE "serialize-to-llvm"
408 LLVM_DEBUG({
409 llvm::dbgs() << "LLVM IR for module: "
410 << cast<gpu::GPUModuleOp>(getOperation()).getNameAttr() << "\n"
411 << llvmModule << "\n";
412 });
413#undef DEBUG_TYPE
414 if (targetOptions.getCompilationTarget() == gpu::CompilationTarget::Offload)
416
417 FailureOr<llvm::TargetMachine *> targetMachine = getOrCreateTargetMachine();
418 if (failed(targetMachine))
419 return getOperation().emitError()
420 << "target Machine unavailable for triple " << triple
421 << ", can't compile with LLVM";
422
423 // Translate the Module to ISA.
424 FailureOr<SmallString<0>> serializedISA =
425 translateModuleToISA(llvmModule, **targetMachine,
426 [&]() { return getOperation().emitError(); });
427 if (failed(serializedISA))
428 return getOperation().emitError() << "failed translating the module to ISA";
429
430#define DEBUG_TYPE "serialize-to-isa"
431 LLVM_DEBUG({
432 llvm::dbgs() << "ISA for module: "
433 << cast<gpu::GPUModuleOp>(getOperation()).getNameAttr() << "\n"
434 << *serializedISA << "\n";
435 });
436#undef DEBUG_TYPE
437 // Return ISA assembly code if the compilation target is assembly.
438 if (targetOptions.getCompilationTarget() == gpu::CompilationTarget::Assembly)
439 return SmallVector<char, 0>(serializedISA->begin(), serializedISA->end());
440
441 // Compiling to binary requires a valid ROCm path, fail if it's not found.
442 if (getToolkitPath().empty())
443 return getOperation().emitError()
444 << "invalid ROCm path, please set a valid path";
445
446 // Compile to binary.
447 return compileToBinary(*serializedISA);
448}
449
450#if LLVM_HAS_AMDGPU_TARGET
451namespace {
452class AMDGPUSerializer : public SerializeGPUModuleBase {
453public:
454 AMDGPUSerializer(Operation &module, ROCDLTargetAttr target,
455 const gpu::TargetOptions &targetOptions);
456
457 FailureOr<SmallVector<char, 0>>
458 moduleToObject(llvm::Module &llvmModule) override;
459
460private:
461 // Target options.
462 gpu::TargetOptions targetOptions;
463};
464} // namespace
465
466AMDGPUSerializer::AMDGPUSerializer(Operation &module, ROCDLTargetAttr target,
467 const gpu::TargetOptions &targetOptions)
468 : SerializeGPUModuleBase(module, target, targetOptions),
469 targetOptions(targetOptions) {}
470
471FailureOr<SmallVector<char, 0>>
472AMDGPUSerializer::moduleToObject(llvm::Module &llvmModule) {
473 return moduleToObjectImpl(targetOptions, llvmModule);
474}
475#endif // LLVM_HAS_AMDGPU_TARGET
476
477std::optional<mlir::gpu::SerializedObject>
478ROCDLTargetAttrImpl::serializeToObject(
479 Attribute attribute, Operation *module,
480 const gpu::TargetOptions &options) const {
481 assert(module && "The module must be non null.");
482 if (!module)
483 return std::nullopt;
484 if (!mlir::isa<gpu::GPUModuleOp>(module)) {
485 module->emitError("module must be a GPU module");
486 return std::nullopt;
487 }
488#if LLVM_HAS_AMDGPU_TARGET
489 AMDGPUSerializer serializer(*module, cast<ROCDLTargetAttr>(attribute),
490 options);
491 serializer.init();
492 std::optional<SmallVector<char, 0>> binary = serializer.run();
493 if (!binary)
494 return std::nullopt;
495 return gpu::SerializedObject{std::move(*binary)};
496#else
497 module->emitError("the `AMDGPU` target was not built. Please enable it when "
498 "building LLVM");
499 return std::nullopt;
500#endif // LLVM_HAS_AMDGPU_TARGET
501}
502
503Attribute
504ROCDLTargetAttrImpl::createObject(Attribute attribute, Operation *module,
505 const mlir::gpu::SerializedObject &object,
506 const gpu::TargetOptions &options) const {
507 gpu::CompilationTarget format = options.getCompilationTarget();
508 // If format is `fatbin` transform it to binary as `fatbin` is not yet
509 // supported.
510 gpu::KernelTableAttr kernels;
511 if (format > gpu::CompilationTarget::Binary) {
512 format = gpu::CompilationTarget::Binary;
513 kernels = ROCDL::getKernelMetadata(module, object.getObject());
514 }
515 DictionaryAttr properties{};
516 Builder builder(attribute.getContext());
517 StringAttr objectStr = builder.getStringAttr(
518 StringRef(object.getObject().data(), object.getObject().size()));
519 return builder.getAttr<gpu::ObjectAttr>(attribute, format, objectStr,
520 properties, kernels);
521}
return success()
#define __DEFAULT_ROCM_PATH__
Definition Target.cpp:51
static llvm::ManagedStatic< PassManagerOptions > options
Attributes are known-constant values of operations.
Definition Attributes.h:25
MLIRContext * getContext() const
Return the context this attribute belongs to.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
This class represents a diagnostic that is inflight and set to be reported.
LogicalResult loadBitcodeFilesFromList(llvm::LLVMContext &context, ArrayRef< Attribute > librariesToLink, SmallVector< std::unique_ptr< llvm::Module > > &llvmModules, bool failureOnError=true)
Loads multiple bitcode files.
FailureOr< llvm::TargetMachine * > getOrCreateTargetMachine()
Create the target machine based on the target triple and chip.
virtual void setDataLayoutAndTriple(llvm::Module &module)
Hook for computing the Datalayout.
virtual FailureOr< SmallVector< char, 0 > > moduleToObject(llvm::Module &llvmModule)
Serializes the LLVM IR bitcode to an object file, by default it serializes to LLVM bitcode.
StringRef triple
Target triple.
Operation & getOperation()
Returns the operation being serialized.
static FailureOr< SmallString< 0 > > translateModuleToISA(llvm::Module &llvmModule, llvm::TargetMachine &targetMachine, function_ref< InFlightDiagnostic()> emitError)
Translate LLVM module to textual ISA.
StringRef chip
Target chip.
ModuleToObject(Operation &module, StringRef triple, StringRef chip, StringRef features={}, int optLevel=3, function_ref< void(llvm::Module &)> initialLlvmIRCallback={}, function_ref< void(llvm::Module &)> linkedLlvmIRCallback={}, function_ref< void(llvm::Module &)> optimizedLlvmIRCallback={}, function_ref< void(StringRef)> isaCallback={})
Operation & module
Module to transform to a binary object.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
void appendDialectRegistry(const DialectRegistry &registry)
Append the contents of the given dialect registry to the registry associated with this context.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
Base class for all ROCDL serializations from GPU modules into binary strings.
Definition Utils.h:57
ROCDLTargetAttr getTarget() const
Returns the target attribute.
Definition Target.cpp:126
ArrayRef< Attribute > getLibrariesToLink() const
Returns the LLVM bitcode libraries to be linked.
Definition Target.cpp:130
AMDGCNLibraries deviceLibs
AMD GCN libraries to use when linking, the default is using none.
Definition Utils.h:120
ROCDLTargetAttr target
ROCDL target attribute.
Definition Utils.h:111
SerializeGPUModuleBase(Operation &module, ROCDLTargetAttr target, const gpu::TargetOptions &targetOptions={})
Initializes the toolkitPath with the path in targetOptions or if empty with the path in getROCMPath.
Definition Target.cpp:95
FailureOr< SmallVector< char, 0 > > moduleToObjectImpl(const gpu::TargetOptions &targetOptions, llvm::Module &llvmModule)
Default implementation of ModuleToObject::moduleToObject.
Definition Target.cpp:404
virtual FailureOr< SmallVector< char, 0 > > compileToBinary(StringRef serializedISA)
Compiles assembly to a binary.
Definition Target.cpp:384
virtual std::optional< SmallVector< std::unique_ptr< llvm::Module > > > loadBitcodeFiles(llvm::Module &module) override
Loads the bitcode files in fileList.
Definition Target.cpp:178
void addControlVariables(llvm::Module &module, AMDGCNLibraries libs, bool wave64, bool daz, bool finiteOnly, bool unsafeMath, bool fastMath, bool correctSqrt, StringRef abiVer)
Adds oclc control variables to the LLVM Module if needed.
Definition Target.cpp:229
std::string toolkitPath
ROCM toolkit path.
Definition Utils.h:114
SmallVector< Attribute > librariesToLink
List of LLVM bitcode files to link to.
Definition Utils.h:117
static void init()
Initializes the LLVM AMDGPU target by safely calling LLVMInitializeAMDGPU* methods if available.
Definition Target.cpp:112
StringRef getToolkitPath() const
Returns the ROCM toolkit path.
Definition Target.cpp:128
LogicalResult appendStandardLibs(AMDGCNLibraries libs)
Appends standard ROCm device libraries to fileList.
Definition Target.cpp:134
LogicalResult handleBitcodeFile(llvm::Module &module) override
Removes unnecessary metadata from the loaded bitcode files.
Definition Target.cpp:191
void handleModulePreLink(llvm::Module &module) override
Determines required Device Libraries and adds oclc control variables to the LLVM Module if needed.
Definition Target.cpp:204
This class represents a serialized object (GPU binary) with metadata (e.g.
This class serves as an opaque interface for passing options to the TargetAttrInterface methods.
CompilationTarget getCompilationTarget() const
Returns the compilation target.
FailureOr< SmallVector< char, 0 > > assembleIsa(StringRef isa, StringRef targetTriple, StringRef chip, StringRef features, function_ref< InFlightDiagnostic()> emitError)
Assembles ISA to an object code.
Definition Target.cpp:282
FailureOr< SmallVector< char, 0 > > linkObjectCode(ArrayRef< char > objectCode, StringRef lldPath, function_ref< InFlightDiagnostic()> emitError)
Definition Target.cpp:340
void registerROCDLTargetInterfaceExternalModels(DialectRegistry &registry)
Registers the TargetAttrInterface for the #rocdl.target attribute in the given registry.
Definition Target.cpp:70
AMDGCNLibraries
Helper enum for specifying the AMD GCN device libraries required for compilation.
Definition Utils.h:35
gpu::KernelTableAttr getKernelMetadata(Operation *gpuModule, ArrayRef< char > elfData={})
Returns a #gpu.kernel_table containing kernel metadata for each of the kernels in gpuModule.
Definition Utils.cpp:70
StringRef getROCMPath()
Searches & returns the path ROCM toolkit path, the search order is:
Definition Target.cpp:85
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::function_ref< Fn > function_ref
Definition LLVM.h:147