Hackpads are smart collaborative documents. .

Alexis Li

150 days ago
Unfiled. Edited by Alexis Li 150 days ago
Jim H [ Page 5 ]
Pe S
  • 這邊提到驗證執行檔後並載入動態函式庫,為何要有 C Runtime?
 
Jim H 先想想以下程式的執行: (hello.c)
  • int main() { return 1; }
當你在 GNU/Linux 下編譯和執行後 (`gcc -o hello hello.c ; ./hello`),可用 `echo $?` 來取得程式返回值,也就是 `1`,可是這個返回值總有機制來處理吧?所以你需要一套小程式來作,這就是 C runtime (簡稱 crt)。此外,還有 `atexit` 一類的函式,也需要  C runtime 的介入才能實現。
 
C 語言和一般的程式語言有個很重要的差異,就是 C 語言設計來滿足系統程式的需求,首先是作業系統核心,再來是一系列的工具程式,像是 ls, find, grep 等等,而我們如果忽略指標操作這類幾乎可以直接對應於組合語言的指令的特色,C 語言之所以需要 runtime,有以下幾個地方:
  1. int main() { return 1; } 也就是 main() 結束後,要將 exit code 傳遞給作業系統的程式,這部份會放在 crt0
  1. exception handling,不要懷疑,C 語言當然有這個特徵,只是透過 setjmp 和  longjmp 函式來存取,這需要額外的函式庫 (如 libgcc) 來協助處理 stack
  1. 算術操作,特別在硬體沒有 FPU 時,需要 libgcc 來提供浮點運算協助
 
Jie-Han C
  • C 語言裡面有沒有例外處理?
  • setjmp
  • longjmp
 
佳瑩 林
  • kernel 裡的驗證執行檔步驟,是要驗證什麼?
Jim H
  • UNIX 的「執行檔」有很多種可能,一個是依據特定格式保存的機械碼,也可能是透過額外程式去解析的 shell script,作業系統核心必須得事先解析並確認這個合法的執行檔,才能著手去執行
 
[ Page 16 ]
李昆憶
  • 能夠自己編譯自己原始程式碼的程式: Self-hosting:作為 toolchain 的一部分,可以產生新版同一程式的程式
Jim H
  • 想一個情境,C compiler 的原始程式碼如果用 C 語言撰寫,那要用什麼東西來編譯 C compiler 的原始程式碼呢?如果可以作到這件事,就是所謂的 self-compilation,這不是容易的事,因為編譯器要很可靠才行
  • 要知道一件事,由於電腦發展最初是解決軍事需求,後來則應用到人口普查系統,人們一直都希望電腦可以理解人類的語言,這也是為何早期 (1950 年代) 的程式語言其實很高階的緣故,有透過數學表達的風格 (如 LISP),也有類似英文書寫風格 (如 COBOL)
  • 更有趣的是,就算電腦發展還在真空管的時代,人們就著手研究解析語言學和數學的關聯,這也是為何你在計算理論和編譯器課程 (這兩者是資訊工程系和電機系極少沒有重疊的科目) 會發現一些語言學的跡象
  • 回到編譯器的設計,由於早期硬體限制很多,其實是不可能直接實做出高階語言的編譯器,相反的,早期的工程人員必須漸進地開發相關的工具的程式,所以你可以想像最早人們用機械碼拼湊出簡單的 assembler,然後在這之上發展了簡單的 C compiler,之後再用這個 C compiler 開發出更完整的 C compiler,後者可以編譯更完整的 C 語言程式,然後逐步延展下去。
 
[ Page 31 ]
下圖說明如果沒有 IR 這樣的中間表示法,每個前端 (source files; human readable programming language) 直接對應到後端 (machine code) 的話,有太多種組合,勢必會讓開發量爆增。但如果先讓前端輸出 IR,然後 IR 再接到後端,這樣整體的彈性就大多了
 
