static void helper_function(my_struct_t *e,int *outArr)
{
unsigned char event_type = e->header.type;
if (event_type == event_A || event_type == event_B) {
outArr[0] = action_one;
} else if (event_type == event_C) {
outArr[0] = action_one;
outArr[1] = action_two;
} else if (...) { ... }
}
static void buggy_invoker(my_struct_t *e,predicate_t pred)
{
// MAX_ACTIONS is #defined to 5
int action_array[MAX_ACTIONS] = {0};
helper_function(e,action_array);
...
}
static int has_any_actions(my_struct_t *e)
{
int actions[MAX_ACTIONS] = {0};
helper_function(e,actions);
return actions[0] != 0;
}
// *** ENTRY POINT to this code is this function (note not static).
void perfectly_fine_invoker(my_struct_t e,predicate_t pred)
{
memfence();
if (has_any_actions(&e)) {
buggy_invoker(&e,pred);
}
...
}
如果您认为我已经过度混淆或消除了太多,请告诉我.用户 这段代码叫’perfect_fine_invoker’.通过优化,g优化了 ‘has_any_actions’函数可直接调用’helper_function’,即 你可以在装配中看到.
问题
所以,我的问题是,对任何人来说,它看起来像一个错误的优化吗?
如果它有用,我可以发布原始C代码的消毒版本.
这是我第一次发布Stack Overflow,所以如果我能做的话请告诉我 任何使问题更清晰或提供任何其他信息的事情.
答案
编辑(事后几天):
我在下面接受了我的问题的答案 – 这不是g中的优化错误,我只是看错了汇编代码.
但是,对于将来可能会看到这个问题的人,我找到了答案.我在C(http://blog.regehr.org/archives/213和http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html)中对未定义的行为进行了一些阅读,并且编译器的一些描述使用未定义的行为优化掉函数似乎非常熟悉.
我在函数’helper_function’中添加了一些NULL指针检查,并且看到…… bug消失了.我应该开始使用NULL指针检查,但显然没有让它们允许g做任何想做的事情(在我的情况下,优化掉调用).
希望这些信息有助于未来的人.
最佳答案
我觉得你在看错了.我想编译器注意到你的函数很短并且没有触及%rdi寄存器所以它只是不管它(你有与第一个参数相同的变量,我想这是放在%rdi中的内容.参见第21页这里http://www.x86-64.org/documentation/abi.pdf)
如果查看未优化的版本,它会在此行保存%rdi寄存器
9498: 48 89 bd 38 fe ff ff mov %rdi,-0x1c8(%rbp)
…然后在调用helper_function之前,它将保存的值移动到移动到%rdi的%rax中.
94c1: 48 8b 85 38 fe ff ff mov -0x1c8(%rbp),%rax
94c8: 48 89 d6 mov %rdx,%rsi
94cb: 48 89 c7 mov %rax,%rdi
在优化它时,编译器就可以摆脱所有来回移动.
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|