CodeGen IR LLVM

CodeGen生成IR代码

将语法树翻译成LLVM IR中间代码,作为LLVM Backend输入的桥接语言。方便LLVM Backend可以做到与语言无关的优化

这个过程还会与runtime进行桥接

  • 各种类、方法、成员变量等的结构体的生成,将其放到对应的Mach-O的Section中
  • Non-Fragile ABI合成OBJC_IVAR_$_偏移值常量
  • ObjCMessageExpr(AST树结构)翻译生成相应版本的objc_msgSend、super翻译生成objc_msgSendSuper
  • strong、weak、copy、atomic、nonatomic、readwrite等合成@property自动实现setter和getter
  • @synthesize 的处理
  • 生成block_layout数据结构(即block对应的结构体)
  • block和weak处理
  • _block_invoke
  • ARC的处理,即插入objc_storeStrong和objc_storeWeak等ARC代码;ObjCAutoreleasePoolStmt 转 objc_autorealeasePoolPush / Pop;自动添加 [super dealloc];给每个 ivar 的类合成 .cxx_destructor 方法自动释放类的成员变量

不管编译的语言时 Objective-C 还是 Swift 也不管对应机器是什么,亦或是即时编译,LLVM 里唯一不变的是中间语言 LLVM IR

LLVM IR

LLVM IR有三种表示格式,第一种是bitcode这样的存储格式,以.bc做后缀;第二种是可读的.ll;第三种是用于开发是操作LLVM IR的内存格式

一个编译单元即一个文件在IR里就是一个Module,Module里有Global variableFunction,在Function里有Basic BlockBasic Block里有指令Instructions
这样的话,如果想要开发一门新的语言只需要完成语法解析后,通过LLVM提供的丰富接口在内存中生成IR就可以直接运行在各个不同的平台

LLVM IR的优化

选择不同的O2、O3这样的优化回调用对应的Pass进行处理,比如死代码清理、内联化、表达式重组、循环变量移动等这样的Pass,可以通过命令llvm -opt调用LLVM优化相关的库

SSA

LLVM IR是SSA形式的,维护双向def-use信息,user-def是通过普通指针实现信息维护,def-user通过内存跳表和链表来实现,便于forward dataflow analysis和backward dataflow analysis。

llc 编译器是专门编译 LLVM IR 的编译器用来生成汇编文件。