可以指示 GCC 不消除死代码吗?
Can GCC be instructed not to eliminate dead code?
假设我正在使用 GCC
的现代版本来编译 C 程序。此外,考虑到我的程序包含陈旧的分支,但我非常希望这些陈旧的分支中的死代码被编译并出现在最终程序中。考虑以下程序:
int main(int argc, char** argv) {
int a = 0;
goto skip;
a = -1;
skip: ;
return a;
}
显然,如果我使用 GCC
和默认优化设置,第二个赋值将永远不会进入最终程序,因为编译器可以很容易地判断它永远不会被执行。假设我不希望这种情况发生。
在 GCC
中,有许多涉及死代码的标记(最著名的是 -fdce
),我可以选择在相应地调用 GCC 时显式停用这些标记:
-fno-dce
-fno-dse
-fno-tree-dce
-fno-tree-dse
据我所知,这应该指示 GCC
不要搞乱第二个作业。然而,相关代码似乎从未进入我的程序。
为什么GCC
坚持删除死代码,有没有办法指示GCC不删除第二个赋值?
-fno-*
选项对 gcc-4.9.2 也不适用。
也就是说,我认为以下内容应该适用于所有 gcc (4.5+) 目标:
__asm__ goto (""::::no_skip);
goto skip;
no_skip:
a = -1;
skip:;
来自手册:"an asm goto statement is always implicitly considered volatile."
此外,对于 gcc-4.8 及更高版本,您可以考虑添加一个属性让编译器知道这是一个 'unlikely' 路径。这有助于防止在采用 'expected' 路径时可能发生的分支惩罚等:
no_skip: __attribute__ ((cold));
按理说你也可以使用:
skip: __attribute__ ((hot));
假设我正在使用 GCC
的现代版本来编译 C 程序。此外,考虑到我的程序包含陈旧的分支,但我非常希望这些陈旧的分支中的死代码被编译并出现在最终程序中。考虑以下程序:
int main(int argc, char** argv) {
int a = 0;
goto skip;
a = -1;
skip: ;
return a;
}
显然,如果我使用 GCC
和默认优化设置,第二个赋值将永远不会进入最终程序,因为编译器可以很容易地判断它永远不会被执行。假设我不希望这种情况发生。
在 GCC
中,有许多涉及死代码的标记(最著名的是 -fdce
),我可以选择在相应地调用 GCC 时显式停用这些标记:
-fno-dce
-fno-dse
-fno-tree-dce
-fno-tree-dse
据我所知,这应该指示 GCC
不要搞乱第二个作业。然而,相关代码似乎从未进入我的程序。
为什么GCC
坚持删除死代码,有没有办法指示GCC不删除第二个赋值?
-fno-*
选项对 gcc-4.9.2 也不适用。
也就是说,我认为以下内容应该适用于所有 gcc (4.5+) 目标:
__asm__ goto (""::::no_skip);
goto skip;
no_skip:
a = -1;
skip:;
来自手册:"an asm goto statement is always implicitly considered volatile."
此外,对于 gcc-4.8 及更高版本,您可以考虑添加一个属性让编译器知道这是一个 'unlikely' 路径。这有助于防止在采用 'expected' 路径时可能发生的分支惩罚等:
no_skip: __attribute__ ((cold));
按理说你也可以使用:
skip: __attribute__ ((hot));