This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How can I tell the compiler that a variable has some specified values?

Hi, is there a way to tell the compiler that a variable can contain only some specified values?

An example:

    for (i = 0; i < max; i++)
    {
        tot += someFunc(vals[idx]);
        idx = (idx + 1) % 12;
    }

Looking to the assembly I can see two cases:

1) if idx is local and is equal to any number between 0 and 11:

(idx+1) % 12 is computed as idx = (idx > 10)? 0 : idx+1;

2) else if idx is received as a parameter and the compiler doesn't know his value:

the compiler divide idx+1 by 12 (in a smart way) and than compute the % 12.

Of course the solution (1) is way better and faster.

I would like to say to the compiler that, even if coming from another function, idx is absolutely less than 12.

Is it possible via some pragma?

Thanks!

  • There are two things to consider.  One ... The C language itself provides no method for providing such hints to the compiler.  So is there some extension provided by the compiler for this purpose?  Two ... Even if an extension is provided, will the compiler take advantage of that information in the specific way you describe?  The answer to one is yes.  The answer to two is probably not.

    There are two extensions to the language for providing hints to the compiler.  One is the intrinsic _nassert.  The interface is the same as the standard C function assert, which you can look up anywhere.  However, the compiler presumes the expression is always true, and no code is generated for it.  Read more about _nassert in this forum thread.  The other extension is the intrinsic __builtin_expect.  This is borrowed from GCC.  You can look it up by searching for GCC __builtin_expect.

    However, I'm confident that even if you use these intrinsics, the compiler will not use that information to generate the exact code you expect.

    Thanks and regards,

    -George

  • Thanks George, it's an interesting topic.
    Unfortunately neither _nassert nor __builtin_expect changes the compiler behaviour.

    In order to force the compiler to optimize the module I had to add this line before the loop:
    idx %= 12;

    Writing that instruction the compiler understand that idx is always lower than 12 and optimize the module with an if instead that a division.
    I think it should be better if the compiler reads and use the _nassert(idx < 12), don't you think? Could you add this in the next releases?

    The loop cycles number decrease from 10 to 6, it's A LOT better!
  • p.s. I think that TI compiler uses _nassert just for pointer alignment because even writing
    _nassert(idx == 5);
    I cannot see any assembly optimisation...

    Of course when I force idx = 5 in the code everything changes and the loop decrease from 10 cycles to 3
  • SRiva said:
    I think it should be better if the compiler reads and use the _nassert(idx < 12), don't you think? Could you add this in the next releases?

    Unfortunately, such a change in the compiler would benefit very few users.  Therefore, it is unlikely to ever get enough priority to be implemented.

    Thanks and regards,

    -George

  • This is a case in which you know more than the compiler does. You know that you're just incrementing idx and want it to wrap around from 11 to 0. The compiler sees a modulo op and must start from the expectation that it is a general divide-remainder operation.

    The compiler cannot always deduce that the more efficient sequence is appropriate. If that's what you want, you're better off writing it that way directly.
  • pf said:
    This is a case in which you know more than the compiler does.

    This is true, in fact it would be great if the compiler interpreted the _nassert (idx < 12) to increase its knowledge about the variable value in order optimize the sum/module operation.

    Anyway, thanks for your answers, I will be extra-careful when using modulo-operation, regards