diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index f9a7c73534b..8c6631aa2bc 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -65,6 +65,7 @@ namespace { GlobalVariable *FindGlobalCtors(Module &M); bool OptimizeFunctions(Module &M); bool OptimizeGlobalVars(Module &M); + bool ResolveAliases(Module &M); bool OptimizeGlobalCtorsList(GlobalVariable *&GCL); bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator &GVI); }; @@ -2214,6 +2215,23 @@ bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) { return true; } +bool GlobalOpt::ResolveAliases(Module &M) { + bool Changed = false; + + for (Module::alias_iterator I = M.alias_begin(), + E = M.alias_end(); I != E; ++I) { + if (I->use_empty()) + continue; + + if (const GlobalValue *GV = I->resolveAliasedGlobal(/*traverseWeak*/ false)) + if (GV != I) { + I->replaceAllUsesWith(const_cast(GV)); + Changed = true; + } + } + + return Changed; +} bool GlobalOpt::runOnModule(Module &M) { bool Changed = false; @@ -2235,6 +2253,10 @@ bool GlobalOpt::runOnModule(Module &M) { // Optimize non-address-taken globals. LocalChange |= OptimizeGlobalVars(M); Changed |= LocalChange; + + // Resolve aliases, when possible. + LocalChange |= ResolveAliases(M); + Changed |= LocalChange; } // TODO: Move all global ctors functions to the end of the module for code diff --git a/test/Transforms/GlobalOpt/alias-resolve.ll b/test/Transforms/GlobalOpt/alias-resolve.ll new file mode 100644 index 00000000000..3cae4138fde --- /dev/null +++ b/test/Transforms/GlobalOpt/alias-resolve.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -globalopt | llvm-dis > %t +; RUN: cat %t | grep foo1 | count 1 +; RUN: cat %t | grep foo2 | count 4 +; RUN: cat %t | grep bar1 | count 1 +; RUN: cat %t | grep bar2 | count 4 + +@foo1 = alias void ()* @foo2 +@foo2 = alias weak void()* @bar1 +@bar1 = alias void ()* @bar2 + +declare void @bar2() + +define void @baz() { +entry: + call void @foo1() + call void @foo2() + call void @bar1() + ret void +}