Hi Everyone,
I'm using C251 compiler with optimization level 9 with 'size' emphasis. I've a function similar to one given below.
int * fun(short* param1, Boolean param2){
//..........code goes here } This function is being called as fun(someValue,TRUE) or fun(someValue, FALSE) across the souce code. I tried to replace these calls with the help of two new functions that knows beforehand second argument. This change was based on calling convention used by C251. I assumed that C251 passes parameters similarly as C51,i.e. by using registers and memory locations (hence boolean parameter need not be passed at all).
Warpper functions are given below. int * funTRUE(short* param){
return fun(param,TRUE); }
int * funFALSE(short* param){
return fun(param,FALSE); } After this change code size has increased by around 3K rather than went down. Replacement are around 20 so we can not say that code of wrapper functions have added to increase in the code size more than reduction due to call replacements with calls to wrapper functions. How can I've more insight in this phenomenon?
Why use the Bold tag for your code instead of the tag that is provided specifically for source code?!
"I assumed that C251 passes parameters similarly as C51"
You must absolutely not go making assumptions like that - you must study the manuals to obtain such information.
"How can I've more insight in this phenomenon"
Stop making assumptions - confirm things in the documentation;
Look at the Map file to see where the additional code size is actually appearing;
Look at the generated code.
"I assumed that C251 passes parameters similarly as C51,i.e. by using registers and memory locations"
How else do you think parameters might be passed if it is not done via registers or memory locations?
@IB Shy
My reference to 'memory location' was for internal RAM or XRAM but not for HW stack or some yet-to-be-discovered mechanisms.
"... was for internal RAM or XRAM but not for HW stack"
But the hardware stack obviously uses memory locations - doesn't it?!
This is what the manual actually says:
"C functions may pass parameters in registers and/or fixed memory locations"
You left out the key word there - "fixed"
http://www.keil.com/support/man/docs/c251/c251_ap_funcparam.htm
"yet-to-be-discovered mechanisms"
You will discover them by carefully studying the documentation: http://www.keil.com/support/man/docs/c251/
Thanks Neil for your valuable suggestion.
Now, when I see generated assembly I found parameter passing code used for wrapper functions is indeed smaller in size than the actual function call. And code size has incresaed due to reduction in linker optimization performed.
It is generally the case that the effect of optimisers does depend on the nature of the code being optimised.
You appear to have found one of those cases where the difference is significant!
It might even be a direct bug in the optimizer, making it skipping an important optimization because your code no longer matches existing optimization rules and the rule list is missing some reasonable rules.
It might be an idea to try to create as small program as possible that gives this problem and then contact Keil.
I've implemented a small project keeping identical project settings e.g. Memory Model, optimization level etc and I can see wrapping methods, as I explained in opening of thread, gives code size benefits so we can not directly blame the optimizer.