From patchwork Sat Nov 7 12:22:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 541274 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 58A64140324 for ; Sat, 7 Nov 2015 23:22:17 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=s9HRoJu7; 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=B2Mfmz+PTXJqklXY PBAfF2xXp36Zz/8LKxGy2xZZax3HY5BLC7IGl9FEC01ZZfowZX3goALGxVO42p5I k3EYI9s9fGfVlS38SLaNZGVOqcliCJGsyi+9I2Aw4kMcy1XdjurV3FgwbCimBDGJ n4IEPZNpLlllIRD3Wvry/hHvY3w= 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=5IHaV2Pd3eFlxmXBnq9TeS EafQo=; b=s9HRoJu7EXgtpXY3b5LwPEXzUi4ssDp6jA7bVBWB1X0WbZo3cgJI73 wocrDmmSao8Y2tGbxhEn0WWwg9ll7pCHjPZcT2yC4AuJFoyrKX+CbtrQ5h3pvG/V mwXRoXuLIqnt3jghmwZzGQfi7s8KXOzRlkdg3QV1QId9BCstVteOM= Received: (qmail 119848 invoked by alias); 7 Nov 2015 12:22:08 -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 119839 invoked by uid 89); 7 Nov 2015 12:22:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 07 Nov 2015 12:22:05 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-22-qIKI1C7WTTmOtthzGbUJtA-1; Sat, 07 Nov 2015 12:22:00 +0000 Received: from localhost ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Sat, 7 Nov 2015 12:22:00 +0000 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Add a combined_fn enum Date: Sat, 07 Nov 2015 12:22:00 +0000 Message-ID: <87fv0irod3.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-MC-Unique: qIKI1C7WTTmOtthzGbUJtA-1 I'm working on a patch series that needs to be able to treat built-in functions and internal functions in a similar way. This patch adds a new enum, combined_fn, that combines the two together. It also adds utility functions for seeing which combined_fn (if any) is called by a given CALL_EXPR or gcall. Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. OK to install? Thanks, Richard gcc/ * tree-core.h (internal_fn): Move immediately after the definition of built_in_function. (combined_fn): New enum. * tree.h (as_combined_fn, builtin_fn_p, as_builtin_fn) (internal_fn_p, as_internal_fn): New functions. (get_call_combined_fn, combined_fn_name): Declare. * tree.c (get_call_combined_fn): New function. (combined_fn_name): Likewise. * gimple.h (gimple_call_combined_fn): Declare. * gimple.c (gimple_call_combined_fn): New function. diff --git a/gcc/gimple.c b/gcc/gimple.c index 4ce38da..de3520a 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2530,6 +2530,27 @@ gimple_call_builtin_p (const gimple *stmt, enum built_in_function code) return false; } +/* If CALL is a call to a combined_fn (i.e. an internal function or + a normal built-in function), return its code, otherwise return + CFN_LAST. */ + +combined_fn +gimple_call_combined_fn (const gimple *stmt) +{ + if (const gcall *call = dyn_cast (stmt)) + { + if (gimple_call_internal_p (call)) + return as_combined_fn (gimple_call_internal_fn (call)); + + tree fndecl = gimple_call_fndecl (stmt); + if (fndecl + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && gimple_builtin_call_types_compatible_p (stmt, fndecl)) + return as_combined_fn (DECL_FUNCTION_CODE (fndecl)); + } + return CFN_LAST; +} + /* Return true if STMT clobbers memory. STMT is required to be a GIMPLE_ASM. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index 781801b..13cfbce 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1499,6 +1499,7 @@ extern tree gimple_signed_type (tree); extern alias_set_type gimple_get_alias_set (tree); extern bool gimple_ior_addresses_taken (bitmap, gimple *); extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree); +extern combined_fn gimple_call_combined_fn (const gimple *); extern bool gimple_call_builtin_p (const gimple *); extern bool gimple_call_builtin_p (const gimple *, enum built_in_class); extern bool gimple_call_builtin_p (const gimple *, enum built_in_function); diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 954368f..afb53be 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -184,6 +184,35 @@ enum built_in_function { END_BUILTINS }; +/* Internal functions. */ +enum internal_fn { +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE, +#include "internal-fn.def" + IFN_LAST +}; + +/* An enum that combines target-independent built-in functions with + internal functions, so that they can be treated in a similar way. + The numbers for built-in functions are the same as for the + built_in_function enum. The numbers for internal functions + start at END_BUITLINS. */ +enum combined_fn { +#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \ + CFN_##ENUM = int (ENUM), +#include "builtins.def" + +#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) +#define DEF_BUILTIN_CHKP(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \ + CFN_##ENUM##_CHKP = int (ENUM##_CHKP), +#include "builtins.def" + +#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \ + CFN_##CODE = int (END_BUILTINS) + int (IFN_##CODE), +#include "internal-fn.def" + + CFN_LAST +}; + /* Tree code classes. Each tree_code has an associated code class represented by a TREE_CODE_CLASS. */ enum tree_code_class { @@ -766,13 +795,6 @@ enum annot_expr_kind { annot_expr_kind_last }; -/* Internal functions. */ -enum internal_fn { -#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE, -#include "internal-fn.def" - IFN_LAST -}; - /*--------------------------------------------------------------------------- Type definitions ---------------------------------------------------------------------------*/ diff --git a/gcc/tree.c b/gcc/tree.c index 5b9a7bd..94c3a1a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9316,6 +9316,25 @@ get_callee_fndecl (const_tree call) return NULL_TREE; } +/* If CALL_EXPR CALL calls a normal built-in function or an internal function, + return the associated function code, otherwise return CFN_LAST. */ + +combined_fn +get_call_combined_fn (const_tree call) +{ + /* It's invalid to call this function with anything but a CALL_EXPR. */ + gcc_assert (TREE_CODE (call) == CALL_EXPR); + + if (!CALL_EXPR_FN (call)) + return as_combined_fn (CALL_EXPR_IFN (call)); + + tree fndecl = get_callee_fndecl (call); + if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + return as_combined_fn (DECL_FUNCTION_CODE (fndecl)); + + return CFN_LAST; +} + #define TREE_MEM_USAGE_SPACES 40 /* Print debugging information about tree nodes generated during the compile, @@ -13805,5 +13824,18 @@ nonnull_arg_p (const_tree arg) return false; } +/* Return the name of combined function FN, for debugging purposes. */ + +const char * +combined_fn_name (combined_fn fn) +{ + if (builtin_fn_p (fn)) + { + tree fndecl = builtin_decl_explicit (as_builtin_fn (fn)); + return IDENTIFIER_POINTER (DECL_NAME (fndecl)); + } + else + return internal_fn_name (as_internal_fn (fn)); +} #include "gt-tree.h" diff --git a/gcc/tree.h b/gcc/tree.h index 6768b3b..14b46a4 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -22,6 +22,58 @@ along with GCC; see the file COPYING3. If not see #include "tree-core.h" +/* Convert a target-independent built-in function code to a combined_fn. */ + +inline combined_fn +as_combined_fn (built_in_function fn) +{ + return combined_fn (int (fn)); +} + +/* Convert an internal function code to a combined_fn. */ + +inline combined_fn +as_combined_fn (internal_fn fn) +{ + return combined_fn (int (fn) + int (END_BUILTINS)); +} + +/* Return true if CODE is a target-independent built-in function. */ + +inline bool +builtin_fn_p (combined_fn code) +{ + return int (code) < int (END_BUILTINS); +} + +/* Return the target-independent built-in function represented by CODE. + Only valid if builtin_fn_p (CODE). */ + +inline built_in_function +as_builtin_fn (combined_fn code) +{ + gcc_checking_assert (builtin_fn_p (code)); + return built_in_function (int (code)); +} + +/* Return true if CODE is an internal function. */ + +inline bool +internal_fn_p (combined_fn code) +{ + return int (code) >= int (END_BUILTINS); +} + +/* Return the internal function represented by CODE. Only valid if + internal_fn_p (CODE). */ + +inline internal_fn +as_internal_fn (combined_fn code) +{ + gcc_checking_assert (internal_fn_p (code)); + return internal_fn (int (code) - int (END_BUILTINS)); +} + /* Macros for initializing `tree_contains_struct'. */ #define MARK_TS_BASE(C) \ do { \ @@ -4431,6 +4483,7 @@ extern unsigned crc32_unsigned (unsigned, unsigned); extern void clean_symbol_name (char *); extern tree get_file_function_name (const char *); extern tree get_callee_fndecl (const_tree); +extern combined_fn get_call_combined_fn (const_tree); extern int type_num_arguments (const_tree); extern bool associative_tree_code (enum tree_code); extern bool commutative_tree_code (enum tree_code); @@ -4456,6 +4509,7 @@ extern tree lhd_gcc_personality (void); extern void assign_assembler_name_if_neeeded (tree); extern void warn_deprecated_use (tree, tree); extern void cache_integer_cst (tree); +extern const char *combined_fn_name (combined_fn); /* Return the memory model from a host integer. */ static inline enum memmodel