helping the compiler with asserts-hints to optimize

Agustin Perez Paladini agudpp@gmail.com
Thu Apr 24 12:40:00 GMT 2014


Hi All,
Thanks for the replies!

I think that __builtin_unreachable() is what I was looking for.
- It doesn't add code when compiled (a branch).
- Let the compiler know about some "preconditions" or values about variables.
- Optimize using that information.

I did some tests using the macro ASSUME as Jonathan defined (using gcc
4.7.2 with -O3). The tests as next:

int
fun_mul_2(int x, int y)
{
    ASSUME(x == 2);
    return x * y;
}

is compiled into

fun_mul_2:
    .LFB0:
    .cfi_startproc
    movl 8(%esp), %eax
    addl %eax, %eax
    ret
    .cfi_endproc

So it was compiled as expected (just add the same value twice).
Also, it was able to remove some "unreachable" code as expected.

I found a simple example where it wasn't able to notice what I was
trying to say, the test was:

int
fun_module(int a)
{
    ASSUME(a % 4 == 0);

    if (a == 3) {
        return 123;
    }
    return 789;
}

giving this asm

fun_module:
    .LFB3:
    .cfi_startproc
    cmpl $3, 4(%esp)
    movl $789, %edx
    movl $123, %eax
    cmovne %edx, %eax
    ret
    .cfi_endproc


Anyway, I think its pretty much what I was looking for.
Thanks to all!

Agustin

2014-04-24 4:26 GMT-03:00 David Brown <david@westcontrol.com>:
> The obvious improvement is to make your asserts use
> __builtin_unreachable in "release" mode.  So you have something like this:
>
> #ifdef DEBUG
> #define assert(expr) \
>         if (!(expr)) assertFailed(__FILE__, __LINE__)
>
> #else
> #define assert(expr) \
>         if (!(expr)) __builtin_unreachable()
> #endif
>
> mvh.,
> David
>
>
> On 23/04/14 19:10, Agustin Perez Paladini wrote:
>> Hi Jonathan,
>> Yes, that should work, assuming that the compiler will understand what
>> I'm trying to say!
>>
>> Thanks a lot! I will try that and see if there are any improvement.
>> Regards
>>
>> 2014-04-23 13:56 GMT-03:00 Jonathan Wakely <jwakely.gcc@gmail.com>:
>>> On 23 April 2014 17:50, Jonathan Wakely wrote:
>>>> On 23 April 2014 17:24, Agustin Perez Paladini wrote:
>>>>> Basically I was thinking in something like asserts, but that are only
>>>>> visible for the compiler and don't affect the code. Something like
>>>>>
>>>>> __builtin_assume(x > 0);
>>>>> __builtin_assume(x < 10);
>>>>>
>>>>> where x is a variable. That way the compiler can do better optimizations.
>>>>
>>>> You can use __buitlin_expect and __builtin_unreachable to do that.
>>>
>>> Or just __builtin_unreachable alone
>>>
>>> #define ASSUME(X) if (!(X)) __builtin_unreachable()
>>>
>>> This tells the compiler X is always true. Isn't that what you want?
>>
>



More information about the Gcc-help mailing list