[PATCH] Make IPA-CP propagate alignment information of pointers

Jan Hubicka hubicka@ucw.cz
Mon Dec 1 22:41:00 GMT 2014


> > 2014-11-19  Martin Jambor  <mjambor@suse.cz>
> > 
> > 	* ipa-prop.h (ipa_alignment): New type.
> > 	(ipa_jump_func): New field alignment.
> > 	(ipcp_transformation_summary) New type.
> > 	(ipcp_grow_transformations_if_necessary): Declare.
> > 	(ipa_node_agg_replacements): Removed.
> > 	(ipcp_transformations): Declare.
> > 	(ipcp_get_transformation_summary): New function.
> > 	(ipa_get_agg_replacements_for_node): Use it.
> > 	* ipa-cp.c (ipcp_param_lattices): New field alignment.
> > 	(print_all_lattices): Also print alignment.
> > 	(alignment_bottom_p): New function.
> > 	(set_alignment_to_bottom): Likewise.
> > 	(set_all_contains_variable): Also set alignment to bottom.
> > 	(initialize_node_lattices): Likewise.
> > 	(propagate_alignment_accross_jump_function): New function.
> > 	(propagate_constants_accross_call): Call it.
> > 	(ipcp_store_alignment_results): New function.
> > 	(ipcp_driver): Call it.
> > 	* ipa-prop.c (ipa_node_agg_replacements): Removed.
> > 	(ipcp_transformations): New.
> > 	(ipa_print_node_jump_functions_for_edge): Also print alignment.
> > 	(ipa_set_jf_unknown): New function.
> > 	(detect_type_change_from_memory_writes): Use ipa_set_jf_unknown.
> > 	(ipa_compute_jump_functions_for_edge): Also calculate alignment.
> > 	(update_jump_functions_after_inlining): Use ipa_set_jf_unknown.
> > 	(ipcp_grow_transformations_if_necessary): New function.
> > 	(ipa_set_node_agg_value_chain): Use ipcp_transformations.
> > 	(ipa_node_removal_hook): Likewise.
> > 	(ipa_node_duplication_hook): Also duplicate alignment results.
> > 	(ipa_write_jump_function): Also stream alignments.
> > 	(ipa_read_jump_function): Use ipa_set_jf_unknown, also stream
> > 	alignments.
> > 	(write_agg_replacement_chain): Renamed to
> > 	write_ipcp_transformation_info, also stream alignments.
> > 	(read_agg_replacement_chain): Renamed to
> > 	read_ipcp_transformation_info, also stream alignments.
> > 	(ipa_prop_write_all_agg_replacement): Renamed to
> > 	ipcp_write_transformation_summaries. Stream always.
> > 	(ipa_prop_read_all_agg_replacement): Renamed to
> > 	ipcp_read_transformation_summaries.
> > 	(ipcp_update_alignments): New function.
> > 	(ipcp_transform_function): Call it, free also alignments.

In longer term I think we should just propagate value range and known to be zero/nonzero
bits.  This is stronger and more universal than inventing propagation for subproblems
(like non-NULL would be useful).
I think it would be also good excuse to do (simplified) early VRP to populate the vlaue
ranges locally.  This seems to make quite some difference on C++.

But for 5.0 it seems like resonable thing to do.

Since ipa-prop itself is built as propaation engine for multiple types of values
(scalars, aggregates, contexts and now value ranges). I wonder if the code can not be
organized by type of propagated value and perhaps split into multiple file to make
it more readable.

I think the way we split polymorphic-call-context lattice operations into separate
file quite works but more of code separation would be nice.

Well, a bit like df.c infrastructure is done.
> > +  else 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;
> > +

We probably chould avoid new places that rely on tree_fits_shwi_p and use wide_int
instead.
> > +      if (POINTER_TYPE_P (TREE_TYPE(arg)))
> > +	{
> > +	  unsigned HOST_WIDE_INT hwi_bitpos;
> > +	  unsigned align;
> > +
> > +	  if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos)
> > +	      && align > BITS_PER_UNIT)

OK, so here we get the nonzero/zero bits propagation from CCP used, right?

> > +  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_uhwi (ob, parm_al->misalign);

What about using streamer_write_hwi_in_range for misalign (as it is in range 0...align)
to get tiny bit of extra sanity check & code size saving?
We probably also get sane range for ->align. 

Honza



More information about the Gcc-patches mailing list