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

Message ID CAAgBjMkoQgODJAwqdrB37j96Vq6AQr_0QwW2uONX50eM6hLbMQ@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni Oct. 3, 2016, 7:07 p.m.
On 22 September 2016 at 17:26, Jan Hubicka <hubicka@ucw.cz> 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 ?

>

> 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)

Hi,
Sorry for late response, I was travelling.
I tried to verify the alignments are monotonously worse with the
attached patch (verify.diff),
which asserts that alignment lattice is not better than bits lattice
during each propagation
step in propagate_constants_accross_call().
Does that look OK ?

ipa-cp-alignment has better alignments than ipa-bit-cp in following cases:

a) ipa_get_type() returns NULL: ipa-bits-cp sets lattice to bottom if
ipa_get_type (param) returns NULL,
for instance in case of K&R function, while ipa-cp-alignment doesn't
look at param types,
and can propagate alignments.
The following assert:
if (bits_lattice.bottom_p ())
  gcc_assert (align_lattice.bottom_p())

triggered for 400.perlbench, 403.gcc, 456.hmmer and 481.wrf due to
ipa_get_type()
returning NULL. I am not really sure how to handle this case, since we
need to know parameter's
type during bits propagation for obtaining precision.

b) This happens for attached test-case (test.i),
which is a reduced (and slightly modified) test-case from 458.sjeng.
Bits propagation sets lattice to bottom, while alignment propagation
propagates <align 1, misalign 0>.

In bits_lattice::meet_with_1
m_mask = other_mask = 0x0fffffffffffffff0
m_value = 0x7
other_value = 0x8

In this case meet operation sets m_mask to:
(m_mask | mask) | (m_value ^ other_value) = 0x0fffffffffffffff0 |
(0xf) == 0x0ffffffffffffffff
and hence the bits lattice is set to bottom.
I suppose it doesn't matter for this case if bits propagation sets
lattice to bottom,
since propagating <align 1, misalign 0> isn't really useful ?

The attached patch (alignprop-4.diff) removes ipa-cp-alignment, and
checks for misalign against old_misalgin and prints message in the dump file
if they mismatch. Testing in progress.

Thanks,
Prathamesh
> Honza

diff --git a/gcc/common.opt b/gcc/common.opt
index 0e01577..601a347 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1565,10 +1565,6 @@ fipa-cp-clone
 Common Report Var(flag_ipa_cp_clone) Optimization
 Perform cloning to make Interprocedural constant propagation stronger.
 
-fipa-cp-alignment
-Common Report Var(flag_ipa_cp_alignment) Optimization
-Perform alignment discovery and propagation to make Interprocedural constant propagation stronger.
-
 fipa-bit-cp
 Common Report Var(flag_ipa_bit_cp) Optimization
 Perform interprocedural bitwise constant propagation.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6767462..1dfa2e0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -360,7 +360,7 @@ Objective-C and Objective-C++ Dialects}.
 -fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol
 -fif-conversion2 -findirect-inlining @gol
 -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol
--finline-small-functions -fipa-cp -fipa-cp-clone -fipa-cp-alignment -fipa-bit-cp @gol
+-finline-small-functions -fipa-cp -fipa-cp-clone -fipa-bit-cp @gol
 -fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-icf @gol
 -fira-algorithm=@var{algorithm} @gol
 -fira-region=@var{region} -fira-hoist-pressure @gol
@@ -6637,7 +6637,6 @@ also turns on the following optimization flags:
 -finline-small-functions @gol
 -findirect-inlining @gol
 -fipa-cp @gol
--fipa-cp-alignment @gol
 -fipa-bit-cp @gol
 -fipa-sra @gol
 -fipa-icf @gol
@@ -7639,14 +7638,6 @@ it may significantly increase code size
 (see @option{--param ipcp-unit-growth=@var{value}}).
 This flag is enabled by default at @option{-O3}.
 
-@item -fipa-cp-alignment
-@opindex -fipa-cp-alignment
-When enabled, this optimization propagates alignment of function
-parameters to support better vectorization and string operations.
-
-This flag is enabled by default at @option{-O2} and @option{-Os}.  It
-requires that @option{-fipa-cp} is enabled.
-
 @item -fipa-bit-cp
 @opindex -fipa-bit-cp
 When enabled, perform ipa bitwise constant propagation. This flag is
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 95a2a1e..88baf69 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -238,36 +238,6 @@ public:
   struct ipcp_agg_lattice *next;
 };
 
