xref: /llvm-project-15.0.7/lld/ELF/LTO.cpp (revision 498ee00a)
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/CodeGen/CommandFlags.h"
16 #include "llvm/IR/DiagnosticPrinter.h"
17 #include "llvm/LTO/LTO.h"
18 
19 using namespace llvm;
20 using namespace llvm::object;
21 using namespace llvm::ELF;
22 
23 using namespace lld;
24 using namespace lld::elf;
25 
26 // This is for use when debugging LTO.
27 static void saveBuffer(StringRef Buffer, const Twine &Path) {
28   std::error_code EC;
29   raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
30   if (EC)
31     error(EC, "cannot create " + Path);
32   OS << Buffer;
33 }
34 
35 static void diagnosticHandler(const DiagnosticInfo &DI) {
36   SmallString<128> ErrStorage;
37   raw_svector_ostream OS(ErrStorage);
38   DiagnosticPrinterRawOStream DP(OS);
39   DI.print(DP);
40   warn(ErrStorage);
41 }
42 
43 static void checkError(Error E) {
44   handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
45     error(EIB.message());
46     return Error::success();
47   });
48 }
49 
50 static std::unique_ptr<lto::LTO> createLTO() {
51   lto::Config Conf;
52 
53   // LLD supports the new relocations.
54   Conf.Options = InitTargetOptionsFromCodeGenFlags();
55   Conf.Options.RelaxELFRelocations = true;
56 
57   Conf.RelocModel = Config->Pic ? Reloc::PIC_ : Reloc::Static;
58   Conf.DisableVerify = Config->DisableVerify;
59   Conf.DiagHandler = diagnosticHandler;
60   Conf.OptLevel = Config->LtoO;
61 
62   // Set up a custom pipeline if we've been asked to.
63   Conf.OptPipeline = Config->LtoNewPmPasses;
64   Conf.AAPipeline = Config->LtoAAPipeline;
65 
66   if (Config->SaveTemps)
67     checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
68                             /*UseInputModulePath*/ true));
69 
70   lto::ThinBackend Backend;
71   if (Config->ThinLtoJobs != -1u)
72     Backend = lto::createInProcessThinBackend(Config->ThinLtoJobs);
73   return llvm::make_unique<lto::LTO>(std::move(Conf), Backend,
74                                      Config->LtoPartitions);
75 }
76 
77 BitcodeCompiler::BitcodeCompiler() : LtoObj(createLTO()) {}
78 
79 BitcodeCompiler::~BitcodeCompiler() {}
80 
81 static void undefine(Symbol *S) {
82   replaceBody<Undefined>(S, S->body()->getName(), STV_DEFAULT, S->body()->Type,
83                          nullptr);
84 }
85 
86 void BitcodeCompiler::add(BitcodeFile &F) {
87   lto::InputFile &Obj = *F.Obj;
88   if (Obj.getDataLayoutStr().empty())
89     fatal("invalid bitcode file: " + F.getName() + " has no datalayout");
90 
91   unsigned SymNum = 0;
92   std::vector<Symbol *> Syms = F.getSymbols();
93   std::vector<lto::SymbolResolution> Resols(Syms.size());
94 
95   // Provide a resolution to the LTO API for each symbol.
96   for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
97     Symbol *Sym = Syms[SymNum];
98     lto::SymbolResolution &R = Resols[SymNum];
99     ++SymNum;
100     SymbolBody *B = Sym->body();
101 
102     // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
103     // reports two symbols for module ASM defined. Without this check, lld
104     // flags an undefined in IR with a definition in ASM as prevailing.
105     // Once IRObjectFile is fixed to report only one symbol this hack can
106     // be removed.
107     R.Prevailing =
108         !(ObjSym.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
109         B->File == &F;
110 
111     R.VisibleToRegularObj =
112         Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
113     if (R.Prevailing)
114       undefine(Sym);
115   }
116   checkError(LtoObj->add(std::move(F.Obj), Resols));
117 }
118 
119 // Merge all the bitcode files we have seen, codegen the result
120 // and return the resulting ObjectFile(s).
121 std::vector<InputFile *> BitcodeCompiler::compile() {
122   std::vector<InputFile *> Ret;
123   unsigned MaxTasks = LtoObj->getMaxTasks();
124   Buff.resize(MaxTasks);
125 
126   checkError(LtoObj->run([&](size_t Task) {
127     return llvm::make_unique<lto::NativeObjectStream>(
128         llvm::make_unique<llvm::raw_svector_ostream>(Buff[Task]));
129   }));
130 
131   for (unsigned I = 0; I != MaxTasks; ++I) {
132     if (Buff[I].empty())
133       continue;
134     if (Config->SaveTemps) {
135       if (MaxTasks == 1)
136         saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
137       else
138         saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
139     }
140     InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
141     Ret.push_back(Obj);
142   }
143   return Ret;
144 }
145