Where to attach backend builtin decl?
Sa Liu
SALIU@de.ibm.com
Fri Feb 29 16:53:00 GMT 2008
> I was so intrigued that this doesn't work that I have tried it
> myself... and it works!
Thank you for the quick reply and it's really helpful!
I finally figured out the reason it failed with the spu_add_int function
is that the backend parameter checking was not working correctly. I tried
another procedure without input parameter, and it worked fine! So this
should be the right place to substitute the decl.
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.
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.
Index: gcc/gcc/fortran/f95-lang.c
===================================================================
--- gcc.orig/gcc/fortran/f95-lang.c
+++ gcc/gcc/fortran/f95-lang.c
@@ -99,6 +99,7 @@ void insert_block (tree);
static void gfc_clear_binding_stack (void);
static void gfc_be_parse_file (int);
static alias_set_type gfc_get_alias_set (tree);
+static tree save_backend_decl (tree);
#undef LANG_HOOKS_NAME
#undef LANG_HOOKS_INIT
@@ -188,6 +189,8 @@ const char *const tree_code_name[] = {
static GTY(()) struct binding_level *free_binding_level;
+struct gfc_namespace *gfc_backend_builtins_ns;
+
/* The elements of `ridpointers' are identifier nodes
for the reserved type names and storage classes.
It is indexed by a RID_... value. */
@@ -693,6 +696,33 @@ gfc_get_alias_set (tree t)
int ggc_p = 1;
+/* Keep backend builtin decls in backend builtins namespace. */
+tree
+save_backend_decl (tree decl)
+{
+ gfc_namespace *ns;
+ gfc_symbol *sym;
+ const char *name;
+ gfc_symtree *st;
+
+ name = IDENTIFIER_POINTER (DECL_NAME (decl));
+ ns = gfc_backend_builtins_ns;
+
+ if (ns == NULL)
+ {
+ ns = gfc_get_namespace (NULL, 0);
+ gfc_backend_builtins_ns = ns;
+ }
+ gfc_find_sym_tree (name, ns, 0, &st);
+ if (st == NULL)
+ st = gfc_new_symtree (&ns->sym_root, name);
+ sym = gfc_new_symbol (name, ns);
+ sym->backend_decl = decl;
+ st->n.sym = sym;
+
+ return decl;
+}
+
/* Builtin function initialization. */
tree
@@ -700,6 +730,9 @@ gfc_builtin_function (tree decl)
{
make_decl_rtl (decl);
pushdecl (decl);
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
+ save_backend_decl (decl);
+
return decl;
}
Index: gcc/gcc/fortran/gfortran.h
===================================================================
--- gcc.orig/gcc/fortran/gfortran.h
+++ gcc/gcc/fortran/gfortran.h
@@ -1201,6 +1201,8 @@ gfc_namespace;
extern gfc_namespace *gfc_current_ns;
+extern gfc_namespace *gfc_backend_builtins_ns;
+
/* Global symbols are symbols of global scope. Currently we only use
this to detect collisions already when parsing.
TODO: Extend to verify procedure calls. */
Index: gcc/gcc/fortran/trans-decl.c
===================================================================
--- gcc.orig/gcc/fortran/trans-decl.c
+++ gcc/gcc/fortran/trans-decl.c
@@ -65,6 +65,7 @@ static GTY(()) tree saved_parent_functio
static gfc_namespace *module_namespace;
+static tree find_backend_builtin (gfc_symtree *st, gfc_symbol * sym);
/* List of static constructor functions. */
@@ -1113,6 +1114,18 @@ gfc_get_extern_function_decl (gfc_symbol
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))
+ {
+ /* When a procedure is BIND(C) and its binding label starts with
+ "__builtin_", it is translated into a call to the builtin of
+ the same name. */
+ sym->backend_decl
+ = find_backend_builtin (gfc_backend_builtins_ns->sym_root,
sym);
+ if (sym->backend_decl)
+ return sym->backend_decl;
+ }
+
if (sym->attr.intrinsic)
{
/* Call the resolution function to get the actual name. This is
@@ -1347,6 +1360,26 @@ build_function_decl (gfc_symbol * sym)
sym->backend_decl = fndecl;
}
+static tree
+find_backend_builtin (gfc_symtree *st, gfc_symbol * sym)
+{
+ tree fndecl = NULL;
+
+ if (st == NULL)
+ return NULL;
+
+ fndecl = find_backend_builtin (st->right, sym);
+ if (fndecl != NULL)
+ return fndecl;
+ fndecl = find_backend_builtin (st->left, sym);
+ if (fndecl != NULL)
+ return fndecl;
+
+ if (!strcmp(st->n.sym->name, sym->binding_label))
+ return st->n.sym->backend_decl;
+
+ return fndecl;
+}
/* Create the DECL_ARGUMENTS for a procedure. */
More information about the Fortran
mailing list