MLIR  19.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 
24 
25 #include "llvm/IR/Constants.h"
26 #include "llvm/MC/MCAsmBackend.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCCodeEmitter.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCInstrInfo.h"
31 #include "llvm/MC/MCObjectFileInfo.h"
32 #include "llvm/MC/MCObjectWriter.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCRegisterInfo.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/TargetRegistry.h"
38 #include "llvm/Support/FileSystem.h"
39 #include "llvm/Support/FileUtilities.h"
40 #include "llvm/Support/Path.h"
41 #include "llvm/Support/Program.h"
42 #include "llvm/Support/SourceMgr.h"
43 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/TargetParser/TargetParser.h"
45 
46 #include <cstdlib>
47 #include <optional>
48 
49 using namespace mlir;
50 using namespace mlir::ROCDL;
51 
52 #ifndef __DEFAULT_ROCM_PATH__
53 #define __DEFAULT_ROCM_PATH__ ""
54 #endif
55 
56 namespace {
57 // Implementation of the `TargetAttrInterface` model.
58 class ROCDLTargetAttrImpl
59  : public gpu::TargetAttrInterface::FallbackModel<ROCDLTargetAttrImpl> {
60 public:
61  std::optional<SmallVector<char, 0>>
62  serializeToObject(Attribute attribute, Operation *module,
63  const gpu::TargetOptions &options) const;
64 
65  Attribute createObject(Attribute attribute,
66  const SmallVector<char, 0> &object,
67  const gpu::TargetOptions &options) const;
68 };
69 } // namespace
70 
71 // Register the ROCDL dialect, the ROCDL translation and the target interface.
73  DialectRegistry &registry) {
74  registry.addExtension(+[](MLIRContext *ctx, ROCDL::ROCDLDialect *dialect) {
75  ROCDLTargetAttr::attachInterface<ROCDLTargetAttrImpl>(*ctx);
76  });
77 }
78 
80  MLIRContext &context) {
81  DialectRegistry registry;
83  context.appendDialectRegistry(registry);
84 }
85 
86 // Search for the ROCM path.
88  if (const char *var = std::getenv("ROCM_PATH"))
89  return var;
90  if (const char *var = std::getenv("ROCM_ROOT"))
91  return var;
92  if (const char *var = std::getenv("ROCM_HOME"))
93  return var;
94  return __DEFAULT_ROCM_PATH__;
95 }
96 
98  Operation &module, ROCDLTargetAttr target,
99  const gpu::TargetOptions &targetOptions)
100  : ModuleToObject(module, target.getTriple(), target.getChip(),
101  target.getFeatures(), target.getO()),
102  target(target), toolkitPath(targetOptions.getToolkitPath()),
103  fileList(targetOptions.getLinkFiles()) {
104 
105  // If `targetOptions` has an empty toolkitPath use `getROCMPath`
106  if (toolkitPath.empty())
108 
109  // Append the files in the target attribute.
110  if (ArrayAttr files = target.getLink())
111  for (Attribute attr : files.getValue())
112  if (auto file = dyn_cast<StringAttr>(attr))
113  fileList.push_back(file.str());
114 
115  // Append standard ROCm device bitcode libraries to the files to be loaded.
116  (void)appendStandardLibs();
117 }
118 
120  static llvm::once_flag initializeBackendOnce;
121  llvm::call_once(initializeBackendOnce, []() {
122  // If the `AMDGPU` LLVM target was built, initialize it.
123 #if MLIR_ROCM_CONVERSIONS_ENABLED == 1
124  LLVMInitializeAMDGPUTarget();
125  LLVMInitializeAMDGPUTargetInfo();
126  LLVMInitializeAMDGPUTargetMC();
127  LLVMInitializeAMDGPUAsmParser();
128  LLVMInitializeAMDGPUAsmPrinter();
129 #endif
130  });
131 }
132 
133 ROCDLTargetAttr SerializeGPUModuleBase::getTarget() const { return target; }
134 
136 
138  return fileList;
139 }
140 
142  StringRef pathRef = getToolkitPath();
143  if (!pathRef.empty()) {
145  path.insert(path.begin(), pathRef.begin(), pathRef.end());
146  llvm::sys::path::append(path, "amdgcn", "bitcode");
147  pathRef = StringRef(path.data(), path.size());
148  if (!llvm::sys::fs::is_directory(pathRef)) {
149  getOperation().emitRemark() << "ROCm amdgcn bitcode path: " << pathRef
150  << " does not exist or is not a directory.";
151  return failure();
152  }
153  StringRef isaVersion =
154  llvm::AMDGPU::getArchNameAMDGCN(llvm::AMDGPU::parseArchAMDGCN(chip));
155  isaVersion.consume_front("gfx");
156  return getCommonBitcodeLibs(fileList, path, isaVersion);
157  }
158  return success();
159 }
160 
161 std::optional<SmallVector<std::unique_ptr<llvm::Module>>>
165  true)))
166  return std::nullopt;
167  return std::move(bcFiles);
168 }
169 
171  // Some ROCM builds don't strip this like they should
172  if (auto *openclVersion = module.getNamedMetadata("opencl.ocl.version"))
173  module.eraseNamedMetadata(openclVersion);
174  // Stop spamming us with clang version numbers
175  if (auto *ident = module.getNamedMetadata("llvm.ident"))
176  module.eraseNamedMetadata(ident);
177  return success();
178 }
179 
181  [[maybe_unused]] std::optional<llvm::TargetMachine *> targetMachine =
183  assert(targetMachine && "expect a TargetMachine");
184  addControlVariables(module, target.hasWave64(), target.hasDaz(),
185  target.hasFiniteOnly(), target.hasUnsafeMath(),
186  target.hasFastMath(), target.hasCorrectSqrt(),
187  target.getAbi());
188 }
189 
190 // Get the paths of ROCm device libraries.
193  StringRef isaVersion) {
194  auto addLib = [&](StringRef path) -> bool {
195  if (!llvm::sys::fs::is_regular_file(path)) {
196  getOperation().emitRemark() << "Bitcode library path: " << path
197  << " does not exist or is not a file.\n";
198  return true;
199  }
200  libs.push_back(path.str());
201  return false;
202  };
203  auto getLibPath = [&libPath](Twine lib) {
204  auto baseSize = libPath.size();
205  llvm::sys::path::append(libPath, lib + ".bc");
206  std::string path(StringRef(libPath.data(), libPath.size()).str());
207  libPath.truncate(baseSize);
208  return path;
209  };
210 
211  // Add ROCm device libraries. Fail if any of the libraries is not found.
212  if (addLib(getLibPath("ocml")) || addLib(getLibPath("ockl")) ||
213  addLib(getLibPath("hip")) || addLib(getLibPath("opencl")) ||
214  addLib(getLibPath("oclc_isa_version_" + isaVersion)))
215  return failure();
216  return success();
217 }
218 
220  llvm::Module &module, bool wave64, bool daz, bool finiteOnly,
221  bool unsafeMath, bool fastMath, bool correctSqrt, StringRef abiVer) {
222  llvm::Type *i8Ty = llvm::Type::getInt8Ty(module.getContext());
223  auto addControlVariable = [i8Ty, &module](StringRef name, bool enable) {
224  llvm::GlobalVariable *controlVariable = new llvm::GlobalVariable(
225  module, i8Ty, true, llvm::GlobalValue::LinkageTypes::LinkOnceODRLinkage,
226  llvm::ConstantInt::get(i8Ty, enable), name, nullptr,
227  llvm::GlobalValue::ThreadLocalMode::NotThreadLocal, 4);
228  controlVariable->setVisibility(
229  llvm::GlobalValue::VisibilityTypes::ProtectedVisibility);
230  controlVariable->setAlignment(llvm::MaybeAlign(1));
231  controlVariable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
232  };
233  addControlVariable("__oclc_finite_only_opt", finiteOnly || fastMath);
234  addControlVariable("__oclc_unsafe_math_opt", unsafeMath || fastMath);
235  addControlVariable("__oclc_daz_opt", daz || fastMath);
236  addControlVariable("__oclc_correctly_rounded_sqrt32",
237  correctSqrt && !fastMath);
238  addControlVariable("__oclc_wavefrontsize64", wave64);
239 
240  llvm::Type *i32Ty = llvm::Type::getInt32Ty(module.getContext());
241  int abi = 500;
242  abiVer.getAsInteger(0, abi);
243  llvm::GlobalVariable *abiVersion = new llvm::GlobalVariable(
244  module, i32Ty, true, llvm::GlobalValue::LinkageTypes::LinkOnceODRLinkage,
245  llvm::ConstantInt::get(i32Ty, abi), "__oclc_ABI_version", nullptr,
246  llvm::GlobalValue::ThreadLocalMode::NotThreadLocal, 4);
247  abiVersion->setVisibility(
248  llvm::GlobalValue::VisibilityTypes::ProtectedVisibility);
249  abiVersion->setAlignment(llvm::MaybeAlign(4));
250  abiVersion->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
251 }
252 
253 std::optional<SmallVector<char, 0>>
255  auto loc = getOperation().getLoc();
256 
257  StringRef targetTriple = this->triple;
258 
259  SmallVector<char, 0> result;
260  llvm::raw_svector_ostream os(result);
261 
262  llvm::Triple triple(llvm::Triple::normalize(targetTriple));
263  std::string error;
264  const llvm::Target *target =
265  llvm::TargetRegistry::lookupTarget(triple.normalize(), error);
266  if (!target) {
267  emitError(loc, Twine("failed to lookup target: ") + error);
268  return std::nullopt;
269  }
270 
271  llvm::SourceMgr srcMgr;
272  srcMgr.AddNewSourceBuffer(llvm::MemoryBuffer::getMemBuffer(isa), SMLoc());
273 
274  const llvm::MCTargetOptions mcOptions;
275  std::unique_ptr<llvm::MCRegisterInfo> mri(
276  target->createMCRegInfo(targetTriple));
277  std::unique_ptr<llvm::MCAsmInfo> mai(
278  target->createMCAsmInfo(*mri, targetTriple, mcOptions));
279  mai->setRelaxELFRelocations(true);
280  std::unique_ptr<llvm::MCSubtargetInfo> sti(
281  target->createMCSubtargetInfo(targetTriple, chip, features));
282 
283  llvm::MCContext ctx(triple, mai.get(), mri.get(), sti.get(), &srcMgr,
284  &mcOptions);
285  std::unique_ptr<llvm::MCObjectFileInfo> mofi(target->createMCObjectFileInfo(
286  ctx, /*PIC=*/false, /*LargeCodeModel=*/false));
287  ctx.setObjectFileInfo(mofi.get());
288 
289  SmallString<128> cwd;
290  if (!llvm::sys::fs::current_path(cwd))
291  ctx.setCompilationDir(cwd);
292 
293  std::unique_ptr<llvm::MCStreamer> mcStreamer;
294  std::unique_ptr<llvm::MCInstrInfo> mcii(target->createMCInstrInfo());
295 
296  llvm::MCCodeEmitter *ce = target->createMCCodeEmitter(*mcii, ctx);
297  llvm::MCAsmBackend *mab = target->createMCAsmBackend(*sti, *mri, mcOptions);
298  mcStreamer.reset(target->createMCObjectStreamer(
299  triple, ctx, std::unique_ptr<llvm::MCAsmBackend>(mab),
300  mab->createObjectWriter(os), std::unique_ptr<llvm::MCCodeEmitter>(ce),
301  *sti, mcOptions.MCRelaxAll, mcOptions.MCIncrementalLinkerCompatible,
302  /*DWARFMustBeAtTheEnd*/ false));
303  mcStreamer->setUseAssemblerInfoForParsing(true);
304 
305  std::unique_ptr<llvm::MCAsmParser> parser(
306  createMCAsmParser(srcMgr, ctx, *mcStreamer, *mai));
307  std::unique_ptr<llvm::MCTargetAsmParser> tap(
308  target->createMCAsmParser(*sti, *parser, *mcii, mcOptions));
309 
310  if (!tap) {
311  emitError(loc, "assembler initialization error");
312  return {};
313  }
314 
315  parser->setTargetParser(*tap);
316  parser->Run(false);
317 
318  return result;
319 }
320 
321 #if MLIR_ROCM_CONVERSIONS_ENABLED == 1
322 namespace {
323 class AMDGPUSerializer : public SerializeGPUModuleBase {
324 public:
325  AMDGPUSerializer(Operation &module, ROCDLTargetAttr target,
326  const gpu::TargetOptions &targetOptions);
327 
328  gpu::GPUModuleOp getOperation();
329 
330  // Compile to HSA.
331  std::optional<SmallVector<char, 0>>
332  compileToBinary(const std::string &serializedISA);
333 
334  std::optional<SmallVector<char, 0>>
335  moduleToObject(llvm::Module &llvmModule) override;
336 
337 private:
338  // Target options.
339  gpu::TargetOptions targetOptions;
340 };
341 } // namespace
342 
343 AMDGPUSerializer::AMDGPUSerializer(Operation &module, ROCDLTargetAttr target,
344  const gpu::TargetOptions &targetOptions)
345  : SerializeGPUModuleBase(module, target, targetOptions),
346  targetOptions(targetOptions) {}
347 
348 gpu::GPUModuleOp AMDGPUSerializer::getOperation() {
349  return dyn_cast<gpu::GPUModuleOp>(&SerializeGPUModuleBase::getOperation());
350 }
351 
352 std::optional<SmallVector<char, 0>>
353 AMDGPUSerializer::compileToBinary(const std::string &serializedISA) {
354  // Assemble the ISA.
355  std::optional<SmallVector<char, 0>> isaBinary = assembleIsa(serializedISA);
356 
357  if (!isaBinary) {
358  getOperation().emitError() << "Failed during ISA assembling.";
359  return std::nullopt;
360  }
361 
362  // Save the ISA binary to a temp file.
363  int tempIsaBinaryFd = -1;
364  SmallString<128> tempIsaBinaryFilename;
365  if (llvm::sys::fs::createTemporaryFile("kernel%%", "o", tempIsaBinaryFd,
366  tempIsaBinaryFilename)) {
367  getOperation().emitError()
368  << "Failed to create a temporary file for dumping the ISA binary.";
369  return std::nullopt;
370  }
371  llvm::FileRemover cleanupIsaBinary(tempIsaBinaryFilename);
372  {
373  llvm::raw_fd_ostream tempIsaBinaryOs(tempIsaBinaryFd, true);
374  tempIsaBinaryOs << StringRef(isaBinary->data(), isaBinary->size());
375  tempIsaBinaryOs.flush();
376  }
377 
378  // Create a temp file for HSA code object.
379  SmallString<128> tempHsacoFilename;
380  if (llvm::sys::fs::createTemporaryFile("kernel", "hsaco",
381  tempHsacoFilename)) {
382  getOperation().emitError()
383  << "Failed to create a temporary file for the HSA code object.";
384  return std::nullopt;
385  }
386  llvm::FileRemover cleanupHsaco(tempHsacoFilename);
387 
388  llvm::SmallString<128> lldPath(toolkitPath);
389  llvm::sys::path::append(lldPath, "llvm", "bin", "ld.lld");
390  int lldResult = llvm::sys::ExecuteAndWait(
391  lldPath,
392  {"ld.lld", "-shared", tempIsaBinaryFilename, "-o", tempHsacoFilename});
393  if (lldResult != 0) {
394  getOperation().emitError() << "lld invocation failed.";
395  return std::nullopt;
396  }
397 
398  // Load the HSA code object.
399  auto hsacoFile =
400  llvm::MemoryBuffer::getFile(tempHsacoFilename, /*IsText=*/false);
401  if (!hsacoFile) {
402  getOperation().emitError()
403  << "Failed to read the HSA code object from the temp file.";
404  return std::nullopt;
405  }
406 
407  StringRef buffer = (*hsacoFile)->getBuffer();
408 
409  return SmallVector<char, 0>(buffer.begin(), buffer.end());
410 }
411 
412 std::optional<SmallVector<char, 0>>
413 AMDGPUSerializer::moduleToObject(llvm::Module &llvmModule) {
414  // Return LLVM IR if the compilation target is offload.
415 #define DEBUG_TYPE "serialize-to-llvm"
416  LLVM_DEBUG({
417  llvm::dbgs() << "LLVM IR for module: " << getOperation().getNameAttr()
418  << "\n"
419  << llvmModule << "\n";
420  });
421 #undef DEBUG_TYPE
422  if (targetOptions.getCompilationTarget() == gpu::CompilationTarget::Offload)
423  return SerializeGPUModuleBase::moduleToObject(llvmModule);
424 
425  std::optional<llvm::TargetMachine *> targetMachine =
426  getOrCreateTargetMachine();
427  if (!targetMachine) {
428  getOperation().emitError() << "Target Machine unavailable for triple "
429  << triple << ", can't compile with LLVM\n";
430  return std::nullopt;
431  }
432 
433  // Translate the Module to ISA.
434  std::optional<std::string> serializedISA =
435  translateToISA(llvmModule, **targetMachine);
436  if (!serializedISA) {
437  getOperation().emitError() << "Failed translating the module to ISA.";
438  return std::nullopt;
439  }
440 #define DEBUG_TYPE "serialize-to-isa"
441  LLVM_DEBUG({
442  llvm::dbgs() << "ISA for module: " << getOperation().getNameAttr() << "\n"
443  << *serializedISA << "\n";
444  });
445 #undef DEBUG_TYPE
446  // Return ISA assembly code if the compilation target is assembly.
447  if (targetOptions.getCompilationTarget() == gpu::CompilationTarget::Assembly)
448  return SmallVector<char, 0>(serializedISA->begin(), serializedISA->end());
449 
450  // Compile to binary.
451  return compileToBinary(*serializedISA);
452 }
453 #endif // MLIR_ROCM_CONVERSIONS_ENABLED
454 
455 std::optional<SmallVector<char, 0>> ROCDLTargetAttrImpl::serializeToObject(
456  Attribute attribute, Operation *module,
457  const gpu::TargetOptions &options) const {
458  assert(module && "The module must be non null.");
459  if (!module)
460  return std::nullopt;
461  if (!mlir::isa<gpu::GPUModuleOp>(module)) {
462  module->emitError("Module must be a GPU module.");
463  return std::nullopt;
464  }
465 #if MLIR_ROCM_CONVERSIONS_ENABLED == 1
466  AMDGPUSerializer serializer(*module, cast<ROCDLTargetAttr>(attribute),
467  options);
468  serializer.init();
469  return serializer.run();
470 #else
471  module->emitError("The `AMDGPU` target was not built. Please enable it when "
472  "building LLVM.");
473  return std::nullopt;
474 #endif // MLIR_ROCM_CONVERSIONS_ENABLED == 1
475 }
476 
477 Attribute
478 ROCDLTargetAttrImpl::createObject(Attribute attribute,
479  const SmallVector<char, 0> &object,
480  const gpu::TargetOptions &options) const {
481  gpu::CompilationTarget format = options.getCompilationTarget();
482  Builder builder(attribute.getContext());
483  return builder.getAttr<gpu::ObjectAttr>(
484  attribute,
485  format > gpu::CompilationTarget::Binary ? gpu::CompilationTarget::Binary
486  : format,
487  builder.getStringAttr(StringRef(object.data(), object.size())), nullptr);
488 }
#define __DEFAULT_ROCM_PATH__
Definition: Target.cpp:53
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.
Definition: Attributes.cpp:37
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:50
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
void addExtension(std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
StringRef features
Target features.
virtual std::optional< 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.
std::optional< llvm::TargetMachine * > getOrCreateTargetMachine()
Create the target machine based on the target triple and chip.
Operation & getOperation()
Returns the operation being serialized.
LogicalResult loadBitcodeFilesFromList(llvm::LLVMContext &context, ArrayRef< std::string > fileList, SmallVector< std::unique_ptr< llvm::Module >> &llvmModules, bool failureOnError=true)
Loads multiple bitcode files.
StringRef chip
Target chip.
Operation & module
Module to transform to a binary object.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
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
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:216
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:223
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:268
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
Definition: Operation.cpp:289
Base class for all ROCDL serializations from GPU modules into binary strings.
Definition: Utils.h:32
ROCDLTargetAttr getTarget() const
Returns the target attribute.
Definition: Target.cpp:133
ArrayRef< std::string > getFileList() const
Returns the bitcode files to be loaded.
Definition: Target.cpp:137
void addControlVariables(llvm::Module &module, bool wave64, bool daz, bool finiteOnly, bool unsafeMath, bool fastMath, bool correctSqrt, StringRef abiVer)
Adds oclc control variables to the LLVM module.
Definition: Target.cpp:219
ROCDLTargetAttr target
ROCDL target attribute.
Definition: Utils.h:80
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:97
virtual std::optional< SmallVector< std::unique_ptr< llvm::Module > > > loadBitcodeFiles(llvm::Module &module) override
Loads the bitcode files in fileList.
Definition: Target.cpp:162
std::optional< SmallVector< char, 0 > > assembleIsa(StringRef isa)
Returns the assembled ISA.
Definition: Target.cpp:254
SmallVector< std::string > fileList
List of LLVM bitcode files to link to.
Definition: Utils.h:86
std::string toolkitPath
ROCM toolkit path.
Definition: Utils.h:83
LogicalResult appendStandardLibs()
Appends standard ROCm device libraries like ocml.bc, ockl.bc, etc.
Definition: Target.cpp:141
LogicalResult getCommonBitcodeLibs(llvm::SmallVector< std::string > &libs, SmallVector< char, 256 > &libPath, StringRef isaVersion)
Appends the paths of common ROCm device libraries to libs.
Definition: Target.cpp:191
static void init()
Initializes the LLVM AMDGPU target by safely calling LLVMInitializeAMDGPU* methods if available.
Definition: Target.cpp:119
StringRef getToolkitPath() const
Returns the ROCM toolkit path.
Definition: Target.cpp:135
LogicalResult handleBitcodeFile(llvm::Module &module) override
Removes unnecessary metadata from the loaded bitcode files.
Definition: Target.cpp:170
void handleModulePreLink(llvm::Module &module) override
Adds oclc control variables to the LLVM module.
Definition: Target.cpp:180
This class serves as an opaque interface for passing options to the TargetAttrInterface methods.
void registerROCDLTargetInterfaceExternalModels(DialectRegistry &registry)
Registers the TargetAttrInterface for the #rocdl.target attribute in the given registry.
Definition: Target.cpp:72
StringRef getROCMPath()
Searches & returns the path ROCM toolkit path, the search order is:
Definition: Target.cpp:87
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26