如何在没有运行时成本的情况下基于断言指导 GCC 优化? [英] How to guide GCC optimizations based on assertions without runtime cost?

查看:23
本文介绍了如何在没有运行时成本的情况下基于断言指导 GCC 优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调试模式下的代码中使用了一个宏:

I have a macro used all over my code that in debug mode does:

#define contract(condition) 
    if (!(condition)) 
        throw exception("a contract has been violated");

...但处于发布模式:

... but in release mode:

#define contract(condition) 
    if (!(condition)) 
        __builtin_unreachable();

这对 assert() 的作用是,在发布版本中,由于 UB 传播,编译器可以大量优化代码.

What this does over an assert() is that, in release builds, the compiler can heavily optimize the code thanks to UB propagation.

例如,使用以下代码进行测试:

For example, testing with the following code:

int foo(int i) {
    contract(i == 1);
    return i;
}

// ...

foo(0);

... 在调试模式下抛出异常,但在发布模式下为无条件 return 1; 生成程序集:

... throws an exception in debug mode, but produces assembly for an unconditional return 1; in release mode:

foo(int):
        mov     eax, 1
        ret

条件以及依赖于它的一切都已优化.

The condition, and everything that depended on it, has been optimized out.

我的问题出现在更复杂的条件下.当编译器无法证明条件没有副作用时,它不会优化它,与不使用合约相比,这是一个runtme惩罚.

My issue arises with more complex conditions. When compiler cannot prove that the condition has no side effect, it does not optimize it out, which is a runtme penalty compared to not using the contract.

有没有办法表示合约中的条件没有副作用,从而总是优化掉?

Is there a way to express that the condition in the contract has no side effect, so that it is always optimized out?

推荐答案

没有办法像死代码一样强制优化代码,因为 GCC 必须始终抱怨标准.

There is no way to force optimize out code as-if it was dead-code, because GCC has to always be complaint with the standard.

另一方面,可以使用属性 error 检查表达式是否有任何副作用,该属性将在无法优化函数调用时显示错误.

On the other hand the expression can be checked to not have any side effects by using the attribute error which will show an error whenever a function's call could not be optimized out.

一个宏示例,用于检查优化后的内容并进行 UB 传播:

An example of a macro that checks whatever is optimized out and does UB propagation:

#define _contract(condition) 
    {
        ([&]() __attribute__ ((noinline,error ("contract could not be optimized out"))) {
            if (condition) {} // using the condition in if seem to hide `unused` warnings.
        }());
        if (!(condition))
            __builtin_unreachable();
    }

error 属性在没有优化的情况下不起作用(所以这个宏只能用于发布优化模式编译).请注意,链接期间会显示指示合同有副作用的错误.

The error attribute does not work without optimization (so this macro can only be used for releaseoptimization mode compilation). Note that the error that indicates whatever the contract has side effects is shown during linkage.

一项测试,显示了不可优化合约的错误.

一项优化合约的测试,但会使用它进行 UB 传播.

这篇关于如何在没有运行时成本的情况下基于断言指导 GCC 优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