From 3e9e191f30c87df311310bb021fb1ee6bdfca3c2 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Tue, 25 Apr 2023 14:43:03 +0200
Subject: [PATCH v4 1/5]  wip: llvmjit: Use explicit LLVMContextRef.

This is a prerequisite for a later commit fixing a memory leak due to
slow accumulation of types in LLVM.
---
 src/backend/jit/llvm/llvmjit.c          |  9 ++--
 src/backend/jit/llvm/llvmjit_deform.c   | 60 +++++++++++++------------
 src/backend/jit/llvm/llvmjit_expr.c     | 58 +++++++++++++-----------
 src/backend/jit/llvm/llvmjit_inline.cpp | 21 ++++-----
 src/include/jit/llvmjit_emit.h          | 30 ++++++++-----
 5 files changed, 98 insertions(+), 80 deletions(-)

diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index a8b73a9cf1..d9b0aec5af 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -94,6 +94,7 @@ static bool llvm_session_initialized = false;
 static size_t llvm_generation = 0;
 static const char *llvm_triple = NULL;
 static const char *llvm_layout = NULL;
+static LLVMContextRef llvm_context;
 
 
 static LLVMTargetRef llvm_targetref;
@@ -238,7 +239,7 @@ llvm_mutable_module(LLVMJitContext *context)
 	{
 		context->compiled = false;
 		context->module_generation = llvm_generation++;
-		context->module = LLVMModuleCreateWithName("pg");
+		context->module = LLVMModuleCreateWithNameInContext("pg", llvm_context);
 		LLVMSetTarget(context->module, llvm_triple);
 		LLVMSetDataLayout(context->module, llvm_layout);
 	}
@@ -798,6 +799,8 @@ llvm_session_initialize(void)
 	LLVMInitializeNativeAsmPrinter();
 	LLVMInitializeNativeAsmParser();
 
+	llvm_context = LLVMContextCreate();
+
 	/*
 	 * When targeting an LLVM version with opaque pointers enabled by
 	 * default, turn them off for the context we build our code in.  We don't
@@ -1002,9 +1005,9 @@ llvm_create_types(void)
 	}
 
 	/* eagerly load contents, going to need it all */
-	if (LLVMParseBitcode2(buf, &llvm_types_module))
+	if (LLVMParseBitcodeInContext2(llvm_context, buf, &llvm_types_module))
 	{
-		elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
+		elog(ERROR, "LLVMParseBitcodeInContext2 of %s failed", path);
 	}
 	LLVMDisposeMemoryBuffer(buf);
 
diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
index 6b15588da6..68e0ff354d 100644
--- a/src/backend/jit/llvm/llvmjit_deform.c
+++ b/src/backend/jit/llvm/llvmjit_deform.c
@@ -37,6 +37,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 	char	   *funcname;
 
 	LLVMModuleRef mod;
+	LLVMContextRef lc;
 	LLVMBuilderRef b;
 
 	LLVMTypeRef deform_sig;
@@ -99,6 +100,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		return NULL;
 
 	mod = llvm_mutable_module(context);
+	lc = LLVMGetModuleContext(mod);
 
 	funcname = llvm_expand_funcname(context, "deform");
 
@@ -133,8 +135,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 
 		param_types[0] = l_ptr(StructTupleTableSlot);
 
-		deform_sig = LLVMFunctionType(LLVMVoidType(), param_types,
-									  lengthof(param_types), 0);
+		deform_sig = LLVMFunctionType(LLVMVoidTypeInContext(lc),
+									  param_types, lengthof(param_types), 0);
 	}
 	v_deform_fn = LLVMAddFunction(mod, funcname, deform_sig);
 	LLVMSetLinkage(v_deform_fn, LLVMInternalLinkage);
@@ -142,17 +144,17 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 	llvm_copy_attributes(AttributeTemplate, v_deform_fn);
 
 	b_entry =
-		LLVMAppendBasicBlock(v_deform_fn, "entry");
+		LLVMAppendBasicBlockInContext(lc, v_deform_fn, "entry");
 	b_adjust_unavail_cols =
