編譯原理之基本塊和流圖

基本塊和流圖

採用圖的方式表示中間代碼,有助於生成更好的代碼
ä構造方法
1.把中間代碼劃分成基本塊(basic blockBB),每個基本塊滿足如下條件:
控制流只能從基本塊的第一個指令進入
除了基本塊的最後一條指令,控制流在離開基本塊前不會停機或者跳轉
2.基本塊形成了流圖(flow graph)的結點,流圖的邊指明瞭哪些基本塊可能緊隨一個基本塊之後執行
ä中斷等程序行爲可能打破基本塊的上述約定1
構造基本塊和流圖的目的是對代碼進行優化
ä如果中斷正常返回,則中斷本身的保護機制可以使程序正常執行下去,不影響正確性,但可能形象優化效果
ä如果中斷導致異常退出,優化的結果也不會有錯,程序本身非正常終止

 基本塊(1)

基本塊:
ä定義:基本塊是程序中最大限度順序執行的語句序列,其中只有一個入口和出口,入口是其第一個語句,出口是其最後一個語句
ä基本塊的入口語句可能是
程序的第一個語句
跳轉的目標語句
條件跳轉的下一條語句
ä基本塊的結束語句可能是
停機語句
跳轉語句
跳轉目標語句的前一個語句(詞法序)
基本塊(續)
ä構造方法
輸入:一個三地址指令序列
輸出:與之對應的基本塊列表,每個指令恰好被分到一個基本塊中
方法:
ä首先,取定中間代碼序列中哪些指令是首指令(leader,入口指令,基本塊的第一條指令)
1.中間代碼的第一個三地址指令是一個首指令
2.任意一個條件或無條件轉移指令的目標指令是一個首指令
3.緊跟在一個條件或無條件轉移指令之後的指令是一個首指令
ä然後,每個首指令對應的基本塊包括了從它自己開始,直到下一個首指令(不含)或者中間程序的結尾指令之間的所有指令
ä一個特殊情況:過程調用語句作爲一個新的基本塊的開始,甚至獨立成爲一個基本塊

 

 後續使用信息

下次不再引用意味着優化的機會
ä寄存器優化
ä臨時名字存儲單元的指派
計算後續使用信息
ä三地址語句中名字的使用(use定義:
假定三地址語句ia的值賦給x,如果語句jx作爲運算對象,並且控制從i流到j,這條路徑中沒有x的其它賦值,則稱j引用xi定的值
此時,稱x在語句i處活躍(live
ä在基本塊內:後續使用信息
對每個基本塊反向掃描
爲每個名字x在符號表中登記它是否在本塊中有後續使用
如果在本塊中沒有後續使用,則登記它是否在本塊的出口活躍。缺省認爲所有的非臨時變量在出口都是活躍的

 

ä算法8.7:對一個基本塊中的每一個語句確定活躍性與後續使用信息
輸入:一個三地址語句的基本塊B,假設在基本塊B開始時,所有的非臨時變量都是活躍的
輸出:對於每一個語句ix  = y op zxyz的活躍性信息及後續使用信息關聯到i
方法:從基本塊B的最後一個語句開始,反向掃描到B的開始處。對每一個三地址語句 ix  := y op z依次執行下述步驟:
ä把當前符號表中xyz的後續使用信息和活躍信息附加到語句i上;(若x不活躍,則這個語句可以刪掉)
ä在符號表中設置x“無後續使用”和“不活躍”;
ä把符號表中yz的後續使用信息均置爲i活躍信息均置爲“活躍”。 

注意:上述次序不能顛倒,因爲x可能是yz

 

 流圖(1

定義:控制流圖或流圖
ä結點是基本塊的有向圖G = ( N, E, root)
N是結點的集合,每個結點表示一個基本塊
E是邊的集合,如果結點ninj間存在前驅和後繼的關係,則在存在一條從ninj的有向邊(此時意味着,在ni執行後,可能會執行nj
äni的出口語句是goto(s)if … goto(s),且(s)是的nj入口語句
änj在程序中的位置緊跟在ni後,且ni的出口語句不是無條件轉移語句和停語句
root是流圖的首結點(或稱爲根結點),是包含程序第一個語句的基本塊
ä每個流圖都可以等價變換爲單入口,且每個結點最多有兩個後繼的圖

 

 

 

流圖的表示方式 

可以用任意的表示圖的數據結構表示流圖
結點(基本塊)
ä基本塊是一個指令序列
ä可能要頻繁改變這個指令序列
數量或組成的指令
目的之一是優化
ä採用指令鏈表的形式較爲高效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章