[llvm-commits] [llvm] r147899 - in /llvm/trunk: include/llvm/GlobalValue.h lib/Transforms/IPO/ConstantMerge.cpp test/Transforms/ConstantMerge/linker-private.ll

Bill Wendling isanbard at gmail.com
Tue Jan 10 16:13:08 PST 2012


Author: void
Date: Tue Jan 10 18:13:08 2012
New Revision: 147899

URL: http://llvm.org/viewvc/llvm-project?rev=147899&view=rev
Log:
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.
<rdar://problem/10564621>

Added:
    llvm/trunk/test/Transforms/ConstantMerge/linker-private.ll
Modified:
    llvm/trunk/include/llvm/GlobalValue.h
    llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp

Modified: llvm/trunk/include/llvm/GlobalValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/GlobalValue.h?rev=147899&r1=147898&r2=147899&view=diff
==============================================================================
--- llvm/trunk/include/llvm/GlobalValue.h (original)
+++ llvm/trunk/include/llvm/GlobalValue.h Tue Jan 10 18:13:08 2012
@@ -192,6 +192,14 @@
            Linkage == LinkerPrivateWeakDefAutoLinkage;
   }
 
+  /// mayBeRemovedByLinker - Whether the definition of this global may be
+  /// removed at link time.
+  static bool mayBeRemovedByLinker(LinkageTypes Linkage) {
+    return isLinkerPrivateLinkage(Linkage) ||
+      isLinkerPrivateWeakLinkage(Linkage) ||
+      isLinkerPrivateWeakDefAutoLinkage(Linkage);
+  }
+
   bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
   bool hasAvailableExternallyLinkage() const {
     return isAvailableExternallyLinkage(Linkage);
@@ -225,6 +233,8 @@
 
   bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
 
+  bool mayBeRemovedByLinker() const { return mayBeRemovedByLinker(Linkage); }
+
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// create a GlobalValue) from the GlobalValue Src to this one.
   virtual void copyAttributesFrom(const GlobalValue *Src);

Modified: llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp?rev=147899&r1=147898&r2=147899&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp Tue Jan 10 18:13:08 2012
@@ -140,18 +140,21 @@
           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<Constant*, 1, bool> 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 @@
           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();

Added: llvm/trunk/test/Transforms/ConstantMerge/linker-private.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstantMerge/linker-private.ll?rev=147899&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ConstantMerge/linker-private.ll (added)
+++ llvm/trunk/test/Transforms/ConstantMerge/linker-private.ll Tue Jan 10 18:13:08 2012
@@ -0,0 +1,23 @@
+; RUN: opt < %s -constmerge -S | FileCheck %s
+; <rdar://problem/10564621>
+
+%0 = type opaque
+%struct.NSConstantString = type { i32*, i32, i8*, i32 }
+
+; CHECK: @.str3 = linker_private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+
+ at isLogVisible = global i8 0, align 1
+ at __CFConstantStringClassReference = external global [0 x i32]
+ at .str3 = linker_private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+ at _unnamed_cfstring_4 = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([1 x i8]* @.str3, i32 0, i32 0), i32 0 }, section "__DATA,__cfstring"
+ at null.array = weak_odr constant [1 x i8] zeroinitializer, align 1
+
+define linkonce_odr void @bar() nounwind ssp align 2 {
+entry:
+  %stack = alloca i8*, align 4
+  %call = call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %0* (i8*, i8*, %0*)*)(i8* null, i8* null, %0* bitcast (%struct.NSConstantString* @_unnamed_cfstring_4 to %0*))
+  store i8* getelementptr inbounds ([1 x i8]* @null.array, i32 0, i32 0), i8** %stack, align 4
+  ret void
+}
+
+declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind





More information about the llvm-commits mailing list