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
31 :
public impl::GpuModuleToBinaryPassBase<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()
49 <<
"Invalid format specified: '" << compilationTarget
50 <<
"' (expected one of: offloading, llvm, assembly, isa, binary, bin, "
52 return signalPassFailure();
56 std::optional<SymbolTable> parentTable;
57 auto lazyTableBuilder = [&]() -> SymbolTable * {
65 parentTable = SymbolTable(table);
67 return &parentTable.value();
69 SmallVector<Attribute> librariesToLink;
70 for (
const std::string &path : linkFiles)
71 librariesToLink.push_back(StringAttr::get(&
getContext(), path));
72 TargetOptions targetOptions(toolkitPath, librariesToLink, cmdOptions,
73 elfSection, *targetFormat, lazyTableBuilder);
75 getOperation(), OffloadingLLVMTranslationAttrInterface(
nullptr),
77 return signalPassFailure();
81LogicalResult moduleSerializer(GPUModuleOp op,
82 OffloadingLLVMTranslationAttrInterface handler,
83 const TargetOptions &targetOptions) {
84 OpBuilder builder(op->getContext());
85 SmallVector<Attribute> objects;
87 if (!op.getTargetsAttr())
88 return op.emitError(
"the module has no target attributes");
90 for (
auto targetAttr : op.getTargetsAttr()) {
91 assert(targetAttr &&
"Target attribute cannot be null.");
92 auto target = dyn_cast<gpu::TargetAttrInterface>(targetAttr);
94 "Target attribute doesn't implements `TargetAttrInterface`.");
95 std::optional<SerializedObject> serializedModule =
96 target.serializeToObject(op, targetOptions);
97 if (!serializedModule) {
98 op.emitError(
"An error happened while serializing the module.");
103 target.createObject(op, *serializedModule, targetOptions);
105 op.emitError(
"An error happened while creating the object.");
108 objects.push_back(
object);
110 if (
auto moduleHandler =
111 dyn_cast_or_null<OffloadingLLVMTranslationAttrInterface>(
112 op.getOffloadingHandlerAttr());
113 !handler && moduleHandler)
114 handler = moduleHandler;
115 builder.setInsertionPointAfter(op);
116 gpu::BinaryOp::create(builder, op.getLoc(), op.getName(), handler,
117 builder.getArrayAttr(objects));
124 Operation *op, OffloadingLLVMTranslationAttrInterface handler,
127 for (
Block &block : region.getBlocks())
129 llvm::make_early_inc_range(block.getOps<GPUModuleOp>()))
130 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.