Index: lib/Transforms/IPO/FunctionImport.cpp
===================================================================
--- lib/Transforms/IPO/FunctionImport.cpp
+++ lib/Transforms/IPO/FunctionImport.cpp
@@ -266,7 +266,8 @@
ExportList.insert(GUID);
}
-using EdgeInfo = std::pair;
+using EdgeInfo = std::tuple;
/// Compute the list of functions to import for a given caller. Mark these
/// imported functions and the symbols they reference in their source module as
@@ -316,18 +317,30 @@
assert(ResolvedCalleeSummary->instCount() <= NewThreshold &&
"selectCallee() didn't honor the threshold");
+ auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {
+ // Adjust the threshold for next level of imported functions.
+ // The threshold is different for hot callsites because we can then
+ // inline chains of hot calls.
+ if (IsHotCallsite)
+ return Threshold * ImportHotInstrFactor;
+ return Threshold * ImportInstrFactor;
+ };
+
+ bool IsHotCallsite = Edge.second.Hotness == CalleeInfo::HotnessType::Hot;
+ const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
+
auto ExportModulePath = ResolvedCalleeSummary->modulePath();
auto &ProcessedThreshold = ImportList[ExportModulePath][GUID];
/// 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 >= Threshold) {
+ if (ProcessedThreshold && ProcessedThreshold >= AdjThreshold) {
DEBUG(dbgs() << "ignored! Target was already seen with Threshold "
<< ProcessedThreshold << "\n");
continue;
}
// Mark this function as imported in this module, with the current Threshold
- ProcessedThreshold = Threshold;
+ ProcessedThreshold = AdjThreshold;
// Make exports in the source module.
if (ExportLists) {
@@ -348,20 +361,8 @@
}
}
- auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {
- // Adjust the threshold for next level of imported functions.
- // The threshold is different for hot callsites because we can then
- // inline chains of hot calls.
- if (IsHotCallsite)
- return Threshold * ImportHotInstrFactor;
- return Threshold * ImportInstrFactor;
- };
-
- bool IsHotCallsite = Edge.second.Hotness == CalleeInfo::HotnessType::Hot;
-
// Insert the newly imported function to the worklist.
- Worklist.emplace_back(ResolvedCalleeSummary,
- GetAdjustedThreshold(Threshold, IsHotCallsite));
+ Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold, GUID);
}
}
@@ -395,8 +396,16 @@
// Process the newly imported functions and add callees to the worklist.
while (!Worklist.empty()) {
auto FuncInfo = Worklist.pop_back_val();
- auto *Summary = FuncInfo.first;
- auto Threshold = FuncInfo.second;
+ 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);