aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2010-01-20 22:57:20 +0000
committerJakub Jelinek <jakub@gcc.gnu.org>2010-01-20 23:57:20 +0100
commit4a4d4c08ed9c1843d70c528024ca1cc36207bd63 (patch)
tree4088f82d6455c183fee2c4833a094934305ba26d /gcc
parent50e87e30cdd8439fd7c6382f5c3c96653054b363 (diff)
downloadgcc-4a4d4c08ed9c1843d70c528024ca1cc36207bd63.zip
gcc-4a4d4c08ed9c1843d70c528024ca1cc36207bd63.tar.gz
gcc-4a4d4c08ed9c1843d70c528024ca1cc36207bd63.tar.bz2
re PR debug/42782 (VTA missed location: parameter via stack)
PR debug/42782 * var-tracking.c: Include tree-flow.h. (mem_dies_at_call): New. (dataflow_set_preserve_mem_locs): Use it. (dataflow_set_remove_mem_locs): Likewise. (dump_var): Renamed from dump_variable. Adjust all callers. (dump_var_slot): Renamed from dump_variable_slot. Likewise. * Makefile.in (var-tracking.o): Adjust deps. * gcc.dg/guality/pr42782.c: New. From-SVN: r156092
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr42782.c24
-rw-r--r--gcc/var-tracking.c67
5 files changed, 88 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 346c795..b926d9e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2010-01-20 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/42782
+ * var-tracking.c: Include tree-flow.h.
+ (mem_dies_at_call): New.
+ (dataflow_set_preserve_mem_locs): Use it.
+ (dataflow_set_remove_mem_locs): Likewise.
+ (dump_var): Renamed from dump_variable. Adjust all callers.
+ (dump_var_slot): Renamed from dump_variable_slot. Likewise.
+ * Makefile.in (var-tracking.o): Adjust deps.
+
2010-01-20 Joern Rennecke <amylaar@spamcop.net>
* doc/tm.texi (TARGET_SCHED_SET_SCHED_FLAGS): Fix argument list.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7c08ea2..c388586 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3024,7 +3024,8 @@ regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
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) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
- $(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) cselib.h $(TARGET_H)
+ $(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
+ cselib.h $(TARGET_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
$(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a3bf6c9..faf0f05 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-01-20 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/42782
+ * gcc.dg/guality/pr42782.c: New.
+
2010-01-20 Jason Merrill <jason@redhat.com>
PR c++/41788
diff --git a/gcc/testsuite/gcc.dg/guality/pr42782.c b/gcc/testsuite/gcc.dg/guality/pr42782.c
new file mode 100644
index 0000000..6a88081
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr42782.c
@@ -0,0 +1,24 @@
+/* { dg-options "-g" } */
+
+#include "guality.h"
+
+void __attribute__ ((__noinline__))
+g (void)
+{
+ asm volatile ("");
+}
+
+int
+f (int a)
+{
+ g ();
+ GUALCHKVAL (a);
+ return a;
+}
+
+int
+main (int argc, char *argv[])
+{
+ f (argc + 2);
+ f (argc + 5);
+}
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index e5f95d9..d3eee44 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -106,6 +106,7 @@
#include "expr.h"
#include "timevar.h"
#include "tree-pass.h"
+#include "tree-flow.h"
#include "cselib.h"
#include "target.h"
@@ -446,8 +447,8 @@ static bool compute_bb_dataflow (basic_block);
static void vt_find_locations (void);
static void dump_attrs_list (attrs);
-static int dump_variable_slot (void **, void *);
-static void dump_variable (variable);
+static int dump_var_slot (void **, void *);
+static void dump_var (variable);
static void dump_vars (htab_t);
static void dump_dataflow_set (dataflow_set *);
static void dump_dataflow_sets (void);
@@ -3716,13 +3717,32 @@ find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
return where;
}
+/* Return TRUE if the value of MEM may vary across a call. */
+
+static bool
+mem_dies_at_call (rtx mem)
+{
+ tree expr = MEM_EXPR (mem);
+ tree decl;
+
+ if (!expr)
+ return true;
+
+ decl = get_base_address (expr);
+
+ if (!decl)
+ return true;
+
+ if (!DECL_P (decl))
+ return true;
+
+ return (may_be_aliased (decl)
+ || (!TREE_READONLY (decl) && is_global_var (decl)));
+}
+
/* Remove all MEMs from the location list of a hash table entry for a
one-part variable, except those whose MEM attributes map back to
- the variable itself, directly or within a VALUE.
-
- ??? We could also preserve MEMs that reference stack slots that are
- annotated as not addressable. This is arguably even more reliable
- than the current heuristic. */
+ the variable itself, directly or within a VALUE. */
static int
dataflow_set_preserve_mem_locs (void **slot, void *data)
@@ -3744,16 +3764,18 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
{
for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
{
- /* We want to remove a MEM that doesn't refer to DECL. */
+ /* We want to remove dying MEMs that doesn't refer to
+ DECL. */
if (GET_CODE (loc->loc) == MEM
&& (MEM_EXPR (loc->loc) != decl
- || MEM_OFFSET (loc->loc)))
+ || MEM_OFFSET (loc->loc))
+ && !mem_dies_at_call (loc->loc))
break;
- /* We want to move here a MEM that does refer to DECL. */
+ /* We want to move here MEMs that do refer to DECL. */
else if (GET_CODE (loc->loc) == VALUE
&& find_mem_expr_in_1pdv (decl, loc->loc,
shared_hash_htab (set->vars)))
- break;
+ break;
}
if (!loc)
@@ -3790,7 +3812,8 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
if (GET_CODE (loc->loc) != MEM
|| (MEM_EXPR (loc->loc) == decl
- && MEM_OFFSET (loc->loc) == 0))
+ && MEM_OFFSET (loc->loc) == 0)
+ || !mem_dies_at_call (loc->loc))
{
if (old_loc != loc->loc && emit_notes)
{
@@ -3838,7 +3861,8 @@ dataflow_set_remove_mem_locs (void **slot, void *data)
if (var->refcount > 1 || shared_hash_shared (set->vars))
{
for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
- if (GET_CODE (loc->loc) == MEM)
+ if (GET_CODE (loc->loc) == MEM
+ && mem_dies_at_call (loc->loc))
break;
if (!loc)
@@ -3852,7 +3876,8 @@ dataflow_set_remove_mem_locs (void **slot, void *data)
for (locp = &var->var_part[0].loc_chain, loc = *locp;
loc; loc = *locp)
{
- if (GET_CODE (loc->loc) != MEM)
+ if (GET_CODE (loc->loc) != MEM
+ || !mem_dies_at_call (loc->loc))
{
locp = &loc->next;
continue;
@@ -4034,7 +4059,7 @@ dataflow_set_different_1 (void **slot, void *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "dataflow difference found: removal of:\n");
- dump_variable (var1);
+ dump_var (var1);
}
/* Stop traversing the hash table. */
@@ -4048,8 +4073,8 @@ dataflow_set_different_1 (void **slot, void *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "dataflow difference found: old and new follow:\n");
- dump_variable (var1);
- dump_variable (var2);
+ dump_var (var1);
+ dump_var (var2);
}
/* Stop traversing the hash table. */
@@ -5703,11 +5728,11 @@ dump_attrs_list (attrs list)
/* Print the information about variable *SLOT to dump file. */
static int
-dump_variable_slot (void **slot, void *data ATTRIBUTE_UNUSED)
+dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
{
variable var = (variable) *slot;
- dump_variable (var);
+ dump_var (var);
/* Continue traversing the hash table. */
return 1;
@@ -5716,7 +5741,7 @@ dump_variable_slot (void **slot, void *data ATTRIBUTE_UNUSED)
/* Print the information about variable VAR to dump file. */
static void
-dump_variable (variable var)
+dump_var (variable var)
{
int i;
location_chain node;
@@ -5763,7 +5788,7 @@ dump_vars (htab_t vars)
if (htab_elements (vars) > 0)
{
fprintf (dump_file, "Variables:\n");
- htab_traverse (vars, dump_variable_slot, NULL);
+ htab_traverse (vars, dump_var_slot, NULL);
}
}