diff options
Diffstat (limited to 'lib/LTO/LTO.cpp')
-rw-r--r-- | lib/LTO/LTO.cpp | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 64506890956a..1e345e7dd89e 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -44,6 +44,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" #include "llvm/Transforms/Utils/SplitModule.h" @@ -383,7 +384,9 @@ static bool isWeakObjectWithRWAccess(GlobalValueSummary *GVS) { static void thinLTOInternalizeAndPromoteGUID( GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, - function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { + function_ref<bool(StringRef, GlobalValue::GUID)> isExported, + function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> + isPrevailing) { for (auto &S : GVSummaryList) { if (isExported(S->modulePath(), GUID)) { if (GlobalValue::isLocalLinkage(S->linkage())) @@ -392,6 +395,8 @@ static void thinLTOInternalizeAndPromoteGUID( // Ignore local and appending linkage values since the linker // doesn't resolve them. !GlobalValue::isLocalLinkage(S->linkage()) && + (!GlobalValue::isInterposableLinkage(S->linkage()) || + isPrevailing(GUID, S.get())) && S->linkage() != GlobalValue::AppendingLinkage && // We can't internalize available_externally globals because this // can break function pointer equality. @@ -410,9 +415,12 @@ static void thinLTOInternalizeAndPromoteGUID( // as external and non-exported values as internal. void llvm::thinLTOInternalizeAndPromoteInIndex( ModuleSummaryIndex &Index, - function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { + function_ref<bool(StringRef, GlobalValue::GUID)> isExported, + function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> + isPrevailing) { for (auto &I : Index) - thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported); + thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported, + isPrevailing); } // Requires a destructor for std::vector<InputModule>. @@ -459,8 +467,8 @@ BitcodeModule &InputFile::getSingleBitcodeModule() { LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, Config &Conf) : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), - Ctx(Conf), CombinedModule(llvm::make_unique<Module>("ld-temp.o", Ctx)), - Mover(llvm::make_unique<IRMover>(*CombinedModule)) {} + Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)), + Mover(std::make_unique<IRMover>(*CombinedModule)) {} LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend), CombinedIndex(/*HaveGVs*/ false) { @@ -754,7 +762,8 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, // For now they aren't reported correctly by ModuleSymbolTable. auto &CommonRes = RegularLTO.Commons[Sym.getIRName()]; CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize()); - CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment()); + CommonRes.Align = + std::max(CommonRes.Align, MaybeAlign(Sym.getCommonAlignment())); CommonRes.Prevailing |= Res.Prevailing; } @@ -899,8 +908,7 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { GlobalValue::dropLLVMManglingEscape(Res.second.IRName)); if (Res.second.VisibleOutsideSummary && Res.second.Prevailing) - GUIDPreservedSymbols.insert(GlobalValue::getGUID( - GlobalValue::dropLLVMManglingEscape(Res.second.IRName))); + GUIDPreservedSymbols.insert(GUID); GUIDPrevailingResolutions[GUID] = Res.second.Prevailing ? PrevailingType::Yes : PrevailingType::No; @@ -996,6 +1004,8 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { GV->setLinkage(GlobalValue::InternalLinkage); } + RegularLTO.CombinedModule->addModuleFlag(Module::Error, "LTOPostLink", 1); + if (Conf.PostInternalizeModuleHook && !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) return Error::success(); @@ -1004,6 +1014,16 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex); } +static const char *libcallRoutineNames[] = { +#define HANDLE_LIBCALL(code, name) name, +#include "llvm/IR/RuntimeLibcalls.def" +#undef HANDLE_LIBCALL +}; + +ArrayRef<const char*> LTO::getRuntimeLibcallSymbols() { + return makeArrayRef(libcallRoutineNames); +} + /// This class defines the interface to the ThinLTO backend. class lto::ThinBackendProc { protected: @@ -1141,7 +1161,7 @@ ThinBackend lto::createInProcessThinBackend(unsigned ParallelismLevel) { return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, AddStreamFn AddStream, NativeObjectCache Cache) { - return llvm::make_unique<InProcessThinBackend>( + return std::make_unique<InProcessThinBackend>( Conf, CombinedIndex, ParallelismLevel, ModuleToDefinedGVSummaries, AddStream, Cache); }; @@ -1204,7 +1224,7 @@ public: std::error_code EC; raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC, - sys::fs::OpenFlags::F_None); + sys::fs::OpenFlags::OF_None); if (EC) return errorCodeToError(EC); WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); @@ -1231,7 +1251,7 @@ ThinBackend lto::createWriteIndexesThinBackend( return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, AddStreamFn AddStream, NativeObjectCache Cache) { - return llvm::make_unique<WriteIndexesThinBackend>( + return std::make_unique<WriteIndexesThinBackend>( Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix, ShouldEmitImportsFiles, LinkedObjectsFile, OnWrite); }; @@ -1274,6 +1294,15 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, if (DumpThinCGSCCs) ThinLTO.CombinedIndex.dumpSCCs(outs()); + std::set<GlobalValue::GUID> ExportedGUIDs; + + // Perform index-based WPD. This will return immediately if there are + // no index entries in the typeIdMetadata map (e.g. if we are instead + // performing IR-based WPD in hybrid regular/thin LTO mode). + std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap; + runWholeProgramDevirtOnIndex(ThinLTO.CombinedIndex, ExportedGUIDs, + LocalWPDTargetsMap); + if (Conf.OptLevel > 0) ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, ImportLists, ExportLists); @@ -1282,7 +1311,6 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, // at -O0 because summary-based DCE is implemented using internalization, and // we must apply DCE consistently with the full LTO module in order to avoid // undefined references during the final link. - std::set<GlobalValue::GUID> ExportedGUIDs; for (auto &Res : GlobalResolutions) { // If the symbol does not have external references or it is not prevailing, // then not need to mark it as exported from a ThinLTO partition. @@ -1308,12 +1336,19 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, ExportList->second.count(GUID)) || ExportedGUIDs.count(GUID); }; - thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); + + // Update local devirtualized targets that were exported by cross-module + // importing or by other devirtualizations marked in the ExportedGUIDs set. + updateIndexWPDForExports(ThinLTO.CombinedIndex, isExported, + LocalWPDTargetsMap); auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) { return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath(); }; + thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported, + isPrevailing); + auto recordNewLinkage = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID, GlobalValue::LinkageTypes NewLinkage) { @@ -1368,7 +1403,7 @@ lto::setupStatsFile(StringRef StatsFilename) { llvm::EnableStatistics(false); std::error_code EC; auto StatsFile = - llvm::make_unique<ToolOutputFile>(StatsFilename, EC, sys::fs::F_None); + std::make_unique<ToolOutputFile>(StatsFilename, EC, sys::fs::OF_None); if (EC) return errorCodeToError(EC); |