summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-copy.c
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-10 00:28:01 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-10 00:28:01 +0000
commit260e7e1138194f75585448f45db9a45f64787de2 (patch)
tree9008332e0b51567fbab3eeb7dddef5739f208581 /gcc/tree-ssa-copy.c
parentd991daa38fa6f7e586e7b582d8dd2fb2e6d17671 (diff)
downloadgcc-260e7e1138194f75585448f45db9a45f64787de2.tar.gz
* Makefile.in (tree-ssa-alias.o): Depend on tree-ssa-structalias.h
* tree-cfg.c (CHECK_OP): Only test for is_gimple_val. * tree-dfa.c (dump_subvars_for): New. (debug_subvars_for): New. (dump_variable): Show subvariables if VAR has them. * tree-flow-inline.h (get_subvar_at): New. (overlap_subvar): Change offset and size to unsigned HOST_WIDE_INT. * tree-flow.h (struct ptr_info_def): Remove field pt_malloc. Update all users. (struct subvar): Change fields offset and size to unsigned HOST_WIDE_INT. (dump_subvars_for): Declare. (debug_subvars_for): Declare. (get_subvar_at): Declare. (okay_component_ref_for_subvars): Change 2nd and 3rd argument to unsigned HOST_WIDE_INT *. (overlap_subvar): Likewise. * tree-gimple.c (is_gimple_reg): Always return false for SFTs and memory tags. * tree-pass.h (pass_build_pta, pass_del_pta): Remove. Update all callers. * tree-ssa-alias.c: Include tree-ssa-structalias.h. (compute_may_aliases): Call compute_points_to_sets. (collect_points_to_info_for): Remove. (compute_points_to_and_addr_escape): Remove. (delete_alias_info): Call delete_points_to_sets. (compute_flow_sensitive_aliasing): If the call to find_what_p_points_to returns false, call set_pt_anything. (add_may_alias): Set TREE_ADDRESSABLE when adding a new alias. (set_pt_anything): Clear pi->pt_vars. (set_pt_malloc): Remove. (merge_pointed_to_info): Remove. (add_pointed_to_expr): Remove. (add_pointed_to_var): Remove. (collect_points_to_info_r): Remove. (is_escape_site): Make extern. (create_sft): New. (create_overlap_variables_for): Call it. * tree-ssa-copy.c (merge_alias_info): Never merge flow-sensitive alias information. * tree-ssa-operands.c (get_expr_operands): Adjust variables offset and size to be unsigned HOST_WIDE_INT. (add_to_addressable_set): Rename from note_addressable. Set TREE_ADDRESSABLE as the variables are added to the set. Update all users. (add_stmt_operand): Do not try to micro-optimize unmodifiable operands into VUSEs when adding V_MAY_DEFs for members in an alias set. * tree-ssa-operands.h (add_to_addressable_set): Declare. * tree-ssa-structalias.c: Include tree-ssa-structalias.h last. (struct variable_info): Add bitfield is_heap_var. (var_anyoffset, anyoffset_tree, anyoffset_id): Declare. (new_var_info): Initialize is_heap_var. (get_constraint_for): Add HEAP variables to the symbol table. Mark them with is_heap_var. (update_alias_info): New. Taken mostly from the old compute_points_to_and_addr_escape. (handle_ptr_arith): New. (find_func_aliases): Call update_alias_info. Call handle_ptr_info for tcc_binary expressions. Call mark_stmt_modified. (create_variable_info_for): If DECL has subvars, do not create variables for its subvars. Always add all the fields. (set_uids_in_ptset): If the solution includes ANYOFFSET and SFTs, then add all the SFTs of the structure. If VI->DECL is an aggregate with subvariables, add the SFT at VI->OFFSET. (find_what_p_points_to): If VI is an artificial variable, translate to bitfields in SSA_NAME_PTR_INFO. If the solution is empty, set pi->pt_vars to NULL (init_base_vars): Create ANYOFFSET. (compute_points_to_sets): Rename from create_alias_vars. Make extern. (pass_build_pta): Remove. (delete_points_to_sets): Rename from delete_alias_vars. (pass_del_pta): Remove. * tree-ssa-structalias.h (struct alias_info): Move from tree-ssa-alias.h. (NUM_REFERENCES, NUM_REFERENCES_CLEAR, NUM_REFERENCES_INC, NUM_REFERENCES_SET): Likewise. (compute_points_to_sets, delete_points_to_sets): Declare. testsuite/ChangeLog * gcc.dg/tree-ssa/pta-fp.c: Use -fdump-tree-alias1. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101841 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-copy.c')
-rw-r--r--gcc/tree-ssa-copy.c57
1 files changed, 34 insertions, 23 deletions
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 71119608237..28b19d945e4 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -188,7 +188,9 @@ merge_alias_info (tree orig, tree new)
#endif
/* Synchronize the type tags. If both pointers had a tag and they
- are different, then something has gone wrong. */
+ are different, then something has gone wrong. Type tags can
+ always be merged because they are flow insensitive, all the SSA
+ names of the same base DECL share the same type tag. */
if (new_ann->type_mem_tag == NULL_TREE)
new_ann->type_mem_tag = orig_ann->type_mem_tag;
else if (orig_ann->type_mem_tag == NULL_TREE)
@@ -196,32 +198,41 @@ merge_alias_info (tree orig, tree new)
else
gcc_assert (new_ann->type_mem_tag == orig_ann->type_mem_tag);
- /* Synchronize the name tags. If NEW did not have a name tag, get
- it from ORIG. This happens when NEW is a compiler generated
- temporary which still hasn't had its points-to information filled
- in. */
- if (SSA_NAME_PTR_INFO (orig))
+ /* Check that flow-sensitive information is compatible. Notice that
+ we may not merge flow-sensitive information here. This function
+ is called when propagating equivalences dictated by the IL, like
+ a copy operation P_i = Q_j, and from equivalences dictated by
+ control-flow, like if (P_i == Q_j).
+
+ In the former case, P_i and Q_j are equivalent in every block
+ dominated by the assignment, so their flow-sensitive information
+ is always the same. However, in the latter case, the pointers
+ P_i and Q_j are only equivalent in one of the sub-graphs out of
+ the predicate, so their flow-sensitive information is not the
+ same in every block dominated by the predicate.
+
+ Since we cannot distinguish one case from another in this
+ function, we can only make sure that if P_i and Q_j have
+ flow-sensitive information, they should be compatible. */
+ if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (new))
{
struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
struct ptr_info_def *new_ptr_info = SSA_NAME_PTR_INFO (new);
- if (new_ptr_info == NULL)
- duplicate_ssa_name_ptr_info (new, orig_ptr_info);
- else if (orig_ptr_info->name_mem_tag
- && new_ptr_info->name_mem_tag
- && orig_ptr_info->pt_vars
- && new_ptr_info->pt_vars)
- {
- /* Note that pointer NEW may actually have a different set
- of pointed-to variables. However, since NEW is being
- copy-propagated into ORIG, it must always be true that
- the pointed-to set for pointer NEW is the same, or a
- subset, of the pointed-to set for pointer ORIG. If this
- isn't the case, we shouldn't have been able to do the
- propagation of NEW into ORIG. */
- gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
- orig_ptr_info->pt_vars));
- }
+ /* Note that pointer NEW and ORIG may actually have different
+ pointed-to variables (e.g., PR 18291 represented in
+ testsuite/gcc.c-torture/compile/pr18291.c). However, since
+ NEW is being copy-propagated into ORIG, it must always be
+ true that the pointed-to set for pointer NEW is the same, or
+ a subset, of the pointed-to set for pointer ORIG. If this
+ isn't the case, we shouldn't have been able to do the
+ propagation of NEW into ORIG. */
+ if (orig_ptr_info->name_mem_tag
+ && new_ptr_info->name_mem_tag
+ && orig_ptr_info->pt_vars
+ && new_ptr_info->pt_vars)
+ gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
+ orig_ptr_info->pt_vars));
}
}