aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp42
1 files changed, 29 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index c3d15af..c863936 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -95,9 +95,12 @@ extern cl::opt<unsigned> MaxNumVTableAnnotations;
// global vars at all. When importing function we aren't interested if any
// instruction in it takes an address of any basic block, because instruction
// can only take an address of basic block located in the same function.
+// Set `RefLocalLinkageIFunc` to true if the analyzed value references a
+// local-linkage ifunc.
static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
SetVector<ValueInfo, std::vector<ValueInfo>> &RefEdges,
- SmallPtrSet<const User *, 8> &Visited) {
+ SmallPtrSet<const User *, 8> &Visited,
+ bool &RefLocalLinkageIFunc) {
bool HasBlockAddress = false;
SmallVector<const User *, 32> Worklist;
if (Visited.insert(CurUser).second)
@@ -119,8 +122,18 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
// We have a reference to a global value. This should be added to
// the reference set unless it is a callee. Callees are handled
// specially by WriteFunction and are added to a separate list.
- if (!(CB && CB->isCallee(&OI)))
+ if (!(CB && CB->isCallee(&OI))) {
+ // If an ifunc has local linkage, do not add it into ref edges, and
+ // sets `RefLocalLinkageIFunc` to true. The referencer is not eligible
+ // for import. An ifunc doesn't have summary and ThinLTO cannot
+ // promote it; importing the referencer may cause linkage errors.
+ if (auto *GI = dyn_cast_if_present<GlobalIFunc>(GV);
+ GI && GI->hasLocalLinkage()) {
+ RefLocalLinkageIFunc = true;
+ continue;
+ }
RefEdges.insert(Index.getOrInsertValueInfo(GV));
+ }
continue;
}
if (Visited.insert(Operand).second)
@@ -313,7 +326,8 @@ static void computeFunctionSummary(
// Add personality function, prefix data and prologue data to function's ref
// list.
- findRefEdges(Index, &F, RefEdges, Visited);
+ bool HasLocalIFuncCallOrRef = false;
+ findRefEdges(Index, &F, RefEdges, Visited, HasLocalIFuncCallOrRef);
std::vector<const Instruction *> NonVolatileLoads;
std::vector<const Instruction *> NonVolatileStores;
@@ -326,7 +340,6 @@ static void computeFunctionSummary(
bool HasInlineAsmMaybeReferencingInternal = false;
bool HasIndirBranchToBlockAddress = false;
- bool HasIFuncCall = false;
bool HasUnknownCall = false;
bool MayThrow = false;
for (const BasicBlock &BB : F) {
@@ -372,11 +385,11 @@ static void computeFunctionSummary(
// of calling it we should add GV to RefEdges directly.
RefEdges.insert(Index.getOrInsertValueInfo(GV));
else if (auto *U = dyn_cast<User>(Stored))
- findRefEdges(Index, U, RefEdges, Visited);
+ findRefEdges(Index, U, RefEdges, Visited, HasLocalIFuncCallOrRef);
continue;
}
}
- findRefEdges(Index, &I, RefEdges, Visited);
+ findRefEdges(Index, &I, RefEdges, Visited, HasLocalIFuncCallOrRef);
const auto *CB = dyn_cast<CallBase>(&I);
if (!CB) {
if (I.mayThrow())
@@ -450,7 +463,7 @@ static void computeFunctionSummary(
// Non-local ifunc is not cloned and does not have the issue.
if (auto *GI = dyn_cast_if_present<GlobalIFunc>(CalledValue))
if (GI->hasLocalLinkage())
- HasIFuncCall = true;
+ HasLocalIFuncCallOrRef = true;
// Skip inline assembly calls.
if (CI && CI->isInlineAsm())
continue;
@@ -555,7 +568,7 @@ static void computeFunctionSummary(
SmallPtrSet<const User *, 8> &Cache) {
for (const auto *I : Instrs) {
Cache.erase(I);
- findRefEdges(Index, I, Edges, Cache);
+ findRefEdges(Index, I, Edges, Cache, HasLocalIFuncCallOrRef);
}
};
@@ -631,9 +644,9 @@ static void computeFunctionSummary(
#endif
bool NonRenamableLocal = isNonRenamableLocal(F);
- bool NotEligibleForImport = NonRenamableLocal ||
- HasInlineAsmMaybeReferencingInternal ||
- HasIndirBranchToBlockAddress || HasIFuncCall;
+ bool NotEligibleForImport =
+ NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
+ HasIndirBranchToBlockAddress || HasLocalIFuncCallOrRef;
GlobalValueSummary::GVFlags Flags(
F.getLinkage(), F.getVisibility(), NotEligibleForImport,
/* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable(),
@@ -787,7 +800,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
SmallVectorImpl<MDNode *> &Types) {
SetVector<ValueInfo, std::vector<ValueInfo>> RefEdges;
SmallPtrSet<const User *, 8> Visited;
- bool HasBlockAddress = findRefEdges(Index, &V, RefEdges, Visited);
+ bool RefLocalIFunc = false;
+ bool HasBlockAddress =
+ findRefEdges(Index, &V, RefEdges, Visited, RefLocalIFunc);
+ const bool NotEligibleForImport = (HasBlockAddress || RefLocalIFunc);
bool NonRenamableLocal = isNonRenamableLocal(V);
GlobalValueSummary::GVFlags Flags(
V.getLinkage(), V.getVisibility(), NonRenamableLocal,
@@ -821,7 +837,7 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
RefEdges.takeVector());
if (NonRenamableLocal)
CantBePromoted.insert(V.getGUID());
- if (HasBlockAddress)
+ if (NotEligibleForImport)
GVarSummary->setNotEligibleToImport();
if (!VTableFuncs.empty())
GVarSummary->setVTableFuncs(VTableFuncs);