This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] New middle-end memory model (final)


This is the final version of the patch, removing some more dead code
regarding to TBAA pruning of points-to sets and the flow-insensitive
alias warning code using points-to information.

I have tested the effects of the patch on SPEC2006 scores for x86_64
and found its effects to be in the noise.  The patch fixes the
placement-new related tramp3d miscompile that got exposed recently 
again.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  I need approval
for the C++ parts.

Ok for trunk?

Thanks,
Richard.

2009-05-20  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.

Index: gcc/alias.c
===================================================================
*** gcc/alias.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/alias.c	2009-05-20 11:23:40.000000000 +0200
*************** write_dependence_p (const_rtx mem, const
*** 2373,2381 ****
        || 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;
--- 2373,2378 ----
Index: gcc/cp/init.c
===================================================================
*** gcc/cp/init.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/cp/init.c	2009-05-20 11:23:40.000000000 +0200
*************** build_raw_new_expr (tree placement, tree
*** 1724,1778 ****
    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
--- 1724,1729 ----
*************** build_new_1 (tree placement, tree type,
*** 1998,2009 ****
    /* 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 (placement != NULL)
! 	rval = avoid_placement_new_aliasing (rval, placement_expr);
!       return rval;
!     }
  
    /* Store the result of the allocation call in a variable so that we can
       use it more than once.  */
--- 1949,1955 ----
    /* In the simple case, we can stop now.  */
    pointer_type = build_pointer_type (type);
    if (!cookie_size && !is_initialized)
!     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.  */
*************** build_new_1 (tree placement, tree type,
*** 2283,2291 ****
    /* A new-expression is never an lvalue.  */
    gcc_assert (!lvalue_p (rval));
  
-   if (placement != NULL)
-     rval = avoid_placement_new_aliasing (rval, placement_expr);
- 
    return rval;
  }
  
--- 2229,2234 ----
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/cfgexpand.c	2009-05-20 11:23:40.000000000 +0200
*************** expand_gimple_basic_block (basic_block b
*** 2100,2106 ****
  		    return new_bb;
  		}
  	    }
! 	  else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE)
  	    {
  	      def_operand_p def_p;
  	      tree stmt_tree;
--- 2100,2106 ----
  		    return new_bb;
  		}
  	    }
