diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index 670097010085..fc1e70b1b3d3 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -18,9 +18,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" -#include "llvm/InitializePasses.h" #include "llvm/Object/ModuleSymbolTable.h" -#include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" @@ -148,6 +146,14 @@ void promoteTypeIds(Module &M, StringRef ModuleId) { } } + if (Function *TypeCheckedLoadRelativeFunc = M.getFunction( + Intrinsic::getName(Intrinsic::type_checked_load_relative))) { + for (const Use &U : TypeCheckedLoadRelativeFunc->uses()) { + auto CI = cast<CallInst>(U.getUser()); + ExternalizeTypeId(CI, 2); + } + } + for (GlobalObject &GO : M.global_objects()) { SmallVector<MDNode *, 1> MDs; GO.getMetadata(LLVMContext::MD_type, MDs); @@ -196,6 +202,13 @@ void simplifyExternals(Module &M) { F.eraseFromParent(); } + for (GlobalIFunc &I : llvm::make_early_inc_range(M.ifuncs())) { + if (I.use_empty()) + I.eraseFromParent(); + else + assert(I.getResolverFunction() && "ifunc misses its resolver function"); + } + for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) { if (GV.isDeclaration() && GV.use_empty()) { GV.eraseFromParent(); @@ -246,6 +259,16 @@ static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM, appendToUsed(DestM, NewUsed); } +#ifndef NDEBUG +static bool enableUnifiedLTO(Module &M) { + bool UnifiedLTO = false; + if (auto *MD = + mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("UnifiedLTO"))) + UnifiedLTO = MD->getZExtValue(); + return UnifiedLTO; +} +#endif + // If it's possible to split M into regular and thin LTO parts, do so and write // a multi-module bitcode file with the two parts to OS. Otherwise, write only a // regular LTO bitcode file to OS. @@ -254,18 +277,20 @@ void splitAndWriteThinLTOBitcode( function_ref<AAResults &(Function &)> AARGetter, Module &M) { std::string ModuleId = getUniqueModuleId(&M); if (ModuleId.empty()) { + assert(!enableUnifiedLTO(M)); // We couldn't generate a module ID for this module, write it out as a // regular LTO module with an index for summary-based dead stripping. ProfileSummaryInfo PSI(M); M.addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI); - WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index); + WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index, + /*UnifiedLTO=*/false); if (ThinLinkOS) // We don't have a ThinLTO part, but still write the module to the // ThinLinkOS if requested so that the expected output file is produced. WriteBitcodeToFile(M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false, - &Index); + &Index, /*UnifiedLTO=*/false); return; } @@ -503,15 +528,17 @@ bool hasTypeMetadata(Module &M) { return false; } -void writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS, +bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS, function_ref<AAResults &(Function &)> AARGetter, Module &M, const ModuleSummaryIndex *Index) { std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr; // See if this module has any type metadata. If so, we try to split it // or at least promote type ids to enable WPD. if (hasTypeMetadata(M)) { - if (enableSplitLTOUnit(M)) - return splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M); + if (enableSplitLTOUnit(M)) { + splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M); + return true; + } // Promote type ids as needed for index-based WPD. std::string ModuleId = getUniqueModuleId(&M); if (!ModuleId.empty()) { @@ -544,6 +571,7 @@ void writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS, // given OS. if (ThinLinkOS && Index) writeThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash); + return false; } } // anonymous namespace @@ -552,10 +580,11 @@ PreservedAnalyses llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) { FunctionAnalysisManager &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); - writeThinLTOBitcode(OS, ThinLinkOS, - [&FAM](Function &F) -> AAResults & { - return FAM.getResult<AAManager>(F); - }, - M, &AM.getResult<ModuleSummaryIndexAnalysis>(M)); - return PreservedAnalyses::all(); + bool Changed = writeThinLTOBitcode( + OS, ThinLinkOS, + [&FAM](Function &F) -> AAResults & { + return FAM.getResult<AAManager>(F); + }, + M, &AM.getResult<ModuleSummaryIndexAnalysis>(M)); + return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); } |