From: Peter D. T. <pd...@do...> - 2016-01-18 16:17:10
|
Hi, Here is my 2 cents, and some ramblings, On Mon, 2016-01-18 at 15:55 +0100, Philipp Klaus Krause wrote: > When calling functions, SDCC usually assumes that all registers that > the > calling convention considers to be saved by the caller need to be > saved > by the caller. > However, sometimes this would not be necessary, as the called > function > does not really overwrite the value of such registers. > To reduce call overhead, it would be useful to be able to use such > knowledge. The knowledge could come from two sources: > 1) The user. We could introduce a syntax to allow the user to specify > in > function declarations that certain functions do not change certain > registers. This would also be useful for functions in the standard > library implemented in asm. > 2) Automatic analysis: After compiling a function we have some > knwowledge on whch registers it might overwrite. If we can prove that > a > ceratin register will never be overwritten (similarly how we > currently > prove that we will never emit a div or divw instruction in the stm8 > backend). This knowledge can then be used at subsequent calls to this > function in the same translation unit. > > See also > https://sourceforge.net/p/sdcc/discussion/1864/thread/722218e2/?limit > =25 > I think both are useful but one is exclusive for assembly. 1) Works great on assembler and even works on exported functions, and really does nothing for C. If the user could select used regs it would not make sense, as reg use changes as code and SDCC changes. It would probably be a very messy experience in C. It should probably create an error if the func is not inline assembly. Syntax suggestion: proto (with decorator): void func(void) __regs(cpu, reg1, reg2, reg2); impl-C (without decorator): void func(void) {} impl-asm (without decorator): asm(_func: ... ...); You could also introduce a keyword to the assembler, But really the "__regs" really only needs to be on the prototype. example: void func(void) __regs(z80,X,Y) __regs(stm8,A,B) __regs(mcs51,O,P); 2) Works great on C, and could even work on assembly. If all the analysis was done on assembly level it would work for C and assembly alike. a) In pass1 all the used regs are collected. b) In pass2 all the collected info is used to eliminate push/pops. 1+2) For future optimizations it would also be great if it could write the info to the REL file. Could be useful for global optimizations. You could also consider going for the global optimization from the start. You can do this by making it a 2 stage rocket: A) Run each file with a special option "--regs". This spits out a simple file for each module describing the reg use. B) Run each file again with all the ".reg" files as input along with the source and usual options. Now the compiler can avoid *all* unnecessary push/pops. You can even distribute your ".reg" file to others along with your own libs so 3rd party users can have use of it. Now that i think of it, this file format could also cover 1), as all you need is an extra ".reg" file for the whole lib. ".reg" could also just be a sub-section in an existing file (e.g. the REL file), so new files are avoided. > For 1) we'd need to find a syntax. I'm not currently aware of any > other > compiler or any standard supporting such syntax. Thanks, /pedro |