GCC(GNU Compiler Collection,GNU編譯器(qi)套(tao)件)是(shi)由GNU開發的編程(cheng)語言(yan)譯器(qi)。GNU編譯器(qi)套(tao)件包(bao)括C、C++、Objective-C、 Fortran、Java、Ada和Go語言(yan)前端,也包(bao)括了這些語言(yan)的庫(如libstdc++,libgcj等。)
GCC的(de)(de)(de)初衷是(shi)為GNU操作系統專門(men)編寫的(de)(de)(de)一款(kuan)編譯器。GNU系統是(shi)徹底(di)的(de)(de)(de)自(zi)(zi)(zi)由(you)軟件。此處,“自(zi)(zi)(zi)由(you)”的(de)(de)(de)含義是(shi)它(ta)尊重(zhong)用戶的(de)(de)(de)自(zi)(zi)(zi)由(you)。
GCC的外(wai)部接(jie)口長(chang)得像(xiang)一(yi)個標準的Unix編(bian)譯器(qi)。使(shi)用者在命令列下鍵入(ru)gcc之程(cheng)序(xu)名(ming),以(yi)及一(yi)些(xie)命令參數,以(yi)便決定(ding)每個輸入(ru)檔案使(shi)用的個別(bie)語(yu)(yu)言(yan)編(bian)譯器(qi),并為輸出程(cheng)序(xu)碼使(shi)用適(shi)合此硬件平(ping)臺(tai)的組合語(yu)(yu)言(yan)編(bian)譯器(qi),并且選擇性地(di)執行連接(jie)器(qi)以(yi)制造可(ke)執行的程(cheng)序(xu)。
每個(ge)語(yu)(yu)言(yan)編譯(yi)(yi)器(qi)(qi)都是獨立程(cheng)(cheng)序,此(ci)(ci)程(cheng)(cheng)序可處(chu)理(li)輸(shu)(shu)入的(de)(de)(de)原始(shi)碼(ma)(ma)(ma),并(bing)輸(shu)(shu)出(chu)組合語(yu)(yu)言(yan)碼(ma)(ma)(ma)。全部的(de)(de)(de)語(yu)(yu)言(yan)編譯(yi)(yi)器(qi)(qi)都擁有共通的(de)(de)(de)中介架(jia)構:一(yi)個(ge)前端解析符(fu)合此(ci)(ci)語(yu)(yu)言(yan)的(de)(de)(de)原始(shi)碼(ma)(ma)(ma),并(bing)產生一(yi)抽象語(yu)(yu)法樹(shu),以(yi)及一(yi)翻譯(yi)(yi)此(ci)(ci)語(yu)(yu)法樹(shu)成為GCC的(de)(de)(de)暫存器(qi)(qi)轉換語(yu)(yu)言(yan)〈RTL〉的(de)(de)(de)后端。編譯(yi)(yi)器(qi)(qi)最佳化與靜態程(cheng)(cheng)序碼(ma)(ma)(ma)解析技術(例(li)如FORTIFY_SOURCE,一(yi)個(ge)試圖發現緩沖區溢位(wei)〈buffer overflow〉的(de)(de)(de)編譯(yi)(yi)器(qi)(qi))在此(ci)(ci)階段應用于(yu)程(cheng)(cheng)序碼(ma)(ma)(ma)上。最后,適用于(yu)此(ci)(ci)硬件架(jia)構的(de)(de)(de)組合語(yu)(yu)言(yan)程(cheng)(cheng)序碼(ma)(ma)(ma)以(yi)Jack Davidson與Chris Fraser發明的(de)(de)(de)算法產出(chu)。
幾乎全部的GCC都由C寫成,除(chu)了Ada前(qian)端(duan)大部分(fen)以(yi)Ada寫成。
前端的功能在(zai)于產生(sheng)一個可(ke)讓后端處理之語法(fa)樹。此語法(fa)解析(xi)器(qi)是手寫之遞歸語法(fa)解析(xi)器(qi)。
直到2004年,程(cheng)序的(de)語(yu)(yu)法樹(shu)(shu)結(jie)構尚無法與欲產出(chu)的(de)處理(li)器架構脫鉤。而語(yu)(yu)法樹(shu)(shu)的(de)規(gui)則有時(shi)在(zai)不(bu)同的(de)語(yu)(yu)言前端也不(bu)一樣(yang),有些前端會(hui)提供它(ta)們特(te)別的(de)語(yu)(yu)法樹(shu)(shu)規(gui)則。
在2005年,兩種與(yu)(yu)語(yu)(yu)(yu)(yu)言(yan)脫(tuo)鉤的(de)(de)新型態語(yu)(yu)(yu)(yu)法樹納入GCC中。它(ta)們(men)(men)稱為(wei)GENERIC與(yu)(yu)GIMPLE。語(yu)(yu)(yu)(yu)法解(jie)析變(bian)成產(chan)生與(yu)(yu)語(yu)(yu)(yu)(yu)言(yan)相關的(de)(de)暫時語(yu)(yu)(yu)(yu)法樹,再將它(ta)們(men)(men)轉成GENERIC。之(zhi)后(hou)再使用(yong)"gimplifier"技術降低GENERIC的(de)(de)復(fu)雜(za)結構,成為(wei)一較簡(jian)單的(de)(de)靜態唯(wei)一形式(shi)(Static Single Assignment form,SSA)基礎的(de)(de)GIMPLE形式(shi)。此形式(shi)是一個與(yu)(yu)語(yu)(yu)(yu)(yu)言(yan)和(he)處理器(qi)架構脫(tuo)鉤的(de)(de)全域最佳化通用(yong)語(yu)(yu)(yu)(yu)言(yan),適(shi)用(yong)于(yu)大多數的(de)(de)現代編程語(yu)(yu)(yu)(yu)言(yan)。
一般編(bian)譯器作(zuo)(zuo)者會將語法樹的(de)(de)最佳(jia)化(hua)(hua)放在(zai)前端,但其實此(ci)步驟(zou)并不(bu)看(kan)語言的(de)(de)種類而有不(bu)同(tong),且不(bu)需要用到(dao)語法解析器。因(yin)此(ci)GCC作(zuo)(zuo)者們將此(ci)步驟(zou)歸入通稱為中介階段的(de)(de)部分里(li)。此(ci)類的(de)(de)最佳(jia)化(hua)(hua)包括消解死(si)碼、消解重(zhong)復運算(suan)與全域數值(zhi)重(zhong)編(bian)碼等。許(xu)多最佳(jia)化(hua)(hua)技巧(qiao)也正在(zai)實作(zuo)(zuo)中。
GCC后(hou)端的(de)行(xing)為因不(bu)同(tong)(tong)的(de)前處理器(qi)宏和特定架構的(de)功能而不(bu)同(tong)(tong),例如(ru)不(bu)同(tong)(tong)的(de)字(zi)符尺寸(cun)、呼叫方式(shi)與(yu)大小尾序等。后(hou)端接(jie)口的(de)前半部利用這些訊息決(jue)定其RTL的(de)生成形式(shi),因此(ci)雖然GCC的(de)RTL理論上不(bu)受處理器(qi)影響,但在此(ci)階段其抽象指(zhi)令已被轉換(huan)成目(mu)標架構的(de)格(ge)式(shi)。
GCC的最(zui)佳(jia)化(hua)技巧依(yi)其釋出版本(ben)而有很(hen)大不同,但(dan)都包含了標準的最(zui)佳(jia)化(hua)算法,例如循(xun)環最(zui)佳(jia)化(hua)、執行緒跳躍(yue)、共通程(cheng)序(xu)子(zi)句(ju)消(xiao)減、指令排程(cheng)等(deng)等(deng)。而RTL的最(zui)佳(jia)化(hua)由(you)于可用的情形(xing)較少,且(qie)缺乏(fa)較高(gao)階的資訊,因此(ci)相比較起來,增加的GIMPLE語法樹形(xing)式,便顯得比較不重(zhong)要。
后端經由一次(ci)重讀(du)取步驟(zou)后,利用(yong)描述目標處(chu)(chu)理器(qi)(qi)的指(zhi)令(ling)集(ji)時所取得的信息,將抽(chou)象暫存器(qi)(qi)替換成處(chu)(chu)理器(qi)(qi)的真實暫存器(qi)(qi)。此階(jie)段非常復雜,因(yin)為它必須關注所有GCC可移植平(ping)臺的處(chu)(chu)理器(qi)(qi)指(zhi)令(ling)集(ji)的規格(ge)與技(ji)術細節。
后端的(de)最后步驟相當公(gong)式化(hua),僅(jin)(jin)僅(jin)(jin)將(jiang)前一階段得到的(de)匯編(bian)語言代碼藉由簡單的(de)子例(li)程轉(zhuan)換其暫(zan)存器(qi)與內存位置成(cheng)相對應(ying)的(de)機(ji)器(qi)碼。
以2006年5月24日釋(shi)出的4.1.1版(ban)為準,本編譯器版(ban)本可處理下(xia)列語言(yan):
Ada〈GNAT〉
C〈GCC〉
C++(G++)
Fortran〈Fortran77:G77,Fortran90:GFORTRAN〉
Java〈編譯器:GCJ;解釋器:GIJ〉
Objective-C〈GOBJC〉
Objective-C++
先前(qian)版本納入的CHILL前(qian)端由于缺乏(fa)維護(hu)而被廢棄(qi)。
Fortran前(qian)端在4.0版之前(qian)是(shi)G77,此(ci)前(qian)端僅支援Fortran77。在本(ben)版本(ben)中,G77被廢棄而采用(yong)更新的GFortran,因為此(ci)前(qian)端支援Fortran95。
下列(lie)前(qian)端依然存在:
Modula-2
Modula-3
Pascal
PL/I
D語言
Mercury
VHDL