From owner-svn-src-head@FreeBSD.ORG Thu Dec 19 18:27:36 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9356F370; Thu, 19 Dec 2013 18:27:36 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 7DD1A1A4E; Thu, 19 Dec 2013 18:27:36 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rBJIRagN047332; Thu, 19 Dec 2013 18:27:36 GMT (envelope-from pfg@svn.freebsd.org) Received: (from pfg@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rBJIRWPc047314; Thu, 19 Dec 2013 18:27:32 GMT (envelope-from pfg@svn.freebsd.org) Message-Id: <201312191827.rBJIRWPc047314@svn.freebsd.org> From: "Pedro F. Giffuni" Date: Thu, 19 Dec 2013 18:27:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r259619 - in head/contrib/gcc: . cp doc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Dec 2013 18:27:36 -0000 Author: pfg Date: Thu Dec 19 18:27:32 2013 New Revision: 259619 URL: http://svnweb.freebsd.org/changeset/base/259619 Log: gcc: backport upstream fix for issue with C++'s placement new Fixes GCC libstdc++/29286 Obtained from: gcc 4.3 (rev. 125603, 125653; GPLv2) MFC after: 2 weeks Modified: head/contrib/gcc/ChangeLog.gcc43 head/contrib/gcc/cp/ChangeLog.gcc43 head/contrib/gcc/cp/init.c head/contrib/gcc/doc/c-tree.texi head/contrib/gcc/expr.c head/contrib/gcc/gimple-low.c head/contrib/gcc/gimplify.c head/contrib/gcc/omp-low.c head/contrib/gcc/print-tree.c head/contrib/gcc/tree-gimple.c head/contrib/gcc/tree-inline.c head/contrib/gcc/tree-pretty-print.c head/contrib/gcc/tree-ssa-alias.c head/contrib/gcc/tree-ssa-dce.c head/contrib/gcc/tree-ssa-operands.c head/contrib/gcc/tree-ssa-structalias.c head/contrib/gcc/tree.def head/contrib/gcc/tree.h Modified: head/contrib/gcc/ChangeLog.gcc43 ============================================================================== --- head/contrib/gcc/ChangeLog.gcc43 Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/ChangeLog.gcc43 Thu Dec 19 18:27:32 2013 (r259619) @@ -65,6 +65,48 @@ fvisibility-ms-compat. * c.opt (fvisibility-ms-compat): New. +2007-06-12 Ian Lance Taylor (r125653) + Daniel Berlin + + PR libstdc++/29286 + * tree.def: Add CHANGE_DYNAMIC_TYPE_EXPR. + * tree.h (CHANGE_DYNAMIC_TYPE_NEW_TYPE): Define. + (CHANGE_DYNAMIC_TYPE_LOCATION): Define. + (DECL_NO_TBAA_P): Define. + (struct tree_decl_common): Add no_tbaa_flag field. + * tree-ssa-structalias.c (struct variable_info): Add + no_tbaa_pruning field. + (new_var_info): Initialize no_tbaa_pruning field. + (unify_nodes): Copy no_tbaa_pruning field. + (find_func_aliases): Handle CHANGE_DYNAMIC_TYPE_EXPR. + (dump_solution_for_var): Print no_tbaa_pruning flag. + (set_uids_in_ptset): Add no_tbaa_pruning parameter. Change all + callers. + (compute_tbaa_pruning): New static function. + (compute_points_to_sets): Remove CHANGE_DYNAMIC_TYPE_EXPR nodes. + Call compute_tbaa_pruning. + * tree-ssa-alias.c (may_alias_p): Test no_tbaa_flag for pointers. + * gimplify.c (gimplify_expr): Handle CHANGE_DYNAMIC_TYPE_EXPR. + * gimple-low.c (lower_stmt): Likewise. + * tree-gimple.c (is_gimple_stmt): Likewise. + * tree-ssa-operands.c (get_expr_operands): Likewise. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise. + * tree-inline.c (estimate_num_insns_1): Likewise. + (copy_result_decl_to_var): Likewise. + * expr.c (expand_expr_real_1): Likewise. + * tree-pretty-print.c (dump_generic_node): Likewise. + * tree-inline.c (copy_decl_to_var): Copy DECL_NO_TBAA_P flag. + * omp-low.c (omp_copy_decl_2): Likewise. + * print-tree.c (print_node): Print DECL_NO_TBAA_P flag. + * doc/c-tree.texi (Expression trees): Document + CHANGE_DYNAMIC_TYPE_EXPR. + +2007-06-09 Daniel Berlin (r125603) + + * tree-ssa-structalias.c (set_uids_in_ptset): Add is_deref'd + parameter, use it. + (find_what_p_points_to): Pass new parameter to set_uids_in_ptset. + 2007-06-05 Joerg Wunsch (r125346) PR preprocessor/23479 Modified: head/contrib/gcc/cp/ChangeLog.gcc43 ============================================================================== --- head/contrib/gcc/cp/ChangeLog.gcc43 Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/cp/ChangeLog.gcc43 Thu Dec 19 18:27:32 2013 (r259619) @@ -25,6 +25,12 @@ * decl2.c (determine_visibility): Remove duplicate code for handling type info. +2007-06-12 Ian Lance Taylor (r125653) + + PR libstdc++/29286 + * init.c (avoid_placement_new_aliasing): New static function. + (build_new_1): Call it. + 2007-05-31 Daniel Berlin (r125239) * typeck.c (build_binary_op): Include types in error. Modified: head/contrib/gcc/cp/init.c ============================================================================== --- head/contrib/gcc/cp/init.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/cp/init.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1,6 +1,7 @@ /* Handle initialization things in C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -1564,6 +1565,55 @@ build_raw_new_expr (tree placement, tree 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 @@ -1607,6 +1657,7 @@ build_new_1 (tree placement, tree type, beginning of the storage allocated for an array-new expression in order to store the number of elements. */ tree cookie_size = NULL_TREE; + tree placement_var; /* True if the function we are calling is a placement allocation function. */ bool placement_allocation_fn_p; @@ -1700,6 +1751,20 @@ build_new_1 (tree placement, tree type, alloc_fn = NULL_TREE; + /* If PLACEMENT is a simple pointer type, then copy it into + PLACEMENT_VAR. */ + if (processing_template_decl + || placement == NULL_TREE + || TREE_CHAIN (placement) != NULL_TREE + || TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) != POINTER_TYPE) + placement_var = NULL_TREE; + else + { + placement_var = get_temp_regvar (TREE_TYPE (TREE_VALUE (placement)), + TREE_VALUE (placement)); + placement = tree_cons (NULL_TREE, placement_var, NULL_TREE); + } + /* Allocate the object. */ if (! placement && TYPE_FOR_JAVA (elt_type)) { @@ -1792,7 +1857,12 @@ build_new_1 (tree placement, tree type, /* 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); + { + rval = build_nop (pointer_type, alloc_call); + if (placement != NULL) + rval = avoid_placement_new_aliasing (rval, placement_var); + return rval; + } /* While we're working, use a pointer to the type we've actually allocated. Store the result of the call in a variable so that we @@ -2051,6 +2121,9 @@ build_new_1 (tree placement, tree type, /* A new-expression is never an lvalue. */ gcc_assert (!lvalue_p (rval)); + if (placement != NULL) + rval = avoid_placement_new_aliasing (rval, placement_var); + return rval; } Modified: head/contrib/gcc/doc/c-tree.texi ============================================================================== --- head/contrib/gcc/doc/c-tree.texi Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/doc/c-tree.texi Thu Dec 19 18:27:32 2013 (r259619) @@ -1916,6 +1916,7 @@ This macro returns the attributes on the @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 @@ -2572,6 +2573,13 @@ mechanism. It represents expressions li 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 ... clauseN]}. It Modified: head/contrib/gcc/expr.c ============================================================================== --- head/contrib/gcc/expr.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/expr.c Thu Dec 19 18:27:32 2013 (r259619) @@ -8718,6 +8718,13 @@ expand_expr_real_1 (tree exp, rtx target /* 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 (cfun); Modified: head/contrib/gcc/gimple-low.c ============================================================================== --- head/contrib/gcc/gimple-low.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/gimple-low.c Thu Dec 19 18:27:32 2013 (r259619) @@ -243,6 +243,7 @@ lower_stmt (tree_stmt_iterator *tsi, str case GOTO_EXPR: case LABEL_EXPR: case SWITCH_EXPR: + case CHANGE_DYNAMIC_TYPE_EXPR: case OMP_FOR: case OMP_SECTIONS: case OMP_SECTION: Modified: head/contrib/gcc/gimplify.c ============================================================================== --- head/contrib/gcc/gimplify.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/gimplify.c Thu Dec 19 18:27:32 2013 (r259619) @@ -5748,6 +5748,11 @@ gimplify_expr (tree *expr_p, tree *pre_p ret = GS_ALL_DONE; break; + case CHANGE_DYNAMIC_TYPE_EXPR: + ret = gimplify_expr (&CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p), + pre_p, post_p, is_gimple_reg, fb_lvalue); + break; + case OBJ_TYPE_REF: { enum gimplify_status r0, r1; Modified: head/contrib/gcc/omp-low.c ============================================================================== --- head/contrib/gcc/omp-low.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/omp-low.c Thu Dec 19 18:27:32 2013 (r259619) @@ -518,6 +518,7 @@ omp_copy_decl_2 (tree var, tree name, tr TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var); DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_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); TREE_USED (copy) = 1; Modified: head/contrib/gcc/print-tree.c ============================================================================== --- head/contrib/gcc/print-tree.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/print-tree.c Thu Dec 19 18:27:32 2013 (r259619) @@ -401,7 +401,9 @@ print_node (FILE *file, const char *pref if (DECL_VIRTUAL_P (node)) fputs (" virtual", file); if (DECL_PRESERVE_P (node)) - fputs (" preserve", file); + 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)) Modified: head/contrib/gcc/tree-gimple.c ============================================================================== --- head/contrib/gcc/tree-gimple.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-gimple.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1,5 +1,6 @@ /* Functions to analyze and validate GIMPLE trees. - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Contributed by Diego Novillo Rewritten by Jason Merrill @@ -215,6 +216,7 @@ is_gimple_stmt (tree t) case TRY_FINALLY_EXPR: case EH_FILTER_EXPR: case CATCH_EXPR: + case CHANGE_DYNAMIC_TYPE_EXPR: case ASM_EXPR: case RESX_EXPR: case PHI_NODE: Modified: head/contrib/gcc/tree-inline.c ============================================================================== --- head/contrib/gcc/tree-inline.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-inline.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1649,6 +1649,11 @@ estimate_num_insns_1 (tree *tp, int *wal *walk_subtrees = 0; return NULL; + /* CHANGE_DYNAMIC_TYPE_EXPR explicitly expands to nothing. */ + case CHANGE_DYNAMIC_TYPE_EXPR: + *walk_subtrees = 0; + return NULL; + /* Try to estimate the cost of assignments. We have three cases to deal with: 1) Simple assignments to registers; @@ -2635,6 +2640,7 @@ copy_decl_to_var (tree decl, copy_body_d TREE_READONLY (copy) = TREE_READONLY (decl); TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl); DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl); + DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl); return copy_decl_for_dup_finish (id, decl, copy); } @@ -2661,6 +2667,7 @@ copy_result_decl_to_var (tree decl, copy { TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl); DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl); + DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl); } return copy_decl_for_dup_finish (id, decl, copy); Modified: head/contrib/gcc/tree-pretty-print.c ============================================================================== --- head/contrib/gcc/tree-pretty-print.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-pretty-print.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1443,6 +1443,17 @@ dump_generic_node (pretty_printer *buffe is_expr = false; break; + case CHANGE_DYNAMIC_TYPE_EXPR: + 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. */ Modified: head/contrib/gcc/tree-ssa-alias.c ============================================================================== --- head/contrib/gcc/tree-ssa-alias.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-ssa-alias.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1,5 +1,5 @@ /* Alias analysis for trees. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by Diego Novillo This file is part of GCC. @@ -1961,28 +1961,29 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG); - alias_stats.tbaa_queries++; - - /* If the alias sets don't conflict then MEM cannot alias VAR. */ - if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) + if (!DECL_NO_TBAA_P (ptr)) { - alias_stats.alias_noalias++; - alias_stats.tbaa_resolved++; - return false; - } + alias_stats.tbaa_queries++; - /* If var is a record or union type, ptr cannot point into var - unless there is some operation explicit address operation in the - program that can reference a field of the ptr's dereferenced - type. This also assumes that the types of both var and ptr are - contained within the compilation unit, and that there is no fancy - addressing arithmetic associated with any of the types - involved. */ + /* If the alias sets don't conflict then MEM cannot alias VAR. */ + if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) + { + alias_stats.alias_noalias++; + alias_stats.tbaa_resolved++; + return false; + } - if ((mem_alias_set != 0) && (var_alias_set != 0)) - { - tree ptr_type = TREE_TYPE (ptr); - tree var_type = TREE_TYPE (var); + /* If VAR is a record or union type, PTR cannot point into VAR + unless there is some explicit address operation in the + program that can reference a field of the type pointed-to by + PTR. This also assumes that the types of both VAR and PTR + are contained within the compilation unit, and that there is + no fancy addressing arithmetic associated with any of the + types involved. */ + if (mem_alias_set != 0 && var_alias_set != 0) + { + tree ptr_type = TREE_TYPE (ptr); + tree var_type = TREE_TYPE (var); /* The star count is -1 if the type at the end of the pointer_to chain is not a record or union type. */ @@ -1991,41 +1992,41 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem { int ptr_star_count = 0; - /* Ipa_type_escape_star_count_of_interesting_type is a little to - restrictive for the pointer type, need to allow pointers to - primitive types as long as those types cannot be pointers - to everything. */ - while (POINTER_TYPE_P (ptr_type)) - /* Strip the *'s off. */ - { - ptr_type = TREE_TYPE (ptr_type); - ptr_star_count++; - } - - /* There does not appear to be a better test to see if the - pointer type was one of the pointer to everything - types. */ + /* ipa_type_escape_star_count_of_interesting_type is a + little too restrictive for the pointer type, need to + allow pointers to primitive types as long as those + types cannot be pointers to everything. */ + while (POINTER_TYPE_P (ptr_type)) + { + /* Strip the *s off. */ + ptr_type = TREE_TYPE (ptr_type); + ptr_star_count++; + } - if (ptr_star_count > 0) - { - alias_stats.structnoaddress_queries++; - if (ipa_type_escape_field_does_not_clobber_p (var_type, - TREE_TYPE (ptr))) + /* There does not appear to be a better test to see if + the pointer type was one of the pointer to everything + types. */ + if (ptr_star_count > 0) + { + alias_stats.structnoaddress_queries++; + if (ipa_type_escape_field_does_not_clobber_p (var_type, + TREE_TYPE (ptr))) + { + alias_stats.structnoaddress_resolved++; + alias_stats.alias_noalias++; + return false; + } + } + else if (ptr_star_count == 0) { + /* If PTR_TYPE was not really a pointer to type, it cannot + alias. */ + alias_stats.structnoaddress_queries++; alias_stats.structnoaddress_resolved++; alias_stats.alias_noalias++; return false; } } - else if (ptr_star_count == 0) - { - /* If ptr_type was not really a pointer to type, it cannot - alias. */ - alias_stats.structnoaddress_queries++; - alias_stats.structnoaddress_resolved++; - alias_stats.alias_noalias++; - return false; - } } } Modified: head/contrib/gcc/tree-ssa-dce.c ============================================================================== --- head/contrib/gcc/tree-ssa-dce.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-ssa-dce.c Thu Dec 19 18:27:32 2013 (r259619) @@ -1,5 +1,6 @@ /* Dead code elimination pass for the GNU compiler. - Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Contributed by Ben Elliston and Andrew MacLeod Adapted to use control dependence by Steven Bosscher, SUSE Labs. @@ -307,6 +308,7 @@ mark_stmt_if_obviously_necessary (tree s case ASM_EXPR: case RESX_EXPR: case RETURN_EXPR: + case CHANGE_DYNAMIC_TYPE_EXPR: mark_stmt_necessary (stmt, true); return; Modified: head/contrib/gcc/tree-ssa-operands.c ============================================================================== --- head/contrib/gcc/tree-ssa-operands.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-ssa-operands.c Thu Dec 19 18:27:32 2013 (r259619) @@ -2057,6 +2057,10 @@ get_expr_operands (tree stmt, tree *expr return; } + case CHANGE_DYNAMIC_TYPE_EXPR: + get_expr_operands (stmt, &CHANGE_DYNAMIC_TYPE_LOCATION (expr), opf_none); + return; + case BLOCK: case FUNCTION_DECL: case EXC_PTR_EXPR: Modified: head/contrib/gcc/tree-ssa-structalias.c ============================================================================== --- head/contrib/gcc/tree-ssa-structalias.c Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree-ssa-structalias.c Thu Dec 19 18:27:32 2013 (r259619) @@ -251,6 +251,10 @@ struct variable_info /* True if this is a heap variable. */ unsigned int is_heap_var:1; + /* True if we may not use TBAA to prune references to this + variable. This is used for C++ placement new. */ + unsigned int no_tbaa_pruning : 1; + /* Points-to set for this variable. */ bitmap solution; @@ -368,6 +372,7 @@ static varinfo_t new_var_info (tree t, unsigned int id, const char *name) { varinfo_t ret = pool_alloc (variable_info_pool); + tree var; ret->id = id; ret->name = name; @@ -378,6 +383,12 @@ new_var_info (tree t, unsigned int id, c ret->is_special_var = false; ret->is_unknown_size_var = false; ret->has_union = false; + 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; @@ -1221,6 +1232,9 @@ unify_nodes (constraint_graph_t graph, u 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; + if (update_changed && TEST_BIT (changed, from)) { RESET_BIT (changed, from); @@ -3564,6 +3578,14 @@ find_func_aliases (tree origt) } } } + else if (TREE_CODE (t) == CHANGE_DYNAMIC_TYPE_EXPR) + { + unsigned int j; + + get_constraint_for (CHANGE_DYNAMIC_TYPE_LOCATION (t), &lhsc); + for (j = 0; VEC_iterate (ce_s, lhsc, j, c); ++j) + get_varinfo (c->var)->no_tbaa_pruning = true; + } /* After promoting variables and computing aliasing we will need to re-scan most statements. FIXME: Try to minimize the @@ -4250,7 +4272,10 @@ dump_solution_for_var (FILE *file, unsig { fprintf (file, "%s ", get_varinfo (i)->name); } - fprintf (file, "}\n"); + fprintf (file, "}"); + if (vi->no_tbaa_pruning) + fprintf (file, " no-tbaa-pruning"); + fprintf (file, "\n"); } } @@ -4422,10 +4447,15 @@ shared_bitmap_add (bitmap pt_vars) /* Set bits in INTO corresponding to the variable uids in solution set FROM, which came from variable PTR. For variables that are actually dereferenced, we also use type - based alias analysis to prune the points-to sets. */ + based alias analysis to prune the points-to sets. + IS_DEREFED is true if PTR was directly dereferenced, which we use to + help determine whether we are we are allowed to prune using TBAA. + If NO_TBAA_PRUNING is true, we do not perform any TBAA pruning of + the from set. */ static void -set_uids_in_ptset (tree ptr, bitmap into, bitmap from) +set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed, + bool no_tbaa_pruning) { unsigned int i; bitmap_iterator bi; @@ -4462,7 +4492,8 @@ set_uids_in_ptset (tree ptr, bitmap into if (sft) { var_alias_set = get_alias_set (sft); - if (!vi->directly_dereferenced + if (no_tbaa_pruning + || (!is_derefed && !vi->directly_dereferenced) || alias_sets_conflict_p (ptr_alias_set, var_alias_set)) bitmap_set_bit (into, DECL_UID (sft)); } @@ -4476,7 +4507,8 @@ set_uids_in_ptset (tree ptr, bitmap into else { var_alias_set = get_alias_set (vi->decl); - if (!vi->directly_dereferenced + if (no_tbaa_pruning + || (!is_derefed && !vi->directly_dereferenced) || alias_sets_conflict_p (ptr_alias_set, var_alias_set)) bitmap_set_bit (into, DECL_UID (vi->decl)); } @@ -4564,7 +4596,9 @@ find_what_p_points_to (tree p) return false; finished_solution = BITMAP_GGC_ALLOC (); - set_uids_in_ptset (vi->decl, finished_solution, vi->solution); + set_uids_in_ptset (vi->decl, finished_solution, vi->solution, + vi->directly_dereferenced, + vi->no_tbaa_pruning); result = shared_bitmap_lookup (finished_solution); if (!result) @@ -4913,6 +4947,142 @@ remove_preds_and_fake_succs (constraint_ 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; + + bitmap_obstack_initialize (&iteration_obstack); + + 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); + bitmap_obstack_release (&iteration_obstack); + } + + 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; + } + } + } + } +} + /* Create points-to sets for the current function. See the comments at the start of the file for an algorithmic overview. */ @@ -4948,7 +5118,7 @@ compute_points_to_sets (struct alias_inf } } - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + for (bsi = bsi_start (bb); !bsi_end_p (bsi); ) { tree stmt = bsi_stmt (bsi); @@ -4959,6 +5129,13 @@ compute_points_to_sets (struct alias_inf This is used when creating name tags and alias sets. */ update_alias_info (stmt, ai); + + /* The information in CHANGE_DYNAMIC_TYPE_EXPR nodes has now + been captured, and we can remove them. */ + if (TREE_CODE (stmt) == CHANGE_DYNAMIC_TYPE_EXPR) + bsi_remove (&bsi, true); + else + bsi_next (&bsi); } } @@ -4991,6 +5168,8 @@ compute_points_to_sets (struct alias_inf solve_graph (graph); + compute_tbaa_pruning (); + if (dump_file) dump_sa_points_to_info (dump_file); have_alias_info = true; Modified: head/contrib/gcc/tree.def ============================================================================== --- head/contrib/gcc/tree.def Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree.def Thu Dec 19 18:27:32 2013 (r259619) @@ -1,7 +1,7 @@ /* This file contains the definitions and documentation for the tree codes used in GCC. Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998, 2000, 2001, 2004, 2005, - 2006 Free Software Foundation, Inc. + 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -880,6 +880,15 @@ DEFTREECODE (CATCH_EXPR, "catch_expr", t 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. + CHNAGE_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) Modified: head/contrib/gcc/tree.h ============================================================================== --- head/contrib/gcc/tree.h Thu Dec 19 18:06:52 2013 (r259618) +++ head/contrib/gcc/tree.h Thu Dec 19 18:27:32 2013 (r259619) @@ -1548,6 +1548,12 @@ struct tree_constructor GTY(()) #define EH_FILTER_FAILURE(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 1) #define EH_FILTER_MUST_NOT_THROW(NODE) TREE_STATIC (EH_FILTER_EXPR_CHECK (NODE)) +/* 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) @@ -2538,6 +2544,11 @@ struct tree_struct_field_tag GTY(()) #define DECL_CALL_CLOBBERED(DECL) \ DECL_COMMON_CHECK (DECL)->decl_common.call_clobbered_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 tree_decl_common GTY(()) { struct tree_decl_minimal common; @@ -2579,6 +2590,8 @@ struct tree_decl_common GTY(()) parm decl. */ unsigned gimple_reg_flag : 1; unsigned call_clobbered_flag : 1; + /* In a DECL with pointer type, set if no TBAA should be done. */ + unsigned no_tbaa_flag : 1; unsigned int align : 24; /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */