Fix PR 32772 Fix PR 32716 Fix PR 32328 Fix PR 32303
2007-08-19 Daniel Berlin <dberlin@dberlin.org> Fix PR 32772 Fix PR 32716 Fix PR 32328 Fix PR 32303 * tree-flow.h (struct stmt_ann_d): Remove makes_clobbering_call. * tree-ssa-alias.c (init_transitive_clobber_worklist): Add on_worklist argument and avoid adding things to worklist multiple times. (add_to_worklist): Ditto. (mark_aliases_call_clobbered): Mark entire structure clobbered if single SFT is clobbered. (set_initial_properties): Ditto. (compute_call_clobbered): Update for changes to function arguments. (create_overlap_variables_for): Always create SFT for offset 0. (create_structure_vars): Handle PHI's, since we are in SSA form at this point. * tree-ssa-loop-ivopts.c (get_ref_tag): Don't return subvars. * tree-ssa-operands.c (access_can_touch_variable): Don't handle TARGET_MEM_REF. (add_vars_for_offset): Figure out aliases from access + points-to. (add_virtual_operand): Use add_vars-for_offset. (get_tmr_operands): Update for NMT changes, rewrite to be correct. (add_call_clobber_ops): Remove makes_clobbering_call set. (get_expr_operands): Always pass through the INDIRECT_REF reference. * tree-ssa-structalias.c (struct constraint_graph): Remove variables member. Add pe, pe_rep, pointer_label, loc_label, pointed_by, points_to, address_taken, pt_used, number_incoming. (FIRST_ADDR_NODE): Removed. (merge_graph_nodes): Remove broken code for the moment. (init_graph): New function. (build_pred_graph): Remove code to init_graph. Add location equivalence support. (struct scc_info): Rename roots to deleted. (scc_visit): Ditto. (init_scc_info): Ditto (init_topo_info): Use graph->size. (compute_topo_order): Ditto. (do_da_constraint): Removed. (do_sd_constraint): Remove calls to find(). set_union_with_increment should always get 0 as last arg here. (do_complex_constraint): Replace do_da_constraint with assert. Stop calling find. (struct equiv_class_label): New. (pointer_equiv_class_table): Ditto. (location_equiv_class_table): Ditto. (equiv_class_label_hash): Ditto. (equiv_class_label_eq): Ditto (equiv_class_lookup): Ditto. (equiv_class_ladd): Ditto. (pointer_equiv_class): Ditto. (location_equiv_class): Ditto. (condense_visit): Rename and rewrite from label_visit to do only SCC related stuff for HU. (label_visit): Do HU work for HU. (perform_var_substitution): Update to do HU and location equivalence. (free_var_substitution_info): Update to free HU and location equivalence structures. */ (find_equivalent_node): Update for pointer but not location equivalence. (unite_pointer_equivalences): New function. (move_complex_constraints): Rewrite to only do moving. (rewrite_constraints): Split out of move_complex_constraints. (solve_graph): Use graph->size. (process_constraint_1): Add from_call argument, use it. Split *a = &b into two constraints. (process_constraint): Use new process_constraint_1. (get_constraint_for_component_ref): Handle bitmaxsize == -1 case. (get_constraint_for): Handle non-pointer integers properly. Remove code that used to handle structures. (handle_ptr_arith): Fix a few bugs in pointer arithmetic handling with unknown addends. (handle_rhs_call): New function. (find_func_aliases): Use handle_rhs_call. (set_uids_in_ptset): Add an assert. (set_used_smts): Fix bug in not considering unified vars. (compute_tbaa_pruning): Stop initing useless iteration_obstack. (compute_points_to_sets): Update for other function changes. (delete_points_to_sets): Ditto. (ipa_pta_execute): Ditto. (pass_ipa_pta): We need to update SSA after ipa_pta. From-SVN: r127629
This commit is contained in:
parent
73f486583f
commit
7b765bedc0
6 changed files with 1008 additions and 440 deletions
|
@ -1,3 +1,91 @@
|
|||
2007-08-19 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
Fix PR 32772
|
||||
Fix PR 32716
|
||||
Fix PR 32328
|
||||
Fix PR 32303
|
||||
|
||||
* tree-flow.h (struct stmt_ann_d): Remove makes_clobbering_call.
|
||||
* tree-ssa-alias.c (init_transitive_clobber_worklist): Add
|
||||
on_worklist argument and avoid adding things to worklist multiple
|
||||
times.
|
||||
(add_to_worklist): Ditto.
|
||||
(mark_aliases_call_clobbered): Mark entire structure clobbered if
|
||||
single SFT is clobbered.
|
||||
(set_initial_properties): Ditto.
|
||||
(compute_call_clobbered): Update for changes to function
|
||||
arguments.
|
||||
(create_overlap_variables_for): Always create SFT for offset 0.
|
||||
(create_structure_vars): Handle PHI's, since we are in SSA form at
|
||||
this point.
|
||||
* tree-ssa-loop-ivopts.c (get_ref_tag): Don't return subvars.
|
||||
* tree-ssa-operands.c (access_can_touch_variable): Don't handle
|
||||
TARGET_MEM_REF.
|
||||
(add_vars_for_offset): Figure out aliases from access + points-to.
|
||||
(add_virtual_operand): Use add_vars-for_offset.
|
||||
(get_tmr_operands): Update for NMT changes, rewrite to be correct.
|
||||
(add_call_clobber_ops): Remove makes_clobbering_call set.
|
||||
(get_expr_operands): Always pass through the INDIRECT_REF
|
||||
reference.
|
||||
* tree-ssa-structalias.c (struct constraint_graph): Remove
|
||||
variables member.
|
||||
Add pe, pe_rep, pointer_label, loc_label, pointed_by, points_to,
|
||||
address_taken, pt_used, number_incoming.
|
||||
(FIRST_ADDR_NODE): Removed.
|
||||
(merge_graph_nodes): Remove broken code for the moment.
|
||||
(init_graph): New function.
|
||||
(build_pred_graph): Remove code to init_graph.
|
||||
Add location equivalence support.
|
||||
(struct scc_info): Rename roots to deleted.
|
||||
(scc_visit): Ditto.
|
||||
(init_scc_info): Ditto
|
||||
(init_topo_info): Use graph->size.
|
||||
(compute_topo_order): Ditto.
|
||||
(do_da_constraint): Removed.
|
||||
(do_sd_constraint): Remove calls to find().
|
||||
set_union_with_increment should always get 0 as last arg here.
|
||||
(do_complex_constraint): Replace do_da_constraint with assert.
|
||||
Stop calling find.
|
||||
(struct equiv_class_label): New.
|
||||
(pointer_equiv_class_table): Ditto.
|
||||
(location_equiv_class_table): Ditto.
|
||||
(equiv_class_label_hash): Ditto.
|
||||
(equiv_class_label_eq): Ditto
|
||||
(equiv_class_lookup): Ditto.
|
||||
(equiv_class_ladd): Ditto.
|
||||
(pointer_equiv_class): Ditto.
|
||||
(location_equiv_class): Ditto.
|
||||
(condense_visit): Rename and rewrite from label_visit to do only
|
||||
SCC related stuff for HU.
|
||||
(label_visit): Do HU work for HU.
|
||||
(perform_var_substitution): Update to do HU and location
|
||||
equivalence.
|
||||
(free_var_substitution_info): Update to free HU and location
|
||||
equivalence structures. */
|
||||
(find_equivalent_node): Update for pointer but not location
|
||||
equivalence.
|
||||
(unite_pointer_equivalences): New function.
|
||||
(move_complex_constraints): Rewrite to only do moving.
|
||||
(rewrite_constraints): Split out of move_complex_constraints.
|
||||
(solve_graph): Use graph->size.
|
||||
(process_constraint_1): Add from_call argument, use it.
|
||||
Split *a = &b into two constraints.
|
||||
(process_constraint): Use new process_constraint_1.
|
||||
(get_constraint_for_component_ref): Handle bitmaxsize == -1 case.
|
||||
(get_constraint_for): Handle non-pointer integers properly.
|
||||
Remove code that used to handle structures.
|
||||
(handle_ptr_arith): Fix a few bugs in pointer arithmetic handling
|
||||
with unknown addends.
|
||||
(handle_rhs_call): New function.
|
||||
(find_func_aliases): Use handle_rhs_call.
|
||||
(set_uids_in_ptset): Add an assert.
|
||||
(set_used_smts): Fix bug in not considering unified vars.
|
||||
(compute_tbaa_pruning): Stop initing useless iteration_obstack.
|
||||
(compute_points_to_sets): Update for other function changes.
|
||||
(delete_points_to_sets): Ditto.
|
||||
(ipa_pta_execute): Ditto.
|
||||
(pass_ipa_pta): We need to update SSA after ipa_pta.
|
||||
|
||||
2007-08-19 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.md: Replace "rim" and "mri" constraints by "g".
|
||||
|
|
|
@ -498,10 +498,6 @@ struct stmt_ann_d GTY(())
|
|||
|
||||
/* Nonzero if the statement makes references to volatile storage. */
|
||||
unsigned has_volatile_ops : 1;
|
||||
|
||||
/* Nonzero if the statement makes a function call that may clobber global
|
||||
and local addressable variables. */
|
||||
unsigned makes_clobbering_call : 1;
|
||||
};
|
||||
|
||||
union tree_ann_d GTY((desc ("ann_type ((tree_ann_t)&%h)")))
|
||||
|
|
|
@ -322,7 +322,8 @@ sort_tags_by_id (const void *pa, const void *pb)
|
|||
|
||||
static void
|
||||
init_transitive_clobber_worklist (VEC (tree, heap) **worklist,
|
||||
VEC (int, heap) **worklist2)
|
||||
VEC (int, heap) **worklist2,
|
||||
bitmap on_worklist)
|
||||
{
|
||||
referenced_var_iterator rvi;
|
||||
tree curr;
|
||||
|
@ -332,7 +333,9 @@ init_transitive_clobber_worklist (VEC (tree, heap) **worklist,
|
|||
if (MTAG_P (curr) && is_call_clobbered (curr))
|
||||
{
|
||||
VEC_safe_push (tree, heap, *worklist, curr);
|
||||
VEC_safe_push (int, heap, *worklist2, var_ann (curr)->escape_mask);
|
||||
VEC_safe_push (int, heap, *worklist2,
|
||||
var_ann (curr)->escape_mask);
|
||||
bitmap_set_bit (on_worklist, DECL_UID (curr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,13 +346,15 @@ init_transitive_clobber_worklist (VEC (tree, heap) **worklist,
|
|||
|
||||
static void
|
||||
add_to_worklist (tree alias, VEC (tree, heap) **worklist,
|
||||
VEC (int, heap) **worklist2,
|
||||
int reason)
|
||||
VEC (int, heap) **worklist2, int reason,
|
||||
bitmap on_worklist)
|
||||
{
|
||||
if (MTAG_P (alias) && !is_call_clobbered (alias))
|
||||
if (MTAG_P (alias) && !is_call_clobbered (alias)
|
||||
&& !bitmap_bit_p (on_worklist, DECL_UID (alias)))
|
||||
{
|
||||
VEC_safe_push (tree, heap, *worklist, alias);
|
||||
VEC_safe_push (int, heap, *worklist2, reason);
|
||||
bitmap_set_bit (on_worklist, DECL_UID (alias));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +363,8 @@ add_to_worklist (tree alias, VEC (tree, heap) **worklist,
|
|||
|
||||
static void
|
||||
mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist,
|
||||
VEC (int, heap) **worklist2)
|
||||
VEC (int, heap) **worklist2,
|
||||
bitmap on_worklist)
|
||||
{
|
||||
bitmap aliases;
|
||||
bitmap_iterator bi;
|
||||
|
@ -375,9 +381,23 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist,
|
|||
EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi)
|
||||
{
|
||||
entry = referenced_var (i);
|
||||
if (!unmodifiable_var_p (entry))
|
||||
/* If you clobber one part of a structure, you
|
||||
clobber the entire thing. While this does not make
|
||||
the world a particularly nice place, it is necessary
|
||||
in order to allow C/C++ tricks that involve
|
||||
pointer arithmetic to work. */
|
||||
if (TREE_CODE (entry) == STRUCT_FIELD_TAG)
|
||||
{
|
||||
add_to_worklist (entry, worklist, worklist2, ta->escape_mask);
|
||||
subvar_t svars;
|
||||
svars = get_subvars_for_var (SFT_PARENT_VAR (entry));
|
||||
for (; svars; svars = svars->next)
|
||||
if (!unmodifiable_var_p (entry))
|
||||
mark_call_clobbered (svars->var, ta->escape_mask);
|
||||
}
|
||||
else if (!unmodifiable_var_p (entry))
|
||||
{
|
||||
add_to_worklist (entry, worklist, worklist2, ta->escape_mask,
|
||||
on_worklist);
|
||||
mark_call_clobbered (entry, ta->escape_mask);
|
||||
}
|
||||
}
|
||||
|
@ -528,8 +548,25 @@ set_initial_properties (struct alias_info *ai)
|
|||
bitmap_iterator bi;
|
||||
unsigned int j;
|
||||
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
|
||||
if (!unmodifiable_var_p (referenced_var (j)))
|
||||
mark_call_clobbered (referenced_var (j), pi->escape_mask);
|
||||
{
|
||||
tree alias = referenced_var (j);
|
||||
|
||||
/* If you clobber one part of a structure, you
|
||||
clobber the entire thing. While this does not make
|
||||
the world a particularly nice place, it is necessary
|
||||
in order to allow C/C++ tricks that involve
|
||||
pointer arithmetic to work. */
|
||||
if (TREE_CODE (alias) == STRUCT_FIELD_TAG)
|
||||
{
|
||||
subvar_t svars;
|
||||
svars = get_subvars_for_var (SFT_PARENT_VAR (alias));
|
||||
for (; svars; svars = svars->next)
|
||||
if (!unmodifiable_var_p (alias))
|
||||
mark_call_clobbered (svars->var, pi->escape_mask);
|
||||
}
|
||||
else if (!unmodifiable_var_p (alias))
|
||||
mark_call_clobbered (alias, pi->escape_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,21 +610,27 @@ static void
|
|||
compute_call_clobbered (struct alias_info *ai)
|
||||
{
|
||||
VEC (tree, heap) *worklist = NULL;
|
||||
VEC(int,heap) *worklist2 = NULL;
|
||||
|
||||
VEC (int,heap) *worklist2 = NULL;
|
||||
bitmap on_worklist;
|
||||
|
||||
timevar_push (TV_CALL_CLOBBER);
|
||||
on_worklist = BITMAP_ALLOC (NULL);
|
||||
|
||||
set_initial_properties (ai);
|
||||
init_transitive_clobber_worklist (&worklist, &worklist2);
|
||||
init_transitive_clobber_worklist (&worklist, &worklist2, on_worklist);
|
||||
while (VEC_length (tree, worklist) != 0)
|
||||
{
|
||||
tree curr = VEC_pop (tree, worklist);
|
||||
int reason = VEC_pop (int, worklist2);
|
||||
|
||||
|
||||
bitmap_clear_bit (on_worklist, DECL_UID (curr));
|
||||
mark_call_clobbered (curr, reason);
|
||||
mark_aliases_call_clobbered (curr, &worklist, &worklist2);
|
||||
mark_aliases_call_clobbered (curr, &worklist, &worklist2,
|
||||
on_worklist);
|
||||
}
|
||||
VEC_free (tree, heap, worklist);
|
||||
VEC_free (int, heap, worklist2);
|
||||
BITMAP_FREE (on_worklist);
|
||||
compute_tag_properties ();
|
||||
timevar_pop (TV_CALL_CLOBBER);
|
||||
}
|
||||
|
@ -3783,11 +3826,14 @@ create_overlap_variables_for (tree var)
|
|||
|
||||
/* If this field isn't in the used portion,
|
||||
or it has the exact same offset and size as the last
|
||||
field, skip it. */
|
||||
field, skip it. Note that we always need the field at
|
||||
offset 0 so we can properly handle pointers to the
|
||||
structure. */
|
||||
|
||||
if (((fo->offset <= up->minused
|
||||
&& fo->offset + fosize <= up->minused)
|
||||
|| fo->offset >= up->maxused)
|
||||
if ((fo->offset != 0
|
||||
&& ((fo->offset <= up->minused
|
||||
&& fo->offset + fosize <= up->minused)
|
||||
|| fo->offset >= up->maxused))
|
||||
|| (fo->offset == lastfooffset
|
||||
&& fosize == lastfosize
|
||||
&& currfotype == lastfotype))
|
||||
|
@ -3975,6 +4021,21 @@ create_structure_vars (void)
|
|||
FOR_EACH_BB (bb)
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
tree phi;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
use_operand_p use;
|
||||
ssa_op_iter iter;
|
||||
|
||||
FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
|
||||
{
|
||||
tree op = USE_FROM_PTR (use);
|
||||
walk_tree_without_duplicates (&op, find_used_portions,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
|
||||
|
@ -4013,7 +4074,7 @@ create_structure_vars (void)
|
|||
tree sym = referenced_var_lookup (i);
|
||||
if (get_subvars_for_var (sym))
|
||||
{
|
||||
update=true;
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4024,7 +4085,7 @@ create_structure_vars (void)
|
|||
tree sym = referenced_var_lookup (i);
|
||||
if (get_subvars_for_var (sym))
|
||||
{
|
||||
update=true;
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4036,7 +4097,7 @@ create_structure_vars (void)
|
|||
tree sym = referenced_var_lookup (i);
|
||||
if (get_subvars_for_var (sym))
|
||||
{
|
||||
update=true;
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5020,7 +5020,7 @@ get_ref_tag (tree ref, tree orig)
|
|||
}
|
||||
|
||||
if (aref && SSA_VAR_P (aref) && get_subvars_for_var (aref))
|
||||
return unshare_expr (sv);
|
||||
return aref;
|
||||
|
||||
if (!var)
|
||||
return NULL_TREE;
|
||||
|
|
|
@ -1181,7 +1181,9 @@ append_vuse (tree var)
|
|||
/* REF is a tree that contains the entire pointer dereference
|
||||
expression, if available, or NULL otherwise. ALIAS is the variable
|
||||
we are asking if REF can access. OFFSET and SIZE come from the
|
||||
memory access expression that generated this virtual operand. */
|
||||
memory access expression that generated this virtual operand.
|
||||
|
||||
XXX: We should handle the NO_ALIAS attributes here. */
|
||||
|
||||
static bool
|
||||
access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
|
||||
|
@ -1197,6 +1199,11 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
|
|||
if (alias == gimple_global_var (cfun))
|
||||
return true;
|
||||
|
||||
/* If ref is a TARGET_MEM_REF, just return true, as we can't really
|
||||
disambiguate them right now. */
|
||||
if (ref && TREE_CODE (ref) == TARGET_MEM_REF)
|
||||
return true;
|
||||
|
||||
/* If ALIAS is an SFT, it can't be touched if the offset
|
||||
and size of the access is not overlapping with the SFT offset and
|
||||
size. This is only true if we are accessing through a pointer
|
||||
|
@ -1290,6 +1297,7 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
|
|||
&& flag_strict_aliasing
|
||||
&& TREE_CODE (ref) != INDIRECT_REF
|
||||
&& !MTAG_P (alias)
|
||||
&& base
|
||||
&& (TREE_CODE (base) != INDIRECT_REF
|
||||
|| TREE_CODE (TREE_TYPE (base)) != UNION_TYPE)
|
||||
&& !AGGREGATE_TYPE_P (TREE_TYPE (alias))
|
||||
|
@ -1335,6 +1343,106 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Add the actual variables FULL_REF can access, given a member of
|
||||
full_ref's points-to set VAR, where FULL_REF is an access of SIZE at
|
||||
OFFSET from var. IS_CALL_SITE is true if this is a call, and IS_DEF
|
||||
is true if this is supposed to be a vdef, and false if this should
|
||||
be a VUSE.
|
||||
|
||||
The real purpose of this function is to take a points-to set for a
|
||||
pointer to a structure, say
|
||||
|
||||
struct s {
|
||||
int a;
|
||||
int b;
|
||||
} foo, *foop = &foo;
|
||||
|
||||
and discover which variables an access, such as foop->b, can alias.
|
||||
|
||||
This is necessary because foop only actually points to foo's first
|
||||
member, so that is all the points-to set contains. However, an access
|
||||
to foop->a may be touching some single SFT if we have created some
|
||||
SFT's for a structure. */
|
||||
|
||||
static bool
|
||||
add_vars_for_offset (tree full_ref, tree var, HOST_WIDE_INT offset,
|
||||
HOST_WIDE_INT size, bool is_call_site, bool is_def)
|
||||
{
|
||||
/* Call-clobbered tags may have non-call-clobbered
|
||||
symbols in their alias sets. Ignore them if we are
|
||||
adding VOPs for a call site. */
|
||||
if (is_call_site && !is_call_clobbered (var))
|
||||
return false;
|
||||
|
||||
/* For offset 0, we already have the right variable. If there is no
|
||||
full_ref, this is not a place we care about (All component
|
||||
related accesses that go through pointers will have full_ref not
|
||||
NULL).
|
||||
Any var for which we didn't create SFT's can't be
|
||||
distinguished. */
|
||||
if (!full_ref || (offset == 0 && size != -1)
|
||||
|| (TREE_CODE (var) != STRUCT_FIELD_TAG
|
||||
&& (!var_can_have_subvars (var) || !get_subvars_for_var (var))))
|
||||
{
|
||||
if (!access_can_touch_variable (full_ref, var, offset, size))
|
||||
return false;
|
||||
|
||||
if (is_def)
|
||||
append_vdef (var);
|
||||
else
|
||||
append_vuse (var);
|
||||
return true;
|
||||
}
|
||||
else if (TREE_CODE (var) == STRUCT_FIELD_TAG)
|
||||
{
|
||||
if (size == -1)
|
||||
{
|
||||
bool added = false;
|
||||
subvar_t sv = get_subvars_for_var (SFT_PARENT_VAR (var));
|
||||
for (; sv; sv = sv->next)
|
||||
{
|
||||
if (overlap_subvar (SFT_OFFSET (var) + offset, size,
|
||||
sv->var, NULL)
|
||||
&& access_can_touch_variable (full_ref, sv->var,
|
||||
offset, size))
|
||||
{
|
||||
added = true;
|
||||
if (is_def)
|
||||
append_vdef (sv->var);
|
||||
else
|
||||
append_vuse (sv->var);
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool added = false;
|
||||
subvar_t sv = get_subvars_for_var (SFT_PARENT_VAR (var));
|
||||
for (; sv; sv = sv->next)
|
||||
{
|
||||
/* Once we hit the end of the parts that could touch,
|
||||
stop looking. */
|
||||
if (SFT_OFFSET (var) + offset + size <= SFT_OFFSET (sv->var))
|
||||
break;
|
||||
if (overlap_subvar (SFT_OFFSET (var) + offset, size,
|
||||
sv->var, NULL)
|
||||
&& access_can_touch_variable (full_ref, sv->var, offset,
|
||||
size))
|
||||
{
|
||||
added = true;
|
||||
if (is_def)
|
||||
append_vdef (sv->var);
|
||||
else
|
||||
append_vuse (sv->var);
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add VAR to the virtual operands array. FLAGS is as in
|
||||
get_expr_operands. FULL_REF is a tree that contains the entire
|
||||
|
@ -1343,7 +1451,7 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
|
|||
generated this virtual operand. IS_CALL_SITE is true if the
|
||||
affected statement is a call site. */
|
||||
|
||||
static void
|
||||
static void
|
||||
add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
|
||||
tree full_ref, HOST_WIDE_INT offset,
|
||||
HOST_WIDE_INT size, bool is_call_site)
|
||||
|
@ -1416,17 +1524,8 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
|
|||
EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi)
|
||||
{
|
||||
al = referenced_var (i);
|
||||
if (!access_can_touch_variable (full_ref, al, offset, size))
|
||||
continue;
|
||||
|
||||
/* Call-clobbered tags may have non-call-clobbered
|
||||
symbols in their alias sets. Ignore them if we are
|
||||
adding VOPs for a call site. */
|
||||
if (is_call_site && !is_call_clobbered (al))
|
||||
continue;
|
||||
|
||||
none_added = false;
|
||||
append_vdef (al);
|
||||
none_added &= !add_vars_for_offset (full_ref, al, offset, size,
|
||||
is_call_site, true);
|
||||
}
|
||||
|
||||
/* If the variable is also an alias tag, add a virtual
|
||||
|
@ -1443,9 +1542,7 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
|
|||
if (none_added
|
||||
|| (TREE_CODE (var) == SYMBOL_MEMORY_TAG
|
||||
&& is_call_site))
|
||||
{
|
||||
append_vdef (var);
|
||||
}
|
||||
append_vdef (var);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1453,17 +1550,9 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
|
|||
EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi)
|
||||
{
|
||||
al = referenced_var (i);
|
||||
if (!access_can_touch_variable (full_ref, al, offset, size))
|
||||
continue;
|
||||
|
||||
/* Call-clobbered tags may have non-call-clobbered
|
||||
symbols in their alias sets. Ignore them if we are
|
||||
adding VOPs for a call site. */
|
||||
if (is_call_site && !is_call_clobbered (al))
|
||||
continue;
|
||||
|
||||
none_added = false;
|
||||
append_vuse (al);
|
||||
none_added &= !add_vars_for_offset (full_ref, al, offset, size,
|
||||
is_call_site, false);
|
||||
|
||||
}
|
||||
|
||||
/* Even if no aliases have been added, we still need to
|
||||
|
@ -1620,9 +1709,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
|
|||
static void
|
||||
get_tmr_operands (tree stmt, tree expr, int flags)
|
||||
{
|
||||
tree tag, ref;
|
||||
HOST_WIDE_INT offset, size, maxsize;
|
||||
subvar_t svars, sv;
|
||||
tree tag;
|
||||
stmt_ann_t s_ann = stmt_ann (stmt);
|
||||
|
||||
/* This statement references memory. */
|
||||
|
@ -1642,23 +1729,13 @@ get_tmr_operands (tree stmt, tree expr, int flags)
|
|||
s_ann->has_volatile_ops = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DECL_P (tag))
|
||||
if (!MTAG_P (tag))
|
||||
{
|
||||
get_expr_operands (stmt, &tag, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
ref = get_ref_base_and_extent (tag, &offset, &size, &maxsize);
|
||||
gcc_assert (ref != NULL_TREE);
|
||||
svars = get_subvars_for_var (ref);
|
||||
for (sv = svars; sv; sv = sv->next)
|
||||
{
|
||||
bool exact;
|
||||
|
||||
if (overlap_subvar (offset, maxsize, sv->var, &exact))
|
||||
add_stmt_operand (&sv->var, s_ann, flags);
|
||||
}
|
||||
add_virtual_operand (tag, s_ann, flags, expr, 0, -1, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1673,11 +1750,6 @@ add_call_clobber_ops (tree stmt, tree callee)
|
|||
stmt_ann_t s_ann = stmt_ann (stmt);
|
||||
bitmap not_read_b, not_written_b;
|
||||
|
||||
/* Functions that are not const, pure or never return may clobber
|
||||
call-clobbered variables. */
|
||||
if (s_ann)
|
||||
s_ann->makes_clobbering_call = true;
|
||||
|
||||
/* If we created .GLOBAL_VAR earlier, just use it. */
|
||||
if (gimple_global_var (cfun))
|
||||
{
|
||||
|
@ -2032,7 +2104,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
|
|||
|
||||
case ALIGN_INDIRECT_REF:
|
||||
case INDIRECT_REF:
|
||||
get_indirect_ref_operands (stmt, expr, flags, NULL_TREE, 0, -1, true);
|
||||
get_indirect_ref_operands (stmt, expr, flags, expr, 0, -1, true);
|
||||
return;
|
||||
|
||||
case TARGET_MEM_REF:
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue