diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 157 |
2 files changed, 90 insertions, 71 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 34cca32e06e..3ce23152d0c 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -156,7 +156,7 @@ static void computeCacheKey( AddUint64(Entry.second.size()); for (auto &Fn : Entry.second) - AddUint64(Fn.first); + AddUint64(Fn); } // Include the hash for the resolved ODR. @@ -221,7 +221,7 @@ static void computeCacheKey( // so we need to collect their used resolutions as well. for (auto &ImpM : ImportList) for (auto &ImpF : ImpM.second) - AddUsedThings(Index.findSummaryInModule(ImpF.first, ImpM.first())); + AddUsedThings(Index.findSummaryInModule(ImpF, ImpM.first())); auto AddTypeIdSummary = [&](StringRef TId, const TypeIdSummary &S) { AddString(TId); diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index c2907937e70..15808a07389 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -262,7 +262,7 @@ static void computeImportForReferencedGlobals( !RefSummary->modulePath().empty() && !GlobalValue::isInterposableLinkage(RefSummary->linkage()) && RefSummary->refs().empty()) { - ImportList[RefSummary->modulePath()][VI.getGUID()] = 1; + ImportList[RefSummary->modulePath()].insert(VI.getGUID()); if (ExportLists) (*ExportLists)[RefSummary->modulePath()].insert(VI.getGUID()); break; @@ -278,7 +278,8 @@ static void computeImportForFunction( const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, SmallVectorImpl<EdgeInfo> &Worklist, FunctionImporter::ImportMapTy &ImportList, - StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) { + StringMap<FunctionImporter::ExportSetTy> *ExportLists, + FunctionImporter::ImportThresholdsTy &ImportThresholds) { computeImportForReferencedGlobals(Summary, DefinedGVSummaries, ImportList, ExportLists); static int ImportCount = 0; @@ -315,19 +316,85 @@ static void computeImportForFunction( const auto NewThreshold = Threshold * GetBonusMultiplier(Edge.second.getHotness()); - auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold, - Summary.modulePath()); - if (!CalleeSummary) { - LLVM_DEBUG( - dbgs() << "ignored! No qualifying callee with summary found.\n"); - continue; - } + auto IT = ImportThresholds.insert( + std::make_pair(VI.getGUID(), std::make_pair(NewThreshold, nullptr))); + bool PreviouslyVisited = !IT.second; + auto &ProcessedThreshold = IT.first->second.first; + auto &CalleeSummary = IT.first->second.second; + + const FunctionSummary *ResolvedCalleeSummary = nullptr; + if (CalleeSummary) { + assert(PreviouslyVisited); + // Since the traversal of the call graph is DFS, we can revisit a function + // a second time with a higher threshold. In this case, it is added back + // to the worklist with the new threshold (so that its own callee chains + // can be considered with the higher threshold). + if (NewThreshold <= ProcessedThreshold) { + LLVM_DEBUG( + dbgs() << "ignored! Target was already imported with Threshold " + << ProcessedThreshold << "\n"); + continue; + } + // Update with new larger threshold. + ProcessedThreshold = NewThreshold; + ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary); + } else { + // If we already rejected importing a callee at the same or higher + // threshold, don't waste time calling selectCallee. + if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) { + LLVM_DEBUG( + dbgs() << "ignored! Target was already rejected with Threshold " + << ProcessedThreshold << "\n"); + continue; + } - // "Resolve" the summary - const auto *ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary->getBaseObject()); + CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold, + Summary.modulePath()); + if (!CalleeSummary) { + // Update with new larger threshold if this was a retry (otherwise + // we would have already inserted with NewThreshold above). + if (PreviouslyVisited) + ProcessedThreshold = NewThreshold; + LLVM_DEBUG( + dbgs() << "ignored! No qualifying callee with summary found.\n"); + continue; + } - assert(ResolvedCalleeSummary->instCount() <= NewThreshold && - "selectCallee() didn't honor the threshold"); + // "Resolve" the summary + CalleeSummary = CalleeSummary->getBaseObject(); + ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary); + + assert(ResolvedCalleeSummary->instCount() <= NewThreshold && + "selectCallee() didn't honor the threshold"); + + auto ExportModulePath = ResolvedCalleeSummary->modulePath(); + auto ILI = ImportList[ExportModulePath].insert(VI.getGUID()); + // We previously decided to import this GUID definition if it was already + // inserted in the set of imports from the exporting module. + bool PreviouslyImported = !ILI.second; + + // Make exports in the source module. + if (ExportLists) { + auto &ExportList = (*ExportLists)[ExportModulePath]; + ExportList.insert(VI.getGUID()); + if (!PreviouslyImported) { + // This is the first time this function was exported from its source + // module, so mark all functions and globals it references as exported + // to the outside if they are defined in the same source module. + // For efficiency, we unconditionally add all the referenced GUIDs + // to the ExportList for this module, and will prune out any not + // defined in the module later in a single pass. + for (auto &Edge : ResolvedCalleeSummary->calls()) { + auto CalleeGUID = Edge.first.getGUID(); + ExportList.insert(CalleeGUID); + } + for (auto &Ref : ResolvedCalleeSummary->refs()) { + auto GUID = Ref.getGUID(); + ExportList.insert(GUID); + } + } + } + } auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) { // Adjust the threshold for next level of imported functions. @@ -342,44 +409,8 @@ static void computeImportForFunction( Edge.second.getHotness() == CalleeInfo::HotnessType::Hot; const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite); - auto ExportModulePath = ResolvedCalleeSummary->modulePath(); - auto &ProcessedThreshold = ImportList[ExportModulePath][VI.getGUID()]; - /// Since the traversal of the call graph is DFS, we can revisit a function - /// a second time with a higher threshold. In this case, it is added back to - /// the worklist with the new threshold. - if (ProcessedThreshold && ProcessedThreshold >= AdjThreshold) { - LLVM_DEBUG(dbgs() << "ignored! Target was already seen with Threshold " - << ProcessedThreshold << "\n"); - continue; - } - bool PreviouslyImported = ProcessedThreshold != 0; - // Mark this function as imported in this module, with the current Threshold - ProcessedThreshold = AdjThreshold; - ImportCount++; - // Make exports in the source module. - if (ExportLists) { - auto &ExportList = (*ExportLists)[ExportModulePath]; - ExportList.insert(VI.getGUID()); - if (!PreviouslyImported) { - // This is the first time this function was exported from its source - // module, so mark all functions and globals it references as exported - // to the outside if they are defined in the same source module. - // For efficiency, we unconditionally add all the referenced GUIDs - // to the ExportList for this module, and will prune out any not - // defined in the module later in a single pass. - for (auto &Edge : ResolvedCalleeSummary->calls()) { - auto CalleeGUID = Edge.first.getGUID(); - ExportList.insert(CalleeGUID); - } - for (auto &Ref : ResolvedCalleeSummary->refs()) { - auto GUID = Ref.getGUID(); - ExportList.insert(GUID); - } - } - } - // Insert the newly imported function to the worklist. Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, VI.getGUID()); } @@ -395,6 +426,7 @@ static void ComputeImportForModule( // Worklist contains the list of function imported in this module, for which // we will analyse the callees and may import further down the callgraph. SmallVector<EdgeInfo, 128> Worklist; + FunctionImporter::ImportThresholdsTy ImportThresholds; // Populate the worklist with the import for the functions in the current // module @@ -416,7 +448,7 @@ static void ComputeImportForModule( LLVM_DEBUG(dbgs() << "Initialize import for " << VI << "\n"); computeImportForFunction(*FuncSummary, Index, ImportInstrLimit, DefinedGVSummaries, Worklist, ImportList, - ExportLists); + ExportLists, ImportThresholds); } // Process the newly imported functions and add callees to the worklist. @@ -424,17 +456,10 @@ static void ComputeImportForModule( auto FuncInfo = Worklist.pop_back_val(); auto *Summary = std::get<0>(FuncInfo); auto Threshold = std::get<1>(FuncInfo); - auto GUID = std::get<2>(FuncInfo); - - // Check if we later added this summary with a higher threshold. - // If so, skip this entry. - auto ExportModulePath = Summary->modulePath(); - auto &LatestProcessedThreshold = ImportList[ExportModulePath][GUID]; - if (LatestProcessedThreshold > Threshold) - continue; computeImportForFunction(*Summary, Index, Threshold, DefinedGVSummaries, - Worklist, ImportList, ExportLists); + Worklist, ImportList, ExportLists, + ImportThresholds); } } @@ -451,11 +476,6 @@ static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, static GlobalValue::GUID getGUID(GlobalValue::GUID G) { return G; } -static GlobalValue::GUID -getGUID(const std::pair<const GlobalValue::GUID, unsigned> &P) { - return P.first; -} - template <class T> static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont) { @@ -574,9 +594,8 @@ void llvm::ComputeCrossModuleImportForModuleFromIndex( // e.g. record required linkage changes. if (Summary->modulePath() == ModulePath) continue; - // Doesn't matter what value we plug in to the map, just needs an entry - // to provoke importing by thinBackend. - ImportList[Summary->modulePath()][GUID] = 1; + // Add an entry to provoke importing by thinBackend. + ImportList[Summary->modulePath()].insert(GUID); } #ifndef NDEBUG dumpImportListForModule(Index, ModulePath, ImportList); @@ -698,10 +717,10 @@ void llvm::gatherImportedSummariesForModule( const auto &DefinedGVSummaries = ModuleToDefinedGVSummaries.lookup(ILI.first()); for (auto &GI : ILI.second) { - const auto &DS = DefinedGVSummaries.find(GI.first); + const auto &DS = DefinedGVSummaries.find(GI); assert(DS != DefinedGVSummaries.end() && "Expected a defined summary for imported global value"); - SummariesForIndex[GI.first] = DS->second; + SummariesForIndex[GI] = DS->second; } } } |