-		LLVMAppendBasicBlock(v_deform_fn, "adjust_unavail_cols");
+		LLVMAppendBasicBlockInContext(lc, v_deform_fn, "adjust_unavail_cols");
 	b_find_start =
-		LLVMAppendBasicBlock(v_deform_fn, "find_startblock");
+		LLVMAppendBasicBlockInContext(lc, v_deform_fn, "find_startblock");
 	b_out =
-		LLVMAppendBasicBlock(v_deform_fn, "outblock");
+		LLVMAppendBasicBlockInContext(lc, v_deform_fn, "outblock");
 	b_dead =
-		LLVMAppendBasicBlock(v_deform_fn, "deadblock");
+		LLVMAppendBasicBlockInContext(lc, v_deform_fn, "deadblock");
 
-	b = LLVMCreateBuilder();
+	b = LLVMCreateBuilderInContext(lc);
 
 	attcheckattnoblocks = palloc(sizeof(LLVMBasicBlockRef) * natts);
 	attstartblocks = palloc(sizeof(LLVMBasicBlockRef) * natts);
@@ -221,7 +223,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 						 LLVMBuildStructGEP(b, v_tuplep,
 											FIELDNO_HEAPTUPLEHEADERDATA_BITS,
 											""),
-						 l_ptr(LLVMInt8Type()),
+						 l_ptr(LLVMInt8TypeInContext(lc)),
 						 "t_bits");
 	v_infomask1 =
 		l_load_struct_gep(b, v_tuplep,
@@ -236,14 +238,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 	v_hasnulls =
 		LLVMBuildICmp(b, LLVMIntNE,
 					  LLVMBuildAnd(b,
-								   l_int16_const(HEAP_HASNULL),
+								   l_int16_const(lc, HEAP_HASNULL),
 								   v_infomask1, ""),
-					  l_int16_const(0),
+					  l_int16_const(lc, 0),
 					  "hasnulls");
 
 	/* t_infomask2 & HEAP_NATTS_MASK */
 	v_maxatt = LLVMBuildAnd(b,
-							l_int16_const(HEAP_NATTS_MASK),
+							l_int16_const(lc, HEAP_NATTS_MASK),
 							v_infomask2,
 							"maxatt");
 
@@ -256,13 +258,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 					  l_load_struct_gep(b, v_tuplep,
 										FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
 										""),
-					  LLVMInt32Type(), "t_hoff");
+					  LLVMInt32TypeInContext(lc), "t_hoff");
 
 	v_tupdata_base =
 		LLVMBuildGEP(b,
 					 LLVMBuildBitCast(b,
 									  v_tuplep,
-									  l_ptr(LLVMInt8Type()),
+									  l_ptr(LLVMInt8TypeInContext(lc)),
 									  ""),
 					 &v_hoff, 1,
 					 "v_tupdata_base");
@@ -319,7 +321,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		LLVMBuildCondBr(b,
 						LLVMBuildICmp(b, LLVMIntULT,
 									  v_maxatt,
-									  l_int16_const(natts),
+									  l_int16_const(lc, natts),
 									  ""),
 						b_adjust_unavail_cols,
 						b_find_start);
@@ -328,8 +330,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		LLVMPositionBuilderAtEnd(b, b_adjust_unavail_cols);
 
 		v_params[0] = v_slot;
-		v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), "");
-		v_params[2] = l_int32_const(natts);
+		v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32TypeInContext(lc), "");
+		v_params[2] = l_int32_const(lc, natts);
 		LLVMBuildCall(b, llvm_pg_func(mod, "slot_getmissingattrs"),
 					  v_params, lengthof(v_params), "");
 		LLVMBuildBr(b, b_find_start);
@@ -352,7 +354,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 
 		for (attnum = 0; attnum < natts; attnum++)
 		{
-			LLVMValueRef v_attno = l_int16_const(attnum);
+			LLVMValueRef v_attno = l_int16_const(lc, attnum);
 
 			LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[attnum]);
 		}
@@ -375,7 +377,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		Form_pg_attribute att = TupleDescAttr(desc, attnum);
 		LLVMValueRef v_incby;
 		int			alignto;
