diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index 4d19aed8f4b8b7dbffdd9dd47fa757d684d4b38f..380d65cc7f3df3984149573cd440bf4cf0e5b56f 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -15,6 +15,9 @@
  */
 #include "postgres.h"
 
+/* see pg_list.h */
+#define PG_LIST_INCLUDE_DEFINITIONS
+
 #include "nodes/pg_list.h"
 
 
@@ -1223,31 +1226,6 @@ list_copy_tail(const List *oldlist, int nskip)
 	return newlist;
 }
 
-/*
- * pg_list.h defines inline versions of these functions if allowed by the
- * compiler; in which case the definitions below are skipped.
- */
-#ifndef USE_INLINE
-
-ListCell *
-list_head(const List *l)
-{
-	return l ? l->head : NULL;
-}
-
-ListCell *
-list_tail(List *l)
-{
-	return l ? l->tail : NULL;
-}
-
-int
-list_length(const List *l)
-{
-	return l ? l->length : 0;
-}
-#endif   /* ! USE_INLINE */
-
 /*
  * Temporary compatibility functions
  *
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 466d53d57ef555cc717ee6b57b627a084d70ea46..7acd9c02a728f0b6682add8aabe7a5c6d4d6aabe 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -21,6 +21,9 @@
 
 #include "postgres.h"
 
+/* see palloc.h */
+#define MCXT_INCLUDE_DEFINITIONS
+
 #include "utils/memutils.h"
 
 
@@ -695,28 +698,6 @@ repalloc(void *pointer, Size size)
 												 pointer, size);
 }
 
-/*
- * MemoryContextSwitchTo
- *		Returns the current context; installs the given context.
- *
- * palloc.h defines an inline version of this function if allowed by the
- * compiler; in which case the definition below is skipped.
- */
-#ifndef USE_INLINE
-
-MemoryContext
-MemoryContextSwitchTo(MemoryContext context)
-{
-	MemoryContext old;
-
-	AssertArg(MemoryContextIsValid(context));
-
-	old = CurrentMemoryContext;
-	CurrentMemoryContext = context;
-	return old;
-}
-#endif   /* ! USE_INLINE */
-
 /*
  * MemoryContextStrdup
  *		Like strdup(), but allocate from the specified context
diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c
index b6d916d3e43d5068cd0c36892338ec72a77a15fe..f703ef049492a212ece3d2997d975deb2d301afa 100644
--- a/src/backend/utils/sort/sortsupport.c
+++ b/src/backend/utils/sort/sortsupport.c
@@ -15,6 +15,9 @@
 
 #include "postgres.h"
 
+/* See sortsupport.h */
+#define SORTSUPPORT_INCLUDE_DEFINITIONS
+
 #include "fmgr.h"
 #include "utils/lsyscache.h"
 #include "utils/sortsupport.h"
@@ -28,50 +31,6 @@ typedef struct
 } SortShimExtra;
 
 
-/*
- * sortsupport.h defines inline versions of these functions if allowed by the
- * compiler; in which case the definitions below are skipped.
- */
-#ifndef USE_INLINE
-
-/*
- * Apply a sort comparator function and return a 3-way comparison result.
- * This takes care of handling reverse-sort and NULLs-ordering properly.
- */
-int
-ApplySortComparator(Datum datum1, bool isNull1,
-					Datum datum2, bool isNull2,
-					SortSupport ssup)
-{
-	int			compare;
-
-	if (isNull1)
-	{
-		if (isNull2)
-			compare = 0;		/* NULL "=" NULL */
-		else if (ssup->ssup_nulls_first)
-			compare = -1;		/* NULL "<" NOT_NULL */
-		else
-			compare = 1;		/* NULL ">" NOT_NULL */
-	}
-	else if (isNull2)
-	{
-		if (ssup->ssup_nulls_first)
-			compare = 1;		/* NOT_NULL ">" NULL */
-		else
-			compare = -1;		/* NOT_NULL "<" NULL */
-	}
-	else
-	{
-		compare = (*ssup->comparator) (datum1, datum2, ssup);
-		if (ssup->ssup_reverse)
-			compare = -compare;
-	}
-
-	return compare;
-}
-#endif   /* ! USE_INLINE */
-
 /*
  * Shim function for calling an old-style comparator
  *
diff --git a/src/include/c.h b/src/include/c.h
index 127b5d94e3c7d5f7780491aefc8f248a161ed435..925d9617af41825a9a9b459c517d03b7210f8ee5 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -748,6 +748,24 @@ typedef NameData *Name;
 #endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
 
 
+/*
+ * Function inlining support -- Allow modules to define functions that may be
+ * inlined, if the compiler supports it.
+ *
+ * The function bodies must be defined in the module header prefixed by
+ * STATIC_IF_INLINE, protected by a cpp symbol that the module's .c file must
+ * define.  If the compiler doesn't support inline functions, the function
+ * definitions are pulled in by the .c file as regular (not inline) symbols.
+ *
+ * The header must also declare the functions' prototypes, protected by
+ * !USE_INLINE.
+ */
+#ifdef USE_INLINE
+#define STATIC_IF_INLINE static inline
+#else
+#define STATIC_IF_INLINE
+#endif	/* USE_INLINE */
+
 /* ----------------------------------------------------------------
  *				Section 7:	random stuff
  * ----------------------------------------------------------------
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index 15b86ddf83d7b8641f196dba4f7d875386b3ab51..d9cf18376bdb476ceb0c22ff8824c6a0667b419a 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -73,32 +73,32 @@ struct ListCell
  * them as macros, since we want to avoid double-evaluation of macro
  * arguments. Therefore, we implement them using static inline functions
  * if supported by the compiler, or as regular functions otherwise.
+ * See STATIC_IF_INLINE in c.h.
  */