! 	  else
  	    {
  	      def_operand_p def_p;
  	      tree stmt_tree;
Index: gcc/doc/c-tree.texi
===================================================================
*** gcc/doc/c-tree.texi.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/doc/c-tree.texi	2009-05-20 11:23:40.000000000 +0200
*************** This macro returns the attributes on the
*** 1995,2001 ****
  @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
--- 1995,2000 ----
*************** mechanism.  It represents expressions li
*** 2708,2720 ****
  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
--- 2707,2712 ----
Index: gcc/doc/gimple.texi
===================================================================
*** gcc/doc/gimple.texi.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/doc/gimple.texi	2009-05-20 11:23:40.000000000 +0200
*************** union gimple_statement_d
*** 332,345 ****
  
  The following table briefly describes the GIMPLE instruction set.
  
! @multitable {@code{GIMPLE_CHANGE_DYNAMIC_TYPE}} {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
--- 332,344 ----
  
  The following table briefly describes the GIMPLE instruction set.
  
! @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_COND}		@tab x			@tab x
  @item @code{GIMPLE_EH_FILTER}		@tab x			@tab
  @item @code{GIMPLE_GOTO}		@tab x			@tab x
*************** Return a deep copy of statement @code{ST
*** 885,891 ****
  * @code{GIMPLE_BIND}::
  * @code{GIMPLE_CALL}::
  * @code{GIMPLE_CATCH}::
- * @code{GIMPLE_CHANGE_DYNAMIC_TYPE}::
  * @code{GIMPLE_COND}::
  * @code{GIMPLE_EH_FILTER}::
  * @code{GIMPLE_LABEL}::
--- 884,889 ----
*************** Set @code{T} to be the set of types hand
*** 1295,1339 ****
  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}
--- 1293,1298 ----
Index: gcc/expr.c
===================================================================
*** gcc/expr.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/expr.c	2009-05-20 11:23:40.000000000 +0200
*************** expand_expr_real_1 (tree exp, rtx target
*** 9298,9310 ****
        /* 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 ();
  
--- 9298,9303 ----
Index: gcc/gimple-low.c
===================================================================
*** gcc/gimple-low.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimple-low.c	2009-05-20 11:23:40.000000000 +0200
*************** lower_stmt (gimple_stmt_iterator *gsi, s
*** 368,374 ****
      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:
--- 368,373 ----
Index: gcc/gimple-pretty-print.c
===================================================================
*** gcc/gimple-pretty-print.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimple-pretty-print.c	2009-05-20 11:23:40.000000000 +0200
*************** dump_gimple_omp_atomic_store (pretty_pri
*** 1324,1350 ****
      }
  }
  
- /* 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.  */
--- 1324,1329 ----
*************** dump_gimple_stmt (pretty_printer *buffer
*** 1508,1517 ****
        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;
--- 1487,1492 ----
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimple.c	2009-05-20 11:23:40.000000000 +0200
*************** gss_for_code (enum gimple_code code)
*** 102,108 ****
      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;
--- 102,107 ----
*************** gimple_size (enum gimple_code code)
*** 190,197 ****
        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:
--- 189,194 ----
*************** gimple_build_omp_single (gimple_seq body
*** 1042,1061 ****
  }
  
  
- /* 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
--- 1039,1044 ----
*************** walk_gimple_op (gimple stmt, walk_tree_f
*** 1460,1475 ****
  	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)
--- 1443,1448 ----
*************** is_gimple_stmt (tree t)
*** 2749,2755 ****
      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:
--- 2722,2727 ----
*************** walk_stmt_load_store_addr_ops (gimple st
*** 3254,3261 ****
      }
    else if (visit_addr
  	   && (is_gimple_assign (stmt)
! 	       || gimple_code (stmt) == GIMPLE_COND
! 	       || gimple_code (stmt) == GIMPLE_CHANGE_DYNAMIC_TYPE))
      {
        for (i = 0; i < gimple_num_ops (stmt); ++i)
  	if (gimple_op (stmt, i)
--- 3226,3232 ----
      }
    else if (visit_addr
  	   && (is_gimple_assign (stmt)
! 	       || gimple_code (stmt) == GIMPLE_COND))
      {
        for (i = 0; i < gimple_num_ops (stmt); ++i)
  	if (gimple_op (stmt, i)
Index: gcc/gimple.def
===================================================================
*** gcc/gimple.def.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimple.def	2009-05-20 11:23:40.000000000 +0200
*************** DEFGSCODE(GIMPLE_LABEL, "gimple_label",
*** 78,94 ****
     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.
--- 78,83 ----
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimple.h	2009-05-20 11:23:40.000000000 +0200
*************** gimple_nop_p (const_gimple g)
*** 4106,4174 ****
  }
  
  
- /* 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
--- 4106,4111 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/gimplify.c	2009-05-20 11:23:40.000000000 +0200
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6838,6856 ****
  	    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;
--- 6838,6843 ----
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-cfg.c	2009-05-20 11:23:40.000000000 +0200
*************** remove_useless_stmts_1 (gimple_stmt_iter
*** 2045,2062 ****
            }
            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);
--- 2045,2050 ----
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4038,4047 ****
      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);
  
--- 4026,4031 ----
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-inline.c	2009-05-20 11:23:40.000000000 +0200
*************** estimate_num_insns (gimple stmt, eni_wei
*** 3072,3078 ****
      case GIMPLE_NOP:
      case GIMPLE_PHI:
      case GIMPLE_RETURN:
-     case GIMPLE_CHANGE_DYNAMIC_TYPE:
      case GIMPLE_PREDICT:
        return 0;
  
--- 3072,3077 ----
*************** expand_call_inline (basic_block bb, gimp
*** 3429,3441 ****
    /* 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))
--- 3428,3433 ----
*************** copy_decl_to_var (tree decl, copy_body_d
*** 4192,4198 ****
    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);
  }
--- 4184,4189 ----
*************** copy_result_decl_to_var (tree decl, copy
*** 4219,4225 ****
      {
        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);
--- 4210,4215 ----
Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-pretty-print.c	2009-05-20 11:23:40.000000000 +0200
*************** dump_generic_node (pretty_printer *buffe
*** 1569,1585 ****
        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.  */
--- 1569,1574 ----
Index: gcc/tree-ssa-dce.c
===================================================================
*** gcc/tree-ssa-dce.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-dce.c	2009-05-20 11:23:40.000000000 +0200
*************** mark_stmt_if_obviously_necessary (gimple
*** 295,301 ****
      case GIMPLE_ASM:
      case GIMPLE_RESX:
      case GIMPLE_RETURN:
-     case GIMPLE_CHANGE_DYNAMIC_TYPE:
        mark_stmt_necessary (stmt, true);
        return;
  
--- 295,300 ----
Index: gcc/tree-ssa-operands.c
===================================================================
*** gcc/tree-ssa-operands.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-operands.c	2009-05-20 11:23:40.000000000 +0200
*************** get_expr_operands (gimple stmt, tree *ex
*** 1009,1017 ****
          return;
        }
  
-     case CHANGE_DYNAMIC_TYPE_EXPR:
-       gcc_unreachable ();
- 
      case FUNCTION_DECL:
      case LABEL_DECL:
      case CONST_DECL:
--- 1009,1014 ----
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-structalias.c	2009-05-20 11:23:40.000000000 +0200
*************** struct variable_info
*** 226,235 ****
    /* 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;
  
--- 226,231 ----
*************** static varinfo_t
*** 360,366 ****
  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;
--- 356,361 ----
*************** new_var_info (tree t, unsigned int id, c
*** 371,382 ****
    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;
--- 366,371 ----
*************** unify_nodes (constraint_graph_t graph, u
*** 1425,1433 ****
    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.  */
  
--- 1414,1419 ----
*************** find_func_aliases (gimple origt)
*** 3725,3738 ****
  	    }
  	}
      }
-   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)
--- 3711,3716 ----
*************** dump_solution_for_var (FILE *file, unsig
*** 4444,4453 ****
  	{
  	  fprintf (file, "%s ", get_varinfo (i)->name);
  	}
!       fprintf (file, "}");
!       if (vi->no_tbaa_pruning)
! 	fprintf (file, " no-tbaa-pruning");
!       fprintf (file, "\n");
      }
  }
  
