Skip to content

Commit 8b70a5c

Browse files
committedApr 8, 2019
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary: ThinLTOCodeGenerator currently does not preserve llvm.used symbols and it can internalize them. In order to pass the necessary information to the legacy ThinLTOCodeGenerator, the input to the code generator is rewritten to be based on lto::InputFile. This fixes: PR41236 rdar://problem/49293439 Reviewers: tejohnson, pcc, dexonsmith Reviewed By: tejohnson Subscribers: mehdi_amini, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60226 llvm-svn: 357931
1 parent 887865c commit 8b70a5c

File tree

7 files changed

+184
-99
lines changed

7 files changed

+184
-99
lines changed
 

‎llvm/include/llvm/LTO/LTO.h

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class InputFile {
131131
using irsymtab::Symbol::isWeak;
132132
using irsymtab::Symbol::isIndirect;
133133
using irsymtab::Symbol::getName;
134+
using irsymtab::Symbol::getIRName;
134135
using irsymtab::Symbol::getVisibility;
135136
using irsymtab::Symbol::canBeOmittedFromSymbolTable;
136137
using irsymtab::Symbol::isTLS;
@@ -161,6 +162,9 @@ class InputFile {
161162
// Returns a table with all the comdats used by this file.
162163
ArrayRef<StringRef> getComdatTable() const { return ComdatTable; }
163164

165+
// Returns the only BitcodeModule from InputFile.
166+
BitcodeModule &getSingleBitcodeModule();
167+
164168
private:
165169
ArrayRef<Symbol> module_symbols(unsigned I) const {
166170
const auto &Indices = ModuleSymIndices[I];

‎llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h

+12-23
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/StringSet.h"
2020
#include "llvm/ADT/Triple.h"
2121
#include "llvm/IR/ModuleSummaryIndex.h"
22+
#include "llvm/LTO/LTO.h"
2223
#include "llvm/Support/CachePruning.h"
2324
#include "llvm/Support/CodeGen.h"
2425
#include "llvm/Support/MemoryBuffer.h"
@@ -31,23 +32,6 @@ class StringRef;
3132
class LLVMContext;
3233
class TargetMachine;
3334

34-
/// Wrapper around MemoryBufferRef, owning the identifier
35-
class ThinLTOBuffer {
36-
std::string OwnedIdentifier;
37-
StringRef Buffer;
38-
39-
public:
40-
ThinLTOBuffer(StringRef Buffer, StringRef Identifier)
41-
: OwnedIdentifier(Identifier), Buffer(Buffer) {}
42-
43-
MemoryBufferRef getMemBuffer() const {
44-
return MemoryBufferRef(Buffer,
45-
{OwnedIdentifier.c_str(), OwnedIdentifier.size()});
46-
}
47-
StringRef getBuffer() const { return Buffer; }
48-
StringRef getBufferIdentifier() const { return OwnedIdentifier; }
49-
};
50-
5135
/// Helper to gather options relevant to the target machine creation
5236
struct TargetMachineBuilder {
5337
Triple TheTriple;
@@ -267,31 +251,36 @@ class ThinLTOCodeGenerator {
267251
* and additionally resolve weak and linkonce symbols.
268252
* Index is updated to reflect linkage changes from weak resolution.
269253
*/
270-
void promote(Module &Module, ModuleSummaryIndex &Index);
254+
void promote(Module &Module, ModuleSummaryIndex &Index,
255+
const lto::InputFile &File);
271256

272257
/**
273258
* Compute and emit the imported files for module at \p ModulePath.
274259
*/
275260
void emitImports(Module &Module, StringRef OutputName,
276-
ModuleSummaryIndex &Index);
261+
ModuleSummaryIndex &Index,
262+
const lto::InputFile &File);
277263

278264
/**
279265
* Perform cross-module importing for the module identified by
280266
* ModuleIdentifier.
281267
*/
282-
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
268+
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index,
269+
const lto::InputFile &File);
283270

284271
/**
285272
* Compute the list of summaries needed for importing into module.
286273
*/
287274
void gatherImportedSummariesForModule(
288275
Module &Module, ModuleSummaryIndex &Index,
289-
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
276+
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
277+
const lto::InputFile &File);
290278

291279
/**
292280
* Perform internalization. Index is updated to reflect linkage changes.
293281
*/
294-
void internalize(Module &Module, ModuleSummaryIndex &Index);
282+
void internalize(Module &Module, ModuleSummaryIndex &Index,
283+
const lto::InputFile &File);
295284

296285
/**
297286
* Perform post-importing ThinLTO optimizations.
@@ -313,7 +302,7 @@ class ThinLTOCodeGenerator {
313302

314303
/// Vector holding the input buffers containing the bitcode modules to
315304
/// process.
316-
std::vector<ThinLTOBuffer> Modules;
305+
std::vector<std::unique_ptr<lto::InputFile>> Modules;
317306

318307
/// Set of symbols that need to be preserved outside of the set of bitcode
319308
/// files.

‎llvm/lib/LTO/LTO.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ StringRef InputFile::getName() const {
420420
return Mods[0].getModuleIdentifier();
421421
}
422422

423+
BitcodeModule &InputFile::getSingleBitcodeModule() {
424+
assert(Mods.size() == 1 && "Expect only one bitcode module");
425+
return Mods[0];
426+
}
427+
423428
LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
424429
Config &Conf)
425430
: ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),

‎llvm/lib/LTO/ThinLTOCodeGenerator.cpp

+80-52
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,13 @@ static void computePrevailingCopies(
135135
}
136136
}
137137

138-
static StringMap<MemoryBufferRef>
139-
generateModuleMap(const std::vector<ThinLTOBuffer> &Modules) {
140-
StringMap<MemoryBufferRef> ModuleMap;
141-
for (auto &ModuleBuffer : Modules) {
142-
assert(ModuleMap.find(ModuleBuffer.getBufferIdentifier()) ==
143-
ModuleMap.end() &&
138+
static StringMap<lto::InputFile *>
139+
generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> &Modules) {
140+
StringMap<lto::InputFile *> ModuleMap;
141+
for (auto &M : Modules) {
142+
assert(ModuleMap.find(M->getName()) == ModuleMap.end() &&
144143
"Expect unique Buffer Identifier");
145-
ModuleMap[ModuleBuffer.getBufferIdentifier()] = ModuleBuffer.getMemBuffer();
144+
ModuleMap[M->getName()] = M.get();
146145
}
147146
return ModuleMap;
148147
}
@@ -175,35 +174,37 @@ static void verifyLoadedModule(Module &TheModule) {
175174
}
176175
}
177176

178-
static std::unique_ptr<Module>
179-
loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context,
180-
bool Lazy, bool IsImporting) {
177+
static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
178+
LLVMContext &Context,
179+
bool Lazy,
180+
bool IsImporting) {
181+
auto &Mod = Input->getSingleBitcodeModule();
181182
SMDiagnostic Err;
182183
Expected<std::unique_ptr<Module>> ModuleOrErr =
183-
Lazy
184-
? getLazyBitcodeModule(Buffer, Context,
185-
/* ShouldLazyLoadMetadata */ true, IsImporting)
186-
: parseBitcodeFile(Buffer, Context);
184+
Lazy ? Mod.getLazyModule(Context,
185+
/* ShouldLazyLoadMetadata */ true, IsImporting)
186+
: Mod.parseModule(Context);
187187
if (!ModuleOrErr) {
188188
handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
189-
SMDiagnostic Err = SMDiagnostic(Buffer.getBufferIdentifier(),
189+
SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
190190
SourceMgr::DK_Error, EIB.message());
191191
Err.print("ThinLTO", errs());
192192
});
193193
report_fatal_error("Can't load module, abort.");
194194
}
195195
if (!Lazy)
196196
verifyLoadedModule(*ModuleOrErr.get());
197-
return std::move(ModuleOrErr.get());
197+
return std::move(*ModuleOrErr);
198198
}
199199

