2015-10-08 59 views
1

當只有一個可能的前驅者時使用phi節點有什麼好處?例如,當我運行opt -loop-<some specific pass> some-cool-file.ll -S時,如果我還沒有添加一個前綴,那麼輸出將經常包含一個只有一個可能前驅的phi節點。只有一個可能的前驅者的LLVM IR phi節點

例子:

endcond.loopexit:      ; preds = %loop <- note: one predecessor 
    %res.lcssa = phi i64 [ %res, %loop ] ; I'm assuming this is from the 
    br label %endcond     ; loop-closed ssa form pass 

endcond: 
    %var = phi i64 [ %res.lcssa, %endcond.loopexit ], <other-pred> 

如果只有一個可能的前身應該不是上面是完全一樣

endcond.loopexit:      ; preds = %loop 
    br label %endcond     ; res assigned a value in %loop 

endcond: 
    %var = phi i64 [ %res, %endcond.loopexit ], <other-pred> ; use %res directly 

不要誤會我的意思,我是一個phi節點的狂熱粉絲,但我只是好奇,除了在只有一個可能的前任時添加一個phi節點時,除了提高可讀性和警告之外,還有其他好處。

回答

4

當然,你是對的,兩者是等價的。但是,前一個環路是LCSSA(環路閉合SSA)形式。這種形式提供了一些非常有用的保證,可以簡化許多循環優化。

這不是特定於LLVM,GCC也是這樣做的。他們對LCSSA表格的具體優勢進行了很好的總結:在典型的編譯通道流水線期間,LCSSA PHI節點將在InstCombine通道的循環優化後被移除。 (如果在所有循環優化之後運行-instcombine,則會得到預期的輸出。)

+0

謝謝!另一個完美的答案!所以我的後續問題是,我在每個塊的開始處(減去條目)使用phi節點來獲取錯誤消息和可讀性。這是好還是壞的風格?或者,只要我使用'-instcombine',它甚至會有問題? –

+0

我想你有兩個原因可能會擔心錯誤信息和可讀性:如果你是因爲某種原因手寫IR,或者在調試產生IR的前端時。無論哪種方式,你對IR的處理完全取決於你 - 畢竟,最終用戶不應該知道IR,LLVM也不會在乎(因爲InstCombine,後來因爲phi節點被完全消除了無論如何)。 –