前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Postgresql中的C/C++混编(JIT)

Postgresql中的C/C++混编(JIT)

作者头像
mingjie
发布2023-10-13 10:32:40
1890
发布2023-10-13 10:32:40
举报

1 Postgresql编译JIT

整体上看使用了GCC、G++编译文件,最后用G++汇总:

在这里插入图片描述
在这里插入图片描述

GCC编译的三个.o文件llvmjit、llvmjit_deform、llvmjit_expr

代码语言:javascript
复制
llvmjit.c        -> llvmjit.o
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2  -Wno-deprecated-declarations -fPIC -fvisibility=hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit.o llvmjit.c -MMD -MP -MF .deps/llvmjit.Po

llvmjit_deform.c -> llvmjit_deform.o
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2  -Wno-deprecated-declarations -fPIC -fvisibility=hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit_deform.o llvmjit_deform.c -MMD -MP -MF .deps/llvmjit_deform.Po

llvmjit_expr.c   -> llvmjit_expr.o
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2  -Wno-deprecated-declarations -fPIC -fvisibility=hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit_expr.o llvmjit_expr.c -MMD -MP -MF .deps/llvmjit_expr.Po

G++编译的三个.o文件llvmjit_error、llvmjit_inline、llvmjit_wrap

代码语言:javascript
复制
llvmjit_error.cpp     ->   llvmjit_error.o
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -g -O2 -std=c++14 -fno-rtti -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit_error.o llvmjit_error.cpp -MMD -MP -MF .deps/llvmjit_error.Po

llvmjit_inline.cpp    ->   llvmjit_inline.o
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -g -O2 -std=c++14 -fno-rtti -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit_inline.o llvmjit_inline.cpp -MMD -MP -MF .deps/llvmjit_inline.Po

llvmjit_wrap.cpp      ->   llvmjit_wrap.o
g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -g -O2 -std=c++14 -fno-rtti -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include  -I../../../../src/include  -D_GNU_SOURCE -I/usr/include/libxml2   -c -o llvmjit_wrap.o llvmjit_wrap.cpp -MMD -MP -MF .deps/llvmjit_wrap.Po

G++汇总的llvmjit.so

代码语言:javascript
复制
llvmjit.so

g++ -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2  -Wno-deprecated-declarations -fPIC -fvisibility=hidden -shared -o llvmjit.so  llvmjit.o llvmjit_error.o llvmjit_inline.o llvmjit_wrap.o llvmjit_deform.o llvmjit_expr.o -L../../../../src/port -L../../../../src/common   -L/data02/mingjie/bin/llvm15/lib  -Wl,--as-needed -Wl,-rpath,'/data02/mingjie/pgroot99/pghome/lib',--enable-new-dtags  -fvisibility=hidden -lLLVMOrcJIT -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCoroutines -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMFrontendOpenMP -lLLVMJITLink -lLLVMX86TargetMCA -lLLVMMCA -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMCFGuard -lLLVMGlobalISel -lLLVMX86Desc -lLLVMX86Info -lLLVMMCDisassembler -lLLVMSelectionDAG -lLLVMInstrumentation -lLLVMAsmPrinter -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMOrcTargetProcess -lLLVMOrcShared -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoMSF -lLLVMDebugInfoDWARF -lLLVMObject -lLLVMTextAPI -lLLVMMCParser -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMBitReader -lLLVMCore -lLLVMRemarks -lLLVMBitstreamReader -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle -lrt -ldl -lpthread -lm -lz -lzstd -ltinfo -lxml2
1.1 GCC

gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2 -Wno-deprecated-declarations -fPIC -fvisibility=hidden

  • llvm-config --cflags: -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include

-I…/…/…/…/src/include -D_GNU_SOURCE -I/usr/include/libxml2 -c -o llvmjit.o llvmjit.c -MMD -MP -MF .deps/llvmjit.Po

1.2 G++

g++ -Wall -Wpointer-arith -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -g -O2 -std=c++14 -fno-rtti -fPIC -fvisibility=hidden -fvisibility-inlines-hidden

  • llvm-config --cflags: -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -DBUILD_EXAMPLES -I/data02/mingjie/bin/llvm15/include

-I…/…/…/…/src/include -D_GNU_SOURCE -I/usr/include/libxml2 -c -o llvmjit_error.o llvmjit_error.cpp -MMD -MP -MF .deps/llvmjit_error.Po

