Hello, Everyone.

Please find attached llvm-gcc patch for symbol aliasing support. Now
libstdc++ can be build as shared library on x86/linux, stripping 10M
from the llvm-gcc distribution. 

This fixes: PR843, PR1006, PR1017.

CFrontend test will follow asap after this patch will be applied.

-- 
With best regards, Anton Korobeynikov.

Faculty of Mathematics & Mechanics, Saint Petersburg State University.

diff -r 4b9ef444e6b1 gcc/cp/method.c
--- a/gcc/cp/method.c	Sun Apr 22 09:01:45 2007 +0000
+++ b/gcc/cp/method.c	Wed Apr 25 15:54:21 2007 +0400
@@ -342,14 +342,7 @@ use_thunk (tree thunk_fndecl, bool emit_
   if (!emit_p)
     return;
 
-  /* APPLE LOCAL begin LLVM */
-  /* PR843 */
-#ifndef ENABLE_LLVM
   if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
-#else
-  if (0 && TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
-#endif
-  /* APPLE LOCAL end LLVM */
    alias = make_alias_for_thunk (function);
   else
    alias = function;
diff -r 4b9ef444e6b1 gcc/llvm-backend.cpp
--- a/gcc/llvm-backend.cpp	Sun Apr 22 09:01:45 2007 +0000
+++ b/gcc/llvm-backend.cpp	Wed Apr 25 17:06:01 2007 +0400
@@ -57,6 +57,7 @@ extern "C" {
 #include "coretypes.h"
 #include "flags.h"
 #include "tree.h"
+#include "c-tree.h" // For aliases
 #include "diagnostic.h"
 #include "output.h"
 #include "toplev.h"
@@ -532,6 +533,84 @@ void llvm_emit_code_for_current_function
   timevar_pop(TV_LLVM_FUNCS);
 }
 
+int emit_alias_to_llvm(tree decl, tree target, unsigned stage) {
+  if (errorcount || sorrycount) return -2;
+    
+  timevar_push(TV_LLVM_GLOBALS);
+
+  // Get or create LLVM global for our alias.
+  GlobalValue *V = cast<GlobalValue>DECL_LLVM(decl);
+  
+  // Try to grab decl from IDENTIFIER_NODE
+  GlobalValue *Aliasee = 0;
+  if (tree c_decl = lookup_name(target))
+    Aliasee = cast<GlobalValue>(DECL_LLVM(c_decl));
+
+  // Query SymTab for aliasee
+  const char* AliaseeName = IDENTIFIER_POINTER(target);
+  if (!Aliasee) {   
+    if (isa<Function>(V)) {
+      Aliasee = TheModule->getFunction(AliaseeName);
+    } else if (isa<GlobalVariable>(V)) {
+      Aliasee = TheModule->getNamedGlobal(AliaseeName);
+    } else if (isa<GlobalAlias>(V)) {
+      Aliasee = TheModule->getNamedAlias(AliaseeName);
+    }
+  }
+
+  // Last resort. Query for name set via __asm__
+  if (!Aliasee) {
+    char *starred = (char*)alloca (strlen (AliaseeName) + 1);
+    starred[0] = 1;
+    strcpy (starred + 1, AliaseeName);
+    if (isa<Function>(V)) {
+      Aliasee = TheModule->getFunction(starred);
+    } else if (isa<GlobalVariable>(V)) {
+      Aliasee = TheModule->getNamedGlobal(starred);
+    } else if (isa<GlobalAlias>(V)) {
+      Aliasee = TheModule->getNamedAlias(starred);
+    }
+  }
+  
+  if (!Aliasee)
+    if (stage) {
+      TheModule->dump();
+      error ("%J%qD aliased to undefined symbol %qE",
+             decl, decl, target);
+    } else
+      return -1;
+    
+  GlobalValue::LinkageTypes Linkage;
+  GlobalValue::VisibilityTypes Visibility;
+
+  // Check for external weak linkage
+  if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
+    Linkage = GlobalValue::WeakLinkage;
+  else if (!TREE_PUBLIC(decl))
+    Linkage = GlobalValue::InternalLinkage;
+  else
+    Linkage = GlobalValue::ExternalLinkage;
+
+  std::string savedName = V->getName();
+  GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), Linkage, savedName,
+                                    Aliasee, TheModule);
+  // Handle visibility style
+  if (TREE_PUBLIC(decl) && DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
+    GA->setVisibility(GlobalValue::HiddenVisibility);
+
+  if (V->getType() == GA->getType())
+    V->replaceAllUsesWith(GA);
+  else if (!V->use_empty())
+    error ("%J% Alias %qD used with invalid type!", decl, decl);
+    
+  changeLLVMValue(V, GA);
+  V->eraseFromParent();
+  GA->setName(savedName);
+
+  return 0;
+}
+
+  
 /// emit_global_to_llvm - Emit the specified VAR_DECL or aggregate CONST_DECL to
 /// LLVM as a global variable.  This function implements the end of
 /// assemble_variable.
diff -r 4b9ef444e6b1 gcc/llvm.h
--- a/gcc/llvm.h	Sun Apr 22 09:01:45 2007 +0000
+++ b/gcc/llvm.h	Wed Apr 25 16:02:30 2007 +0400
@@ -48,6 +48,10 @@ void make_decl_llvm(union tree_node*);
  * variable.
  */
 void emit_global_to_llvm(union tree_node*);
+
+/* emit_global_to_llvm - Emit the specified alias to LLVM
+ */
+int emit_alias_to_llvm(union tree_node*, union tree_node*, unsigned);
 
 /* llvm_get_decl_name - Used by varasm.c, returns the specified declaration's
  * name.
diff -r 4b9ef444e6b1 gcc/varasm.c
--- a/gcc/varasm.c	Sun Apr 22 09:01:45 2007 +0000
+++ b/gcc/varasm.c	Wed Apr 25 17:03:17 2007 +0400
@@ -4645,17 +4647,17 @@ find_decl_and_mark_needed (tree decl, tr
   if (!cgraph_global_info_ready)
     {
       if (TREE_CODE (decl) == FUNCTION_DECL)
-	{
-	  fnode = cgraph_node_for_asm (target);
-	  if (fnode == NULL)
-	    vnode = cgraph_varpool_node_for_asm (target);
-	}
+        {
+          fnode = cgraph_node_for_asm (target);
+          if (fnode == NULL)
+            vnode = cgraph_varpool_node_for_asm (target);
+        }
       else
-	{
-	  vnode = cgraph_varpool_node_for_asm (target);
-	  if (vnode == NULL)
-	    fnode = cgraph_node_for_asm (target);
-	}
+        {
+          vnode = cgraph_varpool_node_for_asm (target);
+          if (vnode == NULL)
+            fnode = cgraph_node_for_asm (target);
+        }
     }
 
   if (fnode)
@@ -4675,6 +4677,14 @@ static void
 static void
 do_assemble_alias (tree decl, tree target)
 {
+/* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM  
+  if (emit_alias_to_llvm(decl, target, 1) == -1)
+    error ("%J%qD aliased to undefined symbol %qE",
+           decl, decl, target);
+  return;
+#endif
+/* APPLE LOCAL end LLVM */
   if (TREE_ASM_WRITTEN (decl))
     return;
 
@@ -4712,9 +4722,9 @@ do_assemble_alias (tree decl, tree targe
        we do not emit multiple .weak directives for it.  */
     for (p = &weak_decls; (t = *p) ; )
       if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
-	*p = TREE_CHAIN (t);
+        *p = TREE_CHAIN (t);
       else
-	p = &TREE_CHAIN (t);
+        p = &TREE_CHAIN (t);
   }
 #endif
 }