-/* Lattice of pointer alignment.  Unlike the previous types of lattices, this
-   one is only capable of holding one value.  */
-
-class ipcp_alignment_lattice
-{
-public:
-  /* If bottom and top are both false, these two fields hold values as given by
-     ptr_info_def and get_pointer_alignment_1.  */
-  unsigned align;
-  unsigned misalign;
-
-  inline bool bottom_p () const;
-  inline bool top_p () const;
-  inline bool set_to_bottom ();
-  bool meet_with (unsigned new_align, unsigned new_misalign);
-  bool meet_with (const ipcp_alignment_lattice &other, HOST_WIDE_INT offset);
-  void print (FILE * f);
-private:
-  /* If set, this lattice is bottom and all other fields should be
-     disregarded.  */
-  bool bottom;
-  /* If bottom and not_top are false, the lattice is TOP.  If not_top is true,
-     the known alignment is stored in the fields align and misalign.  The field
-     is negated so that memset to zero initializes the lattice to TOP
-     state.  */
-  bool not_top;
-
-  bool meet_with_1 (unsigned new_align, unsigned new_misalign);
-};
-
 /* Lattice of known bits, only capable of holding one value.
    Bitwise constant propagation propagates which bits of a
    value are constant.
@@ -354,8 +324,6 @@ public:
   ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
   /* Lattices describing aggregate parts.  */
   ipcp_agg_lattice *aggs;
-  /* Lattice describing known alignment.  */
-  ipcp_alignment_lattice alignment;
   /* Lattice describing known bits.  */
   ipcp_bits_lattice bits_lattice;
   /* Lattice describing value range.  */
@@ -534,19 +502,6 @@ ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
     fprintf (f, "\n");
 }
 
-/* Print alignment lattice to F.  */
-
-void
-ipcp_alignment_lattice::print (FILE * f)
-{
-  if (top_p ())
-    fprintf (f, "         Alignment unknown (TOP)\n");
-  else if (bottom_p ())
-    fprintf (f, "         Alignment unusable (BOTTOM)\n");
-  else
-    fprintf (f, "         Alignment %u, misalignment %u\n", align, misalign);
-}
-
 void
 ipcp_bits_lattice::print (FILE *f)
 {
@@ -595,7 +550,6 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
 	  plats->itself.print (f, dump_sources, dump_benefits);
 	  fprintf (f, "         ctxs: ");
 	  plats->ctxlat.print (f, dump_sources, dump_benefits);
-	  plats->alignment.print (f);
 	  plats->bits_lattice.print (f);
 	  fprintf (f, "         ");
 	  plats->m_value_range.print (f);
@@ -922,38 +876,6 @@ set_agg_lats_contain_variable (struct ipcp_param_lattices *plats)
   return ret;
 }
 
-/* Return true if alignment information in the lattice is yet unknown.  */
-
-bool
-ipcp_alignment_lattice::top_p () const
-{
-  return !bottom && !not_top;
-}
-
-/* Return true if alignment information in the lattice is known to be
-   unusable.  */
-
-bool
-ipcp_alignment_lattice::bottom_p () const
-{
-  return bottom;
-}
-
-/* Set alignment information in the lattice to bottom.  Return true if it
-   previously was in a different state.  */
-
-bool
-ipcp_alignment_lattice::set_to_bottom ()
-{
-  if (bottom_p ())
-    return false;
-  bottom = true;
-  return true;
-}
-
-/* Meet the current value of the lattice with described by OTHER
-   lattice.  */
-
 bool
 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
 {
@@ -1022,82 +944,6 @@ ipcp_vr_lattice::set_to_bottom ()
   return true;
 }
 
