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