summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-17 18:34:47 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-17 18:34:47 +0000
commitbe03bd184a260b3f4d4b0b83676ddf609fa8c641 (patch)
treeb256b1ce82752ff2bfe63d20fcfd0cc3bdde69f8
parent7991eeee5bbef43132820f4cb414690cf804d66f (diff)
downloadgcc-be03bd184a260b3f4d4b0b83676ddf609fa8c641.tar.gz
Add a combined_fn enum
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. 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230472 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/gimple.c21
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/tree-core.h36
-rw-r--r--gcc/tree.c33
-rw-r--r--gcc/tree.h54
6 files changed, 151 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0f56ca48e94..74c7cf939d7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * 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.
+
2015-11-17 Martin Sebor <msebor@redhat.com>
PR c++/68308
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 706b126e5bb..2764df88186 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2531,6 +2531,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 <const gcall *> (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 6486dff03b7..6eb22de1e5e 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1500,6 +1500,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 ff061ef8637..9cc64d92e34 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 1d770c36a7b..29c5f4c9f41 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9317,6 +9317,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,
@@ -13866,4 +13885,18 @@ set_source_range (tree expr, source_range src_range)
SET_EXPR_LOCATION (expr, adhoc);
}
+/* 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 0b9c3b915dc..6a8354e2204 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 { \
@@ -4529,6 +4581,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);
@@ -4554,6 +4607,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