###### 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]
![](https://i.imgur.com/gAEa1ol.png)
https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.7-Kbuild-Easier-LLVM
>[name=dougpuob][color=#c9e4ff][time=20200413]
**● 有些程式語言在 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 的例子