diff options
author | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-19 23:23:29 +0000 |
---|---|---|
committer | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-19 23:23:29 +0000 |
commit | a6db8f1419b14fc5afed873dbc6ddc25cab75bf7 (patch) | |
tree | baa8e18c063d5687f098c1d8745169221e56ef6a /gcc/tree-ssa-operands.c | |
parent | 662e4881030345c1e1e37a422ca3e3af928fc931 (diff) | |
download | gcc-a6db8f1419b14fc5afed873dbc6ddc25cab75bf7.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127629 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 168 |
1 files changed, 120 insertions, 48 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 7a40991e22b..7217b554ff0 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -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: |