xref: /llvm-project-15.0.7/lld/ELF/LTO.cpp (revision fdcca8cd)
1 //===- LTO.cpp ------------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "LTO.h"
11 #include "Config.h"
12 #include "Driver.h"
13 #include "Error.h"
14 #include "InputFiles.h"
15 #include "Symbols.h"
16 #include "llvm/Analysis/AliasAnalysis.h"
17 #include "llvm/Analysis/CGSCCPassManager.h"
18 #include "llvm/Analysis/LoopPassManager.h"
19 #include "llvm/Analysis/TargetLibraryInfo.h"
20 #include "llvm/Analysis/TargetTransformInfo.h"
21 #include "llvm/Bitcode/ReaderWriter.h"
22 #include "llvm/CodeGen/CommandFlags.h"
23 #include "llvm/CodeGen/ParallelCG.h"
24 #include "llvm/IR/AutoUpgrade.h"
25 #include "llvm/IR/LegacyPassManager.h"
26 #include "llvm/IR/PassManager.h"
27 #include "llvm/IR/Verifier.h"
28 #include "llvm/LTO/UpdateCompilerUsed.h"
29 #include "llvm/Linker/IRMover.h"
30 #include "llvm/Passes/PassBuilder.h"
31 #include "llvm/Support/StringSaver.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Target/TargetMachine.h"
34 #include "llvm/Transforms/IPO.h"
35 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
36 #include "llvm/Transforms/Utils/ModuleUtils.h"
37 
38 using namespace llvm;
39 using namespace llvm::object;
40 using namespace llvm::ELF;
41 
42 using namespace lld;
43 using namespace lld::elf;
44 
45 // This is for use when debugging LTO.
46 static void saveLtoObjectFile(StringRef Buffer, unsigned I, bool Many) {
47   SmallString<128> Filename = Config->OutputFile;
48   if (Many)
49     Filename += utostr(I);
50   Filename += ".lto.o";
51   std::error_code EC;
52   raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::F_None);
53   check(EC);
54   OS << Buffer;
55 }
56 
57 // This is for use when debugging LTO.
58 static void saveBCFile(Module &M, StringRef Suffix) {
59   std::error_code EC;
60   raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,
61                     sys::fs::OpenFlags::F_None);
62   check(EC);
63   WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
64 }
65 
66 static void runNewCustomLtoPasses(Module &M, TargetMachine &TM) {
67   PassBuilder PB(&TM);
68 
69   AAManager AA;
70 
71   // Parse a custom AA pipeline if asked to.
72   if (!PB.parseAAPipeline(AA, Config->LtoAAPipeline)) {
73     error("Unable to parse AA pipeline description: " + Config->LtoAAPipeline);
74     return;
75   }
76 
77   LoopAnalysisManager LAM;
78   FunctionAnalysisManager FAM;
79   CGSCCAnalysisManager CGAM;
80   ModuleAnalysisManager MAM;
81 
82   // Register the AA manager first so that our version is the one used.
83   FAM.registerPass([&] { return std::move(AA); });
84 
85   // Register all the basic analyses with the managers.
86   PB.registerModuleAnalyses(MAM);
87   PB.registerCGSCCAnalyses(CGAM);
88   PB.registerFunctionAnalyses(FAM);
89   PB.registerLoopAnalyses(LAM);
90   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
91 
92   ModulePassManager MPM;
93   if (!Config->DisableVerify)
94     MPM.addPass(VerifierPass());
95 
96   // Now, add all the passes we've been requested to.
97   if (!PB.parsePassPipeline(MPM, Config->LtoNewPmPasses)) {
98     error("unable to parse pass pipeline description: " +
99           Config->LtoNewPmPasses);
100     return;
101   }
102 
103   if (!Config->DisableVerify)
104     MPM.addPass(VerifierPass());
105   MPM.run(M, MAM);
106 }
107 
108 static void runOldLtoPasses(Module &M, TargetMachine &TM) {
109   // Note that the gold plugin has a similar piece of code, so
110   // it is probably better to move this code to a common place.
111   legacy::PassManager LtoPasses;
112   LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
113   PassManagerBuilder PMB;
114   PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
115   PMB.Inliner = createFunctionInliningPass();
116   PMB.VerifyInput = PMB.VerifyOutput = !Config->DisableVerify;
117   PMB.LoopVectorize = true;
118   PMB.SLPVectorize = true;
119   PMB.OptLevel = Config->LtoO;
120   PMB.populateLTOPassManager(LtoPasses);
121   LtoPasses.run(M);
122 }
123 
124 static void runLTOPasses(Module &M, TargetMachine &TM) {
125   if (!Config->LtoNewPmPasses.empty()) {
126     // The user explicitly asked for a set of passes to be run.
127     // This needs the new PM to work as there's no clean way to
128     // pass a set of passes to run in the legacy PM.
129     runNewCustomLtoPasses(M, TM);
130     if (HasError)
131       return;
132   } else {
133     // Run the 'default' set of LTO passes. This code still uses
134     // the legacy PM as the new one is not the default.
135     runOldLtoPasses(M, TM);
136   }
137 
138   if (Config->SaveTemps)
139     saveBCFile(M, ".lto.opt.bc");
140 }
141 
142 static bool shouldInternalize(const SmallPtrSet<GlobalValue *, 8> &Used,
143                               Symbol *S, GlobalValue *GV) {
144   if (S->IsUsedInRegularObj || Used.count(GV))
145     return false;
146   return !S->includeInDynsym();
147 }
148 
149 BitcodeCompiler::BitcodeCompiler()
150     : Combined(new llvm::Module("ld-temp.o", Driver->Context)),
151       Mover(*Combined) {}
152 
153 static void undefine(Symbol *S) {
154   replaceBody<Undefined>(S, S->body()->getName(), STV_DEFAULT, S->body()->Type);
155 }
156 
157 static void handleUndefinedAsmRefs(const BasicSymbolRef &Sym, GlobalValue *GV,
158                                    StringSet<> &AsmUndefinedRefs) {
159   // GV associated => not an assembly symbol, bail out.
160   if (GV)
161     return;
162 
163   // This is an undefined reference to a symbol in asm. We put that in
164   // compiler.used, so that we can preserve it from being dropped from
165   // the output, without necessarily preventing its internalization.
166   SmallString<64> Name;
167   raw_svector_ostream OS(Name);
168   Sym.printName(OS);
169   AsmUndefinedRefs.insert(Name.str());
170 }
171 
172 void BitcodeCompiler::add(BitcodeFile &F) {
173   std::unique_ptr<IRObjectFile> Obj = std::move(F.Obj);
174   std::vector<GlobalValue *> Keep;
175   unsigned BodyIndex = 0;
176   ArrayRef<Symbol *> Syms = F.getSymbols();
177 
178   Module &M = Obj->getModule();
179   if (M.getDataLayoutStr().empty())
180     fatal("invalid bitcode file: " + F.getName() + " has no datalayout");
181 
182   // Discard non-compatible debug infos if necessary.
183   M.materializeMetadata();
184   UpgradeDebugInfo(M);
185 
186   // If a symbol appears in @llvm.used, the linker is required
187   // to treat the symbol as there is a reference to the symbol
188   // that it cannot see. Therefore, we can't internalize.
189   SmallPtrSet<GlobalValue *, 8> Used;
190   collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false);
191 
192   for (const BasicSymbolRef &Sym : Obj->symbols()) {
193     uint32_t Flags = Sym.getFlags();
194     GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
195     if (GV && GV->hasAppendingLinkage())
196       Keep.push_back(GV);
197     if (BitcodeFile::shouldSkip(Flags))
198       continue;
199     Symbol *S = Syms[BodyIndex++];
200     if (Flags & BasicSymbolRef::SF_Undefined) {
201       handleUndefinedAsmRefs(Sym, GV, AsmUndefinedRefs);
202       continue;
203     }
204     auto *B = dyn_cast<DefinedBitcode>(S->body());
205     if (!B || B->File != &F)
206       continue;
207 
208     // We collect the set of symbols we want to internalize here
209     // and change the linkage after the IRMover executed, i.e. after
210     // we imported the symbols and satisfied undefined references
211     // to it. We can't just change linkage here because otherwise
212     // the IRMover will just rename the symbol.
213     if (GV && shouldInternalize(Used, S, GV))
214       InternalizedSyms.insert(GV->getName());
215 
216     // At this point we know that either the combined LTO object will provide a
217     // definition of a symbol, or we will internalize it. In either case, we
218     // need to undefine the symbol. In the former case, the real definition
219     // needs to be able to replace the original definition without conflicting.
220     // In the latter case, we need to allow the combined LTO object to provide a
221     // definition with the same name, for example when doing parallel codegen.
222     undefine(S);
223 
224     if (!GV)
225       // Module asm symbol.
226       continue;
227 
228     switch (GV->getLinkage()) {
229     default:
230       break;
231     case llvm::GlobalValue::LinkOnceAnyLinkage:
232       GV->setLinkage(GlobalValue::WeakAnyLinkage);
233       break;
234     case llvm::GlobalValue::LinkOnceODRLinkage:
235       GV->setLinkage(GlobalValue::WeakODRLinkage);
236       break;
237     }
238 
239     Keep.push_back(GV);
240   }
241 
242   if (Error E = Mover.move(Obj->takeModule(), Keep,
243                            [](GlobalValue &, IRMover::ValueAdder) {})) {
244     handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
245       fatal("failed to link module " + F.getName() + ": " + EIB.message());
246     });
247   }
248 }
249 
250 static void internalize(GlobalValue &GV) {
251   assert(!GV.hasLocalLinkage() &&
252          "Trying to internalize a symbol with local linkage!");
253   GV.setLinkage(GlobalValue::InternalLinkage);
254 }
255 
256 std::vector<std::unique_ptr<InputFile>> BitcodeCompiler::runSplitCodegen(
257     const std::function<std::unique_ptr<TargetMachine>()> &TMFactory) {
258   unsigned NumThreads = Config->LtoJobs;
259   OwningData.resize(NumThreads);
260 
261   std::list<raw_svector_ostream> OSs;
262   std::vector<raw_pwrite_stream *> OSPtrs;
263   for (SmallString<0> &Obj : OwningData) {
264     OSs.emplace_back(Obj);
265     OSPtrs.push_back(&OSs.back());
266   }
267 
268   splitCodeGen(std::move(Combined), OSPtrs, {}, TMFactory);
269 
270   std::vector<std::unique_ptr<InputFile>> ObjFiles;
271   for (SmallString<0> &Obj : OwningData)
272     ObjFiles.push_back(createObjectFile(
273         MemoryBufferRef(Obj, "LLD-INTERNAL-combined-lto-object")));
274 
275   if (Config->SaveTemps)
276     for (unsigned I = 0; I < NumThreads; ++I)
277       saveLtoObjectFile(OwningData[I], I, NumThreads > 1);
278 
279   return ObjFiles;
280 }
281 
282 // Merge all the bitcode files we have seen, codegen the result
283 // and return the resulting ObjectFile.
284 std::vector<std::unique_ptr<InputFile>> BitcodeCompiler::compile() {
285   TheTriple = Combined->getTargetTriple();
286   for (const auto &Name : InternalizedSyms) {
287     GlobalValue *GV = Combined->getNamedValue(Name.first());
288     assert(GV);
289     internalize(*GV);
290   }
291 
292   std::string Msg;
293   const Target *T = TargetRegistry::lookupTarget(TheTriple, Msg);
294   if (!T)
295     fatal("target not found: " + Msg);
296   TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
297 
298   // lld supports the new relocations.
299   Options.RelaxELFRelocations = true;
300 
301   Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
302 
303   auto CreateTargetMachine = [&]() {
304     return std::unique_ptr<TargetMachine>(
305         T->createTargetMachine(TheTriple, "", "", Options, R));
306   };
307 
308   std::unique_ptr<TargetMachine> TM = CreateTargetMachine();
309 
310   // Update llvm.compiler.used so that optimizations won't strip
311   // off AsmUndefinedReferences.
312   updateCompilerUsed(*Combined, *TM, AsmUndefinedRefs);
313 
314   if (Config->SaveTemps)
315     saveBCFile(*Combined, ".lto.bc");
316 
317   runLTOPasses(*Combined, *TM);
318   if (HasError)
319     return {};
320 
321   return runSplitCodegen(CreateTargetMachine);
322 }
323