--- 4422,4428 ----
  	{
  	  fprintf (file, "%s ", get_varinfo (i)->name);
  	}
!       fprintf (file, "}\n");
      }
  }
  
*************** shared_bitmap_add (bitmap pt_vars)
*** 4628,4646 ****
  }
  
  
! /* 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 .  */
! 
! static unsigned
! set_uids_in_ptset (bitmap into, bitmap from,
! 		   alias_set_type mem_alias_set, struct pt_solution *pt)
  {
    unsigned int i;
    bitmap_iterator bi;
-   unsigned pruned = 0;
  
    EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
      {
--- 4603,4615 ----
  }
  
  
! /* Set bits in INTO corresponding to the variable uids in solution set FROM.  */
! 
! static void 
! set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
  {
    unsigned int i;
    bitmap_iterator bi;
  
    EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
      {
*************** set_uids_in_ptset (bitmap into, bitmap f
*** 4655,4676 ****
  	  || 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));
--- 4624,4629 ----
*************** set_uids_in_ptset (bitmap into, bitmap f
*** 4678,4790 ****
  	    pt->vars_contains_global = true;
  	}
      }
- 
-   return pruned;
  }
  
  
  static bool have_alias_info = false;
  
! /* Emit a note for the pointer initialization point DEF.  */
  
  static void
! emit_pointer_definition (tree ptr, bitmap visited)
  {
!   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;
    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));
  
--- 4631,4651 ----
  	    pt->vars_contains_global = true;
  	}
      }
  }
  
  
  static bool have_alias_info = false;
  
! /* Compute the points-to solution *PT for the variable VI.  */
  
  static void
