說說靜態單賦值(SSA,Static Single-Assignment)

來源:互聯網
上載者:User

原文地址:http://www.lingcc.com/2011/08/13/11685/精確的資料流分析是讓編譯最佳化能高效進行的基礎。 SSA就是一種高效的資料流分析技術,目前幾乎所有的現代編譯器,如GCC、Open64、LLVM都有將SSA技術的支援, 不僅僅是編譯器,Jikes RVM, HotSpot JVM, .Net的Mono,Python的Pypy, Andoroid的Dalvik,這些虛擬機器/解譯器中的Just-in-Time Compiler也有了SSA的支援。
Firefox的下一代JavaScript引擎IonMonkey中,也將為其JIT引入SSA。

可以看到,幾乎所有熱門的語言所用的熱門編譯器/解譯器/虛擬機器中都有了SSA。

Table of Contents
  • 1 SSA是什嗎?
  • 2 SSA的作用
    • 2.1 SSA與寄存器分配
  • 3 SSA的轉換
    • 3.1 從普通中間表示到SSA
    • 3.2 從SSA到普通中間表示
  • 4 更複雜情況下的SSA
    • 4.1 數組、指標等別名
    • 4.2 堆上的儲存
    • 4.3 複合結構–結構體
  • 5 GCC中的SSA
  • 6 open64 中的SSA
  • 7 相關資料和文獻
1 SSA是什嗎?

SSA即靜態單賦值,Static Single-Assignment,這是一種中間表示形式。 之所以稱之為單賦值,是因為每個名字在SSA中僅被賦值一次.

如中的一段程式的控制流程圖。從這張圖中可以看到,最後一個基本塊中y值的定義或者來自左側的分支,或者來自右側的分支。

SSA_example1.1

將每個指派陳述式中的變數賦予一個唯一的名稱後,一般新名稱採用原變數+版本號碼(Version)的形式。 對於上面這段控制流程圖,就變成如下形式:

SSA_example1.2

這張圖中有個問題,有分支時,若分支中有對變數的操作,就無法確定使用了哪個版本的變數。 因此,引入了PHI節點。如所示:

SSA_example1.3

PHI將分支中的y1和y2串連,並產生一個新的定義y3。有了PHI節點後,最後一個基本塊中y3的定義來自之前的PHI節點,PHI節點中的兩個運算元y1和y2分別來自左右兩個分支。

2 SSA的作用

在SSA中間表示中,可以保證每個被使用的變數都有唯一的定義,即SSA能帶來精確的使用–定義關係。 而在圖SSA_example1.1中的y值定義卻非常模糊。

概括起來,SSA帶來四大益處:

  • 因為SSA使得每個變數都有唯一的定義,因此資料流分析和最佳化演算法可以更加簡單
  • 使用-定義關係鏈所消耗空間從指數增長降低為線性增長。若一個變數有N個使用和M個定義,若不採用SSA,則存在M×N個使用-定義關係。
  • SSA中因為使用和定義的關係更加的精確,能簡化構建幹擾圖的演算法
  • 來源程式中對同一個變數的不相關的若干次使用,在SSA形式中會轉變成對不同變數的使用,因此能消除很多不必要的依賴關係。

有了精確的對象使用–定義關係,許多利用使用–定義關係的最佳化就能更精確、更徹底、更高效。如

  • 常數傳播
  • 無作用程式碼刪除
  • 全域
  • 部分冗餘刪除
  • 強度削弱
  • 寄存器分配
2.1 SSA與寄存器分配

因為SSA使得依賴分析更加簡單、精確,而且PHI節點中的變數不可能同時活躍。因此在SSA形式能協助完成寄存器分配。 實際上,GCC最早的SSA就是GCC 3中RTL階段。

3 SSA的轉換

講了這麼多有關SSA的優點,接下來介紹一下一般編譯器構建SSA的方式。

3.1 從普通中間表示到SSA

