5.1 資料流分析與優化#
從「能跑」到「跑得快」#
1957 年 FORTRAN I 已內建公共子表示式刪除與迴圈最佳化;1970 年代是最佳化理論的黃金期:Gary Kildall(1973,他的博士論文《A Unified Approach to Global Program Optimization》)提出以「格(lattice)」統一資料流分析的框架;Frances Allen(IBM)發展了區間分析與控制流分析,1970 年代其工作為她贏得 2006 年圖靈獎——首位女性得主;John Cocke(IBM, 1970)建立強度削減與暫存器最佳化的系統方法(圖靈獎 1987)。本章聚焦中端最佳化的兩大支柱:控制流圖與資料流分析。
控制流圖(CFG)#
最佳化在 CFG 上進行:節點是基本塊(basic block,單進單出的線性指令序列),邊是可能的跳轉。
flowchart TD
B0[B0: 入口] --> B1
B1[B1: 迴圈頭] -->|true| B2[B2: 迴圈體]
B1 -->|false| B4[B4: 出口]
B2 --> B3[B3: 迴圈閘]
B3 -->|回頭| B1
B3 -->|break| B4支配關係:A 支配 B(所有路徑必經 A)。自然迴圈:回邊 \(B_3 \to B_1\) 中 \(B_1\) 支配 \(B_3\) ,迴圈體為 \(B_1, B_2, B_3\) 。迴圈是最佳化的主戰場——程式 90% 的時間常在 10% 的碼裡。
資料流分析的格理論框架#
對每個程式點,求一組「事實」(如「變數 x 此刻是常數 3」)。抽象為:
- 格 \((L, \sqsubseteq, \sqcap, \sqcup, \top, \bot)\) :事實的偏序集合。
- 轉移函數 \(f: L \to L\) :沿指令邊傳遞事實。
- 匯合運算:控制流匯合處取 meet( \(\sqcap\) 或 \(\sqcup\) ,依分析方向而定)。
- 不動點:解聯立方程組 \(x = F(x)\) 。
Kildall 的迭代不動點演算法:
worklist 演算法:
初始化每個節點的 in/out 為 ⊤ 或 ⊥
將所有節點放入 worklist
while worklist 非空:
取出 n
new_in = meet(over preds of n)
new_out = f_n(new_in)
if new_out ≠ out[n]:
out[n] = new_out
將 n 的後繼加入 worklist
格的高度決定迭代次數上限(單調函數保證收斂);有限高度 ⇒ 終止。
四大經典資料流分析#
| 分析 | 方向 | 匯合 | 事實域 | 用途 |
|---|---|---|---|---|
| 到達定義 | 前向 | 併集 | 定義集合 | use-def 鏈、常數傳播 |
| 可用運算式 | 前向 | 交集 | 運算式集合 | 公共子表示式、迴圈不變量外提 |
| 活躍變數 | 後向 | 併集 | 變數集合 | 死碼刪除、暫存器配置 |
| 非常繁忙運算式 | 後向 | 交集 | 運算式集合 | 運算式提前求值 |
到達定義(reaching definitions):定義 \(d: x = \ldots\) 可到達點 p,若存在路徑無其他 \(x\) 定義覆蓋。用位元向量(每定義一位元)+併集匯合,迭代至不動點。
活躍變數(live variables):變數 v 在點 p 活躍,若從 p 出發存在路徑在重新定義前使用 v。後向分析:
依賴活躍/到達資訊的經典變換#
- 死碼刪除(DCE):定義的結果不活躍 ⇒ 刪除(迭代直到不動點)。
- 常數傳播:稀疏條件常數傳播(SCCP, Wegman & Zadeck, 1991)在 SSA 上追蹤每個值的 ⊥(未知)/常數/⊤(非常數) 三態格。
- 公共子表示式刪除(CSE):在匯合點若某運算式「處處可用」,可用同一臨時值。
- 迴圈不變量外提(LICM):運算式在迴圈內各定義點皆不變 ⇒ 移到迴圈前。需迴圈閉合 SSA(LCSSA)確保正確。
- 強度削減:
i*4→t += 4(Cocke 與 Kennedy 的歸納變數分析,1970s)。
安全性與效益性:變換必須「不改變可觀察行為」(安全),且「平均而言更快」(效益)。LICM 外提可能造成除以零提前觸發——涉及例外/浮點語意時要格外小心。
更進階的框架#
- SSA 稀疏分析:def-use 鏈使資料流沿「值」而非「全域位元向量」傳播,複雜度近線性。
- 條件常數傳播+稀疏條件:可利用分支條件沿特定邊傳遞事實(如
if (x==5) { ... }內 x 是 5)。 - 別名分析(alias analysis):判斷兩指標是否指向同一位址;Steensgaard(1996)近乎線性、Andersen(1994)更精確但 \(O(n^3)\) 。C 的 union、type punning 使其近似不可解。
- 過程間分析(IPA):跨函式內聯、全程序分析;LLVM 的 ThinLTO(2016)以平行+摘要實現規模化。
小結#
- Kildall(1973)以格與不動點統一資料流分析;Allen 與 Cocke 建立迴圈與強度削減理論。
- 到達定義、活躍變數、可用運算式是三大工作馬;SSA 讓分析稀疏化。
- 安全性先於效益性:一切最佳化以不破壞語意為前提。