18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringSwitch.h"
25#define GEN_PASS_DEF_GPUMODULETOBINARYPASS
26#include "mlir/Dialect/GPU/Transforms/Passes.h.inc"
30class GpuModuleToBinaryPass
34 void runOnOperation()
final;
38void GpuModuleToBinaryPass::runOnOperation() {
41 llvm::StringSwitch<std::optional<CompilationTarget>>(compilationTarget)
42 .Cases({
"offloading",
"llvm"}, CompilationTarget::Offload)
43 .Cases({
"assembly",
"isa"}, CompilationTarget::Assembly)
44 .Cases({
"binary",
"bin"}, CompilationTarget::Binary)
45 .Cases({
"fatbinary",
"fatbin"}, CompilationTarget::Fatbin)
46 .Default(std::nullopt);
48 getOperation()->emitError() <<
"Invalid format specified.";
51 std::optional<SymbolTable> parentTable;
52 auto lazyTableBuilder = [&]() -> SymbolTable * {
60 parentTable = SymbolTable(table);
62 return &parentTable.value();
64 SmallVector<Attribute> librariesToLink;
65 for (
const std::string &path : linkFiles)
66 librariesToLink.push_back(StringAttr::get(&
getContext(), path));
67 TargetOptions targetOptions(toolkitPath, librariesToLink, cmdOptions,
68 elfSection, *targetFormat, lazyTableBuilder);
70 getOperation(), OffloadingLLVMTranslationAttrInterface(
nullptr),
72 return signalPassFailure();
76LogicalResult moduleSerializer(GPUModuleOp op,
77 OffloadingLLVMTranslationAttrInterface handler,
78 const TargetOptions &targetOptions) {
79 OpBuilder builder(op->getContext());
80 SmallVector<Attribute> objects;
82 if (!op.getTargetsAttr())
83 return op.emitError(
"the module has no target attributes");
85 for (
auto targetAttr : op.getTargetsAttr()) {
86 assert(targetAttr &&
"Target attribute cannot be null.");
87 auto target = dyn_cast<gpu::TargetAttrInterface>(targetAttr);
89 "Target attribute doesn't implements `TargetAttrInterface`.");
90 std::optional<SmallVector<char, 0>> serializedModule =
91 target.serializeToObject(op, targetOptions);
92 if (!serializedModule) {
93 op.emitError(
"An error happened while serializing the module.");
98 target.createObject(op, *serializedModule, targetOptions);
100 op.emitError(
"An error happened while creating the object.");
103 objects.push_back(
object);
105 if (
auto moduleHandler =
106 dyn_cast_or_null<OffloadingLLVMTranslationAttrInterface>(
107 op.getOffloadingHandlerAttr());
108 !handler && moduleHandler)
109 handler = moduleHandler;
110 builder.setInsertionPointAfter(op);
111 gpu::BinaryOp::create(builder, op.getLoc(), op.getName(), handler,
112 builder.getArrayAttr(objects));
119 Operation *op, OffloadingLLVMTranslationAttrInterface handler,
122 for (
Block &block : region.getBlocks())
124 llvm::make_early_inc_range(block.getOps<GPUModuleOp>()))
125 if (failed(moduleSerializer(module, handler, targetOptions)))
Block represents an ordered list of Operations.
Operation is the basic unit of execution within MLIR.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
static Operation * getNearestSymbolTable(Operation *from)
Returns the nearest symbol table from a given operation from.
This class serves as an opaque interface for passing options to the TargetAttrInterface methods.
LogicalResult transformGpuModulesToBinaries(Operation *op, OffloadingLLVMTranslationAttrInterface handler=nullptr, const gpu::TargetOptions &options={})
Searches for all GPU modules in op and transforms them into GPU binary operations.
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns