This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR42782] preserve nonaddressable MEMs at calls in VTA


When processing call insns, VTA drops all MEMs from location lists, save
for those that claim to *be* the variable, in their MEM_EXPRs.

This is a bit excessive.  MEMs referencing variables that are not
call-clobbered could also be retained.  This patch implements this.

I had to include tree-flow.h for the static inline definition of
is_call_clobbered() that it brings in from tree-flow-inline.h, and then
dump_variable in var-tracking conflicted with the declaration in the
header file, that refers to an incompatible definition in another file.
So I renamed the conflicting definition.

Regstrapping on x86_64-linux-gnu.  Ok if it succeeds?

for  gcc/ChangeLog
from  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.

for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/42782
	* gcc.dg/guality/pr42782.c: New.

Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2010-01-19 12:53:58.000000000 -0200
+++ gcc/var-tracking.c	2010-01-19 12:57:12.000000000 -0200
@@ -106,6 +106,7 @@
 #include "expr.h"
 #include "timevar.h"
 #include "tree-pass.h"
+#include "tree-flow.h"
 #include "cselib.h"
 #include "target.h"
 #include "toplev.h"
@@ -448,8 +449,8 @@ static bool compute_bb_dataflow (basic_b
 static bool 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);
@@ -3718,13 +3719,33 @@ find_mem_expr_in_1pdv (tree expr, rtx va
   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;
+
+  /* ??? Should we use callee-specific information, like
+     tree-ssa-alias's call_may_clobber_ref_p()?  */
+  return is_call_clobbered (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)
@@ -3746,16 +3767,18 @@ dataflow_set_preserve_mem_locs (void **s
 	{
 	  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)
@@ -3792,7 +3815,8 @@ dataflow_set_preserve_mem_locs (void **s
 
 	  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)
 		{
@@ -3840,7 +3864,8 @@ dataflow_set_remove_mem_locs (void **slo
       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)
@@ -3854,7 +3879,8 @@ dataflow_set_remove_mem_locs (void **slo
       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;
@@ -4036,7 +4062,7 @@ dataflow_set_different_1 (void **slot, v
       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.  */
@@ -4050,8 +4076,8 @@ dataflow_set_different_1 (void **slot, v
       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.  */
@@ -5733,11 +5759,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;
@@ -5746,7 +5772,7 @@ dump_variable_slot (void **slot, void *d
 /* Print the information about variable VAR to dump file.  */
 
 static void
-dump_variable (variable var)
+dump_var (variable var)
 {
   int i;
   location_chain node;
@@ -5793,7 +5819,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);
     }
 }
 
Index: gcc/testsuite/gcc.dg/guality/pr42782.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/guality/pr42782.c	2010-01-19 12:53:59.000000000 -0200
@@ -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: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in.orig	2010-01-19 12:54:14.000000000 -0200
+++ gcc/Makefile.in	2010-01-19 12:54:56.000000000 -0200
@@ -3024,7 +3024,7 @@ regstat.o : regstat.c $(CONFIG_H) $(SYST
 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) \
+   $(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
    cselib.h $(TARGET_H) $(TOPLEV_H) $(PARAMS_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) \
-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]