Hello, Everyone.

Please find patch for llvm-gcc4, which enables external weak linkage.
All "supporting" patches to LLVM has been commited to CVS HEAD already. 

Please note, that applying this patch will, probably, break crtstuff.c
compilation on Darwin, since there is no Darwin codegen for external
weak linkage inside.

PS: I've successfully bootstrapped llvm-gcc4 with these patches on
Linux.
-- 
With best regards, Anton Korobeynikov.

Faculty of Mathematics & Mechanics, Saint Petersburg State University.

diff -r 9e71153bc71b README.LLVM
--- a/README.LLVM	Thu Nov 30 11:14:19 2006 +0000
+++ b/README.LLVM	Fri Dec 01 02:41:38 2006 +0300
@@ -42,11 +42,7 @@ Below we assume the LLVM OBJDIR is $LLVM
 //===-----------------------
 Linux-specific Instructions:
 
-Until http://llvm.org/PR821 is fixed, you should configure with
---disable-threads.  This fixes problems linking libgcc.so.1 with
-undefined references to pthread_*.
-
-Until http://llvm.org/PR1006 is fixed, you should configure with
+Until http://llvm.org/PR1017 is fixed, you should configure with
 --disable-shared. This fixes problems when missing symbols in the stdc++ 
 library when trying to link llvm-g++. 
 
diff -r 9e71153bc71b gcc/crtstuff.c
--- a/gcc/crtstuff.c	Thu Nov 30 11:14:19 2006 +0000
+++ b/gcc/crtstuff.c	Sun Nov 26 03:58:43 2006 +0300
@@ -65,13 +65,6 @@ 02111-1307, USA.  */
 #include "coretypes.h"
 #include "tm.h"
 #include "unwind-dw2-fde.h"
-
-/* APPLE LOCAL begin LLVM */
-#ifdef __llvm__
- /* FIXME: Remove when external weak linkage will be alive. */
- #undef JCR_SECTION_NAME
-#endif
-/* APPLE LOCAL end LLVM */
 
 #ifndef FORCE_CODE_SECTION_ALIGN
 # define FORCE_CODE_SECTION_ALIGN
diff -r 9e71153bc71b gcc/llvm-backend.cpp
--- a/gcc/llvm-backend.cpp	Thu Nov 30 11:14:19 2006 +0000
+++ b/gcc/llvm-backend.cpp	Fri Dec 01 02:36:13 2006 +0300
@@ -670,6 +670,6 @@ void make_decl_llvm(tree decl) {
   // object.  Note that this is quite possibly a forward reference to the
   // object, so its type may change later.
   if (TREE_CODE(decl) == FUNCTION_DECL) {
     assert(Name[0] && "Function with empty name!");
     // If this function has already been created, reuse the decl.  This happens
     // when we have something like __builtin_memset and memset in the same file.
@@ -681,6 +683,11 @@ void make_decl_llvm(tree decl) {
       FnEntry = new Function(Ty, Function::ExternalLinkage, Name, TheModule);
       FnEntry->setCallingConv(CC);
 
+      // Check for external weak linkage
+      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) {
+        FnEntry->setLinkage(Function::ExternalWeakLinkage);
+      }
+      
 #ifdef TARGET_ADJUST_LLVM_LINKAGE
       TARGET_ADJUST_LLVM_LINKAGE(FnEntry,decl);
 #endif /* TARGET_ADJUST_LLVM_LINKAGE */
@@ -700,6 +707,11 @@ void make_decl_llvm(tree decl) {
     if (Name[0] == 0) {   // Global has no name.
       GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0,
                               Name, TheModule);
+      
+      // Check for external weak linkage
+      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) {
+        GV->setLinkage(GlobalValue::ExternalWeakLinkage);
+      }
 
 #ifdef TARGET_ADJUST_LLVM_LINKAGE
       TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
@@ -712,6 +724,11 @@ void make_decl_llvm(tree decl) {
       if (GVE == 0) {
         GVE = GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0,
                                       Name, TheModule);
+
+        // Check for external weak linkage
+        if (DECL_EXTERNAL(decl) && DECL_WEAK(decl)) {
+          GV->setLinkage(GlobalValue::ExternalWeakLinkage);
+        }
 
 #ifdef TARGET_ADJUST_LLVM_LINKAGE
         TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
@@ -743,11 +760,6 @@ void make_decl_llvm(tree decl) {
       }
     }
 
-#if 0
-    // FIXME: When we support external weak globals, this is where we do it.
-    x = gen_rtx_SYMBOL_REF(Pmode, name);
-    SYMBOL_REF_WEAK(x) = DECL_WEAK(decl);
-#endif
     SET_DECL_LLVM(decl, GV);
   }
   timevar_pop(TV_LLVM_GLOBALS);
@@ -760,17 +772,21 @@ const char *llvm_get_decl_name(void *LLV
 }
 
 // llvm_mark_decl_weak - Used by varasm.c, called when a decl is found to be
-// weak, but it already had an llvm object created for it.  This marks the LLVM
+// weak, but it already had an llvm object created for it. This marks the LLVM
 // object weak as well.
 void llvm_mark_decl_weak(tree decl) {
   assert(DECL_LLVM_SET_P(decl) && DECL_WEAK(decl) &&
          isa<GlobalValue>(DECL_LLVM(decl)) && "Decl isn't marked weak!");
   GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl));
 
-  if (!GV->isExternal() &&  // FIXME: Support external weak globals!
-      // Do not mark something that is already known to be linkonce or internal.
-      GV->getLinkage() == GlobalValue::ExternalLinkage)
-    GV->setLinkage(GlobalValue::WeakLinkage);
+  // Do not mark something that is already known to be linkonce or internal.
+  if (GV->getLinkage() == GlobalValue::ExternalLinkage) {
+    if (GV->isExternal()) {
+      GV->setLinkage(GlobalValue::ExternalWeakLinkage);
+    } else {
+      GV->setLinkage(GlobalValue::WeakLinkage);
+    }
+  }
 }
 
 // llvm_emit_ctor_dtor - Called to emit static ctors/dtors to LLVM code.  fndecl
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to