LLVM探索

LLVM的概念

日常開發(fā)過程我們的開發(fā)工具或多或少都跟LLVM扯得上一點(diǎn)關(guān)系,那么什么是LLVM呢筷畦?它有什么作用呢继效?首先我們需要明白兩個(gè)概念解釋型語言編譯型語言训措。解釋型語言:當(dāng)它讀到當(dāng)前代碼就立即執(zhí)行如python伪节。編譯型語言:他需要先把它翻譯成CPU可以讀懂的二進(jìn)制文件才可以執(zhí)行。LLVM也稱為架構(gòu)編譯器隙弛,它是用C++編寫的架馋,主要作用是用于優(yōu)化任意程序編寫的程序編譯時(shí)間????????????????????????????????????、鏈接時(shí)間全闷、運(yùn)行時(shí)間和空閑時(shí)間叉寂,對開發(fā)者開放并兼容已有的腳本。

編譯器設(shè)計(jì)


上圖為傳統(tǒng)的編譯器設(shè)計(jì)总珠,它是一種前后端分離的一種模式屏鳍。
編譯器前端(Frontend):解析源代碼。它會進(jìn)行詞法分析局服、語法分析钓瞭、語義分析,源代碼錯(cuò)誤檢查淫奔,并構(gòu)建抽象語法樹(AST)山涡,LLVM的前端還會生成中間代碼(IR)。
優(yōu)化器(Optimizer):負(fù)責(zé)各種優(yōu)化,改善代碼的運(yùn)行時(shí)間鸭丛,如優(yōu)化代碼中的冗余計(jì)算竞穷。
后端(Backend)/代碼生成器(CodeGenerator):將優(yōu)化后的代碼轉(zhuǎn)化為二進(jìn)制文件并映射到目標(biāo)指令集。

iOS的編譯器架構(gòu)


OC鳞溉、C瘾带、C++使用的編譯器前端是Clang,Swift使用的編譯器前端是Swift熟菲,后端都是用的LLVM看政。

LLVM的優(yōu)點(diǎn)


LLVM的設(shè)計(jì),使用通用的代碼表示形式IR抄罕,它是用來在編譯器中表示代碼的形式允蚣。LLVM可以為任何任何語言獨(dú)立的編寫前端,并為任意的硬件架構(gòu)編寫后端贞绵。

Clang

Clang是LLVM項(xiàng)目中的一個(gè)子項(xiàng)目厉萝。它是一個(gè)輕量級的編譯器,它是負(fù)責(zé)編譯C榨崩、C++谴垫, OC語言的編譯器,它在LLVM架構(gòu)中的編譯器的前端母蛛。
終端輸入open /usr/bin可以查看到編譯器Clang

編譯流程分析

  • 首先創(chuàng)建一個(gè).m文件翩剪,并cd到當(dāng)前文件路徑


  • 終端輸入clang -ccc-print-phases main.m,結(jié)果終端會打印如下

    0:輸入文件彩郊,找到源文件前弯。
    1:預(yù)處理階段,處理宏的替換秫逝,頭文件的引入恕出。
    2:編譯階段,詞法分析违帆、語法分析浙巫、最終生成IR。
    3:后端:此階段LLVM通過一個(gè)一個(gè)的pass去優(yōu)化刷后,最終生成匯編代碼的畴。
    4:生成目標(biāo)文件。
    5:鏈接尝胆,鏈接需要的的動靜態(tài)庫丧裁,生成可執(zhí)行文件。
    6:通過不同的架構(gòu)生成對應(yīng)的可執(zhí)行文件含衔。

預(yù)處理

終端執(zhí)行clang -E main.m


執(zhí)行完成后煎娇,我們可以看到頭文件被導(dǎo)入和宏被替換了二庵。

編譯

什么叫詞法分析呢?預(yù)處理階段會將代碼切成一個(gè)一個(gè)的token逊桦,如括號眨猎、等號、字符串等,這個(gè)過程稱為詞法分析


什么叫語法分析呢巴席?語法分析在詞法分析之后疼进,它主要是驗(yàn)證語法是否正確。在詞法的基礎(chǔ)之上把單詞序號合成語法短語信殊,如程序炬称,表達(dá)式等,然后將所有的節(jié)點(diǎn)組成語法樹(AST)涡拘。它主要分析程序在結(jié)構(gòu)上是否正確玲躯。
終端輸入clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
輸出結(jié)果如下圖

生成IR(intermediate representation)

完成上述步驟代碼生成器會將語法樹自上到下逐步翻譯成IR代碼。
終端輸入clang -S -fobjc-arc -emit-llvm main.m可以查看IR代碼
執(zhí)行完成后可以發(fā)現(xiàn)目錄下生成了一個(gè).ll的文件


