Where to attach backend builtin decl?
FX Coudert
fxcoudert@gmail.com
Fri Feb 29 17:21:00 GMT 2008
> The standard intrinsics can be found in built_in_decls[], while the
> backend decls are saved in some backend arrays. But they are once
> initialized in frontend. What I did is to define a new namepsace
> called gfc_backend_builtin_ns, and save all backend builtins' decls
> in that namespace. Latter in gfc_get_extern_fucntion_decl() I look
> up this namespace and find out its corresponding decl. Perhaps an
> array could do the same job. Actually in f95-lang.c function
> gfc_builtin_function() pushes the decl in current_binding_level.
> Can we get it again from the binding_level? That would avoid the
> trouble with the new namespace.
With help from Jakub on IRC, I got the following working:
Index: f95-lang.c
===================================================================
--- f95-lang.c (revision 132578)
+++ f95-lang.c (working copy)
@@ -723,7 +723,20 @@
implicit_built_in_decls[code] = decl;
}
+/* Look for a function decl with a given name. */
+tree
+find_fndecl_toplevel (tree name)
+{
+ tree t;
+ for (t = global_binding_level->names; t; t = TREE_CHAIN (t))
+ if (TREE_CODE (t) == FUNCTION_DECL && DECL_NAME (t) == name)
+ return t;
+
+ return NULL_TREE;
+}
+
+
#define DO_DEFINE_MATH_BUILTIN(code, name, argtype, tbase) \
gfc_define_builtin ("__builtin_" name "l", tbase##longdouble
[argtype], \
BUILT_IN_ ## code ## L, name "l", true); \
Index: trans.h
===================================================================
--- trans.h (revision 132578)
+++ trans.h (working copy)
@@ -476,6 +476,7 @@
tree gfc_build_library_function_decl (tree, tree, int, ...);
/* somewhere! */
+tree find_fndecl_toplevel (tree);
tree pushdecl (tree);
tree pushdecl_top_level (tree);
void pushlevel (int);
Index: trans-decl.c
===================================================================
--- trans-decl.c (revision 132578)
+++ trans-decl.c (working copy)
@@ -1118,6 +1118,15 @@
to know that. */
gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
+ if (sym->attr.is_bind_c == 1
+ && strncmp (sym->binding_label, "__builtin_", 10) == 0)
+ {
+ sym->backend_decl
+ = find_fndecl_toplevel (get_identifier (sym->binding_label));
+ if (sym->backend_decl)
+ return sym->backend_decl;
+ }
+
if (sym->attr.intrinsic)
{
/* Call the resolution function to get the actual name. This is
The find_fndecl_toplevel() function does the job of getting decls
back from the global_binding_level given their identifier. It works
for the builtins I tried it with (like __builtin_sqrt), and I suppose
it should also work with your backend builtins. That saves us from
storing yet another namespace and using the already existing code.
Can you try it and see if it works for you?
And, in case it fails because the backend builtins are defined in a
contained binding level, we can changed the function to look from the
current binding level upwards, like this:
> +/* Look for a function decl with a given name. */
> +tree
> +find_fndecl (tree name)
> +{
> + struct binding_level *b;
> + tree t;
> +
> + for (b = current_binding_level; b; b = b->level_chain)
> + for (t = b->names; t; t = TREE_CHAIN (t))
> + if (TREE_CODE (t) == FUNCTION_DECL && DECL_NAME (t) == name)
> + return t;
> +
> + return NULL_TREE;
> +}
(I have this code in my own tree because I use it for another patch,
the decl merging issue.) If the first one doesn't work, try this one.
> Following is the patch I have. Certainly in
> gfc_get_extern_function_decl() we need to add a check for standard
> intrinsics, before looking for backend intrinsics.
I think the above solution, which handles all intrinsics without
extra bookkeeping, is a better approach.
>
FX
--
François-Xavier Coudert
http://www.homepages.ucl.ac.uk/~uccafco/
More information about the Fortran
mailing list