1.3 llvmjit.so

g++ -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -ggdb -O0 -g3 -gdwarf-2 -Wno-deprecated-declarations -fPIC -fvisibility=hidden -shared -o llvmjit.so llvmjit.o llvmjit_error.o llvmjit_inline.o llvmjit_wrap.o llvmjit_deform.o llvmjit_expr.o -L…/…/…/…/src/port -L…/…/…/…/src/common

  • llvm-config --ldflags: -L/data02/mingjie/bin/llvm15/lib

-Wl,–as-needed -Wl,-rpath,‘/data02/mingjie/pgroot99/pghome/lib’,–enable-new-dtags -fvisibility=hidden

  • llvm-config --libs: -lLLVMOrcJIT -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCoroutines -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMFrontendOpenMP -lLLVMJITLink -lLLVMX86TargetMCA -lLLVMMCA -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMCFGuard -lLLVMGlobalISel -lLLVMX86Desc -lLLVMX86Info -lLLVMMCDisassembler -lLLVMSelectionDAG -lLLVMInstrumentation -lLLVMAsmPrinter -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMOrcTargetProcess -lLLVMOrcShared -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoMSF -lLLVMDebugInfoDWARF -lLLVMObject -lLLVMTextAPI -lLLVMMCParser -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMBitReader -lLLVMCore -lLLVMRemarks -lLLVMBitstreamReader -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle
  • llvm-config --system-libs: -lrt -ldl -lpthread -lm -lz -lzstd -ltinfo -lxml2

2 Postgresql加载JIT

编译后生成llvmjit.so,在程序启动时不做加载,在运行时按需加载。

加载位置:jit.c提供的provider_init函数中,对llvmjit.so进行动态加载:

代码语言:javascript
复制
provider_init
	load_external_function(path, "_PG_jit_provider_init", true, NULL)
		internal_load_library
			dlopen(file_scanner->filename, RTLD_NOW | RTLD_GLOBAL)
		dlsym(lib_handle, funcname);
2.1 如何使用llvmjit.so的符号表?

G++编译的三个cpp文件会依赖llvm库,llvm是用C++实现的,所以llvmjit.so中会存在大量经过mangling的符号,GCC无法识别,例如:readelf -s llvmjit.so | head -n 100

在这里插入图片描述
在这里插入图片描述

那怎么让进程找到符号呢?用extern "C"标注那些不要做mangling的符号。

例如:llvmjit.h (一般在.c中随便写,需要避免mangling的在.h中声明即可)

代码语言:javascript
复制
extern "C"
{
	...
	extern void llvm_enter_fatal_on_oom(void);
	...
	extern bool llvm_compile_expr(struct ExprState *state);
	struct TupleTableSlotOps;
	extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDesc desc,
										const struct TupleTableSlotOps *ops, int natts);
	...
} /* extern "C" */

在符号表中可以看到这几个符号:

在这里插入图片描述
在这里插入图片描述

这类符号就可以被GCC编译的程序正常调用,例如:llvm_enter_fatal_on_oom函数在llvmjit_error.cpp中定义,在llvmjit_expr.c中使用。

3 思考

  1. link llvm后so过大(1.3GB),需要考虑加载时间,加载时IO大文件到内存中还是会严重拉低执行时间的。
  2. 如果避免每个子进程都要加载,在PG中让父进程加载一次即可。
  3. LLVM逻辑可以基本都在CPP中实现,给外部提供接口即可,接口只做钩子函数赋值。
  4. 如果是现存系统,LLVM适合做旁路逻辑,主逻辑还需要存在,需逐步演化。

mangling的一些细节:

声明时禁止mangling:

代码语言:javascript
复制
extern "C" {
   int f1(int);
   int f2(int);
   int f3(int);
};

定义时也可以禁止mangling:

代码语言:javascript
复制
extern "C" {
   void p(int){
      /* not mangled */
   }
};

多层时已最内层为准,会mangling:

代码语言:javascript
复制
extern "C" {
      extern "C++" {
            void func();
      }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 Postgresql编译JIT
    • 1.1 GCC
      • 1.2 G++
        • 1.3 llvmjit.so
        • 2 Postgresql加载JIT
          • 2.1 如何使用llvmjit.so的符号表?
          • 3 思考
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档