diff mbox

[RFC] Extend ipa-bitwise-cp with pointer alignment propagation

Message ID CAAgBjMkR_Am6Zn26zx+Ah7AHZjhKe8J+156VWxZG74C+QZFADw@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni Sept. 21, 2016, 4:44 p.m. UTC
Hi,
The attached patch tries to extend ipa bits propagation to handle
pointer alignment propagation.
The patch just disables ipa-cp-alignment pass, I suppose we want to
eventually remove it ?

Bootstrap+tested on x86_64-unknown-linux-gnu.
Cross-tested on arm*-*-*, aarch64*-*-*.
Does the patch look OK ?

Thanks,
Prathamesh

Comments

Richard Biener Sept. 22, 2016, 9:21 a.m. UTC | #1
On Wed, Sep 21, 2016 at 6:44 PM, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> Hi,
> The attached patch tries to extend ipa bits propagation to handle
> pointer alignment propagation.
> The patch just disables ipa-cp-alignment pass, I suppose we want to
> eventually remove it ?
>
> Bootstrap+tested on x86_64-unknown-linux-gnu.
> Cross-tested on arm*-*-*, aarch64*-*-*.
> Does the patch look OK ?

Just looking at the alignment extraction:

+      else

if (POINTER_TYPE_P (...))

+       {
+         unsigned tem = bits[i].mask.to_uhwi ();
+         unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi ();
+         unsigned align = tem & -tem;
+         unsigned misalign = bitpos & (align - 1);
...
+             if (old_known
+                 && old_align > align)
+               {
+                 if (dump_file)
+                   fprintf (dump_file, "But alignment was already %u.\n",
old_align);
+                 continue;
+               }

it would be nice to sanity check old misalign against misalign.
Basically

   gcc_assert (misalign & (old_align - 1) == old_misalign)

here (and in the old_align > align case the reverse).

+             set_ptr_info_alignment (pi, align, misalign);


-         ret |= propagate_alignment_accross_jump_function (cs, jump_func,
-
&dest_plats->alignment);
+//       ret |= propagate_alignment_accross_jump_function (cs, jump_func,
+//

this should of course be removed rather than commented.

Leaving the IPA parts to somebody else.

Richard.


> Thanks,
> Prathamesh
Richard Biener Sept. 22, 2016, 9:23 a.m. UTC | #2
On Thu, Sep 22, 2016 at 11:21 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Wed, Sep 21, 2016 at 6:44 PM, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> Hi,
>> The attached patch tries to extend ipa bits propagation to handle
>> pointer alignment propagation.
>> The patch just disables ipa-cp-alignment pass, I suppose we want to
>> eventually remove it ?
>>
>> Bootstrap+tested on x86_64-unknown-linux-gnu.
>> Cross-tested on arm*-*-*, aarch64*-*-*.
>> Does the patch look OK ?
>
> Just looking at the alignment extraction:
>
> +      else
>
> if (POINTER_TYPE_P (...))
>
> +       {
> +         unsigned tem = bits[i].mask.to_uhwi ();
> +         unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi ();
> +         unsigned align = tem & -tem;
> +         unsigned misalign = bitpos & (align - 1);
> ...
> +             if (old_known
> +                 && old_align > align)
> +               {
> +                 if (dump_file)
> +                   fprintf (dump_file, "But alignment was already %u.\n",
> old_align);
> +                 continue;
> +               }
>
> it would be nice to sanity check old misalign against misalign.
> Basically
>
>    gcc_assert (misalign & (old_align - 1) == old_misalign)
>
> here (and in the old_align > align case the reverse).

Just occured to me that this might trigger on invalid user code where correct
misalignment gets propagated in IPA but local bogus alignment doesn't
cause an issue because we're on a ! strict-align target.  So maybe instead
of asserting output a warning here ... or at least put sth in the dumpfile.

> +             set_ptr_info_alignment (pi, align, misalign);
>
>
> -         ret |= propagate_alignment_accross_jump_function (cs, jump_func,
> -
> &dest_plats->alignment);
> +//       ret |= propagate_alignment_accross_jump_function (cs, jump_func,
> +//
>
> this should of course be removed rather than commented.
>
> Leaving the IPA parts to somebody else.
>
> Richard.
>
>
>> Thanks,
>> Prathamesh
Jan Hubicka Sept. 22, 2016, 11:56 a.m. UTC | #3
> Hi,
> The attached patch tries to extend ipa bits propagation to handle
> pointer alignment propagation.
> The patch just disables ipa-cp-alignment pass, I suppose we want to
> eventually remove it ?

Yes, can you please verify that alignments it computes are monotonously
worse than those your new code computes and include the removal in the
next iteration of the patch?
> 
> Bootstrap+tested on x86_64-unknown-linux-gnu.
> Cross-tested on arm*-*-*, aarch64*-*-*.
> Does the patch look OK ?
> 
> Thanks,
> Prathamesh
> @@ -2258,8 +2271,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
>  							 &dest_plats->itself);
>  	  ret |= propagate_context_accross_jump_function (cs, jump_func, i,
>  							  &dest_plats->ctxlat);
> -	  ret |= propagate_alignment_accross_jump_function (cs, jump_func,
> -							 &dest_plats->alignment);
> +//	  ret |= propagate_alignment_accross_jump_function (cs, jump_func,
> +//							 &dest_plats->alignment);

obviously we do not want commented out ocde..

>  	  ret |= propagate_bits_accross_jump_function (cs, i, jump_func,
>  						       &dest_plats->bits_lattice);
>  	  ret |= propagate_aggs_accross_jump_function (cs, jump_func,
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index 1629781..5cee27b 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -1701,6 +1701,16 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
>  	      jfunc->bits.mask = 0;
>  	    }
>  	}
> +      else if (POINTER_TYPE_P (TREE_TYPE (arg)))
> +	{
> +	  unsigned HOST_WIDE_INT bitpos;
> +	  unsigned align;
> +
> +	  jfunc->bits.known = true;
> +	  get_pointer_alignment_1 (arg, &align, &bitpos);
> +	  jfunc->bits.mask = wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false).and_not (align / BITS_PER_UNIT - 1);

... and long lines :)

> +	  jfunc->bits.value = bitpos / BITS_PER_UNIT;
> +	}
>        else
>  	gcc_assert (!jfunc->bits.known);
>  
> @@ -5534,7 +5544,7 @@ ipcp_update_bits (struct cgraph_node *node)
>        next_parm = DECL_CHAIN (parm);
>  
>        if (!bits[i].known
> -	  || !INTEGRAL_TYPE_P (TREE_TYPE (parm))
> +	  || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm)))

I suppose eventually we may want to enable other types, too.
It does even make sense to propagate this on aggregates, but definitly on
vectors and complex numbers.  

Otherwise the patch seems fine to me (modulo Richard's comments)
Honza
diff mbox

Patch

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 5ff7bed..d251223 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1871,16 +1871,29 @@  propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
   unsigned precision = TYPE_PRECISION (parm_type);
   signop sgn = TYPE_SIGN (parm_type);
 
-  if (jfunc->type == IPA_JF_PASS_THROUGH)
+  if (jfunc->type == IPA_JF_PASS_THROUGH
+      || jfunc->type == IPA_JF_ANCESTOR)
     {
       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
-      enum tree_code code = ipa_get_jf_pass_through_operation (jfunc);
       tree operand = NULL_TREE;
+      enum tree_code code;
+      unsigned src_idx;
 
-      if (code != NOP_EXPR)
-	operand = ipa_get_jf_pass_through_operand (jfunc);
+      if (jfunc->type == IPA_JF_PASS_THROUGH)
+	{
+	  code = ipa_get_jf_pass_through_operation (jfunc);
+	  src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
+	  if (code != NOP_EXPR)
+	    operand = ipa_get_jf_pass_through_operand (jfunc);
+	}
+      else
+	{
+	  code = POINTER_PLUS_EXPR; 
+	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
+	  unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
+	  operand = build_int_cstu (size_type_node, offset);
+	}
 
-      int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
       struct ipcp_param_lattices *src_lats
 	= ipa_get_parm_lattices (caller_info, src_idx);
 
@@ -2258,8 +2271,8 @@  propagate_constants_accross_call (struct cgraph_edge *cs)
 							 &dest_plats->itself);
 	  ret |= propagate_context_accross_jump_function (cs, jump_func, i,
 							  &dest_plats->ctxlat);
-	  ret |= propagate_alignment_accross_jump_function (cs, jump_func,
-							 &dest_plats->alignment);
+//	  ret |= propagate_alignment_accross_jump_function (cs, jump_func,
+//							 &dest_plats->alignment);
 	  ret |= propagate_bits_accross_jump_function (cs, i, jump_func,
 						       &dest_plats->bits_lattice);
 	  ret |= propagate_aggs_accross_jump_function (cs, jump_func,
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 1629781..5cee27b 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1701,6 +1701,16 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      jfunc->bits.mask = 0;
 	    }
 	}
+      else if (POINTER_TYPE_P (TREE_TYPE (arg)))
+	{
+	  unsigned HOST_WIDE_INT bitpos;
+	  unsigned align;
+
+	  jfunc->bits.known = true;
+	  get_pointer_alignment_1 (arg, &align, &bitpos);
+	  jfunc->bits.mask = wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false).and_not (align / BITS_PER_UNIT - 1);
+	  jfunc->bits.value = bitpos / BITS_PER_UNIT;
+	}
       else
 	gcc_assert (!jfunc->bits.known);
 
@@ -5534,7 +5544,7 @@  ipcp_update_bits (struct cgraph_node *node)
       next_parm = DECL_CHAIN (parm);
 
       if (!bits[i].known
-	  || !INTEGRAL_TYPE_P (TREE_TYPE (parm))
+	  || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm)))
 	  || !is_gimple_reg (parm))
 	continue;       
 
@@ -5549,12 +5559,41 @@  ipcp_update_bits (struct cgraph_node *node)
 	  fprintf (dump_file, "\n");
 	}
 
-      unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
-      signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+      if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
+	{
+	  unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
+	  signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+
+	  wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
+				  | wide_int::from (bits[i].value, prec, sgn);
+	  set_nonzero_bits (ddef, nonzero_bits);
+	}
+      else
+	{
+	  unsigned tem = bits[i].mask.to_uhwi ();
+	  unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi (); 
+	  unsigned align = tem & -tem;
+	  unsigned misalign = bitpos & (align - 1);
 
-      wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
-			      | wide_int::from (bits[i].value, prec, sgn);
-      set_nonzero_bits (ddef, nonzero_bits);
+	  if (align > 1)
+	    {
+	      if (dump_file)
+		fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign); 
+
+	      unsigned old_align, old_misalign;
+	      struct ptr_info_def *pi = get_ptr_info (ddef);
+	      bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
+
+	      if (old_known
+		  && old_align > align)
+		{
+		  if (dump_file)
+		    fprintf (dump_file, "But alignment was already %u.\n", old_align);
+		  continue;
+		}
+	      set_ptr_info_alignment (pi, align, misalign); 
+	    }
+	}
     }
 }
 
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-1.c b/gcc/testsuite/gcc.dg/ipa/propalign-1.c
index f34552c..1491de8 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-1.c
@@ -27,5 +27,5 @@  bar (void)
 }
 
 
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
 /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-2.c b/gcc/testsuite/gcc.dg/ipa/propalign-2.c
index 67b149a..51799c7 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-2.c
@@ -53,5 +53,5 @@  bar2 (void)
   through (c.buf);
 }
 
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
 /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-3.c b/gcc/testsuite/gcc.dg/ipa/propalign-3.c
index d3bc2c4..4f5df4a 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-3.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-cp-alignment -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-ipa-bit-cp -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
 /* { dg-skip-if "No alignment restrictions" { { ! natural_alignment_32 } && { ! natural_alignment_64 } } } */
 
 #include <stdint.h>
@@ -53,5 +53,5 @@  bar2 (void)
   through (c.buf);
 }
 
-/* { dg-final { scan-ipa-dump-not "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump-not "align:" "cp" } } */
 /* { dg-final { scan-tree-dump "fail_the_test" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-4.c b/gcc/testsuite/gcc.dg/ipa/propalign-4.c
index b680813..bd32bf0 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-4.c
@@ -20,4 +20,4 @@  main()
   test (&aa[3]);
   return 0;
 }
-/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4"  "cp"  } } */
+/* { dg-final { scan-ipa-dump "align: 8, misalign: 4"  "cp"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-5.c b/gcc/testsuite/gcc.dg/ipa/propalign-5.c
index f2cf600..68e57da 100644
--- a/gcc/testsuite/gcc.dg/ipa/propalign-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/propalign-5.c
@@ -20,4 +20,4 @@  main()
   test (&bb);
   return 0;
 }
-/* { dg-final { scan-ipa-dump "Alignment 2"  "cp"  } } */
+/* { dg-final { scan-ipa-dump "align: 2"  "cp"  } } */