[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.
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

Patch hide | download patch | download mbox

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"  } } */