@@ -39,32 +39,34 @@ ModuleToObject::ModuleToObject(Operation &module, StringRef triple,
3939 : module(module ), triple(triple), chip(chip), features(features),
4040 optLevel(optLevel) {}
4141
42+ ModuleToObject::~ModuleToObject () = default ;
43+
4244Operation &ModuleToObject::getOperation () { return module ; }
4345
44- std::unique_ptr<llvm::TargetMachine> ModuleToObject::createTargetMachine () {
45- std::string error;
46+ std::optional<llvm::TargetMachine *>
47+ ModuleToObject::getOrCreateTargetMachine () {
48+ if (targetMachine)
49+ return targetMachine.get ();
4650 // Load the target.
51+ std::string error;
4752 const llvm::Target *target =
4853 llvm::TargetRegistry::lookupTarget (triple, error);
4954 if (!target) {
50- getOperation ().emitError () << " Failed to lookup target: " << error;
51- return {};
55+ getOperation ().emitError ()
56+ << " Failed to lookup target for triple '" << triple << " ' " << error;
57+ return std::nullopt ;
5258 }
5359
5460 // Create the target machine using the target.
55- llvm::TargetMachine *machine =
56- target->createTargetMachine (triple, chip, features, {}, {});
57- if (!machine) {
58- getOperation ().emitError () << " Failed to create the target machine." ;
59- return {};
60- }
61- return std::unique_ptr<llvm::TargetMachine>{machine};
61+ targetMachine.reset (
62+ target->createTargetMachine (triple, chip, features, {}, {}));
63+ if (!targetMachine)
64+ return std::nullopt ;
65+ return targetMachine.get ();
6266}
6367
6468std::unique_ptr<llvm::Module>
65- ModuleToObject::loadBitcodeFile (llvm::LLVMContext &context,
66- llvm::TargetMachine &targetMachine,
67- StringRef path) {
69+ ModuleToObject::loadBitcodeFile (llvm::LLVMContext &context, StringRef path) {
6870 llvm::SMDiagnostic error;
6971 std::unique_ptr<llvm::Module> library =
7072 llvm::getLazyIRFileModule (path, error, context);
@@ -73,15 +75,14 @@ ModuleToObject::loadBitcodeFile(llvm::LLVMContext &context,
7375 << " , error: " << error.getMessage ();
7476 return nullptr ;
7577 }
76- if (failed (handleBitcodeFile (*library, targetMachine ))) {
78+ if (failed (handleBitcodeFile (*library))) {
7779 return nullptr ;
7880 }
7981 return library;
8082}
8183
8284LogicalResult ModuleToObject::loadBitcodeFilesFromList (
83- llvm::LLVMContext &context, llvm::TargetMachine &targetMachine,
84- ArrayRef<std::string> fileList,
85+ llvm::LLVMContext &context, ArrayRef<std::string> fileList,
8586 SmallVector<std::unique_ptr<llvm::Module>> &llvmModules,
8687 bool failureOnError) {
8788 for (const std::string &str : fileList) {
@@ -93,7 +94,7 @@ LogicalResult ModuleToObject::loadBitcodeFilesFromList(
9394 return failure ();
9495 }
9596 // Load the file or abort on error.
96- if (auto bcFile = loadBitcodeFile (context, targetMachine, pathRef))
97+ if (auto bcFile = loadBitcodeFile (context, pathRef))
9798 llvmModules.push_back (std::move (bcFile));
9899 else if (failureOnError)
99100 return failure ();
@@ -137,16 +138,22 @@ ModuleToObject::linkFiles(llvm::Module &module,
137138}
138139
139140LogicalResult ModuleToObject::optimizeModule (llvm::Module &module ,
140- llvm::TargetMachine &targetMachine,
141+
141142 int optLevel) {
142143 if (optLevel < 0 || optLevel > 3 )
143144 return getOperation ().emitError ()
144145 << " Invalid optimization level: " << optLevel << " ." ;
145146
146- targetMachine.setOptLevel (static_cast <llvm::CodeGenOptLevel>(optLevel));
147+ std::optional<llvm::TargetMachine *> targetMachine =
148+ getOrCreateTargetMachine ();
149+ if (!targetMachine)
150+ return getOperation ().emitError ()
151+ << " Target Machine unavailable for triple " << triple
152+ << " , can't optimize with LLVM\n " ;
153+ (*targetMachine)->setOptLevel (static_cast <llvm::CodeGenOptLevel>(optLevel));
147154
148155 auto transformer =
149- makeOptimizingTransformer (optLevel, /* sizeLevel=*/ 0 , & targetMachine);
156+ makeOptimizingTransformer (optLevel, /* sizeLevel=*/ 0 , * targetMachine);
150157 auto error = transformer (&module );
151158 if (error) {
152159 InFlightDiagnostic mlirError = getOperation ().emitError ();
@@ -178,9 +185,19 @@ ModuleToObject::translateToISA(llvm::Module &llvmModule,
178185 return stream.str ();
179186}
180187
188+ void ModuleToObject::setDataLayoutAndTriple (llvm::Module &module ) {
189+ // Create the target machine.
190+ std::optional<llvm::TargetMachine *> targetMachine =
191+ getOrCreateTargetMachine ();
192+ if (targetMachine) {
193+ // Set the data layout and target triple of the module.
194+ module .setDataLayout ((*targetMachine)->createDataLayout ());
195+ module .setTargetTriple ((*targetMachine)->getTargetTriple ().getTriple ());
196+ }
197+ }
198+
181199std::optional<SmallVector<char , 0 >>
182- ModuleToObject::moduleToObject (llvm::Module &llvmModule,
183- llvm::TargetMachine &targetMachine) {
200+ ModuleToObject::moduleToObject (llvm::Module &llvmModule) {
184201 SmallVector<char , 0 > binaryData;
185202 // Write the LLVM module bitcode to a buffer.
186203 llvm::raw_svector_ostream outputStream (binaryData);
@@ -196,32 +213,24 @@ std::optional<SmallVector<char, 0>> ModuleToObject::run() {
196213 getOperation ().emitError () << " Failed creating the llvm::Module." ;
197214 return std::nullopt ;
198215 }
199-
200- // Create the target machine.
201- std::unique_ptr<llvm::TargetMachine> targetMachine = createTargetMachine ();
202- if (!targetMachine)
203- return std::nullopt ;
204-
205- // Set the data layout and target triple of the module.
206- llvmModule->setDataLayout (targetMachine->createDataLayout ());
207- llvmModule->setTargetTriple (targetMachine->getTargetTriple ().getTriple ());
216+ setDataLayoutAndTriple (*llvmModule);
208217
209218 // Link bitcode files.
210- handleModulePreLink (*llvmModule, *targetMachine );
219+ handleModulePreLink (*llvmModule);
211220 {
212- auto libs = loadBitcodeFiles (*llvmModule, *targetMachine );
221+ auto libs = loadBitcodeFiles (*llvmModule);
213222 if (!libs)
214223 return std::nullopt ;
215224 if (!libs->empty ())
216225 if (failed (linkFiles (*llvmModule, std::move (*libs))))
217226 return std::nullopt ;
218- handleModulePostLink (*llvmModule, *targetMachine );
227+ handleModulePostLink (*llvmModule);
219228 }
220229
221230 // Optimize the module.
222- if (failed (optimizeModule (*llvmModule, *targetMachine, optLevel)))
231+ if (failed (optimizeModule (*llvmModule, optLevel)))
223232 return std::nullopt ;
224233
225234 // Return the serialized object.
226- return moduleToObject (*llvmModule, *targetMachine );
235+ return moduleToObject (*llvmModule);
227236}
0 commit comments