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