10.3 基本块与控制流图
基本块是一段直线指令:单一入口、单一出口,控制从顶部进、底部出,绝不从中间跳进跳出。
这样分组后,编译器可以把一个块当作一个整体推理,再去推理块与块如何相连。
正在加载交互实验...
正在加载概念检查...
正在加载本节练习...
找出首指令
块在首指令(leader)处切分。首指令包括:首条指令、任何跳转目标、紧跟在跳转之后的指令。从一个首指令到下一个之间就是一个块。
这条规则机械且完备:照做即可把程序无重叠地切成基本块。
控制流图
把块连成边就得到控制流图(CFG)。顺序代码一条后继,条件分支两条后继,循环再补一条回边。
CFG 是下游几乎一切的底座:支配、循环、活跃性、SSA 都要读它。
正在加载交互实验...
正在加载概念检查...
正在加载本节练习...
出度即结构
以条件结尾的块出度为 2,以跳转结尾的为 1,return 为 0。只看边数,分支与汇合结构已经一目了然。
前驱、后继与汇合
每条边有两端,于是每个块有后继集合与前驱集合。前驱≥2 的块就是汇合点,而汇合处数据流最有戏:来自不同路径的值要被调和。这正是 SSA 稍后插入 phi 的地方。
入口、出口与可达性
良构 CFG 有单一入口、概念上单一出口。不可从入口到达的块就是死块,发现即删。一个便宜的首轮优化就是:建 CFG、标记可达、删其余。
例子
沿用上一节的条件 TAC,leader 落在首行、L1、L2,切出四块:测试、else 臂、then 臂、汇合。边从测试到两臂、两臂到汇合,画出来就是标准菱形——能分析的最小有趣 CFG。
把这个菱形读熟:支配、循环、活跃性、SSA 都复用它。
正在加载概念检查...