! find_what_var_points_to (varinfo_t vi, struct pt_solution *pt)
  {
!   unsigned int i;
    bitmap_iterator bi;
    bitmap finished_solution;
    bitmap result;
    tree ptr = vi->decl;
  
    memset (pt, 0, sizeof (struct pt_solution));
  
*************** find_what_var_points_to (varinfo_t vi, s
*** 4821,4827 ****
    /* Instead of doing extra work, simply do not create
       elaborate points-to information for pt_anything pointers.  */
    if (pt->anything)
!     return 0;
  
    /* Share the final set of variables when possible.  */
    finished_solution = BITMAP_GGC_ALLOC ();
--- 4682,4688 ----
    /* Instead of doing extra work, simply do not create
       elaborate points-to information for pt_anything pointers.  */
    if (pt->anything)
!     return;
  
    /* Share the final set of variables when possible.  */
    finished_solution = BITMAP_GGC_ALLOC ();
*************** find_what_var_points_to (varinfo_t vi, s
*** 4830,4844 ****
    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);
    result = shared_bitmap_lookup (finished_solution);
    if (!result)
      {
--- 4691,4697 ----
    if (TREE_CODE (ptr) == SSA_NAME)
      ptr = SSA_NAME_VAR (ptr);
  
!   set_uids_in_ptset (finished_solution, vi->solution, pt);
    result = shared_bitmap_lookup (finished_solution);
    if (!result)
      {
*************** find_what_var_points_to (varinfo_t vi, s
*** 4850,4867 ****
        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.  */
  
  static void
! find_what_p_points_to (tree p, bool is_dereferenced)
  {
    struct ptr_info_def *pi;
-   unsigned int pruned;
    tree lookup_p = p;
    varinfo_t vi;
  
--- 4703,4716 ----
        pt->vars = result;
        bitmap_clear (finished_solution);
      }
  }
  
! /* Given a pointer variable P, fill in its points-to set.  */
  
  static void
! find_what_p_points_to (tree p)
  {
    struct ptr_info_def *pi;
    tree lookup_p = p;
    varinfo_t vi;
  
*************** find_what_p_points_to (tree p, bool is_d
*** 4877,4899 ****
      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);
!     }
  }
  
  
--- 4726,4732 ----
      return;
  
    pi = get_ptr_info (p);
!   find_what_var_points_to (vi, &pi->pt);
  }
  
  
*************** remove_preds_and_fake_succs (constraint_
*** 5372,5510 ****
    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
--- 5205,5210 ----
*************** compute_points_to_sets (void)
*** 5534,5540 ****
    struct scc_info *si;
    basic_block bb;
    unsigned i;
-   sbitmap dereferenced_ptrs;
  
    timevar_push (TV_TREE_PTA);
  
--- 5234,5239 ----
*************** compute_points_to_sets (void)
*** 5543,5553 ****
  
    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)
      {
--- 5242,5247 ----
*************** compute_points_to_sets (void)
*** 5564,5594 ****
        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");
--- 5258,5268 ----
*************** compute_points_to_sets (void)
*** 5642,5656 ****
  
    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);
  
    /* Make sure the ESCAPED solution (which is used as placeholder in
       other solutions) does not reference itself.  This simplifies
--- 5316,5328 ----
  
    solve_graph (graph);
  
    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);
!   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
*************** compute_points_to_sets (void)
*** 5663,5671 ****
        tree ptr = ssa_name (i);
        if (ptr
  	  && POINTER_TYPE_P (TREE_TYPE (ptr)))
! 	find_what_p_points_to (ptr, TEST_BIT (dereferenced_ptrs, i));
      }
-   sbitmap_free (dereferenced_ptrs);
  
    timevar_pop (TV_TREE_PTA);
  
--- 5335,5342 ----
        tree ptr = ssa_name (i);
        if (ptr
  	  && POINTER_TYPE_P (TREE_TYPE (ptr)))
! 	find_what_p_points_to (ptr);
      }
  
    timevar_pop (TV_TREE_PTA);
  
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree.c	2009-05-20 11:23:40.000000000 +0200
*************** walk_tree_1 (tree *tp, walk_tree_fn func
*** 8887,8896 ****
  	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
--- 8887,8892 ----
Index: gcc/tree.def
===================================================================
*** gcc/tree.def.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree.def	2009-05-20 11:23:40.000000000 +0200
*************** DEFTREECODE (CATCH_EXPR, "catch_expr", t
*** 913,927 ****
     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)
--- 913,918 ----
Index: gcc/tree.h
===================================================================
*** gcc/tree.h.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree.h	2009-05-20 11:23:40.000000000 +0200
*************** extern void protected_set_expr_location
*** 1648,1659 ****
  #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)
--- 1648,1653 ----
*************** struct GTY(()) tree_decl_minimal {
*** 2605,2615 ****
  #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;
--- 2599,2604 ----
*************** struct GTY(()) tree_decl_common {
*** 2649,2660 ****
    /* 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;
  
    /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
    unsigned int off_align : 8;
--- 2638,2647 ----
    /* Logically, these two would go in a theoretical base shared by var and
       parm decl. */
    unsigned gimple_reg_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 : 2;
  
    /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
    unsigned int off_align : 8;
Index: gcc/omp-low.c
===================================================================
*** gcc/omp-low.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/omp-low.c	2009-05-20 11:23:40.000000000 +0200
*************** copy_var_decl (tree var, tree name, tree
*** 812,818 ****
    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);
--- 812,817 ----
*************** expand_omp_atomic_pipeline (basic_block
*** 5010,5016 ****
  				    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))
--- 5009,5014 ----
Index: gcc/print-tree.c
===================================================================
*** gcc/print-tree.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/print-tree.c	2009-05-20 11:23:40.000000000 +0200
*************** print_node (FILE *file, const char *pref
*** 425,432 ****
  	    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))
