feicong@llvm
頻道首先介紹一下這個頻道。爲何想要開這樣一個頻道,由於國內有關llvm
的資料實在是太缺少了,缺少到什麼程度,沒有一本(中文)圖書是講llvm
的,網上能夠蒐集到的資料也很是的少,要麼就都是高深莫測,不適合新手入門,或者晦澀難懂的機器翻譯,佶屈聱牙,恍若天書。html
另外一方面,如今已經全面進入了移動互聯網時代,移動App的普及,帶來的App安全保護和加固方面的需求也愈發強烈,安全從業人員與黑產的對抗早已上升到編譯器層面,Native
級別的花指令、字符串混淆和控制流混淆、虛擬機等加固等產品的出現,爲廠商保護本身的知識產權,提升產品的安全級別,提升被破解的難度和成本,作出了不可磨滅的貢獻。前端
更況且如今都8102
年了,移動戰略那都是明日黃花,市面上最火熱的已是大數據
、人工智能
和NPU
了。在人工智能算法陷入性能瓶頸,你們都在思考如何將硬件的特性發揮到極致的今天,在編譯器算法的研究上花點功夫,提升軟硬件協同工做的性能,是從此將來芯片廠商所要關注的一個重點。這也是爲何高通、英特爾、ARM、華爲等芯片公司長期佔據着llvm
基金會贊助商榜首的緣由。算法
昨天碰巧看到知乎大神藍色剛剛出爐的一篇文章《手把手帶你遨遊TVM》(固然他也是llvm
堅決地擁護者,寫了不少llvm
的文章 ),介紹了多種AI
訓練框架Training
以後的結果在不一樣硬件上的Inference
問題,如Intel CPU / Intel GPU / ARM CPU / ARM GPU / NV GPU / FPGA / AI
芯片等,而要在這多種多樣的設備中都保持一個高效的Inference性能,實際上是一件頗有挑戰的事情,這裏面就涉及到了軟硬件結合的問題,自古就是各類性能優化關注的重點問題。macos
讓咱們回到主題上來,編譯器技術如此重要,國內資料卻如此缺少。資料基本上全是英語,《編譯原理》自己也是一門CS
專業須要到大三才會開始授學的專業課。並且說實話,國內的編譯原理的教育能夠說是很是失敗的,學生上完課跟沒上一個樣的狀況很是多,可能也跟連老師都沒有動手操做過一個編譯器有關。學生若是想要切實的學點知識的話,又面臨着資料匱乏的問題,惡性循環,如此往復。後端
因此迫切須要有人來打破這個僵局,這也是我作這個頻道的初衷,但願能夠憑藉咱們你們的力量,將feicong@llvm
這個圈子作好、運營好、運轉好。我將在這個方向上持續地投入時間和精力,也但願你們能夠支持我,加入到圈子中來,一塊兒學習和討論llvm
知識。編譯器是一門很是底層的技術,無論您是作科研、仍是作框架,作開發、仍是作安全,在編譯器方向有所建樹會爲您的簡歷增光很多,評級評優也好,升職跳槽也好,會這門「手藝」都很是吃香,想象一下HR或者CTO或者技術leader拿着您的簡歷,上面寫着「熟悉llvm
編譯器及編譯原理」的場景,hold住二面現場從未如此簡單。xcode
這將是你這麼多年來,花的最值的五十塊錢!!安全
或者歡迎加個人微信(ID:fe1c0ng)或微博(id:非蟲)性能優化
咱們將會從實際的操做和代碼的角度出發,對如下主題進行剖析。bash
將來也打算開一些線下meetup和現場教學,固然圈內的你確定是享有優先體驗權!還在等什麼?趕忙拿起微信掃一掃吧!微信
llvm
概論LLVM
項目的起源也是來源於Chris Lattner
我的對編譯器的興趣,這種模式在歐美很是廣泛,好比Linux
的誕生就是,當時仍是大二學生的大嘴巴託瓦茲我的想要從新造一個*nix
內核,結果一大堆人在羣裏討論得津津有味,而後你們紛紛建言獻策。說明對kernel
感興趣的人特別多,羣衆基礎纔是大基礎,羣衆路線纔是XXXXX,(此處省略馬哲課文獻100頁)。
一樣,不少大學生學完編譯原理(Complier Principles Technology & Tools
,龍書)以後,滿身才華沒有用武之地,(這渾身按耐不住的查克拉,是什麼感受。。。)因此想要找點相似的事情幹,知足一下本身的好奇心,在老外眼裏叫作 「hack something」 ,固然這種文化在中國是沒有的,paper
、建模和導師是壓在莘莘學子身上不斷摩擦的三座大山。
愈來愈多的人提出了一大堆建議,而且還貢獻了一堆代碼,對於歪果仁來講,你這裏作的不對,不指正你一下,是很難受的一件事情。因此越日後這個項目愈來愈大,bug
也愈來愈少,可用性愈來愈強,而後不少商業機構看到這裏這個編譯器實現的挺好的嘛,並且仍是開源的,咱們也是魯迅「拿來主義」的堅決奉行者,來來來,新來的大家仨,週末回家帶上筆記本哈~下週一咱們就決定 "All IN" LLVM
!
其實在硅谷,不少高科技公司的創始人,原本就是學校的老師或教授。教授手下有幾家科技企業,簡直是硅谷教授的標配。教授看到愈來愈多的公司,在項目中使用LLVM
編譯器,巧了立刻又要教龍書了(這本書封面是一批Dragon)(PS:外國文化的Dragon
和中國龍不是一個物種)(龍書從1982年出版到如今,已經36年了,教授每一年都要教),教授內心想,教泥煤的教,龍書本身去看,咱們來聊聊LLVM
!這纔是8102
年編譯器該有的模樣!
學生們原本就頭很大,龍書裏其實啥都有,也啥都沒有,之前只能啃啃GNU
的gcc
,gcc的歷史跟龍書同樣悠久,那代碼讀起來那個酸爽,就跟老奶奶的裹腳布同樣,同窗們看一次吐一次。要不是由於其餘沒得選,開源的(貌似)就它一個!並且使用最普遍的也是它。儘管如此,終年累月積累下來的架構的更迭和設計的混亂,沒個教授或者博士的經驗,根本讀起來都費勁。
那難道就沒有一個現代一點的編譯器了麼?有,那就是llvm!
跟gcc比起來,llvm算是一個「人寫的」、「給人看的」編譯器。llvm清爽、乾淨、模塊化,gcc用的是單體結構,這玩意兒已經不適合現代人來閱讀了。llvm用的C++
,gcc用的c,哪一個更現代化一目瞭然。學生們很是歡迎llvm,經過學習llvm來理解編譯原理每每事半功倍,倍兒輕鬆,用起來也駕輕就熟,這纔是llvm得以普及和迅速擴大影響的關鍵!llvm在學術界的成功能夠說是實踐與理論之間差距不斷縮小的結果。
後來學生們走上了社會,好比去蘋果公司上班了,固然仍是繼續使用llvm編譯器,這時候就涉及到了許可證的問題。gcc用的是GPL許可證,GPL是有名的病毒協議,一日GPL,終身GPL,你用了它的做品,你本身也得免費開源,那我還用你個毛,我產品都送你好了。這在商業環境下是不可能的,而llvm本身的協議,幾乎就是Do What The Fuck You Want To Do Lisence,你能夠do what the fuck you want to do
,惟一的要求就是別忘了提一下他們的LLVM lisence
。
在先進的「WTFPL」 license幫助下,產業界迅速地扔掉了gcc,擁抱更加開放的、能夠拿來隨便改的llvm,影響迅速擴大,2012年llvm被授予ACM軟件系統獎,正是對llvm的高度承認。反之因爲產業界的高度認同及其回哺,llvm從學術界的懵懂、迅速成長爲具備工業級穩定性、史無前例的成熟度和極高效率的編譯器。
趣聞:
Chris Latter
原本只是想寫一個底層的虛擬機,這也是LLVM
名字的由來,low level virtual machine
,跟Java
的JVM
虛擬機同樣,但是後來,llvm歷來沒有被用做過虛擬機,哪怕LLVM
的名氣已經傳開了。因此人們決定仍然叫他LLVM
,更多的時候只是看成「商標」同樣的感受在使用,其實它跟虛擬機沒有半毛錢關係。
以C/C++
爲例,LLVM編譯系統包括如下內容:
GCC 4.2解析器
能解析的語言,好比C,C ++,Objective-C,Fortran
等,它都能提供同能能力的支持;另外它還能支持一些GCC的擴展插件。Pass
管理系統,它根據它們的依賴性自動對Pass
(包括分析,轉換和代碼生成Pass)進行排序,並將它們管道化以提升效率。DWARF - Object files and linked products will use DWARF as the debug information format. [dwarf] DWARF with dSYM File - Object files and linked products will use DWARF as the debug information format, and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). [dwarf-with-dsym]
llvm
安裝和編譯咱們聊一下從源碼環境中編譯生成llvm
套件的可執行文件。這種方式對於深刻學習llvm
的讀者來講,是必需要掌握的。
下載源代碼,而後使用編譯工具進行編譯。編譯工具能夠是llvm
,也能夠是gcc
。咱們分別介紹一下。
源代碼在releases.llvm.org/download.ht…官網進行下載:
macOS
:使用llvm
單獨編譯llvm
llvm
與clang
都做爲單獨的組件以開源形式提供,能夠單獨編譯它們,也能夠組全在一塊兒編譯。咱們先來看下,如何單獨編譯llvm
。
執行以下命令,下載與解壓llvm
的源碼。
$ wget http://releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz
--2018-10-23 22:02:46-- http://releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz
正在解析主機 releases.llvm.org (releases.llvm.org)... 151.101.42.49, 2a04:4e42:6::561
正在鏈接 releases.llvm.org (releases.llvm.org)|151.101.42.49|:80... 已鏈接。
已發出 HTTP 請求,正在等待迴應... 302 Found
位置:http://117.143.109.133/cache/releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz?ich_args2=139-23220102015663_6b4dad2fb2c1b96f7fc8786bd843192d_10001002_9c89602cd4c3f2d2973a518939a83798_c6988e40d0518b9e703b7a4f6f4dd23a [跟隨至新的 URL]
--2018-10-23 22:02:47-- http://117.143.109.133/cache/releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz?ich_args2=139-23220102015663_6b4dad2fb2c1b96f7fc8786bd843192d_10001002_9c89602cd4c3f2d2973a518939a83798_c6988e40d0518b9e703b7a4f6f4dd23a
正在鏈接 117.143.109.133:80... 已鏈接。
已發出 HTTP 請求,正在等待迴應... 200 OK
長度:28324368 (27M) [application/octet-stream]
正在保存至: 「llvm-7.0.0.src.tar.xz」
llvm-7.0.0.src.tar.xz 21%[======================> ] 5.86M 1.08MB/s 剩餘 21s
$ tar -xvf llvm-7.0.0.src.tar.xz
複製代碼
注意:編譯不能夠在解壓後的文件夾內部編譯,須要在外部新建一個文件夾,不然編譯會失敗!
執行如下命令,新建mybuilder目錄,並進行編譯配置。
$ mkdir mybuilder
$ cd mybuilder
$ cmake ../llvm-7.0.0.src/
複製代碼
PS:若是沒有
cmake
能夠先用brew install cmake
安裝一下,而後再執行cmake
命令。
而後再執行如下命令開始編譯:
$ cmake --build
複製代碼
而後就開始編譯了。
CPU佔用率一直不高,穩定在比較低的狀態。一直到結束都不高,大概須要一小時左右。
完成以後進來看看:
$ cd bin
$ ls
FileCheck llvm-cat llvm-dwp llvm-modextract llvm-readobj not
bugpoint llvm-cfi-verify llvm-exegesis llvm-mt llvm-rtdyld obj2yaml
count llvm-config llvm-extract llvm-nm llvm-size opt
dsymutil llvm-cov llvm-go llvm-objcopy llvm-special-case-list-fuzzer sancov
llc llvm-cvtres llvm-isel-fuzzer llvm-objdump llvm-split sanstats
lli llvm-cxxdump llvm-lib llvm-opt-fuzzer llvm-stress verify-uselistorder
lli-child-target llvm-cxxfilt llvm-link llvm-opt-report llvm-strings yaml-bench
llvm-PerfectShuffle llvm-demangle-fuzzer llvm-lit llvm-pdbutil llvm-strip yaml2obj
llvm-ar llvm-diff llvm-lto llvm-profdata llvm-symbolizer
llvm-as llvm-dis llvm-lto2 llvm-ranlib llvm-tblgen
llvm-bcanalyzer llvm-dlltool llvm-mc llvm-rc llvm-undname
llvm-c-test llvm-dwarfdump llvm-mca llvm-readelf llvm-xray
$ ./llvm-as -version
LLVM (http://llvm.org/):
LLVM version 7.0.0
DEBUG build with assertions.
Default target: x86_64-apple-darwin16.7.0
Host CPU: broadwell
複製代碼
固然,llvm
後端要配合clang
前端才能使用,clang
前端的編譯方法也跟llvm
相似。
macOS
:使用llvm
混合編譯llvm
&&clang
大部分流程跟上文中macOS
系統下用llvm
編譯過程相似,首先下載llvm
和clang
的源碼包並解壓,把解壓後的clang
的源碼包重命名,並移動到llvm-7.0.0.src/tools/
目錄下,最終效果爲llvm-7.0.0.src/tools/clang/
。
而後在build文件夾裏運行$ cmake -G "Unix Makefiles" ../llvm-7.0.0.src
命令,cmake
會檢查編譯環境,若是沒有報錯(有報錯的解決報錯),直接運行make
命令便可開始編譯。
編譯完成以後,在build/bin/目錄下,便可找到
llvm和
clang`的工具。
$ ls
FileCheck llc llvm-go llvm-size
arcmt-test lli llvm-isel-fuzzer llvm-special-case-list-fuzzer
bugpoint lli-child-target llvm-lib llvm-split
c-arcmt-test llvm-PerfectShuffle llvm-link llvm-stress
c-index-test llvm-ar llvm-lit llvm-strings
clang llvm-as llvm-lto llvm-strip
clang++ llvm-bcanalyzer llvm-lto2 llvm-symbolizer
clang-7 llvm-c-test llvm-mc llvm-tblgen
clang-check llvm-cat llvm-mca llvm-undname
clang-cl llvm-cfi-verify llvm-modextract llvm-xray
clang-cpp llvm-config llvm-mt not
clang-diff llvm-cov llvm-nm obj2yaml
clang-format llvm-cvtres llvm-objcopy opt
clang-func-mapping llvm-cxxdump llvm-objdump sancov
clang-import-test llvm-cxxfilt llvm-opt-fuzzer sanstats
clang-offload-bundler llvm-demangle-fuzzer llvm-opt-report scan-build
clang-refactor llvm-diff llvm-pdbutil scan-view
clang-rename llvm-dis llvm-profdata set-xcode-analyzer
clang-tblgen llvm-dlltool llvm-ranlib verify-uselistorder
count llvm-dwarfdump llvm-rc yaml-bench
diagtool llvm-dwp llvm-readelf yaml2obj
dsymutil llvm-exegesis llvm-readobj
hmaptool llvm-extract llvm-rtdyld
$ ./clang --version
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Users/userid/Desktop/mybuilder/bin/.
複製代碼
第一大部分的瞭解篇已經進入了尾聲,可能後面還會有小的更新,但總體上,通過這幾篇的講解,相信你們對llvm的功能與能力已經有了比較基礎的認知。在後面的上手篇內容當中,咱們將深刻討論llvm的先後端組件及特性,但願你們持續的關注與喜歡。
如下爲了解篇中,前面內容的一個目錄:
到這裏,本篇就結束了!