From: Erik P. <epe...@iv...> - 2014-02-13 05:12:56
|
On Wed, 12 Feb 2014, Paul Sokolovsky wrote: > Hello, > > On Wed, 12 Feb 2014 12:36:22 +0100 > Philipp Klaus Krause <pk...@sp...> wrote: > >> I have fixed the notVolatile bug (RFE #407 remains) and added some >> peephole rules. While they held somewhat with global variables, they >> don't help in your case. > > But don't you want to say something about dataflow analysis? SDCC does > something of that, right? But "funny" code like superfluous loads > and dead stores is still generated, and not just in stm8 port. (no argument from me; just adding some commentary with respect to the dataflow analysis and identifying one cause of superfluous instructions) The dataflow analysis is currently working at the operand level, not the register level. So there may be some instructions generated to complete all the bytes of an operand, but not all of these bytes are always subsequently used. For example: unsigned int foo(unsigned char x,y) { return (x<<8) | y; } Here x is promoted to an int before the shift, so x is copied to the low byte of the int and 0 is loaded into the high byte of the int. But the left shift by 8 doesn't need the high byte (well, for at least the backends that I'm familiar with), so loading the 0 was a needless instruction that the dataflow didn't realize was needless. Some backends have some peephole rules (deadMove) to remove these sorts of instructions, but ideally a register would not be assigned to the unused bytes of the operands and the code generator could omit the instructions associated with the unused bytes of the result. Ultimately this should reduce the register spills and/or more efficient register use. Erik |