> > 2014-11-19  Martin Jambor  <mjam...@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

Reply via email to