实验 3 基于 LLVM 的 JIT 实现

在本实验中,我们观察、学习、理解并使用 LLVM 的 OrcJIT 架构,了解分层模块化的 JIT 实现模式,从而对 JIT 的实现方式和处理方法有一个大致的概念。学习和理解过程中,将主要以阅读代码的形式进行;使用中,将基于 OrcJIT,修改上一次实验的代码,使其具备 Lazy Compilation 和可控程度精细到 Pass 的代码优化。

这里我们的 JIT 仅包括从 LLVM IR 到可执行程序的 Just-In-Time Compilation,并不包括 AST 的解析;这和 JVM(Java Virtual Machine)、CLR(Common Language Runtime)的模式是相同的。

LLVM OrcJIT

在较新版本的 LLVM 中,OrcJIT(On-Request-Compilation JIT)作为 MCJIT 的功能扩展被引入,成为推荐使用的 JIT Engine。

OrcJIT 基于分层(Layer)化的结构,每层执行一定的任务,通过多个层的分工协作来完成整体的 JIT 任务。整体结构和每一层的行为均由用户配置。

使用的例子可以参考 Kaleidoscope 的 JIT 部分 Tutorial,由于其文档尚未完成,需要同学们直接参考其源码,阅读并理解其行为。这部分代码当中包含了相当丰富的注释,将有助于你的理解。这些源代码在你本地的 LLVM 仓库副本中也存在,推荐使用代码编辑器进行阅读。好事(没什么不对)的同学也可以去看一看施工中的 Tutorial 本体,由于完成度太低,所以如果要参考其内容,需要同学们自行斟酌。

其中 JIT Engine 的实现主要位于ChapterN/KaleidoscopeJIT.h,建议按章节顺序逐个浏览,渐次加深理解。其中的注释十分详细,将大大有助于你的代码阅读。Chapter4Chapter5的内容脱离了本次实验的要求范围,可以忽略。

除此之外,JIT 的一个常见功能是通过在线的 Profiling(即性能统计),分析出热点代码,并对其进行深度优化。这一功能在当前的 LLVM 中尚不具备,但由于 OrcJIT 的存在,这一功能的实现是可能的。你可以思考如何在 OrcJIT 的架构下,通过新 Layer 的实现和组织,完成基于 Hot Profiling 的在线优化;如果有自己的想法,请进行描述。不强制要求回答。

基于 OrcJIT 的 C1 JIT Engine 实现

本次实验将在先前直接使用 MCJIT 的 c1interpreter 基础上修改,基于 OrcJIT 完成其 JIT Engine 的实现,替代先前的简单的 MCJIT 的调用。

基础版本已经在本次实验的仓库中给出。其中的src/execution_engine.cpp中包含了初始的实现,可以看到,这份实现是仿照 Kaleidoscope JIT Tutorial 中的Chapter1/KaleidoscopeJIT.h进行的。你的工作是在其上进行改进,在其中加入优化功能的 Layer,并使其具备 Lazy Compilation 特性。你可以仿照 Kaleidoscope JIT Tutorial 中的Chapter3/KaleidoscopeJIT.h完成这些功能改进。

提交内容

  1. 分阶段阅读 Tutorial,回答以下问题,将回答置于<your-repo>/lab-3-answer.md中:
    1. 阅读Chapter1/KaleidoscopeJIT.h,回答问题:
      1. CompileLayerObjectLayer的功能分别是什么?
      2. 在这个文件中,为什么只调用了CompileLayer的方法,而从未接触ObjectLayer
      3. 在这个文件中,由哪一方法完成了 LLVM IR 到内存中可执行二进制的 JIT 编译?
    2. 阅读Chapter2/KaleidoscopeJIT.h,回答问题:
      1. 这一实现较上一实现增加了什么功能?是由哪一 layer 完成的新增功能?
      2. OptimizeLayerCompileLayerObjectLayer间是如何组织和交互的?
      3. llvm::orc::IRTransformLayer不止可以执行优化工作,还可以实现运行期间每个函数调用的次数和时间统计。思考并简要说明方法。
      4. 列出OptimizeLayer所执行的优化种类。
    3. 阅读Chapter3/KaleidoscopeJIT.h,回答问题:
      1. 这一实现较上一实现增加了什么功能?是由哪一 layer 完成的新增功能?
      2. 本次的四个 layer 间是如何组织的?
      3. (可选)CODLayer是如何达成其功能的?(简单介绍函数被初次调用的流程即可)
  2. (可选)OrcJIT 的可扩展性很好。思考如何在 OrcJIT 的架构下,通过新 Layer 的实现和组织,完成基于 Hot Profiling 的在线优化,简单描述思路,不需要陈述具体细节。将你的思考也置于<your-repo>/lab-3-answer.md中。
  3. 完成c1interpreter_jit
    1. 将公共仓库中的c1interpreter_jit复制进你的仓库,并将你在 lab 2 中实现的c1interpreter/src/assembly_builder.cpp替换至其中对应文件。编译并执行项目。
    2. 测试并改进c1interpreter_jit/src/execution_engine.*
      1. 在其中加入优化功能的 Layer;你可以选择比 KaleidoscopeJIT 更多的 optmization pass 加入其中,但请保证这些优化的时间复杂度较低(低于平方级),JIT 时通常不会接受高时间复杂度的优化。
      2. 使其具备 Lazy Compilation(即Compile On Demand)特性。
    3. c1interpreter_jit/doc/jit.md中描述你的工作;如果你的 optimization pass 较 KaleidoscopeJIT 中有区别,请对新加入的 pass 简单说明其功能。

results matching ""

    No results matching ""