軟體分析筆記2 IR
術語
IR = Intermediate Representation 程式碼的中間形式
AST = Abstract Semantic Tree 抽象語法樹
IR
上節講到的同態對映需要一個具體的載體,類比我們常常將n維線性空間同構到R^n上考慮,這裡就引入了IR
IR也是一種語言,可以作任意語言到IR的同態對映,靜態分析通常建立在IR的基礎上,也就是分析的實際上是IR
回顧編譯的流程:
source code - scanner - 詞法分析 regular expression |
tokens - parser - 語法分析 context free grammar |
AST - type check- 語義分析 attribute grammar |
D-AST - translate - 轉換 |
IR - optimize - 優化 |
IR - code gen - 生成機器碼 |
SA通常在出現IR的環節發揮作用,也即是前後端之間
3AC是一種特殊的IR,它和彙編是非常像的
3AC vs. AST
AST的結構與語法高度相關,通常和語言高度相關,缺少控制流的資訊
3AC相反,且有簡潔和形式簡單的優點
java call
invokespecial: call constructor, superclass methods, private methods
invokevirtual: instance methods(virtual dispatch)
invokeinterface: same as virtual but cannot optimize and checks interface implementation()
invokestatic: call static methods
invokedynamic: JVM在若干版本之後支援各種語言,這東西讓dynamic language方便地在JVM上跑起來
一對尖括號<>內的內容叫做method的signature(簽名), 包含 class name, ret type, 方法名字(可選), param type
格式形如 InstanceName.<ClassName: ReturnType MethodName(Param1Type, ...)>(params, ...)
java constructor
init是動態的建構函式,clinit是靜態建構函式
具體的可能還要後面補,我儘量...
SSA
是一種特殊的3AC,滿足:
每個重複使用的變數都會有不同的名字(而不改變語義)
會有特殊的情況,比如說3AC
1: x = 3
2: if x < 5 goto 5:
3: y = 0
4: goto 6:
5: y = 1
6: z = y
可以發現,經過不同的分支得到的y的別名應該是不同的,即在控制流合併的地方會出現多個別名取其一的情況,這種時候引入\(\phi\)函式來選取
即
1: x1 = 3
2: if x1 < 5 goto 5:
3: y1 = 0
4: goto 6:
5: y2 = 1
6: y3 = phi(y1, y2)
7: z1 = y3
SSA的優勢
- 程式流的資訊可以從變數下標中抽取(即可以用變數定位程式碼位置),從而可以打亂3AC的順序而保持部分流的資訊(或許可以並行?)
- 變數的定義/使用成對,有利於某些任務
劣勢
- 會引入多餘的變數和phi函式
- 變數變多了,效能會受影響(感覺和1重了)
CFG
即control flow graph,是靜態分析的基本結構
圖的節點通常是若干語句(可以是單條)打包形成的blocks(basic blocks=BB)
BB
BB是極大的, 連續的, 滿足(這個block的入口只能在第一條)這一性質的 3AC指令的序列
定義比較好理解,我們用BB造出來一個圖G,再用所有的3AC造一個圖G',那麼G'就是G的一個圖的細分
根據定義很容易給出BB的一個尋找演算法,只需要注意到:
- 有非平凡出邊的點一定是某個block的bottom
- 有非平凡入邊的點一定是某個block的top
- 每個block的bottom一定緊接下一個block的top
就好了