summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/GlobalDCE.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-05-04 00:20:48 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-05-04 00:20:48 +0000
commit95549497ec8b5269f0439f12859537b7371b7c90 (patch)
tree4e4fce296da1602e2a45a1bcc457a618eac9fd8f /llvm/lib/Transforms/IPO/GlobalDCE.cpp
parentc44644d6e9d6ca8020b6ce2435d245766dbb3a00 (diff)
downloadbcm5719-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/Transforms/IPO/GlobalDCE.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/GlobalDCE.cpp26
1 files changed, 26 insertions, 0 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();
OpenPOWER on IntegriCloud