兩步走戰略:

  • 插入PHI節點: PHI節點要插在控制流程圖的匯聚點處(joint point), 只要在匯聚點之前的分支中有針對某個變數的修改, 就需要在該匯聚點插入針對該變數的PHI節點。 PHI節點的運算元是分支路徑中重新定義的變數。
  • 變數重新命名: 在插入PHI節點後,SSA中所有針對變數的定義就具備了,接下來就依次在定義處重新命名變數,並替換對應的變數使用處。

此外,為了節省記憶體空間,簡化SSA上的演算法,我們需要將插入的PHI節點數目最小化。 因為PHI節點本身只是一個概念性的節點,若插入過多不必要的PHI節點,演算法就需要在控制流程圖的匯聚點針對每個分支做分析。 可以借用變數的支配邊界(dominance frontier)進行PHI節點數目最消化。一般都通過直接計算支配邊界的方式插入PHI節點。

3.2 從SSA到普通中間表示

為什麼還要從SSA轉換回去呢?很簡單,處理器不能直接執行PHI節點對應的操作。最簡單的做法,直接拷貝,如所示:

out of ssa

但這樣有一個問題,如。簡單的拷貝演算法可能改變代碼的語義:

out of ssa problem

正確的做法:

  • 對PHI節點的運算元和結果重新命名,使其名稱相同,即變成同一個變數
  • 再在分支中插入拷貝操作
4 更複雜情況下的SSA4.1 數組、指標等別名

上面關於SSA的討論基本都是針對單個簡單變數的SSA操作,那麼對於複雜的指標、數組之類的訪存,SSA應該如何處理呢? 數組和指標使得編譯器無法確定define和use的具體變數。

參考資料7給出了一種定義方式,通過引入maydef,mayuse和zero version使得編譯器也能對別名(即指標和數組)存在的程式做SSA分析。 若通過指標為其所指地區賦值,就在此處插入maydef,表示可能對變數做了定義。同理,對使用指標所指向地區的值的,就插入一個mayuse。 因為無法確定指標所指向的到底是哪個變數,為了正確性,需要對所有變數都插入maydef動作。同樣mayuse也是針對所有變數的。

當指標操作較多時,這種方式就會引入過多的新變數版本。因此就增加了zero version。 zero version的作用就是盡量把maydef所帶來的版本數降低。 將那些很可能不會別名的都使用相同的zero version。 比如某個變數通過maydef產生了一個新版本之後,若還會有新的maydef操作,則直接產生zero version,不再產生新的version。

4.2 堆上的儲存

在堆上分配的儲存空間,一般編譯器都將整個堆看作一個對象,來做SSA。

4.3 複合結構–結構體

因為結構體也是由很多元素構成的,所以就存在兩種處理方式:把結構體整個看作一個整體做SSA、把結構體的每個元素看作一個對象做SSA。 後者相比前者,因為分的更細,在結構體操作頻繁的程式中能帶來不錯的最佳化效果。

5 GCC中的SSA

GCC的SSA

  • tree-ssa.c
  • tree-into-ssa.c:將函數轉換為SSA形式,插入PHI節點,對於未初始化的變數給出警告。
  • tree-ssa-dce.c:掃描整個函數,標記無副作用且結果並未被使用的語句,所有儲存操作都視為有副作用。
  • tree-ssa-dom.c:支配關係相關最佳化:複寫傳播、常數傳播、運算式簡化、冗餘消除、Jump Threading?
  • tree-ssa-forwprop.c:前向傳播單一引用變數,通過將僅使用一次的變數用相應的運算式替代來嘗試容易刪除。
  • tree-ssa-copyrename.c:嘗試將由拷貝動作產生的SSA變數用原變數替換之,最佳化符號表。
  • tree-ssa-phiopt.c: 識別表達條件運算式的phi節點,並將其重寫為直線代碼。
  • tree-ssa-alias.c:流敏感基於SSA的指向分析,得到可能-別名,一定-別名和逃逸分析資訊。 這些資訊將用於將變數從記憶體中地址可用對象提升為非別名變數,這樣這些變數就能使用SSA形式的分析和最佳化了。
  • tree-ssa-structalias.c:用於過程間的指向分析。
  • tree-sra.c:將合適的無別名局部複合變數轉換為一個標量集合,並進而轉換為SSA形式。
  • tree-ssa-dse.c:刪除那些無用的儲存操作
  • tree-ssa-sink.c:將儲存和指派陳述式盡量下沉到和它們的使用點接近的位置。
  • tree-ssa-pre.c:部分冗餘刪除、load語句移動、完全冗餘刪除
  • tree-ssa-loop.c: SSA形式的迴圈最佳化
    • tree-ssa-loop-im.c:迴圈無關語句移動
    • tree-ssa-loop-ivcanon.c:迴圈標準化
    • tree-ssa-loop-ivopts.c:索引變數最佳化
    • tree-ssa-loop-unswitch.c:將迴圈無關的條件跳轉移到迴圈外
    • tree-vectorizer.c, tree-vect-analyze.c, tree-vect-transform.c:自動向量化
  • tree-ssa-ccp.c:條件常數傳播
  • tree-ssa-copy.c:條件複寫傳播
  • tree-vrp.c:取值範圍傳播
  • tree-outof-ssa.c:從SSA形式轉換回普通形式
