llvm.org GIT mirror llvm / 0c4a898
[ThinLTO] Emit individual index files for distributed backends 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 The individual index file encodes the summary and module information required for implementing the importing/exporting decisions made for a given module in the thin link step. This is in place of the current mechanism that uses the combined index to make importing decisions in each back end independently. It is an enabler for doing global summary based optimizations in the thin link step (which will be recorded in the individual index files), and reduces the size of the index that must be sent to each backend process, and the amount of work to scan it in the backends. Rather than create entirely new ModuleSummaryIndex structures (and all the included unique_ptrs) for each backend index file, a map is created to record all of the GUID and summary pointers needed for a particular index file. The IndexBitcodeWriter walks this map instead of the full index (hiding the details of managing the appropriate summary iteration in a new iterator subclass). This is more efficient than walking the entire combined index and filtering out just the needed summaries during each backend bitcode index write. Depends on D19481. Reviewers: joker.eph Subscribers: llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D19556 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268627 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 3 years ago
11 changed file(s) with 492 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
200200 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
201201
202202 /**
203 * Compute the list of summaries needed for importing into module.
204 */
205 static void gatherImportedSummariesForModule(
206 StringRef ModulePath, ModuleSummaryIndex &Index,
207 std::map &ModuleToSummariesForIndex);
208
209 /**
203210 * Perform internalization.
204211 */
205212 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 ModuleSummariesBack =
336 std::prev(Writer.ModuleToSummariesForIndex->end());
337 ModuleSummariesIter = Writer.ModuleToSummariesForIndex->begin();
338 ModuleGVSummariesIter = !IsAtEnd ? ModuleSummariesIter->second.begin()
339 : ModuleSummariesBack->second.end();
340 } else if (!Writer.ModuleToSummariesForIndex &&
341 Writer.Index.begin() != Writer.Index.end()) {
342 IndexSummariesBack = std::prev(Writer.Index.end());
343 IndexSummariesIter = Writer.Index.begin();
344 IndexGVSummariesIter = !IsAtEnd ? IndexSummariesIter->second.begin()
345 : IndexSummariesBack->second.end();
346 }
347 }
348
349 /// Increment the appropriate set of iterators.
350 iterator &operator++() {
351 // First the inner iterator is incremented, then if it is at the end
352 // and there are more outer iterations to go, the inner is reset to
353 // the start of the next inner list.
354 if (Writer.ModuleToSummariesForIndex) {
355 ++ModuleGVSummariesIter;
356 if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
357 ModuleSummariesIter != ModuleSummariesBack) {
358 ++ModuleSummariesIter;
359 ModuleGVSummariesIter = ModuleSummariesIter->second.begin();
360 }
361 } else {
362 ++IndexGVSummariesIter;
363 if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
364 IndexSummariesIter != IndexSummariesBack) {
365 ++IndexSummariesIter;
366 IndexGVSummariesIter = IndexSummariesIter->second.begin();
367 }
368 }
369 return *this;
370 }
371
372 /// Access the pair corresponding to the current
373 /// outer and inner iterator positions.
374 GVInfo operator*() {
375 if (Writer.ModuleToSummariesForIndex)
376 return std::make_pair(ModuleGVSummariesIter->first,
377 ModuleGVSummariesIter->second);
378 return std::make_pair(IndexSummariesIter->first,
379 IndexGVSummariesIter->get());
380 }
381
382 /// Checks if the iterators are equal, with special handling for empty
383 /// indexes.
384 bool operator==(const iterator &RHS) const {
385 if (Writer.ModuleToSummariesForIndex) {
386 // First ensure that both are writing the same subset.
387 if (Writer.ModuleToSummariesForIndex !=
388 RHS.Writer.ModuleToSummariesForIndex)
389 return false;
390 // Already determined above that maps are the same, so if one is
391 // empty, they both are.
392 if (Writer.ModuleToSummariesForIndex->empty())
393 return true;
394 return ModuleGVSummariesIter == RHS.ModuleGVSummariesIter;
395 }
396 // First ensure RHS also writing the full index, and that both are
397 // writing the same full index.
398 if (RHS.Writer.ModuleToSummariesForIndex ||
399 &Writer.Index != &RHS.Writer.Index)
400 return false;
401 // Already determined above that maps are the same, so if one is
402 // empty, they both are.
403 if (Writer.Index.begin() == Writer.Index.end())
404 return true;
405 return IndexGVSummariesIter == RHS.IndexGVSummariesIter;
406 }
407 };
408
409 /// Obtain the start iterator over the summaries to be written.
410 iterator begin() { return iterator(*this, /*IsAtEnd=*/false); }
411 /// Obtain the end iterator over the summaries to be written.
412 iterator end() { return iterator(*this, /*IsAtEnd=*/true); }
285413
286414 private:
287415 /// Main entry point for writing a combined index to bitcode, invoked by
292420 void writeModStrings();
293421 void writeCombinedValueSymbolTable();
294422 void writeCombinedGlobalValueSummary();
423
424 /// Indicates whether the provided \p ModulePath should be written into
425 /// the module string table, e.g. if full index written or if it is in
426 /// the provided subset.
427 bool doIncludeModule(StringRef ModulePath) {
428 return !ModuleToSummariesForIndex ||
429 ModuleToSummariesForIndex->count(ModulePath);
430 }
295431
296432 bool hasValueId(GlobalValue::GUID ValGUID) {
297433 const auto &VMI = GUIDToValueIdMap.find(ValGUID);
29623098
29633099 SmallVector Vals;
29643100 for (const auto &MPSE : Index.modulePaths()) {
3101 if (!doIncludeModule(MPSE.getKey()))
3102 continue;
29653103 StringEncoding Bits =
29663104 getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size());
29673105 unsigned AbbrevToUse = Abbrev8Bit;
32173355 NameVals.clear();
32183356 };
32193357
3220 for (const auto &GSI : Index) {
3221 for (auto &SI : GSI.second) {
3222 GlobalValueSummary *S = SI.get();
3223 assert(S);
3224
3225 assert(hasValueId(GSI.first));
3226 unsigned ValueId = getValueId(GSI.first);
3227 SummaryToValueIdMap[S] = ValueId;
3228
3229 if (auto *AS = dyn_cast(S)) {
3230 // Will process aliases as a post-pass because the reader wants all
3231 // global to be loaded first.
3232 Aliases.push_back(AS);
3233 continue;
3234 }
3235
3236 if (auto *VS = dyn_cast(S)) {
3237 NameVals.push_back(ValueId);
3238 NameVals.push_back(Index.getModuleId(VS->modulePath()));
3239 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
3240 for (auto &RI : VS->refs()) {
3241 NameVals.push_back(getValueId(RI.getGUID()));
3242 }
3243
3244 // Emit the finished record.
3245 Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
3246 FSModRefsAbbrev);
3247 NameVals.clear();
3248 MaybeEmitOriginalName(*S);
3249 continue;
3250 }
3251
3252 auto *FS = cast(S);
3358 for (const auto &I : *this) {
3359 GlobalValueSummary *S = I.second;
3360 assert(S);
3361
3362 assert(hasValueId(I.first));
3363 unsigned ValueId = getValueId(I.first);
3364 SummaryToValueIdMap[S] = ValueId;
3365
3366 if (auto *AS = dyn_cast(S)) {
3367 // Will process aliases as a post-pass because the reader wants all
3368 // global to be loaded first.
3369 Aliases.push_back(AS);
3370 continue;
3371 }
3372
3373 if (auto *VS = dyn_cast(S)) {
32533374 NameVals.push_back(ValueId);
3254 NameVals.push_back(Index.getModuleId(FS->modulePath()));
3255 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
3256 NameVals.push_back(FS->instCount());
3257 NameVals.push_back(FS->refs().size());
3258
3259 for (auto &RI : FS->refs()) {
3375 NameVals.push_back(Index.getModuleId(VS->modulePath()));
3376 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
3377 for (auto &RI : VS->refs()) {
32603378 NameVals.push_back(getValueId(RI.getGUID()));
32613379 }
32623380
3263 bool HasProfileData = false;
3264 for (auto &EI : FS->calls()) {
3265 HasProfileData |= EI.second.ProfileCount != 0;
3266 if (HasProfileData)
3267 break;
3268 }
3269
3270 for (auto &EI : FS->calls()) {
3271 // If this GUID doesn't have a value id, it doesn't have a function
3272 // summary and we don't need to record any calls to it.
3273 if (!hasValueId(EI.first.getGUID()))
3274 continue;
3275 NameVals.push_back(getValueId(EI.first.getGUID()));
3276 assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
3277 NameVals.push_back(EI.second.CallsiteCount);
3278 if (HasProfileData)
3279 NameVals.push_back(EI.second.ProfileCount);
3280 }
3281
3282 unsigned FSAbbrev =
3283 (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
3284 unsigned Code =
3285 (HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
3286
32873381 // Emit the finished record.
3288 Stream.EmitRecord(Code, NameVals, FSAbbrev);
3382 Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
3383 FSModRefsAbbrev);
32893384 NameVals.clear();
32903385 MaybeEmitOriginalName(*S);
3291 }
3386 continue;
3387 }
3388
3389 auto *FS = cast(S);
3390 NameVals.push_back(ValueId);
3391 NameVals.push_back(Index.getModuleId(FS->modulePath()));
3392 NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
3393 NameVals.push_back(FS->instCount());
3394 NameVals.push_back(FS->refs().size());
3395
3396 for (auto &RI : FS->refs()) {
3397 NameVals.push_back(getValueId(RI.getGUID()));
3398 }
3399
3400 bool HasProfileData = false;
3401 for (auto &EI : FS->calls()) {
3402 HasProfileData |= EI.second.ProfileCount != 0;
3403 if (HasProfileData)
3404 break;
3405 }
3406
3407 for (auto &EI : FS->calls()) {
3408 // If this GUID doesn't have a value id, it doesn't have a function
3409 // summary and we don't need to record any calls to it.
3410 if (!hasValueId(EI.first.getGUID()))
3411 continue;
3412 NameVals.push_back(getValueId(EI.first.getGUID()));
3413 assert(EI.second.CallsiteCount > 0 && "Expected at least one callsite");
3414 NameVals.push_back(EI.second.CallsiteCount);
3415 if (HasProfileData)
3416 NameVals.push_back(EI.second.ProfileCount);
3417 }
3418
3419 unsigned FSAbbrev = (HasProfileData ? FSCallsProfileAbbrev : FSCallsAbbrev);
3420 unsigned Code =
3421 (HasProfileData ? bitc::FS_COMBINED_PROFILE : bitc::FS_COMBINED);
3422
3423 // Emit the finished record.
3424 Stream.EmitRecord(Code, NameVals, FSAbbrev);
3425 NameVals.clear();
3426 MaybeEmitOriginalName(*S);
32923427 }
32933428
32943429 for (auto *AS : Aliases) {
35623697
35633698 // Write the specified module summary index to the given raw output stream,
35643699 // where it will be written in a new bitcode block. This is used when
3565 // writing the combined index file for ThinLTO.
3566 void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
3700 // writing the combined index file for ThinLTO. When writing a subset of the
3701 // index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
3702 void llvm::WriteIndexToFile(
3703 const ModuleSummaryIndex &Index, raw_ostream &Out,
3704 std::map *ModuleToSummariesForIndex) {
35673705 SmallVector Buffer;
35683706 Buffer.reserve(256 * 1024);
35693707
3570 IndexBitcodeWriter IndexWriter(Buffer, Index);
3708 IndexBitcodeWriter IndexWriter(Buffer, Index, ModuleToSummariesForIndex);
35713709 IndexWriter.write();
35723710
35733711 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 "
342345 switch (ThinLTOMode) {
343346 case THINLINK:
344347 return thinLink();
348 case THINDISTRIBUTE:
349 return distributedIndexes();
345350 case THINPROMOTE:
346351 return promote();
347352 case THINIMPORT:
384389 return;
385390 }
386391
392 /// Load the combined index from disk, then compute and generate
393 /// individual index files suitable for ThinLTO distributed backend builds
394 /// on the files mentioned on the command line (these must match the index
395 /// content).
396 void distributedIndexes() {
397 if (InputFilenames.size() != 1 && !OutputFilename.empty())
398 report_fatal_error("Can't handle a single output filename and multiple "
399 "input files, do not provide an output filename and "
400 "the output files will be suffixed from the input "
401 "ones.");
402
403 auto Index = loadCombinedIndex();
404 for (auto &Filename : InputFilenames) {
405 // Build a map of module to the GUIDs and summary objects that should
406 // be written to its index.
407 std::map ModuleToSummariesForIndex;
408 ThinLTOCodeGenerator::gatherImportedSummariesForModule(
409 Filename, *Index, ModuleToSummariesForIndex);
410
411 std::string OutputName = OutputFilename;
412 if (OutputName.empty()) {
413 OutputName = Filename + ".thinlto.bc";
414 }
415 std::error_code EC;
416 raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::F_None);
417 error(EC, "error opening the file '" + OutputName + "'");
418 WriteIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
419 }
420 }
421
387422 /// Load the combined index from disk, then load every file referenced by
388423 /// the index and add them to the generator, finally perform the promotion
389424 /// on the files mentioned on the command line (these must match the index