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.

Bug with C6000 compiler???



Hi, I'm developing a device based on the C6713.

I found that whenever there are two consecutive GPVAL assignment statements, the C6000 compiler, under the 'Register (-o0)' Opt Level, would compile only the first statement! Has anybody found this too??? For example, if I have

 *GPVAL |= 0x00000100;       // Make GP8 pin go high
 *GPVAL &= 0xfffffeff;               // Make GP8 pin go low (thus produces a short pulse)


then the second statement, *GPVAL &= 0xfffffeff;, would not get compiled!

I checked the resulting assembly file. It's as if the second statement was not written (and I could not see the pulse on GP8 of course)!

Has anybody found this problem with the C6000 compiler?

How can one make the GP8 pin generate a very short pulse then????

Any help would be much appreciated.

C.M.

  • I guess it's some kind of optimization by this compiler.

    Try to add an ' asm nop ' between these assignment statements.

    Hope this will help.

  • Are you sure that it is the "&=" (CLR)  that disappears?  When I tried your code sequence the result was a "&=" (CLR) and no "|=" (SET).

    Unless GPVAL is declared to point at a volatile int I would expect the "|=" to be eliminated.  Without a volatile qualifier those two statements look like the sequence "set a bit" then "clear that same bit" which the optimizer would correctly conclude is the same as "clear the bit".  "volatile" tells the compiler that something outside of the normal C semantics can affect the value of the designated location.

     

     

  • Hi, thanks for the suggestion. I did try adding a useless line like 'i=0;' in between and it surely worked. However, this is a drag because I'll have to keep watching out for such abnormality forever now.

  • Hi, you are probably right, since I did not even get the GP8 pin to go high (and stay high).

    I'll try your 'volatile' qualifier suggestion and see what happens. Thanks.

    However, assuming it does fix the problem, it would be nice to know the rules when to use such qualifier and when not to, or is this qualifier always beneficial to use???

  • A  variable should be made volatile when it may be affected by or have an affect on some external agent or have a side effect that is not expressible in C.  The typical example is a hardware register associated with I/O.  These registers can behave in ways such that it would be invalid for the compiler to assume that reading the register will yield the last value written there or that two successive reads will produce the same value.  The C standard requires that the compiler access volatile variables exactly as written, no more and no less. 

    To quote the Archeologist (a frequent Forum contributor): There are different ways of looking at how volatile works, but it all boils down to telling the compiler that something unpredictable is going on, and so the compiler shouldn't try to be overly-clever .  For example, in the case of a loop waiting for a variable to change, volatile tells the compiler that something out-of-line (perhaps an I/O device, perhaps an interrupt function) may suddenly change the variable, so the compiler will not attempt to optimize it away.

    For more information on when to use volatile google "C volatile".

     

  • Hi Paul, thanks for the answers. It worked very nicely after I qualified GPVAL as volatile!

  • CMA said:

    However, assuming it does fix the problem, it would be nice to know the rules when to use such qualifier and when not to, or is this qualifier always beneficial to use???

     

    Just to note, it would in fact be DETRIMENTAL to over-use the volatile keyword.  As an example of what is going on, let me simplify your two statements and imagine a large input file with a lot of #if code that eventually reduced to something like the following:

    int i=2;

    int i=3;

    callfunc(i);

    in that case, it hopefully makes sense that the compiler looks at the two expressions setting the value of variable i and says the first one is useless and it will optimize it away (delete it).  The compiler looks for redundant or unneccesary operations like this in all the code and removes it or reduces it to simpler expressions.

    Your code is basically that with a more complex expression, but with the reality that something other than the C code itself is changing the value of the "variable" (which is actually a machine register).  The volatile qualifier, as noted by others, says things outside the C program affect it, and simply reading the code can't tell the compiler everything about the variable, so don't assume any expression is useless or redundant!  That effectively turns off a number of possible optimizations for that variable. 

    If you used it where it wasn't needed, your program would end up being larger and slower.

     

  • Hi Wolf, Thank you very much for this information. Being the first time to write in C/C++, this info is highly helpful. I really appreciate it.

    CM