Inline functiion in GCC
Venkatachala Upadhya
venkatu@samsung.com
Fri Aug 6 11:25:00 GMT 2004
Hello GCC people,
I am working on audio Codecs. I am using Linux 2.4.20 kernel on
ARM926EJS processor. The tool chain used is GCC 3.3.1 and the binutils
2.14. The codec code is optimised for ARMEJS priocessor using ADS suite
version 1.2. This optimised code is having C inline functions with
inline assembly statements. I have given here one inline C function with
inline assembly code for reference.
__inline Word16 add(Word16, Word16);
__inline Word16 add(Word16 x, Word16 y)
{
Word32 xs, ys;
Word16 rs;
__asm{
mov xs, x, lsl #16
mov ys, y, lsl #16
qadd xs, xs, ys
mov rs, xs, asr #16
}
return (rs);
}
I have ported the same code to GNU tool chain. I have used the
C-Language extention with Extended inline assembly feature, available in
GNU tool chain. The GNU port code is also reproduced here for reference.
__inline__ static int add(int, int) __attribute__ ((always_inline));
__inline__ static int add(int x, int y)
{
int xs, ys;
__asm__ __volatile__
(
"mov %3, %0, lsl #16 \n;"
"mov %4, %2, lsl #16 \n;"
"qadd %3, %3, %4 \n;"
"mov %0, %3, asr #16 \n;"
: "=r" (x)
: "0" (x), "r" (y), "r" (xs), "r" (ys)
) ;
return (x);
}
I have used this piece of code in the following example to study how the
inline is happening and the effectiveness of the inline.
#include <stdio.h>
#include <stdlib.h>
__inline__ static int add(int, int) __attribute__ ((always_inline));
__inline__ static int add(int x, int y)
{
int xs, ys;
__asm__ __volatile__
(
"mov %3, %0, lsl #16 \n;"
"mov %4, %2, lsl #16 \n;"
"qadd %3, %3, %4 \n;"
"mov %0, %3, asr #16 \n;"
: "=r" (x)
: "0" (x), "r" (y), "r" (xs), "r" (ys)
) ;
return (x);
}
int main (void)
{
int x=10, y=20, z=30;
int sum1, sum2, sum3;
sum1 = add (x, y);
sum2 = add (y, z);
sum3 = add (sum1, sum2);
printf("sum1 = %d sum2 = %d sum3 = %d\n", sum1, sum2, sum3);
}
Compilation option used is
arm_v4t_le-gcc -march=armv5te -msoft-float -finline-functions -Winline
-I. inline_test.c -o inline_out
I have generated the executable and got the object dump of this
executable with dis-assembly option (option -D). object dump command is
arm_v4t_le-objdump -D inline_out > inline_out_objdump
Using this inline_out_objdump file, I could see that the function main
has 285 ARM instructions. See the attached file inline_out_objdump.
Now I have converted this inline assembly to ARM assembly file as shown
below.
.global add
.code 32
.text
add:
mov r0, r0, lsl #16
mov r1, r1, lsl #16
qadd r0, r0, r1
mov r0, r0, asr #16
bx lr
.end
Now I wrote a test program as shown below.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int x=10, y=20, z=30;
int sum1, sum2, sum3;
sum1 = add (x, y);
sum2 = add (y, z);
sum3 = add (sum1, sum2);
printf("sum1 = %d sum2 = %d sum3 = %d\n", sum1, sum2, sum3);
}
Compilation option used is
arm_v4t_le-gcc -march=armv5te -msoft-float -finline-functions -Winline
inline_add.s inline_test.c -o inline_out_as
I have got the object dump of this executable with dis-assembly option
(option -D). object dump command is
arm_v4t_le-objdump -D inline_out_as > as_objdump
I could see that the function main has 33 ARM instructions and add
function has 5 instructions. Since add is called three times in the
main, total number of instructions are 33+(3*5) = 48 instructions. See
the attached file as_objdump.
Now I find that there is a big increase in the number of ARM
instructions in the inline option compared to function call option. Also
I could notice that compiler has not used the set of registers available
(like r4, r5, ... r10) in the inline option, though it is free to use
it. Moreover, though we have 2 arguments in add, registers r2, r3 are
set to some value before entering the inline function. In case of
function call option. I guess, the compiler has used the registers
correctly. Is this the expected behaviour of GCC? I could not find the
advantage of using the inline in this case. In case of inline case, it
can also be seen that a number of un-necessary instructions are
generated, which can be avoided.
For this experiment, I have compared the GNU output with ADS suite 1.2,
for the same program. ADS output is much better compared to GNU.
Does any one have any comment on this? I am hoping that some one would
work on this to make the GCC better.
Please note that, I have added the number of instructions under the
label main and add to count the number of instructions in each case.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: as_objdump
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20040806/ab3ffa6d/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: inline_out_objdump
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20040806/ab3ffa6d/attachment-0001.ksh>
More information about the Gcc
mailing list