diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-05-04 00:20:48 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-05-04 00:20:48 +0000 |
commit | 95549497ec8b5269f0439f12859537b7371b7c90 (patch) | |
tree | 4e4fce296da1602e2a45a1bcc457a618eac9fd8f /llvm/lib | |
parent | c44644d6e9d6ca8020b6ce2435d245766dbb3a00 (diff) | |
download | bcm5719-llvm-95549497ec8b5269f0439f12859537b7371b7c90.tar.gz bcm5719-llvm-95549497ec8b5269f0439f12859537b7371b7c90.zip |
[GlobalDCE, Misc] Don't remove functions referenced by ifuncs
We forgot to consider the target of ifuncs when considering if a
function was alive or dead.
N.B. Also update a few auxiliary tools like bugpoint and
verify-uselistorder.
This fixes PR27593.
llvm-svn: 268468
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalDCE.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SplitModule.cpp | 12 |
2 files changed, 33 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp index 3b773010bb6..fca549947c6 100644 --- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp +++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp @@ -32,6 +32,7 @@ using namespace llvm; STATISTIC(NumAliases , "Number of global aliases removed"); STATISTIC(NumFunctions, "Number of functions removed"); +STATISTIC(NumIFuncs, "Number of indirect functions removed"); STATISTIC(NumVariables, "Number of global variables removed"); namespace { @@ -118,6 +119,13 @@ PreservedAnalyses GlobalDCEPass::run(Module &M) { GlobalIsNeeded(&GA); } + for (GlobalIFunc &GIF : M.ifuncs()) { + Changed |= RemoveUnusedGlobalValue(GIF); + // Externally visible ifuncs are needed. + if (!GIF.isDiscardableIfUnused()) + GlobalIsNeeded(&GIF); + } + // Now that all globals which are needed are in the AliveGlobals set, we loop // through the program, deleting those which are not alive. // @@ -152,6 +160,14 @@ PreservedAnalyses GlobalDCEPass::run(Module &M) { GA.setAliasee(nullptr); } + // The third pass drops targets of ifuncs which are dead... + std::vector<GlobalIFunc*> DeadIFuncs; + for (GlobalIFunc &GIF : M.ifuncs()) + if (!AliveGlobals.count(&GIF)) { + DeadIFuncs.push_back(&GIF); + GIF.setResolver(nullptr); + } + if (!DeadFunctions.empty()) { // Now that all interferences have been dropped, delete the actual objects // themselves. @@ -182,6 +198,16 @@ PreservedAnalyses GlobalDCEPass::run(Module &M) { Changed = true; } + // Now delete any dead aliases. + if (!DeadIFuncs.empty()) { + for (GlobalIFunc *GIF : DeadIFuncs) { + RemoveUnusedGlobalValue(*GIF); + M.getIFuncList().erase(GIF); + } + NumIFuncs += DeadIFuncs.size(); + Changed = true; + } + // Make sure that all memory is released AliveGlobals.clear(); SeenConstants.clear(); diff --git a/llvm/lib/Transforms/Utils/SplitModule.cpp b/llvm/lib/Transforms/Utils/SplitModule.cpp index 6b0ce9c2573..3db04b8b34c 100644 --- a/llvm/lib/Transforms/Utils/SplitModule.cpp +++ b/llvm/lib/Transforms/Utils/SplitModule.cpp @@ -47,7 +47,7 @@ static void addNonConstUser(ClusterMapType &GVtoClusterMap, if (const Instruction *I = dyn_cast<Instruction>(U)) { const GlobalValue *F = I->getParent()->getParent(); GVtoClusterMap.unionSets(GV, F); - } else if (isa<GlobalAlias>(U) || isa<Function>(U) || + } else if (isa<GlobalIndirectSymbol>(U) || isa<Function>(U) || isa<GlobalVariable>(U)) { GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U)); } else { @@ -107,8 +107,8 @@ static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap, // For aliases we should not separate them from their aliasees regardless // of linkage. - if (GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) { - if (const GlobalObject *Base = GA->getBaseObject()) + if (auto *GIS = dyn_cast<GlobalIndirectSymbol>(&GV)) { + if (const GlobalObject *Base = GIS->getBaseObject()) GVtoClusterMap.unionSets(&GV, Base); } @@ -205,8 +205,8 @@ static void externalize(GlobalValue *GV) { // Returns whether GV should be in partition (0-based) I of N. static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) { - if (auto GA = dyn_cast<GlobalAlias>(GV)) - if (const GlobalObject *Base = GA->getBaseObject()) + if (auto *GIS = dyn_cast<GlobalIndirectSymbol>(GV)) + if (const GlobalObject *Base = GIS->getBaseObject()) GV = Base; StringRef Name; @@ -236,6 +236,8 @@ void llvm::SplitModule( externalize(&GV); for (GlobalAlias &GA : M->aliases()) externalize(&GA); + for (GlobalIFunc &GIF : M->ifuncs()) + externalize(&GIF); } // This performs splitting without a need for externalization, which might not |