[llvm-commits] [llvm-gcc-4.2] r103229 - in /llvm-gcc-4.2/trunk/gcc: cgraph.c cgraph.h cgraphunit.c ipa.c llvm-convert.cpp

Dale Johannesen dalej at apple.com
Thu May 6 18:10:24 PDT 2010


Author: johannes
Date: Thu May  6 20:10:24 2010
New Revision: 103229

URL: http://llvm.org/viewvc/llvm-project?rev=103229&view=rev
Log:
Fix for PR 4262 / 6599374 (extern inline handling).

The basic problem with Duncan's previous attempt (see PR 4262)
is that there isn't anything in GCC's IR corresponding to "extern"
in the source; there is a DECL_EXTERNAL bit which means that in C,
but is abused by C++ and ObjC to mean other things.  The way around
that is to pay attention to that bit only if the language is C; ugly,
but so is the problem it's working around.  Tested by gcc.dg/98031[23]-1.c
in gcc testsuite.


Modified:
    llvm-gcc-4.2/trunk/gcc/cgraph.c
    llvm-gcc-4.2/trunk/gcc/cgraph.h
    llvm-gcc-4.2/trunk/gcc/cgraphunit.c
    llvm-gcc-4.2/trunk/gcc/ipa.c
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/cgraph.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cgraph.c?rev=103229&r1=103228&r2=103229&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cgraph.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cgraph.c Thu May  6 20:10:24 2010
@@ -601,7 +601,7 @@
       if (!n->next_clone && !n->global.inlined_to
 	  && (cgraph_global_info_ready
               /* LLVM LOCAL extern inline */
-	      && (TREE_ASM_WRITTEN (n->decl) || IS_EXTERN_INLINE (n->decl))))
+	      && (TREE_ASM_WRITTEN (n->decl) || IS_EXTERN_NOINLINE (n->decl))))
 	kill_body = true;
     }
 

Modified: llvm-gcc-4.2/trunk/gcc/cgraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cgraph.h?rev=103229&r1=103228&r2=103229&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cgraph.h (original)
+++ llvm-gcc-4.2/trunk/gcc/cgraph.h Thu May  6 20:10:24 2010
@@ -336,13 +336,32 @@
 
 /* LLVM LOCAL begin 6501843 */
 /* We're no longer running gcc's inliner at all, so the bodies of 
-   used extern always-inline functions must be passed down to the LLVM BE.
-   cgraph used to remove these.  (gcc "extern inline" == c99 "inline") */
+   used extern inline functions must be passed down to the LLVM BE.
+   cgraph used to remove these.  (gcc "extern inline" == c99 "inline").
+
+   C++ uses DECL_EXTERNAL to mark functions instantiated as part of
+   template instantiation which should not be emitted. Objective C uses
+   it for some other convoluted purpose.  Functions marked this way in
+   other languages should not be passed down to the LLVM BE.  The easiest
+   way to outwit this, although inelegant, seems to be to check the language.
+
+   Weak extern inlines are treated as weak.
+
+   For compilation speed in the common case we don't include langhooks.h
+   here; the few users of this file that use IS_EXTERN_[NO]INLINE need to
+   include it. */
 #ifdef ENABLE_LLVM
 #define IS_EXTERN_INLINE(f) (DECL_EXTERNAL(f) && \
-           !lookup_attribute("always_inline", DECL_ATTRIBUTES(f)))
+           DECL_EXPLICIT_INLINE_P(f) && \
+           !lookup_attribute ("weak", DECL_ATTRIBUTES (f)) && \
+           strcmp (lang_hooks.name, "GNU C") == 0)
+#define IS_EXTERN_NOINLINE(f) (DECL_EXTERNAL(f) && \
+           (!DECL_EXPLICIT_INLINE_P(f) || \
+            lookup_attribute ("weak", DECL_ATTRIBUTES (f)) || \
+            strcmp (lang_hooks.name, "GNU C") != 0))
 #else
 #define IS_EXTERN_INLINE(f) (DECL_EXTERNAL(f))
+#define IS_EXTERN_NOINLINE(f) (!DECL_EXTERNAL(f))
 #endif
 /* LLVM LOCAL end */
 #endif  /* GCC_CGRAPH_H  */

