编译原理之美
宫文学
北京原点代码 CEO
46197 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
编译原理 · 期中考试周 (1讲)
编译原理之美
15
15
1.0x
00:00/00:00
登录|注册

26 | 生成IR:实现静态编译的语言

一课一思
课程小结
编译并运行程序
支持本地变量
支持if语句
尝试生成LLVM IR
LLVM IR的对象模型
生成IR:实现静态编译的语言

该思维导图由 AI 生成,仅供参考

目前来讲,你已经初步了解了 LLVM 和它的 IR,也能够使用它的命令行工具。不过,我们还是要通过程序生成 LLVM 的 IR,这样才能复用 LLVM 的功能,从而实现一门完整的语言。
不过,如果我们要像前面生成汇编语言那样,通过字符串拼接来生成 LLVM 的 IR,除了要了解 LLVM IR 的很多细节之外,代码一定比较啰嗦和复杂,因为字符串拼接不是结构化的方法,所以,最好用一个定义良好的数据结构来表示 IR。
好在 LLVM 项目已经帮我们考虑到了这一点,它提供了代表 LLVM IR 的一组对象模型,我们只要生成这些对象,就相当于生成了 IR,这个难度就低多了。而且,LLVM 还提供了一个工具类,IRBuilder,我们可以利用它,进一步提升创建 LLVM IR 的对象模型的效率,让生成 IR 的过程变得更加简单!
接下来,就让我们先来了解 LLVM IR 的对象模型。

LLVM IR 的对象模型

LLVM 在内部有用 C++ 实现的对象模型,能够完整表示 LLVM IR,当我们把字节码读入内存时,LLVM 就会在内存中构建出这个模型。只有基于这个对象模型,我们才可以做进一步的工作,包括代码优化,实现即时编译和运行,以及静态编译生成目标文件。所以说,这个对象模型是 LLVM 运行时的核心。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文详细介绍了如何使用LLVM API生成IR,并验证生成的IR的正确性。文章首先介绍了LLVM IR的对象模型,包括Module、Function、BasicBlock、Instruction和Value等类,以及LLVMContext类。通过示例代码演示了如何为一个包含if语句的函数生成IR,包括创建基本块、条件跳转指令和phi指令等步骤。另外,文章还展示了如何支持本地变量,并说明了LLVM IR对寄存器和内存中变量的赋值规则。通过这些示例,读者可以学习如何生成基本的IR,包括支持本地变量、加法运算和if语句等。最后,文章提到了通过优化算法可以将使用内存保存临时变量的版本优化成使用寄存器的版本。文章内容清晰,逻辑严谨,对于想要深入了解LLVM IR的读者来说,是一份有价值的技术指南。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • ZYS
    宫老师考虑把课程整理成一本书出版那,很好的内容

    作者回复: 嗯,已经在准备中~~~ 我们的教程,限于篇幅,很多细节还是不会延伸太多。写成书的话,就可以讲得更充分。

    2020-01-28
    9
  • 渔子长
    请教一个问题宫老师,LLVM的Module,设计是什么粒度的?比如一堆脚本可能拆分了几百个文件,把这些文件编译成IR,是每个文件对应一个Module?还是整体只构建一个Module?

    作者回复: 如果对应于C或C++语言,一个Module就相当于一个目标文件,里面有一些函数式对外公开的,另一些是私有的,然后多个Module可以链接到一起。 所以,基本上是一个文件对应一个Module。

    2019-12-11
    2
    6
  • xiaobang
    请教一下老师,为什么if语句要生成merge块,明明then和else里已经return了?难道llvm只允许一个函数一个return

    作者回复: 不是的,可以有多个return。 不过,一般CFG会要求有两个特殊的块:入口块(Entry Block)和退出块(Exit Block)。这样的话,CFG就是一个有根的图(Rooted Directed Graph),便于执行某些分析和优化算法。如果要深入研究,可以去看看图的算法。 在LLVM中,有一个优化算法可以把多个return语句合并,这样就只有一个Exit Block了。

    2019-11-12
    5
  • 沉淀的梦想
    老师用的什么版本的llvm,我使用llvm 7.0编译老师lab-26的代码,发现LegacyRTDyldObjectLinkingLayer和AcknowledgeORCv1Deprecation都已经不存在了,但是网上搜了一下,也没找到什么可以替代的东西

    作者回复: 用llvm 9.0吧。 并且最好下载源代码,自己编译。这样会按照debug模式编译,用opt等工具的时候,可以输出更多信息,有利于你做实验。

    2019-10-23
    2
    3
  • Geek_6c84aa
    使用默认选项编译安装llvm9时默认是没有开启rtti的。在编译本节代码时遇到undefined reference 'typeinfo'问题,需要在cmakelist中添加add_compile_options(-fno-rtti) 或者重新编译llvm(-DLLVM-ENABLE-RTTI)。希望对大家有帮助。

    作者回复: 感谢分享经验:-)

    2021-01-16
    1
  • coconut
    Python版本基于llvmlite库的实现。 https://github.com/leveryd/PlayWithCompiler/blob/master/llvm/1.%E5%88%9D%E8%AF%86llvm/test.py

    作者回复: Great! python + llvm。 感谢你分享了更丰富使用编译技术的场景!

    2021-01-04
    1
  • lion_fly
    如果是在linux下使用LLVM的JIT,在编译的时候需要注意如下问题: If you are compiling this on Linux, make sure to add the “-rdynamic” option as well. This makes sure that the external functions are resolved properly at runtime.

    作者回复: 感谢分享!

    2020-12-22
  • lion_fly
    declare void @foo(i32) Failure value returned from cantFail wrapped call Symbols not found: [ foo ] UNREACHABLE executed at /usr/lib/llvm-11/include/llvm/Support/Error.h:749!

    作者回复: llvm工具要用熟练,会遇到很多小坑。不过代价是值得的。

    2020-12-16
  • lion_fly
    在新版中llvm_map_components_to_libnames(llvm_libs all)已经过时,新版需要写成:set(llvm_libs LLVM-11)

    作者回复: 感谢分享!

    2020-12-14
  • overmind
    如何通过优化算法,把上述代码从使用内存的版本,优化成使用寄存器的版本。谢谢

    作者回复: 第29讲有介绍分配寄存器的算法。尽量多使用寄存器,实在寄存器放不下的,才“溢出”到内存。

    2019-12-21
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部