-		LLVMValueRef l_attno = l_int16_const(attnum);
+		LLVMValueRef l_attno = l_int16_const(lc, attnum);
 		LLVMValueRef v_attdatap;
 		LLVMValueRef v_resultp;
 
@@ -436,14 +438,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 			else
 				b_next = attcheckattnoblocks[attnum + 1];
 
-			v_nullbyteno = l_int32_const(attnum >> 3);
-			v_nullbytemask = l_int8_const(1 << ((attnum) & 0x07));
+			v_nullbyteno = l_int32_const(lc, attnum >> 3);
+			v_nullbytemask = l_int8_const(lc, 1 << ((attnum) & 0x07));
 			v_nullbyte = l_load_gep1(b, v_bits, v_nullbyteno, "attnullbyte");
 
 			v_nullbit = LLVMBuildICmp(b,
 									  LLVMIntEQ,
 									  LLVMBuildAnd(b, v_nullbyte, v_nullbytemask, ""),
-									  l_int8_const(0),
+									  l_int8_const(lc, 0),
 									  "attisnull");
 
 			v_attisnull = LLVMBuildAnd(b, v_hasnulls, v_nullbit, "");
@@ -454,7 +456,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 
 			/* store null-byte */
 			LLVMBuildStore(b,
-						   l_int8_const(1),
+						   l_int8_const(lc, 1),
 						   LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1, ""));
 			/* store zero datum */
 			LLVMBuildStore(b,
@@ -524,7 +526,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 					l_load_gep1(b, v_tupdata_base, v_off, "padbyte");
 				v_ispad =
 					LLVMBuildICmp(b, LLVMIntEQ,
-								  v_possible_padbyte, l_int8_const(0),
+								  v_possible_padbyte, l_int8_const(lc, 0),
 								  "ispadbyte");
 				LLVMBuildCondBr(b, v_ispad,
 								attalignblocks[attnum],
@@ -639,7 +641,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		v_resultp = LLVMBuildGEP(b, v_tts_values, &l_attno, 1, "");
 
 		/* store null-byte (false) */
-		LLVMBuildStore(b, l_int8_const(0),
+		LLVMBuildStore(b, l_int8_const(lc, 0),
 					   LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1, ""));
 
 		/*
@@ -650,7 +652,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		{
 			LLVMValueRef v_tmp_loaddata;
 			LLVMTypeRef vartypep =
-			LLVMPointerType(LLVMIntType(att->attlen * 8), 0);
+			LLVMPointerType(LLVMIntTypeInContext(lc, att->attlen * 8), 0);
 
 			v_tmp_loaddata =
 				LLVMBuildPointerCast(b, v_attdatap, vartypep, "");
@@ -739,11 +741,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
 		LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, "");
 		LLVMValueRef v_flags;
 
-		LLVMBuildStore(b, l_int16_const(natts), v_nvalidp);
-		v_off = LLVMBuildTrunc(b, v_off, LLVMInt32Type(), "");
+		LLVMBuildStore(b, l_int16_const(lc, natts), v_nvalidp);
+		v_off = LLVMBuildTrunc(b, v_off, LLVMInt32TypeInContext(lc), "");
 		LLVMBuildStore(b, v_off, v_slotoffp);
 		v_flags = LLVMBuildLoad(b, v_flagsp, "tts_flags");
-		v_flags = LLVMBuildOr(b, v_flags, l_int16_const(TTS_FLAG_SLOW), "");
+		v_flags = LLVMBuildOr(b, v_flags, l_int16_const(lc, TTS_FLAG_SLOW), "");
 		LLVMBuildStore(b, v_flags, v_flagsp);
 		LLVMBuildRetVoid(b);
 	}
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index a1b33d6e6c..61089ebdfc 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -84,6 +84,7 @@ llvm_compile_expr(ExprState *state)
 
 	LLVMBuilderRef b;
 	LLVMModuleRef mod;
+	LLVMContextRef lc;
 	LLVMValueRef eval_fn;
 	LLVMBasicBlockRef entry;
 	LLVMBasicBlockRef *opblocks;
@@ -143,8 +144,9 @@ llvm_compile_expr(ExprState *state)
 	INSTR_TIME_SET_CURRENT(starttime);
 
 	mod = llvm_mutable_module(context);
+	lc = LLVMGetModuleContext(mod);
 
-	b = LLVMCreateBuilder();
+	b = LLVMCreateBuilderInContext(lc);
 
 	funcname = llvm_expand_funcname(context, "evalexpr");
 
@@ -155,7 +157,7 @@ llvm_compile_expr(ExprState *state)
 	LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
 	llvm_copy_attributes(AttributeTemplate, eval_fn);
 
-	entry = LLVMAppendBasicBlock(eval_fn, "entry");
+	entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry");
 
 	/* build state */
 	v_state = LLVMGetParam(eval_fn, 0);
@@ -301,7 +303,7 @@ llvm_compile_expr(ExprState *state)
 										  "");
 					LLVMBuildCondBr(b,
 									LLVMBuildICmp(b, LLVMIntUGE, v_nvalid,
-												  l_int16_const(op->d.fetch.last_var),
+												  l_int16_const(lc, op->d.fetch.last_var),
 												  ""),
 									opblocks[opno + 1], b_fetch);
 
@@ -335,7 +337,7 @@ llvm_compile_expr(ExprState *state)
 						LLVMValueRef params[2];
 
 						params[0] = v_slot;
-						params[1] = l_int32_const(op->d.fetch.last_var);
+						params[1] = l_int32_const(lc, op->d.fetch.last_var);
 
 						LLVMBuildCall(b,
 									  llvm_pg_func(mod, "slot_getsomeattrs_int"),
@@ -372,7 +374,7 @@ llvm_compile_expr(ExprState *state)
 						v_nulls = v_scannulls;
 					}
 
-					v_attnum = l_int32_const(op->d.var.attnum);
+					v_attnum = l_int32_const(lc, op->d.var.attnum);
 					value = l_load_gep1(b, v_values, v_attnum, "");
 					isnull = l_load_gep1(b, v_nulls, v_attnum, "");
 					LLVMBuildStore(b, value, v_resvaluep);
@@ -438,12 +440,12 @@ llvm_compile_expr(ExprState *state)
 					}
 
 					/* load data */
