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