目錄
(1)如何求解數據流方程?
不論是Reaching Definition Analysis中對可達定義集合的求解,還是Liveness Analysis中對活躍變量集合的求解,本質上都是在解方程。
以RDA舉例,其數據流方程如下:
可認爲每個指令都對應方程中的兩個變量,即IN(p)和OUT(p)。爲了減少變量個數,把(1)式帶入(2)式,以去掉IN(p):
此時方程中的變量爲,而和則屬於常數,因爲其值隨着指令的確定而相應確定。
此外,方程還有一個初值,即,
轉化爲OUT,
爲了說明求解思路,先用更簡化的符號來表示上述方程:
通過此方程可以看出,數據流方程的一個重要特點就是,待求的每個未知數既是若干方程的自變量,也是某個方程的因變量。
從此特點出發,我們很快發現一種求解的思路,即先給定一組未知數的初始值如,接着將這組值帶入上述方程,得到又一組未知數的值,如果與相等,則說明找到了一組方程的解,因爲這組值可讓上述方程成立。如果與不相等,則重複上述過程,一定能找出方程的一組解。原因如下:
對於RDA,自變量越大(即集合的基數越大),根據方程,其因變量也相應越大。
由此可知,上述方程中的函數都是單調不減的,即如果,則有
,即
要讓解集合隨着迭代的進行而越來越大(即集合的基數越大),還需要一個初始條件,即
如果令,則有
此時初始條件和函數單調性共同作用,有如下鏈式反應:
由於是離散值(集合)且有上界(集合元素有上限),因此上述鏈式反應一定會終止,終止時會有
,這即爲方程的一組解。
(2)WorkList Algorithm
上述思路對應的算法爲Round-Robin Iterations,即各未知數的迭代次數(or更新次數)保持同步,即算法每次循環結束後都有
,而WorkList Algorithm則不同,其未知數的迭代次數不一定同步,在算法每次循環結束後可能會出現
,這說明針對未知數的值的更新,WorkList Algorithm有一套優先級規則。(其實這兩種更新思路與數值分析中求解線性方程組的Jacobi迭代和Gauss-Seidel迭代有共通之處)
先給出WorkList Algorithm的(不規範的)僞代碼:
WorkList()
for i <- 1 to n do
y[i] <- { } //初始化隨具體情況而定
w <- [ y[1] y[2] ... y[n] ] //將未知數放入worklist中
while(!is_empty(w)) do
y[i] <- extract(w) //從worklist以某種方式抽出一個未知數
old <- y[i] //記錄此未知數的值
y[i] <- f_i(y[1], y[2], ..., y[n]) //挑出以此未知數作爲因變量的方程,並進行運算,結果賦給此未知數
if old != y[i] then //如果未知數的值在運算後發生變化
for y[k] <- dep(y[i]) do
//將依賴它的那些未知數放入worklist中,a依賴b的含義是
//以a爲因變量的方程使用b作爲自變量,因此當b發生變化,a也就可能發生變化
//故把a放入worklist中
w <- insert(w, y[k])
未完待續