-					v_attnum = l_int32_const(op->d.assign_var.attnum);
+					v_attnum = l_int32_const(lc, op->d.assign_var.attnum);
 					v_value = l_load_gep1(b, v_values, v_attnum, "");
 					v_isnull = l_load_gep1(b, v_nulls, v_attnum, "");
 
 					/* compute addresses of targets */
-					v_resultnum = l_int32_const(op->d.assign_var.resultnum);
+					v_resultnum = l_int32_const(lc, op->d.assign_var.resultnum);
 					v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
 											 &v_resultnum, 1, "");
 					v_risnullp = LLVMBuildGEP(b, v_resultnulls,
@@ -472,7 +474,7 @@ llvm_compile_expr(ExprState *state)
 					v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
 
 					/* compute addresses of targets */
-					v_resultnum = l_int32_const(resultnum);
+					v_resultnum = l_int32_const(lc, resultnum);
 					v_rvaluep =
 						LLVMBuildGEP(b, v_resultvalues, &v_resultnum, 1, "");
 					v_risnullp =
@@ -1691,7 +1693,7 @@ llvm_compile_expr(ExprState *state)
 					v_cmpresult =
 						LLVMBuildTrunc(b,
 									   LLVMBuildLoad(b, v_resvaluep, ""),
-									   LLVMInt32Type(), "");
+									   LLVMInt32TypeInContext(lc), "");
 
 					switch (rctype)
 					{
@@ -1717,7 +1719,7 @@ llvm_compile_expr(ExprState *state)
 					v_result = LLVMBuildICmp(b,
 											 predicate,
 											 v_cmpresult,
-											 l_int32_const(0),
+											 l_int32_const(lc, 0),
 											 "");
 					v_result = LLVMBuildZExt(b, v_result, TypeSizeT, "");
 
@@ -1860,7 +1862,7 @@ llvm_compile_expr(ExprState *state)
 					LLVMValueRef value,
 								isnull;
 
-					v_aggno = l_int32_const(op->d.aggref.aggno);
+					v_aggno = l_int32_const(lc, op->d.aggref.aggno);
 
 					/* load agg value / null */
 					value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue");
@@ -1894,7 +1896,7 @@ llvm_compile_expr(ExprState *state)
 					 * expression). So load it from memory each time round.
 					 */
 					v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
