Make hack in C99 extern inline handling lesser hack

Jan Hubicka jh@suse.cz
Wed Jun 18 13:51:00 GMT 2008


Hi,
C99 extern inline semantics introduced hack that calls
cgraph_finalize_function twice on the same function.  This is not
supposed to happen and works just accidentally because of former extern
inline hack where the function was called twice on the same decl each
time with different body.  So cgraph_reset_function brings function into
former stage and copmilation restarts.  This works resonably in
unit-at-atime as we do almost nothing in cgraph_finalize, however in
non-unit-at-a-time we already process the function and optimize it so
restarting is iffy and breaks badly with SSA at O0 (or with
-fno-unit-at-a-time at higher levels)

With C99 however the body is same, only declaration is slightly
modified.  This is better handled just by re-deciding if the function is
needed.

Bootstrapped/regtested i686-linux, comitted.

Honza

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 136892)
+++ ChangeLog	(working copy)
@@ -1,5 +1,11 @@
 2008-06-16  Jan Hubicka  <jh@suse.cz>
 
+	* cgraph.h (cgraph_mark_if_needed): New function.
+	* cgraphunit.c (cgraph_mark_if_needed): New function.
+	* c-decl.c (duplicate_decl): Use it.
+
+2008-06-16  Jan Hubicka  <jh@suse.cz>
+
 	* cgraph.c (cgraph_add_new_function): When in expansion state, do
 	lowering.
 
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 136890)
+++ cgraph.h	(working copy)
@@ -331,6 +331,7 @@ void cgraph_add_new_function (tree, bool
 
 /* In cgraphunit.c  */
 void cgraph_finalize_function (tree, bool);
+void cgraph_mark_if_needed (tree);
 void cgraph_finalize_compilation_unit (void);
 void cgraph_optimize (void);
 void cgraph_mark_needed_node (struct cgraph_node *);
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 136890)
+++ cgraphunit.c	(working copy)
@@ -642,6 +642,18 @@ cgraph_finalize_function (tree decl, boo
     do_warn_unused_parameter (decl);
 }
 
+/* C99 extern inline keywords allow changing of declaration after function
+   has been finalized.  We need to re-decide if we want to mark the function as
+   needed then.   */
+
+void
+cgraph_mark_if_needed (tree decl)
+{
+  struct cgraph_node *node = cgraph_node (decl);
+  if (node->local.finalized && decide_is_function_needed (node, decl))
+    cgraph_mark_needed_node (node);
+}
+
 /* Verify cgraph nodes of given cgraph node.  */
 void
 verify_cgraph_node (struct cgraph_node *node)
Index: c-decl.c
===================================================================
--- c-decl.c	(revision 136890)
+++ c-decl.c	(working copy)
@@ -1913,9 +1913,9 @@ merge_decls (tree newdecl, tree olddecl,
   /* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL,
      and the definition is coming from the old version, cgraph needs
      to be called again.  */
-  if (extern_changed && !new_is_definition 
+  if (extern_changed && !new_is_definition
       && TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl))
-    cgraph_finalize_function (olddecl, false);
+    cgraph_mark_if_needed (olddecl);
 }
 
 /* Handle when a new declaration NEWDECL has the same name as an old



More information about the Gcc-patches mailing list