Can I hint the optimizer by giving the range of an integer?

后端 未结 4 976
一生所求
一生所求 2020-12-02 04:15

I am using an int type to store a value. By the semantics of the program, the value always varies in a very small range (0 - 36), and int (not a

4条回答
  •  南笙
    南笙 (楼主)
    2020-12-02 04:39

    The current answer is good for the case when you know for sure what the range is, but if you still want correct behavior when the value is out of the expected range, then it won't work.

    For that case, I found this technique can work:

    if (x == c)  // assume c is a constant
    {
        foo(x);
    }
    else
    {
        foo(x);
    }
    

    The idea is a code-data tradeoff: you're moving 1 bit of data (whether x == c) into control logic.
    This hints to the optimizer that x is in fact a known constant c, encouraging it to inline and optimize the first invocation of foo separately from the rest, possibly quite heavily.

    Make sure to actually factor the code into a single subroutine foo, though -- don't duplicate the code.

    Example:

    For this technique to work you need to be a little lucky -- there are cases where the compiler decides not to evaluate things statically, and they're kind of arbitrary. But when it works, it works well:

    #include 
    #include 
    
    unsigned foo(unsigned x)
    {
        return x * (x + 1);
    }
    
    unsigned bar(unsigned x) { return foo(x + 1) + foo(2 * x); }
    
    int main()
    {
        unsigned x;
        scanf("%u", &x);
        unsigned r;
        if (x == 1)
        {
            r = bar(bar(x));
        }
        else if (x == 0)
        {
            r = bar(bar(x));
        }
        else
        {
            r = bar(x + 1);
        }
        printf("%#x\n", r);
    }
    

    Just use -O3 and notice the pre-evaluated constants 0x20 and 0x30e in the assembler output.

提交回复
热议问题