25
25
#include " llvm/IR/PassManager.h"
26
26
#include " llvm/IR/Verifier.h"
27
27
#include " llvm/LTO/LTO.h"
28
+ #include " llvm/LTO/legacy/UpdateCompilerUsed.h"
28
29
#include " llvm/MC/SubtargetFeature.h"
29
30
#include " llvm/Passes/PassBuilder.h"
30
31
#include " llvm/Support/Error.h"
@@ -275,6 +276,19 @@ Expected<const Target *> initAndLookupTarget(Config &C, Module &Mod) {
275
276
276
277
}
277
278
279
+ static void handleAsmUndefinedRefs (Module &Mod, TargetMachine &TM) {
280
+ // Collect the list of undefined symbols used in asm and update
281
+ // llvm.compiler.used to prevent optimization to drop these from the output.
282
+ StringSet<> AsmUndefinedRefs;
283
+ object::IRObjectFile::CollectAsmUndefinedRefs (
284
+ Triple (Mod.getTargetTriple ()), Mod.getModuleInlineAsm (),
285
+ [&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
286
+ if (Flags & object::BasicSymbolRef::SF_Undefined)
287
+ AsmUndefinedRefs.insert (Name);
288
+ });
289
+ updateCompilerUsed (Mod, TM, AsmUndefinedRefs);
290
+ }
291
+
278
292
Error lto::backend (Config &C, AddOutputFn AddOutput,
279
293
unsigned ParallelCodeGenParallelismLevel,
280
294
std::unique_ptr<Module> Mod) {
@@ -285,6 +299,8 @@ Error lto::backend(Config &C, AddOutputFn AddOutput,
285
299
std::unique_ptr<TargetMachine> TM =
286
300
createTargetMachine (C, Mod->getTargetTriple (), *TOrErr);
287
301
302
+ handleAsmUndefinedRefs (*Mod, *TM);
303
+
288
304
if (!C.CodeGenOnly )
289
305
if (!opt (C, TM.get (), 0 , *Mod, /* IsThinLto=*/ false ))
290
306
return Error ();
@@ -310,6 +326,8 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddOutputFn AddOutput,
310
326
std::unique_ptr<TargetMachine> TM =
311
327
createTargetMachine (Conf, Mod.getTargetTriple (), *TOrErr);
312
328
329
+ handleAsmUndefinedRefs (Mod, *TM);
330
+
313
331
if (Conf.CodeGenOnly ) {
314
332
codegen (Conf, TM.get (), AddOutput, Task, Mod);
315
333
return Error ();
0 commit comments