From patchwork Fri Oct 30 13:40:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 538325 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id EB3A1140D92 for ; Sat, 31 Oct 2015 00:41:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Vf2YSJ08; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=MuVa2joHSFQY6Cx/fbTMwVBLkJWRv5NEDZSqsi1OuJinkpfgMx 8Zp2qN/HPIBvhoPlwhVKTwFHQvFTPZUnRThGuGo7kLvfI0oYC7PRpvJggRqORtyw Rbww05Y7iAF+rNYr7JB7++LEG6mXQXvfMZJUj8LJQLKPFNHRQsmNJEDCQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=pxbts4dl1BuQM+5A/8RPy45V1Mg=; b=Vf2YSJ08AXvB1q4c7yPY 2uHGEtwKqJ4fbiPRf4Bv6tX2WuH9Pqp3SWBPHk1Dz1UB8mIBH9a9GTwxi/JwhJTZ Qv4EG/cdRpPDTx2N84ML0yQU90EQ4kc3xxk41O8Jl9Xsy1jY3mPVnXdaYrEdDl+w D9DDE0Wiqv+jcBri5e2nnt8= Received: (qmail 42074 invoked by alias); 30 Oct 2015 13:41:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 42062 invoked by uid 89); 30 Oct 2015 13:41:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: fencepost.gnu.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (208.118.235.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 30 Oct 2015 13:41:17 +0000 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53999) by fencepost.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1Zs9ve-00030o-KJ for gcc-patches@gnu.org; Fri, 30 Oct 2015 09:41:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zs9vX-0003YL-Fq for gcc-patches@gnu.org; Fri, 30 Oct 2015 09:41:14 -0400 Received: from relay1.mentorg.com ([192.94.38.131]:40943) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zs9vX-0003YG-3p for gcc-patches@gnu.org; Fri, 30 Oct 2015 09:41:07 -0400 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-02.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1Zs9vT-00076K-8G from Tom_deVries@mentor.com ; Fri, 30 Oct 2015 06:41:03 -0700 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-02.mgc.mentorg.com (137.202.0.106) with Microsoft SMTP Server id 14.3.224.2; Fri, 30 Oct 2015 13:40:24 +0000 To: "gcc-patches@gnu.org" , Jakub Jelinek From: Tom de Vries Subject: [gomp4, committed] Backport tree-ssa-structalias.c fixes from trunk Message-ID: <56337342.7080006@mentor.com> Date: Fri, 30 Oct 2015 14:40:18 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 Hi, this patch backports my commits to trunk of this week in tree-ssa-structalias.c. Committed to gomp-4_0-branch. Thanks, - Tom Backport tree-ssa-structalias.c fixes from trunk 2015-10-30 Tom de Vries backport from trunk: 2015-10-30 Tom de Vries * tree-ssa-structalias.c (ipa_pta_execute): Declare variable from as unsigned, and initialize, and use initial value instead of hardcoded constant. Add generic constraints dumping section. Don't dump global initializers constraints dumping section if empty. Don't update variable from if unused. 2015-10-28 Tom de Vries * tree-ssa-structalias.c (intra_create_variable_infos): Remove superfluous code. * tree-ssa-structalias.c (intra_create_variable_infos): Don't iterate into vi_next of a full_var. * tree-ssa-structalias.c (new_var_info, make_heapvar) (make_constraint_from_restrict, make_constraint_from_global_restrict) (create_function_info_for, create_variable_info_for_1) (create_variable_info_for): Add and handle add_id parameter. (get_call_vi, new_scalar_tmp_constraint_exp, handle_rhs_call) (init_base_vars): Add extra argument to calls to new_var_info. (get_vi_for_tree): Add extra argument to call to create_variable_info_for. (process_constraint, do_deref, process_all_all_constraints): Add extra argument to calls to new_scalar_tmp_constraint_exp. (handle_lhs_call, find_func_aliases_for_builtin_call): Add extra argument to calls to make_heapvar. (make_restrict_var_constraints): Add extra argument to call to make_constraint_from_global_restrict. (intra_create_variable_infos): Add extra argument to call to create_variable_info_for_1. (ipa_pta_execute): Add extra argument to call to create_function_info_for. * gcc.dg/tree-ssa/pta-callused.c: Update to scan for CALLUSED(id). 2015-10-27 Tom de Vries * tree-ssa-structalias.c (push_fields_onto_fieldstack): Add and use var field_type. 2015-10-26 Tom de Vries * tree-ssa-structalias.c (make_restrict_var_constraints): New function, factored out of ... (intra_create_variable_infos): ... here. * tree-ssa-structalias.c (intra_create_variable_infos): Add restrict_pointer_p and recursive_restrict_p variables. * tree-ssa-structalias.c (intra_create_variable_infos): Inline get_vi_for_tree call. 2015-10-23 Tom de Vries * tree-ssa-structalias.c (intra_create_variable_infos): Use make_constraint_from. * tree-ssa-structalias.c (create_variable_info_for_1): Add missing setting of is_full_var in case of a single field. --- gcc/ChangeLog.gomp | 65 +++++++++ gcc/testsuite/ChangeLog.gomp | 7 + gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c | 2 +- gcc/tree-ssa-structalias.c | 203 +++++++++++++++------------ 4 files changed, 189 insertions(+), 88 deletions(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c index 59408fa..b9a57d8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c @@ -22,5 +22,5 @@ int bar (int b) return *foo (&q); } -/* { dg-final { scan-tree-dump "CALLUSED = { ESCAPED NONLOCAL f.* i q }" "alias" } } */ +/* { dg-final { scan-tree-dump "CALLUSED\\(\[0-9\]+\\) = { ESCAPED NONLOCAL f.* i q }" "alias" } } */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 8d86dcb..f5e17a3 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -220,7 +220,7 @@ static bitmap_obstack oldpta_obstack; /* Used for per-solver-iteration bitmaps. */ static bitmap_obstack iteration_obstack; -static unsigned int create_variable_info_for (tree, const char *); +static unsigned int create_variable_info_for (tree, const char *, bool); typedef struct constraint_graph *constraint_graph_t; static void unify_nodes (constraint_graph_t, unsigned int, unsigned int, bool); @@ -361,11 +361,18 @@ enum { nothing_id = 1, anything_id = 2, string_id = 3, to the vector of variable info structures. */ static varinfo_t -new_var_info (tree t, const char *name) +new_var_info (tree t, const char *name, bool add_id) { unsigned index = varmap.length (); varinfo_t ret = variable_info_pool.allocate (); + if (dump_file && add_id) + { + char *tempname = xasprintf ("%s(%d)", name, index); + name = ggc_strdup (tempname); + free (tempname); + } + ret->id = index; ret->name = name; ret->decl = t; @@ -416,13 +423,13 @@ get_call_vi (gcall *call) if (existed) return *slot_p; - vi = new_var_info (NULL_TREE, "CALLUSED"); + vi = new_var_info (NULL_TREE, "CALLUSED", true); vi->offset = 0; vi->size = 1; vi->fullsize = 2; vi->is_full_var = true; - vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED"); + vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true); vi2->offset = 1; vi2->size = 1; vi2->fullsize = 2; @@ -2883,7 +2890,10 @@ get_vi_for_tree (tree t) { varinfo_t *slot = vi_for_tree->get (t); if (slot == NULL) - return get_varinfo (create_variable_info_for (t, alias_get_name (t))); + { + unsigned int id = create_variable_info_for (t, alias_get_name (t), false); + return get_varinfo (id); + } return *slot; } @@ -2891,12 +2901,12 @@ get_vi_for_tree (tree t) /* Get a scalar constraint expression for a new temporary variable. */ static struct constraint_expr -new_scalar_tmp_constraint_exp (const char *name) +new_scalar_tmp_constraint_exp (const char *name, bool add_id) { struct constraint_expr tmp; varinfo_t vi; - vi = new_var_info (NULL_TREE, name); + vi = new_var_info (NULL_TREE, name, add_id); vi->offset = 0; vi->size = -1; vi->fullsize = -1; @@ -3002,7 +3012,7 @@ process_constraint (constraint_t t) { /* Split into tmp = *rhs, *lhs = tmp */ struct constraint_expr tmplhs; - tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp"); + tmplhs = new_scalar_tmp_constraint_exp ("doubledereftmp", true); process_constraint (new_constraint (tmplhs, rhs)); process_constraint (new_constraint (lhs, tmplhs)); } @@ -3010,7 +3020,7 @@ process_constraint (constraint_t t) { /* Split into tmp = &rhs, *lhs = tmp */ struct constraint_expr tmplhs; - tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp"); + tmplhs = new_scalar_tmp_constraint_exp ("derefaddrtmp", true); process_constraint (new_constraint (tmplhs, rhs)); process_constraint (new_constraint (lhs, tmplhs)); } @@ -3314,7 +3324,7 @@ do_deref (vec *constraints) else if (c->type == DEREF) { struct constraint_expr tmplhs; - tmplhs = new_scalar_tmp_constraint_exp ("dereftmp"); + tmplhs = new_scalar_tmp_constraint_exp ("dereftmp", true); process_constraint (new_constraint (tmplhs, *c)); c->var = tmplhs.var; } @@ -3572,7 +3582,7 @@ process_all_all_constraints (vec lhsc, else { struct constraint_expr tmp; - tmp = new_scalar_tmp_constraint_exp ("allalltmp"); + tmp = new_scalar_tmp_constraint_exp ("allalltmp", true); FOR_EACH_VEC_ELT (rhsc, i, rhsp) process_constraint (new_constraint (tmp, *rhsp)); FOR_EACH_VEC_ELT (lhsc, i, lhsp) @@ -3757,7 +3767,7 @@ build_fake_var_decl (tree type) Return the created variable. */ static varinfo_t -make_heapvar (const char *name) +make_heapvar (const char *name, bool add_id) { varinfo_t vi; tree heapvar; @@ -3765,7 +3775,7 @@ make_heapvar (const char *name) heapvar = build_fake_var_decl (ptr_type_node); DECL_EXTERNAL (heapvar) = 1; - vi = new_var_info (heapvar, name); + vi = new_var_info (heapvar, name, add_id); vi->is_artificial_var = true; vi->is_heap_var = true; vi->is_unknown_size_var = true; @@ -3783,9 +3793,9 @@ make_heapvar (const char *name) for tracking restrict pointers. */ static varinfo_t -make_constraint_from_restrict (varinfo_t lhs, const char *name) +make_constraint_from_restrict (varinfo_t lhs, const char *name, bool add_id) { - varinfo_t vi = make_heapvar (name); + varinfo_t vi = make_heapvar (name, add_id); vi->is_restrict_var = 1; vi->is_global_var = 1; vi->may_have_pointers = 1; @@ -3799,9 +3809,10 @@ make_constraint_from_restrict (varinfo_t lhs, const char *name) point to global memory. */ static varinfo_t -make_constraint_from_global_restrict (varinfo_t lhs, const char *name) +make_constraint_from_global_restrict (varinfo_t lhs, const char *name, + bool add_id) { - varinfo_t vi = make_constraint_from_restrict (lhs, name); + varinfo_t vi = make_constraint_from_restrict (lhs, name, add_id); make_copy_constraint (vi, nonlocal_id); return vi; } @@ -3881,7 +3892,7 @@ handle_rhs_call (gcall *stmt, vec *results) varinfo_t uses = get_call_use_vi (stmt); if (!(flags & EAF_DIRECT)) { - varinfo_t tem = new_var_info (NULL_TREE, "callarg"); + varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); make_constraint_to (tem->id, arg); make_transitive_closure_constraints (tem); make_copy_constraint (uses, tem->id); @@ -3895,7 +3906,7 @@ handle_rhs_call (gcall *stmt, vec *results) struct constraint_expr lhs, rhs; varinfo_t uses = get_call_use_vi (stmt); varinfo_t clobbers = get_call_clobber_vi (stmt); - varinfo_t tem = new_var_info (NULL_TREE, "callarg"); + varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); make_constraint_to (tem->id, arg); if (!(flags & EAF_DIRECT)) make_transitive_closure_constraints (tem); @@ -3995,7 +4006,7 @@ handle_lhs_call (gcall *stmt, tree lhs, int flags, vec rhsc, varinfo_t vi; struct constraint_expr tmpc; rhsc.create (0); - vi = make_heapvar ("HEAP"); + vi = make_heapvar ("HEAP", true); /* We are marking allocated storage local, we deal with it becoming global by escaping and setting of vars_contains_escaped_heap. */ DECL_EXTERNAL (vi->decl) = 0; @@ -4246,7 +4257,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) tree ptrptr = gimple_call_arg (t, 0); get_constraint_for (ptrptr, &lhsc); do_deref (&lhsc); - varinfo_t vi = make_heapvar ("HEAP"); + varinfo_t vi = make_heapvar ("HEAP", true); /* We are marking allocated storage local, we deal with it becoming global by escaping and setting of vars_contains_escaped_heap. */ DECL_EXTERNAL (vi->decl) = 0; @@ -5313,13 +5324,14 @@ push_fields_onto_fieldstack (tree type, vec *fieldstack, { bool push = false; HOST_WIDE_INT foff = bitpos_of_field (field); + tree field_type = TREE_TYPE (field); if (!var_can_have_subvars (field) - || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE - || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) + || TREE_CODE (field_type) == QUAL_UNION_TYPE + || TREE_CODE (field_type) == UNION_TYPE) push = true; else if (!push_fields_onto_fieldstack - (TREE_TYPE (field), fieldstack, offset + foff) + (field_type, fieldstack, offset + foff) && (DECL_SIZE (field) && !integer_zerop (DECL_SIZE (field)))) /* Empty structures may have actual size, like in C++. So @@ -5372,8 +5384,8 @@ push_fields_onto_fieldstack (tree type, vec *fieldstack, e.may_have_pointers = true; e.only_restrict_pointers = (!has_unknown_size - && POINTER_TYPE_P (TREE_TYPE (field)) - && TYPE_RESTRICT (TREE_TYPE (field))); + && POINTER_TYPE_P (field_type) + && TYPE_RESTRICT (field_type)); fieldstack->safe_push (e); } } @@ -5412,7 +5424,7 @@ count_num_arguments (tree decl, bool *is_varargs) of the variable we've created for the function. */ static varinfo_t -create_function_info_for (tree decl, const char *name) +create_function_info_for (tree decl, const char *name, bool add_id) { struct function *fn = DECL_STRUCT_FUNCTION (decl); varinfo_t vi, prev_vi; @@ -5423,7 +5435,7 @@ create_function_info_for (tree decl, const char *name) /* Create the variable info. */ - vi = new_var_info (decl, name); + vi = new_var_info (decl, name, add_id); vi->offset = 0; vi->size = 1; vi->fullsize = fi_parm_base + num_args; @@ -5446,7 +5458,7 @@ create_function_info_for (tree decl, const char *name) newname = ggc_strdup (tempname); free (tempname); - clobbervi = new_var_info (NULL, newname); + clobbervi = new_var_info (NULL, newname, false); clobbervi->offset = fi_clobbers; clobbervi->size = 1; clobbervi->fullsize = vi->fullsize; @@ -5460,7 +5472,7 @@ create_function_info_for (tree decl, const char *name) newname = ggc_strdup (tempname); free (tempname); - usevi = new_var_info (NULL, newname); + usevi = new_var_info (NULL, newname, false); usevi->offset = fi_uses; usevi->size = 1; usevi->fullsize = vi->fullsize; @@ -5482,7 +5494,7 @@ create_function_info_for (tree decl, const char *name) newname = ggc_strdup (tempname); free (tempname); - chainvi = new_var_info (fn->static_chain_decl, newname); + chainvi = new_var_info (fn->static_chain_decl, newname, false); chainvi->offset = fi_static_chain; chainvi->size = 1; chainvi->fullsize = vi->fullsize; @@ -5510,7 +5522,7 @@ create_function_info_for (tree decl, const char *name) newname = ggc_strdup (tempname); free (tempname); - resultvi = new_var_info (resultdecl, newname); + resultvi = new_var_info (resultdecl, newname, false); resultvi->offset = fi_result; resultvi->size = 1; resultvi->fullsize = vi->fullsize; @@ -5540,7 +5552,7 @@ create_function_info_for (tree decl, const char *name) newname = ggc_strdup (tempname); free (tempname); - argvi = new_var_info (argdecl, newname); + argvi = new_var_info (argdecl, newname, false); argvi->offset = fi_parm_base + i; argvi->size = 1; argvi->is_full_var = true; @@ -5572,7 +5584,7 @@ create_function_info_for (tree decl, const char *name) /* We need sth that can be pointed to for va_start. */ decl = build_fake_var_decl (ptr_type_node); - argvi = new_var_info (decl, newname); + argvi = new_var_info (decl, newname, false); argvi->offset = fi_parm_base + num_args; argvi->size = ~0; argvi->is_full_var = true; @@ -5611,7 +5623,7 @@ check_for_overlaps (vec fieldstack) of DECL. */ static varinfo_t -create_variable_info_for_1 (tree decl, const char *name) +create_variable_info_for_1 (tree decl, const char *name, bool add_id) { varinfo_t vi, newvi; tree decl_type = TREE_TYPE (decl); @@ -5623,7 +5635,7 @@ create_variable_info_for_1 (tree decl, const char *name) if (!declsize || !tree_fits_uhwi_p (declsize)) { - vi = new_var_info (decl, name); + vi = new_var_info (decl, name, add_id); vi->offset = 0; vi->size = ~0; vi->fullsize = ~0; @@ -5678,7 +5690,7 @@ create_variable_info_for_1 (tree decl, const char *name) if (fieldstack.length () == 0 || fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE) { - vi = new_var_info (decl, name); + vi = new_var_info (decl, name, add_id); vi->offset = 0; vi->may_have_pointers = true; vi->fullsize = tree_to_uhwi (declsize); @@ -5691,8 +5703,10 @@ create_variable_info_for_1 (tree decl, const char *name) return vi; } - vi = new_var_info (decl, name); + vi = new_var_info (decl, name, add_id); vi->fullsize = tree_to_uhwi (declsize); + if (fieldstack.length () == 1) + vi->is_full_var = true; for (i = 0, newvi = vi; fieldstack.iterate (i, &fo); ++i, newvi = vi_next (newvi)) @@ -5724,7 +5738,7 @@ create_variable_info_for_1 (tree decl, const char *name) newvi->only_restrict_pointers = fo->only_restrict_pointers; if (i + 1 < fieldstack.length ()) { - varinfo_t tem = new_var_info (decl, name); + varinfo_t tem = new_var_info (decl, name, false); newvi->next = tem->id; tem->head = vi->id; } @@ -5734,9 +5748,9 @@ create_variable_info_for_1 (tree decl, const char *name) } static unsigned int -create_variable_info_for (tree decl, const char *name) +create_variable_info_for (tree decl, const char *name, bool add_id) { - varinfo_t vi = create_variable_info_for_1 (decl, name); + varinfo_t vi = create_variable_info_for_1 (decl, name, add_id); unsigned int id = vi->id; insert_vi_for_tree (decl, vi); @@ -5757,7 +5771,8 @@ create_variable_info_for (tree decl, const char *name) || vi->only_restrict_pointers) { varinfo_t rvi - = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT"); + = make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT", + true); /* ??? For now exclude reads from globals as restrict sources if those are not (indirectly) from incoming parameters. */ rvi->is_restrict_var = false; @@ -5842,6 +5857,21 @@ debug_solution_for_var (unsigned int var) dump_solution_for_var (stderr, var); } +/* Register the constraints for restrict var VI. */ + +static void +make_restrict_var_constraints (varinfo_t vi) +{ + for (; vi; vi = vi_next (vi)) + if (vi->may_have_pointers) + { + if (vi->only_restrict_pointers) + make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT", true); + else + make_copy_constraint (vi, nonlocal_id); + } +} + /* Create varinfo structures for all of the variables in the function for intraprocedural mode. */ @@ -5855,53 +5885,43 @@ intra_create_variable_infos (struct function *fn) passed-by-reference argument. */ for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t)) { - varinfo_t p = get_vi_for_tree (t); + bool restrict_pointer_p = (POINTER_TYPE_P (TREE_TYPE (t)) + && TYPE_RESTRICT (TREE_TYPE (t))); + bool recursive_restrict_p + = (restrict_pointer_p + && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t)))); + varinfo_t p = lookup_vi_for_tree (t); + if (p == NULL) + { + p = create_variable_info_for_1 (t, alias_get_name (t), false); + insert_vi_for_tree (t, p); + } /* For restrict qualified pointers build a representative for the pointed-to object. Note that this ends up handling out-of-bound references conservatively by aggregating them in the first/last subfield of the object. */ - if (POINTER_TYPE_P (TREE_TYPE (t)) - && TYPE_RESTRICT (TREE_TYPE (t)) - && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (t)))) + if (recursive_restrict_p) { - struct constraint_expr lhsc, rhsc; varinfo_t vi; tree heapvar = build_fake_var_decl (TREE_TYPE (TREE_TYPE (t))); DECL_EXTERNAL (heapvar) = 1; - vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS"); + vi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true); vi->is_restrict_var = 1; insert_vi_for_tree (heapvar, vi); - lhsc.var = p->id; - lhsc.type = SCALAR; - lhsc.offset = 0; - rhsc.var = vi->id; - rhsc.type = ADDRESSOF; - rhsc.offset = 0; - process_constraint (new_constraint (lhsc, rhsc)); - for (; vi; vi = vi_next (vi)) - if (vi->may_have_pointers) - { - if (vi->only_restrict_pointers) - make_constraint_from_global_restrict (vi, "GLOBAL_RESTRICT"); - else - make_copy_constraint (vi, nonlocal_id); - } + make_constraint_from (p, vi->id); + make_restrict_var_constraints (vi); continue; } - if (POINTER_TYPE_P (TREE_TYPE (t)) - && TYPE_RESTRICT (TREE_TYPE (t))) - make_constraint_from_global_restrict (p, "PARM_RESTRICT"); - else + for (; p; p = vi_next (p)) { - for (; p; p = vi_next (p)) - { - if (p->only_restrict_pointers) - make_constraint_from_global_restrict (p, "PARM_RESTRICT"); - else if (p->may_have_pointers) - make_constraint_from (p, nonlocal_id); - } + if (p->only_restrict_pointers) + make_constraint_from_global_restrict (p, "PARM_RESTRICT", true); + else if (p->may_have_pointers) + make_constraint_from (p, nonlocal_id); + if (p->is_full_var) + break; } } @@ -6500,7 +6520,7 @@ init_base_vars (void) /* Create the NULL variable, used to represent that a variable points to NULL. */ - var_nothing = new_var_info (NULL_TREE, "NULL"); + var_nothing = new_var_info (NULL_TREE, "NULL", false); gcc_assert (var_nothing->id == nothing_id); var_nothing->is_artificial_var = 1; var_nothing->offset = 0; @@ -6512,7 +6532,7 @@ init_base_vars (void) /* Create the ANYTHING variable, used to represent that a variable points to some unknown piece of memory. */ - var_anything = new_var_info (NULL_TREE, "ANYTHING"); + var_anything = new_var_info (NULL_TREE, "ANYTHING", false); gcc_assert (var_anything->id == anything_id); var_anything->is_artificial_var = 1; var_anything->size = ~0; @@ -6538,7 +6558,7 @@ init_base_vars (void) /* Create the STRING variable, used to represent that a variable points to a string literal. String literals don't contain pointers so STRING doesn't point to anything. */ - var_string = new_var_info (NULL_TREE, "STRING"); + var_string = new_var_info (NULL_TREE, "STRING", false); gcc_assert (var_string->id == string_id); var_string->is_artificial_var = 1; var_string->offset = 0; @@ -6549,7 +6569,7 @@ init_base_vars (void) /* Create the ESCAPED variable, used to represent the set of escaped memory. */ - var_escaped = new_var_info (NULL_TREE, "ESCAPED"); + var_escaped = new_var_info (NULL_TREE, "ESCAPED", false); gcc_assert (var_escaped->id == escaped_id); var_escaped->is_artificial_var = 1; var_escaped->offset = 0; @@ -6559,7 +6579,7 @@ init_base_vars (void) /* Create the NONLOCAL variable, used to represent the set of nonlocal memory. */ - var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL"); + var_nonlocal = new_var_info (NULL_TREE, "NONLOCAL", false); gcc_assert (var_nonlocal->id == nonlocal_id); var_nonlocal->is_artificial_var = 1; var_nonlocal->offset = 0; @@ -6613,7 +6633,7 @@ init_base_vars (void) /* Create the STOREDANYTHING variable, used to represent the set of variables stored to *ANYTHING. */ - var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING"); + var_storedanything = new_var_info (NULL_TREE, "STOREDANYTHING", false); gcc_assert (var_storedanything->id == storedanything_id); var_storedanything->is_artificial_var = 1; var_storedanything->offset = 0; @@ -6623,7 +6643,7 @@ init_base_vars (void) /* Create the INTEGER variable, used to represent that a variable points to what an INTEGER "points to". */ - var_integer = new_var_info (NULL_TREE, "INTEGER"); + var_integer = new_var_info (NULL_TREE, "INTEGER", false); gcc_assert (var_integer->id == integer_id); var_integer->is_artificial_var = 1; var_integer->size = ~0; @@ -7263,7 +7283,7 @@ ipa_pta_execute (void) { struct cgraph_node *node; varpool_node *var; - int from; + unsigned int from = 0; in_ipa_mode = 1; @@ -7275,6 +7295,14 @@ ipa_pta_execute (void) fprintf (dump_file, "\n"); } + if (dump_file) + { + fprintf (dump_file, "Generating generic constraints\n\n"); + dump_constraints (dump_file, from); + fprintf (dump_file, "\n"); + from = constraints.length (); + } + /* Build the constraints. */ FOR_EACH_DEFINED_FUNCTION (node) { @@ -7289,7 +7317,7 @@ ipa_pta_execute (void) gcc_assert (!node->clone_of); vi = create_function_info_for (node->decl, - alias_get_name (node->decl)); + alias_get_name (node->decl), false); node->call_for_symbol_thunks_and_aliases (associate_varinfo_to_alias, vi, true); } @@ -7303,14 +7331,15 @@ ipa_pta_execute (void) get_vi_for_tree (var->decl); } - if (dump_file) + if (dump_file + && from != constraints.length ()) { fprintf (dump_file, "Generating constraints for global initializers\n\n"); - dump_constraints (dump_file, 0); + dump_constraints (dump_file, from); fprintf (dump_file, "\n"); + from = constraints.length (); } - from = constraints.length (); FOR_EACH_DEFINED_FUNCTION (node) { @@ -7395,8 +7424,8 @@ ipa_pta_execute (void) fprintf (dump_file, "\n"); dump_constraints (dump_file, from); fprintf (dump_file, "\n"); + from = constraints.length (); } - from = constraints.length (); } /* From the constraints compute the points-to sets. */ -- 1.9.1