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:
Richard Guenther 2009-05-22 20:41:31 +00:00 committed by Richard Biener
parent 83a6ac60c6
commit 4d7a65ea61
34 changed files with 198 additions and 713 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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 ();

View File

@ -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:

View File

@ -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;

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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))

View File

@ -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))

View File

@ -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.

View File

@ -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;
}

View File

@ -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 } */

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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. */

View File

@ -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. */

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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;