[ Page 36 - 38 ]
Charles L
  1. Pointer Aliasing會讓編譯器最佳化功能無用武之地。
  1. 針對下面程式碼
  • void foo(int *i1, int *i2, int *res){
  •     for(int i=0;i<10;i++){
  •         *res += *i1 + *i2;
  •     }
  • }
  • 可能一開始會想優化成下面這樣來加速
  • void foo(int *i1, int *i2, int *res){
  •     int tmp=*i1 + *i2;
  •     for(int i=0;i<10;i++)
  •         *res += tmp;
  •     }
  • }
  • 但若考慮到有人這樣寫 foo(&var, &var, &var) 來呼叫foo(),那很明顯就會發生問題了,*res值的改變影響*i1、*i2。所以Compiler不會這樣最佳化,因為不知道caller會怎麼丟值。
  •  
Jim H [ Page 40 ]
丁羿慈
  • SSA (Static Single Assignment)
  • 每個被Assign的變數只會出現一次
  • 將被Assign的變數給一個版本號碼,再使用∅function 例如: ret3 = ? (ret1, ret2)去判斷從何而來
Jim H
  • SSA 把原本複雜的條件和程式邏輯轉化為 Graph,用讓每個程式邏輯轉成明確的路徑
陳婉雅
  • " The SSA form is based on the premise that program variables are assigned in exactly one location in the program. Multiple assignments to the same variable create new versions of that variable. "
  • SSA 最佳化實例:
  • constant propagation
  • 用法: 
  1. 先拆成 basic blocks (單行的指令, 沒有jump or label)
  1. 合併 basic blocks
  1. 最佳化 CFG (減少 goto )
  1. 轉成 SSA form (變數 runtime decided 時, 用函數表示, 並給新的版本號) . 例: i1 =Φ(i0, i2)
  1. constant propagation (變數換成常數)
  1. dead code elimination (remove 不需要的變數)
  1. value range propagation (變數用一個範圍的常數來代替)
  1. dead code elimination (結果: 直接 return 0)
Jim H 延伸閱讀: Static Single Assignment Form, Kenneth Zadeck (GCC Summit 2004)
 
coldnew [ Page 43 ] GCC 可輸出包含 Basic Block 的CFG
  • gcc -c -fdump-tree-cfg=out test.c
 
[ Page 62] GCC 後端: Register Transfer Language (RTL)
  • LISP-Style Representation  (令人喜愛的 S-Expression :) )
  • 生成 RTL 的方式
  • gcc -fdump-rtl-expand xxx.c
  • RTL Uses Virtual Register
  • GCC Built-in Operation and Arch-defined Operation
  • Instruction scheduling (Pipeline scheduling)
  • Peephole optimizations
 
Jim H [ Page 67 ]
  • 最佳化來自對系統的認知
假設我們有兩個****有號整數***: <stdint.h>
  • int32_t a, b;
然後原本涉及到分支的陳述:
  • if (b < 0) a++;
可更換為沒有分支的版本:
  • a -= b >> 31;
 
[ Page 69 ]
林郁寧
  • Compiler可以砍掉沒人使用的static global variable來節省空間,但是不能砍掉沒人使用的 non-static global variable因為無法確定別的 Compilation Unit 會不會用到此變數
Jim H
  • 這是為何建議 local function 要宣告成 static 的用意!
 
[ Page 71 ]
  • gcc 會把特定的 `printf()` 悄悄換成 `puts()`,這有什麼好處?
  • printf() 本身就是個解譯器,要處理一堆格式,執行時間和字串長度並未完全相符合。但 puts() 就不一樣,只跟何時找到 null terminator 有關,行為明確多了,當然整體執行時間也更短。
 
Jie-Han C
  • 為何GCC算是個Compiler Driver? 在使用上.我們要進行link也是會另外使用ld. gcc也可以當linker嗎?
...

Contact Support



Please check out our How-to Guide and FAQ first to see if your question is already answered! :)

If you have a feature request, please add it to this pad. Thanks!


Log in