200200
static void
201201
crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
202-
StringMap<MemoryBufferRef> &ModuleMap,
202+
StringMap<lto::InputFile*> &ModuleMap,
203203
const FunctionImporter::ImportMapTy &ImportList) {
204204
auto Loader = [&](StringRef Identifier) {
205-
return loadModuleFromBuffer(ModuleMap[Identifier], TheModule.getContext(),
206-
/*Lazy=*/true, /*IsImporting*/ true);
205+
auto &Input = ModuleMap[Identifier];
206+
return loadModuleFromInput(Input, TheModule.getContext(),
207+
/*Lazy=*/true, /*IsImporting*/ true);
207208
};
208209

209210
FunctionImporter Importer(Index, Loader);
@@ -248,6 +249,15 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM,
248249
PM.run(TheModule);
249250
}
250251

252+
static void
253+
addUsedSymbolToPreservedGUID(const lto::InputFile &File,
254+
DenseSet<GlobalValue::GUID> &PreservedGUID) {
255+
for (const auto &Sym : File.symbols()) {
256+
if (Sym.isUsed())
257+
PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
258+
}
259+
}
260+
251261
// Convert the PreservedSymbols map from "Name" based to "GUID" based.
252262
static DenseSet<GlobalValue::GUID>
253263
computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
@@ -381,7 +391,7 @@ class ModuleCacheEntry {
381391

382392
static std::unique_ptr<MemoryBuffer>
383393
ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
384-
StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM,
394+
StringMap<lto::InputFile *> &ModuleMap, TargetMachine &TM,
385395
const FunctionImporter::ImportMapTy &ImportList,
386396
const FunctionImporter::ExportSetTy &ExportList,
387397
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
@@ -488,15 +498,13 @@ static void initTMBuilder(TargetMachineBuilder &TMBuilder,
488498
} // end anonymous namespace
489499

490500
void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
491-
ThinLTOBuffer Buffer(Data, Identifier);
492-
LLVMContext Context;
493-
StringRef TripleStr;
494-
ErrorOr<std::string> TripleOrErr = expectedToErrorOrAndEmitErrors(
495-
Context, getBitcodeTargetTriple(Buffer.getMemBuffer()));
501+
MemoryBufferRef Buffer(Data, Identifier);
496502

497-
if (TripleOrErr)
498-
TripleStr = *TripleOrErr;
503+
auto InputOrError = lto::InputFile::create(Buffer);
504+
if (!InputOrError)
505+
report_fatal_error("ThinLTO cannot create input file");
499506

507+
auto TripleStr = (*InputOrError)->getTargetTriple();
500508
Triple TheTriple(TripleStr);
501509

502510
if (Modules.empty())
@@ -508,7 +516,7 @@ void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
508516
initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
509517
}
510518

