This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Deal with local static same way as we deal with global static for IPA
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com, jason at redhat dot com,zadeck at naturalbridge dot com
- Date: Tue, 7 Jun 2005 22:11:59 +0200
- Subject: Deal with local static same way as we deal with global static for IPA
Hi,
This patch makes local static variables to behave like global static variables
from IPA point of view (so they are present in the variable pool and emitted
via IPA channels instead being "on the side" of function bodies). I would like
opinion of more dwarf aware person whether my debug changes are fine here. It
seems to byte compare for produced assembly in the trivial testcases (function
having local static and function having local static being inlined several
times) and pass gdb testsuite but I don't claim I 100% know what I am doing
(the basic idea is to delay the debug info for final pass where we know what
variables will be output and what optimized out completely). The patch
is short but it took me surprisingly long to converge into this rather
obvious version (also due to some related bugs in varpool fixed now)
Bootstrapped/regtested i686-pc-gnu-linux, OK?
Honza
2005-06-07 Jan Hubicka <jh@suse.cz>
* cgraphunit.c (cgraph_create_edges): Do not walk BLOCK; finalize
local statics when doing unit-at-a-time.
(cgraph_varpool_assemble_pending_decls): Output debug info.
* dwarf2out.c (decls_for_scope): Skip local statics.
(dwarf2out_decl): Handle local statics.
* passes.c (rest_of_decl_compilation): Do not differentiate
local and global statics in unit-at-a-time.
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.116
diff -c -3 -p -r1.116 cgraphunit.c
*** cgraphunit.c 4 Jun 2005 20:23:13 -0000 1.116
--- cgraphunit.c 7 Jun 2005 17:41:15 -0000
*************** cgraph_create_edges (struct cgraph_node
*** 543,568 ****
walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
}
! /* Walk over any private statics that may take addresses of functions. */
! if (TREE_CODE (DECL_INITIAL (body)) == BLOCK)
! {
! for (step = BLOCK_VARS (DECL_INITIAL (body));
! step;
! step = TREE_CHAIN (step))
! if (DECL_INITIAL (step))
! walk_tree (&DECL_INITIAL (step), record_reference, node, visited_nodes);
}
-
- /* Also look here for private statics. */
- if (DECL_STRUCT_FUNCTION (body))
- for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list;
- step;
- step = TREE_CHAIN (step))
- {
- tree decl = TREE_VALUE (step);
- if (DECL_INITIAL (decl) && TREE_STATIC (decl))
- walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
- }
pointer_set_destroy (visited_nodes);
visited_nodes = NULL;
--- 543,566 ----
walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
}
! /* Look for initializers of constant variables and private statics. */
! for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list;
! step;
! step = TREE_CHAIN (step))
! {
! tree decl = TREE_VALUE (step);
! if (TREE_CODE (decl) == VAR_DECL
! && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
! && flag_unit_at_a_time)
! /* FIXME: tree-inline.c duplicates static declarations during copying
! BIND_EXPR_VARS list (so they can be chained by TREE_CHAIN) while
! other occurences are still shared (as static variables
! are shared), so we need to look for the origin here. Kill it
! once this is cleaned up. */
! cgraph_varpool_finalize_decl (DECL_ORIGIN (decl));
! else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
! walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
}
pointer_set_destroy (visited_nodes);
visited_nodes = NULL;
*************** cgraph_varpool_assemble_pending_decls (v
*** 743,748 ****
--- 741,754 ----
if (!TREE_ASM_WRITTEN (decl) && !node->alias && !DECL_EXTERNAL (decl))
{
assemble_variable (decl, 0, 1, 0);
+ /* Local static vairables are neever seen by check_global_declarations
+ so we need to output debug info by hand. */
+ if (decl_function_context (decl) && errorcount == 0 && sorrycount == 0)
+ {
+ timevar_push (TV_SYMOUT);
+ (*debug_hooks->global_decl) (decl);
+ timevar_pop (TV_SYMOUT);
+ }
changed = true;
}
node->next_needed = NULL;
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.598
diff -c -3 -p -r1.598 dwarf2out.c
*** dwarf2out.c 7 Jun 2005 10:17:32 -0000 1.598
--- dwarf2out.c 7 Jun 2005 17:41:16 -0000
*************** decls_for_scope (tree stmt, dw_die_ref c
*** 12524,12529 ****
--- 12524,12534 ----
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
+ /* Do not produce debug information for static variables since
+ these might be optimized out. We are called for these later
+ in cgraph_varpool_analyze_pending_decls. */
+ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ ;
else
gen_decl_die (decl, context_die);
}
*************** dwarf2out_decl (tree decl)
*** 13071,13076 ****
--- 13076,13085 ----
if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
return;
+ /* For local statics lookup proper context die. */
+ if (TREE_STATIC (decl) && decl_function_context (decl))
+ context_die = lookup_decl_die (DECL_CONTEXT (decl));
+
/* If we are in terse mode, don't generate any DIEs to represent any
variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.91
diff -c -3 -p -r2.91 passes.c
*** passes.c 25 May 2005 12:33:32 -0000 2.91
--- passes.c 7 Jun 2005 17:41:16 -0000
*************** rest_of_decl_compilation (tree decl,
*** 227,233 ****
&& !DECL_EXTERNAL (decl))
{
if (flag_unit_at_a_time && !cgraph_global_info_ready
! && TREE_CODE (decl) != FUNCTION_DECL && top_level)
cgraph_varpool_finalize_decl (decl);
else
assemble_variable (decl, top_level, at_end, 0);
--- 227,233 ----
&& !DECL_EXTERNAL (decl))
{
if (flag_unit_at_a_time && !cgraph_global_info_ready
! && TREE_CODE (decl) != FUNCTION_DECL)
cgraph_varpool_finalize_decl (decl);
else
assemble_variable (decl, top_level, at_end, 0);