aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2009-02-17 23:05:26 +0000
committerDuncan Sands <baldrick@free.fr>2009-02-17 23:05:26 +0000
commitcdf5ffb7fb3215e9ce5556ce896d4f573ab564e4 (patch)
tree4e40bf73e3a2e79d5e7264a85cdee9eb6311f518
parent0d90e5d08b09c8c72927dae70681ad9d2845475e (diff)
If an alias is dead and so is its aliasee, then globaldce would
crash because the alias would still be using the aliasee when the aliasee was deleted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64844 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/IPO/GlobalDCE.cpp24
-rw-r--r--test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll4
2 files changed, 20 insertions, 8 deletions
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp
index a0f8923242..c28d5e3e57 100644
--- a/lib/Transforms/IPO/GlobalDCE.cpp
+++ b/lib/Transforms/IPO/GlobalDCE.cpp
@@ -82,7 +82,7 @@ bool GlobalDCE::runOnModule(Module &M) {
I != E; ++I) {
Changed |= RemoveUnusedGlobalValue(*I);
// Externally visible aliases are needed.
- if (!I->hasInternalLinkage() && !I->hasLinkOnceLinkage())
+ if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage())
GlobalIsNeeded(I);
}
@@ -107,6 +107,15 @@ bool GlobalDCE::runOnModule(Module &M) {
I->deleteBody();
}
+ // The third pass drops targets of aliases which are dead...
+ std::vector<GlobalAlias*> DeadAliases;
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
+ ++I)
+ if (!AliveGlobals.count(I)) {
+ DeadAliases.push_back(I);
+ I->setAliasee(0);
+ }
+
if (!DeadFunctions.empty()) {
// Now that all interferences have been dropped, delete the actual objects
// themselves.
@@ -128,14 +137,13 @@ bool GlobalDCE::runOnModule(Module &M) {
}
// Now delete any dead aliases.
- for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;) {
- Module::alias_iterator J = I++;
- if (!AliveGlobals.count(J)) {
- RemoveUnusedGlobalValue(*J);
- M.getAliasList().erase(J);
- ++NumAliases;
- Changed = true;
+ if (!DeadAliases.empty()) {
+ for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadAliases[i]);
+ M.getAliasList().erase(DeadAliases[i]);
}
+ NumAliases += DeadAliases.size();
+ Changed = true;
}
// Make sure that all memory is released
diff --git a/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll b/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll
new file mode 100644
index 0000000000..8c15c51a4e
--- /dev/null
+++ b/test/Transforms/GlobalDCE/2009-02-17-AliasUsesAliasee.ll
@@ -0,0 +1,4 @@
+; RUN: llvm-as < %s | opt -globaldce
+
+@A = alias internal void ()* @F
+define internal void @F() { ret void }