From 37b94c6b4e605c522164bcafc58ea1e1afb50cc0 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 11 Jan 2012 00:13:08 +0000 Subject: If the global variable is removed by the linker, then don't constant merge it with other symbols. An object in the __cfstring section is suppoed to be filled with CFString objects, which have a pointer to ___CFConstantStringClassReference followed by a pointer to a __cstring. If we allow the object in the __cstring section to be merged with another global, then it could end up in any section. Because the linker is going to remove these symbols in the final executable, we shouldn't bother to merge them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147899 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/ConstantMerge.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'lib/Transforms/IPO/ConstantMerge.cpp') diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index c3ecb7a..268a281 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -140,18 +140,21 @@ bool ConstantMerge::runOnModule(Module &M) { UsedGlobals.count(GV)) continue; + // Ignore any constants which may be removed by the linker. + if (GV->mayBeRemovedByLinker()) + continue; + Constant *Init = GV->getInitializer(); // Check to see if the initializer is already known. PointerIntPair Pair(Init, hasKnownAlignment(GV)); GlobalVariable *&Slot = CMap[Pair]; - // If this is the first constant we find or if the old on is local, - // replace with the current one. It the current is externally visible + // If this is the first constant we find or if the old one is local, + // replace with the current one. If the current is externally visible // it cannot be replace, but can be the canonical constant we merge with. - if (Slot == 0 || IsBetterCannonical(*GV, *Slot)) { + if (Slot == 0 || IsBetterCannonical(*GV, *Slot)) Slot = GV; - } } // Second: identify all globals that can be merged together, filling in @@ -169,8 +172,9 @@ bool ConstantMerge::runOnModule(Module &M) { UsedGlobals.count(GV)) continue; - // We can only replace constant with local linkage. - if (!GV->hasLocalLinkage()) + // We can only replace constants with local linkage and which aren't + // removed by the linker. + if (!GV->hasLocalLinkage() || GV->mayBeRemovedByLinker()) continue; Constant *Init = GV->getInitializer(); -- cgit v1.1 From e15f421a9acd18ca71fed382ac09f7367b6a72f6 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 11 Jan 2012 22:06:46 +0000 Subject: Re-fix the issue Bill fixed in r147899 in a slightly different way, which doesn't abuse the semantics of linker_private. We don't really want to merge any string constant with a weak_odr global. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147971 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/ConstantMerge.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/Transforms/IPO/ConstantMerge.cpp') diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index 268a281..d8fae8a 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -140,8 +140,11 @@ bool ConstantMerge::runOnModule(Module &M) { UsedGlobals.count(GV)) continue; - // Ignore any constants which may be removed by the linker. - if (GV->mayBeRemovedByLinker()) + // This transformation is legal for weak ODR globals in the sense it + // doesn't change semantics, but we really don't want to perform it + // anyway; it's likely to pessimize code generation, and some tools + // (like the Darwin linker in cases involving CFString) don't expect it. + if (GV->isWeakForLinker()) continue; Constant *Init = GV->getInitializer(); @@ -172,9 +175,8 @@ bool ConstantMerge::runOnModule(Module &M) { UsedGlobals.count(GV)) continue; - // We can only replace constants with local linkage and which aren't - // removed by the linker. - if (!GV->hasLocalLinkage() || GV->mayBeRemovedByLinker()) + // We can only replace constant with local linkage. + if (!GV->hasLocalLinkage()) continue; Constant *Init = GV->getInitializer(); -- cgit v1.1