llvm.org GIT mirror llvm / 27af205
Restore "[ThinLTO] Emit individual index files for distributed backends" This restores commit r268627: Summary: When launching ThinLTO backends in a distributed build (currently supported in gold via the thinlto-index-only plugin option), emit an individual index file for each backend process as described here: http://lists.llvm.org/pipermail/llvm-dev/2016-April/098272.html ... Differential Revision: http://reviews.llvm.org/D19556 Address msan failures by avoiding std::prev on map.end(), the theory is that this is causing issues due to some known UB problems in __tree. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269059 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 3 years ago
11 changed file(s) with 498 addition(s) and 114 deletion(s). Raw diff Collapse all Expand all
9696
9797 /// Write the specified module summary index to the given raw output stream,
9898 /// where it will be written in a new bitcode block. This is used when
99 /// writing the combined index file for ThinLTO.
100 void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out);
99 /// writing the combined index file for ThinLTO. When writing a subset of the
100 /// index for a distributed backend, provide the \p ModuleToSummariesForIndex
101 /// map.
102 void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out,
103 std::map
104 *ModuleToSummariesForIndex = nullptr);
101105
102106 /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
103107 /// for an LLVM IR bitcode wrapper.
1818 #include "llvm-c/lto.h"
1919 #include "llvm/ADT/StringSet.h"
2020 #include "llvm/ADT/Triple.h"
21 #include "llvm/IR/ModuleSummaryIndex.h"
2122 #include "llvm/Support/CodeGen.h"
2223 #include "llvm/Support/MemoryBuffer.h"
2324 #include "llvm/Target/TargetOptions.h"
2627
2728 namespace llvm {
2829 class StringRef;
29 class ModuleSummaryIndex;
3030 class LLVMContext;
3131 class TargetMachine;
3232
207207 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
208208
209209 /**
210 * Compute the list of summaries needed for importing into module.
211 */
212 static void gatherImportedSummariesForModule(
213 StringRef ModulePath, ModuleSummaryIndex &Index,
214 std::map &ModuleToSummariesForIndex);
215
216 /**
210217 * Perform internalization.
211218 */
212219 void internalize(Module &Module, ModuleSummaryIndex &Index);
8686 void ComputeCrossModuleImportForModule(
8787 StringRef ModulePath, const ModuleSummaryIndex &Index,
8888 FunctionImporter::ImportMapTy &ImportList);
89
90 /// Compute the set of summaries needed for a ThinLTO backend compilation of
91 /// \p ModulePath.
92 //
93 /// This includes summaries from that module (in case any global summary based
94 /// optimizations were recorded) and from any definitions in other modules that
95 /// should be imported.
96 //
97 /// \p ModuleToSummariesForIndex will be populated with the needed summaries
98 /// from each required module path. Use a std::map instead of StringMap to get
99 /// stable order for bitcode emission.
100 void gatherImportedSummariesForModule(
101 StringRef ModulePath,
102 const StringMap &ModuleToDefinedGVSummaries,
103 const StringMap &ImportLists,
104 std::map &ModuleToSummariesForIndex);
89105 }
90106
91107 #endif // LLVM_FUNCTIONIMPORT_H
262262 /// The combined index to write to bitcode.
263263 const ModuleSummaryIndex &Index;
264264
265 /// When writing a subset of the index for distributed backends, client
266 /// provides a map of modules to the corresponding GUIDs/summaries to write.
267 std::map *ModuleToSummariesForIndex;
268
265269 /// Map that holds the correspondence between the GUID used in the combined
266270 /// index and a value id generated by this class to use in references.
267271 std::map GUIDToValueIdMap;
271275
272276 public:
273277 /// Constructs a IndexBitcodeWriter object for the given combined index,
274 /// writing to the provided \p Buffer.
278 /// writing to the provided \p Buffer. When writing a subset of the index
279 /// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
275280 IndexBitcodeWriter(SmallVectorImpl &Buffer,
276 const ModuleSummaryIndex &Index)
277 : BitcodeWriter(Buffer), Index(Index) {
278 // Assign unique value ids to all functions in the index for use
281 const ModuleSummaryIndex &Index,
282 std::map
283 *ModuleToSummariesForIndex = nullptr)
284 : BitcodeWriter(Buffer), Index(Index),
285 ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
286 // Assign unique value ids to all summaries to be written, for use
279287 // in writing out the call graph edges. Save the mapping from GUID
280288 // to the new global value id to use when writing those edges, which
281289 // are currently saved in the index in terms of GUID.
282 for (auto &II : Index)
283 GUIDToValueIdMap[II.first] = ++GlobalValueId;
284 }
290 for (const auto &I : *this)
291 GUIDToValueIdMap[I.first] = ++GlobalValueId;
292 }
293
294 /// The below iterator returns the GUID and associated summary.
295 typedef std::pair GVInfo;
296
297 /// Iterator over the value GUID and summaries to be written to bitcode,
298 /// hides the details of whether they are being pulled from the entire
299 /// index or just those in a provided ModuleToSummariesForIndex map.
300 class iterator
301 : public llvm::iterator_facade_base
302 GVInfo> {
303 /// Enables access to parent class.
304 const IndexBitcodeWriter &Writer;
305
306 // Iterators used when writing only those summaries in a provided
307 // ModuleToSummariesForIndex map:
308
309 /// Points to the last element in outer ModuleToSummariesForIndex map.
310 std::map::iterator ModuleSummariesBack;
311 /// Iterator on outer ModuleToSummariesForIndex map.
312 std::map::iterator ModuleSummariesIter;
313 /// Iterator on an inner global variable summary map.
314 GVSummaryMapTy::iterator ModuleGVSummariesIter;
315
316 // Iterators used when writing all summaries in the index:
317
318 /// Points to the last element in the Index outer GlobalValueMap.
319 const_gvsummary_iterator IndexSummariesBack;
320 /// Iterator on outer GlobalValueMap.
321 const_gvsummary_iterator IndexSummariesIter;
322 /// Iterator on an inner GlobalValueSummaryList.
323 GlobalValueSummaryList::const_iterator IndexGVSummariesIter;
324
325 public:
326 /// Construct iterator from parent \p Writer and indicate if we are
327 /// constructing the end iterator.
328 iterator(const IndexBitcodeWriter &Writer, bool IsAtEnd) : Writer(Writer) {
329 // Set up the appropriate set of iterators given whether we are writing
330 // the full index or just a subset.
331 // Can't setup the Back or inner iterators if the corresponding map
332 // is empty. This will be handled specially in operator== as well.
333 if (Writer.ModuleToSummariesForIndex &&
334 !Writer.ModuleToSummariesForIndex->empty()) {
335 ModuleSummariesIter = Writer.ModuleToSummariesForIndex->begin();
336 for (ModuleSummariesBack = Writer.ModuleToSummariesForIndex->begin();
337 std::next(ModuleSummariesBack) !=
338 Writer.ModuleToSummariesForIndex->end();
339 ModuleSummariesBack++)
340 ;
341 ModuleGVSummariesIter = !IsAtEnd ? ModuleSummariesIter->second.begin()
342 : ModuleSummariesBack->second.end();
343 } else if (!Writer.ModuleToSummariesForIndex &&
344 Writer.Index.begin() != Writer.Index.end()) {
345 IndexSummariesIter = Writer.Index.begin();
346 for (IndexSummariesBack = Writer.Index.begin();
347 std::next(IndexSummariesBack) != Writer.Index.end();
348 IndexSummariesBack++)
349 ;
350 IndexGVSummariesIter = !IsAtEnd ? IndexSummariesIter->second.begin()
351 : IndexSummariesBack->second.end();
352 }
353 }
354
355 /// Increment the appropriate set of iterators.
356 iterator &operator++() {
357 // First the inner iterator is incremented, then if it is at the end
358 // and there are more outer iterations to go, the inner is reset to
359 // the start of the next inner list.
360 if (Writer.ModuleToSummariesForIndex) {
361 ++ModuleGVSummariesIter;
362 if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
363 ModuleSummariesIter != ModuleSummariesBack) {
364 ++ModuleSummariesIter;
365 ModuleGVSummariesIter = ModuleSummariesIter->second.begin();
366 }
367 } else {
368 ++IndexGVSummariesIter;
369 if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
370 IndexSummariesIter != IndexSummariesBack) {
371 ++IndexSummariesIter;
372 IndexGVSummariesIter = IndexSummariesIter->second.begin();
373 }
374 }
375 return *this;
376 }
377
378 /// Access the pair corresponding to the current
379 /// outer and inner iterator positions.
380 GVInfo operator*() {
381 if (Writer.ModuleToSummariesForIndex)
382 return std::make_pair(ModuleGVSummariesIter->first,
383 ModuleGVSummariesIter->second);
384 return std::make_pair(IndexSummariesIter->first,
385 IndexGVSummariesIter->get());
386 }
387
388 /// Checks if the iterators are equal, with special handling for empty
389 /// indexes.
390 bool operator==(const iterator &RHS) const {
391 if (Writer.ModuleToSummariesForIndex) {
392 // First ensure that both are writing the same subset.
393 if (Writer.ModuleToSummariesForIndex !=
394 RHS.Writer.ModuleToSummariesForIndex)
395 return false;
396 // Already determined above that maps are the same, so if one is
397 // empty, they both are.
398 if (Writer.ModuleToSummariesForIndex->empty())
399 return true;
400 return ModuleGVSummariesIter == RHS.ModuleGVSummariesIter;
401 }
402 // First ensure RHS also writing the full index, and that both are
403 // writing the same full index.
404 if (RHS.Writer.ModuleToSummariesForIndex ||
405 &Writer.Index != &RHS.Writer.Index)
406 return false;
407 // Already determined above that maps are the same, so if one is
408 // empty, they both are.
409 if (Writer.Index.begin() == Writer.Index.end())
410 return true;
411 return IndexGVSummariesIter == RHS.IndexGVSummariesIter;
412 }
413 };
414
415 /// Obtain the start iterator over the summaries to be written.
416 iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
417 /// Obtain the end iterator over the summaries to be written.
418 iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
285419
286420 private:
287421 /// Main entry point for writing a combined index to bitcode, invoked by
292426 void writeModStrings();
293427 void writeCombinedValueSymbolTable();
294428 void writeCombinedGlobalValueSummary();
429
430 /// Indicates whether the provided \p ModulePath should be written into
431 /// the module string table, e.g. if full index written or if it is in
432 /// the provided subset.
433 bool doIncludeModule(StringRef ModulePath) {
434 return !ModuleToSummariesForIndex ||
435 ModuleToSummariesForIndex->count(ModulePath);
436 }
295437
296438 bool hasValueId(GlobalValue::GUID ValGUID) {
297439 const auto &VMI = GUIDToValueIdMap.find(ValGUID);
29633105
29643106 SmallVector Vals;
29653107 for (const auto &MPSE : Index.modulePaths()) {
3108 if (!doIncludeModule(MPSE.getKey()))
3109 continue;
29663110 StringEncoding Bits =
29673111 getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size());
29683112 unsigned AbbrevToUse = Abbrev8Bit;
32163360 NameVals.clear();
32173361 };
32183362
3219 for (const auto &GSI : Index) {
3220 for (auto &SI : GSI.second) {
3221 GlobalValueSummary *S = SI.get();
3222 assert(S);
3223
3224 assert(hasValueId(GSI.first));
3225 unsigned ValueId = getValueId(GSI.first);
3226 SummaryToValueIdMap[S] = ValueId;
3227
3228 if (auto *AS = dyn_cast(S)) {
3229 // Will process aliases as a post-pass because the reader wants all
3230 // global to be loaded first.
3231 Aliases.push_back(AS);
3232 continue;
3233 }
3234
3235 if (auto *VS = dyn_cast(S)) {
3236 NameVals.push_back(ValueId);
3237 NameVals.push_back(Index.getModuleId(VS->modulePath()));
3238 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
3239 for (auto &RI : VS->refs()) {
3240 NameVals.push_back(getValueId(RI.getGUID()));
3241 }
3242
3243 // Emit the finished record.
3244 Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
3245 FSModRefsAbbrev);
3246 NameVals.clear();
3247 MaybeEmitOriginalName(*S);
3248 continue;
3249 }
3250
3251 auto *FS = cast(S);
3363 for (const auto &I : *this) {
3364 GlobalValueSummary *S = I.second;
3365 assert(S);
3366
3367 assert(hasValueId(I.first));
3368 unsigned ValueId = getValueId(I.first);
3369 SummaryToValueIdMap[S] = ValueId;
3370
3371 if (auto *AS = dyn_cast(S)) {
3372 // Will process aliases as a post-pass because the reader wants all
3373 // global to be loaded first.
3374 Aliases.push_back(AS);
3375 continue;
3376 }
3377
3378 if (auto *VS = dyn_cast(S)) {
32523379 NameVals.push_back(ValueId);
3253 NameVals.push_back(Index.getModuleId(FS->modulePath()));
3254 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
3255 NameVals.push_back(FS->instCount());
3256 NameVals.push_back(FS->refs().size());
3257
3258 for (auto &RI : FS->refs()) {
3380 NameVals.push_back(Index.getModuleId(VS->modulePath()));
3381 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
3382 for (auto &RI : VS->refs()) {
32593383 NameVals.push_back(getValueId(RI.getGUID()));
32603384 }
32613385
3262 bool HasProfileData = false;
3263 for (auto &EI : FS->calls()) {
3264 HasProfileData |= EI.second.ProfileCount != 0;
3265 if (HasProfileData)
3266 break;
3267 }
3268
3269 for (auto &EI : FS->calls()) {
3270 // If this GUID doesn't have a value id, it doesn't have a function
3271 // summary and we don't need to record any calls to it.
3272 if (!hasValueId(EI.first.getGUID()))
3273 continue;
3274 NameVals.push_back(getValueId(EI.first.getGUID()));
3275 assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
3276 NameVals.push_back(EI.second.CallsiteCount);
3277 if (HasProfileData)
3278 NameVals.push_back(EI.second.ProfileCount);
3279 }
3280
3281 unsigned FSAbbrev =
3282 (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
3283 unsigned Code =
3284 (HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
3285
32863386 // Emit the finished record.
3287 Stream.EmitRecord(Code, NameVals, FSAbbrev);
3387 Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
3388 FSModRefsAbbrev);
32883389 NameVals.clear();
32893390 MaybeEmitOriginalName(*S);
3290 }
3391 continue;
3392 }
3393
3394 auto *FS = cast(S);
3395 NameVals.push_back(ValueId);
3396 NameVals.push_back(Index.getModuleId(FS->modulePath()));
3397 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
3398 NameVals.push_back(FS->instCount());
3399 NameVals.push_back(FS->refs().size());
3400
3401 for (auto &RI : FS->refs()) {
3402 NameVals.push_back(getValueId(RI.getGUID()));
3403 }
3404
3405 bool HasProfileData = false;
3406 for (auto &EI : FS->calls()) {
3407 HasProfileData |= EI.second.ProfileCount != 0;
3408 if (HasProfileData)
3409 break;
3410 }
3411
3412 for (auto &EI : FS->calls()) {
3413 // If this GUID doesn't have a value id, it doesn't have a function
3414 // summary and we don't need to record any calls to it.
3415 if (!hasValueId(EI.first.getGUID()))
3416 continue;
3417 NameVals.push_back(getValueId(EI.first.getGUID()));
3418 assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
3419 NameVals.push_back(EI.second.CallsiteCount);
3420 if (HasProfileData)
3421 NameVals.push_back(EI.second.ProfileCount);
3422 }
3423
3424 unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
3425 unsigned Code =
3426 (HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
3427
3428 // Emit the finished record.
3429 Stream.EmitRecord(Code, NameVals, FSAbbrev);
3430 NameVals.clear();
3431 MaybeEmitOriginalName(*S);
32913432 }
32923433
32933434 for (auto *AS : Aliases) {
35613702
35623703 // Write the specified module summary index to the given raw output stream,
35633704 // where it will be written in a new bitcode block. This is used when
3564 // writing the combined index file for ThinLTO.
3565 void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
3705 // writing the combined index file for ThinLTO. When writing a subset of the
3706 // index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
3707 void llvm::WriteIndexToFile(
3708 const ModuleSummaryIndex &Index, raw_ostream &Out,
3709 std::map *ModuleToSummariesForIndex) {
35663710 SmallVector Buffer;
35673711 Buffer.reserve(256 * 1024);
35683712
3569 IndexBitcodeWriter IndexWriter(Buffer, Index);
3713 IndexBitcodeWriter IndexWriter(Buffer, Index, ModuleToSummariesForIndex);
35703714 IndexWriter.write();
35713715
35723716 Out.write((char *)&Buffer.front(), Buffer.size());
719719 }
720720
721721 /**
722 * Compute the list of summaries needed for importing into module.
723 */
724 void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
725 StringRef ModulePath, ModuleSummaryIndex &Index,
726 std::map &ModuleToSummariesForIndex) {
727 auto ModuleCount = Index.modulePaths().size();
728
729 // Collect for each module the list of function it defines (GUID -> Summary).
730 StringMap ModuleToDefinedGVSummaries(ModuleCount);
731 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
732
733 // Generate import/export list
734 StringMap ImportLists(ModuleCount);
735 StringMap ExportLists(ModuleCount);
736 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
737 ExportLists);
738
739 llvm::gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
740 ImportLists,
741 ModuleToSummariesForIndex);
742 }
743
744 /**
722745 * Perform internalization.
723746 */
724747 void ThinLTOCodeGenerator::internalize(Module &TheModule,
417417 #endif
418418 }
419419
420 /// Compute the set of summaries needed for a ThinLTO backend compilation of
421 /// \p ModulePath.
422 void llvm::gatherImportedSummariesForModule(
423 StringRef ModulePath,
424 const StringMap &ModuleToDefinedGVSummaries,
425 const StringMap &ImportLists,
426 std::map &ModuleToSummariesForIndex) {
427 // Include all summaries from the importing module.
428 ModuleToSummariesForIndex[ModulePath] =
429 ModuleToDefinedGVSummaries.lookup(ModulePath);
430 auto ModuleImports = ImportLists.find(ModulePath);
431 if (ModuleImports != ImportLists.end()) {
432 // Include summaries for imports.
433 for (auto &ILI : ModuleImports->second) {
434 auto &SummariesForIndex = ModuleToSummariesForIndex[ILI.first()];
435 const auto &DefinedGVSummaries =
436 ModuleToDefinedGVSummaries.lookup(ILI.first());
437 for (auto &GI : ILI.second) {
438 const auto &DS = DefinedGVSummaries.find(GI.first);
439 assert(DS != DefinedGVSummaries.end() &&
440 "Expected a defined summary for imported global value");
441 SummariesForIndex[GI.first] = DS->second;
442 }
443 }
444 }
445 }
446
420447 // Automatically import functions in Module \p DestModule based on the summaries
421448 // index.
422449 //
0 define void @g() {
1 entry:
2 ret void
3 }
0 ; RUN: opt -module-summary %s -o %t1.bc
1 ; RUN: opt -module-summary %p/Inputs/distributed_indexes.ll -o %t2.bc
2 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
3 ; RUN: llvm-lto -thinlto-action=distributedindexes -thinlto-index %t.index.bc %t1.bc %t2.bc
4 ; RUN: llvm-bcanalyzer -dump %t1.bc.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
5 ; RUN: llvm-bcanalyzer -dump %t2.bc.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
6
7 ; The backend index for this module contains summaries from itself and
8 ; Inputs/distributed_indexes.ll, as it imports from the latter.
9 ; BACKEND1:
10 ; BACKEND1-NEXT:
11 ; BACKEND1-NEXT:
12 ; BACKEND1-NEXT:
13 ; BACKEND1-NEXT:
14 ; BACKEND1-NEXT:
15 ; BACKEND1-NEXT:
16 ; BACKEND1-NEXT:
17 ; BACKEND1-NEXT:
18 ; BACKEND1-NEXT:
19 ; Check that the format is: op0=valueid, op1=offset, op2=funcguid,
20 ; where funcguid is the lower 64 bits of the function name MD5.
21 ; BACKEND1-NEXT:
22 ; BACKEND1-NEXT:
23 ; BACKEND1-NEXT:
24
25 ; The backend index for Input/distributed_indexes.ll contains summaries from
26 ; itself only, as it does not import anything.
27 ; BACKEND2:
28 ; BACKEND2-NEXT:
29 ; BACKEND2-NEXT:
30 ; BACKEND2-NEXT:
31 ; BACKEND2-NEXT:
32 ; BACKEND2-NEXT:
33 ; BACKEND2-NEXT:
34 ; BACKEND2-NEXT:
35 ; Check that the format is: op0=valueid, op1=offset, op2=funcguid,
36 ; where funcguid is the lower 64 bits of the function name MD5.
37 ; BACKEND2-NEXT:
38 ; BACKEND2-NEXT:
39
40 declare void @g(...)
41
42 define void @f() {
43 entry:
44 call void (...) @g()
45 ret void
46 }
2020 ; RUN: --plugin-opt=thinlto \
2121 ; RUN: --plugin-opt=thinlto-index-only \
2222 ; RUN: -shared %t.o %t2.o -o %t3
23 ; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED
23 ; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
24 ; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
2425 ; RUN: not test -e %t3
2526
2627 ; Ensure gold generates an index as well as a binary by default in ThinLTO mode.
5253 ; NM: T f
5354 ; NM2: T {{f|g}}
5455
56 ; The backend index for this module contains summaries from itself and
57 ; Inputs/thinlto.ll, as it imports from the latter.
58 ; BACKEND1:
59 ; BACKEND1-NEXT:
60 ; BACKEND1-NEXT:
61 ; BACKEND1-NEXT:
62 ; BACKEND1-NEXT:
63 ; BACKEND1-NEXT:
64 ; BACKEND1-NEXT:
65 ; BACKEND1-NEXT:
66 ; BACKEND1-NEXT:
67 ; BACKEND1-NEXT:
68 ; Check that the format is: op0=valueid, op1=offset, op2=funcguid,
69 ; where funcguid is the lower 64 bits of the function name MD5.
70 ; BACKEND1-NEXT:
71 ; BACKEND1-NEXT:
72 ; BACKEND1-NEXT:
73
74 ; The backend index for Input/thinlto.ll contains summaries from itself only,
75 ; as it does not import anything.
76 ; BACKEND2:
77 ; BACKEND2-NEXT:
78 ; BACKEND2-NEXT:
79 ; BACKEND2-NEXT:
80 ; BACKEND2-NEXT:
81 ; BACKEND2-NEXT:
82 ; BACKEND2-NEXT:
83 ; BACKEND2-NEXT:
84 ; Check that the format is: op0=valueid, op1=offset, op2=funcguid,
85 ; where funcguid is the lower 64 bits of the function name MD5.
86 ; BACKEND2-NEXT:
87 ; BACKEND2-NEXT:
88
5589 ; COMBINED:
5690 ; COMBINED-NEXT:
5791 ; COMBINED-NEXT:
4040 #include "llvm/Support/raw_ostream.h"
4141 #include "llvm/Support/thread.h"
4242 #include "llvm/Transforms/IPO.h"
43 #include "llvm/Transforms/IPO/FunctionImport.h"
4344 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
4445 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
4546 #include "llvm/Transforms/Utils/GlobalStatus.h"
178179 static bool thinlto = false;
179180 // If false, all ThinLTO backend compilations through code gen are performed
180181 // using multiple threads in the gold-plugin, before handing control back to
181 // gold. If true, exit after creating the combined index, the assuming is
182 // gold. If true, write individual backend index files which reflect
183 // the import decisions, and exit afterwards. The assumption is
182184 // that the build system will launch the backend processes.
183185 static bool thinlto_index_only = false;
184186 // Additional options to pass into the code generator.
11891191 Task.cleanup();
11901192 }
11911193
1192 /// gold informs us that all symbols have been read. At this point, we use
1193 /// get_symbols to see if any of our definitions have been overridden by a
1194 /// native object file. Then, perform optimization and codegen.
1195 static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
1196 if (Modules.empty())
1197 return LDPS_OK;
1198
1199 if (unsigned NumOpts = options::extra.size())
1200 cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
1201
1202 // If we are doing ThinLTO compilation, simply build the combined
1203 // module index/summary and emit it. We don't need to parse the modules
1204 // and link them in this case.
1205 if (options::thinlto) {
1206 ModuleSummaryIndex CombinedIndex;
1207 uint64_t NextModuleId = 0;
1194 /// Perform ThinLTO link, which creates the combined index file.
1195 /// Also, either launch backend threads or (under thinlto-index-only)
1196 /// emit individual index files for distributed backends and exit.
1197 static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
1198 ModuleSummaryIndex CombinedIndex;
1199 uint64_t NextModuleId = 0;
1200 for (claimed_file &F : Modules) {
1201 PluginInputFile InputFile(F.handle);
1202
1203 std::unique_ptr Index =
1204 getModuleSummaryIndexForFile(F, InputFile.file());
1205
1206 // Skip files without a module summary.
1207 if (Index)
1208 CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
1209 }
1210
1211 if (options::thinlto_index_only) {
1212 // Collect for each module the list of function it defines (GUID ->
1213 // Summary).
1214 StringMap>
1215 ModuleToDefinedGVSummaries(NextModuleId);
1216 CombinedIndex.collectDefinedGVSummariesPerModule(
1217 ModuleToDefinedGVSummaries);
1218
1219 // FIXME: We want to do this for the case where the threads are launched
1220 // from gold as well, in which case this will be moved out of the
1221 // thinlto_index_only handling, and the function importer will be invoked
1222 // directly using the Lists.
1223 StringMap ImportLists(NextModuleId);
1224 StringMap ExportLists(NextModuleId);
1225 ComputeCrossModuleImport(CombinedIndex, ModuleToDefinedGVSummaries,
1226 ImportLists, ExportLists);
1227
1228 // For each input bitcode file, generate an individual index that
1229 // contains summaries only for its own global values, and for any that
1230 // should be imported.
12081231 for (claimed_file &F : Modules) {
12091232 PluginInputFile InputFile(F.handle);
1210
1211 std::unique_ptr Index =
1212 getModuleSummaryIndexForFile(F, InputFile.file());
1213
1214 // Skip files without a module summary.
1215 if (Index)
1216 CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
1217 }
1218
1233 std::error_code EC;
1234 raw_fd_ostream OS((Twine(InputFile.file().name) + ".thinlto.bc").str(),
1235 EC, sys::fs::OpenFlags::F_None);
1236 if (EC)
1237 message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
1238 InputFile.file().name, EC.message().c_str());
1239 // Build a map of module to the GUIDs and summary objects that should
1240 // be written to its index.
1241 std::map ModuleToSummariesForIndex;
1242 gatherImportedSummariesForModule(InputFile.file().name,
1243 ModuleToDefinedGVSummaries, ImportLists,
1244 ModuleToSummariesForIndex);
1245 WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);
1246 }
1247
1248 cleanup_hook();
1249 exit(0);
1250 }
1251
1252 // Create OS in nested scope so that it will be closed on destruction.
1253 {
12191254 std::error_code EC;
12201255 raw_fd_ostream OS(output_name + ".thinlto.bc", EC,
12211256 sys::fs::OpenFlags::F_None);
12231258 message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
12241259 output_name.data(), EC.message().c_str());
12251260 WriteIndexToFile(CombinedIndex, OS);
1226 OS.close();
1227
1228 if (options::thinlto_index_only) {
1229 cleanup_hook();
1230 exit(0);
1231 }
1232
1233 thinLTOBackends(ApiFile, CombinedIndex);
1261 }
1262
1263 thinLTOBackends(ApiFile, CombinedIndex);
1264 return LDPS_OK;
1265 }
1266
1267 /// gold informs us that all symbols have been read. At this point, we use
1268 /// get_symbols to see if any of our definitions have been overridden by a
1269 /// native object file. Then, perform optimization and codegen.
1270 static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
1271 if (Modules.empty())
12341272 return LDPS_OK;
1235 }
1273
1274 if (unsigned NumOpts = options::extra.size())
1275 cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
1276
1277 if (options::thinlto)
1278 return thinLTOLink(ApiFile);
12361279
12371280 LLVMContext Context;
12381281 Context.setDiscardValueNames(options::TheOutputType !=
6565
6666 enum ThinLTOModes {
6767 THINLINK,
68 THINDISTRIBUTE,
6869 THINPROMOTE,
6970 THINIMPORT,
7071 THININTERNALIZE,
7980 clEnumValN(
8081 THINLINK, "thinlink",
8182 "ThinLink: produces the index by linking only the summaries."),
83 clEnumValN(THINDISTRIBUTE, "distributedindexes",
84 "Produces individual indexes for distributed backends."),
8285 clEnumValN(THINPROMOTE, "promote",
8386 "Perform pre-import promotion (requires -thinlto-index)."),
8487 clEnumValN(THINIMPORT, "import", "Perform both promotion and "
353356 switch (ThinLTOMode) {
354357 case THINLINK:
355358 return thinLink();
359 case THINDISTRIBUTE:
360 return distributedIndexes();
356361 case THINPROMOTE:
357362 return promote();
358363 case THINIMPORT:
395400 return;
396401 }
397402
403 /// Load the combined index from disk, then compute and generate
404 /// individual index files suitable for ThinLTO distributed backend builds
405 /// on the files mentioned on the command line (these must match the index
406 /// content).
407 void distributedIndexes() {
408 if (InputFilenames.size() != 1 && !OutputFilename.empty())
409 report_fatal_error("Can't handle a single output filename and multiple "
410 "input files, do not provide an output filename and "
411 "the output files will be suffixed from the input "
412 "ones.");
413
414 auto Index = loadCombinedIndex();
415 for (auto &Filename : InputFilenames) {
416 // Build a map of module to the GUIDs and summary objects that should
417 // be written to its index.
418 std::map ModuleToSummariesForIndex;
419 ThinLTOCodeGenerator::gatherImportedSummariesForModule(
420 Filename, *Index, ModuleToSummariesForIndex);
421
422 std::string OutputName = OutputFilename;
423 if (OutputName.empty()) {
424 OutputName = Filename + ".thinlto.bc";
425 }
426 std::error_code EC;
427 raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::F_None);
428 error(EC, "error opening the file '" + OutputName + "'");
429 WriteIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
430 }
431 }
432
398433 /// Load the combined index from disk, then load every file referenced by
399434 /// the index and add them to the generator, finally perform the promotion
400435 /// on the files mentioned on the command line (these must match the index