我正在編寫一門課程的編譯器。我遇到了一些優化問題,我不確定如何處理最佳。假設輸入語言有一個while循環,它使用必須保存在寄存器中的N個局部變量(或者應該爲了快速計算)。假設N> K,寄存器的數量。在while循環結束時有可能改變條件寄存器。編譯代碼生成 - 條件塊內部的寄存器分配
例如,假設x的寄存器(比方說,在i386%EAX)確定之前發表聲明如下:
while (x) { x = x - 1 ; /* more statements */ }
在多個語句代碼,它有可能被溢出的X回到棧上。當代碼跳回到while循環的開始以重新計算x時,它將嘗試使用%eax - 但這可能甚至不會保存x的值。所以我們可以有像我使用的是強制代碼while語句(所以寄存器被視爲空從代碼生成的角度來看)之前,溢出所有修改寄存器
movl -8(%ebp), %eax # eax <- x
.... # do stuff but let x stay in %eax
_LOOP1: cmpl $0, %eax
....
movl -12(%ebp), %eax #eax now holds something else
....
jmp _LOOP1
一種解決方案。在while循環的標籤之後,代碼必須根據需要將所有內容加載到寄存器中。
我的解決辦法是這樣的:
movl -8(%ebp), %eax # eax <- x
.... # do stuff but let x stay in %eax
movl %eax, -8(%ebp) # spilling and clearing all registers
_LOOP1: movl -8(%ebp), %eax # get a register for x again
cmpl $0, %eax
....
movl -12(%ebp), %eax # eax now holds something else
....
movl %eax, -8(%ebp) # spill to prevent overwrite
jmp _LOOP1
好像我的解決辦法是有點多餘的或不必要的。有沒有我在這裏忘記的一些一般優化技巧?
編輯:我還想指出類似的情況發生的條件,如if和if else。發生這種情況是因爲一個寄存器可能被分配給條件塊內的一個變量,但代碼生成器假定它被移動到那裏以後的其他所有內容中。我處理這個案件的方法幾乎相同。
我還沒有太多時間來研究這個問題,但似乎以增加複雜性爲代價的性能增益非常微小? – Kizaru 2010-09-27 13:30:17
取決於正在編譯的代碼(與所有編譯器優化一樣),獲得的增益差別很大。很少有優化影響代碼速度總體上超過百分之幾。 – 2010-09-27 17:43:12
謝謝。我授予賞金。當我發佈我的第一條評論時,我打算這麼做。在一些測試用例之後,優化確實很小(對於i386)。我期望它能在像MIPS這樣的架構上有用。 – Kizaru 2010-09-29 15:57:57