-/* Meet the current value of the lattice with alignment described by NEW_ALIGN
-   and NEW_MISALIGN, assuming that we know the current value is neither TOP nor
-   BOTTOM.  Return true if the value of lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with_1 (unsigned new_align, unsigned new_misalign)
-{
-  gcc_checking_assert (new_align != 0);
-  if (align == new_align && misalign == new_misalign)
-    return false;
-
-  bool changed = false;
-  if (align > new_align)
-    {
-      align = new_align;
-      misalign = misalign % new_align;
-      changed = true;
-    }
-  if (misalign != (new_misalign % align))
-    {
-      int diff = abs ((int) misalign - (int) (new_misalign % align));
-      align = least_bit_hwi (diff);
-      if (align)
-	misalign = misalign % align;
-      else
-	set_to_bottom ();
-      changed = true;
-    }
-  gcc_checking_assert (bottom_p () || align != 0);
-  return changed;
-}
-
-/* Meet the current value of the lattice with alignment described by NEW_ALIGN
-   and NEW_MISALIGN.  Return true if the value of lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with (unsigned new_align, unsigned new_misalign)
-{
-  gcc_assert (new_align != 0);
-  if (bottom_p ())
-    return false;
-  if (top_p ())
-    {
-      not_top = true;
-      align = new_align;
-      misalign = new_misalign;
-      return true;
-    }
-  return meet_with_1 (new_align, new_misalign);
-}
-
-/* Meet the current value of the lattice with OTHER, taking into account that
-   OFFSET has been added to the pointer value.  Return true if the value of
-   lattice has changed.  */
-
-bool
-ipcp_alignment_lattice::meet_with (const ipcp_alignment_lattice &other,
-				   HOST_WIDE_INT offset)
-{
-  if (other.bottom_p ())
-    return set_to_bottom ();
-  if (bottom_p () || other.top_p ())
-    return false;
-
-  unsigned adjusted_misalign = (other.misalign + offset) % other.align;
-  if (top_p ())
-    {
-      not_top = true;
-      align = other.align;
-      misalign = adjusted_misalign;
-      return true;
-    }
-
-  return meet_with_1 (other.align, adjusted_misalign);
-}
-
 /* Set lattice value to bottom, if it already isn't the case.  */
 
 bool
@@ -1253,7 +1099,6 @@ set_all_contains_variable (struct ipcp_param_lattices *plats)
   ret = plats->itself.set_contains_variable ();
   ret |= plats->ctxlat.set_contains_variable ();
   ret |= set_agg_lats_contain_variable (plats);
-  ret |= plats->alignment.set_to_bottom ();
   ret |= plats->bits_lattice.set_to_bottom ();
   ret |= plats->m_value_range.set_to_bottom ();
   return ret;
@@ -1342,7 +1187,6 @@ initialize_node_lattices (struct cgraph_node *node)
 	      plats->itself.set_to_bottom ();
 	      plats->ctxlat.set_to_bottom ();
 	      set_agg_lats_to_bottom (plats);
-	      plats->alignment.set_to_bottom ();
 	      plats->bits_lattice.set_to_bottom ();
 	      plats->m_value_range.set_to_bottom ();
 	    }
@@ -1910,59 +1754,6 @@ propagate_context_accross_jump_function (cgraph_edge *cs,
   return ret;
 }
 
-/* Propagate alignments across jump function JFUNC that is associated with
-   edge CS and update DEST_LAT accordingly.  */
-
-static bool
-propagate_alignment_accross_jump_function (cgraph_edge *cs,
-					   ipa_jump_func *jfunc,
-					   ipcp_alignment_lattice *dest_lat)
-{
-  if (dest_lat->bottom_p ())
-    return false;
-
-  if (jfunc->type == IPA_JF_PASS_THROUGH
-	   || jfunc->type == IPA_JF_ANCESTOR)
-    {
-      struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
-      HOST_WIDE_INT offset = 0;
-      int src_idx;
-
-      if (jfunc->type == IPA_JF_PASS_THROUGH)
-	{
-	  enum tree_code op = ipa_get_jf_pass_through_operation (jfunc);
-	  if (op != NOP_EXPR)
-	    {
-	      if (op != POINTER_PLUS_EXPR
-		  && op != PLUS_EXPR)
-		return dest_lat->set_to_bottom ();
-	      tree operand = ipa_get_jf_pass_through_operand (jfunc);
-	      if (!tree_fits_shwi_p (operand))
-		return dest_lat->set_to_bottom ();
-	      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;
-	}
-
-      struct ipcp_param_lattices *src_lats;
-      src_lats = ipa_get_parm_lattices (caller_info, src_idx);
-      return dest_lat->meet_with (src_lats->alignment, offset);
-    }
-  else
-    {
-      if (jfunc->alignment.known)
-	return dest_lat->meet_with (jfunc->alignment.align,
-				    jfunc->alignment.misalign);
-      else
-	return dest_lat->set_to_bottom ();
-    }
-}
-
 /* Propagate bits across jfunc that is associated with
    edge cs and update dest_lattice accordingly.  */
 
@@ -1993,16 +1784,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);
 
