mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 04:50:25 +08:00
re PR tree-optimization/38964 (TBAA side-effects of C++ new still missing)
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. From-SVN: r147805
This commit is contained in:
parent
83a6ac60c6
commit
4d7a65ea61
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
31
gcc/gimple.c
31
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)
|
||||
|
@ -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.
|
||||
|
63
gcc/gimple.h
63
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
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 } */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
15
gcc/tree.h
15
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user