6 open64 中的SSA

open64中的SSA主要用於迴圈嵌套最佳化、過程間最佳化以及普通的函數內最佳化。 除了迴圈變換和內聯最佳化外的所有機器無關最佳化都基於SSA做。 這部分可以說是Open64的重要賣點,對應的代碼在osprey/be/opt下。

Open64在沒有過程間最佳化時,主要以函數為單位進行,基於控制流程圖和別名分析得到的資訊構建SSA。

  • opt_goto.cxx:goto語句轉換,方便做SSA
  • opt_loop.cxx:迴圈正規化
  • opt_sym.cxx:構建相關符號表
  • opt_alias_class.cxx:別名分類,方便別名分析
  • opt_cfg.cxx:構建控制流程圖,包括支配樹,不可到達代碼識別,if語句轉換
  • opt_tail.cxx:尾遞迴消除
  • opt_alias_analysis.cxx:流無關別名分析
  • opt_ssa.cxx:構建基於WHIRL的SSA
  • opt_dse.cxx:死store刪除
  • opt_htable.cxx:構建HSSA–基於雜湊的全域值編號SSA
  • opt_ivr.cxx:索引變數標準化
  • opt_prop.cxx:複寫傳播
  • opt_revise_ssa.cxx:將非直接變數展開成直接變數
  • opt_dce.cxx:無作用程式碼刪除
  • opt_cfg_trans.cxx:控制流程轉換
  • opt_rename.cxx:SSA變數重新命名、更新
  • opt_du.cxx:構建define-use資訊
  • opt_etable.cxx:基於運算式的部分冗餘刪除
  • opt_estr.cxx:強度削弱
  • opt_ehoist.cxx:代碼提升
  • opt_lftr2.cxx:線性代碼測試、替換
  • opt_vn.cxx:基於值編號的完全冗餘刪除
  • opt_ltable.cxx:針對load的部分冗餘刪除
  • opt_stable.cxx:store Partial Redundancy Elimination 針對store的部分冗餘刪除
  • opt_bdce.cxx: Bitwise dead code elimination–針對結構體
  • opt_htable_emit.cxx: 從SSA轉換回WHIRL中間表示
7 相關資料和文獻
  • http://en.wikipedia.org/wiki/Static_single_assignment_form
  • http://en.wikipedia.org/wiki/SpiderMonkey_%28JavaScript_engine%29
  • Advanced Compiler Design and Implementation, by Steven S. Muchnick, Page 252-265
  • Modern Compiler Implementation in C, by Andrew W. Appel, Page 433-473
  • Crafting A Compiler, by Charles N. Fischer, etc , Page 410-414
  • 8. Static Single Assignment Form, by Marcus Denker,
    http://marcusdenker.de/talks/08CC/08IntroSSA.pdf
  • Effective Representation of Aliases and Indirect Memory Operations in SSA Form, Fred Chow, Sun Chan, etc. Compiler Construction 1996  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.