Hi,

Most generated calls to build_libcall don't require any special
conversions from the generic type returned by the library. Add an
overload that calls the library function without doing any nop casts.

Regstrapped on x86_64-linux-gnu, committed to mainline.

Regards,
Iain.

---
gcc/d/ChangeLog:

        * d-tree.h (build_libcall): New declaration.
        * runtime.cc (build_libcall_1): New function.
        (build_libcall): New overload.
        * d-codegen.cc (build_assert_call): Call build_libcall without Type
        argument.
        (build_array_bounds_call): Likewise.
        (build_bounds_index_condition): Likewise.
        (build_bounds_slice_condition): Likewise.
        (build_closure): Likewise.
        * expr.cc (ExprVisitor::visit): Likewise.
        * toir.cc (IRVisitor::visit): Likewise.
---
 gcc/d/d-codegen.cc | 13 ++++++-------
 gcc/d/d-tree.h     |  1 +
 gcc/d/expr.cc      |  7 +++----
 gcc/d/runtime.cc   | 42 +++++++++++++++++++++++++++++++++++-------
 gcc/d/toir.cc      |  5 ++---
 5 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index b22bdef77ce..791918a1ab5 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1994,9 +1994,9 @@ build_assert_call (const Loc &loc, libcall_fn libcall, 
tree msg)
 
 
   if (msg != NULL_TREE)
-    return build_libcall (libcall, Type::tnoreturn, 3, msg, file, line);
+    return build_libcall (libcall, 3, msg, file, line);
   else
-    return build_libcall (libcall, Type::tnoreturn, 2, file, line);
+    return build_libcall (libcall, 2, file, line);
 }
 
 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
@@ -2010,7 +2010,7 @@ build_array_bounds_call (const Loc &loc)
     return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
   else
     {
-      return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tnoreturn, 2,
+      return build_libcall (LIBCALL_ARRAYBOUNDSP, 2,
                            build_filename_from_loc (loc),
                            size_int (loc.linnum ()));
     }
@@ -2039,7 +2039,7 @@ build_bounds_index_condition (IndexExp *ie, tree index, 
tree length)
     boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
   else
     {
-      boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tnoreturn, 
4,
+      boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, 4,
                                 build_filename_from_loc (ie->e2->loc),
                                 size_int (ie->e2->loc.linnum ()),
                                 index, length);
@@ -2088,8 +2088,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, 
tree upper, tree length)
            }
          else
            {
-             boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
-                                        Type::tnoreturn, 5,
+             boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, 5,
                                         build_filename_from_loc (se->loc),
                                         size_int (se->loc.linnum ()),
                                         lower, upper, length);
@@ -2924,7 +2923,7 @@ build_closure (FuncDeclaration *fd)
 
       /* Allocate memory for closure.  */
       tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
-      tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
+      tree init = build_libcall (LIBCALL_ALLOCMEMORY, 1, arg);
 
       tree init_exp = build_assign (INIT_EXPR, decl,
                                    build_nop (TREE_TYPE (decl), init));
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index d4ae94fd693..e6949f37ff2 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -694,6 +694,7 @@ extern void d_defer_declaration (Declaration *);
 extern void d_finish_compilation (tree *, int);
 
 /* In runtime.cc.  */
+extern tree build_libcall (libcall_fn, int ...);
 extern tree build_libcall (libcall_fn, Type *, int ...);
 
 /* In typeinfo.cc.  */
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 8c068b083e5..75a8b4e726d 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -1005,7 +1005,7 @@ public:
   void visit (ThrowExp *e) final override
   {
     tree arg = build_expr_dtor (e->e1);
-    this->result_ = build_libcall (LIBCALL_THROW, Type::tnoreturn, 1, arg);
+    this->result_ = build_libcall (LIBCALL_THROW, 1, arg);
   }
 
   /* Build a postfix expression.  */
@@ -1254,7 +1254,7 @@ public:
        libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
          ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
 
-       this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
+       this->result_ = build_libcall (libcall, 1, t1);
        return;
       }
     else
@@ -1764,8 +1764,7 @@ public:
                if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
                  {
                    arg = d_save_expr (arg);
-                   assert_pass = build_libcall (LIBCALL_INVARIANT,
-                                                Type::tvoid, 1, arg);
+                   assert_pass = build_libcall (LIBCALL_INVARIANT, 1, arg);
                  }
              }
            else if (tb1->ty == TY::Tpointer
diff --git a/gcc/d/runtime.cc b/gcc/d/runtime.cc
index 4fb63f85b5b..5ec59923823 100644
--- a/gcc/d/runtime.cc
+++ b/gcc/d/runtime.cc
@@ -301,24 +301,52 @@ get_libcall (libcall_fn libcall)
   return libcall_decls[libcall];
 }
 
-/* Generate a call to LIBCALL, returning the result as TYPE.  NARGS is the
-   number of call arguments, the expressions of which are provided in `...'.
+
+/* Subroutine of build_libcall; generate a call to LIBCALL.  NARGS is the
+   number of call arguments, the expressions of which are provided in ARGP.
    This does not perform conversions or promotions on the arguments.  */
 
-tree
-build_libcall (libcall_fn libcall, Type *type, int nargs, ...)
+static tree
+build_libcall_1 (libcall_fn libcall, int nargs, va_list argp)
 {
   /* Build the call expression to the runtime function.  */
   tree decl = get_libcall (libcall);
   tree *args = XALLOCAVEC (tree, nargs);
+
+  for (int i = 0; i < nargs; i++)
+    args[i] = va_arg (argp, tree);
+
+  return build_call_expr_loc_array (input_location, decl, nargs, args);
+}
+
+/* Generate a call to LIBCALL.  NARGS is the number of call arguments, the
+   expressions of which are provided in `...'.  */
+
+tree
+build_libcall (libcall_fn libcall, int nargs, ...)
+{
   va_list ap;
 
   va_start (ap, nargs);
-  for (int i = 0; i < nargs; i++)
-    args[i] = va_arg (ap, tree);
+
+  tree result = build_libcall_1 (libcall, nargs, ap);
   va_end (ap);
 
-  tree result = build_call_expr_loc_array (input_location, decl, nargs, args);
+  return result;
+}
+
+/* Generate a call to LIBCALL, returning the result as TYPE.  NARGS is the
+   number of call arguments, the expressions of which are provided in `...'.  
*/
+
+tree
+build_libcall (libcall_fn libcall, Type *type, int nargs, ...)
+{
+  va_list ap;
+
+  va_start (ap, nargs);
+
+  tree result = build_libcall_1 (libcall, nargs, ap);
+  va_end (ap);
 
   /* Assumes caller knows what it is doing.  */
   return convert (build_ctype (type), result);
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index 1ad41cf9368..51f840f3f28 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -1241,7 +1241,7 @@ public:
     else
       arg = build_nop (build_ctype (get_object_type ()), arg);
 
-    add_stmt (build_libcall (LIBCALL_THROW, Type::tnoreturn, 1, arg));
+    add_stmt (build_libcall (LIBCALL_THROW, 1, arg));
   }
 
   /* Build a try-catch statement, one of the building blocks for exception
@@ -1307,8 +1307,7 @@ public:
               the end catch callback.  */
            if (cd->isCPPclass ())
              {
-               tree endcatch = build_libcall (LIBCALL_CXA_END_CATCH,
-                                              Type::tvoid, 0);
+               tree endcatch = build_libcall (LIBCALL_CXA_END_CATCH, 0);
                catchbody = build2 (TRY_FINALLY_EXPR, void_type_node,
                                    catchbody, endcatch);
              }
-- 
2.43.0

Reply via email to