23 #include "llvm/IR/LegacyPassManager.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/TargetSelect.h"
26 #include "llvm/Target/TargetMachine.h"
31 #define DEBUG_TYPE "serialize-to-blob"
43 std::optional<std::string>
44 gpu::SerializeToBlobPass::translateToISA(llvm::Module &llvmModule,
45 llvm::TargetMachine &targetMachine) {
46 llvmModule.setDataLayout(targetMachine.createDataLayout());
48 if (
failed(optimizeLlvm(llvmModule, targetMachine)))
51 std::string targetISA;
52 llvm::raw_string_ostream stream(targetISA);
55 llvm::buffer_ostream pstream(stream);
56 llvm::legacy::PassManager codegenPasses;
58 if (targetMachine.addPassesToEmitFile(codegenPasses, pstream,
nullptr,
59 llvm::CodeGenFileType::AssemblyFile))
62 codegenPasses.run(llvmModule);
70 llvm::LLVMContext llvmContext;
71 std::unique_ptr<llvm::Module> llvmModule = translateToLLVMIR(llvmContext);
73 return signalPassFailure();
76 std::unique_ptr<llvm::TargetMachine> targetMachine = createTargetMachine();
78 return signalPassFailure();
80 std::optional<std::string> maybeTargetISA =
81 translateToISA(*llvmModule, *targetMachine);
83 if (!maybeTargetISA.has_value())
84 return signalPassFailure();
86 std::string targetISA = std::move(*maybeTargetISA);
89 llvm::dbgs() <<
"ISA for module: " << getOperation().getNameAttr() <<
"\n";
90 llvm::dbgs() << targetISA <<
"\n";
95 std::unique_ptr<std::vector<char>> blob = serializeISA(targetISA);
97 return signalPassFailure();
102 getOperation()->setAttr(gpuBinaryAnnotation, attr);
107 llvm::TargetMachine &targetMachine) {
108 int optLevel = this->optLevel.getValue();
109 if (optLevel < 0 || optLevel > 3)
110 return getOperation().emitError()
111 <<
"invalid optimization level " << optLevel;
113 targetMachine.setOptLevel(
static_cast<llvm::CodeGenOptLevel
>(optLevel));
117 auto error = transformer(&llvmModule);
120 llvm::handleAllErrors(
121 std::move(error), [&mlirError](
const llvm::ErrorInfoBase &ei) {
122 mlirError <<
"could not optimize LLVM IR: " << ei.message();
129 std::unique_ptr<llvm::TargetMachine>
130 gpu::SerializeToBlobPass::createTargetMachine() {
131 Location loc = getOperation().getLoc();
133 const llvm::Target *target =
134 llvm::TargetRegistry::lookupTarget(triple, error);
136 emitError(loc, Twine(
"failed to lookup target: ") + error);
139 llvm::TargetMachine *machine =
140 target->createTargetMachine(triple, chip, features, {}, {});
142 emitError(loc,
"failed to create target machine");
146 return std::unique_ptr<llvm::TargetMachine>{machine};
149 std::unique_ptr<llvm::Module>
152 "LLVMDialectModule");
static MLIRContext * getContext(OpFoldResult val)
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Pass to transform an operation of a specific type.
This class provides an efficient unique identifier for a specific C++ type.
Base pass class to serialize kernel functions through LLVM into user-specified IR and add the resulti...
void runOnOperation() final
The polymorphic API that runs the pass over the currently held operation.
SerializeToBlobPass(TypeID passID)
virtual std::unique_ptr< llvm::Module > translateToLLVMIR(llvm::LLVMContext &llvmContext)
Translates the 'getOperation()' result to an LLVM module.
virtual LogicalResult optimizeLlvm(llvm::Module &llvmModule, llvm::TargetMachine &targetMachine)
Hook allowing the application of optimizations before codegen By default, does nothing.
std::string getDefaultGpuBinaryAnnotation()
Returns the default annotation name for GPU binary blobs.
Include the generated interface declarations.
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.
std::function< llvm::Error(llvm::Module *)> makeOptimizingTransformer(unsigned optLevel, unsigned sizeLevel, llvm::TargetMachine *targetMachine)
Create a module transformer function for MLIR ExecutionEngine that runs LLVM IR passes corresponding ...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
std::unique_ptr< llvm::Module > translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, llvm::StringRef name="LLVMDialectModule")
Translate operation that satisfies LLVM dialect module requirements into an LLVM IR module living in ...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.