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][RFC] Adjust the middle-end memory model


This adjusts the middle-end memory model to properly honor type-based
aliasing rules set by the C and C++ standards.

The bulk of the patch gets rid of our previous attempts to fix
the issues around placement new and friends, CHANGE_DYNAMIC_TYPE_EXPR
and DECL_NO_TBAA_P.  The core pieces are separated in the changelog.

 - We no longer prune points-to sets using TBAA (there is no noticable
   slowdown because of this in SPEC 2000 or SPEC 2006).  This is
   because we need unpruned points-to sets to compute anti and
   output dependencies.  We could keep both pruned and unpruned sets,
   but the only differences should be in disambiguating two accesses
   via pointers.  Another advantage is that we can re-activate
   merge_alias_info again with unpruned sets.

 - The instruction scheduler (or rather, anti_dependence and
   output_dependence) no longer can use TBAA information.

 - The tree alias oracle got similar functionality, refs_anti_dependent
   and refs_output_dependent and the tree level data dependence
   analysis code makes use of these.

What remains to be done?

 - The alias warning code during points-to analysis needs to be
   re-done again.  It relies on the availability of pruned points-to sets.


Bootstrapped and tested on x86_64-unknown-linux-gnu (with the obvious
strict-aliasing warning failures).

I am looking for comments for now, but apart from the alias warning
code re-write the patch should be final.

This patch should enable us to put the malloc attribute on C++ new
among other things.

Thanks,
Richard.

2009-05-05  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 (find_what_p_points_to): Do not
	prune points-to sets.
	* 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.

	

	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-07 13:23:54.000000000 +0200
--- gcc/alias.c	2009-05-07 14:21:39.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-07 13:23:54.000000000 +0200
--- gcc/cp/init.c	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/cfgexpand.c	2009-05-07 14:21:39.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-04-28 10:48:39.000000000 +0200
--- gcc/doc/c-tree.texi	2009-05-07 14:21:39.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-04-28 10:48:39.000000000 +0200
--- gcc/doc/gimple.texi	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/expr.c	2009-05-07 14:21:39.000000000 +0200
*************** expand_expr_real_1 (tree exp, rtx target
*** 9293,9305 ****
        /* 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 ();
  
--- 9293,9298 ----
Index: gcc/gimple-low.c
===================================================================
*** gcc/gimple-low.c.orig	2009-04-27 10:20:49.000000000 +0200
--- gcc/gimple-low.c	2009-05-07 14:21:39.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-04-03 12:56:20.000000000 +0200
--- gcc/gimple-pretty-print.c	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/gimple.c	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/gimple.def	2009-05-07 14:21:39.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-04-28 10:48:42.000000000 +0200
--- gcc/gimple.h	2009-05-07 14:21:39.000000000 +0200
*************** gimple_nop_p (const_gimple g)
*** 4135,4203 ****
  }
  
  
- /* 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
--- 4135,4140 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2009-05-07 13:25:48.000000000 +0200
--- gcc/gimplify.c	2009-05-07 14:21:39.000000000 +0200
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6839,6857 ****
  	    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;
--- 6839,6844 ----
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2009-05-07 13:22:51.000000000 +0200
--- gcc/tree-cfg.c	2009-05-07 14:21:39.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-04 13:00:33.000000000 +0200
--- gcc/tree-inline.c	2009-05-07 14:21:39.000000000 +0200
*************** estimate_num_insns (gimple stmt, eni_wei
*** 3016,3022 ****
      case GIMPLE_NOP:
      case GIMPLE_PHI:
      case GIMPLE_RETURN:
-     case GIMPLE_CHANGE_DYNAMIC_TYPE:
      case GIMPLE_PREDICT:
        return 0;
  
--- 3016,3021 ----
*************** expand_call_inline (basic_block bb, gimp
*** 3393,3405 ****
    /* 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))
--- 3392,3397 ----
*************** copy_decl_to_var (tree decl, copy_body_d
*** 4150,4156 ****
    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);
  }
--- 4142,4147 ----
*************** copy_result_decl_to_var (tree decl, copy
*** 4177,4183 ****
      {
        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);
--- 4168,4173 ----
Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c.orig	2009-04-20 12:08:50.000000000 +0200
--- gcc/tree-pretty-print.c	2009-05-07 14:21:39.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-04-08 17:19:27.000000000 +0200
--- gcc/tree-ssa-dce.c	2009-05-07 14:21:39.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-04-16 15:22:08.000000000 +0200
--- gcc/tree-ssa-operands.c	2009-05-07 14:21:39.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-04 11:09:18.000000000 +0200
--- gcc/tree-ssa-structalias.c	2009-05-07 14:21:39.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");
      }
  }
  
*************** set_uids_in_ptset (bitmap into, bitmap f
*** 4659,4665 ****
  	     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);
--- 4634,4639 ----
*************** find_what_var_points_to (varinfo_t vi, s
*** 4830,4839 ****
    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);
--- 4804,4810 ----
    if (TREE_CODE (ptr) == SSA_NAME)
      ptr = SSA_NAME_VAR (ptr);
  
!   if (!do_tbaa_pruning)
      mem_alias_set = 0;
    else
      mem_alias_set = get_deref_alias_set (ptr);
*************** find_what_p_points_to (tree p, bool is_d
*** 4877,4883 ****
      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)
--- 4848,4859 ----
      return;
  
    pi = get_ptr_info (p);
!   /* ???  To query anti and output dependencies we have to use unpruned
!      points-to sets.  Either defer pruning to the oracle when
!      disambiguating two memory references based on pointers or store
!      two points-to sets per variable.  Unpruned points-to sets can
!      also be transfered during merge_alias_info, pruned can not.  */
!   pruned = find_what_var_points_to (vi, &pi->pt, false && is_dereferenced);
  
    if (!(pi->pt.anything || pi->pt.nonlocal || pi->pt.escaped)
        && bitmap_empty_p (pi->pt.vars)
*************** 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
--- 5348,5353 ----
*************** compute_points_to_sets (void)
*** 5642,5649 ****
  
    solve_graph (graph);
  
-   compute_tbaa_pruning ();
- 
    if (dump_file)
      dump_sa_points_to_info (dump_file);
  
--- 5485,5490 ----
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig	2009-05-05 18:07:12.000000000 +0200
--- gcc/tree.c	2009-05-07 14:21:39.000000000 +0200
*************** walk_tree_1 (tree *tp, walk_tree_fn func
*** 8855,8864 ****
  	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
--- 8855,8860 ----
Index: gcc/tree.def
===================================================================
*** gcc/tree.def.orig	2009-04-20 16:02:29.000000000 +0200
--- gcc/tree.def	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/tree.h	2009-05-07 14:21:39.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-04-21 11:57:23.000000000 +0200
--- gcc/omp-low.c	2009-05-07 14:21:39.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-07 13:25:48.000000000 +0200
--- gcc/print-tree.c	2009-05-07 14:21:39.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-04-27 10:20:49.000000000 +0200
--- gcc/tree-ssa-copyrename.c	2009-05-07 14:21:39.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-04-28 10:48:42.000000000 +0200
--- gcc/tree-data-ref.c	2009-05-07 14:21:39.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-04-20 12:08:50.000000000 +0200
--- gcc/tree-ssa-alias.c	2009-05-07 14:52:59.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-04-23 11:24:44.000000000 +0200
--- gcc/tree-ssa-alias.h	2009-05-07 14:21:39.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-04-03 12:56:06.000000000 +0200
--- gcc/doc/tree-ssa.texi	2009-05-07 14:46:08.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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]