diff options
| author | Nick Lewycky <nicholas@mxc.ca> | 2011-01-15 18:14:21 +0000 |
|---|---|---|
| committer | Nick Lewycky <nicholas@mxc.ca> | 2011-01-15 18:14:21 +0000 |
| commit | 0296a481f94b6f58f73b541ad4ca8605d97eeb3e (patch) | |
| tree | e4903968cdf6e10915ed2a304a9b552e6ddfd5df /llvm | |
| parent | 25ac830e72f66f95b2872382903bb8e6499d0db1 (diff) | |
| download | bcm5719-llvm-0296a481f94b6f58f73b541ad4ca8605d97eeb3e.tar.gz bcm5719-llvm-0296a481f94b6f58f73b541ad4ca8605d97eeb3e.zip | |
Make constmerge a two-pass algorithm so that it won't miss merging
opporuntities. Fixes PR8978.
llvm-svn: 123541
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/IPO/ConstantMerge.cpp | 38 | ||||
| -rw-r--r-- | llvm/test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll | 18 |
2 files changed, 52 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/ConstantMerge.cpp b/llvm/lib/Transforms/IPO/ConstantMerge.cpp index ea01ffeeb50..8efad05855a 100644 --- a/llvm/lib/Transforms/IPO/ConstantMerge.cpp +++ b/llvm/lib/Transforms/IPO/ConstantMerge.cpp @@ -101,15 +101,18 @@ bool ConstantMerge::runOnModule(Module &M) { continue; } - // Only process constants with initializers in the default addres space. + // Only process constants with initializers in the default address space. if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || - GV->getType()->getAddressSpace() != 0 || !GV->getSection().empty() || + GV->getType()->getAddressSpace() != 0 || GV->hasSection() || // Don't touch values marked with attribute(used). UsedGlobals.count(GV)) continue; + // Start by filling slots with only the globals we aren't allowed to + // delete because they're externally visible. + if (GV->hasLocalLinkage()) + continue; - Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. @@ -117,7 +120,32 @@ bool ConstantMerge::runOnModule(Module &M) { if (Slot == 0) { // Nope, add it to the map. Slot = GV; - } else if (GV->hasLocalLinkage()) { // Yup, this is a duplicate! + } + } + + for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); + GVI != E; ) { + GlobalVariable *GV = GVI++; + + // Only process constants with initializers in the default address space. + if (!GV->isConstant() ||!GV->hasDefinitiveInitializer() || + GV->getType()->getAddressSpace() != 0 || GV->hasSection() || + // Don't touch values marked with attribute(used). + UsedGlobals.count(GV)) + continue; + + // Only look at the remaining globals now. + if (!GV->hasLocalLinkage()) + continue; + + Constant *Init = GV->getInitializer(); + + // Check to see if the initializer is already known. + GlobalVariable *&Slot = CMap[Init]; + + if (Slot == 0) { // Nope, add it to the map. + Slot = GV; + } else { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the canonical version. Replacements.push_back(std::make_pair(GV, Slot)); } @@ -135,6 +163,8 @@ bool ConstantMerge::runOnModule(Module &M) { Replacements[i].first->replaceAllUsesWith(Replacements[i].second); // Delete the global value from the module. + assert(Replacements[i].first->hasLocalLinkage() && + "Refusing to delete an externally visible global variable."); Replacements[i].first->eraseFromParent(); } diff --git a/llvm/test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll b/llvm/test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll new file mode 100644 index 00000000000..7001ce1ba4c --- /dev/null +++ b/llvm/test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll @@ -0,0 +1,18 @@ +; RUN: opt -constmerge %s -S -o - | FileCheck %s +; PR8978 + +declare i32 @zed(%struct.foobar*, %struct.foobar*) + +%struct.foobar = type { i32 } +; CHECK: bar.d +@bar.d = constant %struct.foobar zeroinitializer, align 4 +; CHECK-NOT: foo.d +@foo.d = internal constant %struct.foobar zeroinitializer, align 4 +define i32 @main() nounwind ssp { +entry: +; CHECK: bar.d + %call2 = tail call i32 @zed(%struct.foobar* @foo.d, %struct.foobar* @bar.d) +nounwind + ret i32 0 +} + |