@@ -2426,8 +2230,6 @@ 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_bits_accross_jump_function (cs, i, jump_func,
 						       &dest_plats->bits_lattice);
 	  ret |= propagate_aggs_accross_jump_function (cs, jump_func,
@@ -4997,81 +4799,6 @@ ipcp_decision_stage (struct ipa_topo_info *topo)
     }
 }
 
-/* Look up all alignment information that we have discovered and copy it over
-   to the transformation summary.  */
-
-static void
-ipcp_store_alignment_results (void)
-{
-  cgraph_node *node;
-
-  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
-  {
-    ipa_node_params *info = IPA_NODE_REF (node);
-    bool dumped_sth = false;
-    bool found_useful_result = false;
-
-    if (!opt_for_fn (node->decl, flag_ipa_cp_alignment))
-      {
-	if (dump_file)
-	  fprintf (dump_file, "Not considering %s for alignment discovery "
-		   "and propagate; -fipa-cp-alignment: disabled.\n",
-		   node->name ());
-	continue;
-      }
-
-   if (info->ipcp_orig_node)
-      info = IPA_NODE_REF (info->ipcp_orig_node);
-
-   unsigned count = ipa_get_param_count (info);
-   for (unsigned i = 0; i < count ; i++)
-     {
-       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-       if (!plats->alignment.bottom_p ()
-	   && !plats->alignment.top_p ())
-	 {
-	   gcc_checking_assert (plats->alignment.align > 0);
-	   found_useful_result = true;
-	   break;
-	 }
-     }
-   if (!found_useful_result)
-     continue;
-
-   ipcp_grow_transformations_if_necessary ();
-   ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-   vec_safe_reserve_exact (ts->alignments, count);
-
-   for (unsigned i = 0; i < count ; i++)
-     {
-       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-       ipa_alignment al;
-
-       if (!plats->alignment.bottom_p ()
-	   && !plats->alignment.top_p ())
-	 {
-	   al.known = true;
-	   al.align = plats->alignment.align;
-	   al.misalign = plats->alignment.misalign;
-	 }
-       else
-	 al.known = false;
-
-       ts->alignments->quick_push (al);
-       if (!dump_file || !al.known)
-	 continue;
-       if (!dumped_sth)
-	 {
-	   fprintf (dump_file, "Propagated alignment info for function %s/%i:\n",
-		    node->name (), node->order);
-	   dumped_sth = true;
-	 }
-       fprintf (dump_file, "  param %i: align: %u, misalign: %u\n",
-		i, al.align, al.misalign);
-     }
-  }
-}
-
 /* Look up all the bits information that we have discovered and copy it over
    to the transformation summary.  */
 
@@ -5246,8 +4973,6 @@ ipcp_driver (void)
   ipcp_propagate_stage (&topo);
   /* Decide what constant propagation and cloning should be performed.  */
   ipcp_decision_stage (&topo);
-  /* Store results of alignment propagation. */
-  ipcp_store_alignment_results ();
   /* Store results of bits propagation.  */
   ipcp_store_bits_results ();
   /* Store results of value range propagation.  */
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index feecd23..5ed9bbf 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -294,15 +294,6 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 	  ctx->dump (dump_file);
 	}
 
-      if (jump_func->alignment.known)
-	{
-	  fprintf (f, "         Alignment: %u, misalignment: %u\n",
-		   jump_func->alignment.align,
-		   jump_func->alignment.misalign);
-	}
-      else
-	fprintf (f, "         Unknown alignment\n");
-
       if (jump_func->bits.known)
 	{
 	  fprintf (f, "         value: "); print_hex (jump_func->bits.value, f);
@@ -402,7 +393,6 @@ static void
 ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
 {
   jfunc->type = IPA_JF_UNKNOWN;
-  jfunc->alignment.known = false;
   jfunc->bits.known = false;
   jfunc->vr_known = false;
 }
@@ -1678,25 +1668,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    useful_context = true;
 	}
 
