|
14 | 14 | #include "mlir/Target/LLVM/ModuleToObject.h" |
15 | 15 |
|
16 | 16 | #include "mlir/ExecutionEngine/OptUtils.h" |
| 17 | +#include "mlir/IR/BuiltinAttributeInterfaces.h" |
| 18 | +#include "mlir/IR/BuiltinAttributes.h" |
17 | 19 | #include "mlir/IR/BuiltinOps.h" |
18 | 20 | #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" |
19 | 21 | #include "mlir/Target/LLVMIR/Export.h" |
|
25 | 27 | #include "llvm/Linker/Linker.h" |
26 | 28 | #include "llvm/MC/TargetRegistry.h" |
27 | 29 | #include "llvm/Support/FileSystem.h" |
| 30 | +#include "llvm/Support/MemoryBuffer.h" |
28 | 31 | #include "llvm/Support/Path.h" |
29 | 32 | #include "llvm/Support/SourceMgr.h" |
30 | 33 | #include "llvm/Support/raw_ostream.h" |
@@ -89,22 +92,53 @@ ModuleToObject::loadBitcodeFile(llvm::LLVMContext &context, StringRef path) { |
89 | 92 | } |
90 | 93 |
|
91 | 94 | LogicalResult ModuleToObject::loadBitcodeFilesFromList( |
92 | | - llvm::LLVMContext &context, ArrayRef<std::string> fileList, |
| 95 | + llvm::LLVMContext &context, ArrayRef<Attribute> librariesToLink, |
93 | 96 | SmallVector<std::unique_ptr<llvm::Module>> &llvmModules, |
94 | 97 | bool failureOnError) { |
95 | | - for (const std::string &str : fileList) { |
96 | | - // Test if the path exists, if it doesn't abort. |
97 | | - StringRef pathRef = StringRef(str.data(), str.size()); |
98 | | - if (!llvm::sys::fs::is_regular_file(pathRef)) { |
| 98 | + for (Attribute linkLib : librariesToLink) { |
| 99 | + // Attributes in this list can be either list of file paths using |
| 100 | + // StringAttr, or a resource attribute pointing to the LLVM bitcode in |
| 101 | + // memory. |
| 102 | + if (auto filePath = dyn_cast<StringAttr>(linkLib)) { |
| 103 | + // Test if the path exists, if it doesn't abort. |
| 104 | + if (!llvm::sys::fs::is_regular_file(filePath.strref())) { |
| 105 | + getOperation().emitError() |
| 106 | + << "File path: " << filePath << " does not exist or is not a file."; |
| 107 | + return failure(); |
| 108 | + } |
| 109 | + // Load the file or abort on error. |
| 110 | + if (auto bcFile = loadBitcodeFile(context, filePath)) |
| 111 | + llvmModules.push_back(std::move(bcFile)); |
| 112 | + else if (failureOnError) |
| 113 | + return failure(); |
| 114 | + continue; |
| 115 | + } |
| 116 | + if (auto blobAttr = dyn_cast<BlobAttr>(linkLib)) { |
| 117 | + // Load the file or abort on error. |
| 118 | + llvm::SMDiagnostic error; |
| 119 | + ArrayRef<char> data = blobAttr.getData(); |
| 120 | + std::unique_ptr<llvm::MemoryBuffer> buffer = |
| 121 | + llvm::MemoryBuffer::getMemBuffer(StringRef(data.data(), data.size()), |
| 122 | + "blobLinkedLib", |
| 123 | + /*RequiresNullTerminator=*/false); |
| 124 | + std::unique_ptr<llvm::Module> mod = |
| 125 | + getLazyIRModule(std::move(buffer), error, context); |
| 126 | + if (mod) { |
| 127 | + if (failed(handleBitcodeFile(*mod))) |
| 128 | + return failure(); |
| 129 | + llvmModules.push_back(std::move(mod)); |
| 130 | + } else if (failureOnError) { |
| 131 | + getOperation().emitError() |
| 132 | + << "Couldn't load LLVM library for linking: " << error.getMessage(); |
| 133 | + return failure(); |
| 134 | + } |
| 135 | + continue; |
| 136 | + } |
| 137 | + if (failureOnError) { |
99 | 138 | getOperation().emitError() |
100 | | - << "File path: " << pathRef << " does not exist or is not a file.\n"; |
| 139 | + << "Unknown attribute describing LLVM library to load: " << linkLib; |
101 | 140 | return failure(); |
102 | 141 | } |
103 | | - // Load the file or abort on error. |
104 | | - if (auto bcFile = loadBitcodeFile(context, pathRef)) |
105 | | - llvmModules.push_back(std::move(bcFile)); |
106 | | - else if (failureOnError) |
107 | | - return failure(); |
108 | 142 | } |
109 | 143 | return success(); |
110 | 144 | } |
|
0 commit comments