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