PR debug/42782
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 22:57:20 +0000 (22:57 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2010 22:57:20 +0000 (22:57 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156092 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr42782.c [new file with mode: 0644]
gcc/var-tracking.c

index 346c795..b926d9e 100644 (file)
@@ -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.
index 7c08ea2..c388586 100644 (file)
@@ -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 \
index a3bf6c9..faf0f05 100644 (file)
@@ -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 (file)
index 0000000..6a88081
--- /dev/null
@@ -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);
+}
index e5f95d9..d3eee44 100644 (file)
 #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);
     }
 }