diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 22 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 78 | ||||
-rw-r--r-- | gcc/ipa-prop.h | 15 |
4 files changed, 87 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5fcf03c..65f8bce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-09-23 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.h (jump_func_type): Updated comments. + (ipa_known_type_data): New type. + (ipa_jump_func): Use it to describe known type jump functions. + * ipa-prop.c (ipa_print_node_jump_functions_for_edge): Updated to + reflect the new known type jump function contents. + (compute_known_type_jump_func): Likewise. + (combine_known_type_and_ancestor_jfs): Likewise. + (try_make_edge_direct_virtual_call): Likewise. + (ipa_write_jump_function): Likewise. + (ipa_read_jump_function): Likewise. + * ipa-cp.c (ipa_value_from_known_type_jfunc): New function. + (ipa_value_from_jfunc): Use ipa_value_from_known_type_jfunc. + (propagate_accross_jump_function): Likewise. + 2011-09-23 Georg-Johann Lay <avr@gjlay.de> PR target/50446 diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index f440b1d..45cb00b 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -674,6 +674,20 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input) return NULL_TREE; } +/* Extract the acual BINFO being described by JFUNC which must be a known type + jump function. */ + +static tree +ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc) +{ + tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type); + if (!base_binfo) + return NULL_TREE; + return get_binfo_at_offset (base_binfo, + jfunc->value.known_type.offset, + jfunc->value.known_type.component_type); +} + /* Determine whether JFUNC evaluates to a known value (that is either a constant or a binfo) and if so, return it. Otherwise return NULL. INFO describes the caller node so that pass-through jump functions can be @@ -685,7 +699,7 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) if (jfunc->type == IPA_JF_CONST) return jfunc->value.constant; else if (jfunc->type == IPA_JF_KNOWN_TYPE) - return jfunc->value.base_binfo; + return ipa_value_from_known_type_jfunc (jfunc); else if (jfunc->type == IPA_JF_PASS_THROUGH || jfunc->type == IPA_JF_ANCESTOR) { @@ -991,7 +1005,11 @@ propagate_accross_jump_function (struct cgraph_edge *cs, tree val; if (jfunc->type == IPA_JF_KNOWN_TYPE) - val = jfunc->value.base_binfo; + { + val = ipa_value_from_known_type_jfunc (jfunc); + if (!val) + return set_lattice_contains_variable (dest_lat); + } else val = jfunc->value.constant; return add_value_to_lattice (dest_lat, val, cs, NULL, 0); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 5e85325..54ba417 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -160,10 +160,12 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs) fprintf (f, "UNKNOWN\n"); else if (type == IPA_JF_KNOWN_TYPE) { - tree binfo_type = TREE_TYPE (jump_func->value.base_binfo); - fprintf (f, "KNOWN TYPE, type in binfo is: "); - print_generic_expr (f, binfo_type, 0); - fprintf (f, " (%u)\n", TYPE_UID (binfo_type)); + fprintf (f, "KNOWN TYPE: base "); + print_generic_expr (f, jump_func->value.known_type.base_type, 0); + fprintf (f, ", offset "HOST_WIDE_INT_PRINT_DEC", component ", + jump_func->value.known_type.offset); + print_generic_expr (f, jump_func->value.known_type.component_type, 0); + fprintf (f, "\n"); } else if (type == IPA_JF_CONST) { @@ -634,7 +636,7 @@ compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc, gimple call) { HOST_WIDE_INT offset, size, max_size; - tree base, binfo; + tree base; if (!flag_devirtualize || TREE_CODE (op) != ADDR_EXPR @@ -650,18 +652,14 @@ compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc, || is_global_var (base)) return; - if (detect_type_change (op, base, call, jfunc, offset)) + if (detect_type_change (op, base, call, jfunc, offset) + || !TYPE_BINFO (TREE_TYPE (base))) return; - binfo = TYPE_BINFO (TREE_TYPE (base)); - if (!binfo) - return; - binfo = get_binfo_at_offset (binfo, offset, TREE_TYPE (op)); - if (binfo) - { - jfunc->type = IPA_JF_KNOWN_TYPE; - jfunc->value.base_binfo = binfo; - } + jfunc->type = IPA_JF_KNOWN_TYPE; + jfunc->value.known_type.base_type = TREE_TYPE (base); + jfunc->value.known_type.offset = offset; + jfunc->value.known_type.component_type = TREE_TYPE (op); } @@ -1500,18 +1498,16 @@ static void combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src, struct ipa_jump_func *dst) { - tree new_binfo; + HOST_WIDE_INT combined_offset; + tree combined_type; - new_binfo = get_binfo_at_offset (src->value.base_binfo, - dst->value.ancestor.offset, - dst->value.ancestor.type); - if (new_binfo) - { - dst->type = IPA_JF_KNOWN_TYPE; - dst->value.base_binfo = new_binfo; - } - else - dst->type = IPA_JF_UNKNOWN; + combined_offset = src->value.known_type.offset + dst->value.ancestor.offset; + combined_type = dst->value.ancestor.type; + + dst->type = IPA_JF_KNOWN_TYPE; + dst->value.known_type.base_type = src->value.known_type.base_type; + dst->value.known_type.offset = combined_offset; + dst->value.known_type.component_type = combined_type; } /* Update the jump functions associated with call graph edge E when the call @@ -1646,22 +1642,19 @@ static struct cgraph_edge * try_make_edge_direct_virtual_call (struct cgraph_edge *ie, struct ipa_jump_func *jfunc) { - tree binfo, type, target; - HOST_WIDE_INT token; - - if (jfunc->type == IPA_JF_KNOWN_TYPE) - binfo = jfunc->value.base_binfo; - else - return NULL; + tree binfo, target; - if (!binfo) + if (jfunc->type != IPA_JF_KNOWN_TYPE) return NULL; - token = ie->indirect_info->otr_token; - type = ie->indirect_info->otr_type; - binfo = get_binfo_at_offset (binfo, ie->indirect_info->anc_offset, type); + binfo = TYPE_BINFO (jfunc->value.known_type.base_type); + gcc_checking_assert (binfo); + binfo = get_binfo_at_offset (binfo, jfunc->value.known_type.offset + + ie->indirect_info->anc_offset, + ie->indirect_info->otr_type); if (binfo) - target = gimple_get_virt_method_for_binfo (token, binfo); + target = gimple_get_virt_method_for_binfo (ie->indirect_info->otr_token, + binfo); else return NULL; @@ -2578,7 +2571,9 @@ ipa_write_jump_function (struct output_block *ob, case IPA_JF_UNKNOWN: break; case IPA_JF_KNOWN_TYPE: - stream_write_tree (ob, jump_func->value.base_binfo, true); + streamer_write_uhwi (ob, jump_func->value.known_type.offset); + stream_write_tree (ob, jump_func->value.known_type.base_type, true); + stream_write_tree (ob, jump_func->value.known_type.component_type, true); break; case IPA_JF_CONST: stream_write_tree (ob, jump_func->value.constant, true); @@ -2614,7 +2609,10 @@ ipa_read_jump_function (struct lto_input_block *ib, case IPA_JF_UNKNOWN: break; case IPA_JF_KNOWN_TYPE: - jump_func->value.base_binfo = stream_read_tree (ib, data_in); + jump_func->value.known_type.offset = streamer_read_uhwi (ib); + jump_func->value.known_type.base_type = stream_read_tree (ib, data_in); + jump_func->value.known_type.component_type = stream_read_tree (ib, + data_in); break; case IPA_JF_CONST: jump_func->value.constant = stream_read_tree (ib, data_in); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 1b7ba69..58caa92 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -72,13 +72,24 @@ along with GCC; see the file COPYING3. If not see enum jump_func_type { IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */ - IPA_JF_KNOWN_TYPE, /* represented by field base_binfo */ + IPA_JF_KNOWN_TYPE, /* represented by field known_type */ IPA_JF_CONST, /* represented by field costant */ IPA_JF_CONST_MEMBER_PTR, /* represented by field member_cst */ IPA_JF_PASS_THROUGH, /* represented by field pass_through */ IPA_JF_ANCESTOR /* represented by field ancestor */ }; +/* Structure holding data required to describe a known type jump function. */ +struct GTY(()) ipa_known_type_data +{ + /* Offset of the component of the base_type being described. */ + HOST_WIDE_INT offset; + /* Type of the whole object. */ + tree base_type; + /* Type of the component of the object that is being described. */ + tree component_type; +}; + /* Structure holding data required to describe a pass-through jump function. */ struct GTY(()) ipa_pass_through_data @@ -127,7 +138,7 @@ typedef struct GTY (()) ipa_jump_func functions and member_cst holds constant c++ member functions. */ union jump_func_value { - tree GTY ((tag ("IPA_JF_KNOWN_TYPE"))) base_binfo; + struct ipa_known_type_data GTY ((tag ("IPA_JF_KNOWN_TYPE"))) known_type; tree GTY ((tag ("IPA_JF_CONST"))) constant; struct ipa_member_ptr_cst GTY ((tag ("IPA_JF_CONST_MEMBER_PTR"))) member_cst; struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through; |