llvm.org GIT mirror llvm / eb80fa1
Revert "[ThinLTO] Emit individual index files for distributed backends" MemorySanitizer: use-of-uninitialized-value in lib/Bitcode/Writer/BitcodeWriter.cpp:364:70 http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/12544/steps/check-llvm%20msan/logs/stdio This reverts commit 0c4a898ea550699d1b2f4fe3767251c8f9a48d52. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268660 91177308-0d34-0410-b5e6-96231b3b80d8 Vitaly Buka 3 years ago
11 changed file(s) with 114 addition(s) and 492 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. 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);
99 /// writing the combined index file for ThinLTO.
100 void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out);
105101
106102 /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
107103 /// 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"
2221 #include "llvm/Support/CodeGen.h"
2322 #include "llvm/Support/MemoryBuffer.h"
2423 #include "llvm/Target/TargetOptions.h"
2726
2827 namespace llvm {
2928 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 /**
210203 * Perform internalization.
211204 */
212205 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);
10589 }
10690
10791 #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
269265 /// Map that holds the correspondence between the GUID used in the combined
270266 /// index and a value id generated by this class to use in references.
271267 std::map GUIDToValueIdMap;
275271
276272 public:
277273 /// Constructs a IndexBitcodeWriter object for the given combined index,
278 /// writing to the provided \p Buffer. When writing a subset of the index
279 /// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
274 /// writing to the provided \p Buffer.
280275 IndexBitcodeWriter(SmallVectorImpl &Buffer,
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
276 const ModuleSummaryIndex &Index)
277 : BitcodeWriter(Buffer), Index(Index) {
278 // Assign unique value ids to all functions in the index for use
287279 // in writing out the call graph edges. Save the mapping from GUID
288280 // to the new global value id to use when writing those edges, which
289281 // are currently saved in the index in terms of GUID.
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); }
282 for (auto &II : Index)
283 GUIDToValueIdMap[II.first] = ++GlobalValueId;
284 }
413285
414286 private:
415287 /// Main entry point for writing a combined index to bitcode, invoked by
420292 void writeModStrings();
421293 void writeCombinedValueSymbolTable();
422294 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 }
431295
432296 bool hasValueId(GlobalValue::GUID ValGUID) {
433297 const auto &VMI = GUIDToValueIdMap.find(ValGUID);
30982962
30992963 SmallVector Vals;
31002964 for (const auto &MPSE : Index.modulePaths()) {
3101 if (!doIncludeModule(MPSE.getKey()))
3102 continue;
31032965 StringEncoding Bits =
31042966 getStringEncoding(MPSE.getKey().data(), MPSE.getKey().size());
31052967 unsigned AbbrevToUse = Abbrev8Bit;
33553217 NameVals.clear();
33563218 };
33573219
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)) {
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);
33743253 NameVals.push_back(ValueId);
3375 NameVals.push_back(Index.getModuleId(VS->modulePath()));
3376 NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
3377 for (auto &RI : VS->refs()) {
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()) {
33783260 NameVals.push_back(getValueId(RI.getGUID()));
33793261 }
33803262
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
33813287 // Emit the finished record.
3382 Stream.EmitRecord(bitc::FS_COMBINED_GLOBALVAR_INIT_REFS, NameVals,
3383 FSModRefsAbbrev);
3288 Stream.EmitRecord(Code, NameVals, FSAbbrev);
33843289 NameVals.clear();
33853290 MaybeEmitOriginalName(*S);
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);
3291 }
34273292 }
34283293
34293294 for (auto *AS : Aliases) {
36973562
36983563 // Write the specified module summary index to the given raw output stream,
36993564 // where it will be written in a new bitcode block. This is used when
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) {
3565 // writing the combined index file for ThinLTO.
3566 void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
37053567 SmallVector Buffer;
37063568 Buffer.reserve(256 * 1024);
37073569
3708 IndexBitcodeWriter IndexWriter(Buffer, Index, ModuleToSummariesForIndex);
3570 IndexBitcodeWriter IndexWriter(Buffer, Index);
37093571 IndexWriter.write();
37103572
37113573 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 /**
745722 * Perform internalization.
746723 */
747724 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
447420 // Automatically import functions in Module \p DestModule based on the summaries
448421 // index.
449422 //
+0
-4
test/ThinLTO/X86/Inputs/distributed_indexes.ll less more
None define void @g() {
1 entry:
2 ret void
3 }
+0
-47
test/ThinLTO/X86/distributed_indexes.ll less more
None ; 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 %t.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
24 ; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
23 ; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED
2524 ; RUN: not test -e %t3
2625
2726 ; Ensure gold generates an index as well as a binary by default in ThinLTO mode.
5352 ; NM: T f
5453 ; NM2: T {{f|g}}
5554
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
8955 ; COMBINED:
9056 ; COMBINED-NEXT:
9157 ; 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"
4443 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
4544 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
4645 #include "llvm/Transforms/Utils/GlobalStatus.h"
179178 static bool thinlto = false;
180179 // If false, all ThinLTO backend compilations through code gen are performed
181180 // using multiple threads in the gold-plugin, before handing control back to
182 // gold. If true, write individual backend index files which reflect
183 // the import decisions, and exit afterwards. The assumption is
181 // gold. If true, exit after creating the combined index, the assuming is
184182 // that the build system will launch the backend processes.
185183 static bool thinlto_index_only = false;
186184 // Additional options to pass into the code generator.
11911189 Task.cleanup();
11921190 }
11931191
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.
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;
12311208 for (claimed_file &F : Modules) {
12321209 PluginInputFile InputFile(F.handle);
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 {
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
12541219 std::error_code EC;
12551220 raw_fd_ostream OS(output_name + ".thinlto.bc", EC,
12561221 sys::fs::OpenFlags::F_None);
12581223 message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
12591224 output_name.data(), EC.message().c_str());
12601225 WriteIndexToFile(CombinedIndex, OS);
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())
1226 OS.close();
1227
1228 if (options::thinlto_index_only) {
1229 cleanup_hook();
1230 exit(0);
1231 }
1232
1233 thinLTOBackends(ApiFile, CombinedIndex);
12721234 return LDPS_OK;
1273
1274 if (unsigned NumOpts = options::extra.size())
1275 cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
1276
1277 if (options::thinlto)
1278 return thinLTOLink(ApiFile);
1235 }
12791236
12801237 LLVMContext Context;
12811238 Context.setDiscardValueNames(options::TheOutputType !=
6565
6666 enum ThinLTOModes {
6767 THINLINK,
68 THINDISTRIBUTE,
6968 THINPROMOTE,
7069 THINIMPORT,
7170 THININTERNALIZE,
8079 clEnumValN(
8180 THINLINK, "thinlink",
8281 "ThinLink: produces the index by linking only the summaries."),
83 clEnumValN(THINDISTRIBUTE, "distributedindexes",
84 "Produces individual indexes for distributed backends."),
8582 clEnumValN(THINPROMOTE, "promote",
8683 "Perform pre-import promotion (requires -thinlto-index)."),
8784 clEnumValN(THINIMPORT, "import", "Perform both promotion and "
356353 switch (ThinLTOMode) {
357354 case THINLINK:
358355 return thinLink();
359 case THINDISTRIBUTE:
360 return distributedIndexes();
361356 case THINPROMOTE:
362357 return promote();
363358 case THINIMPORT:
400395 return;
401396 }
402397
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
433398 /// Load the combined index from disk, then load every file referenced by
434399 /// the index and add them to the generator, finally perform the promotion
435400 /// on the files mentioned on the command line (these must match the index