Modified: llvm-gcc-4.2/trunk/gcc/cgraphunit.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cgraphunit.c?rev=103229&r1=103228&r2=103229&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cgraphunit.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cgraphunit.c Thu May  6 20:10:24 2010
@@ -385,7 +385,7 @@
       if (!n->global.inlined_to
 	  && !n->alias
           /* LLVM LOCAL extern inline */
-	  && !IS_EXTERN_INLINE (n->decl))
+	  && !IS_EXTERN_NOINLINE (n->decl))
 	{
 	  cgraph_expand_function (n);
 	  output = true;
@@ -849,7 +849,7 @@
   if (node->analyzed
       && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
       /* LLVM LOCAL extern inline */ 
-      && (!IS_EXTERN_INLINE (node->decl) || node->global.inlined_to))
+      && (!IS_EXTERN_NOINLINE (node->decl) || node->global.inlined_to))
     {
       if (this_cfun->cfg)
 	{
@@ -1295,7 +1295,7 @@
 	      || (e && node->reachable))
 	  && !TREE_ASM_WRITTEN (decl)
           /* LLVM LOCAL extern inline */
-	  && !IS_EXTERN_INLINE (decl))
+	  && !IS_EXTERN_NOINLINE (decl))
 	node->output = 1;
       else
 	{
@@ -1303,7 +1303,7 @@
 #ifdef ENABLE_CHECKING
 	  if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
               /* LLVM LOCAL extern inline */
-	      && !IS_EXTERN_INLINE (decl))
+	      && !IS_EXTERN_NOINLINE (decl))
 	    {
 	      dump_cgraph_node (stderr, node);
 	      internal_error ("failed to reclaim unneeded function");
@@ -1311,7 +1311,7 @@
 #endif
           /* LLVM LOCAL extern inline */
 	  gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
-		      || IS_EXTERN_INLINE (decl));
+		      || IS_EXTERN_NOINLINE (decl));
 	}
 
     }
@@ -2040,3 +2040,4 @@
 }
 
 #include "gt-cgraphunit.h"
+

Modified: llvm-gcc-4.2/trunk/gcc/ipa.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ipa.c?rev=103229&r1=103228&r2=103229&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/ipa.c (original)
+++ llvm-gcc-4.2/trunk/gcc/ipa.c Thu May  6 20:10:24 2010
@@ -23,6 +23,7 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "cgraph.h"
+#include "langhooks.h"
 
 /* Fill array order with all nodes with output flag set in the reverse
    topological order.  */
@@ -113,7 +114,7 @@
   for (node = cgraph_nodes; node; node = node->next)
     if (node->needed && !node->global.inlined_to
         /* LLVM LOCAL extern inline */
-	&& ((!IS_EXTERN_INLINE (node->decl))
+	&& ((!IS_EXTERN_NOINLINE (node->decl))
             || !node->analyzed
             || before_inlining_p))
       {
@@ -137,7 +138,7 @@
 	    && node->analyzed
 	    && (!e->inline_failed || !e->callee->analyzed
                 /* LLVM LOCAL extern inline */
-		|| !IS_EXTERN_INLINE(e->callee->decl)
+		|| !IS_EXTERN_NOINLINE(e->callee->decl)
                 || before_inlining_p))
 	  {
 	    e->callee->aux = first;
@@ -169,7 +170,7 @@
 	  if (file)
 	    fprintf (file, " %s", cgraph_node_name (node));
               /* LLVM LOCAL extern inline */
-	  if (!node->analyzed || !IS_EXTERN_INLINE(node->decl)
+	  if (!node->analyzed || !IS_EXTERN_NOINLINE(node->decl)
 	      || before_inlining_p)
 	    cgraph_remove_node (node);
 	  else

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=103229&r1=103228&r2=103229&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu May  6 20:10:24 2010
@@ -529,10 +529,6 @@
   assert(Fn->empty() && "Function expanded multiple times!");
   
   // Compute the linkage that the function should get.
-  // Functions declared "always inline" should not have a body
-  // emitted; hack this by pretending they're static.  That will either
-  // make them go away or emit a static definition that won't collide with
-  // anything.
   if (DECL_LLVM_PRIVATE(FnDecl)) {
     Fn->setLinkage(Function::PrivateLinkage);
   } else if (DECL_LLVM_LINKER_PRIVATE(FnDecl)) {
@@ -541,7 +537,7 @@
     Fn->setLinkage(Function::InternalLinkage);
   } else if (DECL_EXTERNAL(FnDecl) && 
              lookup_attribute ("always_inline", DECL_ATTRIBUTES (FnDecl))) {
-    Fn->setLinkage(Function::InternalLinkage);
+    Fn->setLinkage(Function::AvailableExternallyLinkage);
   } else if (DECL_COMDAT(FnDecl)) {
     Fn->setLinkage(Function::getLinkOnceLinkage(flag_odr));
   } else if (DECL_WEAK(FnDecl)) {
@@ -549,6 +545,9 @@
     Fn->setLinkage(Function::WeakAnyLinkage);
   } else if (DECL_ONE_ONLY(FnDecl)) {
     Fn->setLinkage(Function::getWeakLinkage(flag_odr));
+  } else if (IS_EXTERN_INLINE(FnDecl)) {
+    // gcc "extern inline", C99 "inline"
+    Fn->setLinkage(Function::AvailableExternallyLinkage);
   }
 
 #ifdef TARGET_ADJUST_LLVM_LINKAGE





More information about the llvm-commits mailing list