X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fipa-cp.c;h=0b2cd630ee2d735c8a1fe7d9625825f8ac7f688b;hb=44abeaaa70548f8f8807a81f07c7574db91a356f;hp=7380b2a34054225da1b43374bab96a9221366ea3;hpb=7d521283740c6dc4c4c609cb092d40c3dedefd8e;p=gcc.git diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 7380b2a3405..0b2cd630ee2 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1,5 +1,5 @@ /* Interprocedural constant propagation - Copyright (C) 2005-2016 Free Software Foundation, Inc. + Copyright (C) 2005-2017 Free Software Foundation, Inc. Contributed by Razya Ladelsky and Martin Jambor @@ -61,7 +61,7 @@ along with GCC; see the file COPYING3. If not see values: Pass through - the caller's formal parameter is passed as an actual - argument, plus an operation on it can be performed. + argument, plus an operation on it can be performed. Constant - a constant is passed as an actual argument. Unknown - neither of the above. @@ -193,7 +193,7 @@ public: }; /* Lattice describing potential values of a formal parameter of a function, or - a part of an aggreagate. TOP is represented by a lattice with zero values + a part of an aggregate. TOP is represented by a lattice with zero values and with contains_variable and bottom flags cleared. BOTTOM is represented by a lattice with the bottom flag set. In that case, values and contains_variable flag should be disregarded. */ @@ -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. @@ -298,8 +268,8 @@ public: bool top_p () { return m_lattice_val == IPA_BITS_UNDEFINED; } bool constant_p () { return m_lattice_val == IPA_BITS_CONSTANT; } bool set_to_bottom (); - bool set_to_constant (widest_int, widest_int); - + bool set_to_constant (widest_int, widest_int); + widest_int get_value () { return m_value; } widest_int get_mask () { return m_mask; } @@ -318,9 +288,9 @@ private: value is known to be constant. */ widest_int m_value, m_mask; - bool meet_with_1 (widest_int, widest_int, unsigned); + bool meet_with_1 (widest_int, widest_int, unsigned); void get_value_and_mask (tree, widest_int *, widest_int *); -}; +}; /* Lattice of value ranges. */ @@ -354,8 +324,6 @@ public: ipcp_lattice 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. */ @@ -456,7 +424,7 @@ static void print_ipcp_constant_value (FILE * f, tree v) { if (TREE_CODE (v) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL) + && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL) { fprintf (f, "& "); print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)), 0); @@ -534,19 +502,6 @@ ipcp_lattice::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); @@ -660,6 +614,12 @@ determine_versionability (struct cgraph_node *node, decloned constructors, inlining is always better anyway. */ else if (node->comdat_local_p ()) reason = "comdat-local function"; + else if (node->calls_comdat_local) + { + /* TODO: call is versionable if we make sure that all + callers are inside of a comdat group. */ + reason = "calls comdat-local function"; + } if (reason && dump_file && !node->alias && !node->thunk.thunk_p) fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n", @@ -730,18 +690,18 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) if (!opt_for_fn (node->decl, flag_ipa_cp_clone)) { if (dump_file) - fprintf (dump_file, "Not considering %s for cloning; " + fprintf (dump_file, "Not considering %s for cloning; " "-fipa-cp-clone disabled.\n", - node->name ()); + node->name ()); return false; } if (node->optimize_for_size_p ()) { if (dump_file) - fprintf (dump_file, "Not considering %s for cloning; " + fprintf (dump_file, "Not considering %s for cloning; " "optimizing it for size.\n", - node->name ()); + node->name ()); return false; } @@ -751,8 +711,8 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) if (inline_summaries->get (node)->self_size < stats.n_calls) { if (dump_file) - fprintf (dump_file, "Considering %s for cloning; code might shrink.\n", - node->name ()); + fprintf (dump_file, "Considering %s for cloning; code might shrink.\n", + node->name ()); return true; } @@ -768,7 +728,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) "usually called directly.\n", node->name ()); return true; - } + } } if (!stats.n_hot_calls) { @@ -922,38 +882,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 +950,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 @@ -1133,7 +985,7 @@ ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_ if (TREE_CODE (operand) == INTEGER_CST) { - *valuep = wi::to_widest (operand); + *valuep = wi::to_widest (operand); *maskp = 0; } else @@ -1153,8 +1005,8 @@ ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask, unsigned precision) { gcc_assert (constant_p ()); - - widest_int old_mask = m_mask; + + widest_int old_mask = m_mask; m_mask = (m_mask | mask) | (m_value ^ value); if (wi::sext (m_mask, precision) == -1) @@ -1177,7 +1029,7 @@ ipcp_bits_lattice::meet_with (widest_int value, widest_int mask, { if (wi::sext (mask, precision) == -1) return set_to_bottom (); - return set_to_constant (value, mask); + return set_to_constant (value, mask); } return meet_with_1 (value, mask, precision); @@ -1224,12 +1076,6 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision, return set_to_bottom (); } - else if (code == NOP_EXPR) - { - adjusted_value = other.m_value; - adjusted_mask = other.m_mask; - } - else return set_to_bottom (); @@ -1237,7 +1083,7 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision, { if (wi::sext (adjusted_mask, precision) == -1) return set_to_bottom (); - return set_to_constant (adjusted_value, adjusted_mask); + return set_to_constant (adjusted_value, adjusted_mask); } else return meet_with_1 (adjusted_value, adjusted_mask, precision); @@ -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; @@ -1326,7 +1171,7 @@ initialize_node_lattices (struct cgraph_node *node) disable = true; } - for (i = 0; i < ipa_get_param_count (info) ; i++) + for (i = 0; i < ipa_get_param_count (info); i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); plats->m_value_range.init (); @@ -1334,7 +1179,7 @@ initialize_node_lattices (struct cgraph_node *node) if (disable || variable) { - for (i = 0; i < ipa_get_param_count (info) ; i++) + for (i = 0; i < ipa_get_param_count (info); i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); if (disable) @@ -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 (); } @@ -1358,7 +1202,7 @@ initialize_node_lattices (struct cgraph_node *node) for (ie = node->indirect_calls; ie; ie = ie->next_callee) if (ie->indirect_info->polymorphic - && ie->indirect_info->param_index >= 0) + && ie->indirect_info->param_index >= 0) { gcc_checking_assert (ie->indirect_info->param_index >= 0); ipa_get_parm_lattices (info, @@ -1381,13 +1225,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) return NULL_TREE; if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) - == tcc_comparison) - restype = boolean_type_node; + == tcc_unary) + res = fold_unary (ipa_get_jf_pass_through_operation (jfunc), + TREE_TYPE (input), input); else - restype = TREE_TYPE (input); - res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype, - input, ipa_get_jf_pass_through_operand (jfunc)); - + { + if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) + == tcc_comparison) + restype = boolean_type_node; + else + restype = TREE_TYPE (input); + res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype, + input, ipa_get_jf_pass_through_operand (jfunc)); + } if (res && !is_gimple_ip_invariant (res)) return NULL_TREE; @@ -1665,7 +1515,7 @@ ipcp_lattice::add_value (valtype newval, cgraph_edge *cs, if (ipa_edge_within_scc (cs)) { ipcp_value_source *s; - for (s = val->sources; s ; s = s->next) + for (s = val->sources; s; s = s->next) if (s->cs == cs) break; if (s) @@ -1707,11 +1557,9 @@ ipcp_lattice::add_value (valtype newval, cgraph_edge *cs, is the index of the source parameter. */ static bool -propagate_vals_accross_pass_through (cgraph_edge *cs, - ipa_jump_func *jfunc, - ipcp_lattice *src_lat, - ipcp_lattice *dest_lat, - int src_idx) +propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc, + ipcp_lattice *src_lat, + ipcp_lattice *dest_lat, int src_idx) { ipcp_value *src_val; bool ret = false; @@ -1741,11 +1589,10 @@ propagate_vals_accross_pass_through (cgraph_edge *cs, is the index of the source parameter. */ static bool -propagate_vals_accross_ancestor (struct cgraph_edge *cs, - struct ipa_jump_func *jfunc, - ipcp_lattice *src_lat, - ipcp_lattice *dest_lat, - int src_idx) +propagate_vals_across_ancestor (struct cgraph_edge *cs, + struct ipa_jump_func *jfunc, + ipcp_lattice *src_lat, + ipcp_lattice *dest_lat, int src_idx) { ipcp_value *src_val; bool ret = false; @@ -1770,9 +1617,9 @@ propagate_vals_accross_ancestor (struct cgraph_edge *cs, edge CS and put the values into DEST_LAT. */ static bool -propagate_scalar_accross_jump_function (struct cgraph_edge *cs, - struct ipa_jump_func *jfunc, - ipcp_lattice *dest_lat) +propagate_scalar_across_jump_function (struct cgraph_edge *cs, + struct ipa_jump_func *jfunc, + ipcp_lattice *dest_lat) { if (dest_lat->bottom) return false; @@ -1806,11 +1653,11 @@ propagate_scalar_accross_jump_function (struct cgraph_edge *cs, return dest_lat->set_contains_variable (); if (jfunc->type == IPA_JF_PASS_THROUGH) - ret = propagate_vals_accross_pass_through (cs, jfunc, src_lat, - dest_lat, src_idx); + ret = propagate_vals_across_pass_through (cs, jfunc, src_lat, + dest_lat, src_idx); else - ret = propagate_vals_accross_ancestor (cs, jfunc, src_lat, dest_lat, - src_idx); + ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat, + src_idx); if (src_lat->contains_variable) ret |= dest_lat->set_contains_variable (); @@ -1827,7 +1674,7 @@ propagate_scalar_accross_jump_function (struct cgraph_edge *cs, edge CS and describes argument IDX and put the values into DEST_LAT. */ static bool -propagate_context_accross_jump_function (cgraph_edge *cs, +propagate_context_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, int idx, ipcp_lattice *dest_lat) { @@ -1910,65 +1757,13 @@ 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. */ bool -propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *jfunc, - ipcp_bits_lattice *dest_lattice) +propagate_bits_across_jump_function (cgraph_edge *cs, int idx, + ipa_jump_func *jfunc, + ipcp_bits_lattice *dest_lattice) { if (dest_lattice->bottom_p ()) return false; @@ -1993,16 +1788,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); @@ -2017,8 +1825,8 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j and we store it in jump function during analysis stage. */ if (src_lats->bits_lattice.bottom_p () - && jfunc->bits.known) - return dest_lattice->meet_with (jfunc->bits.value, jfunc->bits.mask, + && jfunc->bits) + return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask, precision); else return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn, @@ -2027,56 +1835,95 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j else if (jfunc->type == IPA_JF_ANCESTOR) return dest_lattice->set_to_bottom (); - - else if (jfunc->bits.known) - return dest_lattice->meet_with (jfunc->bits.value, jfunc->bits.mask, precision); - + else if (jfunc->bits) + return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask, + precision); else return dest_lattice->set_to_bottom (); } +/* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to + DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if + the result is a range or an anti-range. */ + +static bool +ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr, + enum tree_code operation, + tree dst_type, tree src_type) +{ + memset (dst_vr, 0, sizeof (*dst_vr)); + extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); + if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE) + return true; + else + return false; +} + /* Propagate value range across jump function JFUNC that is associated with - edge CS and update DEST_PLATS accordingly. */ + edge CS with param of callee of PARAM_TYPE and update DEST_PLATS + accordingly. */ static bool -propagate_vr_accross_jump_function (cgraph_edge *cs, - ipa_jump_func *jfunc, - struct ipcp_param_lattices *dest_plats) +propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, + struct ipcp_param_lattices *dest_plats, + tree param_type) { - struct ipcp_param_lattices *src_lats; ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; if (dest_lat->bottom_p ()) return false; + if (!param_type + || (!INTEGRAL_TYPE_P (param_type) + && !POINTER_TYPE_P (param_type))) + return dest_lat->set_to_bottom (); + if (jfunc->type == IPA_JF_PASS_THROUGH) { - struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - if (dest_lat->bottom_p ()) - return false; - int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); - src_lats = ipa_get_parm_lattices (caller_info, src_idx); + enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); - if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) - return dest_lat->meet_with (src_lats->m_value_range); + if (TREE_CODE_CLASS (operation) == tcc_unary) + { + struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); + int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); + tree operand_type = ipa_get_type (caller_info, src_idx); + struct ipcp_param_lattices *src_lats + = ipa_get_parm_lattices (caller_info, src_idx); + + if (src_lats->m_value_range.bottom_p ()) + return dest_lat->set_to_bottom (); + value_range vr; + if (ipa_vr_operation_and_type_effects (&vr, + &src_lats->m_value_range.m_vr, + operation, param_type, + operand_type)) + return dest_lat->meet_with (&vr); + } } else if (jfunc->type == IPA_JF_CONST) { tree val = ipa_get_jf_constant (jfunc); if (TREE_CODE (val) == INTEGER_CST) { + val = fold_convert (param_type, val); if (TREE_OVERFLOW_P (val)) val = drop_tree_overflow (val); - jfunc->vr_known = true; - jfunc->m_vr.type = VR_RANGE; - jfunc->m_vr.min = val; - jfunc->m_vr.max = val; - return dest_lat->meet_with (&jfunc->m_vr); + + value_range tmpvr; + memset (&tmpvr, 0, sizeof (tmpvr)); + tmpvr.type = VR_RANGE; + tmpvr.min = val; + tmpvr.max = val; + return dest_lat->meet_with (&tmpvr); } } - if (jfunc->vr_known) - return dest_lat->meet_with (&jfunc->m_vr); + value_range vr; + if (jfunc->m_vr + && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR, + param_type, + TREE_TYPE (jfunc->m_vr->min))) + return dest_lat->meet_with (&vr); else return dest_lat->set_to_bottom (); } @@ -2135,8 +1982,8 @@ merge_agg_lats_step (struct ipcp_param_lattices *dest_plats, if (**aglat && (**aglat)->offset == offset) { if ((**aglat)->size != val_size - || ((**aglat)->next - && (**aglat)->next->offset < offset + val_size)) + || ((**aglat)->next + && (**aglat)->next->offset < offset + val_size)) { set_agg_lats_to_bottom (dest_plats); return false; @@ -2259,9 +2106,9 @@ agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats, edge CS and put the values into DEST_LAT. */ static bool -propagate_aggs_accross_jump_function (struct cgraph_edge *cs, - struct ipa_jump_func *jfunc, - struct ipcp_param_lattices *dest_plats) +propagate_aggs_across_jump_function (struct cgraph_edge *cs, + struct ipa_jump_func *jfunc, + struct ipcp_param_lattices *dest_plats) { bool ret = false; @@ -2361,7 +2208,7 @@ call_passes_through_thunk_p (cgraph_edge *cs) caller. */ static bool -propagate_constants_accross_call (struct cgraph_edge *cs) +propagate_constants_across_call (struct cgraph_edge *cs) { struct ipa_node_params *callee_info; enum availability availability; @@ -2416,25 +2263,25 @@ propagate_constants_accross_call (struct cgraph_edge *cs) { struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i); struct ipcp_param_lattices *dest_plats; + tree param_type = ipa_get_type (callee_info, i); dest_plats = ipa_get_parm_lattices (callee_info, i); if (availability == AVAIL_INTERPOSABLE) ret |= set_all_contains_variable (dest_plats); else { - ret |= propagate_scalar_accross_jump_function (cs, jump_func, - &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, - dest_plats); + ret |= propagate_scalar_across_jump_function (cs, jump_func, + &dest_plats->itself); + ret |= propagate_context_across_jump_function (cs, jump_func, i, + &dest_plats->ctxlat); + ret + |= propagate_bits_across_jump_function (cs, i, jump_func, + &dest_plats->bits_lattice); + ret |= propagate_aggs_across_jump_function (cs, jump_func, + dest_plats); if (opt_for_fn (callee->decl, flag_ipa_vrp)) - ret |= propagate_vr_accross_jump_function (cs, - jump_func, dest_plats); + ret |= propagate_vr_across_jump_function (cs, jump_func, + dest_plats, param_type); else ret |= dest_plats->m_value_range.set_to_bottom (); } @@ -2510,8 +2357,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, else t = known_csts[param_index]; - if (t && - TREE_CODE (t) == ADDR_EXPR + if (t + && TREE_CODE (t) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL) return TREE_OPERAND (t, 0); else @@ -2547,11 +2394,10 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, if (!t && known_aggs.length () > (unsigned int) param_index && !ie->indirect_info->by_ref) { - struct ipa_agg_jump_function *agg; - agg = known_aggs[param_index]; - t = ipa_find_agg_cst_for_param (agg, known_csts[param_index], - ie->indirect_info->offset, - true); + struct ipa_agg_jump_function *agg; + agg = known_aggs[param_index]; + t = ipa_find_agg_cst_for_param (agg, known_csts[param_index], + ie->indirect_info->offset, true); } /* If we found the virtual table pointer, lookup the target. */ @@ -2577,9 +2423,9 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, return NULL; target = ipa_impossible_devirt_target (ie, target); } - *speculative = ie->indirect_info->vptr_changed; + *speculative = ie->indirect_info->vptr_changed; if (!*speculative) - return target; + return target; } } } @@ -2871,7 +2717,7 @@ gather_context_independent_values (struct ipa_node_params *info, if (removable_params_cost) *removable_params_cost = 0; - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); ipcp_lattice *lat = &plats->itself; @@ -2946,16 +2792,20 @@ static void perform_estimation_of_a_value (cgraph_node *node, vec known_csts, vec known_contexts, vec known_aggs_ptrs, - int base_time, int removable_params_cost, + sreal base_time, int removable_params_cost, int est_move_cost, ipcp_value_base *val) { - int time, size, time_benefit; + int size, time_benefit; + sreal time; inline_hints hints; estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts, known_aggs_ptrs, &size, &time, &hints); - time_benefit = base_time - time + base_time -= time; + if (base_time > 65535) + base_time = 65535; + time_benefit = base_time.to_int () + devirtualization_time_bonus (node, known_csts, known_contexts, known_aggs_ptrs) + hint_time_bonus (hints) @@ -2986,15 +2836,15 @@ estimate_local_effects (struct cgraph_node *node) vec known_aggs; vec known_aggs_ptrs; bool always_const; - int base_time = inline_summaries->get (node)->time; + sreal base_time = inline_summaries->get (node)->time.to_int (); int removable_params_cost; if (!count || !ipcp_versionable_function_p (node)) return; if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %i.\n", - node->name (), node->order, base_time); + fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %f.\n", + node->name (), node->order, base_time.to_double ()); always_const = gather_context_independent_values (info, &known_csts, &known_contexts, &known_aggs, @@ -3007,7 +2857,8 @@ estimate_local_effects (struct cgraph_node *node) { struct caller_statistics stats; inline_hints hints; - int time, size; + sreal time; + int size; init_caller_stats (&stats); node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, @@ -3021,7 +2872,7 @@ estimate_local_effects (struct cgraph_node *node) if (dump_file) fprintf (dump_file, " - context independent values, size: %i, " - "time_benefit: %i\n", size, base_time - time); + "time_benefit: %f\n", size, (base_time - time).to_double ()); if (size <= 0 || node->local.local) { @@ -3032,7 +2883,7 @@ estimate_local_effects (struct cgraph_node *node) fprintf (dump_file, " Decided to specialize for all " "known contexts, code not going to grow.\n"); } - else if (good_cloning_opportunity_p (node, base_time - time, + else if (good_cloning_opportunity_p (node, (base_time - time).to_int (), stats.freq_sum, stats.count_sum, size)) { @@ -3054,10 +2905,10 @@ estimate_local_effects (struct cgraph_node *node) else if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Not cloning for all contexts because " "!good_cloning_opportunity_p.\n"); - + } - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); ipcp_lattice *lat = &plats->itself; @@ -3126,7 +2977,7 @@ estimate_local_effects (struct cgraph_node *node) known_contexts[i] = ipa_polymorphic_call_context (); } - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); struct ipa_agg_jump_function *ajf; @@ -3162,7 +3013,7 @@ estimate_local_effects (struct cgraph_node *node) fprintf (dump_file, " - estimates for value "); print_ipcp_constant_value (dump_file, val->value); fprintf (dump_file, " for "); - ipa_dump_param (dump_file, info, i); + ipa_dump_param (dump_file, info, i); fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]: time_benefit: %i, size: %i\n", plats->aggs_by_ref ? "ref " : "", @@ -3175,7 +3026,7 @@ estimate_local_effects (struct cgraph_node *node) } } - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) vec_free (known_aggs[i].items); known_csts.release (); @@ -3248,7 +3099,7 @@ add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo) struct ipa_node_params *info = IPA_NODE_REF (node); int i, count = ipa_get_param_count (info); - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); ipcp_lattice *lat = &plats->itself; @@ -3310,7 +3161,7 @@ propagate_constants_topo (struct ipa_topo_info *topo) if (ipa_edge_within_scc (cs)) { IPA_NODE_REF (v)->node_within_scc = true; - if (propagate_constants_accross_call (cs)) + if (propagate_constants_across_call (cs)) push_node_to_stack (topo, cs->callee->function_symbol ()); } v = pop_node_from_stack (topo); @@ -3328,7 +3179,7 @@ propagate_constants_topo (struct ipa_topo_info *topo) add_all_node_vals_to_toposort (v, topo); for (cs = v->callees; cs; cs = cs->next_callee) if (!ipa_edge_within_scc (cs)) - propagate_constants_accross_call (cs); + propagate_constants_across_call (cs); } cycle_nodes.release (); } @@ -3395,27 +3246,10 @@ ipcp_propagate_stage (struct ipa_topo_info *topo) if (dump_file) fprintf (dump_file, "\n Propagating constants:\n\n"); - if (in_lto_p) - ipa_update_after_lto_read (); - - FOR_EACH_DEFINED_FUNCTION (node) { struct ipa_node_params *info = IPA_NODE_REF (node); - /* In LTO we do not have PARM_DECLs but we would still like to be able to - look at types of parameters. */ - if (in_lto_p) - { - tree t = TYPE_ARG_TYPES (TREE_TYPE (node->decl)); - for (int k = 0; k < ipa_get_param_count (info) && t; k++) - { - gcc_assert (t != void_list_node); - info->descriptors[k].decl_or_type = TREE_VALUE (t); - t = t ? TREE_CHAIN (t) : NULL; - } - } - determine_versionability (node, info); if (node->has_gimple_body_p ()) { @@ -3758,7 +3592,7 @@ get_replacement_map (struct ipa_node_params *info, tree value, int parm_num) { fprintf (dump_file, " replacing "); ipa_dump_param (dump_file, info, parm_num); - + fprintf (dump_file, " with const "); print_generic_expr (dump_file, value, 0); fprintf (dump_file, "\n"); @@ -3782,14 +3616,14 @@ dump_profile_updates (struct cgraph_node *orig_node, fprintf (dump_file, " setting count of the specialized node to " HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count); - for (cs = new_node->callees; cs ; cs = cs->next_callee) + for (cs = new_node->callees; cs; cs = cs->next_callee) fprintf (dump_file, " edge to %s has count " HOST_WIDE_INT_PRINT_DEC "\n", cs->callee->name (), (HOST_WIDE_INT) cs->count); fprintf (dump_file, " setting count of the original node to " HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count); - for (cs = orig_node->callees; cs ; cs = cs->next_callee) + for (cs = orig_node->callees; cs; cs = cs->next_callee) fprintf (dump_file, " edge to %s is left with " HOST_WIDE_INT_PRINT_DEC "\n", cs->callee->name (), (HOST_WIDE_INT) cs->count); @@ -3840,18 +3674,18 @@ update_profiling_info (struct cgraph_node *orig_node, remainder = orig_node_count - new_sum; orig_node->count = remainder; - for (cs = new_node->callees; cs ; cs = cs->next_callee) + for (cs = new_node->callees; cs; cs = cs->next_callee) if (cs->frequency) cs->count = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (new_sum, - orig_node_count)); + GCOV_COMPUTE_SCALE (new_sum, + orig_node_count)); else cs->count = 0; - for (cs = orig_node->callees; cs ; cs = cs->next_callee) + for (cs = orig_node->callees; cs; cs = cs->next_callee) cs->count = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (remainder, - orig_node_count)); + GCOV_COMPUTE_SCALE (remainder, + orig_node_count)); if (dump_file) dump_profile_updates (orig_node, new_node); @@ -3881,19 +3715,19 @@ update_specialized_profile (struct cgraph_node *new_node, new_node->count += redirected_sum; orig_node->count -= redirected_sum; - for (cs = new_node->callees; cs ; cs = cs->next_callee) + for (cs = new_node->callees; cs; cs = cs->next_callee) if (cs->frequency) cs->count += apply_probability (cs->count, - GCOV_COMPUTE_SCALE (redirected_sum, - new_node_count)); + GCOV_COMPUTE_SCALE (redirected_sum, + new_node_count)); else cs->count = 0; - for (cs = orig_node->callees; cs ; cs = cs->next_callee) + for (cs = orig_node->callees; cs; cs = cs->next_callee) { gcov_type dec = apply_probability (cs->count, - GCOV_COMPUTE_SCALE (redirected_sum, - orig_node_count)); + GCOV_COMPUTE_SCALE (redirected_sum, + orig_node_count)); if (dec < cs->count) cs->count -= dec; else @@ -3942,7 +3776,7 @@ create_specialized_node (struct cgraph_node *node, fprintf (dump_file, " cannot change function signature\n"); } - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { tree t = known_csts[i]; if (t) @@ -3960,7 +3794,7 @@ create_specialized_node (struct cgraph_node *node, args_to_skip, "constprop"); ipa_set_node_agg_value_chain (new_node, aggvals); for (av = aggvals; av; av = av->next) - new_node->maybe_create_reference (av->value, IPA_REF_ADDR, NULL); + new_node->maybe_create_reference (av->value, NULL); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3968,7 +3802,7 @@ create_specialized_node (struct cgraph_node *node, new_node->name (), new_node->order); if (known_contexts.exists ()) { - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) if (!known_contexts[i].useless_p ()) { fprintf (dump_file, " known ctx %i is ", i); @@ -4002,7 +3836,7 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node, struct ipa_node_params *info = IPA_NODE_REF (node); int i, count = ipa_get_param_count (info); - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct cgraph_edge *cs; tree newval = NULL_TREE; @@ -4017,15 +3851,15 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node, struct ipa_jump_func *jump_func; tree t; - if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) + if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) || (i == 0 && call_passes_through_thunk_p (cs)) || (!cs->callee->instrumentation_clone && cs->callee->function_symbol ()->instrumentation_clone)) - { - newval = NULL_TREE; - break; - } + { + newval = NULL_TREE; + break; + } jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func); if (!t @@ -4070,7 +3904,7 @@ find_more_contexts_for_caller_subset (cgraph_node *node, ipa_node_params *info = IPA_NODE_REF (node); int i, count = ipa_get_param_count (info); - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { cgraph_edge *cs; @@ -4187,7 +4021,7 @@ intersect_with_plats (struct ipcp_param_lattices *plats, } } -/* Copy agggregate replacement values of NODE (which is an IPA-CP clone) to the +/* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the vector result while subtracting OFFSET from the individual value offsets. */ static vec @@ -4404,7 +4238,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node, count = c; } - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) { struct cgraph_edge *cs; vec inter = vNULL; @@ -4449,7 +4283,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node, return res; } -/* Turn KNOWN_AGGS into a list of aggreate replacement values. */ +/* Turn KNOWN_AGGS into a list of aggregate replacement values. */ static struct ipa_agg_replacement_value * known_aggs_to_agg_replacement_list (vec known_aggs) @@ -4815,7 +4649,7 @@ decide_whether_version_node (struct cgraph_node *node) info->do_clone_for_all_contexts ? &known_aggs : NULL, NULL); - for (i = 0; i < count ;i++) + for (i = 0; i < count;i++) { struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); ipcp_lattice *lat = &plats->itself; @@ -4854,7 +4688,7 @@ decide_whether_version_node (struct cgraph_node *node) known_contexts); } - info = IPA_NODE_REF (node); + info = IPA_NODE_REF (node); } if (info->do_clone_for_all_contexts) @@ -4880,7 +4714,7 @@ decide_whether_version_node (struct cgraph_node *node) info = IPA_NODE_REF (node); info->do_clone_for_all_contexts = false; IPA_NODE_REF (clone)->is_all_contexts_clone = true; - for (i = 0; i < count ; i++) + for (i = 0; i < count; i++) vec_free (known_aggs[i].items); known_aggs.release (); ret = true; @@ -4923,7 +4757,7 @@ spread_undeadness (struct cgraph_node *node) static bool has_undead_caller_from_outside_scc_p (struct cgraph_node *node, - void *data ATTRIBUTE_UNUSED) + void *data ATTRIBUTE_UNUSED) { struct cgraph_edge *cs; @@ -4946,19 +4780,19 @@ static void identify_dead_nodes (struct cgraph_node *node) { struct cgraph_node *v; - for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) + for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) if (v->local.local && !v->call_for_symbol_thunks_and_aliases (has_undead_caller_from_outside_scc_p, NULL, true)) IPA_NODE_REF (v)->node_dead = 1; - for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) + for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) if (!IPA_NODE_REF (v)->node_dead) spread_undeadness (v); if (dump_file && (dump_flags & TDF_DETAILS)) { - for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) + for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) if (IPA_NODE_REF (v)->node_dead) fprintf (dump_file, " Marking node as dead: %s/%i.\n", v->name (), v->order); @@ -4985,7 +4819,7 @@ ipcp_decision_stage (struct ipa_topo_info *topo) { struct cgraph_node *v; iterate = false; - for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) + for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) if (v->has_gimple_body_p () && ipcp_versionable_function_p (v)) iterate |= decide_whether_version_node (v); @@ -4997,81 +4831,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. */ @@ -5109,42 +4868,40 @@ ipcp_store_bits_results (void) } } - if (!found_useful_result) - continue; + if (!found_useful_result) + continue; - ipcp_grow_transformations_if_necessary (); - ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); - vec_safe_reserve_exact (ts->bits, count); + ipcp_grow_transformations_if_necessary (); + ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); + vec_safe_reserve_exact (ts->bits, count); - for (unsigned i = 0; i < count; i++) - { - ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - ipa_bits bits_jfunc; + for (unsigned i = 0; i < count; i++) + { + ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); + ipa_bits *jfbits; - if (plats->bits_lattice.constant_p ()) - { - bits_jfunc.known = true; - bits_jfunc.value = plats->bits_lattice.get_value (); - bits_jfunc.mask = plats->bits_lattice.get_mask (); - } - else - bits_jfunc.known = false; + if (plats->bits_lattice.constant_p ()) + jfbits + = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (), + plats->bits_lattice.get_mask ()); + else + jfbits = NULL; - ts->bits->quick_push (bits_jfunc); - if (!dump_file || !bits_jfunc.known) - continue; - if (!dumped_sth) - { - fprintf (dump_file, "Propagated bits info for function %s/%i:\n", - node->name (), node->order); - dumped_sth = true; - } - fprintf (dump_file, " param %i: value = ", i); - print_hex (bits_jfunc.value, dump_file); - fprintf (dump_file, ", mask = "); - print_hex (bits_jfunc.mask, dump_file); - fprintf (dump_file, "\n"); - } + ts->bits->quick_push (jfbits); + if (!dump_file || !jfbits) + continue; + if (!dumped_sth) + { + fprintf (dump_file, "Propagated bits info for function %s/%i:\n", + node->name (), node->order); + dumped_sth = true; + } + fprintf (dump_file, " param %i: value = ", i); + print_hex (jfbits->value, dump_file); + fprintf (dump_file, ", mask = "); + print_hex (jfbits->mask, dump_file); + fprintf (dump_file, "\n"); + } } } @@ -5157,62 +4914,62 @@ ipcp_store_vr_results (void) cgraph_node *node; FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) - { - ipa_node_params *info = IPA_NODE_REF (node); - bool found_useful_result = false; + { + ipa_node_params *info = IPA_NODE_REF (node); + bool found_useful_result = false; - if (!opt_for_fn (node->decl, flag_ipa_vrp)) - { - if (dump_file) - fprintf (dump_file, "Not considering %s for VR discovery " - "and propagate; -fipa-ipa-vrp: disabled.\n", - node->name ()); - continue; - } + if (!opt_for_fn (node->decl, flag_ipa_vrp)) + { + if (dump_file) + fprintf (dump_file, "Not considering %s for VR discovery " + "and propagate; -fipa-ipa-vrp: disabled.\n", + node->name ()); + continue; + } - if (info->ipcp_orig_node) - info = IPA_NODE_REF (info->ipcp_orig_node); + 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->m_value_range.bottom_p () - && !plats->m_value_range.top_p ()) - { - found_useful_result = true; - break; - } - } - if (!found_useful_result) - continue; + 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->m_value_range.bottom_p () + && !plats->m_value_range.top_p ()) + { + 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->m_vr, count); + ipcp_grow_transformations_if_necessary (); + ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); + vec_safe_reserve_exact (ts->m_vr, count); - for (unsigned i = 0; i < count ; i++) - { - ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - ipa_vr vr; + for (unsigned i = 0; i < count; i++) + { + ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); + ipa_vr vr; - if (!plats->m_value_range.bottom_p () - && !plats->m_value_range.top_p ()) - { - vr.known = true; - vr.type = plats->m_value_range.m_vr.type; - vr.min = plats->m_value_range.m_vr.min; - vr.max = plats->m_value_range.m_vr.max; - } - else - { - vr.known = false; - vr.type = VR_VARYING; - vr.min = vr.max = wi::zero (INT_TYPE_SIZE); - } - ts->m_vr->quick_push (vr); - } - } + if (!plats->m_value_range.bottom_p () + && !plats->m_value_range.top_p ()) + { + vr.known = true; + vr.type = plats->m_value_range.m_vr.type; + vr.min = plats->m_value_range.m_vr.min; + vr.max = plats->m_value_range.m_vr.max; + } + else + { + vr.known = false; + vr.type = VR_VARYING; + vr.min = vr.max = wi::zero (INT_TYPE_SIZE); + } + ts->m_vr->quick_push (vr); + } + } } /* The IPCP driver. */ @@ -5227,16 +4984,16 @@ ipcp_driver (void) ipa_check_create_node_params (); ipa_check_create_edge_args (); grow_edge_clone_vectors (); - edge_duplication_hook_holder = - symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL); - edge_removal_hook_holder = - symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL); + edge_duplication_hook_holder + = symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL); + edge_removal_hook_holder + = symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL); if (dump_file) { fprintf (dump_file, "\nIPA structures before propagation:\n"); if (dump_flags & TDF_DETAILS) - ipa_print_all_params (dump_file); + ipa_print_all_params (dump_file); ipa_print_all_jump_functions (dump_file); } @@ -5246,8 +5003,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. */