From 4b2acde21a9372fdbdb86155a6dda04c5f79f567 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 2 May 2014 18:35:25 +0000 Subject: Teach GlobalDCE how to remove empty global_ctor entries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- llvm/lib/Transforms/IPO/GlobalDCE.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Transforms/IPO/GlobalDCE.cpp') 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(Entry.front())) + return false; + ReturnInst &RI = cast(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); -- cgit v1.2.3