mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
Make constmerge a two-pass algorithm so that it won't miss merging
opporuntities. Fixes PR8978. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123541 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
111fd9ce64
commit
2820c25e84
@ -101,14 +101,17 @@ 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();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
18
test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll
Normal file
18
test/Transforms/ConstantMerge/2011-01-15-EitherOrder.ll
Normal file
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user