--- 425,430 ----
Index: gcc/tree-ssa-copyrename.c
===================================================================
*** gcc/tree-ssa-copyrename.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-copyrename.c	2009-05-20 11:23:40.000000000 +0200
*************** copy_rename_partition_coalesce (var_map
*** 233,252 ****
        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);
  
--- 233,238 ----
Index: gcc/tree-data-ref.c
===================================================================
*** gcc/tree-data-ref.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-data-ref.c	2009-05-20 11:23:40.000000000 +0200
*************** dr_may_alias_p (const struct data_refere
*** 1223,1229 ****
      return false;
  
    /* Query the alias oracle.  */
!   if (!refs_may_alias_p (DR_REF (a), DR_REF (b)))
      return false;
  
    if (!addr_a || !addr_b)
--- 1223,1239 ----
      return false;
  
    /* Query the alias oracle.  */
!   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)
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-alias.c	2009-05-20 11:23:40.000000000 +0200
*************** ptr_deref_may_alias_global_p (tree ptr)
*** 155,164 ****
    if (!pi)
      return true;
  
    return pt_solution_includes_global (&pi->pt);
  }
  
! /* Return true if dereferencing PTR may alias DECL.  */
  
  static bool
  ptr_deref_may_alias_decl_p (tree ptr, tree decl)
--- 155,167 ----
    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.
!    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)
*************** ptr_deref_may_alias_decl_p (tree ptr, tr
*** 190,196 ****
    return pt_solution_includes (&pi->pt, decl);
  }
  
! /* Return true if dereferenced PTR1 and PTR2 may alias.  */
  
  static bool
  ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
--- 193,201 ----
    return pt_solution_includes (&pi->pt, decl);
  }
  
! /* 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)
*************** ptr_derefs_may_alias_p (tree ptr1, tree
*** 222,227 ****
--- 227,234 ----
    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);
  }
  
*************** indirect_refs_may_alias_p (tree ref1, tr
*** 653,665 ****
  /* Return true, if the two memory references REF1 and REF2 may alias.  */
  
  static bool
