共筆
請留下你的問題,課中我將直接回答你,課後我也可以使用文字的方式給與回覆。如果你分享會結束後,你仍然有些問題想一起討論也可以寫email給我或直接寫在共筆,再一起尋找答案吧!
Douglas Chen dougpuob@gmail.com
[共筆] 不深不淺,帶你認識 LLVM (此份文件)
http://bit.ly/369THkW
[簡報]不深不淺,帶你認識 LLVM (Found LLVM in your life)
http://bit.ly/344wjTP
● 我有剛問題,我的問題是 …
●在iPad上實現MacOS VM的可能性如何?
你的意思是在 iPad 上也來一個 Parallels(VM) 嗎?
如果是的話:
iPad 的 CPU 使用了 ARM based 的 CPU,Linux 上 QEMU 支援能執行在 ARM (qemu-system-arm) 的版本,所以應該是有機會。
但私心認為實用性不大,因為 iPad 畢境屬於 mobile device,長效省電是產品的主軸,所以這樣子的應用應該是不會出現。
dougpuob20200122 @CocoaHeads
● 我發現有錯誤,錯誤是 …
●演講時interpreter的發音應該在第二個音節。
看到你的留言我自己又讀了幾次,我也發現我放在第三個音節,感謝糾正。如果有其它發現,還請不用客氣。
dougpuob20200122 @CocoaHeads
● LLVM 跟 Clang 的關係是?
Clang 是 LLVM 的 frontend。
簡單的說如果我編譯 sample.c 程式,使用 gcc 我會使用gcc sample.c
;使用 LLVM 我會這樣子下指令clang sample.c
。
dougpuob20191217 @系統貓
● 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的方式。我目前還沒研究到那裡。 >
dougpuob20191217
另外,我說明的方式可能會讓大家把 QEMU's TCG 與 LLVM JIT 當成是同一件事。
我試著把這個問題分成兩個問題,如果理解錯誤再讓我知道,其它延伸問題也歡迎:
- LLVM 的 JIT 如何以「區塊為單位」,它的相關程式碼?
- QEMU 的 TCG 如何以「區塊為單位」,它的相關程式碼?
dougpuob20191217
我想這個問題是想問以「什麼」區塊為單位,是function,BB,statement?而不是問如何「以區塊為單位」。
mshockwave20191220
Hi
mshockwave
,
謝謝提醒,原本想直接將問題引到程式碼,能更清楚。
dougpuob20191222
● LLVM 的 JIT 如何以「區塊為單位」,它的相關程式碼?
LLVM專案中的範例程式
llvm/examples/Fibonacci/fibonacci.cpp
中試使用MCJIT實作 fibonacci函式,如下:int fib(int x) { if(x<=2) return 1; return fib(x-1)+fib(x-2); }
將fibonacci函式寫成JIT的版本,有興趣可以直接在 GitHub 上閱讀程式碼fibonacci.cpp,看過後應該會比較有感覺。另一個方式是,期侍我下一次的 presentation。
dougpuob20191217
值得一提的是MCJIT,LLVM舊的JIT,一次就會把整個Module都編譯完成。所以假設你的Module有10個function,就算你只有用到其中的一個function,它還是會編譯其他9個、浪費不少資源。LLVM的現役JIT,OrcJIT,就可以解決這個問題。
mshockwave20191220
Hi
mshockwave
感謝補充。
dougpuob20191222
● 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
。希望這樣子的回內容能回覆到您的疑惑。下面是幾個函式的位置,方便查找:
- ./accel/tcg/cpu-exec.c!cpu_exec()
- ./accel/tcg/cpu-exec.c!tb_find()
- ./accel/tcg/cpu-exec.c!tb_htable_lookup()
- ./accel/tcg/translate-all.c!tb_gen_code()
/** * 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(); } } }
dougpuob20191217
● 你剛剛提到目前 LLVM 還沒有辦法編譯 Linux kernel,那 LLVM 目前有這打算嗎?
這題感謝會後跟我分享的朋友,他提到目前 LLVM 9.0 已經可以編譯 Linux Kernel (x86)。應該是這則新聞,AMD/Intel Benchmarks: Building The Mainline Linux x86_64 Kernel With LLVM Clang。
dougpuob20191220
https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.7-Kbuild-Easier-LLVM
dougpuob20200413
● 有些程式語言在 LLVM IR 之上又有另一種 IR 的目的是?
這是現場Q&A的問題
巷子裡的專案 Poga Po 大大的回覆:
因為有些語言需要的 optimization 或是 type checking 不容易在 LLVM IR 上做,像是檢查 tensor shape 或是 rust 的 affine types。MLIR 讓人能針對特殊需求設計 IR Dialects,省掉各自維護 IR 的重複工作
dougpuob20191217
● Slide 41 這張投影片裡面出現的 "0x12345678" 是 object 裡各 symbol 的記憶體位址?
從
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)
dougpuob20191027 @TFC
● 如果有些很舊的語言像傳統VB寫的程式,也可以透過LLVM轉成成WebAssembly嗎?
應該是不行,我想的到的幾個原因:
- 我目前還沒有聽說Clang(LLVM's frontend)有支援VB。
- 就算有Clang支援了VB,但VB在link-time/run-time時需要的libraries也是個問題。
dougpuob20191027 @TFC
● Clang 目前不能 build 整個Linux kernel ?
看起來目前應該還是努力進行中的事項。
這份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)這份slide是FOSDEM 2019其中一場在討論這個主題的presentation,看起來目前已經達成的有下面這張圖的幾項。
Compiling the Linux kernel with LLVM tools(Slides/Video)dougpuob20191027 @TFC
● 4x 頁的投影篇標題有拼錯字->optimization
感謝,已更正。
dougpuob20191027 @TFC
emscripten: C++ to WebAssembly
Clang vs Other Open Source Compilers
LLVM 官網上比較 Clang 與其它 compilers 的優缺點。
20190415-開源教-教我正確選擇軟體授權
主講者,林誠夏 (Lucien Lin) 是我聽過把 Open Source License 講的最好的講者之一,非常值得一看的影片。
GPL, AGPL, LGPL, MIT, BSD… 各種複雜的軟體授權條款,是大部分人在利用開源的軟體套件的時候會遇到的棘手問題。到底用了哪些授權方式的軟體、套件,或是用了開源的資料庫,會如何影響到我本來想要選擇的授權方式呢?我又應該要選擇哪一種授權方式,才能符合我心中希望這軟體被流通應用的方式?
「開源教教我正確選擇軟體授權」第一堂課程,特地請到長年研究開源科技法律授權的林誠夏法制顧問,深入淺出介紹各種開源授權方式,並透過實例的操作,分析已經用了很多套件的開源軟體,如何選擇合適的授權。絕對保證能夠幫各位從頭根治到腳,通體舒暢從此不再煩惱授權!千萬不要錯過這次的分享!
Diablo 1 for web browsers
WebAssembly 的例子