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