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