From a0c4a73410a988fa770fbd265f030c2007d63aa1 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Wed, 23 Aug 2023 18:52:05 +0300
Subject: [PATCH v1 4/4] vectorize list_make* functions

---
 src/backend/nodes/list.c    |  70 +++++++++++-----------
 src/include/nodes/pg_list.h | 112 +++++++++++++-----------------------
 2 files changed, 75 insertions(+), 107 deletions(-)

diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index 750ee5a7e5..9e616d7e4c 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -229,67 +229,69 @@ enlarge_list(List *list, int min_size)
 
 /*
  * Convenience functions to construct short Lists from given values.
- * (These are normally invoked via the list_makeN macros.)
+ * (These are normally invoked via the list_make* macros.)
  */
+#define list_make_ptr_cell(v)	((ListCell) {.ptr_value = (v)})
+#define list_make_int_cell(v)	((ListCell) {.int_value = (v)})
+#define list_make_oid_cell(v)	((ListCell) {.oid_value = (v)})
+#define list_make_xid_cell(v)	((ListCell) {.xid_value = (v)})
+
 List *
-list_make1_impl(NodeTag t, ListCell datum1)
+list_make_impl(NodeTag t, int n, ...)
 {
-	List	   *list = new_list(t, 1);
+	List	   *list = new_list(t, n);
 
-	list->elements[0] = datum1;
-	check_list_invariants(list);
-	return list;
-}
+	va_list datum;
+	va_start(datum, n);
 
-List *
-list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2)
-{
-	List	   *list = new_list(t, 2);
+	for (int i = 0; i < n; i++)
+		list->elements[i] = list_make_ptr_cell(va_arg(datum, void *));
 
-	list->elements[0] = datum1;
-	list->elements[1] = datum2;
 	check_list_invariants(list);
 	return list;
 }
 
 List *
-list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2,
-				ListCell datum3)
+list_make_int_impl(NodeTag t, int n, ...)
 {
-	List	   *list = new_list(t, 3);
+	List	   *list = new_list(t, n);
+
+	va_list datum;
+	va_start(datum, n);
+
+	for (int i = 0; i < n; i++)
+		list->elements[i] = list_make_int_cell(va_arg(datum, int));
 
-	list->elements[0] = datum1;
-	list->elements[1] = datum2;
-	list->elements[2] = datum3;
 	check_list_invariants(list);
 	return list;
 }
 
 List *
-list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2,
-				ListCell datum3, ListCell datum4)
+list_make_oid_impl(NodeTag t, int n, ...)
 {
-	List	   *list = new_list(t, 4);
+	List	   *list = new_list(t, n);
+
+	va_list datum;
+	va_start(datum, n);
+
+	for (int i = 0; i < n; i++)
+		list->elements[i] = list_make_oid_cell(va_arg(datum, Oid));
 
-	list->elements[0] = datum1;
-	list->elements[1] = datum2;
-	list->elements[2] = datum3;
-	list->elements[3] = datum4;
 	check_list_invariants(list);
 	return list;
 }
 
 List *
-list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2,
-				ListCell datum3, ListCell datum4, ListCell datum5)
+list_make_xid_impl(NodeTag t, int n, ...)
 {
-	List	   *list = new_list(t, 5);
+	List	   *list = new_list(t, n);
+
+	va_list datum;
+	va_start(datum, n);
+
+	for (int i = 0; i < n; i++)
+		list->elements[i] = list_make_xid_cell(va_arg(datum, TransactionId));
 
-	list->elements[0] = datum1;
-	list->elements[1] = datum2;
-	list->elements[2] = datum3;
-	list->elements[3] = datum4;
-	list->elements[4] = datum5;
 	check_list_invariants(list);
 	return list;
 }
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index daae56ec32..5592dc3de1 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -204,70 +204,41 @@ list_length(const List *l)
 /*
  * Convenience macros for building fixed-length lists
  */
