ANF可以保證每個計算都由一系列的let序列化,並且所有operands都一定是values,從而對指令語言後端編譯是好用的表示形式。但ANF也有一些缺點
ANF在 -reduction 下不封閉 [local-0]
ANF的缺點之一是在 -reduction 下不封閉,比如
但這個表達式不是合法的ANF,在RHS位置 不被允許出現。這讓ANF -equivalence必須重新normalize所有commuting conversions
這對最佳化來說是一個缺陷,因為 -equivalence model了inlining optimizations;而renormalize是不便又昂貴的計算
會導致程式碼指數級的增長 [local-1]
我們可以觀察以下案例套用 的結果
let x := if0 (if0 (if0 0 0 1) 0 1) 0 1 in LARGE
因為continuation 是 let x := ♢ in LARGE,所以第一次轉換得到
if0 (if0 (if0 0 0 1) 0 1) E1[0] E1[1]
再來 是 if0 ♢ E1[0] E1[1],好吧,那就得到
if0 (if0 0 0 1) E2[0] E2[1]
再來 是 if0 ♢ E2[0] E2[1],所以是
if0 0 E3[0] E3[1]
最後我們攤開來看就得到
if0 0
if0 0
if0 0
let x := 0 in LARGE
let x := 1 in LARGE
if0 1
let x := 0 in LARGE
let x := 1 in LARGE
if0 1
if0 0
let x := 0 in LARGE
let x := 1 in LARGE
if0 1
let x := 0 in LARGE
let x := 1 in LARGE
所以3層if的堆疊得到8個 LARGE
到這裡,Bowman就問說,如果ANF有這麼多問題,那麼與其去修復它,為什麼不要禁止 轉換然後允許 let x := if0 V M1 M2 in M 這個形式呢?畢竟這個形式說穿了也就是
begin:
if0 V
set! x M1
set! x M2
M
這完全是指令語言後端可以接受的程式!事實上,這早就已經是實用編譯器的常見做法
A-normalization對非monadic effect不安全 [local-2]
Bowman舉了letregion作為案例,並認為沒有文獻討論過這個缺陷。注意到Bowman不想重複join point的老路,也就是要避免用local continuation處理這個問題