xref: /llvm-project-15.0.7/lld/ELF/LTO.cpp (revision fcef3e46)
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/IR/LegacyPassManager.h"
19 #include "llvm/Linker/IRMover.h"
20 #include "llvm/Support/StringSaver.h"
21 #include "llvm/Support/TargetRegistry.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Transforms/IPO.h"
24 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
25 
26 using namespace llvm;
27 using namespace llvm::object;
28 using namespace llvm::ELF;
29 
30 using namespace lld;
31 using namespace lld::elf;
32 
33 // This is for use when debugging LTO.
34 static void saveLtoObjectFile(StringRef Buffer) {
35   std::error_code EC;
36   raw_fd_ostream OS(Config->OutputFile.str() + ".lto.o", EC,
37                     sys::fs::OpenFlags::F_None);
38   check(EC);
39   OS << Buffer;
40 }
41 
42 // This is for use when debugging LTO.
43 static void saveBCFile(Module &M, StringRef Suffix) {
44   std::error_code EC;
45   raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC,
46                     sys::fs::OpenFlags::F_None);
47   check(EC);
48   WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
49 }
50 
51 // Run LTO passes.
52 // FIXME: Reduce code duplication by sharing this code with the gold plugin.
53 static void runLTOPasses(Module &M, TargetMachine &TM) {
54   legacy::PassManager LtoPasses;
55   LtoPasses.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
56   PassManagerBuilder PMB;
57   PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
58   PMB.Inliner = createFunctionInliningPass();
59   PMB.VerifyInput = true;
60   PMB.VerifyOutput = true;
61   PMB.LoopVectorize = true;
62   PMB.SLPVectorize = true;
63   PMB.OptLevel = 2; // FIXME: This should be an option.
64   PMB.populateLTOPassManager(LtoPasses);
65   LtoPasses.run(M);
66 
67   if (Config->SaveTemps)
68     saveBCFile(M, ".lto.opt.bc");
69 }
70 
71 void BitcodeCompiler::add(BitcodeFile &F) {
72   std::unique_ptr<IRObjectFile> Obj =
73       check(IRObjectFile::create(F.MB, Context));
74   std::vector<GlobalValue *> Keep;
75   unsigned BodyIndex = 0;
76   ArrayRef<SymbolBody *> Bodies = F.getSymbols();
77 
78   for (const BasicSymbolRef &Sym : Obj->symbols()) {
79     GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
80     assert(GV);
81     if (GV->hasAppendingLinkage()) {
82       Keep.push_back(GV);
83       continue;
84     }
85     if (BitcodeFile::shouldSkip(Sym))
86       continue;
87     SymbolBody *B = Bodies[BodyIndex++];
88     if (!B || &B->repl() != B || !isa<DefinedBitcode>(B))
89       continue;
90     switch (GV->getLinkage()) {
91     default:
92       break;
93     case llvm::GlobalValue::LinkOnceAnyLinkage:
94       GV->setLinkage(GlobalValue::WeakAnyLinkage);
95       break;
96     case llvm::GlobalValue::LinkOnceODRLinkage:
97       GV->setLinkage(GlobalValue::WeakODRLinkage);
98       break;
99     }
100     Keep.push_back(GV);
101   }
102 
103   Mover.move(Obj->takeModule(), Keep,
104              [](GlobalValue &, IRMover::ValueAdder) {});
105 }
106 
107 // Merge all the bitcode files we have seen, codegen the result
108 // and return the resulting ObjectFile.
109 template <class ELFT>
110 std::unique_ptr<elf::ObjectFile<ELFT>> BitcodeCompiler::compile() {
111   if (Config->SaveTemps)
112     saveBCFile(Combined, ".lto.bc");
113 
114   std::unique_ptr<TargetMachine> TM(getTargetMachine());
115   runLTOPasses(Combined, *TM);
116 
117   raw_svector_ostream OS(OwningData);
118   legacy::PassManager CodeGenPasses;
119   if (TM->addPassesToEmitFile(CodeGenPasses, OS,
120                               TargetMachine::CGFT_ObjectFile))
121     fatal("failed to setup codegen");
122   CodeGenPasses.run(Combined);
123   MB = MemoryBuffer::getMemBuffer(OwningData,
124                                   "LLD-INTERNAL-combined-lto-object", false);
125   if (Config->SaveTemps)
126     saveLtoObjectFile(MB->getBuffer());
127 
128   std::unique_ptr<InputFile> IF = createObjectFile(*MB);
129   auto *OF = cast<ObjectFile<ELFT>>(IF.release());
130   return std::unique_ptr<ObjectFile<ELFT>>(OF);
131 }
132 
133 TargetMachine *BitcodeCompiler::getTargetMachine() {
134   StringRef TripleStr = Combined.getTargetTriple();
135   std::string Msg;
136   const Target *T = TargetRegistry::lookupTarget(TripleStr, Msg);
137   if (!T)
138     fatal("target not found: " + Msg);
139   TargetOptions Options;
140   Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static;
141   return T->createTargetMachine(TripleStr, "", "", Options, R);
142 }
143 
144 template std::unique_ptr<elf::ObjectFile<ELF32LE>> BitcodeCompiler::compile();
145 template std::unique_ptr<elf::ObjectFile<ELF32BE>> BitcodeCompiler::compile();
146 template std::unique_ptr<elf::ObjectFile<ELF64LE>> BitcodeCompiler::compile();
147 template std::unique_ptr<elf::ObjectFile<ELF64BE>> BitcodeCompiler::compile();
148