-											 l_ptr(LLVMInt32Type()));
+											 l_ptr(LLVMInt32TypeInContext(lc)));
 					v_wfuncno = LLVMBuildLoad(b, v_wfuncnop, "v_wfuncno");
 
 					/* load window func value / null */
@@ -2002,7 +2004,7 @@ llvm_compile_expr(ExprState *state)
 					/* strict function, check for NULL args */
 					for (int argno = 0; argno < nargs; argno++)
 					{
-						LLVMValueRef v_argno = l_int32_const(argno);
+						LLVMValueRef v_argno = l_int32_const(lc, argno);
 						LLVMValueRef v_argisnull;
 						LLVMBasicBlockRef b_argnotnull;
 
@@ -2059,7 +2061,7 @@ llvm_compile_expr(ExprState *state)
 														FIELDNO_AGGSTATE_ALL_PERGROUPS,
 														"aggstate.all_pergroups");
 
-					v_setoff = l_int32_const(op->d.agg_plain_pergroup_nullcheck.setoff);
+					v_setoff = l_int32_const(lc, op->d.agg_plain_pergroup_nullcheck.setoff);
 
 					v_pergroup_allaggs = l_load_gep1(b, v_allpergroupsp, v_setoff, "");
 
@@ -2128,8 +2130,8 @@ llvm_compile_expr(ExprState *state)
 						l_load_struct_gep(b, v_aggstatep,
 										  FIELDNO_AGGSTATE_ALL_PERGROUPS,
 										  "aggstate.all_pergroups");
-					v_setoff = l_int32_const(op->d.agg_trans.setoff);
-					v_transno = l_int32_const(op->d.agg_trans.transno);
+					v_setoff = l_int32_const(lc, op->d.agg_trans.setoff);
+					v_transno = l_int32_const(lc, op->d.agg_trans.transno);
 					v_pergroupp =
 						LLVMBuildGEP(b,
 									 l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
@@ -2232,7 +2234,7 @@ llvm_compile_expr(ExprState *state)
 
 					/* set aggstate globals */
 					LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
-					LLVMBuildStore(b, l_int32_const(op->d.agg_trans.setno),
+					LLVMBuildStore(b, l_int32_const(lc, op->d.agg_trans.setno),
 								   v_current_setp);
 					LLVMBuildStore(b, v_pertransp, v_current_pertransp);
 
@@ -2468,11 +2470,14 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
 			LLVMModuleRef mod, FunctionCallInfo fcinfo,
 			LLVMValueRef *v_fcinfo_isnull)
 {
+	LLVMContextRef lc;
 	LLVMValueRef v_fn;
 	LLVMValueRef v_fcinfo_isnullp;
 	LLVMValueRef v_retval;
 	LLVMValueRef v_fcinfo;
 
+	lc = LLVMGetModuleContext(mod);
+
 	v_fn = llvm_function_reference(context, b, mod, fcinfo);
 
 	v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
@@ -2494,12 +2499,12 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
 		LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
 		LLVMValueRef params[2];
 
-		params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs);
-		params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type()));
+		params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo->nargs);
+		params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
 		LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
 
-		params[0] = l_int64_const(sizeof(fcinfo->isnull));
-		params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type()));
+		params[0] = l_int64_const(lc, sizeof(fcinfo->isnull));
+		params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
 		LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
 	}
 
@@ -2545,6 +2550,7 @@ create_LifetimeEnd(LLVMModuleRef mod)
 	LLVMTypeRef sig;
 	LLVMValueRef fn;
 	LLVMTypeRef param_types[2];
+	LLVMContextRef lc;
 
 	/* LLVM 5+ has a variadic pointer argument */
 #if LLVM_VERSION_MAJOR < 5
@@ -2557,12 +2563,12 @@ create_LifetimeEnd(LLVMModuleRef mod)
 	if (fn)
 		return fn;
 
