###### tags: `共筆` # [共筆] 不深不淺,帶你認識 LLVM :::info 請留下你的問題,課中我將直接回答你,課後我也可以使用文字的方式給與回覆。如果你分享會結束後,你仍然有些問題想一起討論也可以寫email給我或直接寫在共筆,再一起尋找答案吧! Douglas Chen <dougpuob@gmail.com> ::: --- ## 簡報 - **[共筆] 不深不淺,帶你認識 LLVM (此份文件)** http://bit.ly/369THkW - **[簡報]不深不淺,帶你認識 LLVM (Found LLVM in your life)** http://bit.ly/344wjTP --- ## 提議與建議 1. OOOOO 1. OOOOO 1. OOOOO --- ## 問題 Q&A (新問題置上) --- ## 問題 Q&A (2020/01/14 @可可頭) **● 我有剛問題,我的問題是 ...** **●在iPad上實現MacOS VM的可能性如何?** >你的意思是在 iPad 上也來一個 Parallels(VM) 嗎? >如果是的話: >iPad 的 CPU 使用了 ARM based 的 CPU,Linux 上 QEMU 支援能執行在 ARM (qemu-system-arm) 的版本,所以應該是有機會。 >但私心認為實用性不大,因為 iPad 畢境屬於 mobile device,長效省電是產品的主軸,所以這樣子的應用應該是不會出現。 >[name=dougpuob][color=#c9e4ff][time=20200122] @CocoaHeads > **● 我發現有錯誤,錯誤是 ...** **●演講時interpreter的發音應該在第二個音節。** >看到你的留言我自己又讀了幾次,我也發現我放在第三個音節,感謝糾正。如果有其它發現,還請不用客氣。 >[name=dougpuob][color=#c9e4ff][time=20200122] @CocoaHeads > --- ## 問題 Q&A (2019/12/18 @系統貓) **● LLVM 跟 Clang 的關係是?** > Clang 是 LLVM 的 frontend。 > 簡單的說如果我編譯 sample.c 程式,使用 gcc 我會使用 `gcc sample.c`;使用 LLVM 我會這樣子下指令 `clang sample.c`。 >[name=dougpuob][color=#c9e4ff][time=20191217] @系統貓 **● JIT 重複使用所產生的機器碼是以怎樣的區塊為單位?function?block?statement?您提到可以從llvm程式碼裡找到答案,能否告知在哪個檔案或模組?** > > 從LLVM的JIT的範例,使用者的應用時,其中每一個branch都需要拆分開(eg.if-else就有兩個branch)為llvm::BasicBlock class,這兩個branchs需要由llvm::BranchInst選擇需要的條件式。接著,會透過llvm::Function class組合為函式,最後用透ExecutionEngine執行該函式。 > > 您可能想接著問,如果有重覆內容的llvm::Function instances,或是LLVM實際執行JIT的方式。我目前還沒研究到那裡。 > >[name=dougpuob][color=#c9e4ff][time=20191217] > 另外,我說明的方式可能會讓大家把 QEMU's TCG 與 LLVM JIT 當成是同一件事。 > 我試著把這個問題分成兩個問題,如果理解錯誤再讓我知道,其它延伸問題也歡迎: > > 1. LLVM 的 JIT 如何以「區塊為單位」,它的相關程式碼? > 2. QEMU 的 TCG 如何以「區塊為單位」,它的相關程式碼? > >[name=dougpuob][color=#c9e4ff][time=20191217] >我想這個問題是想問以「什麼」區塊為單位,是function,BB,statement?而不是問如何「以區塊為單位」。 >[name=mshockwave][color=#c9e4ff][time=20191220] > Hi `mshockwave` , > 謝謝提醒,原本想直接將問題引到程式碼,能更清楚。 >[name=dougpuob][color=#c9e4ff][time=20191222] **● LLVM 的 JIT 如何以「區塊為單位」,它的相關程式碼?** > LLVM專案中的範例程式`llvm/examples/Fibonacci/fibonacci.cpp` 中試使用MCJIT實作 fibonacci函式,如下: > ```cpp > int fib(int x) { > if(x<=2) return 1; > return fib(x-1)+fib(x-2); > } > ``` > 將fibonacci函式寫成JIT的版本,有興趣可以直接在 GitHub 上閱讀程式碼[fibonacci.cpp](https://github.com/llvm-mirror/llvm/blob/master/examples/Fibonacci/fibonacci.cpp),看過後應該會比較有感覺。另一個方式是,期侍我下一次的 presentation。 >[name=dougpuob][color=#c9e4ff][time=20191217] >值得一提的是MCJIT,LLVM舊的JIT,一次就會把整個Module都編譯完成。所以假設你的Module有10個function,就算你只有用到其中的一個function,它還是會編譯其他9個、浪費不少資源。LLVM的現役JIT,OrcJIT,就可以解決這個問題。 >[name=mshockwave][color=#c9e4ff][time=20191220] > Hi `mshockwave` 感謝補充。 >[name=dougpuob][color=#c9e4ff][time=20191222] **● QEMU 的 TCG 如何以「區塊為單位」,它的相關程式碼?** > 這是我之前 survey 時留下的筆記,如果有理解錯誤的部份再麻煩跟我說一聲。 > > TCG會動態將guest assembly code生成為host CPU的assembly code。轉換過的assembly code稱為translated block(TB)存放在記憶體中,其中為這段程式碼產生一個hash,下次要使用時就不需要轉換,直接取出使用。 > > 而TB是以 Function 或是 Branch Block 為單位,以我初淺的瞭解它不是Function也不是Branch Block,因為轉換與執行的都是QEMU本身,所以它TB為單位執行時直接執行`static_code_gen_buffer`裡的assembly code。其中轉換的函式是`tb_gen_code` `tcb_gen_code`、執行使用到的函式是`tcg_qemu_tb_exec`。希望這樣子的回內容能回覆到您的疑惑。 > > 下面是幾個函式的位置,方便查找: > 1. ./accel/tcg/cpu-exec.c!cpu_exec() > 1. ./accel/tcg/cpu-exec.c!tb_find() > 1. ./accel/tcg/cpu-exec.c!tb_htable_lookup() > 1. ./accel/tcg/translate-all.c!tb_gen_code() > > ```cpp > /** > * DisasJumpType: > * @DISAS_NEXT: Next instruction in program order. > * @DISAS_TOO_MANY: Too many instructions translated. > * @DISAS_NORETURN: Following code is dead. > * @DISAS_TARGET_*: Start of target-specific conditions. > * > * What instruction to disassemble next. > */ > typedef enum DisasJumpType { > DISAS_NEXT, > DISAS_TOO_MANY, > DISAS_NORETURN, > } DisasJumpType; > > cpu_exec() > { > tb_find() > { > tb = tb_htable_lookup(); // <-- 詢找已轉換過的TB。 > if (likely(tb == NULL)) { > tb = tb_gen_code(); // <-- 執行DBT。 > } > cpu_tb_exec(cpu, tb); // <-- 執行該TB。 > } > } > > tb_gen_code() > { > tcg_func_start(); > gen_intermediate_code() // <-- 不同的CPU會有各自的實作(接下來的函式也會有)。 > { > translator_loop() > { > gen_tb_start(); > ops->tb_start(); > > while(true) > { > // 這裡開始真正的轉換,其中 > // db->is_jmp 不是 DISAS_NEXT 時會停止TB,也是TB結束點。 > db->num_insns++; > ops->insn_start(); > ops->translate_insn(); > } > ops->tb_stop(); > gen_tb_end(); > } > } > } > ``` >[name=dougpuob][color=#c9e4ff][time=20191217] **● 你剛剛提到目前 LLVM 還沒有辦法編譯 Linux kernel,那 LLVM 目前有這打算嗎?** > 這題感謝會後跟我分享的朋友,他提到目前 LLVM 9.0 已經可以編譯 Linux Kernel (x86)。應該是這則新聞,[AMD/Intel Benchmarks: Building The Mainline Linux x86_64 Kernel With LLVM Clang](https://www.phoronix.com/scan.php?page=article&item=clang-linux-53&num=1)。 >[name=dougpuob][color=#c9e4ff][time=20191220] **● 有些程式語言在 LLVM IR 之上又有另一種 IR 的目的是?** :::info 這是現場Q&A的問題 - Li Kuanting: 是這篇google發表的簡報 主題是MLIR (https://llvm.org/devmtg/2019-04/slides/Keynote-ShpeismanLattner-MLIR.pdf) ::: > 巷子裡的專案 Poga Po 大大的回覆: >![](https://i.imgur.com/Sa9OZBY.png) > 因為有些語言需要的 optimization 或是 type checking 不容易在 LLVM IR 上做,像是檢查 tensor shape 或是 rust 的 affine types。MLIR 讓人能針對特殊需求設計 IR Dialects,省掉各自維護 IR 的重複工作 >[name=dougpuob][color=#c9e4ff][time=20191217] --- ## 問題 Q&A (2019/10/17 @TFC,Monospace) **● Slide 41 這張投影片裡面出現的 "0x12345678" 是 object 裡各 symbol 的記憶體位址?** >![Uploading file..._8pxdd1gfh](https://i.imgur.com/AhaZXS3.png) > > 從`createPointerRepresentation()`函式看的出來它將出錯的pointer指到的記憶體位置為輸入,再以hex string為輸出。而呼叫此函式時帶的pointer是 `class`,所以這個16進制的數值應該是一個 class object address。 > **createPointerRepresentation()** > - `clang/lib/AST/JSONNodeDumper.cpp!std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr)` > - 上面這個函式的位置。(https://github.com/llvm/llvm-project/blob/27c7a9b157555e53fb3887e87a492f74fa8bcc56/clang/lib/AST/JSONNodeDumper.cpp#L259) > >[name=dougpuob][color=#c9e4ff][time=20191027] @TFC **● 如果有些很舊的語言像傳統VB寫的程式,也可以透過LLVM轉成成WebAssembly嗎?** > 應該是不行,我想的到的幾個原因: > 1. 我目前還沒有聽說Clang(LLVM's frontend)有支援VB。 > 2. 就算有Clang支援了VB,但VB在link-time/run-time時需要的libraries也是個問題。 > >[name=dougpuob][color=#c9e4ff][time=20191027] @TFC **● Clang 目前不能 build 整個Linux kernel ?** > 看起來目前應該還是努力進行中的事項。 > > 1. 這份slide提到使用Clang build Linux kernel 會遇到那些問題 > Switching a Linux distribution’s main toolchain to LLVM/Clang > (https://llvm.org/devmtg/2019-04/slides/TechTalk-Rosenkranzer-Switching_a_Linux_distro.pdf) > > 2. 這份slide是FOSDEM 2019其中一場在討論這個主題的presentation,看起來目前已經達成的有下面這張圖的幾項。 > ![Uploading file..._lovobmqk9](https://i.imgur.com/69ENJK2.png) Compiling the Linux kernel with LLVM tools([Slides](https://archive.fosdem.org/2019/schedule/event/llvm_kernel/attachments/slides/3330/export/events/attachments/llvm_kernel/slides/3330/clang_linux_fosdem_19.pdf)/[Video](http://mirroronet.pl/pub/mirrors/video.fosdem.org/2019/K.4.201/llvm_kernel.webm)) > > [name=dougpuob][color=#c9e4ff][time=20191027] @TFC --- ## 錯誤修正 **● 4x 頁的投影篇標題有拼錯字->optimization** > 感謝,已更正。 >[name=dougpuob][color=#c9e4ff][time=20191027] @TFC --- ## 資源 1. emscripten: C++ to WebAssembly 1. [**MLIR 影/投影片**](https://llvm.org/devmtg/2019-04/talks.html) 1. [**Ignition: An Interpreter for V8**](https://docs.google.com/presentation/d/1OqjVqRhtwlKeKfvMdX6HaCIu9wpZsrzqpIVIwQSuiXQ/edit) 1. [**Clang vs Other Open Source Compilers**](https://clang.llvm.org/comparison.html) LLVM 官網上比較 Clang 與其它 compilers 的優缺點。 1. [**Clang supports many language extensions**](https://clang.llvm.org/docs/LanguageExtensions.html) 1. [**20190415-開源教-教我正確選擇軟體授權**](https://www.youtube.com/watch?v=raHdvb8y_-Q&t=714s) 主講者,林誠夏 (Lucien Lin) 是我聽過把 Open Source License 講的最好的講者之一,非常值得一看的影片。 > GPL, AGPL, LGPL, MIT, BSD... 各種複雜的軟體授權條款,是大部分人在利用開源的軟體套件的時候會遇到的棘手問題。到底用了哪些授權方式的軟體、套件,或是用了開源的資料庫,會如何影響到我本來想要選擇的授權方式呢?我又應該要選擇哪一種授權方式,才能符合我心中希望這軟體被流通應用的方式? > > 「開源教教我正確選擇軟體授權」第一堂課程,特地請到長年研究開源科技法律授權的林誠夏法制顧問,深入淺出介紹各種開源授權方式,並透過實例的操作,分析已經用了很多套件的開源軟體,如何選擇合適的授權。絕對保證能夠幫各位從頭根治到腳,通體舒暢從此不再煩惱授權!千萬不要錯過這次的分享! 7. [**Diablo 1 for web browsers**](https://github.com/d07RiV/diabloweb) WebAssembly 的例子