This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with optimisation of volatiles

Hi there All,

I have a problem which seemed to be defying explanation, but I have come up with a theory. Could I possibly have some feedback on whether the following is likely, plausible, possible, untrue or downright rubbish?

If one reads the contents of a CAN or ADC chip register at a particular address, then the label volatile is placed upon that address to prevent the compiler optimising out repeat readings of the address. If one reads the contents of the address into a variable, then the compiler would automatically treat the contents of this variable with similar care.

Is it possible that there has been an oversight with statements where the contents of a variable depend on the contents of a volatile by way of an if statement, ie...

normal_var=volatile_var;

...is correctly optimised, but...

normal_var=voltile_var;
if (normal_var=0x00)
   {
   another_normal_var+=1;
   }

...is not correctly optimised all of the time, dependant on the surrounding code, unless normal_var itself is declared to be volatile?

For info - am using optimisation level...

OPTIMIZE(3,SPEED)

...and am using version...

C166 COMPILER V4.11

Any thoughts, or is any or all of the above thoughts and understanding way off the mark?


Yours (grateful for any input),


Richard.

Parents
  • The only difference I see is that in the 'broken' code one of the variables (CAN_LED_status) is placed in the register R14. All the other veriables are placed on the user stack. Of course, this is perfectly legal and the compiler generated correct code.
    There can be all sorts of reasons why the code fails: changed execution speed, corruption of registers by interrupt service routines we don't know of, plain bug in the code (so it works accidentally sometimes) and so on.

    Best of luck!
    - mike

Reply
  • The only difference I see is that in the 'broken' code one of the variables (CAN_LED_status) is placed in the register R14. All the other veriables are placed on the user stack. Of course, this is perfectly legal and the compiler generated correct code.
    There can be all sorts of reasons why the code fails: changed execution speed, corruption of registers by interrupt service routines we don't know of, plain bug in the code (so it works accidentally sometimes) and so on.

    Best of luck!
    - mike

Children
  • I'll second Mike's observation. There's absolutely no change at all between the three assembly outputs you show, as far as accesses to your CAN registers are concerned. They're those EXTB+MOVB pairs. Which means that whatever the real bug is, it's not in the piece of assembly code you did show. It's elsewhere.

    One thing I'm worried about is that I don't see any remains of the most significan byte actual addresses of your CAN registers (0x20) in any of the quoted code. Now, I don't do 166's at all, but this does feel fishy.

    Are you sure this code succeeds in accessing your CAN hardware registers at all, in the first place?

    You really should trace through this in some simulator or emulator to see what actually happens.

  • One thing I'm worried about is that I don't see any remains of the most significan byte actual addresses of your CAN registers (0x20) in any of the quoted code.

    It's those EXTP instructions. EXTP #080H,#01H is pretty much the same as EXTS #020H,#01H, which wouldn't alarm you. For some reason the C166 compiler prefers EXTP to EXTS, but that doesn't do any harm.

    - mike