+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
|| 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;
return new_bb;
}
}
- else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE)
+ else
{
def_operand_p def_p;
tree stmt_tree;
+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.
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
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
/* 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)))
/* 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. */
/* 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;
}
@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
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
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
* @code{GIMPLE_BIND}::
* @code{GIMPLE_CALL}::
* @code{GIMPLE_CATCH}::
-* @code{GIMPLE_CHANGE_DYNAMIC_TYPE}::
* @code{GIMPLE_COND}::
* @code{GIMPLE_EH_FILTER}::
* @code{GIMPLE_LABEL}::
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}
* 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
@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
+
/* 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 ();
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:
}
}
-/* 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. */
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;
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;
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:
}
-/* 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
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)
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:
}
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)
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.
}
-/* 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
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;
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);
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))
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))
+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.
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;
}
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 } */
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;
}
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);
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);
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)
case GIMPLE_NOP:
case GIMPLE_PHI:
case GIMPLE_RETURN:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
case GIMPLE_PREDICT:
return 0;
/* 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))
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);
}
{
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);
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. */
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)
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)
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);
}
/* 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)
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;
/* 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 ();
}
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
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. */
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,
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);
case GIMPLE_ASM:
case GIMPLE_RESX:
case GIMPLE_RETURN:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
mark_stmt_necessary (stmt, true);
return;
return;
}
- case CHANGE_DYNAMIC_TYPE_EXPR:
- gcc_unreachable ();
-
case FUNCTION_DECL:
case LABEL_DECL:
case CONST_DECL:
/* 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;
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;
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;
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. */
}
}
}
- 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)
{
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");
}
}
}
-/* 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)
{
|| 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));
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));
/* 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 ();
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)
{
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;
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);
}
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
struct scc_info *si;
basic_block bb;
unsigned i;
- sbitmap dereferenced_ptrs;
timevar_push (TV_TREE_PTA);
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)
{
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");
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
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);
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
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)
#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)
#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;
/* 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;