第6章:LLVM JIT
第6章:LLVM JIT
“LLVM 不仅是编译器框架,更是构建 JIT 编译系统的最佳基础设施。”
6.1 LLVM 概述
LLVM(Low Level Virtual Machine)是一个模块化、可重用的编译器和工具链技术集合。它提供了从源代码到机器码的完整编译基础设施,特别适合构建自定义 JIT 编译系统。
6.1.1 LLVM 架构
┌─────────────────────────────────────────────────────────────────┐
│ LLVM 架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 源代码 (C/C++/Rust/自定义语言) │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Frontend │ ← Clang (C/C++), rustc (Rust) │
│ │ (前端) │ │
│ └──────┬──────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ LLVM IR │ ← 中间表示(文本或二进制) │
│ │ (中间层) │ │
│ └──────┬──────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Optimizer │ ← 多趟优化 │
│ │ (优化器) │ │
│ └──────┬──────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Backend │ ← 目标代码生成 │
│ │ (后端) │ x86, ARM, RISC-V, WebAssembly │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
6.1.2 LLVM 的 JIT 演进
2007 LLVM JIT (旧 JIT)
│
2012 MCJIT 发布
│ └─ 基于 MC 层的 JIT 引擎
│
2015 ORC JIT v1
│ └─ On-Request Compilation
│
2019 ORC JIT v2
│ └─ 重设计,更好的延迟编译
│
2021 LLVM JITLink
└─ 自定义链接器
6.2 LLVM IR 基础
6.2.1 LLVM IR 的特点
LLVM IR 是一种强类型、低级的、与目标无关的表示形式。
; LLVM IR 文本格式示例
; 定义一个简单的加法函数
define i32 @add(i32 %a, i32 %b) {
entry:
%result = add i32 %a, %b
ret i32 %result
}
; 循环示例:计算数组元素之和
define i64 @sum_array(i32* %arr, i64 %len) {
entry:
%sum = alloca i64
store i64 0, i64* %sum
%i = alloca i64
store i64 0, i64* %i
br label %loop
loop:
%i_val = load i64, i64* %i
%cmp = icmp slt i64 %i_val, %len
br i1 %cmp, %body, %exit
body:
%ptr = getelementptr i32, i32* %arr, i64 %i_val
%val = load i32, i32* %ptr
%ext = sext i32 %val to i64
%sum_val = load i64, i64* %sum
%new_sum = add i64 %sum_val, %ext
store i64 %new_sum, i64* %sum
%new_i = add i64 %i_val, 1
store i64 %new_i, i64* %i
br label %loop
exit:
%result = load i64, i64* %sum
ret i64 %result
}
6.2.2 LLVM IR 类型系统
; 基本类型
; 整数: i1, i8, i16, i32, i64, i128
; 浮点: float, double, fp128
; 示例
define i32 @types_demo() {
; 整数常量
%a = add i32 1, 2
%b = add i64 1, 2
; 浮点常量
%c = fadd float 1.0, 2.0
%d = fadd double 1.0, 2.0
; 布尔
%e = and i1 true, false
ret i32 0
}
; 指针类型
%Point = type { double, double }
define double @distance(%Point* %p) {
%x_ptr = getelementptr %Point, %Point* %p, i32 0, i32 0
%y_ptr = getelementptr %Point, %Point* %p, i32 0, i32 1
%x = load double, double* %x_ptr
%y = load double, double* %y_ptr
%x2 = fmul double %x, %x
%y2 = fmul double %y, %y
%sum = fadd double %x2, %y2
%dist = call double @sqrt(double %sum)
ret double %dist
}
declare double @sqrt(double)
6.2.3 生成 LLVM IR
// 使用 LLVM C++ API 生成 IR
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
using namespace llvm;
int main() {
LLVMContext context;
Module module("my_module", context);
IRBuilder<> builder(context);
// 定义函数类型: i32 (i32, i32)
Type* int32Type = Type::getInt32Ty(context);
FunctionType* funcType = FunctionType::get(
int32Type,
{int32Type, int32Type},
false
);
// 创建函数
Function* addFunc = Function::Create(
funcType,
Function::ExternalLinkage,
"add",
module
);
// 创建基本块
BasicBlock* entry = BasicBlock::Create(context, "entry", addFunc);
builder.SetInsertPoint(entry);
// 获取参数
auto args = addFunc->arg_begin();
Value* a = &*args++;
Value* b = &*args;
// 生成加法指令
Value* sum = builder.CreateAdd(a, b, "sum");
builder.CreateRet(sum);
// 验证
verifyFunction(*addFunc);
// 输出 IR
module.print(outs(), nullptr);
return 0;
}
// 生成循环
Function* createSumLoop(Module& module, LLVMContext& context) {
IRBuilder<> builder(context);
Type* int64Type = Type::getInt64Ty(context);
Type* int32PtrType = Type::getInt32PtrTy(context);
FunctionType* funcType = FunctionType::get(
int64Type,
{int32PtrType, int64Type},
false
);
Function* func = Function::Create(
funcType,
Function::ExternalLinkage,
"sum_array",
module
);
// 基本块
BasicBlock* entry = BasicBlock::Create(context, "entry", func);
BasicBlock* loop = BasicBlock::Create(context, "loop", func);
BasicBlock* body = BasicBlock::Create(context, "body", func);
BasicBlock* exit = BasicBlock::Create(context, "exit", func);
// Entry
builder.SetInsertPoint(entry);
Value* arr = func->arg_begin();
Value* len = func->arg_begin() + 1;
Value* sumAlloca = builder.CreateAlloca(int64Type, nullptr, "sum");
Value* iAlloca = builder.CreateAlloca(int64Type, nullptr, "i");
builder.CreateStore(ConstantInt::get(int64Type, 0), sumAlloca);
builder.CreateStore(ConstantInt::get(int64Type, 0), iAlloca);
builder.CreateBr(loop);
// Loop
builder.SetInsertPoint(loop);
Value* iVal = builder.CreateLoad(int64Type, iAlloca);
Value* cmp = builder.CreateICmpSLT(iVal, len);
builder.CreateCondBr(cmp, body, exit);
// Body
builder.SetInsertPoint(body);
Value* ptr = builder.CreateGEP(Type::getInt32Ty(context), arr, iVal);
Value* val = builder.CreateLoad(Type::getInt32Ty(context), ptr);
Value* ext = builder.CreateSExt(val, int64Type);
Value* sumVal = builder.CreateLoad(int64Type, sumAlloca);
Value* newSum = builder.CreateAdd(sumVal, ext);
builder.CreateStore(newSum, sumAlloca);
Value* newI = builder.CreateAdd(iVal, ConstantInt::get(int64Type, 1));
builder.CreateStore(newI, iAlloca);
builder.CreateBr(loop);
// Exit
builder.SetInsertPoint(exit);
Value* result = builder.CreateLoad(int64Type, sumAlloca);
builder.CreateRet(result);
return func;
}
6.3 MCJIT
6.3.1 MCJIT 概述
MCJIT 是 LLVM 的第一代正式 JIT 引擎,基于 MC(Machine Code)层实现。
// MCJIT 基本用法
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/TargetSelect.h"
int main() {
// 初始化目标
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
LLVMContext context;
Module module("jit_demo", context);
// ... 创建 IR ...
// 创建 MCJIT 执行引擎
std::string error;
ExecutionEngine* engine = EngineBuilder(std::move(module))
.setEngineKind(EngineKind::JIT)
.setErrorStr(&error)
.create();
if (!engine) {
errs() << "Failed to create engine: " << error << "\n";
return 1;
}
// 获取函数指针
auto func = (int(*)(int, int))engine->getFunctionAddress("add");
if (func) {
int result = func(3, 4);
outs() << "Result: " << result << "\n"; // 7
}
delete engine;
return 0;
}
6.3.2 MCJIT 的工作流程
┌─────────────────────────────────────────────────────────────────┐
│ MCJIT 工作流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. LLVM IR │
│ │ │
│ ▼ │
│ 2. 目标代码生成 │
│ └─ IR → 汇编代码 (MC 层) │
│ │ │
│ ▼ │
│ 3. 目标文件生成 │
│ └─ 汇编 → 目标文件 (Object File) │
│ │ │
│ ▼ │
│ 4. 链接 │
│ └─ 解析符号,重定位 │
│ │ │
│ ▼ │
│ 5. 执行 │
│ └─ 跳转到机器码执行 │
│ │
└─────────────────────────────────────────────────────────────────┘
6.3.3 MCJIT 的局限
| 局限 | 说明 |
|---|---|
| 整模块编译 | 必须编译整个模块 |
| 延迟编译有限 | 不支持真正的按需编译 |
| 内存管理 | 每个模块需要独立的内存管理器 |
| 重编译困难 | 不支持高效的代码更新 |
6.4 ORC JIT
6.4.1 ORC JIT 概述
ORC(On-Request Compilation)JIT 是 LLVM 的下一代 JIT 框架,解决了 MCJIT 的诸多限制。
// ORC JIT 基本用法 (LLVM 17+)
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/Support/TargetSelect.h"
using namespace llvm;
using namespace llvm::orc;
int main() {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
// 创建 LLJIT 实例
auto jit = LLJITBuilder().create();
if (!jit) {
errs() << "Failed to create LLJIT: "
<< toString(jit.takeError()) << "\n";
return 1;
}
// 从 IR 文件添加模块
auto module = parseIRFile("module.ll", err, context);
if (!module) {
errs() << "Failed to parse IR\n";
return 1;
}
// 添加到 JIT
auto threadSafeModule = ThreadSafeModule(
std::move(module), std::make_unique<LLVMContext>()
);
jit->addIRModule(std::move(threadSafeModule));
// 查找并调用函数
auto mainSym = jit->lookup("main");
if (!mainSym) {
errs() << "Failed to find main\n";
return 1;
}
auto* mainFunc = mainSym->toPtr<int()>();
int result = mainFunc();
outs() << "Result: " << result << "\n";
return 0;
}
6.4.2 ORC JIT v2 架构
┌─────────────────────────────────────────────────────────────────┐
│ ORC JIT v2 架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Execution │ │ IR Compile │ │ Object │ │
│ │ Session │──│ Layer │──│ Layer │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ └──────────────│ JITLink │───────────────┘ │
│ │ (Linker) │ │
│ └──────────────┘ │
│ │
│ 主要组件: │
│ - ExecutionSession: 管理 JIT 执行上下文 │
│ - IRCompileLayer: IR → Object 编译 │
│ - ObjectLinkLayer: Object → 可执行代码 │
│ - JITLink: 自定义链接器 │
│ │
└─────────────────────────────────────────────────────────────────┘
6.4.3 延迟编译
// ORC JIT 延迟编译
#include "llvm/ExecutionEngine/Orc/LLLazyJIT.h"
using namespace llvm::orc;
// 创建懒加载 JIT
auto jit = LLLazyJITBuilder().create();
// 添加模块(不立即编译)
jit->addLazyIRModule(std::move(module));
// 只有在实际调用时才编译
auto sym = jit->lookup("expensive_function");
// ← 此时才触发编译
6.4.4 模块重编译
// ORC JIT 支持代码更新
class JITRecompiler {
std::unique_ptr<LLJIT> jit;
ResourceTrackerSP tracker;
public:
void compileAndRun(const std::string& code) {
// 如果已有代码,移除旧模块
if (tracker) {
tracker->remove();
}
// 编译新代码
auto module = compileCode(code);
tracker = jit->getMainJITDylib().createResourceTracker();
jit->addIRModule(
ThreadSafeModule(std::move(module), makeContext()),
tracker
);
// 执行
auto mainSym = jit->lookup("main");
auto* mainFunc = mainSym->toPtr<int()>();
mainFunc();
}
};
6.5 自定义编译器示例
6.5.1 构建简单语言 JIT
// 完整的表达式语言 JIT
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include <map>
#include <string>
class ExpressionJIT {
LLVMContext context;
std::unique_ptr<Module> module;
IRBuilder<> builder;
std::unique_ptr<orc::LLJIT> jit;
std::map<std::string, Value*> namedValues;
public:
ExpressionJIT() : builder(context) {
module = std::make_unique<Module>("expr_jit", context);
// 初始化 JIT
auto jitOrErr = orc::LLJITBuilder().create();
if (!jitOrErr) {
errs() << "Failed to create JIT\n";
exit(1);
}
jit = std::move(*jitOrErr);
}
// 编译表达式
double evaluate(const std::string& expr) {
// 解析表达式
auto ast = parse(expr);
// 生成 IR
Function* func = codegen(ast);
// 添加到 JIT
module->setDataLayout(jit->getDataLayout());
auto tsm = orc::ThreadSafeModule(
std::move(module), std::make_unique<LLVMContext>()
);
jit->addIRModule(std::move(tsm));
// 创建新模块用于后续编译
module = std::make_unique<Module>("expr_jit", context);
// 查找并执行
auto sym = jit->lookup("__anon_expr");
if (!sym) {
errs() << "Failed to find function\n";
return 0;
}
auto* funcPtr = sym->toPtr<double()>();
return funcPtr();
}
private:
Function* codegen(ASTNode* node) {
// 创建函数
FunctionType* funcType = FunctionType::get(
builder.getDoubleTy(), {}, false
);
Function* func = Function::Create(
funcType, Function::ExternalLinkage,
"__anon_expr", module.get()
);
BasicBlock* entry = BasicBlock::Create(context, "entry", func);
builder.SetInsertPoint(entry);
// 生成表达式代码
Value* val = codegenExpr(node);
builder.CreateRet(val);
verifyFunction(*func);
return func;
}
Value* codegenExpr(ASTNode* node) {
switch (node->type) {
case NodeType::Number:
return ConstantFP::get(context, APFloat(node->value));
case NodeType::BinaryOp:
Value* L = codegenExpr(node->left);
Value* R = codegenExpr(node->right);
switch (node->op) {
case '+': return builder.CreateFAdd(L, R, "addtmp");
case '-': return builder.CreateFSub(L, R, "subtmp");
case '*': return builder.CreateFMul(L, R, "multmp");
case '/': return builder.CreateFDiv(L, R, "divtmp");
}
}
return nullptr;
}
};
// 使用
int main() {
ExpressionJIT jit;
std::cout << jit.evaluate("3 + 4 * 2") << std::endl; // 11
std::cout << jit.evaluate("(3 + 4) * 2") << std::endl; // 14
std::cout << jit.evaluate("sin(3.14)") << std::endl; // ~0
return 0;
}
6.5.2 LLVM JIT 优化管线配置
// 配置优化管线
#include "llvm/Passes/PassBuilder.h"
FunctionPassManager createOptPipeline() {
FunctionPassManager FPM;
// 添加优化 Pass
FPM.addPass(InstCombinePass()); // 指令合并
FPM.addPass(ReassociatePass()); // 重新关联
FPM.addPass(GVNPass()); // 全局值编号
FPM.addPass(SimplifyCFGPass()); // 简化 CFG
FPM.addPass(LoopSimplifyPass()); // 循环简化
FPM.addPass(LoopVectorizePass()); // 循环向量化
FPM.addPass(LoopUnrollPass()); // 循环展开
return FPM;
}
ModulePassManager createModulePipeline() {
ModulePassManager MPM;
// 函数 Pass
FunctionPassManager FPM = createOptPipeline();
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
// 模块级 Pass
MPM.addPass(GlobalDCEPass()); // 死全局消除
MPM.addPass(ConstantMergePass()); // 常量合并
return MPM;
}
6.6 DSL 编译
6.6.1 什么是 DSL
DSL(Domain Specific Language,领域特定语言)是为特定问题域设计的专用语言。LLVM JIT 非常适合为 DSL 构建编译器。
6.6.2 数学表达式 DSL
// 数学 DSL JIT 编译器
class MathDSLJIT {
// AST 节点
struct Expr {
enum Type { Num, Var, BinOp, Call } type;
double value; // Num
std::string name; // Var, Call
char op; // BinOp
std::vector<std::unique_ptr<Expr>> args;
};
LLVMContext ctx;
IRBuilder<> builder;
std::unique_ptr<Module> module;
public:
// 编译数学函数
// DSL 输入: "fn f(x) = x * x + 2 * x + 1"
// 输出: 可调用的机器码函数
void* compileFunction(const std::string& name,
const std::vector<std::string>& params,
Expr* body) {
module = std::make_unique<Module>(name, ctx);
IRBuilder<> builder(ctx);
// 创建函数类型
std::vector<Type*> paramTypes(params.size(),
builder.getDoubleTy());
FunctionType* funcType = FunctionType::get(
builder.getDoubleTy(), paramTypes, false
);
Function* func = Function::Create(
funcType, Function::ExternalLinkage, name, module.get()
);
// 设置参数名
std::map<std::string, Value*> namedValues;
size_t i = 0;
for (auto& arg : func->args()) {
arg.setName(params[i]);
namedValues[params[i]] = &arg;
i++;
}
// 生成函数体
BasicBlock* entry = BasicBlock::Create(ctx, "entry", func);
builder.SetInsertPoint(entry);
Value* retVal = codegen(body, namedValues);
builder.CreateRet(retVal);
// 编译并返回函数指针
return compileModule(func);
}
private:
Value* codegen(Expr* expr, std::map<std::string, Value*>& vars) {
switch (expr->type) {
case Expr::Num:
return ConstantFP::get(ctx, APFloat(expr->value));
case Expr::Var:
if (vars.count(expr->name))
return vars[expr->name];
return nullptr;
case Expr::BinOp: {
Value* L = codegen(expr->args[0].get(), vars);
Value* R = codegen(expr->args[1].get(), vars);
switch (expr->op) {
case '+': return builder.CreateFAdd(L, R);
case '-': return builder.CreateFSub(L, R);
case '*': return builder.CreateFMul(L, R);
case '/': return builder.CreateFDiv(L, R);
case '^':
// 内联 pow 的特殊情况
if (auto* c = dyn_cast<ConstantFP>(R)) {
if (c->getValue().convertToDouble() == 2.0)
return builder.CreateFMul(L, L);
}
return createPowCall(L, R);
}
}
case Expr::Call:
if (expr->name == "sin") {
Value* arg = codegen(expr->args[0].get(), vars);
return builder.CreateCall(getIntrinsic(Intrinsic::sin), {arg});
}
if (expr->name == "cos") {
Value* arg = codegen(expr->args[0].get(), vars);
return builder.CreateCall(getIntrinsic(Intrinsic::cos), {arg});
}
}
return nullptr;
}
};
6.6.3 SQL DSL 编译
// 简化的 SQL WHERE 子句编译
// DSL: "age > 18 AND city = 'Beijing'"
struct Row {
int age;
std::string city;
double salary;
};
class SQLFilterJIT {
LLVMContext ctx;
IRBuilder<> builder;
// 编译 SQL 表达式为过滤函数
using FilterFunc = bool(*)(const Row*);
FilterFunc compileFilter(const std::string& sqlWhere) {
auto module = std::make_unique<Module>("sql_filter", ctx);
// 解析 SQL WHERE 子句
auto ast = parseSQLWhere(sqlWhere);
// 创建 Row 结构体类型
StructType* rowType = createRowType();
// 创建过滤函数
FunctionType* funcType = FunctionType::get(
builder.getInt1Ty(),
{PointerType::getUnqual(rowType)},
false
);
Function* func = Function::Create(
funcType, Function::ExternalLinkage,
"filter", module.get()
);
// 生成过滤逻辑
BasicBlock* entry = BasicBlock::Create(ctx, "entry", func);
builder.SetInsertPoint(entry);
Value* row = func->arg_begin();
Value* result = codegenSQLExpr(ast, row);
builder.CreateRet(result);
// 编译
return (FilterFunc)compileModule(func);
}
Value* codegenSQLExpr(SQLExpr* expr, Value* row) {
switch (expr->type) {
case SQLExpr::Compare: {
Value* field = loadField(row, expr->field);
Value* value = createConstant(expr->value);
return builder.CreateICmpSGT(field, value); // >
}
case SQLExpr::And: {
Value* left = codegenSQLExpr(expr->left, row);
Value* right = codegenSQLExpr(expr->right, row);
return builder.CreateAnd(left, right);
}
case SQLExpr::Or: {
Value* left = codegenSQLExpr(expr->left, row);
Value* right = codegenSQLExpr(expr->right, row);
return builder.CreateOr(left, right);
}
}
return nullptr;
}
};
6.7 性能优化技术
6.7.1 LLVM 优化 Pass
// 常用 LLVM 优化 Pass
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Vectorize.h"
#include "llvm/Transforms/IPO.h"
// 内联优化
FPM.addPass(InlinePass());
// 循环优化
FPM.addPass(LoopRotatePass()); // 循环旋转
FPM.addPass(LoopStrengthReducePass()); // 循环强度削减
FPM.addPass(IndVarSimplifyPass()); // 归纳变量简化
// 向量化
FPM.addPass(SLPVectorizerPass()); // SLP 向量化
FPM.addPass(LoopVectorizePass()); // 循环向量化
// 窥孔优化
FPM.addPass(PeepholePass()); // 窥孔优化
FPM.addPass(DivRemPairsPass()); // 除法/取余对优化
6.7.2 自定义优化 Pass
// 自定义优化 Pass 示例
struct MyCustomPass : public PassInfoMixin<MyCustomPass> {
PreservedAnalyses run(Function& F, FunctionAnalysisManager& AM) {
bool changed = false;
for (auto& BB : F) {
for (auto& I : BB) {
// 检测特定模式并优化
if (auto* mul = dyn_cast<BinaryOperator>(&I)) {
if (mul->getOpcode() == Instruction::Mul) {
// 优化乘以 2 为左移
if (isPowerOf2(getConstantValue(mul->getOperand(1)))) {
IRBuilder<> builder(mul);
int shift = log2(getConstantValue(mul->getOperand(1)));
Value* shifted = builder.CreateShl(
mul->getOperand(0),
ConstantInt::get(builder.getInt32Ty(), shift)
);
mul->replaceAllUsesWith(shifted);
changed = true;
}
}
}
}
}
return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
};
// 注册到管线
FPM.addPass(MyCustomPass());
6.8 适用场景
6.8.1 LLVM JIT 的最佳场景
┌─────────────────────────────────────────────────────────────────┐
│ LLVM JIT 最佳应用场景 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 自定义编程语言 │
│ └─ 构建新的编程语言编译器 │
│ │
│ 2. DSL 编译器 │
│ └─ 数学 DSL、SQL DSL、配置 DSL │
│ │
│ 3. 科学计算 │
│ └─ 数值计算、矩阵运算、物理模拟 │
│ │
│ 4. 代码生成工具 │
│ └─ 模板引擎、ORM 查询生成 │
│ │
│ 5. 硬件仿真 │
│ └─ CPU 仿真、GPU 计算 │
│ │
│ 6. 数据库查询 │
│ └─ 查询计划编译、表达式求值 │
│ │
└─────────────────────────────────────────────────────────────────┘
6.8.2 数据库查询编译示例
// ClickHouse 风格的查询编译
// 将 SQL 查询编译为高效的机器码
// 原始 SQL:
// SELECT count(*), avg(price) FROM orders
// WHERE status = 'completed' AND date > '2024-01-01'
// GROUP BY category
// 编译为机器码函数
void* compileQuery(const Query& query) {
// 1. 解析查询计划
auto plan = analyzeQuery(query);
// 2. 生成 LLVM IR
auto func = generateIR(plan);
// 3. 应用优化
optimizeFunction(func);
// 4. JIT 编译
return jit.compile(func);
}
6.9 本章小结
关键要点
- LLVM 提供完整的编译基础设施:从前端到后端的完整工具链
- MCJIT 是稳定的 JIT 引擎:适合整模块编译
- ORC JIT 是下一代框架:支持延迟编译和代码更新
- 非常适合构建自定义编译器:DSL、领域特定语言
- 强大的优化能力:数十种优化 Pass 可组合使用
选择建议
- 构建新语言编译器 → LLVM ORC JIT
- 简单的表达式编译 → LLVM IR API
- 数据库查询优化 → 查询编译
- 科学计算 DSL → LLVM + 自定义前端
6.10 扩展阅读
上一章: 第5章 - GraalVM 下一章: 第7章 - Java HotSpot