-
Notifications
You must be signed in to change notification settings - Fork 25
Add a custom gpu-module-to-binary pass.
#525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Hardcode84
merged 26 commits into
iree-org:main
from
Hardcode84:water-dump-intermediates-clear
Dec 8, 2025
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
aa42d43
pass stub
Hardcode84 0d9db3e
WIP
Hardcode84 f8c72ba
wip
Hardcode84 2c68a85
style
Hardcode84 794d01a
optimization
Hardcode84 84bdcbc
opt level
Hardcode84 f8b4250
rename
Hardcode84 3589b95
ISA
Hardcode84 cf6f17a
FailureOr
Hardcode84 5e59c43
HSACO
Hardcode84 13af7e9
HSACO 2
Hardcode84 9a402dd
init target
Hardcode84 287493c
clenaup
Hardcode84 ea43fba
dump-intermediates
Hardcode84 aaa4eaa
dump hsaco
Hardcode84 4154ee9
renamings
Hardcode84 65a2256
override
Hardcode84 d2e9e66
test
Hardcode84 7bc1338
create dump dir
Hardcode84 df0f21c
cleanup
Hardcode84 421a360
cleanup
Hardcode84 91f8555
override hsaco
Hardcode84 e00427e
update test
Hardcode84 9b27a3f
add lib
Hardcode84 78160ae
cleanup
Hardcode84 7f134f6
fixes
Hardcode84 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,143 @@ | ||||||
| // Copyright 2025 The Wave Authors | ||||||
| // | ||||||
| // Licensed under the Apache License v2.0 with LLVM Exceptions. | ||||||
| // See https://llvm.org/LICENSE.txt for license information. | ||||||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
|
|
||||||
| #include "AssembleISA.h" | ||||||
|
|
||||||
| #include "llvm/MC/MCAsmBackend.h" | ||||||
| #include "llvm/MC/MCAsmInfo.h" | ||||||
| #include "llvm/MC/MCCodeEmitter.h" | ||||||
| #include "llvm/MC/MCContext.h" | ||||||
| #include "llvm/MC/MCInstrInfo.h" | ||||||
| #include "llvm/MC/MCObjectFileInfo.h" | ||||||
| #include "llvm/MC/MCObjectWriter.h" | ||||||
| #include "llvm/MC/MCParser/MCAsmParser.h" | ||||||
| #include "llvm/MC/MCParser/MCTargetAsmParser.h" | ||||||
| #include "llvm/MC/MCRegisterInfo.h" | ||||||
| #include "llvm/MC/MCStreamer.h" | ||||||
| #include "llvm/MC/MCSubtargetInfo.h" | ||||||
| #include "llvm/MC/TargetRegistry.h" | ||||||
| #include "llvm/Support/FileSystem.h" | ||||||
| #include "llvm/Support/FileUtilities.h" | ||||||
| #include "llvm/Support/MemoryBuffer.h" | ||||||
| #include "llvm/Support/Path.h" | ||||||
| #include "llvm/Support/Program.h" | ||||||
| #include "llvm/Support/SourceMgr.h" | ||||||
| #include "llvm/Support/TargetSelect.h" | ||||||
| #include "llvm/Support/raw_ostream.h" | ||||||
| #include "llvm/Target/TargetMachine.h" | ||||||
|
|
||||||
| using namespace mlir; | ||||||
|
|
||||||
| namespace mlir::water { | ||||||
|
|
||||||
| void initializeAMDGPUTarget() { | ||||||
| static bool initialized = []() { | ||||||
| LLVMInitializeAMDGPUTarget(); | ||||||
| LLVMInitializeAMDGPUTargetInfo(); | ||||||
| LLVMInitializeAMDGPUTargetMC(); | ||||||
| LLVMInitializeAMDGPUAsmParser(); | ||||||
| LLVMInitializeAMDGPUAsmPrinter(); | ||||||
| return true; | ||||||
| }(); | ||||||
| (void)initialized; | ||||||
| } | ||||||
|
|
||||||
| FailureOr<SmallVector<char, 0>> | ||||||
| assembleISAToHSACO(Operation *op, StringRef isa, | ||||||
| llvm::TargetMachine &targetMachine, StringRef toolkitPath) { | ||||||
| initializeAMDGPUTarget(); | ||||||
|
|
||||||
| // Step 1: Assemble ISA to object file using MC infrastructure. | ||||||
| llvm::Triple triple = targetMachine.getTargetTriple(); | ||||||
| std::string error; | ||||||
| const llvm::Target *target = | ||||||
| llvm::TargetRegistry::lookupTarget(triple, error); | ||||||
| if (!target) | ||||||
| return op->emitError() << "Failed to lookup target: " << error; | ||||||
|
|
||||||
| // Set up MC infrastructure. | ||||||
| llvm::SourceMgr srcMgr; | ||||||
| srcMgr.AddNewSourceBuffer(llvm::MemoryBuffer::getMemBuffer(isa), | ||||||
| llvm::SMLoc()); | ||||||
|
|
||||||
| const llvm::MCTargetOptions mcOptions; | ||||||
| std::unique_ptr<llvm::MCRegisterInfo> mri(target->createMCRegInfo(triple)); | ||||||
| std::unique_ptr<llvm::MCAsmInfo> mai( | ||||||
| target->createMCAsmInfo(*mri, triple, mcOptions)); | ||||||
| std::unique_ptr<llvm::MCSubtargetInfo> sti( | ||||||
| target->createMCSubtargetInfo(triple, targetMachine.getTargetCPU(), | ||||||
| targetMachine.getTargetFeatureString())); | ||||||
|
|
||||||
| SmallVector<char, 0> objectBuffer; | ||||||
| llvm::raw_svector_ostream os(objectBuffer); | ||||||
|
|
||||||
| llvm::MCContext ctx(triple, mai.get(), mri.get(), sti.get(), &srcMgr, | ||||||
| &mcOptions); | ||||||
| std::unique_ptr<llvm::MCObjectFileInfo> mofi(target->createMCObjectFileInfo( | ||||||
| ctx, /*PIC=*/false, /*LargeCodeModel=*/false)); | ||||||
| ctx.setObjectFileInfo(mofi.get()); | ||||||
|
|
||||||
| std::unique_ptr<llvm::MCInstrInfo> mcii(target->createMCInstrInfo()); | ||||||
| llvm::MCCodeEmitter *ce = target->createMCCodeEmitter(*mcii, ctx); | ||||||
| llvm::MCAsmBackend *mab = target->createMCAsmBackend(*sti, *mri, mcOptions); | ||||||
| std::unique_ptr<llvm::MCStreamer> mcStreamer(target->createMCObjectStreamer( | ||||||
| triple, ctx, std::unique_ptr<llvm::MCAsmBackend>(mab), | ||||||
| mab->createObjectWriter(os), std::unique_ptr<llvm::MCCodeEmitter>(ce), | ||||||
| *sti)); | ||||||
|
|
||||||
| std::unique_ptr<llvm::MCAsmParser> parser( | ||||||
| createMCAsmParser(srcMgr, ctx, *mcStreamer, *mai)); | ||||||
| std::unique_ptr<llvm::MCTargetAsmParser> tap( | ||||||
| target->createMCAsmParser(*sti, *parser, *mcii, mcOptions)); | ||||||
|
|
||||||
| if (!tap) | ||||||
| return op->emitError("Assembler initialization error"); | ||||||
|
|
||||||
| parser->setTargetParser(*tap); | ||||||
| if (parser->Run(false)) | ||||||
| return op->emitError("Assembly parsing failed"); | ||||||
|
|
||||||
| // Step 2: Link object file to create HSACO. | ||||||
| // Write object to temporary file. | ||||||
| int tempObjFd = -1; | ||||||
| SmallString<128> tempObjFilename; | ||||||
| if (llvm::sys::fs::createTemporaryFile("kernel%%", "o", tempObjFd, | ||||||
Hardcode84 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| tempObjFilename)) | ||||||
| return op->emitError("Failed to create temporary file for object"); | ||||||
|
|
||||||
| llvm::FileRemover cleanupObj(tempObjFilename); | ||||||
| { | ||||||
| llvm::raw_fd_ostream tempObjOs(tempObjFd, true); | ||||||
| tempObjOs << StringRef(objectBuffer.data(), objectBuffer.size()); | ||||||
| tempObjOs.flush(); | ||||||
| } | ||||||
|
|
||||||
| // Create temporary file for HSACO. | ||||||
| SmallString<128> tempHsacoFilename; | ||||||
| if (llvm::sys::fs::createTemporaryFile("kernel", "hsaco", tempHsacoFilename)) | ||||||
| return op->emitError("Failed to create temporary file for HSACO"); | ||||||
|
|
||||||
| llvm::FileRemover cleanupHsaco(tempHsacoFilename); | ||||||
|
|
||||||
| // Link using ld.lld. | ||||||
| SmallString<128> lldPath(toolkitPath); | ||||||
| llvm::sys::path::append(lldPath, "llvm", "bin", "ld.lld"); | ||||||
| int lldResult = llvm::sys::ExecuteAndWait( | ||||||
| lldPath, {"ld.lld", "-shared", tempObjFilename, "-o", tempHsacoFilename}); | ||||||
| if (lldResult != 0) | ||||||
| return op->emitError("ld.lld invocation failed"); | ||||||
Hardcode84 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| // Read HSACO file. | ||||||
| auto hsacoFile = | ||||||
| llvm::MemoryBuffer::getFile(tempHsacoFilename, /*IsText=*/false); | ||||||
| if (!hsacoFile) | ||||||
| return op->emitError("Failed to read HSACO from temporary file"); | ||||||
|
|
||||||
| StringRef buffer = (*hsacoFile)->getBuffer(); | ||||||
| return SmallVector<char, 0>(buffer.begin(), buffer.end()); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the prev comment, I can it, but it will be a lot of pointer casts. |
||||||
| } | ||||||
|
|
||||||
| } // namespace mlir::water | ||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // Copyright 2025 The Wave Authors | ||
| // | ||
| // Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
|
||
| #ifndef WATER_LIB_TRANSFORMS_ASSEMBLEISA_H | ||
| #define WATER_LIB_TRANSFORMS_ASSEMBLEISA_H | ||
|
|
||
| #include "mlir/IR/Operation.h" | ||
| #include "mlir/Support/LogicalResult.h" | ||
| #include "llvm/ADT/SmallVector.h" | ||
| #include "llvm/ADT/StringRef.h" | ||
|
|
||
| namespace llvm { | ||
| class TargetMachine; | ||
| } // namespace llvm | ||
|
|
||
| namespace mlir::water { | ||
|
|
||
| /// Initializes the LLVM AMDGPU target. Safe to call multiple times. | ||
| void initializeAMDGPUTarget(); | ||
|
|
||
| /// Assembles ISA (assembly code) to HSACO (HSA Code Object) binary. | ||
| /// | ||
| /// This function: | ||
| /// 1. Parses the ISA using LLVM MC infrastructure | ||
| /// 2. Assembles it to an ELF object file | ||
| /// 3. Links the object file using ld.lld to create an HSACO | ||
| /// | ||
| /// \param op Operation for error reporting | ||
| /// \param isa Assembly code to assemble | ||
| /// \param targetMachine Target machine for MC infrastructure setup | ||
| /// \param toolkitPath Path to toolkit containing ld.lld | ||
| /// \return Binary data of the HSACO file, or failure | ||
| FailureOr<SmallVector<char, 0>> | ||
| assembleISAToHSACO(Operation *op, StringRef isa, | ||
| llvm::TargetMachine &targetMachine, StringRef toolkitPath); | ||
|
|
||
| } // namespace mlir::water | ||
|
|
||
| #endif // WATER_LIB_TRANSFORMS_ASSEMBLEISA_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The preferred data type for raw memory is
unsigned charorstd::byte.edit: I now see it used everywhere like this in the MLIR codebase. I don't understand why.
Using
unsigned charorstd::byteovercharis done to disambiguate strings which are null terminated from raw bytes, mostly to avoid their accidental use in C string apis.In this case it might be worth disambiguating because hsaco has both a serialized and a text representation. Which I would expect to be
const char*andunsigned char*respectively.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, all llvm classes like
MemoryBufferare usingchar*.