From c5983755a3d3470a072c8fc6169a98fa79b0b75e Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet
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