mbl*_*ler 7 compiling gcc symbol-table
交叉编译 Linux 内核 3.18.10 时,编译器会.part.<N>
在某些符号的末尾添加后缀(参见下面的示例)。<N>
使用不同的 defconfigs 时,数字会发生变化。有人知道在什么条件下编译器会在符号末尾添加零件后缀吗?
$ arm-none-linux-gnueabi-readelf -a vmlinux | grep do_kernel_fault
给
c03a48f8 116 FUNC LOCAL DEFAULT 2 __do_kernel_fault.part.10
结尾的符号.part
是一个真正的函数符号,而不是某种函数装饰。更准确的说,结尾.part
的函数是GCC从一个更大的函数生成的函数。
有时,GCC 评估一个大函数的控制流的某个部分可以很容易地内联,但内联整个巨大的函数是不行的。因此,它将函数拆分为将大部分放在自己的函数中,该函数接收原始函数名称加.part
+作为名称.<some number>
,并将其余部分内联到其他函数中。
这是 GCC 源代码中描述的优化的一部分,在gcc/ipa-split.c
. 至少在 gcc-4.8.3 中(可能还有更高版本,我现在无法检查),它说:
Run Code Online (Sandbox Code Playgroud)/* The purpose of this pass is to split function bodies to improve inlining. I.e. for function of the form: func (...) { if (cheap_test) something_small else something_big } Produce: func.part (...) { something_big } func (...) { if (cheap_test) something_small else func.part (...); } When func becomes inlinable and when cheap_test is often true, inlining func, but not fund.part leads to performance improvement similar as inlining original func while the code size growth is smaller. The pass is organized in three stages: 1) Collect local info about basic block into BB_INFO structure and compute function body estimated size and time. 2) Via DFS walk find all possible basic blocks where we can split and chose best one. 3) If split point is found, split at the specified BB by creating a clone and updating function to call it. The decisions what functions to split are in execute_split_functions and consider_split. There are several possible future improvements for this pass including: 1) Splitting to break up large functions 2) Splitting to reduce stack frame usage 3) Allow split part of function to use values computed in the header part. The values needs to be passed to split function, perhaps via same interface as for nested functions or as argument. 4) Support for simple rematerialization. I.e. when split part use value computed in header from function parameter in very cheap way, we can just recompute it. 5) Support splitting of nested functions. 6) Support non-SSA arguments. 7) There is nothing preventing us from producing multiple parts of single function when needed or splitting also the parts. */
您可能已经猜到了,这个过程完全由编译器控制。新的符号名称由函数产生clone_function_name
在gcc/cgraphclones.c
。后面加的数字.part
没有特别的意义,它只是用来防止名称冲突。这是一个简单的计数器,每次 GCC 从某个现有函数(GCC 的开发人员称之为“克隆”)创建一个新函数时,它都会递增。
您可以使用该选项-fdisable-ipa-fnsplit
来阻止编译器应用此优化,或-fenable-ipa-fnsplit
启用它。默认情况下,它的应用在优化级别-O2
和-O3
否则无效。
归档时间: |
|
查看次数: |
1409 次 |
最近记录: |