跳轉到內容

GNU C 編譯器內部/風格技巧 4 1

來自華夏公益教科書,為開放世界而開放的書籍

這些練習來自 http://gcc.gnu.org/projects/beginner.html

拆分龐大的原始碼檔案

[編輯 | 編輯原始碼]

並不難。注意檔案範圍內的全域性變數。建議的目標

大檔案
檔案大小 檔名
494K java/parse.y
413K combine.c
408K dwarf2out.c
375K cp/pt.c
367K fold-const.c
356K loop.c

還有幾個其他檔案的大小在這個範圍內,我沒有列出來,因為修改它們是不可取的(例如,reload,Fortran 前端)。你可以嘗試,但我對由此可能造成的任何理智損傷概不負責。

拆分龐大的函式

[編輯 | 編輯原始碼]

這與上面的拆分檔案類似,但難度更大,因為你需要注意不要改變任何語義。一般來說,你需要將獨立的程式碼塊提取到它們自己的函式中。任何頭部有半打區域性變數宣告的內部程式碼塊都是一個不錯的候選者。但是,要注意那些區域性變數在外部迴圈迭代之間傳遞資訊的地方!

更謹慎地,你可能能夠找到一些地方,整個程式碼塊在大型函式之間重複(可能略有不同),並將它們分解出來。

拆分龐大的條件語句

[編輯 | 編輯原始碼]

難度更大,因為你可能無法確定條件測試,更不可能知道它是否應該測試。但如果你能做到,絕對值得付出努力。一個我們想要改變的示例

if (mode1 == VOIDmode
    || GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
    || (modifier != EXPAND_CONST_ADDRESS
        && modifier != EXPAND_INITIALIZER
        && ((mode1 != BLKmode && ! direct_load[(int) mode1]
             && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
             && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
            /* If the field isn't aligned enough to fetch as a memref,
               fetch it as a bit field.  */
            || (mode1 != BLKmode  
                && SLOW_UNALIGNED_ACCESS (mode1, alignment)
                && ((TYPE_ALIGN (TREE_TYPE (tem))
                     < GET_MODE_ALIGNMENT (mode))
                    || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)))
            /* If the type and the field are a constant size and the
               size of the type isn't the same size as the bitfield,
               we must use bitfield operations.  */
            || ((bitsize >= 0
                 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (exp)))
                     == INTEGER_CST)
                 && 0 != compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)),
                                           bitsize[check spelling])))))
    || (modifier != EXPAND_CONST_ADDRESS
        && modifier != EXPAND_INITIALIZER
        && mode == BLKmode
        && SLOW_UNALIGNED_ACCESS (mode, alignment)
        && (TYPE_ALIGN (type) > alignment
            || bitpos % TYPE_ALIGN (type) != 0)))
  {

刪除垃圾程式碼

[編輯 | 編輯原始碼]

多年來一直存在的 #if 0 程式碼塊、未使用的函式、未使用的整個檔案、失效的配置、失效的 Makefile 邏輯、失效的 RTL 和樹形式,等等等等。根據它的具體情況,可能不清楚它是否是垃圾程式碼。先從容易的部分開始。

對 RTL 物件使用謂詞

[編輯 | 編輯原始碼]

GCC 有簡單的謂詞,用來判斷給定的 rtx 是否屬於某個特定類。這些謂詞只檢視給定 RTL 物件的 rtx_code,如果謂詞為真則返回非零值。例如,如果 rtx 表示一個暫存器,那麼 REG_P (rtx) 為非零值。

不幸的是,中間端和後端的很多程式碼都沒有使用這些謂詞,而是直接比較 rtx_code:(GET_CODE (rtx) == REG)。找到所有可以用謂詞替換這種比較的地方。此外,對於許多常見的比較,還沒有謂詞。看看哪些值得新增謂詞,並新增它們。你可以在郵件列表存檔中找到許多建議。

華夏公益教科書