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)。找到所有可以用谓词替换这种比较的地方。此外,对于许多常见的比较,还没有谓词。看看哪些值得添加谓词,并添加它们。你可以在邮件列表存档中找到许多建议。