-#ifdef USE_INLINE
-
-static inline ListCell *
+#ifndef USE_INLINE
+extern ListCell *list_head(const List *l);
+extern ListCell *list_tail(List *l);
+extern int	list_length(const List *l);
+#endif   /* USE_INLINE */
+#if defined(USE_INLINE) || defined(PG_LIST_INCLUDE_DEFINITIONS)
+STATIC_IF_INLINE ListCell *
 list_head(const List *l)
 {
 	return l ? l->head : NULL;
 }
 
-static inline ListCell *
+STATIC_IF_INLINE ListCell *
 list_tail(List *l)
 {
 	return l ? l->tail : NULL;
 }
 
-static inline int
+STATIC_IF_INLINE int
 list_length(const List *l)
 {
 	return l ? l->length : 0;
 }
-#else
-
-extern ListCell *list_head(const List *l);
-extern ListCell *list_tail(List *l);
-extern int	list_length(const List *l);
-#endif   /* USE_INLINE */
+#endif	/* USE_INLINE || PG_LIST_INCLUDE_DEFINITIONS */
 
 /*
  * NB: There is an unfortunate legacy from a previous incarnation of
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 973f30699724f5b6efccbcc8fb9d380900cb29f7..75d8864ad4352fbcf4f5dee2012c9b06d54000d9 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -73,14 +73,19 @@ extern void *repalloc(void *pointer, Size size);
 /*
  * MemoryContextSwitchTo can't be a macro in standard C compilers.
  * But we can make it an inline function if the compiler supports it.
+ * See STATIC_IF_INLINE in c.h.
  *
  * This file has to be includable by some non-backend code such as
  * pg_resetxlog, so don't expose the CurrentMemoryContext reference
  * if FRONTEND is defined.
  */
-#if defined(USE_INLINE) && !defined(FRONTEND)
+#ifndef FRONTEND
 
-static inline MemoryContext
+#ifndef USE_INLINE
+extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
+#endif   /* !USE_INLINE */
+#if defined(USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS)
+STATIC_IF_INLINE MemoryContext
 MemoryContextSwitchTo(MemoryContext context)
 {
 	MemoryContext old = CurrentMemoryContext;
@@ -88,10 +93,9 @@ MemoryContextSwitchTo(MemoryContext context)
 	CurrentMemoryContext = context;
 	return old;
 }
-#else
+#endif
 
-extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
-#endif   /* USE_INLINE && !FRONTEND */
+#endif /* !FRONTEND */
 
 /*
  * These are like standard strdup() except the copied string is
diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h
index 720a54c0d769cb11ac2a588f29f28041e8d49fb2..ecb51ed3bea06730b6ebf4c93d47b65583e74102 100644
--- a/src/include/utils/sortsupport.h
+++ b/src/include/utils/sortsupport.h
@@ -101,14 +101,21 @@ typedef struct SortSupportData
 } SortSupportData;
 
 
-/* ApplySortComparator should be inlined if possible */
-#ifdef USE_INLINE
-
+/*
+ * ApplySortComparator should be inlined if possible.  See STATIC_IF_INLINE
+ * in c.h.
+ */
+#ifndef USE_INLINE
+extern int ApplySortComparator(Datum datum1, bool isNull1,
+					Datum datum2, bool isNull2,
+					SortSupport ssup);
+#endif   /* !USE_INLINE */
+#if defined(USE_INLINE) || defined(SORTSUPPORT_INCLUDE_DEFINITIONS)
 /*
  * Apply a sort comparator function and return a 3-way comparison result.
  * This takes care of handling reverse-sort and NULLs-ordering properly.
  */
-static inline int
+STATIC_IF_INLINE int
 ApplySortComparator(Datum datum1, bool isNull1,
 					Datum datum2, bool isNull2,
 					SortSupport ssup)
@@ -140,12 +147,7 @@ ApplySortComparator(Datum datum1, bool isNull1,
 
 	return compare;
 }
-#else
-
-extern int ApplySortComparator(Datum datum1, bool isNull1,
-					Datum datum2, bool isNull2,
-					SortSupport ssup);
-#endif   /* USE_INLINE */
+#endif	/* USE_INLINE || SORTSUPPORT_INCLUDE_DEFINITIONS */
 
 /* Other functions in utils/sort/sortsupport.c */
 extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup);