ORC JIT是LLVM面向编译器作者的可组合底层JIT构建块,用于将已生成的IR模块动态编译为机器码并执行;核心流程为:创建ExecutionSession→配置IRTransformLayer和ObjectLinkingLayer→添加模块→解析符号获取函数指针。

理解 ORC JIT 的核心定位
ORC(On-Resident Compilation)是 LLVM 提供的现代 JIT 框架,取代了旧版 MCJIT。它不是“一键运行字符串代码”的工具,而是面向编译器作者设计的、可组合、可扩展的底层 JIT 构建块。你用它来把 已生成的 IR 模块(Module) 动态编译成机器码并执行,不是直接喂 C++ 源码。
基础流程:从 Module 到可调用函数
典型路径分四步:构造 ExecutionSession → 设置 ORC Layer(IRTransformLayer + ObjectLinkingLayer)→ 添加模块 → 解析符号获取函数指针。
- 用
ExecutionSession管理 JIT 内存、符号表和资源生命周期 - 用
IRTransformLayer注入优化(如createFunctionPassManagerForModule),再接ObjectLinkingLayer完成链接 - 调用
addIRModule注入std::unique_ptr<module></module>,ORC 自动编译、重定位、注册符号 - 用
lookup("func_name")得到JITSymbol,再调用getAddress()转为函数指针(注意类型强转)
关键细节:内存管理与符号可见性
ORC 默认使用 jitdylib 隔离符号空间。主 JIT dylib(如 es.createBareJITDylib("main"))需显式添加依赖才能看到外部符号(比如 printf)。
- 对外部 C 函数,先用
absoluteSymbols注册地址,再通过auto &mainJD = es.createBareJITDylib("main"); mainJD.addGenerator(...)让 JIT 能解析它们 - 避免多次
addIRModule引发重复定义错误:每个 Module 的全局符号名必须唯一,或启用setAutoClaimResponsibilityForObjectSymbols(true) - 释放资源时,调用
removeModule或直接销毁 JITDylib —— ORC 会自动回收对应内存页(通过SectionMemoryManager)
实用示例:编译一个加法函数并调用
假设你已有 LLVM IR 描述的 int add(int a, int b) { return a + b; }(可用 parseIRFile 或手动生成):
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~