From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13885 invoked by alias); 8 Aug 2014 06:11:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 13868 invoked by uid 89); 8 Aug 2014 06:11:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mailout2.w1.samsung.com Received: from mailout2.w1.samsung.com (HELO mailout2.w1.samsung.com) (210.118.77.12) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Fri, 08 Aug 2014 06:11:28 +0000 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N9Z00IWZ56HN790@mailout2.w1.samsung.com>; Fri, 08 Aug 2014 07:11:05 +0100 (BST) Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id FD.92.25543.B0A64E35; Fri, 08 Aug 2014 07:11:23 +0100 (BST) Received: from [106.109.9.145] by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0N9Z00IJL56ZDX00@eusync3.samsung.com>; Fri, 08 Aug 2014 07:11:23 +0100 (BST) Message-id: <53E46A0D.6020602@samsung.com> Date: Fri, 08 Aug 2014 06:11:00 -0000 From: Yury Gribov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-version: 1.0 To: Richard Biener , Jakub Jelinek Cc: GCC Patches , Konstantin Serebryany , Dmitry Vyukov , Viacheslav Garbuzov , Marek Polacek Subject: [PATCH 1/2] Support fnspecs for internal functions References: <53C922DE.6020000@samsung.com> <53CE720A.4030002@samsung.com> <20140723200935.GB2397@laptop.redhat.com> <53D0A5DA.4020301@samsung.com> <20140724074851.GD2397@laptop.redhat.com> <53D65AB0.4090807@samsung.com> <20140801071757.GC7393@tucnak.redhat.com> In-reply-to: Content-type: multipart/mixed; boundary=------------060408050801000708010806 X-IsSubscribed: yes X-SW-Source: 2014-08/txt/msg00865.txt.bz2 This is a multi-part message in MIME format. --------------060408050801000708010806 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 503 Hi all, Following discussion in https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00016.html this patch adds support for fnspecs to internal function machinery which should (hopefully) allow compiler to perform better analysis and optimization of this construct. For now the only internal functions using this machinery would be UBSAN_NULL and ASAN_CHECK (both would take EAF_DIRECT and EAF_NOESCAPE for their pointer argument). The patch was bootstrapped and regtested on x64. Ok for trunk? -Y --------------060408050801000708010806 Content-Type: text/x-diff; name="ifn_fnspec-1.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ifn_fnspec-1.diff" Content-length: 9046 commit b90c4abf0b804c60b548f94fe59118d029363140 Author: Yury Gribov Date: Wed Aug 6 11:05:39 2014 +0400 Added fnspec to internal functions. 2014-08-08 Yury Gribov * gimple.c (gimple_call_fnspec): Support internal functions. (gimple_call_return_flags): Use const. * Makefile.in: Add internal-fn.h to list of GC files. * internal-fn.def: Add fnspec information. * internal-fn.h (internal_fn_fnspec): New function. (init_internal_fns): Declare new function. * internal-fn.c (internal_fn_fnspec_array): New global variable. (init_internal_fns): New function. * tree-core.h: Update macro call. * tree.c (build_common_builtin_nodes): Initialize internal fns. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index a2fb5f5..67b497f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2297,7 +2297,9 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/vtable-verify.c \ $(srcdir)/asan.c \ $(srcdir)/ubsan.c \ - $(srcdir)/tsan.c $(srcdir)/ipa-devirt.c \ + $(srcdir)/tsan.c \ + $(srcdir)/ipa-devirt.c \ + $(srcdir)/internal-fn.h \ @all_gtfiles@ # Compute the list of GT header files from the corresponding C sources, diff --git a/gcc/gimple.c b/gcc/gimple.c index 4a9d379..4763a59 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1327,11 +1327,14 @@ gimple_call_flags (const_gimple stmt) /* Return the "fn spec" string for call STMT. */ -static tree +static const_tree gimple_call_fnspec (const_gimple stmt) { tree type, attr; + if (gimple_call_internal_p (stmt)) + return internal_fn_fnspec (gimple_call_internal_fn (stmt)); + type = gimple_call_fntype (stmt); if (!type) return NULL_TREE; @@ -1348,7 +1351,7 @@ gimple_call_fnspec (const_gimple stmt) int gimple_call_arg_flags (const_gimple stmt, unsigned arg) { - tree attr = gimple_call_fnspec (stmt); + const_tree attr = gimple_call_fnspec (stmt); if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr)) return 0; @@ -1382,7 +1385,7 @@ gimple_call_arg_flags (const_gimple stmt, unsigned arg) int gimple_call_return_flags (const_gimple stmt) { - tree attr; + const_tree attr; if (gimple_call_flags (stmt) & ECF_MALLOC) return ERF_NOALIAS; diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 78f59d6..b58b868 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see /* The names of each internal function, indexed by function number. */ const char *const internal_fn_name_array[] = { -#define DEF_INTERNAL_FN(CODE, FLAGS) #CODE, +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE, #include "internal-fn.def" #undef DEF_INTERNAL_FN "" @@ -48,12 +48,26 @@ const char *const internal_fn_name_array[] = { /* The ECF_* flags of each internal function, indexed by function number. */ const int internal_fn_flags_array[] = { -#define DEF_INTERNAL_FN(CODE, FLAGS) FLAGS, +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS, #include "internal-fn.def" #undef DEF_INTERNAL_FN 0 }; +/* Fnspec of each internal function, indexed by function number. */ +const_tree internal_fn_fnspec_array[IFN_LAST + 1]; + +void +init_internal_fns () +{ +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \ + if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \ + build_string ((int) sizeof (FNSPEC) + 1, FNSPEC ? FNSPEC : ""); +#include "internal-fn.def" +#undef DEF_INTERNAL_FN + internal_fn_fnspec_array[IFN_LAST] = 0; +} + /* ARRAY_TYPE is an array of vector modes. Return the associated insn for load-lanes-style optab OPTAB. The insn must exist. */ @@ -897,7 +911,7 @@ expand_BUILTIN_EXPECT (gimple stmt) where STMT is the statement that performs the call. */ static void (*const internal_fn_expanders[]) (gimple) = { -#define DEF_INTERNAL_FN(CODE, FLAGS) expand_##CODE, +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE, #include "internal-fn.def" #undef DEF_INTERNAL_FN 0 diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index f0766bc..9857542 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -28,29 +28,30 @@ along with GCC; see the file COPYING3. If not see Each entry in this file has the form: - DEF_INTERNAL_FN (NAME, FLAGS) + DEF_INTERNAL_FN (NAME, FLAGS, FNSPEC) - where NAME is the name of the function and FLAGS is a set of - ECF_* flags. Each entry must have a corresponding expander - of the form: + where NAME is the name of the function, FLAGS is a set of + ECF_* flags and FNSPEC is a string describing functions fnspec. + + Each entry must have a corresponding expander of the form: void expand_NAME (gimple stmt) where STMT is the statement that performs the call. */ -DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF) -DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF) -DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF) -DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF) -DEF_INTERNAL_FN (ANNOTATE, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (UBSAN_BOUNDS, ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW) -DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN) -DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW) +DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF, NULL) +DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF, NULL) +DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF, NULL) +DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF, NULL) +DEF_INTERNAL_FN (ANNOTATE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, ".W.") +DEF_INTERNAL_FN (UBSAN_BOUNDS, ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) +DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL) +DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h index 2dcf44e..14573aa 100644 --- a/gcc/internal-fn.h +++ b/gcc/internal-fn.h @@ -20,6 +20,12 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_INTERNAL_FN_H #define GCC_INTERNAL_FN_H +#include "coretypes.h" + +/* Initialize internal function tables. */ + +extern void init_internal_fns (); + /* Return the name of internal function FN. The name is only meaningful for dumps; it has no linkage. */ @@ -41,6 +47,16 @@ internal_fn_flags (enum internal_fn fn) return internal_fn_flags_array[(int) fn]; } +/* Return fnspec for function FN. */ + +extern GTY(()) const_tree internal_fn_fnspec_array[IFN_LAST + 1]; + +static inline const_tree +internal_fn_fnspec (enum internal_fn fn) +{ + return internal_fn_fnspec_array[(int) fn]; +} + extern void expand_internal_call (gimple); #endif diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 9d462d1..9e9ca8c 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -667,7 +667,7 @@ enum annot_expr_kind { /* Internal functions. */ enum internal_fn { -#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE, +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE, #include "internal-fn.def" #undef DEF_INTERNAL_FN IFN_LAST diff --git a/gcc/tree.c b/gcc/tree.c index d95cf78..1545a86 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9870,8 +9870,9 @@ local_define_builtin (const char *name, tree type, enum built_in_function code, } /* Call this function after instantiating all builtins that the language - front end cares about. This will build the rest of the builtins that - are relied upon by the tree optimizers and the middle-end. */ + front end cares about. This will build the rest of the builtins + and internal function that are relied upon by the tree optimizers and + the middle-end. */ void build_common_builtin_nodes (void) @@ -10104,6 +10105,8 @@ build_common_builtin_nodes (void) ECF_CONST | ECF_NOTHROW | ECF_LEAF); } } + + init_internal_fns (); } /* HACK. GROSS. This is absolutely disgusting. I wish there was a --------------060408050801000708010806--