From c5983755a3d3470a072c8fc6169a98fa79b0b75e Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet <p.psql@pinaraf.info>
Date: Fri, 13 Jul 2018 09:45:44 +0200
Subject: [PATCH] Skip alignment code blocks when they are not needed

---
 src/backend/jit/llvm/llvmjit_deform.c | 57 ++++++++++++++++-----------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
index 795f67114e..d042e4fba5 100644
--- a/src/backend/jit/llvm/llvmjit_deform.c
+++ b/src/backend/jit/llvm/llvmjit_deform.c
@@ -331,6 +331,34 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 		LLVMValueRef l_attno = l_int16_const(attnum);
 		LLVMValueRef v_attdatap;
 		LLVMValueRef v_resultp;
+		bool			has_alignment;
+		bool			has_alignment_check;
+		LLVMBasicBlockRef	align_block_target;
+
+		/* determine required alignment */
+		if (att->attalign == 'i')
+			alignto = ALIGNOF_INT;
+		else if (att->attalign == 'c')
+			alignto = 1;
+		else if (att->attalign == 'd')
+			alignto = ALIGNOF_DOUBLE;
+		else if (att->attalign == 's')
+			alignto = ALIGNOF_SHORT;
+		else
+		{
+			elog(ERROR, "unknown alignment");
+			alignto = 0;
+		}
+
+		has_alignment = (alignto > 1 &&
+			(known_alignment < 0 || known_alignment != TYPEALIGN(alignto, known_alignment)));
+		has_alignment_check = has_alignment && (att->attlen == -1);
+		if (has_alignment_check)
+			align_block_target = attcheckalignblocks[attnum];
+		else if (has_alignment)
+			align_block_target = attalignblocks[attnum];
+		else
+			align_block_target = attstoreblocks[attnum];
 
 		/* build block checking whether we did all the necessary attributes */
 		LLVMPositionBuilderAtEnd(b, attcheckattnoblocks[attnum]);
@@ -363,6 +391,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 									 "heap_natts");
 			LLVMBuildCondBr(b, v_islast, b_out, attstartblocks[attnum]);
 		}
+
 		LLVMPositionBuilderAtEnd(b, attstartblocks[attnum]);
 
 		/*
@@ -381,7 +410,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 			LLVMValueRef v_nullbyte;
 			LLVMValueRef v_nullbit;
 
-			b_ifnotnull = attcheckalignblocks[attnum];
+			b_ifnotnull = align_block_target;
 			b_ifnull = attisnullblocks[attnum];
 
 			if (attnum + 1 == natts)
@@ -420,27 +449,12 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 		else
 		{
 			/* nothing to do */
-			LLVMBuildBr(b, attcheckalignblocks[attnum]);
+			LLVMBuildBr(b, align_block_target);
 			LLVMPositionBuilderAtEnd(b, attisnullblocks[attnum]);
-			LLVMBuildBr(b, attcheckalignblocks[attnum]);
+			LLVMBuildBr(b, align_block_target);
 		}
 		LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
 
-		/* determine required alignment */
-		if (att->attalign == 'i')
-			alignto = ALIGNOF_INT;
-		else if (att->attalign == 'c')
-			alignto = 1;
-		else if (att->attalign == 'd')
-			alignto = ALIGNOF_DOUBLE;
-		else if (att->attalign == 's')
-			alignto = ALIGNOF_SHORT;
-		else
-		{
-			elog(ERROR, "unknown alignment");
-			alignto = 0;
-		}
-
 		/* ------
 		 * Even if alignment is required, we can skip doing it if provably
 		 * unnecessary:
@@ -450,8 +464,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 		 *   is compatible with current column.
 		 * ------
 		 */
-		if (alignto > 1 &&
-			(known_alignment < 0 || known_alignment != TYPEALIGN(alignto, known_alignment)))
+		if (has_alignment)
 		{
 			/*
 			 * When accessing a varlena field we have to "peek" to see if we
@@ -462,7 +475,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 			 * length word, or the first byte of a correctly aligned 4-byte
 			 * length word; in either case we need not align.
 			 */
-			if (att->attlen == -1)
+			if (has_alignment_check)
 			{
 				LLVMValueRef v_possible_padbyte;
 				LLVMValueRef v_ispad;
@@ -526,7 +539,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
 		else
 		{
 			LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
-			LLVMBuildBr(b, attalignblocks[attnum]);
+			LLVMBuildBr(b, attstoreblocks[attnum]);
 			LLVMPositionBuilderAtEnd(b, attalignblocks[attnum]);
 			LLVMBuildBr(b, attstoreblocks[attnum]);
 		}
-- 
2.18.0

