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 和树形式,等等等等。根据它的具体情况,可能不清楚它是否是垃圾代码。先从容易的部分开始。
GCC 有简单的谓词,用来判断给定的 rtx 是否属于某个特定类。这些谓词只查看给定 RTL 对象的 rtx_code,如果谓词为真则返回非零值。例如,如果 rtx 表示一个寄存器,那么 REG_P (rtx) 为非零值。
不幸的是,中间端和后端的很多代码都没有使用这些谓词,而是直接比较 rtx_code:(GET_CODE (rtx) == REG)。找到所有可以用谓词替换这种比较的地方。此外,对于许多常见的比较,还没有谓词。看看哪些值得添加谓词,并添加它们。你可以在邮件列表存档中找到许多建议。