Thanks David :) ~d
P.S. the unrecognizable insn bug fixed (and some another wiered one). The code is in cvs. On Friday 13 December 2002 12:53, David Brown wrote: > > David Brown wrote: > > >This is a mistake many people make when they are new to embedded > > >development, or new to using an optomising C compiler for embedded > > >development. The code snippet "int x = 1; while (x) ; " tells the > > > >compiler > > > > >to enter an infinite loop. You've already told the compiler what value > > > >"x" > > > > >has - why should it bother re-reading it all the time? That's what > > >optomisation is for - being smart and saving the processor some effort. > > >What you need to do is declare your variable to be "volatile" - that > > > >tells > > > > >the compiler the you really do want it to read the memory each loop. > > > > I know this is in the documentation, and there is a workaround, but I > > for one would be glad to see the back of this. I've used over a dozen C > > compilers for embedded work over the years, and this is the only one > > that does this optimisation, after all, short informal delays are the > > bread and ripping of embedded work. > > I think you are dangerously wrong there - so much so that I'm giving a much > longer argument than might be necessary, for the benifit of others who > think the same as you. > > First, the fact is that a good number of C compilers will do this same > optomisation, although some only do so at a higher level of optomisation. > For example, IAR's msp430 compiler will do exactly the same, at a high > enough optomisation level. Any compiler that does not do this is not a > good optomising compiler. msp430-gcc may be unusual in that it always does > it, even with no optomisation turned on, but that is fair enough. Choosing > a low optomisation setting means you want the compiler to be less efficient > for the purposes of smaller code size, easier debugging, or faster > compilation - it says nothing about how you want the code to work. > > Any case in which the optomisation carried out by the compiler affects the > logic or results of the program is an incorrect program (or a bug in the > compiler, of course :-). This cannot be stressed too much - if your > program works with low optomisations, and fails with higher optomisations, > then you have a flaw in your program. If it runs fine when compiled with > one compiler and fails with another compiler (baring compiler-specific > extensions), then you have a flaw in your program. > > When you write the code for your short, informal delay loop such as: > > void pause(void) { > int x = 100; > while (x--) ; > } > > what you are telling the compiler here is "x is an integer variable. > Nothing else can possibly influence this variable in any way, or even know > of its existance, since it is a local variable. Count down x until it > reaches 0." The compiler thinks "I can do this in my head - x ends up at > 0. In fact, you are not doing anything with x later on anyway - there is no > need to bother with it at all". Implementing "pause" as an empty loop is a > perfectly correct interpretation of the C code as written. In fact, > running the loop 10 times, or 1000 times, then exiting is also a correct > interpretation. You have written a function that has no effect. You might > think you have written a function that wastes a bit of time, but the C > language has no concept of time - "wasting time" is meaningless. So given > the choice, a good C compiler will skip the time wasting code. > > Note that it will not help much making "x" a global variable. This will > tell the compiler that at the start of the function, it must read in x, and > at the end of the function, it must write out x again - while inside the > function, however, the compiler can read or write x as often or as seldom > as it likes. In this case, the function "pause" would reduce simply to "x > = 0". > > There is just one technique that can be correctly used to get the desired > effect, and that is to make use of "volatile" (you might think that calling > an external function within the loop would work, but that might be > eliminated by a compiler that uses link-time code generation). The word > "volatile" tells the compiler that the given element must be accessed > exactly as written in the code, neither more nor less. Thus the easiest > correct solution is to make "int x" into "volatile int x" - this will work > whether the variable is local or global. > > An alternative solution is to put a non-eliminatable function inside the > while loop - most embedded compilers have a "nop()" function or similar > which is guarenteed not to be eliminated. Other ways to make a function > "non-eliminatable" are to use a volatile variable inside the function - > although the function could well be inlined and everything but this > volatile access eliminated. If you use the second technique, it is worth > noting that the compiler is still free to eliminate or change x in any way > it wants - just as long as the function (or the non-eliminatable parts of > it) are carried out the correct number of times, in the correct order. For > example, the loop could be unrolled in bunches of 10, with a counter > running from 9 down to 0. > > > It is interesting to note how msp430-gcc optomises such loops, depending on > the compiler flags and the sizes of the loops. For example, with a loop > with "x = 10", the compiler will eliminate the code at -O2 and above but > not at -O1. But if "x = 100", the code will not be eliminated unless > "-funroll-loops" is on - a loop of size 100 is too big for automatic > unrolling. Once unrolled, the code is then eliminated. > > > It leaves me worried about what else the compiler might be optimising > > out. I've always thought that, as engineers, we are grown up enough to > > be in charge of the process, not it in charge of us. > > > > Paul Burke > > As for what else the compiler might optomise out - just think about what it > *could* optomise out, and code accordingly. It is also worth using the > full set of compiler warning flags (at least "-W -Wall") to track dead code > and unnecessary variables. I use -O2 as standard - the only reason I don't > use -O3 is that it is easier to read the generated assembly with -O2. > > As engineers, we should write what we mean when programming - not what we > think a simpler, older compiler might think we mean. > > mvh. > > David. > > > > > ------------------------------------------------------- > This sf.net email is sponsored by: > With Great Power, Comes Great Responsibility > Learn to use your power at OSDN's High Performance Computing Channel > http://hpc.devchannel.org/ > _______________________________________________ > Mspgcc-users mailing list > Mspgcc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mspgcc-users -- ********************************************************************* ("`-''-/").___..--''"`-._ (\ Dimmy the Wild UA1ACZ `6_ 6 ) `-. ( ).`-.__.`) Enterprise Information Sys (_Y_.)' ._ ) `._ `. ``-..-' Nevsky prospekt, 20 / 44 _..`--'_..-_/ /--'_.' ,' Saint Petersburg, Russia (il),-'' (li),' ((!.-' +7 (812) 314-8860, 5585314 *********************************************************************