re PR debug/49888 (VTA: -O2 -g variable value changes, it does not change in the source)

gcc/ChangeLog:
PR debug/49888
* var-tracking.c: Include alias.h.
(overlapping_mems): New struct.
(drop_overlapping_mem_locs): New.
(clobber_overlapping_mems): New.
(var_mem_delete_and_set, var_mem_delete): Call it.
(val_bind): Likewise, but only if modified.
(compute_bb_dataflow, emit_notes_in_bb): Call it on MEMs.
* Makefile.in (var-tracking.o): Depend in $(ALIAS_H).
gcc/testsuite/ChangeLog:
PR debug/49888
* gcc.dg/guality/pr49888.c: New.

From-SVN: r188531
This commit is contained in:
Alexandre Oliva 2012-06-13 21:43:51 +00:00 committed by Alexandre Oliva
parent d05cae4a97
commit 8cda8ad3d0
5 changed files with 159 additions and 2 deletions

View file

@ -1,3 +1,15 @@
2012-06-13 Alexandre Oliva <aoliva@redhat.com>
PR debug/49888
* var-tracking.c: Include alias.h.
(overlapping_mems): New struct.
(drop_overlapping_mem_locs): New.
(clobber_overlapping_mems): New.
(var_mem_delete_and_set, var_mem_delete): Call it.
(val_bind): Likewise, but only if modified.
(compute_bb_dataflow, emit_notes_in_bb): Call it on MEMs.
* Makefile.in (var-tracking.o): Depend in $(ALIAS_H).
2012-06-13 Alexandre Oliva <aoliva@redhat.com>
PR debug/47624

View file

@ -3131,8 +3131,8 @@ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
$(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
$(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) pointer-set.h \
$(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H)
cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) \
pointer-set.h $(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H) $(ALIAS_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(REGS_H) $(EXPR_H) $(FUNCTION_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \

View file

@ -1,3 +1,8 @@
2012-06-13 Alexandre Oliva <aoliva@redhat.com>
PR debug/49888
* gcc.dg/guality/pr49888.c: New.
2012-06-13 Alexandre Oliva <aoliva@redhat.com>
* g++.dg/tree-ssa/ivopts-2.C: Adjust for coalescing.

View file

@ -0,0 +1,25 @@
/* PR debug/49888 */
/* { dg-do run } */
/* { dg-options "-g" } */
static int v;
static void __attribute__((noinline, noclone))
f (int *p)
{
int c = *p;
v = c;
*p = 1; /* { dg-final { gdb-test 12 "c" "0" } } */
/* c may very well be optimized out at this point, so we test !c,
which will evaluate to the expected value. We just want to make
sure it doesn't remain bound to *p as it did before, in which
case !c would evaluate to 0. */
v = 0; /* { dg-final { gdb-test 17 "!c" "1" } } */
}
int
main ()
{
int a = 0;
f (&a);
return 0;
}

View file

@ -115,6 +115,7 @@
#include "pointer-set.h"
#include "recog.h"
#include "tm_p.h"
#include "alias.h"
/* var-tracking.c assumes that tree code with the same value as VALUE rtx code
has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
@ -1954,6 +1955,111 @@ var_regno_delete (dataflow_set *set, int regno)
*reg = NULL;
}
/* Hold parameters for the hashtab traversal function
drop_overlapping_mem_locs, see below. */
struct overlapping_mems
{
dataflow_set *set;
rtx loc, addr;
};
/* Remove all MEMs that overlap with COMS->LOC from the location list
of a hash table entry for a value. COMS->ADDR must be a
canonicalized form of COMS->LOC's address, and COMS->LOC must be
canonicalized itself. */
static int
drop_overlapping_mem_locs (void **slot, void *data)
{
struct overlapping_mems *coms = (struct overlapping_mems *)data;
dataflow_set *set = coms->set;
rtx mloc = coms->loc, addr = coms->addr;
variable var = (variable) *slot;
if (var->onepart == ONEPART_VALUE)
{
location_chain loc, *locp;
bool changed = false;
rtx cur_loc;
gcc_assert (var->n_var_parts == 1);
if (shared_var_p (var, set->vars))
{
for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
if (GET_CODE (loc->loc) == MEM
&& canon_true_dependence (mloc, GET_MODE (mloc), addr,
loc->loc, NULL))
break;
if (!loc)
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
var = (variable)*slot;
gcc_assert (var->n_var_parts == 1);
}
if (VAR_LOC_1PAUX (var))
cur_loc = VAR_LOC_FROM (var);
else
cur_loc = var->var_part[0].cur_loc;
for (locp = &var->var_part[0].loc_chain, loc = *locp;
loc; loc = *locp)
{
if (GET_CODE (loc->loc) != MEM
|| !canon_true_dependence (mloc, GET_MODE (mloc), addr,
loc->loc, NULL))
{
locp = &loc->next;
continue;
}
*locp = loc->next;
/* If we have deleted the location which was last emitted
we have to emit new location so add the variable to set
of changed variables. */
if (cur_loc == loc->loc)
{
changed = true;
var->var_part[0].cur_loc = NULL;
if (VAR_LOC_1PAUX (var))
VAR_LOC_FROM (var) = NULL;
}
pool_free (loc_chain_pool, loc);
}
if (!var->var_part[0].loc_chain)
{
var->n_var_parts--;
changed = true;
}
if (changed)
variable_was_changed (var, set);
}
return 1;
}
/* Remove from SET all VALUE bindings to MEMs that overlap with LOC. */
static void
clobber_overlapping_mems (dataflow_set *set, rtx loc)
{
struct overlapping_mems coms;
coms.set = set;
coms.loc = canon_rtx (loc);
coms.addr = canon_rtx (get_addr (XEXP (loc, 0)));
set->traversed_vars = set->vars;
htab_traverse (shared_hash_htab (set->vars),
drop_overlapping_mem_locs, &coms);
set->traversed_vars = NULL;
}
/* Set the location of DV, OFFSET as the MEM LOC. */
static void
@ -1996,6 +2102,7 @@ var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
tree decl = MEM_EXPR (loc);
HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
clobber_overlapping_mems (set, loc);
decl = var_debug_decl (decl);
if (initialized == VAR_INIT_STATUS_UNKNOWN)
@ -2016,6 +2123,7 @@ var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
tree decl = MEM_EXPR (loc);
HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
clobber_overlapping_mems (set, loc);
decl = var_debug_decl (decl);
if (clobber)
clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
@ -2059,6 +2167,9 @@ val_bind (dataflow_set *set, rtx val, rtx loc, bool modified)
{
struct elt_loc_list *l = CSELIB_VAL_PTR (val)->locs;
if (modified)
clobber_overlapping_mems (set, loc);
if (l && GET_CODE (l->loc) == VALUE)
l = canonical_cselib_val (CSELIB_VAL_PTR (l->loc))->locs;
@ -6371,6 +6482,8 @@ compute_bb_dataflow (basic_block bb)
}
else if (REG_P (uloc))
var_regno_delete (out, REGNO (uloc));
else if (MEM_P (uloc))
clobber_overlapping_mems (out, uloc);
val_store (out, val, dstv, insn, true);
}
@ -8870,6 +8983,8 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
}
else if (REG_P (uloc))
var_regno_delete (set, REGNO (uloc));
else if (MEM_P (uloc))
clobber_overlapping_mems (set, uloc);
val_store (set, val, dstv, insn, true);