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]

Re: Fix alignment propagation


> On Fri, Feb 20, 2015 at 12:39:29AM +0100, Jan Hubicka wrote:
> > Hi,
> > this patch fixes alignment propagation that causes wrong code on solex and firefox.
> > Patch is by Martin, I just added the obvous MINUS_EXPR fix (the offset would be wrong,
> > but I see no reason for MINUX_ExPR appearing there with constant parameter), went
> > ahead and commited the fix.
> > 
> > Tested on x86_64-linux.
> 
> Two nits:
> 
> > Index: ChangeLog
> > ===================================================================
> > --- ChangeLog	(revision 220825)
> > +++ ChangeLog	(working copy)
> > @@ -1,3 +1,10 @@
> > +2015-02-19  Martin Jambor  <mjmabor@suse.cz>
> 
> Typo in the e-mail address.
> 
> 
> Two ;'s at the end of the line.

Oops, looks like celebrations of lunar new year was bit too devastating.
This is followup patch that also fixes ;; issue.
It makes the alignment propagation to do proper lattice operations instead
of requiring perfect match and dropping everything to bottom otherwise.
Martin, does it look OK?

	* ipa-cp.c (ipcp_verify_propagated_values): Verify that there
	are no bottoms in alignment.
	(decrease_alignment, increase_alignment): New functions.
	(propagate_alignment_accross_jump_function): Use proper lattice
	operations
	* ipa-cp-1.c: New testcase.
	* ipa-cp-2.c: New testcase.
Index: ipa-cp.c
===================================================================
--- ipa-cp.c	(revision 220826)
+++ ipa-cp.c	(working copy)
@@ -1041,10 +1041,14 @@ ipcp_verify_propagated_values (void)
       for (i = 0; i < count; i++)
 	{
 	  ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
+	  struct ipcp_param_lattices *plats;
+	  plats = ipa_get_parm_lattices (info, i);
 
-	  if (!lat->bottom
-	      && !lat->contains_variable
-	      && lat->values_count == 0)
+	  if ((!lat->bottom
+	       && !lat->contains_variable
+	       && lat->values_count == 0)
+	      || (!plats->alignment.known
+		  && opt_for_fn (node->decl, flag_ipa_cp_alignment)))
 	    {
 	      if (dump_file)
 		{
@@ -1409,6 +1413,60 @@ propagate_context_accross_jump_function
   return ret;
 }
 
+/* Decrease alignment info DEST to be at most CUR.  */
+
+static bool
+decrease_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+  bool changed = false;
+
+  if (!cur.known)
+    return false;
+  if (!dest->known)
+    {
+      *dest = cur;
+      return true;
+    }
+  if (dest->align == cur.align
+      && dest->misalign == cur.misalign)
+    return false;
+
+  if (dest->align > cur.align)
+    {
+      dest->align = cur.align;
+      if (cur.align)
+	dest->misalign
+	  = dest->misalign % cur.align;
+      changed = true;
+    }
+  if (dest->align && (dest->misalign != (cur.misalign % dest->align)))
+    {
+      int diff = abs (dest->misalign
+		      - (cur.misalign % dest->align));
+      dest->align = MIN (dest->align, (unsigned)diff & - diff);
+      if (dest->align)
+	dest->misalign
+	  = dest->misalign % dest->align;
+      changed = true;
+    }
+  return changed;
+}
+
+/* Increase alignment info DEST to be at least CUR.  */
+
+static bool
+increase_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+  if (!dest->known)
+    return false;
+  if (!cur.known || dest->align < cur.align)
+    {
+      *dest = cur;
+      return true;
+    }
+  return false;
+}
+
 /* Propagate alignments across jump function JFUNC that is associated with
    edge CS and update DEST_LAT accordingly.  */
 
@@ -1420,17 +1478,25 @@ propagate_alignment_accross_jump_functio
   if (alignment_bottom_p (dest_lat))
     return false;
 
-  ipa_alignment cur;
-  cur.known = false;
-  if (jfunc->alignment.known)
-    cur = jfunc->alignment;
-  else if (jfunc->type == IPA_JF_PASS_THROUGH
-	   || jfunc->type == IPA_JF_ANCESTOR)
+  ipa_alignment cur = jfunc->alignment;
+
+  /* For some reason UNKNOWN jump function gets alignment to be TOP
+     instead of BOTTOM.  */
+  if (!cur.known)
+    {
+      cur.known = true;
+      cur.align = 0;
+    }
+
+  if (jfunc->type == IPA_JF_PASS_THROUGH
+      || jfunc->type == IPA_JF_ANCESTOR)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
       struct ipcp_param_lattices *src_lats;
       HOST_WIDE_INT offset = 0;
       int src_idx;
+      ipa_alignment incomming_cur;
+      bool ok = true;
 
       if (jfunc->type == IPA_JF_PASS_THROUGH)
 	{
@@ -1439,44 +1505,34 @@ propagate_alignment_accross_jump_functio
 	    {
 	      if (op != POINTER_PLUS_EXPR
 		  && op != PLUS_EXPR)
-		goto prop_fail;
+		ok = false;
 	      tree operand = ipa_get_jf_pass_through_operand (jfunc);
 	      if (!tree_fits_shwi_p (operand))
-		goto prop_fail;
-	      offset = tree_to_shwi (operand);
+		ok = false;
+	      else
+	        offset = tree_to_shwi (operand);
 	    }
 	  src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
 	}
       else
 	{
 	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
-	  offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;;
+	  offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
 	}
 
-      src_lats = ipa_get_parm_lattices (caller_info, src_idx);
-      if (!src_lats->alignment.known
-	  || alignment_bottom_p (src_lats))
-	goto prop_fail;
-
-      cur = src_lats->alignment;
-      cur.misalign = (cur.misalign + offset) % cur.align;
-    }
-
-  if (cur.known)
-    {
-      if (!dest_lat->alignment.known)
+      if (ok)
 	{
-	  dest_lat->alignment = cur;
-	  return true;
+	  src_lats = ipa_get_parm_lattices (caller_info, src_idx);
+
+	  incomming_cur = src_lats->alignment;
+	  if (incomming_cur.known && incomming_cur.align)
+	    incomming_cur.misalign = (incomming_cur.misalign + offset)
+				     % incomming_cur.align;
+	  increase_alignment (&cur, incomming_cur);
 	}
-      else if (dest_lat->alignment.align == cur.align
-	       && dest_lat->alignment.misalign == cur.misalign)
-	return false;
     }
 
- prop_fail:
-  set_alignment_to_bottom (dest_lat);
-  return true;
+  return decrease_alignment (&dest_lat->alignment, cur);
 }
 
 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
Index: testsuite/gcc.dg/ipa/ipa-cp-2.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-2.c	(revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-2.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp"  } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+  __builtin_memset (a,0,n);
+}
+
+static __attribute__ ((aligned(16))) int aa[10];
+
+int
+main()
+{
+  test (&aa[1]);
+  test (&aa[3]);
+  return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4"  "cp"  } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
Index: testsuite/gcc.dg/ipa/ipa-cp-1.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-1.c	(revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-1.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp"  } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+  __builtin_memset (a,0,n);
+}
+
+int
+main()
+{
+  int aa;
+  short bb;
+  test (&aa);
+  test (&bb);
+  return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 2"  "cp"  } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */


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