-#define list_make_ptr_cell(v)	((ListCell) {.ptr_value = (v)})
-#define list_make_int_cell(v)	((ListCell) {.int_value = (v)})
-#define list_make_oid_cell(v)	((ListCell) {.oid_value = (v)})
-#define list_make_xid_cell(v)	((ListCell) {.xid_value = (v)})
-
-#define list_make1(x1) \
-	list_make1_impl(T_List, list_make_ptr_cell(x1))
-#define list_make2(x1,x2) \
-	list_make2_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2))
-#define list_make3(x1,x2,x3) \
-	list_make3_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
-					list_make_ptr_cell(x3))
-#define list_make4(x1,x2,x3,x4) \
-	list_make4_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
-					list_make_ptr_cell(x3), list_make_ptr_cell(x4))
-#define list_make5(x1,x2,x3,x4,x5) \
-	list_make5_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
-					list_make_ptr_cell(x3), list_make_ptr_cell(x4), \
-					list_make_ptr_cell(x5))
-
-#define list_make1_int(x1) \
-	list_make1_impl(T_IntList, list_make_int_cell(x1))
-#define list_make2_int(x1,x2) \
-	list_make2_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2))
-#define list_make3_int(x1,x2,x3) \
-	list_make3_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
-					list_make_int_cell(x3))
-#define list_make4_int(x1,x2,x3,x4) \
-	list_make4_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
-					list_make_int_cell(x3), list_make_int_cell(x4))
-#define list_make5_int(x1,x2,x3,x4,x5) \
-	list_make5_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
-					list_make_int_cell(x3), list_make_int_cell(x4), \
-					list_make_int_cell(x5))
-
-#define list_make1_oid(x1) \
-	list_make1_impl(T_OidList, list_make_oid_cell(x1))
-#define list_make2_oid(x1,x2) \
-	list_make2_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2))
-#define list_make3_oid(x1,x2,x3) \
-	list_make3_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
-					list_make_oid_cell(x3))
-#define list_make4_oid(x1,x2,x3,x4) \
-	list_make4_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
-					list_make_oid_cell(x3), list_make_oid_cell(x4))
-#define list_make5_oid(x1,x2,x3,x4,x5) \
-	list_make5_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
-					list_make_oid_cell(x3), list_make_oid_cell(x4), \
-					list_make_oid_cell(x5))
-
-#define list_make1_xid(x1) \
-	list_make1_impl(T_XidList, list_make_xid_cell(x1))
-#define list_make2_xid(x1,x2) \
-	list_make2_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2))
-#define list_make3_xid(x1,x2,x3) \
-	list_make3_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
-					list_make_xid_cell(x3))
-#define list_make4_xid(x1,x2,x3,x4) \
-	list_make4_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
-					list_make_xid_cell(x3), list_make_xid_cell(x4))
-#define list_make5_xid(x1,x2,x3,x4,x5) \
-	list_make5_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
-					list_make_xid_cell(x3), list_make_xid_cell(x4), \
-					list_make_xid_cell(x5))
+#define list_make1(x1) list_make(x1)
+#define list_make2(x1,x2) list_make(x1,x2)
+#define list_make3(x1,x2,x3) list_make(x1,x2,x3)
+#define list_make4(x1,x2,x3,x4) list_make(x1,x2,x3,x4)
+#define list_make5(x1,x2,x3,x4,x5) list_make(x1,x2,x3,x4,x5)
+
+#define list_make(...) \
+	list_make_impl(T_List, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
+
+#define list_make1_int(x1) list_make_int(x1)
+#define list_make2_int(x1,x2) list_make_int(_intx1,x2)
+#define list_make3_int(x1,x2,x3) list_make_int(x1,x2,x3)
+#define list_make4_int(x1,x2,x3,x4) list_make_int(x1,x2,x3,x4)
+#define list_make5_int(x1,x2,x3,x4,x5) list_make_int(x1,x2,x3,x4,x5)
+
+#define list_make_int(...) \
+	list_make_int_impl(T_IntList, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
+
+#define list_make1_oid(x1) list_make_oid((x1))
+#define list_make2_oid(x1,x2) list_make_oid((x1),(x2))
+#define list_make3_oid(x1,x2,x3) list_make_oid((x1),(x2),(x3))
+#define list_make4_oid(x1,x2,x3,x4) list_make_oid((x1),(x2),(x3),(x4))
+#define list_make5_oid(x1,x2,x3,x4,x5) list_make_oid((x1),(x2),(x3),(x4),(x5))
+
+#define list_make_oid(...) \
+	list_make_oid_impl(T_OidList, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
+
+#define list_make1_xid(x1) list_make_xid(x1)
+#define list_make2_xid(x1,x2) list_make_xid(_intx1,x2)
+#define list_make3_xid(x1,x2,x3) list_make_xid(x1,x2,x3)
+#define list_make4_xid(x1,x2,x3,x4) list_make_xid(x1,x2,x3,x4)
+#define list_make5_xid(x1,x2,x3,x4,x5) list_make_xid(x1,x2,x3,x4,x5)
+
+#define list_make_xid(...) \
+	list_make_xid_impl(T_XidList, VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__)
 
 /*
  * Locate the n'th cell (counting from 0) of the list.
@@ -547,15 +518,10 @@ for_both_cell_setup(const List *list1, const ListCell *initcell1,
 
 /* Functions in src/backend/nodes/list.c */
 
-extern List *list_make1_impl(NodeTag t, ListCell datum1);
-extern List *list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2);
-extern List *list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2,
-							 ListCell datum3);
-extern List *list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2,
-							 ListCell datum3, ListCell datum4);
-extern List *list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2,
-							 ListCell datum3, ListCell datum4,
-							 ListCell datum5);
+extern List *list_make_impl(NodeTag t, int n, ...);
+extern List *list_make_int_impl(NodeTag t, int n, ...);
+extern List *list_make_oid_impl(NodeTag t, int n, ...);
+extern List *list_make_xid_impl(NodeTag t, int n, ...);
 
 extern pg_nodiscard List *lappend(List *list, void *datum);
 extern pg_nodiscard List *lappend_int(List *list, int datum);
-- 
2.41.0