! refs_may_alias_p_1 (tree ref1, tree ref2)
  {
    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;
  
    gcc_assert ((SSA_VAR_P (ref1)
  	       || handled_component_p (ref1)
--- 660,673 ----
  /* Return true, if the two memory references REF1 and REF2 may alias.  */
  
  static bool
! 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)
*************** refs_may_alias_p_1 (tree ref1, tree ref2
*** 694,700 ****
  				  base2, offset2, max_size2);
  
    /* First defer to TBAA if possible.  */
!   if (flag_strict_aliasing
        && !alias_sets_conflict_p (get_alias_set (ref1), get_alias_set (ref2)))
      return false;
  
--- 702,709 ----
  				  base2, offset2, max_size2);
  
    /* First defer to TBAA if possible.  */
!   if (tbaa_p
!       && flag_strict_aliasing
        && !alias_sets_conflict_p (get_alias_set (ref1), get_alias_set (ref2)))
      return false;
  
*************** refs_may_alias_p_1 (tree ref1, tree ref2
*** 708,728 ****
    /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
    ind1_p = INDIRECT_REF_P (base1);
    ind2_p = INDIRECT_REF_P (base2);
    if (var1_p && ind2_p)
      return indirect_ref_may_alias_decl_p (ref2, TREE_OPERAND (base2, 0),
! 					  offset2, max_size2, -1,
  					  ref1, base1,
! 					  offset1, max_size1, -1);
    else if (ind1_p && var2_p)
      return indirect_ref_may_alias_decl_p (ref1, TREE_OPERAND (base1, 0),
! 					  offset1, max_size1, -1,
  					  ref2, base2,
! 					  offset2, max_size2, -1);
    else if (ind1_p && ind2_p)
      return indirect_refs_may_alias_p (ref1, TREE_OPERAND (base1, 0),
! 				      offset1, max_size1, -1,
  				      ref2, TREE_OPERAND (base2, 0),
! 				      offset2, max_size2, -1);
  
    gcc_unreachable ();
  }
--- 717,738 ----
    /* 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, set,
  					  ref1, base1,
! 					  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, set,
  					  ref2, base2,
! 					  offset2, max_size2, set);
    else if (ind1_p && ind2_p)
      return indirect_refs_may_alias_p (ref1, TREE_OPERAND (base1, 0),
! 				      offset1, max_size1, set,
  				      ref2, TREE_OPERAND (base2, 0),
! 				      offset2, max_size2, set);
  
    gcc_unreachable ();
  }
*************** refs_may_alias_p_1 (tree ref1, tree ref2
*** 730,736 ****
  bool
  refs_may_alias_p (tree ref1, tree ref2)
  {
!   bool res = refs_may_alias_p_1 (ref1, ref2);
    if (res)
      ++alias_stats.refs_may_alias_p_may_alias;
    else
--- 740,746 ----
  bool
  refs_may_alias_p (tree ref1, tree ref2)
  {
!   bool res = refs_may_alias_p_1 (ref1, ref2, true);
    if (res)
      ++alias_stats.refs_may_alias_p_may_alias;
    else
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 738,743 ****
--- 748,770 ----
    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.  */
Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/tree-ssa-alias.h	2009-05-20 11:23:40.000000000 +0200
*************** struct GTY(()) pt_solution
*** 78,83 ****
--- 78,85 ----
  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,
Index: gcc/doc/tree-ssa.texi
===================================================================
*** gcc/doc/tree-ssa.texi.orig	2009-05-20 11:21:42.000000000 +0200
--- gcc/doc/tree-ssa.texi	2009-05-20 11:23:40.000000000 +0200
*************** passes for GIMPLE@.
*** 41,46 ****
--- 41,47 ----
  * 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
*************** providing its aliasing VDEF.  The walk s
*** 892,894 ****
--- 893,923 ----
  
  @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
+ 
Index: gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C
===================================================================
*** gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C.orig	2008-12-04 16:47:36.000000000 +0100
--- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C	2009-05-20 12:28:18.000000000 +0200
***************
*** 4,11 ****
  
  int foo() {
    int x;
!   float& q = reinterpret_cast<float&> (x);  /* { dg-message "initialized" } */
!   q = 1.0; /* { dg-warning "does break strict-aliasing" } */
    return x;
  }
  
--- 4,11 ----
  
  int foo() {
    int x;
!   float& q = reinterpret_cast<float&> (x);  /* { dg-message "initialized" "" { xfail *-*-* } } */
!   q = 1.0; /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */
    return x;
  }
  
Index: gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c
===================================================================
*** gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c.orig	2008-12-05 12:55:11.000000000 +0100
--- gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c	2009-05-20 12:29:29.000000000 +0200
*************** int foo()
*** 9,13 ****
    return i;
  }
  
! /* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } } 8 } */
! /* { dg-message "initialized" "" { target { *-*-* && lp64 } } 8 } */
--- 9,13 ----
    return i;
  }
  
! /* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */
! /* { dg-message "initialized" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */
Index: gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
===================================================================
*** gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c.orig	2008-12-04 16:47:36.000000000 +0100
--- gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c	2009-05-20 12:30:22.000000000 +0200
*************** int foo() {
*** 11,22 ****
    float* r;
  
    if (flag) {
!     q = (float*) &x;  /* { dg-message "initialized" } */
    } else {
!     q = (float*) &y;  /* { dg-message "initialized" } */
    }
  
!   *q = 1.0;  /* { dg-warning "does break strict-aliasing" } */
  
    return x;
  
--- 11,22 ----
    float* r;
  
    if (flag) {
!     q = (float*) &x;  /* { dg-message "initialized" "" { xfail *-*-* } } */
    } else {
!     q = (float*) &y;  /* { dg-message "initialized" "" { xfail *-*-* } } */
    }
  
!   *q = 1.0;  /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */
  
    return x;
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]