summaryrefslogtreecommitdiff
path: root/gcc/langhooks.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-10-29 08:39:33 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-10-29 08:39:33 +0000
commit740785381ec9944c861dcc29b420c96aa933f040 (patch)
tree00a84533bfa0cdcce1c5eb24f16e6bfe9f0f54cf /gcc/langhooks.c
parent891966480630f58f115825c31badc59dd18d5eb9 (diff)
Add a simulate_builin_function_decl langhook
Although it's possible to define the SVE intrinsics in a normal header file, it's much more convenient to define them directly in the compiler. This also speeds up compilation and gives better error messages. The idea is therefore for arm_sve.h (the main intrinsics header file) to have the pragma: #pragma GCC aarch64 "arm_sve.h" telling GCC to define (almost) everything arm_sve.h needs to define. The target then needs a way of injecting new built-in function declarations during compilation. The main hook for defining built-in functions is add_builtin_function. This is designed for use at start-up, and so has various features that are correct in that context but not for the pragma above: (1) the location is always BUILTINS_LOCATION, whereas for arm_sve.h it ought to be the location of the pragma. (2) the function is only immediately visible if it's in the implementation namespace, whereas the pragma is deliberately injecting functions into the general namespace. (3) there's no attempt to emulate a normal function declaration in C or C++, whereas functions declared by the pragma should be checked in the same way as an open-coded declaration would be. E.g. we should get an error if there was a previous incompatible declaration. (4) in C++, the function is treated as extern "C" and so can't be overloaded, whereas SVE intrinsics do use function overloading. This patch therefore adds a hook that targets can use to inject the equivalent of a source-level function declaration, but bound to a BUILT_IN_MD function. The main SVE intrinsic patch has tests to make sure that we report an error for conflicting definitions that appear either before or after including arm_sve.h. 2019-10-29 Richard Sandiford <richard.sandiford@arm.com> gcc/ * langhooks.h (lang_hooks::simulate_builtin_function_decl): New hook. (simulate_builtin_function_decl): Declare. * langhooks-def.h (LANG_HOOKS_SIMULATE_BUILTIN_FUNCTION_DECL): Define. (LANG_HOOKS_INITIALIZER): Include it. * langhooks.c (add_builtin_function_common): Rename to... (build_builtin_function): ...this. Add a location parameter and use it instead of BUILTINS_LOCATION. Remove the hook parameter and return the decl instead. (add_builtin_function): Update accordingly, passing the returned decl to the lang hook. (add_builtin_function_ext_scope): Likewise (simulate_builtin_function_decl): New function. gcc/c/ * c-tree.h (c_simulate_builtin_function_decl): Declare. * c-decl.c (c_simulate_builtin_function_decl): New function. * c-objc-common.h (LANG_HOOKS_SIMULATE_BUILTIN_FUNCTION_DECL): Define to the above. gcc/cp/ * cp-tree.h (cxx_simulate_builtin_function_decl): Declare. * decl.c (cxx_simulate_builtin_function_decl): New function. * cp-objcp-common.h (LANG_HOOKS_SIMULATE_BUILTIN_FUNCTION_DECL): Define to the above. From-SVN: r277554
Diffstat (limited to 'gcc/langhooks.c')
-rw-r--r--gcc/langhooks.c63
1 files changed, 45 insertions, 18 deletions
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 89fb5bc3ad8..2230e151e63 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -599,19 +599,16 @@ lhd_omp_mappable_type (tree type)
return true;
}
-/* Common function for add_builtin_function and
- add_builtin_function_ext_scope. */
+/* Common function for add_builtin_function, add_builtin_function_ext_scope
+ and simulate_builtin_function_decl. */
+
static tree
-add_builtin_function_common (const char *name,
- tree type,
- int function_code,
- enum built_in_class cl,
- const char *library_name,
- tree attrs,
- tree (*hook) (tree))
+build_builtin_function (location_t location, const char *name, tree type,
+ int function_code, enum built_in_class cl,
+ const char *library_name, tree attrs)
{
tree id = get_identifier (name);
- tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, id, type);
+ tree decl = build_decl (location, FUNCTION_DECL, id, type);
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
@@ -632,8 +629,7 @@ add_builtin_function_common (const char *name,
else
decl_attributes (&decl, NULL_TREE, 0);
- return hook (decl);
-
+ return decl;
}
/* Create a builtin function. */
@@ -646,9 +642,9 @@ add_builtin_function (const char *name,
const char *library_name,
tree attrs)
{
- return add_builtin_function_common (name, type, function_code, cl,
- library_name, attrs,
- lang_hooks.builtin_function);
+ tree decl = build_builtin_function (BUILTINS_LOCATION, name, type,
+ function_code, cl, library_name, attrs);
+ return lang_hooks.builtin_function (decl);
}
/* Like add_builtin_function, but make sure the scope is the external scope.
@@ -666,9 +662,40 @@ add_builtin_function_ext_scope (const char *name,
const char *library_name,
tree attrs)
{
- return add_builtin_function_common (name, type, function_code, cl,
- library_name, attrs,
- lang_hooks.builtin_function_ext_scope);
+ tree decl = build_builtin_function (BUILTINS_LOCATION, name, type,
+ function_code, cl, library_name, attrs);
+ return lang_hooks.builtin_function_ext_scope (decl);
+}
+
+/* Simulate a declaration of a target-specific built-in function at
+ location LOCATION, as though it had been declared directly in the
+ source language. NAME is the name of the function, TYPE is its function
+ type, FUNCTION_CODE is the target-specific function code, LIBRARY_NAME
+ is the name of the underlying library function (NULL if none) and
+ ATTRS is a list of function attributes.
+
+ Return the decl of the declared function. */
+
+tree
+simulate_builtin_function_decl (location_t location, const char *name,
+ tree type, int function_code,
+ const char *library_name, tree attrs)
+{
+ tree decl = build_builtin_function (location, name, type,
+ function_code, BUILT_IN_MD,
+ library_name, attrs);
+ tree new_decl = lang_hooks.simulate_builtin_function_decl (decl);
+
+ /* Give the front end a chance to create a new decl if necessary,
+ but if the front end discards the decl in favour of a conflicting
+ (erroneous) previous definition, return the decl that we tried but
+ failed to add. This allows the caller to process the returned decl
+ normally, even though the source code won't be able to use it. */
+ if (TREE_CODE (new_decl) == FUNCTION_DECL
+ && fndecl_built_in_p (new_decl, function_code, BUILT_IN_MD))
+ return new_decl;
+
+ return decl;
}
tree