This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,c++] introduce cp_build_function_call_nary


The patch below introduces cp_build_function_call_nary and uses it to
eliminate nearly all of the calls to cp_build_function_call.  The
benefits are fewer uses of TREE_LIST and slightly less consing during
compilation.  cp_build_function_call can't be totally delted at the
moment, as it's used by build_function_call, which is used by the ObjC++
front-end.  I have a WIP patch to convert ObjC{,++} to use a non
TREE_LIST interface, but it's somewhat invasive.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

	* cp-tree.h (cp_build_function_call_nary): Declare.
	* typeck.c (cp_build_function_call_nary): Define.
	* decl.c (register_dtor_fn): Use it instead of
	cp_build_function_call.
	(cxx_maybe_build_cleanup): Likewise.
	* decl2.c (generate_ctor_or_dtor_function): Likewise.
	* except.c (do_get_exception_ptr): Likewise.
	(do_begin_catch): Likewise.
	(do_allocate_exception): Likewise.
	(do_free_exception): Likewise.
	(build_throw): Likewise.  Use cp_build_function_call_vec instead
	of cp_build_function_call.
	(do_end_catch): Likewise.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3e1b310..5c73fa8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5376,6 +5376,8 @@ extern tree cp_build_array_ref			(location_t, tree, tree,
 						 tsubst_flags_t);
 extern tree get_member_function_from_ptrfunc	(tree *, tree);
 extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
+extern tree cp_build_function_call_nary         (tree, tsubst_flags_t,
+						 int n, ...);
 extern tree cp_build_function_call_vec		(tree, VEC(tree,gc) **,
 						 tsubst_flags_t);
 extern tree build_x_binary_op			(enum tree_code, tree,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5420f71..fa81e92 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6241,10 +6241,11 @@ register_dtor_fn (tree decl)
 {
   tree cleanup;
   tree compound_stmt;
-  tree args;
   tree fcall;
   tree type;
   bool use_dtor;
+  tree arg0, arg1 = NULL_TREE, arg2 = NULL_TREE;
+  int nargs;
 
   type = TREE_TYPE (decl);
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
@@ -6322,25 +6323,27 @@ register_dtor_fn (tree decl)
 	   in, and, in general, it's cheaper to pass NULL than any
 	   other value.  */
 	addr = null_pointer_node;
-      args = tree_cons (NULL_TREE,
-			cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
-                                        tf_warning_or_error),
-			NULL_TREE);
+      arg2 = cp_build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0,
+                                tf_warning_or_error);
       if (targetm.cxx.use_aeabi_atexit ())
 	{
-	  args = tree_cons (NULL_TREE, cleanup, args);
-	  args = tree_cons (NULL_TREE, addr, args);
+	  arg1 = cleanup;
+	  arg0 = addr;
 	}
       else
 	{
-	  args = tree_cons (NULL_TREE, addr, args);
-	  args = tree_cons (NULL_TREE, cleanup, args);
+	  arg1 = addr;
+	  arg0 = cleanup;
 	}
+      nargs = 3;
     }
   else
-    args = tree_cons (NULL_TREE, cleanup, NULL_TREE);
-  return cp_build_function_call (get_atexit_node (), args, 
-				 tf_warning_or_error);
+    {
+      arg0 = cleanup;
+      nargs = 1;
+    }
+  return cp_build_function_call_nary (get_atexit_node (), tf_warning_or_error,
+                                      nargs, arg0, arg1, arg2);
 }
 
 /* DECL is a VAR_DECL with static storage duration.  INIT, if present,
@@ -12882,9 +12885,7 @@ cxx_maybe_build_cleanup (tree decl)
       fn = lookup_name (id);
       arg = build_address (decl);
       mark_used (decl);
-      cleanup = cp_build_function_call (fn, build_tree_list (NULL_TREE,
-							     arg),
-					tf_warning_or_error);
+      cleanup = cp_build_function_call_nary (fn, tf_warning_or_error, 1, arg);
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2fd6305..0edb6da 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3276,7 +3276,6 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
 				location_t *locus)
 {
   char function_key;
-  tree arguments;
   tree fndecl;
   tree body;
   size_t i;
@@ -3309,17 +3308,18 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
       /* Calls to pure or const functions will expand to nothing.  */
       if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
 	{
+          tree call;
+
 	  if (! body)
 	    body = start_objects (function_key, priority);
 
-	  arguments = tree_cons (NULL_TREE,
-				 build_int_cst (NULL_TREE, priority),
-				 NULL_TREE);
-	  arguments = tree_cons (NULL_TREE,
-				 build_int_cst (NULL_TREE, constructor_p),
-				 arguments);
-	  finish_expr_stmt (cp_build_function_call (fndecl, arguments,
-						    tf_warning_or_error));
+	  call = cp_build_function_call_nary (fndecl, tf_warning_or_error,
+					      2,
+					      build_int_cst (NULL_TREE,
+                                                             constructor_p),
+					      build_int_cst (NULL_TREE,
+							     priority));
+	  finish_expr_stmt (call);
 	}
     }
 
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index c0867ef..cab287b 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -183,9 +183,8 @@ do_get_exception_ptr (void)
       fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
     }
 
