From 6253f9de6702fa73101997034b4fec038d547f6d Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 29 Aug 2008 22:49:07 +0000
Subject: [PATCH] In GCC-based builds, use a better newNode() macro that relies
 on GCC-specific syntax to avoid a useless store into a global variable.  Per
 experimentation, this works better than my original thought of trying to push
 the code into an out-of-line subroutine.

---
 src/backend/nodes/nodes.c |  6 +++++-
 src/include/nodes/nodes.h | 21 ++++++++++++++++++++-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c
index a2ced5f945..30cbeb8e1d 100644
--- a/src/backend/nodes/nodes.c
+++ b/src/backend/nodes/nodes.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/nodes.c,v 1.28 2008/01/01 19:45:50 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/nodes.c,v 1.29 2008/08/29 22:49:07 tgl Exp $
  *
  * HISTORY
  *	  Andrew Yu			Oct 20, 1994	file creation
@@ -22,6 +22,10 @@
 
 /*
  * Support for newNode() macro
+ *
+ * In a GCC build there is no need for the global variable newNodeMacroHolder.
+ * However, we create it anyway, to support the case of a non-GCC-built
+ * loadable module being loaded into a GCC-built backend.
  */
 
 Node	   *newNodeMacroHolder;
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index b9e00bfdde..78dd917ecf 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.209 2008/08/22 00:16:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.210 2008/08/29 22:49:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -384,6 +384,23 @@ typedef struct Node
  * !WARNING!: Avoid using newNode directly. You should be using the
  *	  macro makeNode.  eg. to create a Query node, use makeNode(Query)
  *
+ * Note: the size argument should always be a compile-time constant, so the
+ * apparent risk of multiple evaluation doesn't matter in practice.
+ */
+#ifdef __GNUC__
+
+/* With GCC, we can use a compound statement within an expression */
+#define newNode(size, tag) \
+({	Node   *_result; \
+	AssertMacro((size) >= sizeof(Node));		/* need the tag, at least */ \
+	_result = (Node *) palloc0fast(size); \
+	_result->type = (tag); \
+	_result; \
+})
+
+#else
+
+/*
  *	There is no way to dereference the palloc'ed pointer to assign the
  *	tag, and also return the pointer itself, so we need a holder variable.
  *	Fortunately, this macro isn't recursive so we just define
@@ -399,6 +416,8 @@ extern PGDLLIMPORT Node *newNodeMacroHolder;
 	newNodeMacroHolder \
 )
 
+#endif   /* __GNUC__ */
+
 
 #define makeNode(_type_)		((_type_ *) newNode(sizeof(_type_),T_##_type_))
 #define NodeSetTag(nodeptr,t)	(((Node*)(nodeptr))->type = (t))
-- 
2.40.0