summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/GlobalDCE.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-05-02 18:35:25 +0000
committerNico Weber <nicolasweber@gmx.de>2014-05-02 18:35:25 +0000
commit4b2acde21a9372fdbdb86155a6dda04c5f79f567 (patch)
tree56f8a8a428542de0c2eff1dbc56c28892809c60f /llvm/lib/Transforms/IPO/GlobalDCE.cpp
parent4f51a0740a17aedfef3036352e78ec970ce0ac57 (diff)
downloadbcm5719-llvm-4b2acde21a9372fdbdb86155a6dda04c5f79f567.tar.gz
bcm5719-llvm-4b2acde21a9372fdbdb86155a6dda04c5f79f567.zip
Teach GlobalDCE how to remove empty global_ctor entries.
This moves most of GlobalOpt's constructor optimization code out of GlobalOpt into Transforms/Utils/CDtorUtils.{h,cpp}. The public interface is a single function OptimizeGlobalCtorsList() that takes a predicate returning which constructors to remove. GlobalOpt calls this with a function that statically evaluates all constructors, just like it did before. This part of the change is behavior-preserving. Also add a call to this from GlobalDCE with a filter that removes global constructors that contain a "ret" instruction and nothing else – this fixes PR19590. llvm-svn: 207856
Diffstat (limited to 'llvm/lib/Transforms/IPO/GlobalDCE.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/GlobalDCE.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp
index 0cf03a54c22..03b17d52386 100644
--- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp
@@ -19,7 +19,9 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
+#include "llvm/Transforms/Utils/CtorUtils.h"
#include "llvm/Pass.h"
using namespace llvm;
@@ -52,6 +54,15 @@ namespace {
bool RemoveUnusedGlobalValue(GlobalValue &GV);
};
+
+/// Returns true if F contains only a single "ret" instruction.
+bool isEmptyFunction(void *Context, Function *F) {
+ BasicBlock &Entry = F->getEntryBlock();
+ if (Entry.size() != 1 || !isa<ReturnInst>(Entry.front()))
+ return false;
+ ReturnInst &RI = cast<ReturnInst>(Entry.front());
+ return RI.getReturnValue() == NULL;
+}
}
char GlobalDCE::ID = 0;
@@ -62,7 +73,10 @@ ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
bool GlobalDCE::runOnModule(Module &M) {
bool Changed = false;
-
+
+ // Remove empty functions from the global ctors list.
+ Changed |= optimizeGlobalCtorsList(M, isEmptyFunction, nullptr);
+
// Loop over the module, adding globals which are obviously necessary.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
Changed |= RemoveUnusedGlobalValue(*I);
OpenPOWER on IntegriCloud