I don't mean to sound patronising, but I don't think you are aware of what compilers do, how they work, how "volatile" works, or how to write good C code for embedded systems. I'm afraid your post is almost completely incorrect - I hope you take my reply here as constructive critisism to aid your better understanding. Thinking about these things is good, and discussing them will refine that thinking.
----- Original Message ----- From: "Roberto Padovani" <padovan...@gmail.com> To: "GCC for MSP430 - http://mspgcc.sf.net" <mspgcc-users@lists.sourceforge.net> Sent: Monday, July 03, 2006 9:16 AM Subject: Re: [Mspgcc-users] Code generation question > knowing how a compiler works in the most unusual situations is always > interesting...and this discussion is no different. That's not only true, but essential to embedded programming. Knowing your compiler is vital, including knowing its shortcomings. > however, a compiler is just a machine with a lot of rules, so you > cannot expect it to be "clever" anytime, even if correct code is a > necessity and efficiency is only a plus; You can certainly expect the compiler to be "clever" - the people who wrote it were clever people, and I have often looked at generated assembly code and admired neat tricks I hadn't thought of myself. The aim of the compiler's optimiser is to give you the best generated assembly that has the same effect as the code you wrote, regardless of the style in which you wrote it. In fact, to make the best use of your compiler, you must rely on it being clever. As a simple example, if you want to divide a variable by two, you should write "y = x / 2;", in the sure knowledge that the compiler is clever enough to change this to a single-instruction shift, rather than a library routine for division. Thus you write your code in the way that makes most sense for the code, and rely on the compiler to generate good code for the target. Of course, you must be aware of your target and compiler - you wouldn't use floats for x and y and expect good results. The compiler is clever, but not a mind-reader. > but in this case, reading the C source code, I honestly can't > understand for sure what it meant....if I were to translate manually > that code into asm, I would have asked a clarification to the > programmer: did you want to sample twice the port and then add these > two samples ? (say for making an average) or did you want two sample > the port once and double that reading ? > IMHO the answer wasn't clear, even if I considered all the volatile qualifiers; In that case, you simply don't have the experiance to understand volatiles properly. The code was perfectly clear - the port should be sampled twice, and it's sum taken. If Grant had wanted to sample it once and double it, he would have writen "two = 2 * P6IN;". Of course, in real code the function and variable names would have given an indication of *why* he was doing this, but the code itself is perfectly clear. > so I wouldn't try to add another complicated rule to gcc, but I would > rather write a better C code...an unambiguous one that the "simple" > rules of any compiler can understand. > A C compiler is required to generate correct code for all legal input - it would be a poor compiler indeed if it required specific simplistic styles to generate correct code. What has been uncovered here are two issues - one is inefficient code (which will be fixed if it can easily be done), and the other is incorrect code (which people are already working on to find a fix). It may be that in the meantime, people will need to use a workaround to avoid the bug - but that's an exceptional circumstance, not a solution. > for sampling twice: x = P6IN; x += P6IN; Why do you thing that is better than "x = P6IN + P6IN" ? To the compiler, this is exactly the same (assuming "x" is a local variable), and it generates exactly the same output. To the writer (and reader) of the C code, it is more verbose without adding any useful information - and therefore worse code. > for doubling the sampling: x = P6IN * 2; That would be correct if Grant had wanted to double a single sample, but that's not what he was after. > > the compiler won't mistake. > They have different meanings, and will be treated differently - but your first example has the same meaning as the original code, and is treated as such. > By the way, I think it's also better to change your initial example: > > unsigned two; > void foo(void) > { > two = P6IN + P6IN; > } > > into: > > unsigned two; > > void foo(void) > unsigned int tmp; > { > tmp = P6IN + P6IN; // <----- tmp = 2 * P6IN; // <----- tmp = > P6IN; tmp+= P6IN; > two = tmp; > } > You may think that, but no one will agree with you. There is no benifit in introducing an extra temporary variable here - it simply makes the code more verbose and thus less readable. You are writing in C, using a compiler - you are not writing everything out explicitly in assembler. It is up to the compiler to figure out what extra temporary variables it needs - in fact, the compiler will probably internally use exactly the code you have written out explicitly. And unless you are specifically compiling with no optimisation, the code generated is identical with or without the "tmp" variable. > or even better a function. it's more efficient (and easier to compile) > if you make the calculations through local variables. > It is hard to split up a single-line function into smaller functions. And as for being easier to compile - I try to be nice to my computer, but I refuse to structure my code differently just to save the computer a couple of microsecond's effort during compilation. Local variables are, in general, more efficient than global variables - but they are not more efficient than calculations carried out internally by the compiler using registers. Add variables when they make sense in your code, and make the logic of your code clearer - don't do it for the compiler's sake. mvh., David > > Roberto > > > > 2006/7/1, Grant Edwards <gra...@visi.com>: > > On 2006-06-30, Chris Liechti <cliec...@gmx.net> wrote: > > > > >>>>Just for fun, I tried compiling the code with "two" changed to > > >>>>an unsigned char. My mps430 compiler (3.2.3) then gives > > >>>> > > >>>> mov.b &P6IN, r15 > > >>>> rla.b r15 > > >>>> mov.b r15, &two > > >>>> ret > > >>>> > > >>>>In other words, it makes the same mistake you did and > > >>>>disregards the "volatile" qualifier. This is far more serious > > >>>>than the original question - it is incorrect code, rather than > > >>>>just inefficient code. > > > > >> Rather than just complaining, I should try to fix it. Is this > > >> something that could be fixed by somebody like me who's only > > >> done minor hacking on GCC? > > > > > > if you already have an idea how the backend of gcc works i > > > could think of "yes" > > > > I've read descriptions of the backend, but never worked on it. > > I've only tweaked a few things in the front end. > > > > > gcc likes to output code for volatile acceess as > > > load/modify/store, even when with the MSP430 a single mov, > > > bis, bic/and would be fine too. there are extra optinizations > > > by mspgcc to generate efficent code in such a case. that might > > > also explain the different code at the two optimization > > > levels. > > > > It does generate correct code for -O0: > > > > foo: > > mov.b &0x0034, r15 > > add.b &0x0034, r15 > > mov.b r15, &two > > ret > > > > At -O1 and -O2, it generates the incorrect code as previously > > noted. > > > > > maybe someone could check with -mno-volatile-workaround > > > > No difference. It still generates incorrect code for the > > -O[12] case when the destination matches the width of the > > source (both 8 bits wide). For the original case where the > > destination i s16 bits wide, it stell generates an extra mov.b > > and an extraneous and.b #-1,r15. > > > > >> I see that there are several more recent versions of mspgcc in > > >> CVS. Are any of the newer ones ready for production use? If > > >> not, is 3.2.3 still being maintained? > > > > > > 3.2.3 is our "stable" version > > > > Is it getting bug fixes? > > > > > the latest 4.x should be the next version, but it's not yet > > > ready > > > > -- > > Grant Edwards grante Yow! YOU'D cry too if it > > at happened to YOU!! > > visi.com > > > > > > Using Tomcat but need to do more? Need to support web services, security? > > Get stuff done quickly with pre-integrated technology to make your job easier > > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > > _______________________________________________ > > Mspgcc-users mailing list > > Mspgcc-users@lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/mspgcc-users > > > > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Mspgcc-users mailing list > Mspgcc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mspgcc-users > > >