openGauss源码解析(137)

openGauss源码解析:执行器解析(30)

openGauss GodeGen的整体编译流程如图7-25所示。

图7-25 openGauss CodeGen编译执行流程

数据库启动后,首先对LLVM初始化,其中CodeGenProcessInitialize函数对LLVM的环境进行初始化,包括通过isCPUFeatureSupportCodegen函数和canInitCodegenInvironment函数检查CPU是否支持CodeGen、是否能够进行环境初始化。然后通过“GsCodeGen::InitializeLlvm”函数对本地环境检查,检查环境是否为Aarch64或x86架构,并返回全局变量gscodegen_initialized。

CodeGenThreadInitialize函数在本线程中创建一个新的GsCodeGen对象,并创建内存。如果创建失败,要返回原来的内存上下文给系统,当前线程中codegen的部分保存在knl_t_codegen_context中,具体结构代码为:

typedef struct knl_t_codegen_context {

void* thr_codegen_obj;

bool g_runningInFmgr;

long codegen_IRload_thr_count;

} knl_t_codegen_context;

其中thr_codegen_obj字段保存代码中LLVM对象,在初始化和调用时通常转换成GsCodeGen类,GsCodeGen保存了LLVM全部封装好的LLVM函数、内存和成员变量等。g_runningInFmgr字段表示函数是否运行在function manager中。codegen_IRload_thr_count字段是IR载入计数。

当所有的LLVM执行环境设置完成后,执行器初始化阶段可根据解析器和优化器提供的查询计划去检查当前的计划是否可以进行LLVM代码生成优化。以gsql客户端为例,整个运行过程内嵌在执行引擎运行过程内,函数的调用从函数exec_simple_plan函数为入口,LLVM运行的3个阶段分别对应executor的3个阶段:ExecutorStart、ExecutorRun以及ExecutorEnd(从其他客户端输入的查询,最终也会走到ExecutorStart、ExecutorRun以及ExecutorEnd阶段)。

(1) ExecutorStart阶段:为运行准备阶段,初始化查询级别的GsCodeGen类对象,并在InitPlan阶段按照优化器产生的执行计划遍历其中各个算子节点初始化函数,生成IR函数。
(2) ExecutorRun阶段:为运行阶段,若已成功生成LLVM IR函数,则对该IR函数进行编译,生成可执行的机器码,并在具体的算子运行阶段用机器码替换到原本的执行函数入口。
(3) ExecutorEnd阶段:为运行完清理环境阶段,在ExecutorEnd函数中将第一阶段生成的LLVMCodeGen对象及其相关资源进行释放。

GsCodeGen的接口定义在文件“codegen/gscodegen.h”中,GsCodeGen中接口说明如表7-31所示。

表7-31 GsCodeGen接口汇总

接口名称

接口类型

职责描述

initialize

API

分配Codegen使用内存使用环境

InitializeLLVM

API

初始化LLVM运行环境

parseIRFile

API

解析IR文件

cleanupLlvm

API

停止LLVM调用线程

createNewModule

API

创建一个新的LLVM模板

compileCurrentModule

API

编译当前指定LLVM模块中的函数

compileModule

API

编译模板并依据相关选项对模板中未用的IR函数进行优化

releaseResource

API

释放LLVM模块占用的系统资源

FinalizeFunction

API

确定最后的IR函数是否可用

getType

API

从openGauss的类型转换到LLVM内部对应的类型

verifyFunction

API

检查输入的LLVM IR函数的有效性

getPtrType

API

从openGauss的类型转换到LLVM内部对应该类型的指针类型

castPtrToLlvmPtr

API

将openGauss的指针转换为LLVM的指针

getIntConstant

API

将openGauss对应类型的常数转换为LLVM对应类型的常数

generatePrototype

API

创建要加入当前LLVM模块的函数原型

replaceCallSites

API

替换LLVM当前模块的函数

optimizeModule

API

优化LLVM当前模块中的函数

addFunctionToMCJit

API

外部函数调用接口

canInitCodegenInvironment

API

判断当前可否初始化CodeGen环境

canInitThreadCodeGen

API

判断当前可否初始化CodeGen线程

CodeGenReleaseResource

API

删除当前模板和LLVM执行引擎

CodeGenProcessInitialize

API

初始化LLVM服务进程

CodeGenThreadInitilize

API

初始化LLVM服务线程

CodeGenThreadRuntimeSetup

API

初始化LLVM服务对象

CodeGenThreadRuntimeCodeGenerate

API

编译当前LLVM模板中的IR函数

CodeGenThreadTearDown

API

释放LLVM模块占用的系统资源接口

CodeGenThreadObjectReady

API

判断当前LLVM服务对象是否有效

CodeGenThreadReset

API

清空当前内存中的机器码

CodeGenPassThreshold

API

根据返回行数判断是否需要CodeGen

posted @ 2024-04-30 11:04  openGauss-bot  阅读(9)  评论(0编辑  收藏  举报