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