From 482f67d9909d81a742b5707eb0a1a34fe4fb5d04 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 26 Sep 2019 11:44:53 -0700
Subject: [PATCH v2 1/8] jit: Instrument function purpose separately, add
 tracking of modules.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/backend/commands/explain.c        | 24 +++++++++++++++++++++++-
 src/backend/jit/jit.c                 |  3 +++
 src/backend/jit/llvm/llvmjit.c        |  2 ++
 src/backend/jit/llvm/llvmjit_deform.c |  1 +
 src/backend/jit/llvm/llvmjit_expr.c   |  1 +
 src/include/jit/jit.h                 | 11 ++++++++++-
 6 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 62fb3434a32..ef65035bfba 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -825,7 +825,26 @@ ExplainPrintJIT(ExplainState *es, int jit_flags,
 			appendStringInfoString(es->str, "JIT:\n");
 		es->indent += 1;
 
-		ExplainPropertyInteger("Functions", NULL, ji->created_functions, es);
+		/* having to emit code more than once has performance consequences */
+		if (ji->created_modules > 1)
+			ExplainPropertyInteger("Modules", NULL, ji->created_modules, es);
+
+		appendStringInfoSpaces(es->str, es->indent * 2);
+		appendStringInfo(es->str, "Functions: %zu", ji->created_functions);
+		if (ji->created_expr_functions > 0 || ji->created_deform_functions)
+		{
+			appendStringInfoString(es->str, " (");
+			if (ji->created_expr_functions)
+			{
+				appendStringInfo(es->str, "%zu for expression evaluation", ji->created_expr_functions);
+				if (ji->created_deform_functions)
+					appendStringInfoString(es->str, ", ");
+			}
+			if (ji->created_deform_functions)
+				appendStringInfo(es->str, "%zu for tuple deforming", ji->created_deform_functions);
+			appendStringInfoChar(es->str, ')');
+		}
+		appendStringInfoChar(es->str, '\n');
 
 		appendStringInfoSpaces(es->str, es->indent * 2);
 		appendStringInfo(es->str, "Options: %s %s, %s %s, %s %s, %s %s\n",
@@ -851,7 +870,10 @@ ExplainPrintJIT(ExplainState *es, int jit_flags,
 	else
 	{
 		ExplainPropertyInteger("Worker Number", NULL, worker_num, es);
+		ExplainPropertyInteger("Modules", NULL, ji->created_modules, es);
 		ExplainPropertyInteger("Functions", NULL, ji->created_functions, es);
+		ExplainPropertyInteger("Expression Functions", NULL, ji->created_expr_functions, es);
+		ExplainPropertyInteger("Deforming Functions", NULL, ji->created_deform_functions, es);
 
 		ExplainOpenGroup("Options", "Options", true, es);
 		ExplainPropertyBool("Inlining", jit_flags & PGJIT_INLINE, es);
diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c
index 43e65b1a543..63c709002d8 100644
--- a/src/backend/jit/jit.c
+++ b/src/backend/jit/jit.c
@@ -186,7 +186,10 @@ jit_compile_expr(struct ExprState *state)
 void
 InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add)
 {
+	dst->created_modules += add->created_modules;
 	dst->created_functions += add->created_functions;
+	dst->created_expr_functions += add->created_expr_functions;
+	dst->created_deform_functions += add->created_deform_functions;
 	INSTR_TIME_ADD(dst->generation_counter, add->generation_counter);
 	INSTR_TIME_ADD(dst->inlining_counter, add->inlining_counter);
 	INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter);
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 82c4afb7011..5489e118041 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -212,6 +212,8 @@ llvm_mutable_module(LLVMJitContext *context)
 		context->module = LLVMModuleCreateWithName("pg");
 		LLVMSetTarget(context->module, llvm_triple);
 		LLVMSetDataLayout(context->module, llvm_layout);
+
+		context->base.instr.created_modules++;
 	}
 
 	return context->module;
diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
index 835aea83e97..80a85858524 100644
--- a/src/backend/jit/llvm/llvmjit_deform.c
+++ b/src/backend/jit/llvm/llvmjit_deform.c
@@ -101,6 +101,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 	mod = llvm_mutable_module(context);
 
 	funcname = llvm_expand_funcname(context, "deform");
+	context->base.instr.created_deform_functions++;
 
 	/*
 	 * Check which columns have to exist, so we don't have to check the row's
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index d09324637b9..4ba8c78cbc9 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -144,6 +144,7 @@ llvm_compile_expr(ExprState *state)
 	b = LLVMCreateBuilder();
 
 	funcname = llvm_expand_funcname(context, "evalexpr");
+	context->base.instr.created_expr_functions++;
 
 	/* Create the signature and function */
 	{
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index d879cef20f3..668f965cb0a 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -26,9 +26,18 @@
 
 typedef struct JitInstrumentation
 {
-	/* number of emitted functions */
+	/* number of modules (i.e. separate optimize / link cycles) created */
+	size_t		created_modules;
+
+	/* number of functions generated */
 	size_t		created_functions;
 
+	/* number of expression evaluation functions generated */
+	size_t		created_expr_functions;
+
+	/* number of tuple deforming functions generated */
+	size_t		created_deform_functions;
+
 	/* accumulated time to generate code */
 	instr_time	generation_counter;
 
-- 
2.23.0.385.gbc12974a89

