[llvm-commits] [llvm] r64583 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll
Duncan Sands
baldrick at free.fr
Sun Feb 15 01:56:09 PST 2009
Author: baldrick
Date: Sun Feb 15 03:56:08 2009
New Revision: 64583
URL: http://llvm.org/viewvc/llvm-project?rev=64583&view=rev
Log:
If the target of an alias has internal linkage, then the
alias can be morphed into the target. Implement this
transform, and fix a crash in the existing transform at
the same time.
Added:
llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=64583&r1=64582&r2=64583&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Sun Feb 15 03:56:08 2009
@@ -50,6 +50,8 @@
STATISTIC(NumFastCallFns , "Number of functions converted to fastcc");
STATISTIC(NumCtorsEvaluated, "Number of static ctors evaluated");
STATISTIC(NumNestRemoved , "Number of nest attributes removed");
+STATISTIC(NumAliasesResolved, "Number of global aliases resolved");
+STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated");
namespace {
struct VISIBILITY_HIDDEN GlobalOpt : public ModulePass {
@@ -2373,15 +2375,61 @@
bool Changed = false;
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I) {
- if (I->use_empty())
+ I != E;) {
+ Module::alias_iterator J = I++;
+ // If the aliasee may change at link time, nothing can be done - bail out.
+ if (J->mayBeOverridden())
continue;
- if (const GlobalValue *GV = I->resolveAliasedGlobal())
- if (GV != I) {
- I->replaceAllUsesWith(const_cast<GlobalValue*>(GV));
- Changed = true;
- }
+ Constant *Aliasee = J->getAliasee();
+ GlobalValue *Target = cast<GlobalValue>(Aliasee->stripPointerCasts());
+ bool hasOneUse = Target->hasOneUse() && Aliasee->hasOneUse();
+
+ // Make all users of the alias use the aliasee instead.
+ if (!J->use_empty()) {
+ J->replaceAllUsesWith(Aliasee);
+ ++NumAliasesResolved;
+ Changed = true;
+ }
+
+ // If the aliasee has internal linkage, give it the name and linkage
+ // of the alias, and delete the alias. This turns:
+ // define internal ... @f(...)
+ // @a = alias ... @f
+ // into:
+ // define ... @a(...)
+ if (!Target->hasInternalLinkage())
+ continue;
+
+ // The transform is only useful if the alias does not have internal linkage.
+ if (J->hasInternalLinkage())
+ continue;
+
+ // Be conservative and do not perform the transform if multiple aliases
+ // potentially target the aliasee. TODO: Make this more aggressive.
+ if (!hasOneUse)
+ continue;
+
+ // Do not perform the transform if it would change the visibility.
+ if (J->getVisibility() != Target->getVisibility())
+ continue;
+
+ // Do not perform the transform if it would change the section.
+ if (J->hasSection() != Target->hasSection() ||
+ (J->hasSection() && J->getSection() != Target->getSection()))
+ continue;
+
+ // Give the aliasee the name and linkage of the alias.
+ Target->takeName(J);
+ Target->setLinkage(J->getLinkage());
+
+ // The alignment is the only remaining attribute that may not match.
+ Target->setAlignment(std::max(J->getAlignment(), Target->getAlignment()));
+
+ // Delete the alias.
+ M.getAliasList().erase(J);
+ ++NumAliasesRemoved;
+ Changed = true;
}
return Changed;
Added: llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll?rev=64583&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll Sun Feb 15 03:56:08 2009
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | opt -globalopt
+
+ at g = external global i32
+
+ at a = alias bitcast (i32* @g to i8*)
+
+define void @f() {
+ %tmp = load i8* @a
+ ret void
+}
Added: llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll?rev=64583&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/2009-02-15-ResolveAlias.ll Sun Feb 15 03:56:08 2009
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -globalopt | llvm-dis | grep {define void @a}
+
+define internal void @f() {
+ ret void
+}
+
+ at a = alias void ()* @f
+
+define void @g() {
+ call void()* @a()
+ ret void
+}
More information about the llvm-commits
mailing list