mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-27 04:54:21 +01:00
This PR is unapologetically stolen from @vmg's implementation in Vitess implemented here https://github.com/vitessio/vitess/pull/12369. If you want a more in depth explanation of how this works you can read the [blog post he carefully wrote](https://planetscale.com/blog/faster-interpreters-in-go-catching-up-with-cpp). In limbo we have a huge problem with [register spilling](https://en.wikipedia.org/wiki/Register_allocation), this can be easily observed with the prolog of `Program::step` before: ```llvm start: %e.i.i304.i = alloca [0 x i8], align 8 %formatter.i305.i = alloca [64 x i8], align 8 %buf.i306.i = alloca [24 x i8], align 8 %formatter.i259.i = alloca [64 x i8], align 8 ..................... these are repeated for hundreds of lines ..................... %formatter.i52.i = alloca [64 x i8], align 8 %buf.i53.i = alloca [24 x i8], align 8 %formatter.i.i = alloca [64 x i8], align 8 %buf.i.i = alloca [24 x i8], align 8 %_87.i = alloca [48 x i8], align 8 %_82.i = alloca [24 x i8], align 8 %_73.i = alloca [24 x i8], align 8 %_66.i8446 = alloca [24 x i8], align 8 %_57.i = alloca [24 x i8], align 8 %_48.i = alloca [24 x i8], align 8 ``` After these changes we completely remove the need of register spilling (yes that is the complete prolog): ```llvm start: %self1 = alloca [80 x i8], align 8 %pager = alloca [8 x i8], align 8 %mv_store = alloca [8 x i8], align 8 store ptr %0, ptr %mv_store, align 8 store ptr %1, ptr %pager, align 8 %2 = getelementptr inbounds i8, ptr %state, i64 580 %3 = getelementptr inbounds i8, ptr %state, i64 576 %4 = getelementptr inbounds i8, ptr %self, i64 16 %5 = getelementptr inbounds i8, ptr %self, i64 8 %6 = getelementptr inbounds i8, ptr %self1, i64 8 br label %bb1, !dbg !286780 ``` When it comes to branch prediction, we don't really fix a lot because thankfully rust already compiles `match` expressions to a jump table: ```llvm %insn = getelementptr inbounds [0 x %"vdbe::insn::Insn"], ptr %self657, i64 0, i64 %index, !dbg !249527 %332 = load i8, ptr %insn, align 8, !dbg !249528, !range !38291, !noundef !14 switch i8 %332, label %default.unreachable26674 [ i8 0, label %bb111 i8 1, label %bb101 i8 2, label %bb100 i8 3, label %bb110 ... i8 104, label %bb5 i8 105, label %bb16 i8 106, label %bb14 ], !dbg !249530 ``` Some results ---- ``` function dispatch: Execute `SELECT 1`/limbo_execute_select_1 time: [29.498 ns 29.548 ns 29.601 ns] change: [-3.6125% -3.3592% -3.0804%] (p = 0.00 < 0.05) main: Execute `SELECT 1`/limbo_execute_select_1 time: [33.789 ns 33.832 ns 33.878 ns] ```