1. 程式人生 > 其它 >軟體分析筆記2 IR

軟體分析筆記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的優勢

  1. 程式流的資訊可以從變數下標中抽取(即可以用變數定位程式碼位置),從而可以打亂3AC的順序而保持部分流的資訊(或許可以並行?)
  2. 變數的定義/使用成對,有利於某些任務

劣勢

  1. 會引入多餘的變數和phi函式
  2. 變數變多了,效能會受影響(感覺和1重了)

CFG

即control flow graph,是靜態分析的基本結構
圖的節點通常是若干語句(可以是單條)打包形成的blocks(basic blocks=BB)

BB

BB是極大的, 連續的, 滿足(這個block的入口只能在第一條)這一性質的 3AC指令的序列
定義比較好理解,我們用BB造出來一個圖G,再用所有的3AC造一個圖G',那麼G'就是G的一個圖的細分

根據定義很容易給出BB的一個尋找演算法,只需要注意到:

  1. 有非平凡出邊的點一定是某個block的bottom
  2. 有非平凡入邊的點一定是某個block的top
  3. 每個block的bottom一定緊接下一個block的top
    就好了