Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Deal with local static same way as we deal with global static for IPA

    9 answers - 5960 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    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, K?
    Honza
    2005-06-07 Jan Hubicka <jh (AT) suse (DOT) cz>
    * cgraphunit.c (cgraph_create_edges): Do not walk BLCK; finalize
    local statics when doing unit-at-a-time.
    (): 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.c4 Jun 2005 20:23:13 -00001.116
    cgraphunit.c7 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_CDE (DECL_INITIAL (body)) == BLCK)
    ! {
    ! for (step = BLCK_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_FUNCTIN (body))
    - for (step = DECL_STRUCT_FUNCTIN (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_FUNCTIN (body)->unexpanded_var_list;
    ! step;
    ! step = TREE_CHAIN (step))
    ! {
    ! tree decl = TREE_VALUE (step);
    ! if (TREE_CDE (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 (DECLRIGIN (decl));
    ! else if (TREE_CDE (decl) == VAR_DECL && DECL_INITIAL (decl))
    ! walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
    }
    pointer_set_destroy (visited_nodes);
    visited_nodes = NULL;
    (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_SYMUT);
    + (*debug_hooks->global_decl) (decl);
    + timevar_pop (TV_SYMUT);
    + }
    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.c7 Jun 2005 10:17:32 -00001.598
    dwarf2out.c7 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 */
    + if (TREE_CDE (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_CNTEXT (decl));
    +
    /* If we are in terse mode, don't generate any DIEs to represent any
    variable declarations or definitions. */
    if (debug_info_level <= DINFLEVEL_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.c25 May 2005 12:33:32 -00002.91
    passes.c7 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_CDE (decl) != FUNCTIN_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_CDE (decl) != FUNCTIN_DECL)
    cgraph_varpool_finalize_decl (decl);
    else
    assemble_variable (decl, top_level, at_end, 0);
  • No.1 | | 550 bytes | |

    Tue, Jun 07, 2005 at 10:11:59PM +0200, Jan Hubicka wrote:
    ! /* 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 (DECLRIGIN (decl));

    I think I'd rather you fix this first, rather than put this hack in.

    The rest of it seems ok.

    r~
  • No.2 | | 53 bytes | |

    The dwarf2 changes seem fine.
    Jason
  • No.3 | | 1040 bytes | |

    Tue, Jun 07, 2005 at 10:11:59PM +0200, Jan Hubicka wrote:
    ! /* 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 (DECLRIGIN (decl));

    I think I'd rather you fix this first, rather than put this hack in.

    I don't see how to do that easilly - the BIND_EXPRs are linked via
    TREE_CHAIN pointers and we need the local static in two BIND_EXPRs at
    once, but we have only one link pointer.
    sollution I saw was to make C++ frontend lower function before
    clonning (so we don't clone at generic level at all). I got half way
    throught my way across C++ frontend, I might try to finish it if this
    plan sounds sane, but I would preffer doing so incrementally.

    Honza

    The rest of it seems ok.

    r~
  • No.4 | | 1933 bytes | |

    Tue, Jun 07, 2005 at 10:11:59PM +0200, Jan Hubicka wrote:
    ! /* 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 (DECLRIGIN (decl));

    I think I'd rather you fix this first, rather than put this hack in.

    I don't see how to do that easilly - the BIND_EXPRs are linked via
    TREE_CHAIN pointers and we need the local static in two BIND_EXPRs at
    once, but we have only one link pointer.
    sollution I saw was to make C++ frontend lower function before
    clonning (so we don't clone at generic level at all). I got half way
    throught my way across C++ frontend, I might try to finish it if this
    plan sounds sane, but I would preffer doing so incrementally.
    K and the point where I stopped is that C++ frontend currently produce
    some code in DECL_SAVED_TREE while constructing the clone (apparently
    initializing the parameters that differ from original) and then it
    appends the duplicated body.
    Now we have the initializers in generic and the body in gimple that
    means that either C++ frontend would have to produce gimple directly
    when constructing the initializers or gimplify the partical function
    body before pasting in the inlined body. Since I would like to keep
    frontend's generic and backend's gimple separated so generic or gimple
    memory representation might change at some time, this looks like nasty
    obstackle.
    What sounds like resonable way to solve this? (assuming that this is
    resonable plan at first place ;), but killing the generic code from
    tree-inline is pretty desirable cleanup)

    Honza

    The rest of it seems ok.

    r~
  • No.5 | | 599 bytes | |

    Wed, Jun 08, 2005 at 11:02:51AM +0200, Jan Hubicka wrote:
    I don't see how to do that easilly - the BIND_EXPRs are linked via
    TREE_CHAIN pointers and we need the local static in two BIND_EXPRs at
    once, but we have only one link pointer.

    I don't think it needs to be linked into the bind_expr at all.

    We don't use the BIND_EXPRs for debugging, only the BLCKs. You may
    need to insert the variable into the inliner's unexpanded_var_list,
    to make sure that its DECL_RTL gets created at the right time, but
    that should be about it.

    r~
  • No.6 | | 1037 bytes | |

    Wed, Jun 08, 2005 at 11:02:51AM +0200, Jan Hubicka wrote:
    I don't see how to do that easilly - the BIND_EXPRs are linked via
    TREE_CHAIN pointers and we need the local static in two BIND_EXPRs at
    once, but we have only one link pointer.

    I don't think it needs to be linked into the bind_expr at all.

    I tried simply skipping them, problem I run into was the fact that
    gimplifier then didn't put it into unexpanded_var_list and thus it never
    got finalized when the master copy of function got optimized out

    We don't use the BIND_EXPRs for debugging, only the BLCKs. You may
    need to insert the variable into the inliner's unexpanded_var_list,

    K, so you suggest instead of remapping it, simply go ahead and drop it
    into the unexpanded_var_list (so we will have generic functions with
    this list partly initialized before we gimplify)?

    Honza
    to make sure that its DECL_RTL gets created at the right time, but
    that should be about it.

    r~
  • No.7 | | 290 bytes | |

    Wed, Jun 08, 2005 at 09:39:17PM +0200, Jan Hubicka wrote:
    K, so you suggest instead of remapping it, simply go ahead and drop it
    into the unexpanded_var_list (so we will have generic functions with
    this list partly initialized before we gimplify)?
    Yes.
    r~
  • No.8 | | 5983 bytes | |

    Wed, Jun 08, 2005 at 09:39:17PM +0200, Jan Hubicka wrote:
    K, so you suggest instead of remapping it, simply go ahead and drop it
    into the unexpanded_var_list (so we will have generic functions with
    this list partly initialized before we gimplify)?

    Yes.
    K, done thus

    Bootstrapped/regtested i686-pc-gnu-linux, K?

    Honza

    2005-06-07 Jan Hubicka <jh (AT) suse (DOT) cz>
    * cgraphunit.c (cgraph_create_edges): Do not walk BLCK; finalize
    local statics when doing unit-at-a-time.
    (): 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.
    * tree-inline.c (remap_decls): Put local static into
    unexpanded_vars_list rather than introducing duplicated VAR_DECL
    node.
    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.c4 Jun 2005 20:23:13 -00001.116
    cgraphunit.c9 Jun 2005 09:57:18 -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_CDE (DECL_INITIAL (body)) == BLCK)
    ! {
    ! for (step = BLCK_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_FUNCTIN (body))
    - for (step = DECL_STRUCT_FUNCTIN (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,561
    walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
    }

    ! /* Look for initializers of constant variables and private statics. */
    ! for (step = DECL_STRUCT_FUNCTIN (body)->unexpanded_var_list;
    ! step;
    ! step = TREE_CHAIN (step))
    ! {
    ! tree decl = TREE_VALUE (step);
    ! if (TREE_CDE (decl) == VAR_DECL
    ! && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
    ! && flag_unit_at_a_time)
    ! cgraph_varpool_finalize_decl (decl);
    ! else if (TREE_CDE (decl) == VAR_DECL && DECL_INITIAL (decl))
    ! walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
    }

    pointer_set_destroy (visited_nodes);
    visited_nodes = NULL;
    (v
    743,748
    736,749
    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_SYMUT);
    + (*debug_hooks->global_decl) (decl);
    + timevar_pop (TV_SYMUT);
    + }
    changed = true;
    }
    node->next_needed = NULL;
    Index: dwarf2out.c

    RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
    retrieving revision 1.600
    diff -c -3 -p -r1.600 dwarf2out.c
    dwarf2out.c8 Jun 2005 07:48:16 -00001.600
    dwarf2out.c9 Jun 2005 09:57:19 -0000
    decls_for_scope (tree stmt, dw_die_ref c
    12523,12528
    12523,12533

    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 */
    + if (TREE_CDE (decl) == VAR_DECL && TREE_STATIC (decl))
    + ;
    else
    gen_decl_die (decl, context_die);
    }
    dwarf2out_decl (tree decl)
    13070,13075
    13075,13084
    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_CNTEXT (decl));
    +
    /* If we are in terse mode, don't generate any DIEs to represent any
    variable declarations or definitions. */
    if (debug_info_level <= DINFLEVEL_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.c25 May 2005 12:33:32 -00002.91
    passes.c9 Jun 2005 09:57:19 -0000
    rest_of_decl_compilation (tree decl,
    227,233
    && !DECL_EXTERNAL (decl))
    {
    if (flag_unit_at_a_time && !cgraph_global_info_ready
    ! && TREE_CDE (decl) != FUNCTIN_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_CDE (decl) != FUNCTIN_DECL)
    cgraph_varpool_finalize_decl (decl);
    else
    assemble_variable (decl, top_level, at_end, 0);
    Index: tree-inline.c

    RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
    retrieving revision 1.192
    diff -c -3 -p -r1.192 tree-inline.c
    tree-inline.c6 Jun 2005 19:31:26 -00001.192
    tree-inline.c9 Jun 2005 09:57:19 -0000
    remap_decls (tree decls, inline_data *id
    385,390
    385,401
    {
    tree new_var;

    + /* We can not chain the local static declarations into the list
    + as we can't duplicate them or break one decl rule. Go ahead and link
    + them into unexpanded_var_list. */
    + if (! (old_var, id->callee)
    + && !DECL_EXTERNAL (old_var))
    + {
    + cfun->unexpanded_var_list = tree_cons (NULL_TREE, old_var,
    + cfun->unexpanded_var_list);
    + continue;
    + }
    +
    /* Remap the variable. */
    new_var = remap_decl (old_var, id);
  • No.9 | | 552 bytes | |

    Thu, Jun 09, 2005 at 04:12:01PM +0200, Jan Hubicka wrote:
    * cgraphunit.c (cgraph_create_edges): Do not walk BLCK; finalize
    local statics when doing unit-at-a-time.
    (): 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.
    * tree-inline.c (remap_decls): Put local static into
    unexpanded_vars_list rather than introducing duplicated VAR_DECL
    node.

    r~

Re: Deal with local static same way as we deal with global static for IPA


max 4000 letters.
Your nickname that display:
In order to stop the spam: 2 + 1 =
QUESTION ON "Development"

EMSDN.COM