diff options
author | Martin Jambor <mjambor@suse.cz> | 2014-06-06 15:26:24 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2014-06-06 15:26:24 +0200 |
commit | 0d48ee34703105d7b840b6f6862650c188bf15b6 (patch) | |
tree | 0009545635dddfe4dc9b2c6e5b1ce5219e0bc0d0 | |
parent | e2c75eea66fb579de806cb2b3a85cb26d8b792db (diff) | |
download | gcc-0d48ee34703105d7b840b6f6862650c188bf15b6.zip gcc-0d48ee34703105d7b840b6f6862650c188bf15b6.tar.gz gcc-0d48ee34703105d7b840b6f6862650c188bf15b6.tar.bz2 |
ipa-prop.c (get_place_in_agg_contents_list): New function.
2014-06-06 Martin Jambor <mjambor@suse.cz>
* ipa-prop.c (get_place_in_agg_contents_list): New function.
(build_agg_jump_func_from_list): Likewise.
(determine_known_aggregate_parts): Renamed to
determine_locally_known_aggregate_parts. Moved some functionality
to the two functions above, removed bound checks.
From-SVN: r211315
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 126 |
2 files changed, 80 insertions, 54 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d2e201..32e0c56 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-06-06 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.c (get_place_in_agg_contents_list): New function. + (build_agg_jump_func_from_list): Likewise. + (determine_known_aggregate_parts): Renamed to + determine_locally_known_aggregate_parts. Moved some functionality + to the two functions above, removed bound checks. + 2014-06-06 James Greenhalgh <james.greenhalgh@arm.com> * config/aarch64/aarch64-protos.h (aarch64_expand_movmem): New. diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1670821..d02093a 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1495,14 +1495,72 @@ struct ipa_known_agg_contents_list struct ipa_known_agg_contents_list *next; }; +/* Find the proper place in linked list of ipa_known_agg_contents_list + structures where to put a new one with the given LHS_OFFSET and LHS_SIZE, + unless there is a partial overlap, in which case return NULL, or such + element is already there, in which case set *ALREADY_THERE to true. */ + +static struct ipa_known_agg_contents_list ** +get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list, + HOST_WIDE_INT lhs_offset, + HOST_WIDE_INT lhs_size, + bool *already_there) +{ + struct ipa_known_agg_contents_list **p = list; + while (*p && (*p)->offset < lhs_offset) + { + if ((*p)->offset + (*p)->size > lhs_offset) + return NULL; + p = &(*p)->next; + } + + if (*p && (*p)->offset < lhs_offset + lhs_size) + { + if ((*p)->offset == lhs_offset && (*p)->size == lhs_size) + /* We already know this value is subsequently overwritten with + something else. */ + *already_there = true; + else + /* Otherwise this is a partial overlap which we cannot + represent. */ + return NULL; + } + return p; +} + +/* Build aggregate jump function from LIST, assuming there are exactly + CONST_COUNT constant entries there and that th offset of the passed argument + is ARG_OFFSET and store it into JFUNC. */ + +static void +build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list, + int const_count, HOST_WIDE_INT arg_offset, + struct ipa_jump_func *jfunc) +{ + vec_alloc (jfunc->agg.items, const_count); + while (list) + { + if (list->constant) + { + struct ipa_agg_jf_item item; + item.offset = list->offset - arg_offset; + gcc_assert ((item.offset % BITS_PER_UNIT) == 0); + item.value = unshare_expr_without_location (list->constant); + jfunc->agg.items->quick_push (item); + } + list = list->next; + } +} + /* Traverse statements from CALL backwards, scanning whether an aggregate given in ARG is filled in with constant values. ARG can either be an aggregate - expression or a pointer to an aggregate. ARG_TYPE is the type of the aggregate. - JFUNC is the jump function into which the constants are subsequently stored. */ + expression or a pointer to an aggregate. ARG_TYPE is the type of the + aggregate. JFUNC is the jump function into which the constants are + subsequently stored. */ static void -determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, - struct ipa_jump_func *jfunc) +determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type, + struct ipa_jump_func *jfunc) { struct ipa_known_agg_contents_list *list = NULL; int item_count = 0, const_count = 0; @@ -1544,10 +1602,8 @@ determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, return; if (DECL_P (arg_base)) { - tree size; check_ref = false; - size = build_int_cst (integer_type_node, arg_size); - ao_ref_init_from_ptr_and_size (&r, arg_base, size); + ao_ref_init (&r, arg_base); } else return; @@ -1585,7 +1641,6 @@ determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, gimple stmt = gsi_stmt (gsi); HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size; tree lhs, rhs, lhs_base; - bool partial_overlap; if (!stmt_may_clobber_ref_p_1 (stmt, &r)) continue; @@ -1602,11 +1657,7 @@ determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size, &lhs_max_size); if (lhs_max_size == -1 - || lhs_max_size != lhs_size - || (lhs_offset < arg_offset - && lhs_offset + lhs_size > arg_offset) - || (lhs_offset < arg_offset + arg_size - && lhs_offset + lhs_size > arg_offset + arg_size)) + || lhs_max_size != lhs_size) break; if (check_ref) @@ -1624,34 +1675,13 @@ determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, break; } - if (lhs_offset + lhs_size < arg_offset - || lhs_offset >= (arg_offset + arg_size)) - continue; - - partial_overlap = false; - p = &list; - while (*p && (*p)->offset < lhs_offset) - { - if ((*p)->offset + (*p)->size > lhs_offset) - { - partial_overlap = true; - break; - } - p = &(*p)->next; - } - if (partial_overlap) + bool already_there = false; + p = get_place_in_agg_contents_list (&list, lhs_offset, lhs_size, + &already_there); + if (!p) break; - if (*p && (*p)->offset < lhs_offset + lhs_size) - { - if ((*p)->offset == lhs_offset && (*p)->size == lhs_size) - /* We already know this value is subsequently overwritten with - something else. */ - continue; - else - /* Otherwise this is a partial overlap which we cannot - represent. */ - break; - } + if (already_there) + continue; rhs = get_ssa_def_if_simple_copy (rhs); n = XALLOCA (struct ipa_known_agg_contents_list); @@ -1680,19 +1710,7 @@ determine_known_aggregate_parts (gimple call, tree arg, tree arg_type, if (const_count) { jfunc->agg.by_ref = by_ref; - vec_alloc (jfunc->agg.items, const_count); - while (list) - { - if (list->constant) - { - struct ipa_agg_jf_item item; - item.offset = list->offset - arg_offset; - gcc_assert ((item.offset % BITS_PER_UNIT) == 0); - item.value = unshare_expr_without_location (list->constant); - jfunc->agg.items->quick_push (item); - } - list = list->next; - } + build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc); } } @@ -1824,7 +1842,7 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi, || !ipa_get_jf_ancestor_agg_preserved (jfunc)) && (AGGREGATE_TYPE_P (TREE_TYPE (arg)) || POINTER_TYPE_P (param_type))) - determine_known_aggregate_parts (call, arg, param_type, jfunc); + determine_locally_known_aggregate_parts (call, arg, param_type, jfunc); } } |