控制流圖
控制流圖
控制流圖(Control Flow Graph, CFG)也叫控制流程圖,是一個過程或程序的抽象表現,是用在編譯器中的一個抽象數據結構,由編譯器在內部維護,代表了一個程序執行過程中會遍歷到的所有路徑。它用圖的形式表示一個過程內所有基本塊執行的可能流向, 也能反映一個過程的實時執行過程。
Frances E. Allen與1970年提出控制流圖的概念。此後,控制流圖成為了編譯器優化和靜態分析的重要工具。
控制流圖中每個在圖形中的節點代表一個基本塊,例如,沒有任何跳躍或跳躍目標的直線代碼塊;跳躍目標以一個塊開始,和以一個塊結束。定向邊緣被用於代表在控制流中的跳躍。在那裡,在大部分介紹中,兩個特定的設計塊:項目塊,通過它控制到流圖的輸入,和編輯塊,通過它全面控制流輸出。
CFG 能反映出一個過程的許多信息:
是哪一個過程;
一個過程的入口(第一個基本塊) 和出口( 最後一個基本塊);
一個基本塊的所有可能的下一個基本塊( 所有的出口);
一個基本塊的所有可能的上一個基本塊( 所有的入口);
一個基本塊所對應的語句表。
對於一個動態CFG 而言, 它還包含下列信息:
當前活動的基本塊;
上次執行的基本塊;
執行流向,即上次執行的基本塊到當前活動基本塊之間的連線。
一個CFG 可顯示一個過程內各基本塊之間的相互關係、動態執行狀態、各基本塊對應的語句表。此外,還有其他輔助信息,如各基本塊執行次數,執行時間等等。
靜態結構圖為一有向圖,如圖2所示。圖中各節點的序號順序從1排列。第1個塊即為子程序頭“Suborutine子程序名”。從一個節點到下一個節點的連線表明其執行的可能順序,用有箭頭的線表示,稱為有向線。有向線的起點所對應的塊為正要轉移的塊,而箭頭所指的塊為將要轉向的塊。
圖1為一過程XYZA的源程序,圖2 為與該過程對應的CFG。從圖中可以看出,從一個節點畫出的有向線有四種情形:(a)指向下一塊;(b)指向下一塊以後的節點;(c)指向上一個塊或上一塊以前的塊;(d)指向其自身。如圖中, 塊2到塊3為(a)情形,塊6到塊8為(b)情形,塊13到塊6為(c) 情形,塊12為(d)情形。
每一個塊的塊號為其標識符。每一塊對應一組源程序中的語句。
圖1 圖2
動態顯示圖是在靜態圖的基礎上完成的, 它不但能反映源程序的靜態結構關係,還能實時地反映動態執行時的軌跡。
在即將執行一個塊的第一條語句時“點亮”該塊,表明這一塊為將要執行的活動基本塊,而上一個基本塊已經執行完畢,但還沒有完全“熄滅”。這完全是為了記住執行軌跡而人為設置的。從上一次執行的基本塊到當前活動基本塊有一條連線,箭頭表示轉移方向。這條有向線有別於其他的有向線,用紅色標出,稱為“活動線”,因為它是當前的執行軌跡。當從當前塊轉向下一個塊時,重新標出活動線,而原先的活動線則恢復為靜態連線。
任何時候都可以瀏覽圖中任一基本塊所對應的語句表。
由於進入和離開一個基本塊的時刻和進入的次數是知道的,所以一個塊被執行的次數和執行它所花的時間的總和是可以統計出來的。
控制流圖CFG是一有向圖G = (N, E, nentry, nexit). 其中,N是節點集,程序中的每個語句都對應圖中的一個節點;邊集E = {< n1,n2 > | n1, n2∈ N且n1執行后,可能立即執行n2}; nentry 和nexit分別為程序的入口和出口節點。它具有唯一的起始結點START和唯一的終止結點STOP。CFG中的每個結點至多只能有兩個直接後繼。對於有兩個直接後繼的結點v,其出邊具有屬性“T”或“F”,並且在CFG中的任意結點N,均存在一條從START經N到達STOP的路徑。
程序語句格式化、規範化處理;
識別程序的邏輯行;
根據程序邏輯行之間的控制關係繪製CFG圖;
在CFG圖上作適當的標記,例如入/出口、真假分支等。
對CFG 控制有兩種方式,一是在調用圖中用參數選擇決定是否要顯示CFG,二是在CFG的彈出式菜單中選擇參數,決定是否要顯示每一步執行軌跡。如果選擇否,則僅顯示一次靜態CFG。否則,詳細顯示執行軌跡。在CFG中,有控制顯示速度的參數,它們是:無延遲;延遲半秒;延遲1秒和延遲3 秒。此外,還有暫停/ 繼續開關,用於停下來瀏覽等。CFG中的控制菜單如圖4所示。
圖4