-      if (POINTER_TYPE_P (TREE_TYPE(arg)))
-	{
-	  unsigned HOST_WIDE_INT hwi_bitpos;
-	  unsigned align;
-
-	  get_pointer_alignment_1 (arg, &align, &hwi_bitpos);
-	  if (align > BITS_PER_UNIT
-	      && align % BITS_PER_UNIT == 0
-	      && hwi_bitpos % BITS_PER_UNIT == 0)
-	    {
-	      jfunc->alignment.known = true;
-	      jfunc->alignment.align = align / BITS_PER_UNIT;
-	      jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;
-	    }
-	  else
-	    gcc_assert (!jfunc->alignment.known);
-	  gcc_assert (!jfunc->vr_known);
-	}
-      else
+      if (!POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  wide_int min, max;
 	  value_range_type type;
@@ -1713,7 +1685,6 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    }
 	  else
 	    gcc_assert (!jfunc->vr_known);
-	  gcc_assert (!jfunc->alignment.known);
 	}
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
@@ -1733,6 +1704,17 @@ 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);
 
@@ -3745,18 +3727,9 @@ ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
     {
       ipcp_grow_transformations_if_necessary ();
       src_trans = ipcp_get_transformation_summary (src);
-      const vec<ipa_alignment, va_gc> *src_alignments = src_trans->alignments;
       const vec<ipa_vr, va_gc> *src_vr = src_trans->m_vr;
-      vec<ipa_alignment, va_gc> *&dst_alignments
-	= ipcp_get_transformation_summary (dst)->alignments;
       vec<ipa_vr, va_gc> *&dst_vr
 	= ipcp_get_transformation_summary (dst)->m_vr;
-      if (vec_safe_length (src_trans->alignments) > 0)
-	{
-	  vec_safe_reserve_exact (dst_alignments, src_alignments->length ());
-	  for (unsigned i = 0; i < src_alignments->length (); ++i)
-	    dst_alignments->quick_push ((*src_alignments)[i]);
-	}
       if (vec_safe_length (src_trans->m_vr) > 0)
 	{
 	  vec_safe_reserve_exact (dst_vr, src_vr->length ());
@@ -4688,15 +4661,6 @@ ipa_write_jump_function (struct output_block *ob,
     }
 
   bp = bitpack_create (ob->main_stream);
-  bp_pack_value (&bp, jump_func->alignment.known, 1);
-  streamer_write_bitpack (&bp);
-  if (jump_func->alignment.known)
-    {
-      streamer_write_uhwi (ob, jump_func->alignment.align);
-      streamer_write_uhwi (ob, jump_func->alignment.misalign);
-    }
-
-  bp = bitpack_create (ob->main_stream);
   bp_pack_value (&bp, jump_func->bits.known, 1);
   streamer_write_bitpack (&bp);
   if (jump_func->bits.known)
@@ -4780,17 +4744,6 @@ ipa_read_jump_function (struct lto_input_block *ib,
     }
 
   struct bitpack_d bp = streamer_read_bitpack (ib);
-  bool alignment_known = bp_unpack_value (&bp, 1);
-  if (alignment_known)
-    {
-      jump_func->alignment.known = true;
-      jump_func->alignment.align = streamer_read_uhwi (ib);
-      jump_func->alignment.misalign = streamer_read_uhwi (ib);
-    }
-  else
-    jump_func->alignment.known = false;
-
-  bp = streamer_read_bitpack (ib);
   bool bits_known = bp_unpack_value (&bp, 1);
   if (bits_known)
     {
@@ -5156,30 +5109,6 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
     }
 
   ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-  if (ts && vec_safe_length (ts->alignments) > 0)
-    {
-      count = ts->alignments->length ();
-
-      streamer_write_uhwi (ob, count);
-      for (unsigned i = 0; i < count; ++i)
-	{
-	  ipa_alignment *parm_al = &(*ts->alignments)[i];
-
-	  struct bitpack_d bp;
-	  bp = bitpack_create (ob->main_stream);
-	  bp_pack_value (&bp, parm_al->known, 1);
-	  streamer_write_bitpack (&bp);
-	  if (parm_al->known)
-	    {
-	      streamer_write_uhwi (ob, parm_al->align);
-	      streamer_write_hwi_in_range (ob->main_stream, 0, parm_al->align,
-					   parm_al->misalign);
-	    }
-	}
-    }
-  else
-    streamer_write_uhwi (ob, 0);
-
   if (ts && vec_safe_length (ts->m_vr) > 0)
     {
       count = ts->m_vr->length ();
@@ -5250,32 +5179,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
       aggvals = av;
     }
   ipa_set_node_agg_value_chain (node, aggvals);
-
-  count = streamer_read_uhwi (ib);
-  if (count > 0)
-    {
-      ipcp_grow_transformations_if_necessary ();
-
-      ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-      vec_safe_grow_cleared (ts->alignments, count);
-
-      for (i = 0; i < count; i++)
-	{
-	  ipa_alignment *parm_al;
-	  parm_al = &(*ts->alignments)[i];
-	  struct bitpack_d bp;
-	  bp = streamer_read_bitpack (ib);
-	  parm_al->known = bp_unpack_value (&bp, 1);
-	  if (parm_al->known)
-	    {
-	      parm_al->align = streamer_read_uhwi (ib);
-	      parm_al->misalign
-		= streamer_read_hwi_in_range (ib, "ipa-prop misalign",
-					      0, parm_al->align);
-	    }
-	}
-    }
-
+  
   count = streamer_read_uhwi (ib);
   if (count > 0)
     {
@@ -5569,58 +5473,6 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
   return NULL;
 }
 
-/* Update alignment of formal parameters as described in
-   ipcp_transformation_summary.  */
-
-static void
-ipcp_update_alignments (struct cgraph_node *node)
-{
-  tree fndecl = node->decl;
-  tree parm = DECL_ARGUMENTS (fndecl);
-  tree next_parm = parm;
-  ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
-  if (!ts || vec_safe_length (ts->alignments) == 0)
-    return;
-  const vec<ipa_alignment, va_gc> &alignments = *ts->alignments;
-  unsigned count = alignments.length ();
-
-  for (unsigned i = 0; i < count; ++i, parm = next_parm)
-    {
-      if (node->clone.combined_args_to_skip
-	  && bitmap_bit_p (node->clone.combined_args_to_skip, i))
-	continue;
-      gcc_checking_assert (parm);
-      next_parm = DECL_CHAIN (parm);
-
-      if (!alignments[i].known || !is_gimple_reg (parm))
-	continue;
-      tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
-      if (!ddef)
-	continue;
-
-      if (dump_file)
-	fprintf (dump_file, "  Adjusting alignment of param %u to %u, "
-		 "misalignment to %u\n", i, alignments[i].align,
-		 alignments[i].misalign);
-
-      struct ptr_info_def *pi = get_ptr_info (ddef);
-      gcc_checking_assert (pi);
-      unsigned old_align;
-      unsigned old_misalign;
-      bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
-
-      if (old_known
-	  && old_align >= alignments[i].align)
-	{
-	  if (dump_file)
-	    fprintf (dump_file, "    But the alignment was already %u.\n",
-		     old_align);
-	  continue;
-	}
-      set_ptr_info_alignment (pi, alignments[i].align, alignments[i].misalign);
-    }
-}
-
 /* Update bits info of formal parameters as described in
    ipcp_transformation_summary.  */
 
@@ -5647,7 +5499,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;       
 
@@ -5662,12 +5514,53 @@ 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);
+		      if (old_misalign & (align - 1) != misalign)
+			fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
+				 old_misalign, misalign);
+		    }
+		  continue;
+		}
+
+	      if (old_known
+		  && (misalign & (old_align - 1) != old_misalign)
+		  && dump_file)
+		fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n",
+			 old_misalign, misalign);
+
+	      set_ptr_info_alignment (pi, align, misalign); 
+	    }
+	}
     }
 }
 
