public inbox for [email protected]
help / color / mirror / Atom feedFrom: Pierre Ducroquet <[email protected]>
To: Matheus Alcantara <[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: [PATCH] llvmjit: always add the simplifycfg pass
Date: Thu, 22 Jan 2026 20:27:29 +0000
Message-ID: <H9LI9Enj4-NPP6t2g1RB9KMGkkBwzWjQwfiSLHLOTnT7YUwVPYSu_pMHwQLwwzGQGp54DQcER-eLngTa1GzVjH5Q0addrvfalukYnszTjMY=@pinaraf.info> (raw)
In-Reply-To: <[email protected]>
References: <VS3dpR1Sf5jGnWwoFFJ-_x3GbW7fdmV0arzWPIDfrmbVzewifgu6DsQ7oDa-TAwRz9N2p817j3jGstHwfPOJJxOipbcp-nHdNj3zyxKvC4Q=@pinaraf.info>
<[email protected]>
Le jeudi 22 janvier 2026 à 8:54 PM, Matheus Alcantara <[email protected]> a écrit :
> Hi,
>
> On 07/01/26 12:08, Pierre Ducroquet wrote:
>
> > Hi
> >
> > While reading the code generated by llvmjit, I realized the number of LLVM basic blocks used in tuple deforming was directly visible in the generated assembly code with the following code:
> > 0x723382b781c1: jmp 0x723382b781c3
> > 0x723382b781c3: jmp 0x723382b781eb
> > 0x723382b781c5: mov -0x20(%rsp),%rax
> > 0x723382b781..: ... .....
> > 0x723382b781e7: mov %cx,(%rax)
> > 0x723382b781ea: ret
> > 0x723382b781eb: jmp 0x723382b781ed
> > 0x723382b781ed: jmp 0x723382b781ef
> > 0x723382b781ef: jmp 0x723382b781f1
> > 0x723382b781f1: jmp 0x723382b781f3
> > 0x723382b781f3: mov -0x30(%rsp),%rax
> > 0x723382b781..: ... ......
> > 0x723382b78208: mov %rcx,(%rax)
> > 0x723382b7820b: jmp 0x723382b781c5
> > That's a lot of useless jumps, and LLVM has a specific pass to get rid of these. The attached patch modifies the llvmjit code to always call this pass, even below jit_optimize_above_cost.
> >
> > On a basic benchmark (a simple select * from table where f = 42), this optimization saved 7ms of runtime while using only 0.1 ms of extra optimization time.
>
>
> The patch needs a rebase due to e5d99b4d9ef.
>
> You've added the "simplifycfg" only when the "jit_optimize_above_cost"
> is not triggered which will use the default<O0> and mem2reg passes, the
>
> default<O3> pass already include "simplifycfg"?
>
>
> With e5d99b4d9ef being committed, should we add "simplifycfg" when
> PGJIT_INLINE bit is set since it also use the default<O0> and mem2reg
>
> passes?
Hi
Thank you, here is a rebased version of the patch.
To answer your questions:
- O3 already includes simplifycfg, so no need to modify O3
- any code generated by our llvmjit provider, esp. tuple deforming, is heavily dependent on simplifycfg, so when O0 is the basis we should always add this pass
Attachments:
[text/x-patch] 0001-llvmjit-always-use-the-simplifycfg-pass.patch (2.6K, 2-0001-llvmjit-always-use-the-simplifycfg-pass.patch)
download | inline diff:
From cb5cb74461ac9407c16903bfa9d2855f4e76918e Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet <[email protected]>
Date: Wed, 7 Jan 2026 15:43:19 +0100
Subject: [PATCH] llvmjit: always use the simplifycfg pass
The simplifycfg pass will remove empty or unreachable LLVM basic blocks,
and merge blocks together when possible.
This is important because the tuple deforming code will generate a lot of
basic blocks, and previously with O0 we did not run this pass, thus creating
this kind of (amd64) machine code:
0x723382b781c1: jmp 0x723382b781c3
0x723382b781c3: jmp 0x723382b781eb
0x723382b781c5: mov -0x20(%rsp),%rax
0x723382b781..: ... .....
0x723382b781e7: mov %cx,(%rax)
0x723382b781ea: ret
0x723382b781eb: jmp 0x723382b781ed
0x723382b781ed: jmp 0x723382b781ef
0x723382b781ef: jmp 0x723382b781f1
0x723382b781f1: jmp 0x723382b781f3
0x723382b781f3: mov -0x30(%rsp),%rax
0x723382b781..: ... ......
0x723382b78208: mov %rcx,(%rax)
0x723382b7820b: jmp 0x723382b781c5
This is not efficient at all, and triggering the simplifycfg pass ends up
tacking a few hundreds micro seconds while possibly saving much more time
during execution. On a basic benchmark, I saved 7ms on query runtime while
using 0.2ms on extra JIT compilation overhead
---
src/backend/jit/llvm/llvmjit.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 2e8aa4749db..c22f83e97cf 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -633,6 +633,11 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
{
/* we rely on mem2reg heavily, so emit even in the O0 case */
LLVMAddPromoteMemoryToRegisterPass(llvm_fpm);
+ /*
+ * the tuple deforming generates a lot of basic blocks,
+ * simplify them even with O0
+ */
+ LLVMAddCFGSimplificationPass(llvm_fpm);
}
LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm);
@@ -676,10 +681,10 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
passes = "default<O3>";
else if (context->base.flags & PGJIT_INLINE)
/* if doing inlining, but no expensive optimization, add inline pass */
- passes = "default<O0>,mem2reg,inline";
+ passes = "default<O0>,mem2reg,simplifycfg,inline";
else
/* default<O0> includes always-inline pass */
- passes = "default<O0>,mem2reg";
+ passes = "default<O0>,mem2reg,simplifycfg";
options = LLVMCreatePassBuilderOptions();
--
2.43.0
view thread (8+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: [PATCH] llvmjit: always add the simplifycfg pass
In-Reply-To: <H9LI9Enj4-NPP6t2g1RB9KMGkkBwzWjQwfiSLHLOTnT7YUwVPYSu_pMHwQLwwzGQGp54DQcER-eLngTa1GzVjH5Q0addrvfalukYnszTjMY=@pinaraf.info>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox