From patchwork Sun Nov 1 18:20:00 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: 538805 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 2E219140323 for ; Mon, 2 Nov 2015 05:20:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=jDThHAhu; 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=NRS6aLTa6CXtOZ3TV GuRr/hBAMkcVHlCtJ1WGqI1NHwEtdRUAdNrKoYxDaHlIbF3IHlPoamHEc4NmOFY8 NNtbpdX42Uq5BqmumBM+ROmdcHVxroovLdqWbmz2eVJZyVtv6AZo5bwVX6NOvf9s 6aTfqsQzf6iu109IvDEx77jmF8= 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=Bh3i9wnEUlGnm9kUdTkdjBn cggo=; b=jDThHAhus5P+nvIbNsfj+lNVW0VfLJ4HODskmPCs/j8tUPm5ebEwx23 3ah86pIU/hBql74tIdylr4ictg1qO0YL294CLLILQFyJ2tLFGigWAK+MlTJA8k23 mOb0CPGBfuwpKKKdDWWn8RH8vVzfgkgwNnrRQADtp8b7VPWQxo2g= Received: (qmail 62351 invoked by alias); 1 Nov 2015 18:20:24 -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 62340 invoked by uid 89); 1 Nov 2015 18:20:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS, T_RP_MATCHES_RCVD 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; Sun, 01 Nov 2015 18:20:21 +0000 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52250) by fencepost.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1ZsxEo-0006HI-Se for gcc-patches@gnu.org; Sun, 01 Nov 2015 13:20:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZsxEj-0008TO-GO for gcc-patches@gnu.org; Sun, 01 Nov 2015 13:20:18 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:55289) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsxEj-0008TI-6n for gcc-patches@gnu.org; Sun, 01 Nov 2015 13:20:13 -0500 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 1ZsxEh-0001GG-RF from Tom_deVries@mentor.com ; Sun, 01 Nov 2015 10:20:12 -0800 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; Sun, 1 Nov 2015 18:20:10 +0000 Subject: [PATCH, 2/2] Handle recursive restrict in function parameter To: Richard Biener References: <562E0CF5.8000606@mentor.com> <562E5381.5@mentor.com> <562F26E2.40906@mentor.com> <562F6D1A.4010001@mentor.com> <562F748D.5020507@mentor.com> <563653F5.9090302@mentor.com> CC: Richard Biener , "gcc-patches@gnu.org" From: Tom de Vries Message-ID: <563657D0.1030203@mentor.com> Date: Sun, 1 Nov 2015 19:20:00 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <563653F5.9090302@mentor.com> X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 On 01/11/15 19:03, Tom de Vries wrote: > So, the new patch series is: > > 1 Rename make_restrict_var_constraints to make_param_constraints > 2 Handle recursive restrict in function parameter > > I'll repost in reply to this message. > This patch adds handling of all the restrict qualifiers in the type of a function parameter. Thanks, - Tom Handle recursive restrict in function parameter * tree-ssa-structalias.c (struct fieldoff): Add restrict_var field. (push_fields_onto_fieldstack): Add and handle handle_param parameter. (create_variable_info_for_1): Add and handle handle_param parameter. Add extra arg to call to push_fields_onto_fieldstack. Handle restrict pointer fields. (create_variable_info_for): Call create_variable_info_for_1 with extra arg. (make_param_constraints): Drop restrict_name parameter. Ignore vi->only_restrict_pointers. (intra_create_variable_infos): Call create_variable_info_for_1 with extra arg. Remove restrict handling. Call make_param_constraints with one less arg. * gcc.dg/tree-ssa/restrict-7.c: New test. * gcc.dg/tree-ssa/restrict-8.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c | 12 +++++ gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c | 17 ++++++ gcc/tree-ssa-structalias.c | 87 ++++++++++++++++++------------ 3 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c new file mode 100644 index 0000000..f7a68c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-7.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +int +f (int *__restrict__ *__restrict__ *__restrict__ a, int *b) +{ + *b = 1; + ***a = 2; + return *b; +} + +/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c new file mode 100644 index 0000000..b0ab164 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-8.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +struct s +{ + int *__restrict__ *__restrict__ pp; +}; + +int +f (struct s s, int *b) +{ + *b = 1; + **s.pp = 2; + return *b; +} + +/* { dg-final { scan-tree-dump-times "return 1" 1 "fre1" } } */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index ea34764..f4e9b0a 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -320,6 +320,7 @@ static varinfo_t first_or_preceding_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT); static varinfo_t lookup_vi_for_tree (tree); static inline bool type_can_have_subvars (const_tree); +static void make_param_constraints (varinfo_t, bool); /* Pool of variable info structures. */ static object_allocator variable_info_pool @@ -406,6 +407,7 @@ new_var_info (tree t, const char *name, bool add_id) return ret; } +static varinfo_t create_variable_info_for_1 (tree, const char *, bool, bool); /* A map mapping call statements to per-stmt variables for uses and clobbers specific to the call. */ @@ -5208,6 +5210,8 @@ struct fieldoff unsigned may_have_pointers : 1; unsigned only_restrict_pointers : 1; + + varinfo_t restrict_var; }; typedef struct fieldoff fieldoff_s; @@ -5302,11 +5306,12 @@ field_must_have_pointers (tree t) OFFSET is used to keep track of the offset in this entire structure, rather than just the immediately containing structure. Returns false if the caller is supposed to handle the field we - recursed for. */ + recursed for. If HANDLE_PARAM is set, we're handling part of a function + parameter. */ static bool push_fields_onto_fieldstack (tree type, vec *fieldstack, - HOST_WIDE_INT offset) + HOST_WIDE_INT offset, bool handle_param) { tree field; bool empty_p = true; @@ -5332,7 +5337,7 @@ push_fields_onto_fieldstack (tree type, vec *fieldstack, || TREE_CODE (field_type) == UNION_TYPE) push = true; else if (!push_fields_onto_fieldstack - (field_type, fieldstack, offset + foff) + (field_type, fieldstack, offset + foff, handle_param) && (DECL_SIZE (field) && !integer_zerop (DECL_SIZE (field)))) /* Empty structures may have actual size, like in C++. So @@ -5353,7 +5358,8 @@ push_fields_onto_fieldstack (tree type, vec *fieldstack, if (!pair && offset + foff != 0) { - fieldoff_s e = {0, offset + foff, false, false, false, false}; + fieldoff_s e = {0, offset + foff, false, false, false, false, + NULL}; pair = fieldstack->safe_push (e); } @@ -5387,6 +5393,19 @@ push_fields_onto_fieldstack (tree type, vec *fieldstack, = (!has_unknown_size && POINTER_TYPE_P (field_type) && TYPE_RESTRICT (field_type)); + if (handle_param + && e.only_restrict_pointers + && !type_contains_placeholder_p (TREE_TYPE (field_type))) + { + varinfo_t rvi; + tree heapvar = build_fake_var_decl (TREE_TYPE (field_type)); + DECL_EXTERNAL (heapvar) = 1; + rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", + true, true); + rvi->is_restrict_var = 1; + insert_vi_for_tree (heapvar, rvi); + e.restrict_var = rvi; + } fieldstack->safe_push (e); } } @@ -5655,10 +5674,11 @@ check_for_overlaps (vec fieldstack) /* Create a varinfo structure for NAME and DECL, and add it to VARMAP. This will also create any varinfo structures necessary for fields - of DECL. */ + of DECL. DECL is a function parameter if HANDLE_PARAM is set. */ static varinfo_t -create_variable_info_for_1 (tree decl, const char *name, bool add_id) +create_variable_info_for_1 (tree decl, const char *name, bool add_id, + bool handle_param) { varinfo_t vi, newvi; tree decl_type = TREE_TYPE (decl); @@ -5692,7 +5712,7 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id) bool notokay = false; unsigned int i; - push_fields_onto_fieldstack (decl_type, &fieldstack, 0); + push_fields_onto_fieldstack (decl_type, &fieldstack, 0, handle_param); for (i = 0; !notokay && fieldstack.iterate (i, &fo); i++) if (fo->has_unknown_size @@ -5734,6 +5754,19 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id) if (POINTER_TYPE_P (TREE_TYPE (decl)) && TYPE_RESTRICT (TREE_TYPE (decl))) vi->only_restrict_pointers = 1; + if (vi->only_restrict_pointers + && !type_contains_placeholder_p (TREE_TYPE (TREE_TYPE (decl))) + && handle_param) + { + varinfo_t rvi; + tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type)); + DECL_EXTERNAL (heapvar) = 1; + rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, true); + rvi->is_restrict_var = 1; + insert_vi_for_tree (heapvar, rvi); + make_constraint_from (vi, rvi->id); + make_param_constraints (rvi, false); + } fieldstack.release (); return vi; } @@ -5771,6 +5804,13 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id) newvi->fullsize = vi->fullsize; newvi->may_have_pointers = fo->may_have_pointers; newvi->only_restrict_pointers = fo->only_restrict_pointers; + if (handle_param + && newvi->only_restrict_pointers + && fo->restrict_var != NULL) + { + make_constraint_from (newvi, fo->restrict_var->id); + make_param_constraints (fo->restrict_var, false); + } if (i + 1 < fieldstack.length ()) { varinfo_t tem = new_var_info (decl, name, false); @@ -5785,7 +5825,7 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id) static unsigned int create_variable_info_for (tree decl, const char *name, bool add_id) { - varinfo_t vi = create_variable_info_for_1 (decl, name, add_id); + varinfo_t vi = create_variable_info_for_1 (decl, name, add_id, false); unsigned int id = vi->id; insert_vi_for_tree (decl, vi); @@ -5897,12 +5937,12 @@ debug_solution_for_var (unsigned int var) as the base name of created restrict vars. */ static void -make_param_constraints (varinfo_t vi, bool toplevel, const char *restrict_name) +make_param_constraints (varinfo_t vi, bool toplevel) { for (; vi; vi = vi_next (vi)) { if (vi->only_restrict_pointers) - make_constraint_from_global_restrict (vi, restrict_name, true); + ; else if (vi->may_have_pointers) { if (toplevel) @@ -5929,32 +5969,11 @@ intra_create_variable_infos (struct function *fn) passed-by-reference argument. */ for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (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 = create_variable_info_for_1 (t, alias_get_name (t), false); + varinfo_t p + = create_variable_info_for_1 (t, alias_get_name (t), false, true); 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 (recursive_restrict_p) - { - 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", true); - vi->is_restrict_var = 1; - insert_vi_for_tree (heapvar, vi); - make_constraint_from (p, vi->id); - make_param_constraints (vi, false, "GLOBAL_RESTRICT"); - continue; - } - - make_param_constraints (p, true, "PARM_RESTRICT"); + make_param_constraints (p, true); } /* Add a constraint for a result decl that is passed by reference. */ -- 1.9.1