xref: /llvm-project-15.0.7/lld/ELF/LTO.cpp (revision ca5793ea)
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 "Error.h"
13 #include "InputFiles.h"
14 #include "Symbols.h"
15 #include "llvm/Analysis/TargetLibraryInfo.h"
16 #include "llvm/Analysis/TargetTransformInfo.h"
17 #include "llvm/Bitcode/ReaderWriter.h"
18 #include "llvm/CodeGen/CommandFlags.h"
19 #include "llvm/CodeGen/ParallelCG.h"
20 #include "llvm/IR/LegacyPassManager.h"
21 #include "llvm/Linker/IRMover.h"
22 #include "llvm/Support/StringSaver.h"
23 #include "llvm/Support/TargetRegistry.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Transforms/IPO.h"
26 #include "llvm/Transforms/Utils/ModuleUtils.h"
27 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
28 
29 using namespace llvm;
30 using namespace llvm::object;
31 using namespace llvm::ELF;
32 
33 using namespace lld;
34 using namespace lld::elf;
35 
36 // This is for use when debugging LTO.
37 static void saveLtoObjectFile(StringRef Buffer, unsigned I, bool Many) {
38   SmallString<128> Filename = Config->OutputFile;
39   if (Many)
40     Filename += utostr(I);
41   Filename += ".lto.o";
42   std::error_code EC;
43   raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::F_None);
44   check(EC);
45   OS << Buffer;
46 }
47 
48 // This is for use when debugging LTO.
49 static void saveBCFile(Module &M, StringRef Suffix) {
50   std::error_code EC;
51   raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,
52                     sys::fs::OpenFlags::F_None);
53   check(EC);
54   WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
55 }
56 
57 // Run LTO passes.
58 // Note that the gold plugin has a similar piece of code, so
59 // it is probably better to move this code to a common place.
60 static void runLTOPasses(Module &M, TargetMachine &TM) {
61   legacy::PassManager LtoPasses;
62   LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
63   PassManagerBuilder PMB;
64   PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
65   PMB.Inliner = createFunctionInliningPass();
66   PMB.VerifyInput = PMB.VerifyOutput = !Config->DisableVerify;
67   PMB.LoopVectorize = true;
68   PMB.SLPVectorize = true;
69   PMB.OptLevel = Config->LtoO;
70   PMB.populateLTOPassManager(LtoPasses);
71   LtoPasses.run(M);
72 
73   if (Config->SaveTemps)
74     saveBCFile(M, ".lto.opt.bc");
75 }
76 
77 void BitcodeCompiler::add(BitcodeFile &F) {
78   std::unique_ptr<IRObjectFile> Obj =
79       check(IRObjectFile::create(F.MB, Context));
80   std::vector<GlobalValue *> Keep;
81   unsigned BodyIndex = 0;
82   ArrayRef<SymbolBody *> Bodies = F.getSymbols();
83 
84   Module &M = Obj->getModule();
85   if (M.getDataLayoutStr().empty())
86     fatal("invalid bitcode file: " + F.getName() + " has no datalayout");
87 
88   // If a symbol appears in @llvm.used, the linker is required
89   // to treat the symbol as there is a reference to the symbol
90   // that it cannot see. Therefore, we can't internalize.
91   SmallPtrSet<GlobalValue *, 8> Used;
92   collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false);
93 
94   for (const BasicSymbolRef &Sym : Obj->symbols()) {
95     GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
96     // Ignore module asm symbols.
97     if (!GV)
98       continue;
99     if (GV->hasAppendingLinkage()) {
100       Keep.push_back(GV);
101       continue;
102     }
103     if (BitcodeFile::shouldSkip(Sym))
104       continue;
105     SymbolBody *B = Bodies[BodyIndex++];
106     if (!B || &B->repl() != B || !isa<DefinedBitcode>(B))
107       continue;
108     switch (GV->getLinkage()) {
109     default:
110       break;
111     case llvm::GlobalValue::LinkOnceAnyLinkage:
112       GV->setLinkage(GlobalValue::WeakAnyLinkage);
113       break;
114     case llvm::GlobalValue::LinkOnceODRLinkage:
115       GV->setLinkage(GlobalValue::WeakODRLinkage);
116       break;
117     }
118 
119     // We collect the set of symbols we want to internalize here
120     // and change the linkage after the IRMover executed, i.e. after
121     // we imported the symbols and satisfied undefined references
122     // to it. We can't just change linkage here because otherwise
123     // the IRMover will just rename the symbol.
124     // Shared libraries need to be handled slightly differently.
125     // For now, let's be conservative and just never internalize
126     // symbols when creating a shared library.
127     if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() &&
128         !B->MustBeInDynSym)
129       if (!Used.count(GV))
130         InternalizedSyms.insert(GV->getName());
131 
132     Keep.push_back(GV);
133   }
134 
135   Mover.move(Obj->takeModule(), Keep,
136              [](GlobalValue &, IRMover::ValueAdder) {});
137 }
138 
139 static void internalize(GlobalValue &GV) {
140   assert(!GV.hasLocalLinkage() &&
141          "Trying to internalize a symbol with local linkage!");
142   GV.setLinkage(GlobalValue::InternalLinkage);
143 }
144 
145 std::vector<std::unique_ptr<InputFile>> BitcodeCompiler::runSplitCodegen(
146     const std::function<std::unique_ptr<TargetMachine>()> &TMFactory) {
147   unsigned NumThreads = Config->LtoJobs;
148   OwningData.resize(NumThreads);
149 
150   std::list<raw_svector_ostream> OSs;
151   std::vector<raw_pwrite_stream *> OSPtrs;
152   for (SmallString<0> &Obj : OwningData) {
153     OSs.emplace_back(Obj);
154     OSPtrs.push_back(&OSs.back());
155   }
156 
157   splitCodeGen(std::move(Combined), OSPtrs, {}, TMFactory);
158 
159   std::vector<std::unique_ptr<InputFile>> ObjFiles;
160   for (SmallString<0> &Obj : OwningData)
161     ObjFiles.push_back(createObjectFile(
162         MemoryBufferRef(Obj, "LLD-INTERNAL-combined-lto-object")));
163 
164   if (Config->SaveTemps)
165     for (unsigned I = 0; I < NumThreads; ++I)
166       saveLtoObjectFile(OwningData[I], I, NumThreads > 1);
167 
168   return ObjFiles;
169 }
170 
171 // Merge all the bitcode files we have seen, codegen the result
172 // and return the resulting ObjectFile.
173 std::vector<std::unique_ptr<InputFile>> BitcodeCompiler::compile() {
174   TheTriple = Combined->getTargetTriple();
175   for (const auto &Name : InternalizedSyms) {
176     GlobalValue *GV = Combined->getNamedValue(Name.first());
177     assert(GV);
178     internalize(*GV);
179   }
180 
181   if (Config->SaveTemps)
182     saveBCFile(*Combined, ".lto.bc");
183 
184   std::string Msg;
185   const Target *T = TargetRegistry::lookupTarget(TheTriple, Msg);
186   if (!T)
187     fatal("target not found: " + Msg);
188   TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
189   Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
190 
191   auto CreateTargetMachine = [&]() {
192     return std::unique_ptr<TargetMachine>(
193         T->createTargetMachine(TheTriple, "", "", Options, R));
194   };
195 
196   std::unique_ptr<TargetMachine> TM = CreateTargetMachine();
197   runLTOPasses(*Combined, *TM);
198 
199   return runSplitCodegen(CreateTargetMachine);
200 }
201