MLIR 22.0.0git
ModuleToBinary.cpp
Go to the documentation of this file.
1//===- ModuleToBinary.cpp - Transforms GPU modules to GPU binaries ----------=//
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 file implements the `GpuModuleToBinaryPass` pass, transforming GPU
10// modules into GPU binaries.
11//
12//===----------------------------------------------------------------------===//
13
15
17
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringSwitch.h"
20
21using namespace mlir;
22using namespace mlir::gpu;
23
24namespace mlir {
25#define GEN_PASS_DEF_GPUMODULETOBINARYPASS
26#include "mlir/Dialect/GPU/Transforms/Passes.h.inc"
27} // namespace mlir
28
29namespace {
30class GpuModuleToBinaryPass
31 : public impl::GpuModuleToBinaryPassBase<GpuModuleToBinaryPass> {
32public:
33 using Base::Base;
34 void runOnOperation() final;
35};
36} // namespace
37
38void GpuModuleToBinaryPass::runOnOperation() {
39 RewritePatternSet patterns(&getContext());
40 auto targetFormat =
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);
47 if (!targetFormat)
48 getOperation()->emitError() << "Invalid format specified.";
49
50 // Lazy symbol table builder callback.
51 std::optional<SymbolTable> parentTable;
52 auto lazyTableBuilder = [&]() -> SymbolTable * {
53 // Build the table if it has not been built.
54 if (!parentTable) {
55 Operation *table = SymbolTable::getNearestSymbolTable(getOperation());
56 // It's up to the target attribute to determine if failing to find a
57 // symbol table is an error.
58 if (!table)
59 return nullptr;
60 parentTable = SymbolTable(table);
61 }
62 return &parentTable.value();
63 };
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),
71 targetOptions)))
72 return signalPassFailure();
73}
74
75namespace {
76LogicalResult moduleSerializer(GPUModuleOp op,
77 OffloadingLLVMTranslationAttrInterface handler,
78 const TargetOptions &targetOptions) {
79 OpBuilder builder(op->getContext());
80 SmallVector<Attribute> objects;
81 // Fail if there are no target attributes
82 if (!op.getTargetsAttr())
83 return op.emitError("the module has no target attributes");
84 // Serialize all targets.
85 for (auto targetAttr : op.getTargetsAttr()) {
86 assert(targetAttr && "Target attribute cannot be null.");
87 auto target = dyn_cast<gpu::TargetAttrInterface>(targetAttr);
88 assert(target &&
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.");
94 return failure();
95 }
96
97 Attribute object =
98 target.createObject(op, *serializedModule, targetOptions);
99 if (!object) {
100 op.emitError("An error happened while creating the object.");
101 return failure();
102 }
103 objects.push_back(object);
104 }
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));
113 op->erase();
114 return success();
115}
116} // namespace
117
119 Operation *op, OffloadingLLVMTranslationAttrInterface handler,
120 const gpu::TargetOptions &targetOptions) {
121 for (Region &region : op->getRegions())
122 for (Block &block : region.getBlocks())
123 for (auto module :
124 llvm::make_early_inc_range(block.getOps<GPUModuleOp>()))
125 if (failed(moduleSerializer(module, handler, targetOptions)))
126 return failure();
127 return success();
128}
return success()
b getContext())
Block represents an ordered list of Operations.
Definition Block.h:33
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Definition Operation.h:677
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
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.
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:561
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns