LLVM学习笔记——目录(含7.0更新)

前言

2011年前后,GCC后端代码的阅读陷入了举步维艰的境地。GGC-3.4.6后端代码的可读性不友好(当前版本没看过,不予评价。不过据说4.0进行的重构,应该会好些),充斥着动辄数千行的函数,包含着庞大的switch块以及if块,加之函数间的相互调用,看得人昏头转向。

穷极思变,转而看了一下LLVM的源代码。一撇之下,惊为天人。

LLVM是第一次碰到的、几乎完全用C++开发的大规模开源项目。LLVM将C++的潜力发挥得淋漓尽致,相较于直接使用指针,LLVM通过泛型技术构建了大量的容器与迭代器来遍历各种数据结构,使代码的安全性与模块化都得到很大的提高。

通过良好的模块化设计,善用C++提供的抽象支持,LLVM功能模块间实现了松耦合,替换模块或者增加模块就能扩展功能,无需在框架上修改。这一点使LLVM成为了学术界的宠儿。因为与GCC相比,LLVM不要求改写者深入了解各个部分,只需了解接口即可,而GCC则要求改写者对整个GCC代码有相当程度的精通。曾有团队先后使用LLVM与GCC为一款DSP(tricore)开发编译器,结果发现LLVM所需的工作量与难度都远小于GCC。从这点来说,LLVM非常成功。

此外,LLVM的指令生成技术十分先进。它使用一种称为tlbgen的语言来描述目标机器的方方面面(该语言的许多语法成分被LLVM的发明人ChrisLatter借鉴到新发明的Swift语言里),然后在编译LLVM的过程里,通过工具解析生成C++的源代码。

这个过程相当复杂,不过随之而来的是,LLVM有许多代码可以自动生成。而且现有的描述架构可以方便地支持新的处理器。不过,对tblgen语言以及解析工具,LLVM文档并没有深入描述。这也正是我的兴趣所在。

因为集成了大量的算法以及数据结构,编译器从来都是最复杂的软件之一。无论LLVM还是GCC,它们的行数都是以千万计的。如何构建一个模块化、扩展性良好,考虑维护友好性的编译器,绝对是一个困难的任务。但很可惜,常见的编译原理的书重点都在编译器的理论,给出常见算法的概要、框架,以及编译器系统的一般性描述。从这一点来说,编译原理给出的连编译器蓝图都算不上,充其量只是一张比较详细的草图。从草图到活生生的例子、具体的代码,期间的差别,不可以道里计。

因此,看完编译原理,总觉得似懂非懂,好像知道一些,却又说不出所以然——很多细节、答案都藏在源代码里。但另一方面,看编译器源代码也容易陷入细节,只见树木而不见森林,而且代码量也确实很大。不过,不管怎么说,饭要一口口吃,路要一步步走,退一万步来说,LLVM的架构极其先进,如果能从其软件架构中学到些什么,也是有益的。

从今天起(2017-3-10),将不定期更新我学习LLVM的笔记(就我个人经验,阅读复杂的程序,做详细笔记总能事半功倍)。因为LLVM实在庞大,虽穷数年勤苦,就X86目标机器,尚有很大部分代码没有触及,希望慢慢能补齐。

另,原创不易,转载请注明出处。若有错漏,请留言或发邮至wuhui_gdnt@21cn.com,望不吝赐教。谢谢!

第一部分目录
 1. 概述(更新)
     1.1. DAG指令选择生成器
     1.2. SelectionDAG
     1.3. v7.0的变化

2. LLVM的后端描述更新
     2.1. 类型的描述
     2.2. 指令的描述
             2.2.1. TablgeGen的
                    2.2.1.1. dag
                    2.2.1.2. List
                    2.2.1.3. String
                    2.2.1.4. Bit、Int
                    2.2.1.5. Bits

             2.2.2. 参数描述更新
                    2.2.2.1. 寄存器
                          2.2.2.1.1. Register
                          2.2.2.2.1. X86的例子
                          2.2.2.3.1. RegisterClass
                          2.2.2.4.1. ARM的例子
                     2.2.2.2. 一般操作数更新
             2.2.3. 约束条件

             2.2.4. 匹配模板更新
                   2.2.4.1. SDNode
                          2.2.4.1.1. 类型的描述
                          2.2.4.1.2. 属性的描述
                          2.2.4.1.3. SDNode的派生定义

                   2.2.4.2. 可复用的结构更新
                          2.2.4.2.1. PatFrag
                                 2.2.4.2.1.1. SDNodeForm
                                 2.2.4.2.1.2. PatFrag的例子
                          2.2.4.2.2. 其他特殊PatFrag派生类
             2.2.5. 另一个匹配方式
                    2.2.5.1. 谓词Predicate
                    2.2.5.2. 指令定义的例子
                    2.2.5.3. 指令展开的例子

             2.2.6. 调度信息更新
             2.2.7. X86指令的定义
             2.2.8. 指令展开的例子

     2.3. 汇编处理描述更新
     2.4. 目标机器描述
            2.4.1. 特征描述
            2.4.2. 调度信息
                     2.4.2.1. ATOM的描述
                     2.4.2.2. Sandy Bridge的描述
                          2.4.2.2.1. 资源的描述
                          2.4.2.2.2. 执行的描述
                          2.4.2.2.3. Sandy Bridge的定义
                    2.4.2.3. 总结

3.

  • 20
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值