Hi, On Wed, 1 Aug 2012, Richard Guenther wrote:
> Ok. Would be nice to now unify global and local var handling with a > single bitmap. Yeah, wanted to do that as follow-up. Namely like so. Regstrapping on x86_64-linux in progress on top of your remove-referenced-vars patches. Okay for trunk? Ciao, Michael. -- * tree-ssa-live.c (set_is_used): Return a bool. (mark_all_vars_used): Don't take data argument. (mark_all_vars_used_1): Adjust calls to above, merge handling of local and global vars. (remove_unused_scope_block_p): Don't take global_unused_vars, merge handling of local and global vars. (remove_unused_locals): Don't allocate/fill/pass global_unused_vars, use is_used_p for local and global vars. Index: gcc/tree-ssa-live.c =================================================================== *** gcc.orig/tree-ssa-live.c 2012-08-01 17:21:39.000000000 +0200 --- gcc/tree-ssa-live.c 2012-08-01 17:22:01.000000000 +0200 *************** partition_view_bitmap (var_map map, bitm *** 331,342 **** static bitmap usedvars; ! /* Mark VAR as used, so that it'll be preserved during rtl expansion. */ ! static inline void set_is_used (tree var) { ! bitmap_set_bit (usedvars, DECL_UID (var)); } /* Return true if VAR is marked as used. */ --- 331,343 ---- static bitmap usedvars; ! /* Mark VAR as used, so that it'll be preserved during rtl expansion. ! Returns true if VAR wasn't marked before. */ ! static inline bool set_is_used (tree var) { ! return bitmap_set_bit (usedvars, DECL_UID (var)); } /* Return true if VAR is marked as used. */ *************** is_used_p (tree var) *** 347,360 **** return bitmap_bit_p (usedvars, DECL_UID (var)); } ! static inline void mark_all_vars_used (tree *, void *data); /* Helper function for mark_all_vars_used, called via walk_tree. */ 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; --- 348,360 ---- return bitmap_bit_p (usedvars, DECL_UID (var)); } ! static inline void mark_all_vars_used (tree *); /* Helper function for mark_all_vars_used, called via walk_tree. */ static tree ! mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) { 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 *** 370,378 **** fields do not contain vars. */ if (TREE_CODE (t) == TARGET_MEM_REF) { ! mark_all_vars_used (&TMR_BASE (t), data); ! mark_all_vars_used (&TMR_INDEX (t), data); ! mark_all_vars_used (&TMR_INDEX2 (t), data); *walk_subtrees = 0; return NULL; } --- 370,378 ---- fields do not contain vars. */ if (TREE_CODE (t) == TARGET_MEM_REF) { ! mark_all_vars_used (&TMR_BASE (t)); ! mark_all_vars_used (&TMR_INDEX (t)); ! mark_all_vars_used (&TMR_INDEX2 (t)); *walk_subtrees = 0; return NULL; } *************** mark_all_vars_used_1 (tree *tp, int *wal *** 381,396 **** 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. */ --- 381,390 ---- eliminated as unused. */ if (TREE_CODE (t) == VAR_DECL) { ! /* When a global var becomes used for the first time also walk its ! initializer (non global ones don't have any). */ ! if (set_is_used (t) && is_global_var (t)) ! mark_all_vars_used (&DECL_INITIAL (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. */ *************** mark_scope_block_unused (tree scope) *** 435,441 **** done by the inliner. */ static bool ! remove_unused_scope_block_p (tree scope, bitmap global_unused_vars) { tree *t, *next; bool unused = !TREE_USED (scope); --- 429,435 ---- done by the inliner. */ static bool ! remove_unused_scope_block_p (tree scope) { tree *t, *next; bool unused = !TREE_USED (scope); *************** remove_unused_scope_block_p (tree scope, *** 475,483 **** 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 ((is_global_var (*t) ! && !bitmap_bit_p (global_unused_vars, DECL_UID (*t))) ! || 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 --- 469,475 ---- 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 (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 *************** remove_unused_scope_block_p (tree scope, *** 522,528 **** } for (t = &BLOCK_SUBBLOCKS (scope); *t ;) ! if (remove_unused_scope_block_p (*t, global_unused_vars)) { if (BLOCK_SUBBLOCKS (*t)) { --- 514,520 ---- } for (t = &BLOCK_SUBBLOCKS (scope); *t ;) ! if (remove_unused_scope_block_p (*t)) { if (BLOCK_SUBBLOCKS (*t)) { *************** remove_unused_scope_block_p (tree scope, *** 603,611 **** eliminated during the tree->rtl conversion process. */ static inline void ! mark_all_vars_used (tree *expr_p, void *data) { ! walk_tree (expr_p, mark_all_vars_used_1, data, NULL); } --- 595,603 ---- eliminated during the tree->rtl conversion process. */ static inline void ! mark_all_vars_used (tree *expr_p) { ! walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL); } *************** remove_unused_locals (void) *** 693,700 **** { basic_block bb; tree var; ! bitmap global_unused_vars = NULL; ! unsigned srcidx, dstidx, num, ix; bool have_local_clobbers = false; /* Removing declarations from lexical blocks when not optimizing is --- 685,691 ---- { basic_block bb; tree var; ! unsigned srcidx, dstidx, num; bool have_local_clobbers = false; /* Removing declarations from lexical blocks when not optimizing is *************** remove_unused_locals (void) *** 709,721 **** usedvars = BITMAP_ALLOC (NULL); - /* 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) { --- 700,705 ---- *************** remove_unused_locals (void) *** 743,750 **** 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)) --- 727,733 ---- TREE_USED (b) = true; for (i = 0; i < gimple_num_ops (stmt); i++) ! mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i)); } for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) *************** remove_unused_locals (void) *** 758,769 **** 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); } } --- 741,752 ---- continue; def = gimple_phi_result (phi); ! mark_all_vars_used (&def); FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES) { tree arg = USE_FROM_PTR (arg_p); ! mark_all_vars_used (&arg); } } *************** remove_unused_locals (void) *** 793,802 **** 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); --- 776,782 ---- lhs = get_base_address (lhs); if (TREE_CODE (lhs) == SSA_NAME) lhs = SSA_NAME_VAR (lhs); ! if (TREE_CODE (lhs) == VAR_DECL && !is_used_p (lhs)) { unlink_stmt_vdef (stmt); gsi_remove (&gsi, true); *************** remove_unused_locals (void) *** 812,831 **** 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 (!is_used_p (var)) { if (cfun->nonlocal_goto_save_area && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var) --- 792,805 ---- cfun->has_local_explicit_reg_vars = false; ! /* Remove unmarked local and global 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) == VAR_DECL) { ! if (!is_used_p (var)) { if (cfun->nonlocal_goto_save_area && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var) *************** remove_unused_locals (void) *** 845,854 **** if (dstidx != num) VEC_truncate (tree, cfun->local_decls, dstidx); ! remove_unused_scope_block_p (DECL_INITIAL (current_function_decl), ! global_unused_vars); - BITMAP_FREE (global_unused_vars); BITMAP_FREE (usedvars); if (dump_file && (dump_flags & TDF_DETAILS)) --- 819,826 ---- if (dstidx != num) VEC_truncate (tree, cfun->local_decls, dstidx); ! remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); BITMAP_FREE (usedvars); if (dump_file && (dump_flags & TDF_DETAILS))