511-
Modules.push_back(Buffer);
519+
Modules.emplace_back(std::move(*InputOrError));
512520
}
513521

514522
void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
@@ -549,9 +557,10 @@ std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
549557
std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
550558
llvm::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
551559
uint64_t NextModuleId = 0;
552-
for (auto &ModuleBuffer : Modules) {
553-
if (Error Err = readModuleSummaryIndex(ModuleBuffer.getMemBuffer(),
554-
*CombinedIndex, NextModuleId++)) {
560+
for (auto &Mod : Modules) {
561+
auto &M = Mod->getSingleBitcodeModule();
562+
if (Error Err =
563+
M.readSummary(*CombinedIndex, Mod->getName(), NextModuleId++)) {
555564
// FIXME diagnose
556565
logAllUnhandledErrors(
557566
std::move(Err), errs(),
@@ -593,8 +602,8 @@ static void computeDeadSymbolsInIndex(
593602
* Perform promotion and renaming of exported internal functions.
594603
* Index is updated to reflect linkage changes from weak resolution.
595604
*/
596-
void ThinLTOCodeGenerator::promote(Module &TheModule,
597-
ModuleSummaryIndex &Index) {
605+
void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index,
606+
const lto::InputFile &File) {
598607
auto ModuleCount = Index.modulePaths().size();
599608
auto ModuleIdentifier = TheModule.getModuleIdentifier();
600609

@@ -606,6 +615,9 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
606615
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
607616
PreservedSymbols, Triple(TheModule.getTargetTriple()));
608617

618+
// Add used symbol to the preserved symbols.
619+
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
620+
609621
// Compute "dead" symbols, we don't want to import/export these!
610622
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
611623

@@ -619,21 +631,22 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
619631
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
620632
resolvePrevailingInIndex(Index, ResolvedODR);
621633

622-
thinLTOResolvePrevailingInModule(
623-
TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
624-
625634
// Promote the exported values in the index, so that they are promoted
626635
// in the module.
627636
internalizeAndPromoteInIndex(ExportLists, GUIDPreservedSymbols, Index);
628637

629638
promoteModule(TheModule, Index);
639+
640+
thinLTOResolvePrevailingInModule(
641+
TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
630642
}
631643

632644
/**
633645
* Perform cross-module importing for the module identified by ModuleIdentifier.
634646
*/
635647
void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
636-
ModuleSummaryIndex &Index) {
648+
ModuleSummaryIndex &Index,
649+
const lto::InputFile &File) {
637650
auto ModuleMap = generateModuleMap(Modules);
638651
auto ModuleCount = Index.modulePaths().size();
639652

@@ -645,6 +658,8 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
645658
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
646659
PreservedSymbols, Triple(TheModule.getTargetTriple()));
647660

661+
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
662+
648663
// Compute "dead" symbols, we don't want to import/export these!
649664
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
650665

@@ -663,7 +678,8 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
663678
*/
664679
void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
665680
Module &TheModule, ModuleSummaryIndex &Index,
666-
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
681+
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
682+
const lto::InputFile &File) {
667683
auto ModuleCount = Index.modulePaths().size();
668684
auto ModuleIdentifier = TheModule.getModuleIdentifier();
669685

@@ -675,6 +691,8 @@ void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
675691
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
676692
PreservedSymbols, Triple(TheModule.getTargetTriple()));
677693

694+
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
695+
678696
// Compute "dead" symbols, we don't want to import/export these!
679697
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
680698

@@ -693,7 +711,8 @@ void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
693711
* Emit the list of files needed for importing into module.
694712
*/
695713
void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
696-
ModuleSummaryIndex &Index) {
714+
ModuleSummaryIndex &Index,
715+
const lto::InputFile &File) {
697716
auto ModuleCount = Index.modulePaths().size();
698717
auto ModuleIdentifier = TheModule.getModuleIdentifier();
699718

@@ -705,6 +724,8 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
705724
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
706725
PreservedSymbols, Triple(TheModule.getTargetTriple()));
707726

727+
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
728+
708729
// Compute "dead" symbols, we don't want to import/export these!
709730
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
710731

@@ -730,7 +751,8 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
730751
* Perform internalization. Index is updated to reflect linkage changes.
731752
*/
732753
void ThinLTOCodeGenerator::internalize(Module &TheModule,
733-
ModuleSummaryIndex &Index) {
754+
ModuleSummaryIndex &Index,
755+
const lto::InputFile &File) {
734756
initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
735757
auto ModuleCount = Index.modulePaths().size();
736758
auto ModuleIdentifier = TheModule.getModuleIdentifier();
@@ -739,6 +761,8 @@ void ThinLTOCodeGenerator::internalize(Module &TheModule,
739761
auto GUIDPreservedSymbols =
740762
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
741763

764+
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
765+
742766
// Collect for each module the list of function it defines (GUID -> Summary).
743767
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
744768
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
@@ -830,15 +854,14 @@ void ThinLTOCodeGenerator::run() {
830854
// Perform only parallel codegen and return.
831855
ThreadPool Pool;
832856
int count = 0;
833-
for (auto &ModuleBuffer : Modules) {
857+
for (auto &Mod : Modules) {
834858
Pool.async([&](int count) {
835859
LLVMContext Context;
836860
Context.setDiscardValueNames(LTODiscardValueNames);
837861

838862
// Parse module now
839-
auto TheModule =
840-
loadModuleFromBuffer(ModuleBuffer.getMemBuffer(), Context, false,
841-
/*IsImporting*/ false);
863+
auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
864+
/*IsImporting*/ false);
842865

843866
// CodeGen
844867
auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
@@ -881,6 +904,10 @@ void ThinLTOCodeGenerator::run() {
881904
auto GUIDPreservedSymbols =
882905
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
883906

907+
// Add used symbol from inputs to the preserved symbols.
908+
for (const auto &M : Modules)
909+
addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
910+
884911
// Compute "dead" symbols, we don't want to import/export these!
885912
computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
886913

@@ -913,7 +940,7 @@ void ThinLTOCodeGenerator::run() {
913940
// GVSummary and ResolvedODR maps to enable threaded access to these maps
914941
// below.
915942
for (auto &Module : Modules) {
916-
auto ModuleIdentifier = Module.getBufferIdentifier();
943+
auto ModuleIdentifier = Module->getName();
917944
ExportLists[ModuleIdentifier];
918945
ImportLists[ModuleIdentifier];
919946
ResolvedODR[ModuleIdentifier];
@@ -927,18 +954,20 @@ void ThinLTOCodeGenerator::run() {
927954
ModulesOrdering.resize(Modules.size());
928955
std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
929956
llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {
930-
auto LSize = Modules[LeftIndex].getBuffer().size();
931-
auto RSize = Modules[RightIndex].getBuffer().size();
957+
auto LSize =
958+
Modules[LeftIndex]->getSingleBitcodeModule().getBuffer().size();
959+
auto RSize =
960+
Modules[RightIndex]->getSingleBitcodeModule().getBuffer().size();
932961
return LSize > RSize;
933962
});
934963

935964
// Parallel optimizer + codegen
936965
{
937966
ThreadPool Pool(ThreadCount);
938967
for (auto IndexCount : ModulesOrdering) {
939-
auto &ModuleBuffer = Modules[IndexCount];
968+
auto &Mod = Modules[IndexCount];
940969
Pool.async([&](int count) {
941-
auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
970+
auto ModuleIdentifier = Mod->getName();
942971
auto &ExportList = ExportLists[ModuleIdentifier];
943972

944973
auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
@@ -982,9 +1011,8 @@ void ThinLTOCodeGenerator::run() {
9821011
}
9831012

9841013
// Parse module now
985-
auto TheModule =
986-
loadModuleFromBuffer(ModuleBuffer.getMemBuffer(), Context, false,
987-
/*IsImporting*/ false);
1014+
auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1015+
/*IsImporting*/ false);
9881016

9891017
// Save temps: original file.
9901018
saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
2+
target triple = "x86_64-apple-macosx10.15.0"
3+
4+
define i32 @main() {
5+
entry:
6+
%call = call i32 @bar()
7+
ret i32 0
8+
}
9+
10+
declare i32 @bar()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: opt -module-summary -o %t.bc %s
2+
; RUN: opt -module-summary -o %t-main.bc %S/Inputs/thinlto-internalize-used2.ll
3+
; RUN: llvm-lto -thinlto-action=thinlink %t.bc %t-main.bc -o %t-index.bc
4+
; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t-index.bc %t.bc -o %t.promote.bc
5+
; RUN: llvm-dis %t.promote.bc -o - | FileCheck %s
6+
7+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
8+
target triple = "x86_64-apple-macosx10.15.0"
9+
10+
@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @foo to i8*)], section "llvm.metadata"
11+
12+
; Make sure foo is not internalized.
13+
; CHECK: define i32 @foo()
14+
define i32 @foo() {
15+
ret i32 0
16+
}
17+
18+
define hidden i32 @bar() {
19+
ret i32 0
20+
}
21+

‎llvm/tools/llvm-lto/llvm-lto.cpp

+52-24
Original file line numberDiff line numberDiff line change
@@ -449,22 +449,37 @@ std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
449449
return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
450450
}
451451

452-
static std::unique_ptr<Module> loadModule(StringRef Filename,
453-
LLVMContext &Ctx) {
454-
SMDiagnostic Err;
455-
std::unique_ptr<Module> M(parseIRFile(Filename, Err, Ctx));
456-
if (!M) {
457-
Err.print("llvm-lto", errs());
458-
report_fatal_error("Can't load module for file " + Filename);
459-
}
460-
maybeVerifyModule(*M);
452+
static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
453+
ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
454+
"': ");
455+
return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
456+
}
461457

458+
static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
459+
ExitOnError ExitOnErr("llvm-lto: error loading input '" +
460+
Buffer.getBufferIdentifier().str() + "': ");
461+
return ExitOnErr(lto::InputFile::create(Buffer));
462+
}
463+
464+
static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File,
465+
LLVMContext &CTX) {
466+
auto &Mod = File.getSingleBitcodeModule();
467+
auto ModuleOrErr = Mod.parseModule(CTX);
468+
if (!ModuleOrErr) {
469+
handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
470+
SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
471+
SourceMgr::DK_Error, EIB.message());
472+
Err.print("llvm-lto", errs());
473+
});
474+
report_fatal_error("Can't load module, abort.");
475+
}
476+
maybeVerifyModule(**ModuleOrErr);
462477
if (ThinLTOModuleId.getNumOccurrences()) {
463478
if (InputFilenames.size() != 1)
464479
report_fatal_error("Can't override the module id for multiple files");
465-
M->setModuleIdentifier(ThinLTOModuleId);
480+
(*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
466481
}
467-
return M;
482+
return std::move(*ModuleOrErr);
468483
}
469484

470485
static void writeModuleToFile(Module &TheModule, StringRef Filename) {
@@ -562,13 +577,15 @@ class ThinLTOProcessing {
562577
auto Index = loadCombinedIndex();
563578
for (auto &Filename : InputFilenames) {
564579
LLVMContext Ctx;
565-
auto TheModule = loadModule(Filename, Ctx);
580+
auto Buffer = loadFile(Filename);
581+
auto Input = loadInputFile(Buffer->getMemBufferRef());
582+
auto TheModule = loadModuleFromInput(*Input, Ctx);
566583

567584
// Build a map of module to the GUIDs and summary objects that should
568585
// be written to its index.
569586
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
570-
ThinGenerator.gatherImportedSummariesForModule(*TheModule, *Index,
571-
ModuleToSummariesForIndex);
587+
ThinGenerator.gatherImportedSummariesForModule(
588+
*TheModule, *Index, ModuleToSummariesForIndex, *Input);
572589

573590
std::string OutputName = OutputFilename;
574591
if (OutputName.empty()) {
@@ -597,13 +614,16 @@ class ThinLTOProcessing {
597614
auto Index = loadCombinedIndex();
598615
for (auto &Filename : InputFilenames) {
599616
LLVMContext Ctx;
600-
auto TheModule = loadModule(Filename, Ctx);
617+
auto Buffer = loadFile(Filename);
618+
auto Input = loadInputFile(Buffer->getMemBufferRef());
619+
auto TheModule = loadModuleFromInput(*Input, Ctx);
601620
std::string OutputName = OutputFilename;
602621
if (OutputName.empty()) {
603622
OutputName = Filename + ".imports";
604623
}
605-
OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
606-
ThinGenerator.emitImports(*TheModule, OutputName, *Index);
624+
OutputName =
625+
getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
626+
ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
607627
}
608628
}
609629

@@ -621,9 +641,11 @@ class ThinLTOProcessing {
621641
auto Index = loadCombinedIndex();
622642
for (auto &Filename : InputFilenames) {
623643
LLVMContext Ctx;
624-
auto TheModule = loadModule(Filename, Ctx);
644+
auto Buffer = loadFile(Filename);
645+
auto Input = loadInputFile(Buffer->getMemBufferRef());
646+
auto TheModule = loadModuleFromInput(*Input, Ctx);
625647

626-
ThinGenerator.promote(*TheModule, *Index);
648+
ThinGenerator.promote(*TheModule, *Index, *Input);
627649

628650
std::string OutputName = OutputFilename;
629651
if (OutputName.empty()) {
@@ -652,9 +674,11 @@ class ThinLTOProcessing {
652674

653675
for (auto &Filename : InputFilenames) {
654676
LLVMContext Ctx;
655-
auto TheModule = loadModule(Filename, Ctx);
677+
auto Buffer = loadFile(Filename);
678+
auto Input = loadInputFile(Buffer->getMemBufferRef());
679+
auto TheModule = loadModuleFromInput(*Input, Ctx);
656680

657-
ThinGenerator.crossModuleImport(*TheModule, *Index);
681+
ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);
658682

659683
std::string OutputName = OutputFilename;
660684
if (OutputName.empty()) {
@@ -683,9 +707,11 @@ class ThinLTOProcessing {
683707

684708
for (auto &Filename : InputFilenames) {
685709
LLVMContext Ctx;
686-
auto TheModule = loadModule(Filename, Ctx);
710+
auto Buffer = loadFile(Filename);
711+
auto Input = loadInputFile(Buffer->getMemBufferRef());
712+
auto TheModule = loadModuleFromInput(*Input, Ctx);
687713

688-
ThinGenerator.internalize(*TheModule, *Index);
714+
ThinGenerator.internalize(*TheModule, *Index, *Input);
689715

690716
std::string OutputName = OutputFilename;
691717
if (OutputName.empty()) {
@@ -706,7 +732,9 @@ class ThinLTOProcessing {
706732

707733
for (auto &Filename : InputFilenames) {
708734
LLVMContext Ctx;
709-
auto TheModule = loadModule(Filename, Ctx);
735+
auto Buffer = loadFile(Filename);
736+
auto Input = loadInputFile(Buffer->getMemBufferRef());
737+
auto TheModule = loadModuleFromInput(*Input, Ctx);
710738

711739
ThinGenerator.optimize(*TheModule);
712740

0 commit comments

Comments
 (0)
Please sign in to comment.