This finally switches us to not record global vars in referenced-vars. For this to work I had to re-engineer how we handle global var removal from local-decls in remove_unused_locals. Incidentially that code already had some sort of a bitmap (for some weird reason even), thus I borrowed that and simplified the handling. You may notice that it would be easy to handle all vars that way ...
So eventually 5/n will make referenced-vars go away completely (the only serious user seems to be the SSA renamer for its SYMS_TO_RENAME bitmap). Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2012-05-23 Richard Guenther <rguent...@suse.de> * tree-dfa.c (add_referenced_var_1): Do not add global vars. * tree-ssa-live.c (mark_all_vars_used_1): Handle global vars via the global_unused_vars bitmap. (remove_unused_locals): Handle global vars in local-decls via a global_unused_vars bitmap instead of the used flag in the var annotation. Simplify global variable handling and removal. * gcc.dg/torture/pr39074-2.c: Adjust. * gcc.dg/torture/pr39074.c: Likewise. * gcc.dg/torture/pta-structcopy-1.c: Likewise. * gcc.dg/tree-ssa/alias-19.c: Likewise. Index: gcc/tree-dfa.c =================================================================== *** gcc/tree-dfa.c.orig 2012-05-22 14:50:50.000000000 +0200 --- gcc/tree-dfa.c 2012-05-22 15:26:37.868506459 +0200 *************** add_referenced_var_1 (tree var, struct f *** 581,586 **** --- 581,591 ---- || TREE_CODE (var) == PARM_DECL || TREE_CODE (var) == RESULT_DECL); + if (!(TREE_CODE (var) == VAR_DECL + && VAR_DECL_IS_VIRTUAL_OPERAND (var)) + && is_global_var (var)) + return false; + if (!*DECL_VAR_ANN_PTR (var)) create_var_ann (var); Index: gcc/testsuite/gcc.dg/torture/pr39074-2.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr39074-2.c.orig 2011-12-06 10:39:54.000000000 +0100 --- gcc/testsuite/gcc.dg/torture/pr39074-2.c 2012-05-22 15:42:43.068473038 +0200 *************** int main() *** 30,34 **** return 0; } ! /* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 30,35 ---- return 0; } ! /* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */ ! /* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/torture/pr39074.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr39074.c.orig 2012-04-12 11:32:07.000000000 +0200 --- gcc/testsuite/gcc.dg/torture/pr39074.c 2012-05-22 15:43:07.770472209 +0200 *************** int main() *** 29,33 **** return 0; } ! /* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 29,34 ---- return 0; } ! /* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */ ! /* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c.orig 2011-06-21 13:06:08.000000000 +0200 --- gcc/testsuite/gcc.dg/torture/pta-structcopy-1.c 2012-05-22 15:42:19.922473852 +0200 *************** int main() *** 31,35 **** return 0; } ! /* { dg-final { scan-tree-dump "points-to vars: { i }" "ealias" } } */ /* { dg-final { cleanup-tree-dump "ealias" } } */ --- 31,36 ---- return 0; } ! /* { dg-final { scan-tree-dump "y.* = { i }" "ealias" } } */ ! /* { dg-final { scan-tree-dump "y.*, points-to vars: { D..... }" "ealias" } } */ /* { dg-final { cleanup-tree-dump "ealias" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/alias-19.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/alias-19.c.orig 2009-04-03 12:56:17.000000000 +0200 --- gcc/testsuite/gcc.dg/tree-ssa/alias-19.c 2012-05-22 15:39:53.318478953 +0200 *************** int main() *** 26,30 **** } /* { dg-final { scan-tree-dump "q_. = { a b }" "alias" } } */ ! /* { dg-final { scan-tree-dump "q_., points-to vars: { a b }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ --- 26,30 ---- } /* { dg-final { scan-tree-dump "q_. = { a b }" "alias" } } */ ! /* { dg-final { scan-tree-dump "q_., points-to vars: { D..... b }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ Index: gcc/tree-ssa-live.c =================================================================== *** gcc/tree-ssa-live.c (revision 187771) --- gcc/tree-ssa-live.c (working copy) *************** static inline void mark_all_vars_used (t *** 348,353 **** --- 348,354 ---- static tree mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data) { + bitmap global_unused_vars = (bitmap)data; tree t = *tp; enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t)); tree b; *************** mark_all_vars_used_1 (tree *tp, int *wal *** 374,388 **** eliminated as unused. */ if (TREE_CODE (t) == VAR_DECL) { ! 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); ! if (var_ann (t) != NULL) set_is_used (t); } /* remove_unused_scope_block_p requires information about labels which are not DECL_IGNORED_P to tell if they might be used in the IL. */ ! if (TREE_CODE (t) == LABEL_DECL) /* Although the TREE_USED values that the frontend uses would be acceptable (albeit slightly over-conservative) for our purposes, init_vars_expansion clears TREE_USED for LABEL_DECLs too, so we --- 375,394 ---- eliminated as unused. */ if (TREE_CODE (t) == VAR_DECL) { ! /* Global vars do not have a var-annotation so their use is tracked ! with the global_unused_vars bitmap. Also walk their initializer ! when they are first recognized as used. */ ! if (is_global_var (t)) ! { ! if (bitmap_clear_bit (global_unused_vars, DECL_UID (t))) ! mark_all_vars_used (&DECL_INITIAL (t), data); ! } ! else set_is_used (t); } /* remove_unused_scope_block_p requires information about labels which are not DECL_IGNORED_P to tell if they might be used in the IL. */ ! else if (TREE_CODE (t) == LABEL_DECL) /* Although the TREE_USED values that the frontend uses would be acceptable (albeit slightly over-conservative) for our purposes, init_vars_expansion clears TREE_USED for LABEL_DECLs too, so we *************** remove_unused_locals (void) *** 689,695 **** tree var, t; referenced_var_iterator rvi; bitmap global_unused_vars = NULL; ! unsigned srcidx, dstidx, num; bool have_local_clobbers = false; /* Removing declarations from lexical blocks when not optimizing is --- 695,701 ---- tree var, t; referenced_var_iterator rvi; bitmap global_unused_vars = NULL; ! unsigned srcidx, dstidx, num, ix; bool have_local_clobbers = false; /* Removing declarations from lexical blocks when not optimizing is *************** remove_unused_locals (void) *** 706,711 **** --- 712,724 ---- FOR_EACH_REFERENCED_VAR (cfun, t, rvi) clear_is_used (t); + /* Assume all globals in local decls are unused. */ + global_unused_vars = BITMAP_ALLOC (NULL); + FOR_EACH_LOCAL_DECL (cfun, ix, var) + if (TREE_CODE (var) == VAR_DECL + && is_global_var (var)) + bitmap_set_bit (global_unused_vars, DECL_UID (var)); + /* Walk the CFG marking all referenced symbols. */ FOR_EACH_BB (bb) { *************** remove_unused_locals (void) *** 733,739 **** TREE_USED (b) = true; for (i = 0; i < gimple_num_ops (stmt); i++) ! mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i), NULL); } for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) --- 746,753 ---- TREE_USED (b) = true; for (i = 0; i < gimple_num_ops (stmt); i++) ! mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i), ! global_unused_vars); } for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) *************** remove_unused_locals (void) *** 743,759 **** tree def; gimple phi = gsi_stmt (gsi); ! /* No point processing globals. */ ! if (is_global_var (SSA_NAME_VAR (gimple_phi_result (phi)))) continue; def = gimple_phi_result (phi); ! mark_all_vars_used (&def, NULL); FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES) { tree arg = USE_FROM_PTR (arg_p); ! mark_all_vars_used (&arg, NULL); } } --- 757,772 ---- tree def; gimple phi = gsi_stmt (gsi); ! if (!is_gimple_reg (gimple_phi_result (phi))) continue; def = gimple_phi_result (phi); ! mark_all_vars_used (&def, global_unused_vars); FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES) { tree arg = USE_FROM_PTR (arg_p); ! mark_all_vars_used (&arg, global_unused_vars); } } *************** remove_unused_locals (void) *** 783,789 **** 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); --- 796,805 ---- lhs = get_base_address (lhs); if (TREE_CODE (lhs) == SSA_NAME) lhs = SSA_NAME_VAR (lhs); ! if (TREE_CODE (lhs) == VAR_DECL ! && ((is_global_var (lhs) ! && bitmap_bit_p (global_unused_vars, DECL_UID (lhs))) ! || (!is_global_var (lhs) && !is_used_p (lhs)))) { unlink_stmt_vdef (stmt); gsi_remove (&gsi, true); *************** remove_unused_locals (void) *** 799,825 **** cfun->has_local_explicit_reg_vars = false; ! /* Remove unmarked local vars from local_decls. */ num = VEC_length (tree, cfun->local_decls); for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) { var = VEC_index (tree, cfun->local_decls, srcidx); ! if (TREE_CODE (var) != FUNCTION_DECL ! && (!var_ann (var) ! || !is_used_p (var))) { if (is_global_var (var)) { ! if (global_unused_vars == NULL) ! global_unused_vars = BITMAP_ALLOC (NULL); ! bitmap_set_bit (global_unused_vars, DECL_UID (var)); } - else - continue; } ! else if (TREE_CODE (var) == VAR_DECL ! && DECL_HARD_REGISTER (var) ! && !is_global_var (var)) cfun->has_local_explicit_reg_vars = true; if (srcidx != dstidx) --- 815,844 ---- cfun->has_local_explicit_reg_vars = false; ! /* Remove unmarked local and global vars from local_decls ! and referenced vars. */ num = VEC_length (tree, cfun->local_decls); for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) { var = VEC_index (tree, cfun->local_decls, srcidx); ! if (TREE_CODE (var) == VAR_DECL) { if (is_global_var (var)) { ! if (bitmap_bit_p (global_unused_vars, DECL_UID (var))) ! continue; ! } ! else if (var_ann (var) == NULL ! || !is_used_p (var)) ! { ! if (var_ann (var)) ! remove_referenced_var (var); ! continue; } } ! if (TREE_CODE (var) == VAR_DECL ! && DECL_HARD_REGISTER (var) ! && !is_global_var (var)) cfun->has_local_explicit_reg_vars = true; if (srcidx != dstidx) *************** remove_unused_locals (void) *** 828,872 **** } if (dstidx != num) VEC_truncate (tree, cfun->local_decls, dstidx); - /* Remove unmarked global vars from local_decls. */ - if (global_unused_vars != NULL) - { - tree var; - unsigned ix; - FOR_EACH_LOCAL_DECL (cfun, ix, var) - if (TREE_CODE (var) == VAR_DECL - && is_global_var (var) - && 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); - for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) - { - var = VEC_index (tree, cfun->local_decls, srcidx); - if (TREE_CODE (var) == VAR_DECL - && is_global_var (var) - && bitmap_bit_p (global_unused_vars, DECL_UID (var))) - continue; - - if (srcidx != dstidx) - VEC_replace (tree, cfun->local_decls, dstidx, var); - dstidx++; - } - if (dstidx != num) - VEC_truncate (tree, cfun->local_decls, dstidx); - BITMAP_FREE (global_unused_vars); - } - - /* Remove unused variables from REFERENCED_VARs. */ - FOR_EACH_REFERENCED_VAR (cfun, t, rvi) - if (!is_global_var (t) - && TREE_CODE (t) != PARM_DECL - && TREE_CODE (t) != RESULT_DECL - && !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)) { --- 847,854 ---- } if (dstidx != num) VEC_truncate (tree, cfun->local_decls, dstidx); + BITMAP_FREE (global_unused_vars); remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); if (dump_file && (dump_flags & TDF_DETAILS)) {