diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-22 20:41:31 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-22 20:41:31 +0000 |
commit | 2a3ebafa45c591f2c37dcc249816c71c7930245b (patch) | |
tree | 591b8d105b3bc5fac1ff8aabd16a58458d55aece /gcc | |
parent | 59082b2ef2ef2aa4ae3487861a6dc80e4ceab57a (diff) | |
download | gcc-2a3ebafa45c591f2c37dcc249816c71c7930245b.tar.gz |
2009-05-22 Richard Guenther <rguenther@suse.de>
PR middle-end/38964
* alias.c (write_dependence_p): Do not use TBAA for answering
anti-dependence or output-dependence.
* tree-ssa-structalias.c (set_uids_in_ptset): Remove TBAA pruning
code.
(emit_pointer_definition): Remove.
(emit_alias_warning): Likewise.
(find_what_var_points_to): Remove TBAA pruning code.
(find_what_p_points_to): Likewise. Do not warn about strict-aliasing
violations.
(compute_points_to_sets): Remove code computing the set of
dereferenced pointers.
* tree-data-ref.c (dr_may_alias_p): Properly use the split
oracle for querying anti and output dependencies.
* tree-ssa-alias.c (refs_may_alias_p_1): Add argument specifying
if TBAA may be applied.
(refs_anti_dependent_p): New function.
(refs_output_dependent_p): Likewise.
* tree-ssa-alias.h (refs_anti_dependent_p): Declare.
(refs_output_dependent_p): Likewise.
* doc/tree-ssa.texi (Memory model): New section.
testsuite/
* g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C: XFAIL.
* gcc.dg/Wstrict-aliasing-converted-assigned.c: Likewise.
* gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: Likewise.
* doc/c-tree.texi (CHANGE_DYNAMIC_TYPE_EXPR): Remove.
* doc/gimple.texi (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove.
* cfgexpand.c (expand_gimple_basic_block): Do not handle
GIMPLE_CHANGE_DYNAMIC_TYPE or CHANGE_DYNAMIC_TYPE_EXPR.
* expr.c (expand_expr_real_1): Likewise.
* gimple-low.c (lower_stmt): Likewise.
* gimple-pretty-print.c (dump_gimple_stmt): Likewise.
(dump_gimple_cdt): Remove.
* gimple.c (gss_for_code): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE.
(gimple_size): Likewise.
(walk_gimple_op): Likewise.
(is_gimple_stmt): Likewise.
(walk_stmt_load_store_addr_ops): Likewise.
(gimple_build_cdt): Remove.
* gimple.def (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove.
* gimple.h (gimple_cdt_new_type): Remove.
(gimple_cdt_new_type_ptr): Likewise.
(gimple_cdt_set_new_type): Likewise.
(gimple_cdt_location): Likewise.
(gimple_cdt_location_ptr): Likewise.
(gimple_cdt_set_location): Likewise.
* gimplify.c (gimplify_expr): Do not handle CHANGE_DYNAMIC_TYPE_EXPR.
* tree-cfg.c (remove_useless_stmts_1): Do not handle
GIMPLE_CHANGE_DYNAMIC_TYPE.
(verify_types_in_gimple_stmt): Likewise.
* tree-inline.c (estimate_num_insns): Likewise.
(expand_call_inline): Do not copy DECL_NO_TBAA_P.
(copy_decl_to_var): Likewise.
(copy_result_decl_to_var): Likewise.
* tree-pretty-print.c (dump_generic_node): Do not handle
CHANGE_DYNAMIC_TYPE_EXPR.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-structalias.c (struct variable_info): Remove
no_tbaa_pruning member.
(new_var_info): Do not set it based on DECL_NO_TBAA_P.
(unify_nodes): Do not copy it.
(find_func_aliases): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE.
(dump_solution_for_var): Do not dump no_tbaa_pruning state.
(set_uids_in_ptset): Do not check it.
(find_what_var_points_to): Likewise.
(compute_tbaa_pruning): Remove.
(compute_points_to_sets): Do not call it.
* tree.c (walk_tree_1): Do not handle CHANGE_DYNAMIC_TYPE_EXPR.
* tree.def (CHANGE_DYNAMIC_TYPE_EXPR): Remove.
* tree.h (CHANGE_DYNAMIC_TYPE_NEW_TYPE): Remove.
(CHANGE_DYNAMIC_TYPE_LOCATION): Likewise.
(DECL_NO_TBAA_P): Likewise.
(struct tree_decl_common): Move no_tbaa_flag to unused flags section.
* omp-low.c (copy_var_decl): Do not copy DECL_NO_TBAA_P.
(expand_omp_atomic_pipeline): Do not set it.
* print-tree.c (print_node): Do not dump it.
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Remove
redundant check.
cp/
* init.c (avoid_placement_new_aliasing): Remove.
(build_new_1): Do not call it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147805 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
34 files changed, 198 insertions, 713 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45778026483..32c00a6102d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,81 @@ +2009-05-22 Richard Guenther <rguenther@suse.de> + + PR middle-end/38964 + * alias.c (write_dependence_p): Do not use TBAA for answering + anti-dependence or output-dependence. + * tree-ssa-structalias.c (set_uids_in_ptset): Remove TBAA pruning + code. + (emit_pointer_definition): Remove. + (emit_alias_warning): Likewise. + (find_what_var_points_to): Remove TBAA pruning code. + (find_what_p_points_to): Likewise. Do not warn about strict-aliasing + violations. + (compute_points_to_sets): Remove code computing the set of + dereferenced pointers. + * tree-data-ref.c (dr_may_alias_p): Properly use the split + oracle for querying anti and output dependencies. + * tree-ssa-alias.c (refs_may_alias_p_1): Add argument specifying + if TBAA may be applied. + (refs_anti_dependent_p): New function. + (refs_output_dependent_p): Likewise. + * tree-ssa-alias.h (refs_anti_dependent_p): Declare. + (refs_output_dependent_p): Likewise. + * doc/tree-ssa.texi (Memory model): New section. + * doc/c-tree.texi (CHANGE_DYNAMIC_TYPE_EXPR): Remove. + * doc/gimple.texi (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove. + * cfgexpand.c (expand_gimple_basic_block): Do not handle + GIMPLE_CHANGE_DYNAMIC_TYPE or CHANGE_DYNAMIC_TYPE_EXPR. + * expr.c (expand_expr_real_1): Likewise. + * gimple-low.c (lower_stmt): Likewise. + * gimple-pretty-print.c (dump_gimple_stmt): Likewise. + (dump_gimple_cdt): Remove. + * gimple.c (gss_for_code): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE. + (gimple_size): Likewise. + (walk_gimple_op): Likewise. + (is_gimple_stmt): Likewise. + (walk_stmt_load_store_addr_ops): Likewise. + (gimple_build_cdt): Remove. + * gimple.def (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove. + * gimple.h (gimple_cdt_new_type): Remove. + (gimple_cdt_new_type_ptr): Likewise. + (gimple_cdt_set_new_type): Likewise. + (gimple_cdt_location): Likewise. + (gimple_cdt_location_ptr): Likewise. + (gimple_cdt_set_location): Likewise. + * gimplify.c (gimplify_expr): Do not handle CHANGE_DYNAMIC_TYPE_EXPR. + * tree-cfg.c (remove_useless_stmts_1): Do not handle + GIMPLE_CHANGE_DYNAMIC_TYPE. + (verify_types_in_gimple_stmt): Likewise. + * tree-inline.c (estimate_num_insns): Likewise. + (expand_call_inline): Do not copy DECL_NO_TBAA_P. + (copy_decl_to_var): Likewise. + (copy_result_decl_to_var): Likewise. + * tree-pretty-print.c (dump_generic_node): Do not handle + CHANGE_DYNAMIC_TYPE_EXPR. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise. + * tree-ssa-operands.c (get_expr_operands): Likewise. + * tree-ssa-structalias.c (struct variable_info): Remove + no_tbaa_pruning member. + (new_var_info): Do not set it based on DECL_NO_TBAA_P. + (unify_nodes): Do not copy it. + (find_func_aliases): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE. + (dump_solution_for_var): Do not dump no_tbaa_pruning state. + (set_uids_in_ptset): Do not check it. + (find_what_var_points_to): Likewise. + (compute_tbaa_pruning): Remove. + (compute_points_to_sets): Do not call it. + * tree.c (walk_tree_1): Do not handle CHANGE_DYNAMIC_TYPE_EXPR. + * tree.def (CHANGE_DYNAMIC_TYPE_EXPR): Remove. + * tree.h (CHANGE_DYNAMIC_TYPE_NEW_TYPE): Remove. + (CHANGE_DYNAMIC_TYPE_LOCATION): Likewise. + (DECL_NO_TBAA_P): Likewise. + (struct tree_decl_common): Move no_tbaa_flag to unused flags section. + * omp-low.c (copy_var_decl): Do not copy DECL_NO_TBAA_P. + (expand_omp_atomic_pipeline): Do not set it. + * print-tree.c (print_node): Do not dump it. + * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Remove + redundant check. + 2009-05-22 Vladimir Makarov <vmakarov@redhat.com> PR target/39856 diff --git a/gcc/alias.c b/gcc/alias.c index 18d5b747cb0..4d42778a644 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -2373,9 +2373,6 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) return 1; - if (DIFFERENT_ALIAS_SETS_P (x, mem)) - return 0; - /* A read from read-only memory can't conflict with read-write memory. */ if (!writep && MEM_READONLY_P (mem)) return 0; diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index ab9464fdcb5..65a13de8a3d 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2100,7 +2100,7 @@ expand_gimple_basic_block (basic_block bb) return new_bb; } } - else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE) + else { def_operand_p def_p; tree stmt_tree; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c876a17c23b..aeab9a15803 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-05-22 Richard Guenther <rguenther@suse.de> + + PR middle-end/38964 + * init.c (avoid_placement_new_aliasing): Remove. + (build_new_1): Do not call it. + 2009-05-22 Mark Mitchell <mark@codesourcery.com> * decl2.c (decl_needed_p): Consider dllexport'd functions needed. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index fd0d587b81f..25cfd52fcdf 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1742,55 +1742,6 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts, return new_expr; } -/* Make sure that there are no aliasing issues with T, a placement new - expression applied to PLACEMENT, by recording the change in dynamic - type. If placement new is inlined, as it is with libstdc++, and if - the type of the placement new differs from the type of the - placement location itself, then alias analysis may think it is OK - to interchange writes to the location from before the placement new - and from after the placement new. We have to prevent type-based - alias analysis from applying. PLACEMENT may be NULL, which means - that we couldn't capture it in a temporary variable, in which case - we use a memory clobber. */ - -static tree -avoid_placement_new_aliasing (tree t, tree placement) -{ - tree type_change; - - if (processing_template_decl) - return t; - - /* If we are not using type based aliasing, we don't have to do - anything. */ - if (!flag_strict_aliasing) - return t; - - /* If we have a pointer and a location, record the change in dynamic - type. Otherwise we need a general memory clobber. */ - if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE - && placement != NULL_TREE - && TREE_CODE (TREE_TYPE (placement)) == POINTER_TYPE) - type_change = build_stmt (CHANGE_DYNAMIC_TYPE_EXPR, - TREE_TYPE (t), - placement); - else - { - /* Build a memory clobber. */ - type_change = build_stmt (ASM_EXPR, - build_string (0, ""), - NULL_TREE, - NULL_TREE, - tree_cons (NULL_TREE, - build_string (6, "memory"), - NULL_TREE)); - - ASM_VOLATILE_P (type_change) = 1; - } - - return build2 (COMPOUND_EXPR, TREE_TYPE (t), type_change, t); -} - /* Generate code for a new-expression, including calling the "operator new" function, initializing the object, and, if an exception occurs during construction, cleaning up. The arguments are as for @@ -1826,7 +1777,6 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, beginning of the storage allocated for an array-new expression in order to store the number of elements. */ tree cookie_size = NULL_TREE; - bool have_placement; tree placement_first; tree placement_expr = NULL_TREE; /* True if the function we are calling is a placement allocation @@ -1894,7 +1844,6 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* If PLACEMENT is a single simple pointer type not passed by reference, prepare to capture it in a temporary variable. Do this now, since PLACEMENT will change in the calls below. */ - have_placement = !VEC_empty (tree, *placement); placement_first = NULL_TREE; if (VEC_length (tree, *placement) == 1 && (TREE_CODE (TREE_TYPE (VEC_index (tree, *placement, 0))) @@ -2026,12 +1975,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* In the simple case, we can stop now. */ pointer_type = build_pointer_type (type); if (!cookie_size && !is_initialized) - { - rval = build_nop (pointer_type, alloc_call); - if (have_placement) - rval = avoid_placement_new_aliasing (rval, placement_expr); - return rval; - } + return build_nop (pointer_type, alloc_call); /* Store the result of the allocation call in a variable so that we can use it more than once. */ @@ -2307,9 +2251,6 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* A new-expression is never an lvalue. */ gcc_assert (!lvalue_p (rval)); - if (have_placement) - rval = avoid_placement_new_aliasing (rval, placement_expr); - return rval; } diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi index 117b700ec08..35498583ccd 100644 --- a/gcc/doc/c-tree.texi +++ b/gcc/doc/c-tree.texi @@ -1995,7 +1995,6 @@ This macro returns the attributes on the type @var{type}. @tindex TARGET_EXPR @tindex AGGR_INIT_EXPR @tindex VA_ARG_EXPR -@tindex CHANGE_DYNAMIC_TYPE_EXPR @tindex OMP_PARALLEL @tindex OMP_FOR @tindex OMP_SECTIONS @@ -2708,13 +2707,6 @@ mechanism. It represents expressions like @code{va_arg (ap, type)}. Its @code{TREE_TYPE} yields the tree representation for @code{type} and its sole argument yields the representation for @code{ap}. -@item CHANGE_DYNAMIC_TYPE_EXPR -Indicates the special aliasing required by C++ placement new. It has -two operands: a type and a location. It means that the dynamic type -of the location is changing to be the specified type. The alias -analysis code takes this into account when doing type based alias -analysis. - @item OMP_PARALLEL Represents @code{#pragma omp parallel [clause1 @dots{} clauseN]}. It diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi index cc1e8903fdb..a78c52dcafc 100644 --- a/gcc/doc/gimple.texi +++ b/gcc/doc/gimple.texi @@ -332,14 +332,13 @@ union gimple_statement_d The following table briefly describes the GIMPLE instruction set. -@multitable {@code{GIMPLE_CHANGE_DYNAMIC_TYPE}} {High GIMPLE} {Low GIMPLE} +@multitable {@code{GIMPLE_OMP_SECTIONS_SWITCH}} {High GIMPLE} {Low GIMPLE} @item Instruction @tab High GIMPLE @tab Low GIMPLE @item @code{GIMPLE_ASM} @tab x @tab x @item @code{GIMPLE_ASSIGN} @tab x @tab x @item @code{GIMPLE_BIND} @tab x @tab @item @code{GIMPLE_CALL} @tab x @tab x @item @code{GIMPLE_CATCH} @tab x @tab -@item @code{GIMPLE_CHANGE_DYNAMIC_TYPE} @tab x @tab x @item @code{GIMPLE_COND} @tab x @tab x @item @code{GIMPLE_EH_FILTER} @tab x @tab @item @code{GIMPLE_GOTO} @tab x @tab x @@ -885,7 +884,6 @@ Return a deep copy of statement @code{STMT}. * @code{GIMPLE_BIND}:: * @code{GIMPLE_CALL}:: * @code{GIMPLE_CATCH}:: -* @code{GIMPLE_CHANGE_DYNAMIC_TYPE}:: * @code{GIMPLE_COND}:: * @code{GIMPLE_EH_FILTER}:: * @code{GIMPLE_LABEL}:: @@ -1295,45 +1293,6 @@ Set @code{T} to be the set of types handled by @code{GIMPLE_CATCH} @code{G}. Set @code{HANDLER} to be the body of @code{GIMPLE_CATCH} @code{G}. @end deftypefn -@node @code{GIMPLE_CHANGE_DYNAMIC_TYPE} -@subsection @code{GIMPLE_CHANGE_DYNAMIC_TYPE} -@cindex @code{GIMPLE_CHANGE_DYNAMIC_TYPE} - -@deftypefn {GIMPLE function} gimple gimple_build_cdt (tree type, tree ptr) -Build a @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement. @code{TYPE} is the new -type for the location @code{PTR}. -@end deftypefn - -@deftypefn {GIMPLE function} tree gimple_cdt_new_type (gimple g) -Return the new type set by @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement -@code{G}. -@end deftypefn - -@deftypefn {GIMPLE function} tree *gimple_cdt_new_type_ptr (gimple g) -Return a pointer to the new type set by -@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}. -@end deftypefn - -@deftypefn {GIMPLE function} void gimple_cdt_set_new_type (gimple g, tree new_type) -Set @code{NEW_TYPE} to be the type returned by -@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}. -@end deftypefn - -@deftypefn {GIMPLE function} tree gimple_cdt_location (gimple g) -Return the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE} -statement @code{G}. -@end deftypefn - -@deftypefn {GIMPLE function} tree *gimple_cdt_location_ptr (gimple g) -Return a pointer to the location affected by -@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}. -@end deftypefn - -@deftypefn {GIMPLE function} void gimple_cdt_set_location (gimple g, tree ptr) -Set @code{PTR} to be the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE} -statement @code{G}. -@end deftypefn - @node @code{GIMPLE_COND} @subsection @code{GIMPLE_COND} diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi index 1442ce6f5b5..ebb85a05769 100644 --- a/gcc/doc/tree-ssa.texi +++ b/gcc/doc/tree-ssa.texi @@ -41,6 +41,7 @@ passes for GIMPLE@. * SSA Operands:: SSA names referenced by GIMPLE statements. * SSA:: Static Single Assignment representation. * Alias analysis:: Representing aliased loads and stores. +* Memory model:: Memory model used by the middle-end. @end menu @node Annotations @@ -892,3 +893,31 @@ providing its aliasing VDEF. The walk stops if asked to. @end enumerate + +@node Memory model +@section Memory model +@cindex memory model + +The memory model used by the middle-end models that of the C/C++ +languages. The middle-end has the notion of an effective type +of a memory region which is used for type-based alias analysis. + +The following is a refinement of ISO C99 6.5/6, clarifying the block copy case +to follow common sense and extending the concept of a dynamic effective +type to objects with a declared type as required for C++. + +@smallexample +The effective type of an object for an access to its stored value is +the declared type of the object or the effective type determined by +a previous store to it. If a value is stored into an object through +an lvalue having a type that is not a character type, then the +type of the lvalue becomes the effective type of the object for that +access and for subsequent accesses that do not modify the stored value. +If a value is copied into an object using @code{memcpy} or @code{memmove}, +or is copied as an array of character type, then the effective type +of the modified object for that access and for subsequent accesses that +do not modify the value is undetermined. For all other accesses to an +object, the effective type of the object is simply the type of the +lvalue used for the access. +@end smallexample + diff --git a/gcc/expr.c b/gcc/expr.c index 73fde710d80..c2524f2ead5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9298,13 +9298,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Lowered by gimplify.c. */ gcc_unreachable (); - case CHANGE_DYNAMIC_TYPE_EXPR: - /* This is ignored at the RTL level. The tree level set - DECL_POINTER_ALIAS_SET of any variable to be 0, which is - overkill for the RTL layer but is all that we can - represent. */ - return const0_rtx; - case EXC_PTR_EXPR: return get_exception_pointer (); diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 02a1ce63549..42bf9b11ea9 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -368,7 +368,6 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) case GIMPLE_PREDICT: case GIMPLE_LABEL: case GIMPLE_SWITCH: - case GIMPLE_CHANGE_DYNAMIC_TYPE: case GIMPLE_OMP_FOR: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTIONS_SWITCH: diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 163acf9c065..ec366f86f42 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1324,27 +1324,6 @@ dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc, } } -/* Dump a GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. BUFFER, SPC and - FLAGS are as in dump_gimple_stmt. */ - -static void -dump_gimple_cdt (pretty_printer *buffer, gimple gs, int spc, int flags) -{ - if (flags & TDF_RAW) - dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs, - gimple_cdt_new_type (gs), gimple_cdt_location (gs)); - else - { - pp_string (buffer, "<<<change_dynamic_type ("); - dump_generic_node (buffer, gimple_cdt_new_type (gs), spc + 2, flags, - false); - pp_string (buffer, ") "); - dump_generic_node (buffer, gimple_cdt_location (gs), spc + 2, flags, - false); - pp_string (buffer, ")>>>"); - } -} - /* Dump all the memory operands for statement GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */ @@ -1508,10 +1487,6 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags) dump_gimple_omp_critical (buffer, gs, spc, flags); break; - case GIMPLE_CHANGE_DYNAMIC_TYPE: - dump_gimple_cdt (buffer, gs, spc, flags); - break; - case GIMPLE_CATCH: dump_gimple_catch (buffer, gs, spc, flags); break; diff --git a/gcc/gimple.c b/gcc/gimple.c index d81c3f35551..703236691f7 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -102,7 +102,6 @@ gss_for_code (enum gimple_code code) case GIMPLE_COND: case GIMPLE_GOTO: case GIMPLE_LABEL: - case GIMPLE_CHANGE_DYNAMIC_TYPE: case GIMPLE_SWITCH: return GSS_WITH_OPS; case GIMPLE_ASM: return GSS_ASM; case GIMPLE_BIND: return GSS_BIND; @@ -190,8 +189,6 @@ gimple_size (enum gimple_code code) return sizeof (struct gimple_statement_omp_atomic_store); case GIMPLE_WITH_CLEANUP_EXPR: return sizeof (struct gimple_statement_wce); - case GIMPLE_CHANGE_DYNAMIC_TYPE: - return sizeof (struct gimple_statement_with_ops); case GIMPLE_PREDICT: return sizeof (struct gimple_statement_base); default: @@ -1042,20 +1039,6 @@ gimple_build_omp_single (gimple_seq body, tree clauses) } -/* Build a GIMPLE_CHANGE_DYNAMIC_TYPE statement. TYPE is the new type - for the location PTR. */ - -gimple -gimple_build_cdt (tree type, tree ptr) -{ - gimple p = gimple_build_with_ops (GIMPLE_CHANGE_DYNAMIC_TYPE, ERROR_MARK, 2); - gimple_cdt_set_new_type (p, type); - gimple_cdt_set_location (p, ptr); - - return p; -} - - /* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */ gimple @@ -1460,16 +1443,6 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op, return ret; break; - case GIMPLE_CHANGE_DYNAMIC_TYPE: - ret = walk_tree (gimple_cdt_location_ptr (stmt), callback_op, wi, pset); - if (ret) - return ret; - - ret = walk_tree (gimple_cdt_new_type_ptr (stmt), callback_op, wi, pset); - if (ret) - return ret; - break; - case GIMPLE_ASM: ret = walk_gimple_asm (stmt, callback_op, wi); if (ret) @@ -2749,7 +2722,6 @@ is_gimple_stmt (tree t) case TRY_FINALLY_EXPR: case EH_FILTER_EXPR: case CATCH_EXPR: - case CHANGE_DYNAMIC_TYPE_EXPR: case ASM_EXPR: case RESX_EXPR: case STATEMENT_LIST: @@ -3254,8 +3226,7 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data, } else if (visit_addr && (is_gimple_assign (stmt) - || gimple_code (stmt) == GIMPLE_COND - || gimple_code (stmt) == GIMPLE_CHANGE_DYNAMIC_TYPE)) + || gimple_code (stmt) == GIMPLE_COND)) { for (i = 0; i < gimple_num_ops (stmt); ++i) if (gimple_op (stmt, i) diff --git a/gcc/gimple.def b/gcc/gimple.def index 26aa719f660..cee6753d200 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -78,17 +78,6 @@ DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops) They must be CASE_LABEL_EXPR nodes. */ DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops) -/* GIMPLE_CHANGE_DYNAMIC_TYPE indicates a change in the dynamic type - of a memory location. This has no value and generates no - executable code. It is only used for type based alias analysis. - This is generated by C++ placement new and it's a direct - translation from CHANGE_DYNAMIC_TYPE_EXPR. The first operand - (gimple_cdt_new_type) is the new type. The second operand - (gimple_cdt_location) is the location (pointer) whose type is being - changed. */ -DEFGSCODE(GIMPLE_CHANGE_DYNAMIC_TYPE, "gimple_change_dynamic_type", - struct gimple_statement_with_ops) - /* IMPORTANT. Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN. diff --git a/gcc/gimple.h b/gcc/gimple.h index ffcf9aa95ae..b16fb545028 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -4106,69 +4106,6 @@ gimple_nop_p (const_gimple g) } -/* Return the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */ - -static inline tree -gimple_cdt_new_type (gimple gs) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - return gimple_op (gs, 1); -} - -/* Return a pointer to the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE - statement GS. */ - -static inline tree * -gimple_cdt_new_type_ptr (gimple gs) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - return gimple_op_ptr (gs, 1); -} - -/* Set NEW_TYPE to be the type returned by GIMPLE_CHANGE_DYNAMIC_TYPE - statement GS. */ - -static inline void -gimple_cdt_set_new_type (gimple gs, tree new_type) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - gcc_assert (TREE_CODE_CLASS (TREE_CODE (new_type)) == tcc_type); - gimple_set_op (gs, 1, new_type); -} - - -/* Return the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */ - -static inline tree -gimple_cdt_location (gimple gs) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - return gimple_op (gs, 0); -} - - -/* Return a pointer to the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE - statement GS. */ - -static inline tree * -gimple_cdt_location_ptr (gimple gs) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - return gimple_op_ptr (gs, 0); -} - - -/* Set PTR to be the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE - statement GS. */ - -static inline void -gimple_cdt_set_location (gimple gs, tree ptr) -{ - GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE); - gimple_set_op (gs, 0, ptr); -} - - /* Return the predictor of GIMPLE_PREDICT statement GS. */ static inline enum br_predictor diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d734a0fdf08..073fda0005b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -6856,19 +6856,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, break; } - case CHANGE_DYNAMIC_TYPE_EXPR: - { - gimple cdt; - - ret = gimplify_expr (&CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p), - pre_p, post_p, is_gimple_reg, fb_lvalue); - cdt = gimple_build_cdt (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*expr_p), - CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p)); - gimplify_seq_add_stmt (pre_p, cdt); - ret = GS_ALL_DONE; - } - break; - case OBJ_TYPE_REF: { enum gimplify_status r0, r1; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 5a25e95c33a..1a4aea9b37b 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -812,7 +812,6 @@ copy_var_decl (tree var, tree name, tree type) TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var); TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var); DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var); - DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var); DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); DECL_CONTEXT (copy) = DECL_CONTEXT (var); @@ -5010,7 +5009,6 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, false, NULL_TREE, true, GSI_SAME_STMT); stmt = gimple_build_assign (iaddr, iaddr_val); gsi_insert_before (&si, stmt, GSI_SAME_STMT); - DECL_NO_TBAA_P (iaddr) = 1; DECL_POINTER_ALIAS_SET (iaddr) = 0; loadedi = create_tmp_var (itype, NULL); if (gimple_in_ssa_p (cfun)) diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 0d352642157..969c6ea4ba7 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -425,8 +425,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent) fputs (" virtual", file); if (DECL_PRESERVE_P (node)) fputs (" preserve", file); - if (DECL_NO_TBAA_P (node)) - fputs (" no-tbaa", file); if (DECL_LANG_FLAG_0 (node)) fputs (" decl_0", file); if (DECL_LANG_FLAG_1 (node)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d38e47fd68..ed045442dd3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-05-22 Richard Guenther <rguenther@suse.de> + + PR middle-end/38964 + * g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C: XFAIL. + * gcc.dg/Wstrict-aliasing-converted-assigned.c: Likewise. + * gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: Likewise. + 2009-05-22 Mark Mitchell <mark@codesourcery.com> * gcc.dg/dll-6.c: New test. diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C index d88ed4314b3..8b82874f51d 100644 --- a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C @@ -4,8 +4,8 @@ int foo() { int x; - float& q = reinterpret_cast<float&> (x); /* { dg-message "initialized" } */ - q = 1.0; /* { dg-warning "does break strict-aliasing" } */ + float& q = reinterpret_cast<float&> (x); /* { dg-message "initialized" "" { xfail *-*-* } } */ + q = 1.0; /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */ return x; } diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c index 1fef7947c9b..b77373d56bd 100644 --- a/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c +++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c @@ -9,5 +9,5 @@ int foo() return i; } -/* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } } 8 } */ -/* { dg-message "initialized" "" { target { *-*-* && lp64 } } 8 } */ +/* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */ +/* { dg-message "initialized" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */ diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c index fccc178d224..b90fb76c28b 100644 --- a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c +++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c @@ -11,12 +11,12 @@ int foo() { float* r; if (flag) { - q = (float*) &x; /* { dg-message "initialized" } */ + q = (float*) &x; /* { dg-message "initialized" "" { xfail *-*-* } } */ } else { - q = (float*) &y; /* { dg-message "initialized" } */ + q = (float*) &y; /* { dg-message "initialized" "" { xfail *-*-* } } */ } - *q = 1.0; /* { dg-warning "does break strict-aliasing" } */ + *q = 1.0; /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */ return x; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 68d6f5b1c13..17cee626cb8 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2045,18 +2045,6 @@ remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *data) } break; - case GIMPLE_CHANGE_DYNAMIC_TYPE: - /* If we do not optimize remove GIMPLE_CHANGE_DYNAMIC_TYPE as - expansion is confused about them and we only remove them - during alias computation otherwise. */ - if (!optimize) - { - data->last_was_goto = false; - gsi_remove (gsi, false); - break; - } - /* Fallthru. */ - default: data->last_was_goto = false; gsi_next (gsi); @@ -4038,10 +4026,6 @@ verify_types_in_gimple_stmt (gimple stmt) case GIMPLE_ASM: return false; - case GIMPLE_CHANGE_DYNAMIC_TYPE: - return (!is_gimple_val (gimple_cdt_location (stmt)) - || !POINTER_TYPE_P (TREE_TYPE (gimple_cdt_location (stmt)))); - case GIMPLE_PHI: return verify_gimple_phi (stmt); diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index de2ad5f921b..583d2c0fd9e 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1223,7 +1223,17 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b) return false; /* Query the alias oracle. */ - if (!refs_may_alias_p (DR_REF (a), DR_REF (b))) + if (!DR_IS_READ (a) && !DR_IS_READ (b)) + { + if (!refs_output_dependent_p (DR_REF (a), DR_REF (b))) + return false; + } + else if (DR_IS_READ (a) && !DR_IS_READ (b)) + { + if (!refs_anti_dependent_p (DR_REF (a), DR_REF (b))) + return false; + } + else if (!refs_may_alias_p (DR_REF (a), DR_REF (b))) return false; if (!addr_a || !addr_b) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 78cb716d7ad..1b53288bca3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3072,7 +3072,6 @@ estimate_num_insns (gimple stmt, eni_weights *weights) case GIMPLE_NOP: case GIMPLE_PHI: case GIMPLE_RETURN: - case GIMPLE_CHANGE_DYNAMIC_TYPE: case GIMPLE_PREDICT: return 0; @@ -3429,13 +3428,6 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* Declare the return variable for the function. */ retvar = declare_return_variable (id, return_slot, modify_dest, &use_retvar); - if (DECL_IS_OPERATOR_NEW (fn)) - { - gcc_assert (TREE_CODE (retvar) == VAR_DECL - && POINTER_TYPE_P (TREE_TYPE (retvar))); - DECL_NO_TBAA_P (retvar) = 1; - } - /* Add local vars in this inlined callee to caller. */ t_step = id->src_cfun->local_decls; for (; t_step; t_step = TREE_CHAIN (t_step)) @@ -4192,7 +4184,6 @@ copy_decl_to_var (tree decl, copy_body_data *id) TREE_READONLY (copy) = TREE_READONLY (decl); TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl); DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl); - DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl); return copy_decl_for_dup_finish (id, decl, copy); } @@ -4219,7 +4210,6 @@ copy_result_decl_to_var (tree decl, copy_body_data *id) { TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl); DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl); - DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl); } return copy_decl_for_dup_finish (id, decl, copy); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index d9d31eee79b..af734c118ab 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -1544,17 +1544,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, is_expr = false; break; - case CHANGE_DYNAMIC_TYPE_EXPR: - pp_string (buffer, "<<<change_dynamic_type ("); - dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_NEW_TYPE (node), spc + 2, - flags, false); - pp_string (buffer, ") "); - dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_LOCATION (node), spc + 2, - flags, false); - pp_string (buffer, ")>>>"); - is_expr = false; - break; - case LABEL_EXPR: op0 = TREE_OPERAND (node, 0); /* If this is for break or continue, don't bother printing it. */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 8982280fb2c..ef360ea87d5 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -155,10 +155,13 @@ ptr_deref_may_alias_global_p (tree ptr) if (!pi) return true; + /* ??? This does not use TBAA to prune globals ptr may not access. */ return pt_solution_includes_global (&pi->pt); } -/* Return true if dereferencing PTR may alias DECL. */ +/* Return true if dereferencing PTR may alias DECL. + The caller is responsible for applying TBAA to see if PTR + may access DECL at all. */ static bool ptr_deref_may_alias_decl_p (tree ptr, tree decl) @@ -190,7 +193,9 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl) return pt_solution_includes (&pi->pt, decl); } -/* Return true if dereferenced PTR1 and PTR2 may alias. */ +/* Return true if dereferenced PTR1 and PTR2 may alias. + The caller is responsible for applying TBAA to see if accesses + through PTR1 and PTR2 may conflict at all. */ static bool ptr_derefs_may_alias_p (tree ptr1, tree ptr2) @@ -222,6 +227,8 @@ ptr_derefs_may_alias_p (tree ptr1, tree ptr2) if (!pi1 || !pi2) return true; + /* ??? This does not use TBAA to prune decls from the intersection + that not both pointers may access. */ return pt_solutions_intersect (&pi1->pt, &pi2->pt); } @@ -653,13 +660,14 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1, /* Return true, if the two memory references REF1 and REF2 may alias. */ static bool -refs_may_alias_p_1 (tree ref1, tree ref2) +refs_may_alias_p_1 (tree ref1, tree ref2, bool tbaa_p) { tree base1, base2; HOST_WIDE_INT offset1 = 0, offset2 = 0; HOST_WIDE_INT size1 = -1, size2 = -1; HOST_WIDE_INT max_size1 = -1, max_size2 = -1; bool var1_p, var2_p, ind1_p, ind2_p; + alias_set_type set; gcc_assert ((SSA_VAR_P (ref1) || handled_component_p (ref1) @@ -694,7 +702,8 @@ refs_may_alias_p_1 (tree ref1, tree ref2) base2, offset2, max_size2); /* First defer to TBAA if possible. */ - if (flag_strict_aliasing + if (tbaa_p + && flag_strict_aliasing && !alias_sets_conflict_p (get_alias_set (ref1), get_alias_set (ref2))) return false; @@ -708,21 +717,22 @@ refs_may_alias_p_1 (tree ref1, tree ref2) /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */ ind1_p = INDIRECT_REF_P (base1); ind2_p = INDIRECT_REF_P (base2); + set = tbaa_p ? -1 : 0; if (var1_p && ind2_p) return indirect_ref_may_alias_decl_p (ref2, TREE_OPERAND (base2, 0), - offset2, max_size2, -1, + offset2, max_size2, set, ref1, base1, - offset1, max_size1, -1); + offset1, max_size1, set); else if (ind1_p && var2_p) return indirect_ref_may_alias_decl_p (ref1, TREE_OPERAND (base1, 0), - offset1, max_size1, -1, + offset1, max_size1, set, ref2, base2, - offset2, max_size2, -1); + offset2, max_size2, set); else if (ind1_p && ind2_p) return indirect_refs_may_alias_p (ref1, TREE_OPERAND (base1, 0), - offset1, max_size1, -1, + offset1, max_size1, set, ref2, TREE_OPERAND (base2, 0), - offset2, max_size2, -1); + offset2, max_size2, set); gcc_unreachable (); } @@ -730,7 +740,7 @@ refs_may_alias_p_1 (tree ref1, tree ref2) bool refs_may_alias_p (tree ref1, tree ref2) { - bool res = refs_may_alias_p_1 (ref1, ref2); + bool res = refs_may_alias_p_1 (ref1, ref2, true); if (res) ++alias_stats.refs_may_alias_p_may_alias; else @@ -738,6 +748,23 @@ refs_may_alias_p (tree ref1, tree ref2) return res; } +/* Returns true if there is a anti-dependence for the STORE that + executes after the LOAD. */ + +bool +refs_anti_dependent_p (tree load, tree store) +{ + return refs_may_alias_p_1 (load, store, false); +} + +/* Returns true if there is a output dependence for the stores + STORE1 and STORE2. */ + +bool +refs_output_dependent_p (tree store1, tree store2) +{ + return refs_may_alias_p_1 (store1, store2, false); +} /* If the call CALL may use the memory reference REF return true, otherwise return false. */ diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 5f951ae1625..a7ffcaa683c 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -78,6 +78,8 @@ struct GTY(()) pt_solution extern enum escape_type is_escape_site (gimple); extern bool ptr_deref_may_alias_global_p (tree); extern bool refs_may_alias_p (tree, tree); +extern bool refs_anti_dependent_p (tree, tree); +extern bool refs_output_dependent_p (tree, tree); extern bool ref_maybe_used_by_stmt_p (gimple, tree); extern bool stmt_may_clobber_ref_p (gimple, tree); extern void *walk_non_aliased_vuses (tree, tree, diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index 0ac02bab04c..ed221c2f3e0 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -233,20 +233,6 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) return false; } - /* Don't coalesce if the aliasing sets of the types are different. */ - if (POINTER_TYPE_P (TREE_TYPE (root1)) - && POINTER_TYPE_P (TREE_TYPE (root2)) - && ((get_alias_set (TREE_TYPE (TREE_TYPE (root1))) - != get_alias_set (TREE_TYPE (TREE_TYPE (root2)))) - || (DECL_P (root1) && DECL_P (root2) - && DECL_NO_TBAA_P (root1) != DECL_NO_TBAA_P (root2)))) - { - if (debug) - fprintf (debug, " : 2 different aliasing sets. No coalesce.\n"); - return false; - } - - /* Merge the two partitions. */ p3 = partition_union (map->var_partition, p1, p2); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 0c205710425..38f313daa7d 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -295,7 +295,6 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive) case GIMPLE_ASM: case GIMPLE_RESX: case GIMPLE_RETURN: - case GIMPLE_CHANGE_DYNAMIC_TYPE: mark_stmt_necessary (stmt, true); return; diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 7d588f8eb96..0f8912421a1 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1009,9 +1009,6 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags) return; } - case CHANGE_DYNAMIC_TYPE_EXPR: - gcc_unreachable (); - case FUNCTION_DECL: case LABEL_DECL: case CONST_DECL: diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a27afbf3c88..aa944364e48 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -226,10 +226,6 @@ struct variable_info /* True if this is a heap variable. */ unsigned int is_heap_var:1; - /* True if we may not use TBAA to prune references to this - variable. This is used for C++ placement new. */ - unsigned int no_tbaa_pruning : 1; - /* True if this field may contain pointers. */ unsigned int may_have_pointers : 1; @@ -360,7 +356,6 @@ static varinfo_t new_var_info (tree t, unsigned int id, const char *name) { varinfo_t ret = (varinfo_t) pool_alloc (variable_info_pool); - tree var; ret->id = id; ret->name = name; @@ -371,12 +366,6 @@ new_var_info (tree t, unsigned int id, const char *name) ret->is_unknown_size_var = false; ret->is_full_var = false; ret->may_have_pointers = true; - var = t; - if (TREE_CODE (var) == SSA_NAME) - var = SSA_NAME_VAR (var); - ret->no_tbaa_pruning = (DECL_P (var) - && POINTER_TYPE_P (TREE_TYPE (var)) - && DECL_NO_TBAA_P (var)); ret->solution = BITMAP_ALLOC (&pta_obstack); ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack); ret->next = NULL; @@ -1425,9 +1414,6 @@ unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from, merge_graph_nodes (graph, to, from); merge_node_constraints (graph, to, from); - if (get_varinfo (from)->no_tbaa_pruning) - get_varinfo (to)->no_tbaa_pruning = true; - /* Mark TO as changed if FROM was changed. If TO was already marked as changed, decrease the changed count. */ @@ -3725,14 +3711,6 @@ find_func_aliases (gimple origt) } } } - else if (gimple_code (t) == GIMPLE_CHANGE_DYNAMIC_TYPE) - { - unsigned int j; - - get_constraint_for (gimple_cdt_location (t), &lhsc); - for (j = 0; VEC_iterate (ce_s, lhsc, j, c); ++j) - get_varinfo (c->var)->no_tbaa_pruning = true; - } stmt_escape_type = is_escape_site (t); if (stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) @@ -4444,10 +4422,7 @@ dump_solution_for_var (FILE *file, unsigned int var) { fprintf (file, "%s ", get_varinfo (i)->name); } - fprintf (file, "}"); - if (vi->no_tbaa_pruning) - fprintf (file, " no-tbaa-pruning"); - fprintf (file, "\n"); + fprintf (file, "}\n"); } } @@ -4628,19 +4603,13 @@ shared_bitmap_add (bitmap pt_vars) } -/* Set bits in INTO corresponding to the variable uids in solution set FROM. - If MEM_ALIAS_SET is not zero, we also use type based alias analysis to - prune the points-to sets with this alias-set. - Returns the number of pruned variables and updates the vars_contains_global - member of *PT . */ +/* Set bits in INTO corresponding to the variable uids in solution set FROM. */ -static unsigned -set_uids_in_ptset (bitmap into, bitmap from, - alias_set_type mem_alias_set, struct pt_solution *pt) +static void +set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt) { unsigned int i; bitmap_iterator bi; - unsigned pruned = 0; EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi) { @@ -4655,22 +4624,6 @@ set_uids_in_ptset (bitmap into, bitmap from, || TREE_CODE (vi->decl) == PARM_DECL || TREE_CODE (vi->decl) == RESULT_DECL) { - /* Don't type prune artificial vars or points-to sets - for pointers that have not been dereferenced or with - type-based pruning disabled. */ - if (!vi->is_artificial_var - && !vi->no_tbaa_pruning - && mem_alias_set != 0) - { - alias_set_type var_alias_set = get_alias_set (vi->decl); - if (mem_alias_set != var_alias_set - && !alias_set_subset_of (mem_alias_set, var_alias_set)) - { - ++pruned; - continue; - } - } - /* Add the decl to the points-to set. Note that the points-to set contains global variables. */ bitmap_set_bit (into, DECL_UID (vi->decl)); @@ -4678,113 +4631,21 @@ set_uids_in_ptset (bitmap into, bitmap from, pt->vars_contains_global = true; } } - - return pruned; } static bool have_alias_info = false; -/* Emit a note for the pointer initialization point DEF. */ +/* Compute the points-to solution *PT for the variable VI. */ static void -emit_pointer_definition (tree ptr, bitmap visited) +find_what_var_points_to (varinfo_t vi, struct pt_solution *pt) { - gimple def = SSA_NAME_DEF_STMT (ptr); - if (gimple_code (def) == GIMPLE_PHI) - { - use_operand_p argp; - ssa_op_iter oi; - - FOR_EACH_PHI_ARG (argp, def, oi, SSA_OP_USE) - { - tree arg = USE_FROM_PTR (argp); - if (TREE_CODE (arg) == SSA_NAME) - { - if (bitmap_set_bit (visited, SSA_NAME_VERSION (arg))) - emit_pointer_definition (arg, visited); - } - else - inform (0, "initialized from %qE", arg); - } - } - else if (!gimple_nop_p (def)) - inform (gimple_location (def), "initialized from here"); -} - -/* Emit a strict aliasing warning for dereferencing the pointer PTR. */ - -static void -emit_alias_warning (tree ptr) -{ - gimple use; - imm_use_iterator ui; - bool warned = false; - - FOR_EACH_IMM_USE_STMT (use, ui, ptr) - { - tree deref = NULL_TREE; - - if (gimple_has_lhs (use)) - { - tree lhs = get_base_address (gimple_get_lhs (use)); - if (lhs - && INDIRECT_REF_P (lhs) - && TREE_OPERAND (lhs, 0) == ptr) - deref = lhs; - } - if (gimple_assign_single_p (use)) - { - tree rhs = get_base_address (gimple_assign_rhs1 (use)); - if (rhs - && INDIRECT_REF_P (rhs) - && TREE_OPERAND (rhs, 0) == ptr) - deref = rhs; - } - else if (is_gimple_call (use)) - { - unsigned i; - for (i = 0; i < gimple_call_num_args (use); ++i) - { - tree op = get_base_address (gimple_call_arg (use, i)); - if (op - && INDIRECT_REF_P (op) - && TREE_OPERAND (op, 0) == ptr) - deref = op; - } - } - if (deref - && !TREE_NO_WARNING (deref)) - { - TREE_NO_WARNING (deref) = 1; - warned |= warning_at (gimple_location (use), OPT_Wstrict_aliasing, - "dereferencing pointer %qD does break " - "strict-aliasing rules", SSA_NAME_VAR (ptr)); - } - } - if (warned) - { - bitmap visited = BITMAP_ALLOC (NULL); - emit_pointer_definition (ptr, visited); - BITMAP_FREE (visited); - } -} - -/* Compute the points-to solution *PT for the variable VI. - Prunes the points-to set based on TBAA rules if DO_TBAA_PRUNING - is true. Returns the number of TBAA pruned variables from the - points-to set. */ - -static unsigned int -find_what_var_points_to (varinfo_t vi, struct pt_solution *pt, - bool do_tbaa_pruning) -{ - unsigned int i, pruned; + unsigned int i; bitmap_iterator bi; bitmap finished_solution; bitmap result; tree ptr = vi->decl; - alias_set_type mem_alias_set; memset (pt, 0, sizeof (struct pt_solution)); @@ -4821,7 +4682,7 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt, /* Instead of doing extra work, simply do not create elaborate points-to information for pt_anything pointers. */ if (pt->anything) - return 0; + return; /* Share the final set of variables when possible. */ finished_solution = BITMAP_GGC_ALLOC (); @@ -4830,15 +4691,7 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt, if (TREE_CODE (ptr) == SSA_NAME) ptr = SSA_NAME_VAR (ptr); - /* If the pointer decl is marked that no TBAA is to be applied, - do not do tbaa pruning. */ - if (!do_tbaa_pruning - || DECL_NO_TBAA_P (ptr)) - mem_alias_set = 0; - else - mem_alias_set = get_deref_alias_set (ptr); - pruned = set_uids_in_ptset (finished_solution, vi->solution, - mem_alias_set, pt); + set_uids_in_ptset (finished_solution, vi->solution, pt); result = shared_bitmap_lookup (finished_solution); if (!result) { @@ -4850,18 +4703,14 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt, pt->vars = result; bitmap_clear (finished_solution); } - - return pruned; } -/* Given a pointer variable P, fill in its points-to set. Apply - type-based pruning if IS_DEREFERENCED is true. */ +/* Given a pointer variable P, fill in its points-to set. */ static void -find_what_p_points_to (tree p, bool is_dereferenced) +find_what_p_points_to (tree p) { struct ptr_info_def *pi; - unsigned int pruned; tree lookup_p = p; varinfo_t vi; @@ -4877,23 +4726,7 @@ find_what_p_points_to (tree p, bool is_dereferenced) return; pi = get_ptr_info (p); - pruned = find_what_var_points_to (vi, &pi->pt, is_dereferenced); - - if (!(pi->pt.anything || pi->pt.nonlocal || pi->pt.escaped) - && bitmap_empty_p (pi->pt.vars) - && pruned > 0 - && is_dereferenced - && warn_strict_aliasing > 0 - && !SSA_NAME_IS_DEFAULT_DEF (p)) - { - if (dump_file && dump_flags & TDF_DETAILS) - { - fprintf (dump_file, "alias warning for "); - print_generic_expr (dump_file, p, 0); - fprintf (dump_file, "\n"); - } - emit_alias_warning (p); - } + find_what_var_points_to (vi, &pi->pt); } @@ -5372,139 +5205,6 @@ remove_preds_and_fake_succs (constraint_graph_t graph) bitmap_obstack_release (&predbitmap_obstack); } -/* Compute the set of variables we can't TBAA prune. */ - -static void -compute_tbaa_pruning (void) -{ - unsigned int size = VEC_length (varinfo_t, varmap); - unsigned int i; - bool any; - - changed_count = 0; - changed = sbitmap_alloc (size); - sbitmap_zero (changed); - - /* Mark all initial no_tbaa_pruning nodes as changed. */ - any = false; - for (i = 0; i < size; ++i) - { - varinfo_t ivi = get_varinfo (i); - - if (find (i) == i && ivi->no_tbaa_pruning) - { - any = true; - if ((graph->succs[i] && !bitmap_empty_p (graph->succs[i])) - || VEC_length (constraint_t, graph->complex[i]) > 0) - { - SET_BIT (changed, i); - ++changed_count; - } - } - } - - while (changed_count > 0) - { - struct topo_info *ti = init_topo_info (); - ++stats.iterations; - - compute_topo_order (graph, ti); - - while (VEC_length (unsigned, ti->topo_order) != 0) - { - bitmap_iterator bi; - - i = VEC_pop (unsigned, ti->topo_order); - - /* If this variable is not a representative, skip it. */ - if (find (i) != i) - continue; - - /* If the node has changed, we need to process the complex - constraints and outgoing edges again. */ - if (TEST_BIT (changed, i)) - { - unsigned int j; - constraint_t c; - VEC(constraint_t,heap) *complex = graph->complex[i]; - - RESET_BIT (changed, i); - --changed_count; - - /* Process the complex copy constraints. */ - for (j = 0; VEC_iterate (constraint_t, complex, j, c); ++j) - { - if (c->lhs.type == SCALAR && c->rhs.type == SCALAR) - { - varinfo_t lhsvi = get_varinfo (find (c->lhs.var)); - - if (!lhsvi->no_tbaa_pruning) - { - lhsvi->no_tbaa_pruning = true; - if (!TEST_BIT (changed, lhsvi->id)) - { - SET_BIT (changed, lhsvi->id); - ++changed_count; - } - } - } - } - - /* Propagate to all successors. */ - EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi) - { - unsigned int to = find (j); - varinfo_t tovi = get_varinfo (to); - - /* Don't propagate to ourselves. */ - if (to == i) - continue; - - if (!tovi->no_tbaa_pruning) - { - tovi->no_tbaa_pruning = true; - if (!TEST_BIT (changed, to)) - { - SET_BIT (changed, to); - ++changed_count; - } - } - } - } - } - - free_topo_info (ti); - } - - sbitmap_free (changed); - - if (any) - { - for (i = 0; i < size; ++i) - { - varinfo_t ivi = get_varinfo (i); - varinfo_t ivip = get_varinfo (find (i)); - - if (ivip->no_tbaa_pruning) - { - tree var = ivi->decl; - - if (TREE_CODE (var) == SSA_NAME) - var = SSA_NAME_VAR (var); - - if (POINTER_TYPE_P (TREE_TYPE (var))) - { - DECL_NO_TBAA_P (var) = 1; - - /* Tell the RTL layer that this pointer can alias - anything. */ - DECL_POINTER_ALIAS_SET (var) = 0; - } - } - } - } -} - /* Initialize the heapvar for statement mapping. */ static void @@ -5534,7 +5234,6 @@ compute_points_to_sets (void) struct scc_info *si; basic_block bb; unsigned i; - sbitmap dereferenced_ptrs; timevar_push (TV_TREE_PTA); @@ -5543,11 +5242,6 @@ compute_points_to_sets (void) intra_create_variable_infos (); - /* A bitmap of SSA_NAME pointers that are dereferenced. This is - used to track which points-to sets may be TBAA pruned. */ - dereferenced_ptrs = sbitmap_alloc (num_ssa_names); - sbitmap_zero (dereferenced_ptrs); - /* Now walk all statements and derive aliases. */ FOR_EACH_BB (bb) { @@ -5564,31 +5258,11 @@ compute_points_to_sets (void) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - use_operand_p use_p; - ssa_op_iter iter; - - /* Mark dereferenced pointers. This is used by TBAA pruning - of the points-to sets and the alias warning machinery. */ - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) - { - unsigned num_uses, num_loads, num_stores; - tree op = USE_FROM_PTR (use_p); - - if (!POINTER_TYPE_P (TREE_TYPE (op))) - continue; - - /* Determine whether OP is a dereferenced pointer. */ - count_uses_and_derefs (op, stmt, - &num_uses, &num_loads, &num_stores); - if (num_loads + num_stores > 0) - SET_BIT (dereferenced_ptrs, SSA_NAME_VERSION (op)); - } find_func_aliases (stmt); } } - if (dump_file) { fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n"); @@ -5642,15 +5316,13 @@ compute_points_to_sets (void) solve_graph (graph); - compute_tbaa_pruning (); - if (dump_file) dump_sa_points_to_info (dump_file); /* Compute the points-to sets for ESCAPED and CALLUSED used for call-clobber analysis. */ - find_what_var_points_to (var_escaped, &cfun->gimple_df->escaped, false); - find_what_var_points_to (var_callused, &cfun->gimple_df->callused, false); + find_what_var_points_to (var_escaped, &cfun->gimple_df->escaped); + find_what_var_points_to (var_callused, &cfun->gimple_df->callused); /* Make sure the ESCAPED solution (which is used as placeholder in other solutions) does not reference itself. This simplifies @@ -5663,9 +5335,8 @@ compute_points_to_sets (void) tree ptr = ssa_name (i); if (ptr && POINTER_TYPE_P (TREE_TYPE (ptr))) - find_what_p_points_to (ptr, TEST_BIT (dereferenced_ptrs, i)); + find_what_p_points_to (ptr); } - sbitmap_free (dereferenced_ptrs); timevar_pop (TV_TREE_PTA); diff --git a/gcc/tree.c b/gcc/tree.c index ce339a58292..2231b448950 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8961,10 +8961,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len)); } - case CHANGE_DYNAMIC_TYPE_EXPR: - WALK_SUBTREE (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*tp)); - WALK_SUBTREE_TAIL (CHANGE_DYNAMIC_TYPE_LOCATION (*tp)); - case DECL_EXPR: /* If this is a TYPE_DECL, walk into the fields of the type that it's defining. We only want to walk into these fields of a type in this diff --git a/gcc/tree.def b/gcc/tree.def index 41a9e908cab..b4828ad9478 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -913,15 +913,6 @@ DEFTREECODE (CATCH_EXPR, "catch_expr", tcc_statement, 2) expanding. */ DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", tcc_statement, 2) -/* Indicates a change in the dynamic type of a memory location. This - has no value and generates no executable code. It is only used for - type based alias analysis. This is generated by C++ placement new. - CHANGE_DYNAMIC_TYPE_NEW_TYPE, the first operand, is the new type. - CHANGE_DYNAMIC_TYPE_LOCATION, the second operand, is the location - whose type is being changed. */ -DEFTREECODE (CHANGE_DYNAMIC_TYPE_EXPR, "change_dynamic_type_expr", - tcc_statement, 2) - /* Node used for describing a property that is known at compile time. */ DEFTREECODE (SCEV_KNOWN, "scev_known", tcc_expression, 0) diff --git a/gcc/tree.h b/gcc/tree.h index cdabb3ece37..0adf75d9530 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1648,12 +1648,6 @@ extern void protected_set_expr_location (tree, location_t); #define EH_FILTER_MUST_NOT_THROW(NODE) \ (EH_FILTER_EXPR_CHECK (NODE)->base.static_flag) -/* CHANGE_DYNAMIC_TYPE_EXPR accessors. */ -#define CHANGE_DYNAMIC_TYPE_NEW_TYPE(NODE) \ - TREE_OPERAND (CHANGE_DYNAMIC_TYPE_EXPR_CHECK (NODE), 0) -#define CHANGE_DYNAMIC_TYPE_LOCATION(NODE) \ - TREE_OPERAND (CHANGE_DYNAMIC_TYPE_EXPR_CHECK (NODE), 1) - /* OBJ_TYPE_REF accessors. */ #define OBJ_TYPE_REF_EXPR(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 0) #define OBJ_TYPE_REF_OBJECT(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 1) @@ -2605,11 +2599,6 @@ struct GTY(()) tree_decl_minimal { #define DECL_GIMPLE_REG_P(DECL) \ DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag -/* For a DECL with pointer type, this is set if Type Based Alias - Analysis should not be applied to this DECL. */ -#define DECL_NO_TBAA_P(DECL) \ - DECL_COMMON_CHECK (DECL)->decl_common.no_tbaa_flag - struct GTY(()) tree_decl_common { struct tree_decl_minimal common; tree size; @@ -2649,12 +2638,10 @@ struct GTY(()) tree_decl_common { /* Logically, these two would go in a theoretical base shared by var and parm decl. */ unsigned gimple_reg_flag : 1; - /* In a DECL with pointer type, set if no TBAA should be done. */ - unsigned no_tbaa_flag : 1; /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */ unsigned decl_by_reference_flag : 1; /* Padding so that 'off_align' can be on a 32-bit boundary. */ - unsigned decl_common_unused : 1; + unsigned decl_common_unused : 2; /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */ unsigned int off_align : 8; |