@@ -5742,7 +5635,6 @@ ipcp_transform_function (struct cgraph_node *node)
     fprintf (dump_file, "Modification phase of node %s/%i\n",
 	     node->name (), node->order);
 
-  ipcp_update_alignments (node);
   ipcp_update_bits (node);
   ipcp_update_vr (node);
   aggval = ipa_get_agg_replacements_for_node (node);
@@ -5775,7 +5667,6 @@ ipcp_transform_function (struct cgraph_node *node)
   fbi.bb_infos.release ();
   free_dominance_info (CDI_DOMINATORS);
   (*ipcp_transformations)[node->uid].agg_values = NULL;
-  (*ipcp_transformations)[node->uid].alignments = NULL;
   descriptors.release ();
 
   if (!something_changed)
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index a123978..4eeae88 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -143,17 +143,6 @@ struct GTY(()) ipa_agg_jump_function
 
 typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
 
-/* Info about pointer alignments. */
-struct GTY(()) ipa_alignment
-{
-  /* The data fields below are valid only if known is true.  */
-  bool known;
-  /* See ptr_info_def and get_pointer_alignment_1 for description of these
-     two.  */
-  unsigned align;
-  unsigned misalign;
-};
-
 /* Information about zero/non-zero bits.  */
 struct GTY(()) ipa_bits
 {
@@ -186,9 +175,6 @@ struct GTY (()) ipa_jump_func
      description.  */
   struct ipa_agg_jump_function agg;
 
-  /* Information about alignment of pointers. */
-  struct ipa_alignment alignment;
-
   /* Information about zero/non-zero bits.  */
   struct ipa_bits bits;
 
@@ -531,8 +517,6 @@ struct GTY(()) ipcp_transformation_summary
 {
   /* Linked list of known aggregate values.  */
   ipa_agg_replacement_value *agg_values;
-  /* Alignment information for pointers.  */
-  vec<ipa_alignment, va_gc> *alignments;
   /* Known bits information.  */
   vec<ipa_bits, va_gc> *bits;
   /* Value range information.  */
diff --git a/gcc/opts.c b/gcc/opts.c
index 45f1f89c..90e6186 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -504,7 +504,6 @@ static const struct default_options default_options_table[] =
     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
-    { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
@@ -1423,9 +1422,6 @@ enable_fdo_optimizations (struct gcc_options *opts,
   if (!opts_set->x_flag_ipa_cp_clone
       && value && opts->x_flag_ipa_cp)
     opts->x_flag_ipa_cp_clone = value;
-  if (!opts_set->x_flag_ipa_cp_alignment
-      && value && opts->x_flag_ipa_cp)
-    opts->x_flag_ipa_cp_alignment = value;
   if (!opts_set->x_flag_ipa_bit_cp
       && value && opts->x_flag_ipa_cp)
     opts->x_flag_ipa_bit_cp = value;
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"  } } */

Patch hide | download patch | download mbox

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 77da489..fee530e 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1910,6 +1910,28 @@  propagate_context_accross_jump_function (cgraph_edge *cs,
   return ret;
 }
 
+static void
+verify_align_worse_p (ipcp_param_lattices *dest_plats)
+{
+  ipcp_alignment_lattice align_lattice = dest_plats->alignment;
+  ipcp_bits_lattice bits_lattice = dest_plats->bits_lattice;
+
+  if (bits_lattice.top_p ())
+    gcc_assert (align_lattice.top_p () || align_lattice.bottom_p ());
+
+  else if (bits_lattice.bottom_p ())
+    gcc_assert (align_lattice.bottom_p ());
+
+  else if ((!align_lattice.bottom_p () && !align_lattice.top_p ())
+      && bits_lattice.constant_p ())
+    {
+      bool align = align_lattice.align;
+      unsigned tem = bits_lattice.get_mask ().to_uhwi ();   
+      unsigned bits_align = tem & -tem;
+      gcc_assert (align <= bits_align);
+    }
+}
+
 /* Propagate alignments across jump function JFUNC that is associated with
    edge CS and update DEST_LAT accordingly.  */
 
@@ -2451,6 +2473,9 @@  propagate_constants_accross_call (struct cgraph_edge *cs)
 						       jump_func, dest_plats);
 	  else
 	    ret |= dest_plats->m_value_range.set_to_bottom ();
+
+	  if (flag_ipa_cp_alignment && flag_ipa_bit_cp)
+	    verify_align_worse_p (dest_plats);
 	}
     }
   for (; i < parms_count; i++)