@@ -4725,20 +4735,25 @@ void
 void
 finish_aliases_1 (void)
 {
+/* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+  return;
+#endif
+/* APPLE LOCAL end LLVM */
   unsigned i;
   alias_pair p;
-
+  
   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
     {
       tree target_decl;
 
       target_decl = find_decl_and_mark_needed (p->decl, p->target);
       if (target_decl == NULL)
-	error ("%J%qD aliased to undefined symbol %qE",
-	       p->decl, p->decl, p->target);
+        error ("%J%qD aliased to undefined symbol %qE",
+               p->decl, p->decl, p->target);
       else if (DECL_EXTERNAL (target_decl))
-	error ("%J%qD aliased to external symbol %qE",
-	       p->decl, p->decl, p->target);
+        error ("%J%qD aliased to external symbol %qE",
+               p->decl, p->decl, p->target);
     }
 }
 
@@ -4764,8 +4779,12 @@ void
 void
 assemble_alias (tree decl, tree target)
 {
+/* APPLE LOCAL begin LLVM */
+#ifndef ENABLE_LLVM
   tree target_decl;
-
+#endif  
+/* APPLE LOCAL end LLVM */
+  
 #if !defined (ASM_OUTPUT_DEF)
 # if !defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL)
   error ("%Jalias definitions not supported in this configuration", decl);
@@ -4779,18 +4798,17 @@ assemble_alias (tree decl, tree target)
 # endif
 #endif
   
-  /* APPLE LOCAL begin LLVM */
-#ifdef ENABLE_LLVM
-  inform ("%JLLVM does not support aliases yet", decl);
-  return;
-#endif
-  /* APPLE LOCAL end LLVM */
-
   /* We must force creation of DECL_RTL for debug info generation, even though
      we don't use it here.  */
+/* APPLE LOCAL begin LLVM */  
+#ifndef ENABLE_LLVM  
   make_decl_rtl (decl);
+#else
+  make_decl_llvm (decl);
+#endif
+/* APPLE LOCAL end LLVM */
   TREE_USED (decl) = 1;
-
+  
   /* A quirk of the initial implementation of aliases required that the user
      add "extern" to all of them.  Which is silly, but now historical.  Do
      note that the symbol is in fact locally defined.  */
@@ -4802,11 +4820,19 @@ assemble_alias (tree decl, tree target)
   else
     cgraph_varpool_node (decl)->alias = true;
 
+/* APPLE LOCAL begin LLVM */
+#ifdef ENABLE_LLVM
+  /* Can we emit alias right now (usually true for C functions)? If yes - do it,
+   * otherwise save for late processing */
+  if (emit_alias_to_llvm(decl, target, 0) == -1)
+#else  
   /* If the target has already been emitted, we don't have to queue the
      alias.  This saves a tad o memory.  */
   target_decl = find_decl_and_mark_needed (decl, target);
   if (target_decl && TREE_ASM_WRITTEN (target_decl))
     do_assemble_alias (decl, target);
   else
+#endif
+/* APPLE LOCAL end LLVM */    
     {
       alias_pair p; 
diff -r 4b9ef444e6b1 README.LLVM
--- a/README.LLVM	Sun Apr 22 09:01:45 2007 +0000
+++ b/README.LLVM	Wed Apr 25 18:36:58 2007 +0400
@@ -41,10 +41,6 @@ Below we assume the LLVM OBJDIR is $LLVM
 
 //===-----------------------
 Linux-specific Instructions:
-
-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++. 
 
 If llvm-gcc doesn't build right, try building LLVM with OPTIMIZE_OPTION=-O2.
 This may be host compiler version specific.
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to