Hey! It's optomizing my volatiles away!

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hey! It's optomizing my volatiles away!

2,093 Views
borisyost
Contributor II
Dear Group:
 
I have code with the form of:
 
volatile unsigned int FPGA_mem_map[0x4000];
...
extern volatile unsigned int FPGA_mem_map[] @ (0x018000);
...
  do {
     FPGA_mem_map[ADDR]= reg;
      reg = dummy(reg); // magic line to prevent Metrowerks from optimizing volatiles
     status = (volatile) FPGA_mem_map[ADDR];
     done = DONE_MACRO(status);
     time_out++;
     // done goes to zero when cleared
 } while((time_out<CLR_TIME_OUT_EXP) && done);
dummy() is a function that just returns it's argument.
We have PPAGE set to RUNTIME.
 
With the magic line included, it works.  With the magic line not included, it times out every time.
 
With this code, what MW does is that it sees that the value of reg was put in a processor register, and it is still preserved if the 'magic line' is not included, so it simply assigns the processor register to the variable status instead of fetching a fresh copy out of FPGA_mem_map[ADDR].  If the magic line is included, I guess that MW can't guarantee that the register wasn't used in the dummy() context, so it does fetch a fresh copy (by calling _LOAD_FAR_16).
 
We have IDE 5.5.1272, HC12 3.1 build 4047 and SP PE 29.4.01 .
 
We have been chasing this and a variety of other bugs involving volatile variables that aren't getting fetched fresh.  We've tried turning off all sorts of optomizations.  Any idea how to stop this behavior?
 
Boris
 
 
Labels (1)
0 Kudos
3 Replies

610 Views
Lundin
Senior Contributor IV
Well, why do you need to use "reg" as a temporary variable? Why not assign "status" directly from "FPGA_mem_map"?
Otherwise I believe "reg" must be volatile as well for that code to work. But if "reg" is declared as volatile, then the compiler doesn't conform to ANSI C...


The optimizer is really annoying. I don't want to debug optimized code. I don't want certain parts of my code optimized.

For several years, I have asked over and over and over for a feature "turn all optimizations off". Every other known compiler for every known language and platform has this feature, even the non-commercial ones.

Messing around with the optimizer's settings without reading all the helpfiles may cause the program to behave very strange and unexpected. So you have to read 50+ helpfiles about compiler settings that you have little or no interest in, except the fact that they might mess up your program.
0 Kudos

610 Views
borisyost
Contributor II
Daniel:
 
    Let's be a little more 'clear':
 
void clear_burst_done( char * err_message ){
  volatile unsigned int status;
  volatile unsigned int done;
  unsigned int time_out;
  unsigned int reg;
  // clear the burst done status
  reg = ( INTERRUPT_SDRAM_BURST_DONE_SET(1));
  time_out = 0;
  do {
     vmc_regs[MASKED_INT]= reg;
     // prevent Metrowerks from optimizing volatiles
  reg = dummy(reg);
  status = (volatile) vmc_regs[MASKED_INT];
  done = INTERRUPT_SDRAM_BURST_DONE(status);
  (void) dummy(done+13);  // was also thrown in to keep optomizations off
  time_out++;
     // done goes to zero when cleared
 } while((time_out<TIME_OUT_EXP) && done);
 if( time_out >= TIME_OUT_EXP ){
   serial_puts(err_message, MAX_STR_SIZE);
 }
}

 
vmc_regs[MASKED_INT] is a memory mapped FPGA register in an interrupt controller that follows the common system of "write a '1' to clear it".  So, this function clears the interrupt status register, then busy-waits to make sure the hardware actually does it before moving on.
 
I don't think that the second call to 'dummy' is really necessary, but that's what's in there now so I just copied it.
 
I'm pretty sure that I can come up with a more minimalist example--something that one could implement with just about any demo board and not need to use external bus mode or assume the existence of string I/O (i.e. accessing PIM registers).  If there's somebody who could do something positive about the net result, I would make the effort.
 
Yes, I have read more than one 1000 page PDF detailing the fine points of #pragma's.  (No, I didn't enjoy it.  The software guys appreciated me giving them the abridged version.)
 
Boris
 
0 Kudos

610 Views
petr
Contributor I
Hello
I'm not 100% sure this will work, but instead of

volatile unsigned int FPGA_mem_map[0x4000];

try to declare it as

volatile unsigned int volatile FPGA_mem_map[0x4000];

I think that the first definition tells the compiler that FPGA_mem_map is volatile pointer to memory, but the second should tell the compiler that the FPGA_mem_map is volatile pointer to volatile data.
Regards
Petr
0 Kudos