X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-ssa-live.c;h=80ab42558cc10fac58a5401d2a91be463f5955bd;hb=70d2aaaa4527221ce952bdc3253a788be0d8c875;hp=232df844a49c1a527680cb9f26b7792f9826c2c5;hpb=755107920da8ba6b4ff4d32bcac7d5b52d2739a8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 232df844a49..80ab42558cc 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -1,5 +1,5 @@ /* Liveness for SSA trees. - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Andrew MacLeod @@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-dump.h" #include "tree-ssa-live.h" #include "diagnostic-core.h" -#include "toplev.h" #include "debug.h" #include "flags.h" #include "gimple.h" @@ -158,10 +157,8 @@ delete_var_map (var_map map) { var_map_base_fini (map); partition_delete (map->var_partition); - if (map->partition_to_view) - free (map->partition_to_view); - if (map->view_to_partition) - free (map->view_to_partition); + free (map->partition_to_view); + free (map->view_to_partition); free (map); } @@ -377,7 +374,8 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data) eliminated as unused. */ if (TREE_CODE (t) == VAR_DECL) { - if (data != NULL && bitmap_clear_bit ((bitmap) data, DECL_UID (t))) + if (data != NULL && bitmap_clear_bit ((bitmap) data, DECL_UID (t)) + && DECL_CONTEXT (t) == current_function_decl) mark_all_vars_used (&DECL_INITIAL (t), data); set_is_used (t); } @@ -428,7 +426,6 @@ remove_unused_scope_block_p (tree scope) { tree *t, *next; bool unused = !TREE_USED (scope); - var_ann_t ann; int nsubblocks = 0; for (t = &BLOCK_VARS (scope); *t; t = next) @@ -465,8 +462,7 @@ remove_unused_scope_block_p (tree scope) info about optimized-out variables in the scope blocks. Exception are the scope blocks not containing any instructions at all so user can't get into the scopes at first place. */ - else if ((ann = var_ann (*t)) != NULL - && ann->used) + else if (var_ann (*t) != NULL && is_used_p (*t)) unused = false; else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t)) /* For labels that are still used in the IL, the decision to @@ -491,11 +487,16 @@ remove_unused_scope_block_p (tree scope) can be considered dead. We only want to keep around blocks user can breakpoint into and ask about value of optimized out variables. - Similarly we need to keep around types at least until all variables of - all nested blocks are gone. We track no information on whether given - type is used or not. */ + Similarly we need to keep around types at least until all + variables of all nested blocks are gone. We track no + information on whether given type is used or not, so we have + to keep them even when not emitting debug information, + otherwise we may end up remapping variables and their (local) + types in different orders depending on whether debug + information is being generated. */ - else if (debug_info_level == DINFO_LEVEL_NORMAL + else if (TREE_CODE (*t) == TYPE_DECL + || debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE) ; else @@ -626,13 +627,11 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags) for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var)) { bool used = false; - var_ann_t ann; - if ((ann = var_ann (var)) - && ann->used) - used = true; + if (var_ann (var)) + used = is_used_p (var); - fprintf (file, "%*s",indent, ""); + fprintf (file, "%*s", indent, ""); print_generic_decl (file, var, flags); fprintf (file, "%s\n", used ? "" : " (unused)"); } @@ -685,9 +684,9 @@ remove_unused_locals (void) basic_block bb; tree var, t; referenced_var_iterator rvi; - var_ann_t ann; bitmap global_unused_vars = NULL; unsigned srcidx, dstidx, num; + bool have_local_clobbers = false; /* Removing declarations from lexical blocks when not optimizing is not only a waste of time, it actually causes differences in stack @@ -695,11 +694,13 @@ remove_unused_locals (void) if (!optimize) return; + timevar_push (TV_REMOVE_UNUSED); + mark_scope_block_unused (DECL_INITIAL (current_function_decl)); /* Assume all locals are unused. */ - FOR_EACH_REFERENCED_VAR (t, rvi) - var_ann (t)->used = false; + FOR_EACH_REFERENCED_VAR (cfun, t, rvi) + clear_is_used (t); /* Walk the CFG marking all referenced symbols. */ FOR_EACH_BB (bb) @@ -718,6 +719,12 @@ remove_unused_locals (void) if (is_gimple_debug (stmt)) continue; + if (gimple_clobber_p (stmt)) + { + have_local_clobbers = true; + continue; + } + if (b) TREE_USED (b) = true; @@ -751,6 +758,41 @@ remove_unused_locals (void) TREE_USED (e->goto_block) = true; } + /* We do a two-pass approach about the out-of-scope clobbers. We want + to remove them if they are the only references to a local variable, + but we want to retain them when there's any other. So the first pass + ignores them, and the second pass (if there were any) tries to remove + them. */ + if (have_local_clobbers) + FOR_EACH_BB (bb) + { + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) + { + gimple stmt = gsi_stmt (gsi); + tree b = gimple_block (stmt); + + if (gimple_clobber_p (stmt)) + { + tree lhs = gimple_assign_lhs (stmt); + lhs = get_base_address (lhs); + if (TREE_CODE (lhs) == SSA_NAME) + lhs = SSA_NAME_VAR (lhs); + if (DECL_P (lhs) && (!var_ann (lhs) || !is_used_p (lhs))) + { + unlink_stmt_vdef (stmt); + gsi_remove (&gsi, true); + release_defs (stmt); + continue; + } + if (b) + TREE_USED (b) = true; + } + gsi_next (&gsi); + } + } + cfun->has_local_explicit_reg_vars = false; /* Remove unmarked local vars from local_decls. */ @@ -759,8 +801,8 @@ remove_unused_locals (void) { var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) != FUNCTION_DECL - && (!(ann = var_ann (var)) - || !ann->used)) + && (!var_ann (var) + || !is_used_p (var))) { if (is_global_var (var)) { @@ -791,8 +833,9 @@ remove_unused_locals (void) FOR_EACH_LOCAL_DECL (cfun, ix, var) if (TREE_CODE (var) == VAR_DECL && is_global_var (var) - && (ann = var_ann (var)) != NULL - && ann->used) + && var_ann (var) != NULL + && is_used_p (var) + && DECL_CONTEXT (var) == current_function_decl) mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); num = VEC_length (tree, cfun->local_decls); @@ -814,12 +857,11 @@ remove_unused_locals (void) } /* Remove unused variables from REFERENCED_VARs. */ - FOR_EACH_REFERENCED_VAR (t, rvi) + FOR_EACH_REFERENCED_VAR (cfun, t, rvi) if (!is_global_var (t) && TREE_CODE (t) != PARM_DECL && TREE_CODE (t) != RESULT_DECL - && !(ann = var_ann (t))->used - && !ann->is_heapvar) + && !is_used_p (t)) remove_referenced_var (t); remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); if (dump_file && (dump_flags & TDF_DETAILS)) @@ -827,6 +869,8 @@ remove_unused_locals (void) fprintf (dump_file, "Scope blocks after cleanups:\n"); dump_scope_blocks (dump_file, dump_flags); } + + timevar_pop (TV_REMOVE_UNUSED); }