静态程序分析chapter5 - 常量传播分析上(Costant Propagation Analysis)
四、
數據流分析之常量傳播(Constant Propagation)
概述
??????Constant Propagation:Given a variable x at program point p, determine whether x is guaranteed to hold a constant value at p. 比如在 p 處之前的一條語句是 x = 2,那就認為在 p 處 x 是一個常量值。反過來若在 p 處之前的一條語句為 x = y,那在 p 處 x 是否為一個常量值不能確定。
??????要判斷在每一個程序點處變量是否為一個常量值,按照之前的分析框架能夠一步步得到:首先,應該采用位向量對所有變量是否為常量值進行抽象,應該采用前向分析,應該采用 must analysis(從 guaranteed 能夠看出,這是一個 1 op 0 = 0 的故事),并且迭代算法在邊界處的初始值應該為 ⊥。其次,除邊界處外別的語句的初始值應為 T ,控制流處理應該采用 與操作。最后,轉換函數的分析也可以采用前面的 Gen/Kill 框架,至此分析結束。
??????上述分析流程具體可見博客:https://blog.csdn.net/Little_ant_/article/details/118732952
??????但是這個問題又有點不太一樣,它會稍微復雜一點。比如在兩條路徑匯聚的情況下,一條路徑上 x = 1,另一條路徑上 x = 2,因為1和2不相等,所以在匯聚點處 x 不是一個常量值。這需要分情況來討論。
??????學習了格理論之后,數據流分析框架常被描述為下面這樣:
??????上圖和之前講的數據流分析步驟都能對應上,只不過是更加專業點而已。
用途
??????為了用常量值替換掉變量來優化程序。對于簡單的程序如下:
int a = 2 ; int b; b = a + 4; printf("%d\n",b);??????在編譯時采用常量傳播優化之后:
printf("%d\n",6);D
??????從 CPA 的語義上可以得出應該采用前向分析。
L
抽象
??????在這里不采用位向量對變量是否為常量值進行抽象,因為當變量為一個常量值的話,為了用常量值替換掉變量來優化程序,需要存儲每一個變量的常量值。因此令 CFG 中每一個節點的 OUT 中包含一系列的元素對(x ,v),其中 x 為變量,v 為 x 的值。這里和之前抽象不一樣的地方在于從位向量變為元素對向量。
??????而每一個變量的值現在有三種情況:未初始化(UNDEF)、常量(c)和非常量(NAC)。其中 NAC 作為 ⊥,UNDEF 作為 T。對于 must analysis 而言,初始化每一個 OUT 為 T,即將每一個元素對中變量的值都置為 UNDEF,此時是不安全的或者說是不正確的。而當每一個元素對中變量的值都為 NAC時,對于 CPA 來說就不會做優化了,因此也不會出錯了,這是一個正確但是無用的結果。這對應于數據流分析的特點 unsafe → safe。
控制流處理
??????之前抽象的結果只有兩種情況 0 和 1,所以在控制流處理時 meet 采用 與 操作。現在抽象的結果有三種情況,所以控制流處理時 meet 操作需要分類討論:
??????NAC ? v = NAC;非常量和其他任意值 meet 的結果為非常量。
??????UNDEF ? v = v;從邏輯上來看,一條路徑為 UNDEF,另一條路徑為 v,在匯聚點處取二者之間的哪一個都不太好,但是因為 UNDEF 不在常量傳播的分析范圍之內,所以 meet 之后的結果為 v 。從操作符本身來看,? 表示取最大下界,而 UNDEF 和 v 的最大下界為 v。
?????? c ? v 的結果需要討論變量 v 的值,若 v 的值和 c 相等,則 c ? v = c。若 v 的值和 c 不相等,則 c ? v = NAC。
F
?????? 轉換函數仍然通過對于一個語句的分析,得到一般性的結論。比如對于一個語句 s:x = … ,它的轉換函數需要 kill 掉原來的元素對中 x 對應的值,然后根據具體的語句來執行 gen 給 x 生成一個新的值,這樣就得到了 OUT[s]。
??????轉換函數 F 表示為:OUT[s] = gen ∪ (IN[s] – {(x, _)})
?????? 令元素對中 x 對應的值用 val(x) 來表示,對語句 s 分類討論:
??????1,s: x = c; //c為常量??????那么生成新的元素對 gen = { (x,c) }
??????2,s: x = y; ??????那么生成新的元素對 gen = { (x, val(y)) }
??????3,s: x = y op z; ??????那么生成新的元素對 gen = { (x, f(y,z)) }
??????其中 f(y,z) 的結果:在當 val(y) 和 val(z) 都是常量時,f(y,z) = val(y) op val(z)。
????????????????????????????????????在當 val(y) 或 val(z) 是非常量 (NAC) 時,f(y,z) = NAC。
????????????????????????????????????在當 val(y) 和 val(z) 一個為常量,另一個為 UNDEF 時,或者兩個都是 UNDEF時,f(y,z) = UNDEF。這里指的是常量和一個未定義的變量執行某種操作,其結果自然是未定義。據說:如果令一個常量和 UNDEF 操作的結果為常量,那么轉換函數 F 就不再是單調的啦。
??????如果語句 s 不是一個賦值語句,那么 OUT[s] = IN[s] 。
常量傳播不是可分配的
??????不是可分配的意味著迭代算法的精度沒有 MOP 高。在下圖中,迭代算法得到的結果為 NAC ,MOP 得到的結果為常量 10,參照 must analysis 的那張圖片,可得,MOP 的精度要更高一些。
總結
??????示例和算法實現,以及Java代碼測試見下一篇博客-常量傳播分析下(用soot實現)。未完待續~
總結
以上是生活随笔為你收集整理的静态程序分析chapter5 - 常量传播分析上(Costant Propagation Analysis)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 静态程序分析chapter4 - 基于格
- 下一篇: 目标文件(.o)结构的简单了解