-  return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
-						NULL_TREE),
-				 tf_warning_or_error);
+  return cp_build_function_call_nary (fn, tf_warning_or_error,
+				      1, build_exc_ptr ());
 }
 
 /* Build up a call to __cxa_begin_catch, to tell the runtime that the
@@ -203,9 +202,8 @@ do_begin_catch (void)
       fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
     }
 
-  return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
-						NULL_TREE),
-				 tf_warning_or_error);
+  return cp_build_function_call_nary (fn, tf_warning_or_error,
+				      1, build_exc_ptr ());
 }
 
 /* Returns nonzero if cleaning up an exception of type TYPE (which can be
@@ -243,7 +241,7 @@ do_end_catch (tree type)
       TREE_NOTHROW (fn) = 0;
     }
 
-  cleanup = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
+  cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
 
   return cleanup;
@@ -568,10 +566,8 @@ do_allocate_exception (tree type)
       fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
     }
 
-  return cp_build_function_call (fn, 
-				 tree_cons (NULL_TREE, size_in_bytes (type),
-					    NULL_TREE),
-				 tf_warning_or_error);
+  return cp_build_function_call_nary (fn, tf_warning_or_error,
+				      1, size_in_bytes (type));
 }
 
 /* Call __cxa_free_exception from a cleanup.  This is never invoked
@@ -589,8 +585,7 @@ do_free_exception (tree ptr)
       fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
     }
 
-  return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
-				 tf_warning_or_error);
+  return cp_build_function_call_nary (fn, tf_warning_or_error, 1, ptr);
 }
 
 /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
@@ -668,8 +663,7 @@ build_throw (tree exp)
 	  return error_mark_node;
 	}
       fn = OVL_CURRENT (fn);
-      exp = cp_build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE),
-				    tf_warning_or_error);
+      exp = cp_build_function_call_nary (fn, tf_warning_or_error, 1, exp);
     }
   else if (exp)
     {
@@ -800,11 +794,9 @@ build_throw (tree exp)
       else
 	cleanup = build_int_cst (cleanup_type, 0);
 
-      tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE);
-      tmp = tree_cons (NULL_TREE, throw_type, tmp);
-      tmp = tree_cons (NULL_TREE, ptr, tmp);
       /* ??? Indicate that this function call throws throw_type.  */
-      tmp = cp_build_function_call (fn, tmp, tf_warning_or_error);
+      tmp = cp_build_function_call_nary (fn, tf_warning_or_error,
+					 3, ptr, throw_type, cleanup);
 
       /* Tack on the initialization stuff.  */
       exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp);
@@ -823,7 +815,7 @@ build_throw (tree exp)
 
       /* ??? Indicate that this function call allows exceptions of the type
 	 of the enclosing catch block (if known).  */
-      exp = cp_build_function_call (fn, NULL_TREE, tf_warning_or_error);
+      exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
     }
 
   exp = build1 (THROW_EXPR, void_type_node, exp);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 77cf8fd..96f2c8e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3217,6 +3217,26 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
   return ret;
 }
 
+/* Build a function call using varargs.  */
+
+tree
+cp_build_function_call_nary (tree function, tsubst_flags_t complain,
+                             int nargs, ...)
+{
+  VEC(tree,gc) *vec;
+  va_list args;
+  tree ret;
+  int i;
+
+  vec = make_tree_vector ();
+  va_start (args, nargs);
+  for (i = 0; i < nargs; i++)
+    VEC_safe_push (tree, gc, vec, va_arg (args, tree));
+  ret = cp_build_function_call_vec (function, &vec, complain);
+  release_tree_vector (vec);
+  return ret;
+}
+
 /* Build a function call using a vector of arguments.  PARAMS may be
    NULL if there are no parameters.  This changes the contents of
    PARAMS.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]