2.构建JIT:添加优化 - ORC层介绍
- 使用IRTransformLayer优化模块
- 完整的代码清单
2.1。第2章介绍
在“使用LLVM实现语言”教程系列的第4章中,使用llvm FunctionPassManager作为优化LLVM IR的手段而引入。感兴趣的读者可以阅读该章节以获取详细信息,但简而言之:为了优化模块,我们创建了一个llvm :: FunctionPassManager实例,使用一组优化对其进行配置,然后在模块上运行PassManager以将其变为(希望)更多优化但语义上等效的形式。在原始教程系列中,FunctionPassManager是在KaleidoscopeJIT之外创建的,模块在添加到模块之前已经过优化。在本章中,我们将优化作为JIT的一个阶段。现在,这将为我们提供更多了解ORC层的动力,但从长远来看,优化JIT的一部分将产生一个重要的好处:当我们开始懒洋洋地编译代码时(即推迟编译每个函数直到它第一次编译)跑),
要为我们的JIT添加优化支持,我们将从第1章开始使用KaleidoscopeJIT并在顶部构建 ORC IRTransformLayer。我们将在下面详细介绍IRTransformLayer的工作方式,但界面很简单:该层的构造函数引用下面的层(如同所有层一样)以及它将应用于每个模块的IR优化函数通过addModule添加:
接下来,我们需要在关键方法中使用对OptimizeLayer的引用替换对’CompileLayer’的引用:addModule,findSymbol和removeModule。在addModule中,我们需要小心替换两个引用:我们的解析器中的findSymbol调用,以及对addModule的调用。
这是IRTransformLayer的整个定义,从中 llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h删除了它的注释。它是一个模板类有两个模板参数:BaesLayerT和 TransformFtor提供基础层的分别的类型和“变换函子”(在我们的情况下,一个std ::功能)的类型。这个类涉及两个非常简单的工作:(1)运行通过变换仿函数添加addModule的每个IR模块,以及(2)符合ORC层接口。该接口由一个typedef和五个方法组成:
2.3 完整的代码清单
以下是我们运行示例的完整代码清单,其中添加了IRTransformLayer以启用优化。要构建此示例,请使用:
- [1] 当我们将顶层表达式添加到JIT时,对我们之前定义的函数的任何调用都将作为外部符号出现在RTDyldObjectLinkingLayer中。RTDyldObjectLinkingLayer将调用我们在addModule中定义的SymbolResolver,后者又调用OptimizeLayer上的findSymbol,此时甚至一个惰性变换层也必须完成它的工作。