创建时间:2021年7月23日16点08分
什么是IR
程序语言的中间表达形式,去除了如注释等无关程序运行的部分,提供了一个通用的分析对象。
编译器和静态分析器
AST和IR
AST:
- 高层,接近语法结构
- 通常依赖于编程语言
- 适合快速的类型检查
- 缺少控制流信息
IR:
- 底层,接近机器码
- 通常语言无关
- 简洁且统一
- 包含控制流信息
- 常常被认为是静态分析的基础
IR三地址码
右侧结构内最多只能有一个操作符
3AC: 包含最多三个地址
地址有以下三种情况:
- 名称:a, b
- 常量:3
- 编译器生成临时变量:t1, t2
一些常见的三地址码形式:
- x = y bop z
- x = uop y
- x = y
- goto L
- if x goto L
- if x rop y goto L
x, y, z:地址
bop:二元运算符或者逻辑操作
uop:一元运算符,取负,取反,转换等
L:程序位置标记
rop:关系运算符 (<, >, ==, >=, <=等)
goto L:无条件跳转
if … goto L: 条件跳转
Soot中的三地址码
TODO:soot教程
invokespecial:调用构造器,超类方法,私有方法
invokevirtual:实例方法调用(虚拟派发)
invokeinterface:不能优化,检测接口实现
invokedynamic:
SSA
- SSA中所有参数都是有单独姓名的变量
- 给每个定义一个新的名字
- 对后续使用分配一个新名字
- 每个变量都只有一个定义
控制流合并的变量使用会用phi函数计算合并几个单独变量
为什么用SSA:
- 流信息可以间接融入独一无二的变量名中,即变量名其实说明了执行顺序
- 定义-使用的配对更明确
为什么不用SSA:
- 会引入太多变量和phi函数
- 翻译到字节码的时候会导致低效问题
基本块(BB)
BB是满足下列性质最大的三地址指令序列:
- 入口在第一个指令
- 出口在最后一个指令
通过这个方法判断是否能加进来
INPUT: 程序P的一系列三地址码指令
OUTPUT: P的基本块列表
METHOD:
- 决定P中的领导者
- P的第一条指令是一个领导者
- 条件或无条件跳转的目标指令是一个领导者
- 任何跟在跳转指令后面的指令是一个领导者
- 构建P的基本快
- 基本块包含领导者和到下一个领导者之间的代码
控制流图(CFG)
- 控制流分析通常指构建控制流图
- CFG作为静态分析的基本结构
- CFG的节点是单独的三地址指令,或者是一个基本块