oc代碼在這一步會進(jìn)行runtime的橋接鳄乏,property合成跷车,ARC處理

  • IR的基本語法
    @:全局標(biāo)識
    %:????????局部標(biāo)識
    alloca:????????開辟內(nèi)存空間
    align: ????????內(nèi)存對齊
    i32:32個(gè)??bit??,4個(gè)字節(jié)
    store:????????寫入內(nèi)存
    load:讀取數(shù)據(jù)
    call:調(diào)用函數(shù)
    ret:????返回

IR的優(yōu)化

LLVM的優(yōu)化級別分別是-O0 橱野、-O1朽缴、-O2、-O3水援、-Os
終端指令clang -Os -S -fobjc-arc -emit-llvm main.m -o main.ll

bitCode

開啟bitcode后xcode會對代碼進(jìn)一步優(yōu)化密强,并生成.bc的中間代碼。
終端指令clang -emit-llvm -c main.ll -o main.bc可以優(yōu)化IR代碼生成.bc代碼

生成匯編代碼

終端指令clang -S -fobjc-arc main.bc -o main.sclang -S -fobjc-arc main.ll -o main.s 可以將將.bc或者.ll代碼生成匯編代碼蜗元。當(dāng)然生成的匯編代碼也可以通過終端指令clang -Os -S -fobjc-arc main.m -o main.s進(jìn)一步優(yōu)化

生成目標(biāo)文件

目標(biāo)文件的生成或渤,是由匯編器以匯編代碼作為輸入,將匯編代碼轉(zhuǎn)化成機(jī)器代碼奕扣,最后輸出成目標(biāo)文件薪鹦。
終端指令clang -fmodules -c main.s -o main.o可以將匯編文件輸出成目標(biāo)文件。
main.o文件中的符號可以通過nm命令查看
終端指令xcrun nm -nm main.o


undefined: ????????????????????????????表示在當(dāng)前文件暫時(shí)找不到符號_printf成畦。
external:表示這個(gè)符號外部可以訪問距芬。

生成可執(zhí)行文件

連接器最終將編譯生成的.o文件和.dylib.a文件,生成mach-o文件循帐。
終端指令clang main.o -o main
同理我們也可以通過nm查看鏈接之后的可執(zhí)行文件的符號框仔。
終端指令xcrun nm -nm main

總結(jié)

  • 編譯流程:
    輸入代碼->展開預(yù)處理->詞法分析(token)->語法分析 ->生成IR ->IR優(yōu)化 ->生成匯編代碼 ->生成目標(biāo)文件 ->鏈接動靜態(tài)庫生成可執(zhí)行文件。
  • typedef:不做預(yù)處理拄养,不是預(yù)處理指令离斩。
  • 優(yōu)化等級不是越高越好银舱,太高會把有用代碼優(yōu)化掉。
  • .o文件不能執(zhí)行跛梗,需要鏈接外部庫寻馏,鏈接只是打標(biāo)記。
  • LLVM優(yōu)點(diǎn):前后端分離核偿,擴(kuò)展性非常強(qiáng)诚欠。
  • LLVM會影響編譯速度,優(yōu)化可執(zhí)行文件可以提高編譯速度漾岳。
  • 不同的節(jié)點(diǎn)上轰绵,還能進(jìn)行優(yōu)化。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末液样,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鞭莽,更是在濱河造成了極大的恐慌撮抓,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乖酬,死亡現(xiàn)場離奇詭異,居然都是意外死亡县昂,警方通過查閱死者的電腦和手機(jī)倒彰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痴晦,“玉大人誊酌,你說我怎么就攤上這事。” “怎么了猾骡?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嫂便。 經(jīng)常有香客問我,道長厂画,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮欲虚,結(jié)果婚禮上绝页,老公的妹妹穿的比我還像新娘。我一直安慰自己酷鸦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布丁寄。 她就那樣靜靜地躺著盛正,像睡著了一般。 火紅的嫁衣襯著肌膚如雪续崖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天莺丑,我揣著相機(jī)與錄音著蟹,去河邊找鬼萧豆。 笑死昏名,一個(gè)胖子當(dāng)著我的面吹牛样刷,可吹牛的內(nèi)容都是我干的蜓竹。 我是一名探鬼主播蛛碌,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聂喇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤彤路,失蹤者是張志新(化名)和其女友劉穎秕硝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洲尊,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡远豺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坞嘀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躯护。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丽涩,靈堂內(nèi)的尸體忽然破棺而出棺滞,到底是詐尸還是另有隱情,我是刑警寧澤矢渊,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布继准,位于F島的核電站,受9級特大地震影響矮男,放射性物質(zhì)發(fā)生泄漏移必。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一毡鉴、第九天 我趴在偏房一處隱蔽的房頂上張望崔泵。 院中可真熱鬧秒赤,春花似錦、人聲如沸憎瘸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽含思。三九已至崎弃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間含潘,已是汗流浹背饲做。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遏弱,地道東北人盆均。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像漱逸,于是被迫代替她去往敵國和親泪姨。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容