-	param_types[0] = LLVMInt64Type();
-	param_types[1] = l_ptr(LLVMInt8Type());
+	lc = LLVMGetModuleContext(mod);
+	param_types[0] = LLVMInt64TypeInContext(lc);
+	param_types[1] = l_ptr(LLVMInt8TypeInContext(lc));
 
-	sig = LLVMFunctionType(LLVMVoidType(),
-						   param_types, lengthof(param_types),
-						   false);
+	sig = LLVMFunctionType(LLVMVoidTypeInContext(lc), param_types,
+						   lengthof(param_types), false);
 	fn = LLVMAddFunction(mod, nm, sig);
 
 	LLVMSetFunctionCallConv(fn, LLVMCCallConv);
diff --git a/src/backend/jit/llvm/llvmjit_inline.cpp b/src/backend/jit/llvm/llvmjit_inline.cpp
index c765add856..cbd17a9fef 100644
--- a/src/backend/jit/llvm/llvmjit_inline.cpp
+++ b/src/backend/jit/llvm/llvmjit_inline.cpp
@@ -114,12 +114,12 @@ typedef llvm::StringMap<std::unique_ptr<llvm::ModuleSummaryIndex> > SummaryCache
 llvm::ManagedStatic<SummaryCache> summary_cache;
 
 
-static std::unique_ptr<ImportMapTy> llvm_build_inline_plan(llvm::Module *mod);
+static std::unique_ptr<ImportMapTy> llvm_build_inline_plan(LLVMContextRef lc, llvm::Module *mod);
 static void llvm_execute_inline_plan(llvm::Module *mod,
 									 ImportMapTy *globalsToInline);
 
-static llvm::Module* load_module_cached(llvm::StringRef modPath);
-static std::unique_ptr<llvm::Module> load_module(llvm::StringRef Identifier);
+static llvm::Module* load_module_cached(LLVMContextRef c, llvm::StringRef modPath);
+static std::unique_ptr<llvm::Module> load_module(LLVMContextRef c, llvm::StringRef Identifier);
 static std::unique_ptr<llvm::ModuleSummaryIndex> llvm_load_summary(llvm::StringRef path);
 
 
@@ -159,9 +159,10 @@ summaries_for_guid(const InlineSearchPath& path, llvm::GlobalValue::GUID guid);
 void
 llvm_inline(LLVMModuleRef M)
 {
+	LLVMContextRef lc = LLVMGetModuleContext(M);
 	llvm::Module *mod = llvm::unwrap(M);
 
-	std::unique_ptr<ImportMapTy> globalsToInline = llvm_build_inline_plan(mod);
+	std::unique_ptr<ImportMapTy> globalsToInline = llvm_build_inline_plan(lc, mod);
 	if (!globalsToInline)
 		return;
 	llvm_execute_inline_plan(mod, globalsToInline.get());
@@ -172,7 +173,7 @@ llvm_inline(LLVMModuleRef M)
  * mod.
  */
 static std::unique_ptr<ImportMapTy>
-llvm_build_inline_plan(llvm::Module *mod)
+llvm_build_inline_plan(LLVMContextRef lc, llvm::Module *mod)
 {
 	std::unique_ptr<ImportMapTy> globalsToInline(new ImportMapTy());
 	FunctionInlineStates functionStates;
@@ -271,7 +272,7 @@ llvm_build_inline_plan(llvm::Module *mod)
 				continue;
 			}
 
-			defMod = load_module_cached(modPath);
+			defMod = load_module_cached(lc, modPath);
 			if (defMod->materializeMetadata())
 				elog(FATAL, "failed to materialize metadata");
 
@@ -466,20 +467,20 @@ llvm_execute_inline_plan(llvm::Module *mod, ImportMapTy *globalsToInline)
  * the cache state would get corrupted.
  */
 static llvm::Module*
-load_module_cached(llvm::StringRef modPath)
+load_module_cached(LLVMContextRef lc, llvm::StringRef modPath)
 {
 	auto it = module_cache->find(modPath);
 	if (it == module_cache->end())
 	{
 		it = module_cache->insert(
-			std::make_pair(modPath, load_module(modPath))).first;
+			std::make_pair(modPath, load_module(lc, modPath))).first;
 	}
 
 	return it->second.get();
 }
 
 static std::unique_ptr<llvm::Module>
