2009-09-30 Alexandre Oliva * tree-dfa.c (referenced_var_p): New. (remove_referenced_var): Clear renaming mark. * tree-flow.h (referenced_var_p): Declare. (sym_marked_for_renaming, clear_mark_for_renaming): Declare. * tree-into-ssa.c (clear_mark_for_renaming): New. (sym_marked_for_renaming): New. * tree-ssa-operands.c (pop_stmt_changes): Reset debug stmts that reference otherwise-unreferenced variables. * gcc.dg/debug/vta-1.c: New. --- gcc/tree-dfa.c.orig 2009-09-30 04:00:45.000000000 -0300 +++ gcc/tree-dfa.c 2009-09-30 04:01:21.000000000 -0300 @@ -639,6 +639,23 @@ set_default_def (tree var, tree def) SSA_NAME_IS_DEFAULT_DEF (def) = true; } +/* Return TRUE if VAR is in the set of referenced variables. */ + +bool +referenced_var_p (tree var) +{ + struct tree_decl_minimal in; + + gcc_assert (DECL_P (var)); + + if (!gimple_referenced_vars (cfun)) + return false; + + in.uid = DECL_UID (var); + return htab_find_with_hash (gimple_referenced_vars (cfun), &in, in.uid) + != NULL; +} + /* Add VAR to the list of referenced variables if it isn't already there. */ bool @@ -686,6 +703,15 @@ remove_referenced_var (tree var) void **loc; unsigned int uid = DECL_UID (var); + /* Symbols that decayed from addressable to gimple registers, but + that are referenced only in debug stmts, may be marked for + renaming, but renaming them would fail once they're no longer + referenced. Let them rest in peace. */ + if (TREE_CODE (var) != SSA_NAME + && is_gimple_reg (var) + && sym_marked_for_renaming (var)) + clear_mark_for_renaming (var); + clear_call_clobbered (var); bitmap_clear_bit (gimple_call_used_vars (cfun), uid); if ((v_ann = var_ann (var))) --- gcc/tree-flow.h.orig 2009-09-30 04:00:46.000000000 -0300 +++ gcc/tree-flow.h 2009-09-30 04:01:21.000000000 -0300 @@ -773,6 +773,7 @@ extern void dump_referenced_vars (FILE * extern void dump_variable (FILE *, tree); extern void debug_variable (tree); extern tree get_virtual_var (tree); +extern bool referenced_var_p (tree); extern bool add_referenced_var (tree); extern void remove_referenced_var (tree); extern void mark_symbols_for_renaming (gimple); @@ -889,7 +890,9 @@ bool name_registered_for_update_p (tree) bitmap ssa_names_to_replace (void); void release_ssa_name_after_update_ssa (tree); void compute_global_livein (bitmap, bitmap); +bool sym_marked_for_renaming (tree); void mark_sym_for_renaming (tree); +void clear_mark_for_renaming (tree); void mark_set_for_renaming (bitmap); tree get_current_def (tree); void set_current_def (tree, tree); --- gcc/tree-into-ssa.c.orig 2009-09-30 04:00:45.000000000 -0300 +++ gcc/tree-into-ssa.c 2009-09-30 04:01:21.000000000 -0300 @@ -2874,6 +2874,37 @@ mark_sym_for_renaming (tree sym) } } +/* Unregister symbol SYM to be renamed by update_ssa. SYM must be a + gimple register. */ + +void +clear_mark_for_renaming (tree sym) +{ + if (need_to_initialize_update_ssa_p) + return; + + gcc_assert (is_gimple_reg (sym)); + + bitmap_clear_bit (syms_to_rename, DECL_UID (sym)); + + if (bitmap_empty_p (syms_to_rename)) + BITMAP_FREE (syms_to_rename); +} + +/* Return true if a symbol is marked for renaming. This is an + exported interface for symbol_marked_for_renaming. */ + +bool +sym_marked_for_renaming (tree sym) +{ + if (need_to_initialize_update_ssa_p) + return false; + + if (!syms_to_rename) + return false; + + return symbol_marked_for_renaming (sym); +} /* Register all the symbols in SET to be renamed by update_ssa. */ --- gcc/tree-ssa-operands.c.orig 2009-09-30 04:00:45.000000000 -0300 +++ gcc/tree-ssa-operands.c 2009-09-30 04:01:21.000000000 -0300 @@ -2716,9 +2716,22 @@ pop_stmt_changes (gimple *stmt_p) mark_difference_for_renaming (stores, buf->stores); /* Mark all the naked GIMPLE register operands for renaming. */ - FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF|SSA_OP_USE) - if (DECL_P (op)) - mark_sym_for_renaming (op); + if (gimple_debug_bind_p (stmt)) + { + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF|SSA_OP_USE) + if (DECL_P (op) && !referenced_var_p (op)) + { + gimple_debug_bind_reset_value (stmt); + update_stmt (stmt); + break; + } + } + else + { + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF|SSA_OP_USE) + if (DECL_P (op)) + mark_sym_for_renaming (op); + } /* FIXME, need to add more finalizers here. Cleanup EH info, recompute invariants for address expressions, add --- gcc/testsuite/gcc.dg/debug/vta-1.c 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/gcc.dg/debug/vta-1.c 2009-09-30 04:01:21.000000000 -0300 @@ -0,0 +1,35 @@ +/* https://bugzilla.redhat.com/show_bug.cgi?id=521991#c5 + + Distilled from Linux XFS source code. foo, inlined into bar, ends + up with debug stmts referencing the addressable variable b. + Optimization made it non-addressable, and then completely optimized + away, before we got a chance to rename (and discard) the occurrence + in the debug stmt. When we did, we crashed, attempting to rename + an unreference variable. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +static inline int +foo (void *x, unsigned y) +{ + unsigned z = *(unsigned long *) x % y; + *(unsigned long *) x = *(unsigned long *) x / y; + return z; +} + +struct S +{ + unsigned t; +}; + +void +bar (struct S *x, int *y) +{ + int a = 0; + unsigned long b = x->t; + foo (&b, x->t); + for (;; a++) + if (b) + *y = 1; +}