On Oct  3, 2012, Jakub Jelinek <ja...@redhat.com> wrote:

> basically there is a non-addressable parameter in stack slot, and
> vt_canon_true_dep -> canon_true_dependence thinks an argument push
> insn might alias with it, because it doesn't have a MEM_EXPR and
> ao_ref_from_mem fails.

I have a pending (still unreviewed) patch that might address :-), so to
speak, this problem.

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

	PR debug/53671
	PR debug/49888
	* var-tracking.c (attrs_list_by_loc_eq): New.
	(track_stack_pointer): New.
	(dataflow_set_merge): Use it.
	(vt_initialize): Record the initial stack pointer in the
	dataflow set.

Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2012-06-26 17:33:12.991323578 -0300
+++ gcc/var-tracking.c	2012-06-26 17:51:55.316453808 -0300
@@ -1462,6 +1462,17 @@ attrs_list_member (attrs list, decl_or_v
   return NULL;
 }
 
+/* Return the entry whose LOC field equals LOC.  */
+
+static attrs
+attrs_list_by_loc_eq (attrs list, rtx loc)
+{
+  for (; list; list = list->next)
+    if (list->loc == loc)
+      return list;
+  return NULL;
+}
+
 /* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */
 
 static void
@@ -4028,6 +4039,86 @@ variable_merge_over_src (variable s2var,
   return 1;
 }
 
+/* Add to DST any needed binding for the canonicalization of the stack
+   pointer to yield the same expression as in SRC1 and SRC2, if they
+   both yield the same expression.
+
+   Return TRUE iff we found an equivalence.
+
+   ??? The return value, that was useful during testing, ended up
+   unused, but this single-use static function will be inlined, and
+   then the return value computation will be optimized out, so I'm
+   leaving it in.
+
+   ??? We use this kludge to avoid accidental aliasing between
+   incoming arguments and register-saving or outgoing-args pushes.  We
+   shouldn't have to add explicit stack pointer tracking for that:
+   intersect_loc_chains ought to be able to take information from the
+   static cselib table and recognize additional equivalences, but we
+   don't have a sufficiently efficient algorithm to do that yet.  */
+
+static bool
+track_stack_pointer (dataflow_set *dst, dataflow_set *src1, dataflow_set *src2)
+{
+  attrs dattr, s1attr, s2attr;
+  rtx daddr, s1addr, s2addr;
+  decl_or_value dv;
+
+  for (dattr = dst->regs[STACK_POINTER_REGNUM];
+       (dattr = attrs_list_by_loc_eq (dattr, stack_pointer_rtx))
+	 && (dattr->offset || !dv_is_value_p (dattr->dv));
+       dattr = dattr->next)
+    ;
+
+  for (s1attr = src1->regs[STACK_POINTER_REGNUM];
+       (s1attr = attrs_list_by_loc_eq (s1attr, stack_pointer_rtx))
+	 && (s1attr->offset || !dv_is_value_p (s1attr->dv));
+       s1attr = s1attr->next)
+    ;
+  if (!s1attr)
+    return false;
+
+  for (s2attr = src2->regs[STACK_POINTER_REGNUM];
+       (s2attr = attrs_list_by_loc_eq (s2attr, stack_pointer_rtx))
+	 && (s2attr->offset || !dv_is_value_p (s2attr->dv));
+       s2attr = s2attr->next)
+    ;
+  if (!s2attr)
+    return false;
+
+  if (dattr)
+    daddr = vt_canonicalize_addr (dst, dv_as_value (dattr->dv));
+  else
+    daddr = NULL;
+  s1addr = vt_canonicalize_addr (src1, dv_as_value (s1attr->dv));
+  s2addr = vt_canonicalize_addr (src2, dv_as_value (s2attr->dv));
+
+  if (!rtx_equal_p (s1addr, s2addr))
+    return false;
+
+  if (daddr && rtx_equal_p (daddr, s1addr))
+    return true;
+
+  dst_can_be_shared = false;
+  if (daddr)
+    dv = dattr->dv;
+  else if (vt_get_canonicalize_base (s1addr)
+	   != (cfa_base_rtx ? cfa_base_rtx : arg_pointer_rtx))
+    return false;
+  else
+    {
+      cselib_val *val = cselib_lookup (s1addr, GET_MODE (s1addr), 1, VOIDmode);
+      cselib_preserve_value (val);
+      dv = dv_from_value (val->val_rtx);
+    }
+
+  var_reg_decl_set (dst, stack_pointer_rtx,
+		    VAR_INIT_STATUS_INITIALIZED,
+		    dv, 0, NULL_RTX, INSERT);
+
+  return true;
+}
+
 /* Combine dataflow set information from SRC2 into DST, using PDST
    to carry over information across passes.  */
 
@@ -4066,6 +4157,8 @@ dataflow_set_merge (dataflow_set *dst, d
   FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.cur->vars), var, variable, hi)
     variable_merge_over_cur (var, &dsm);
 
+  track_stack_pointer (dst, src1, src2);
+
   if (dsm.src_onepart_cnt)
     dst_can_be_shared = false;
 
@@ -9682,6 +9775,18 @@ vt_initialize (void)
 	  expr = plus_constant (GET_MODE (reg), reg, ofst);
 	  cselib_add_permanent_equiv (val, expr, get_insns ());
 	}
+
+      /* VAL below will generally be the one set within the
+	 conditional block, but if OFST happens to be zero, we'll be
+	 happy to use the one corresponding to REG.
+
+	 ??? We shouldn't need this any more once dataflow merges
+	 start using equivalences from the cselib table in addition to
+	 those in dataflow sets.  */
+      var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out,
+			stack_pointer_rtx, VAR_INIT_STATUS_INITIALIZED,
+			dv_from_value (val->val_rtx), 0, NULL_RTX,
+			INSERT);
     }
 
   /* In order to factor out the adjustments made to the stack pointer or to
-- 
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

Reply via email to