-load_module(llvm::StringRef Identifier)
+load_module(LLVMContextRef lc, llvm::StringRef Identifier)
 {
 	LLVMMemoryBufferRef buf;
 	LLVMModuleRef mod;
@@ -491,7 +492,7 @@ load_module(llvm::StringRef Identifier)
 	if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &msg))
 		elog(FATAL, "failed to open bitcode file \"%s\": %s",
 			 path, msg);
-	if (LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), buf, &mod))
+	if (LLVMGetBitcodeModuleInContext2(lc, buf, &mod))
 		elog(FATAL, "failed to parse bitcode in file \"%s\"", path);
 
 	/*
diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h
index 0745dcac9c..5e74543be4 100644
--- a/src/include/jit/llvmjit_emit.h
+++ b/src/include/jit/llvmjit_emit.h
@@ -44,36 +44,36 @@ l_ptr(LLVMTypeRef t)
  * Emit constant integer.
  */
 static inline LLVMValueRef
-l_int8_const(int8 i)
+l_int8_const(LLVMContextRef lc, int8 i)
 {
-	return LLVMConstInt(LLVMInt8Type(), i, false);
+	return LLVMConstInt(LLVMInt8TypeInContext(lc), i, false);
 }
 
 /*
  * Emit constant integer.
  */
 static inline LLVMValueRef
-l_int16_const(int16 i)
+l_int16_const(LLVMContextRef lc, int16 i)
 {
-	return LLVMConstInt(LLVMInt16Type(), i, false);
+	return LLVMConstInt(LLVMInt16TypeInContext(lc), i, false);
 }
 
 /*
  * Emit constant integer.
  */
 static inline LLVMValueRef
-l_int32_const(int32 i)
+l_int32_const(LLVMContextRef lc, int32 i)
 {
-	return LLVMConstInt(LLVMInt32Type(), i, false);
+	return LLVMConstInt(LLVMInt32TypeInContext(lc), i, false);
 }
 
 /*
  * Emit constant integer.
  */
 static inline LLVMValueRef
-l_int64_const(int64 i)
+l_int64_const(LLVMContextRef lc, int64 i)
 {
-	return LLVMConstInt(LLVMInt64Type(), i, false);
+	return LLVMConstInt(LLVMInt64TypeInContext(lc), i, false);
 }
 
 /*
@@ -137,12 +137,15 @@ l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...)
 {
 	char		buf[512];
 	va_list		args;
+	LLVMContextRef lc;
 
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
-	return LLVMInsertBasicBlock(r, buf);
+	lc = LLVMGetTypeContext(LLVMTypeOf(LLVMGetBasicBlockParent(r)));
+
+	return LLVMInsertBasicBlockInContext(lc, r, buf);
 }
 
 /* separate, because pg_attribute_printf(2, 3) can't appear in definition */
@@ -157,12 +160,15 @@ l_bb_append_v(LLVMValueRef f, const char *fmt,...)
 {
 	char		buf[512];
 	va_list		args;
+	LLVMContextRef lc;
 
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
-	return LLVMAppendBasicBlock(f, buf);
+	lc = LLVMGetTypeContext(LLVMTypeOf(f));
+
+	return LLVMAppendBasicBlockInContext(lc, f, buf);
 }
 
 /*
@@ -174,7 +180,7 @@ l_callsite_ro(LLVMValueRef f)
 	const char	argname[] = "readonly";
 	LLVMAttributeRef ref;
 
-	ref = LLVMCreateStringAttribute(LLVMGetGlobalContext(),
+	ref = LLVMCreateStringAttribute(LLVMGetTypeContext(LLVMTypeOf(f)),
 									argname,
 									sizeof(argname) - 1,
 									NULL, 0);
@@ -194,7 +200,7 @@ l_callsite_alwaysinline(LLVMValueRef f)
 
 	id = LLVMGetEnumAttributeKindForName(argname,
 										 sizeof(argname) - 1);
-	attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), id, 0);
+	attr = LLVMCreateEnumAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), id, 0);
 	LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
 }
 
-- 
2.32.1 (Apple Git-133)

