Messages in this thread | | | Date | Mon, 6 Apr 2015 08:40:05 +0200 | From | Nicholas Mc Guire <> | Subject | Re: [PATCH 2/3] time: allow gcc to fold constants when using msecs_to_jiffies |
| |
On Sun, 05 Apr 2015, Joe Perches wrote:
> On Mon, 2015-04-06 at 06:26 +0200, Nicholas Mc Guire wrote: > > On Sun, 05 Apr 2015, Joe Perches wrote: > > > Try it and look at the generated .lst files with and > > > without the patch I sent. > [] > > from all that I understood it should > > be doable both as macro and inline. > > I think it _should_ be doable too but I also think > the only reason gcc doesn't optimize the inline > is because gcc's optimizer isn't good enough yet. >
"unfortunately" I can't blame it on gcc - here is the initial toy-case - test.c and either testi.h or testm.h included - m = TIMEOUT or m = atoi(argv[1]); both in the inline and the macro case gcc reduced the code to a single load mediate or register instruction for the constant - so the optimizer is doing its job.
test.c: #include <stdio.h> #define HZ 100 #define MSECS_PER_SEC 1000 #define TIMEOUT 100 #include "testi.h" /* inline msecs_to_jiffies */ //#include "testm.h" /* macro versions */
int main(int argc, char **argv) { //int m = atoi(argv[0]); /* non-const */ int m = TIMEOUT; /* const */ printf("%lu\n",msecs_to_jiffies(m)); return 0; }
testm.h:
#define msecs_to_jiffies(m) \ (__builtin_constant_p (m) \ ? ((m) * HZ / MSECS_PER_SEC ) : __msecs_to_jiffies(m))
unsigned long __msecs_to_jiffies(int m) { return m * HZ / MSECS_PER_SEC ; }
first case with a non-const main: .LFB12: .cfi_startproc subq $8, %rsp #, .cfi_def_cfa_offset 16 movq 8(%rsi), %rdi # MEM[(char * *)argv_2(D) + 8B], MEM[(char * *)argv_2(D) + 8B] xorl %eax, %eax # call atoi # movl $1717986919, %edx #, tmp69 movl %eax, %ecx #, m movl $.LC0, %edi #, imull %edx # tmp69 sarl $31, %ecx #, tmp71 xorl %eax, %eax # sarl $2, %edx #, tmp67 subl %ecx, %edx # tmp71, tmp67 movslq %edx, %rsi # tmp67, tmp72 call printf #
o second with a constant: main: .LFB12: .cfi_startproc subq $8, %rsp #, .cfi_def_cfa_offset 16 movl $10, %esi #, movl $.LC0, %edi #, xorl %eax, %eax # call printf #
inline: -------
testi.h: static inline unsigned long __msecs_to_jiffies(int m) { return m * HZ / MSECS_PER_SEC; }
static inline unsigned long msecs_to_jiffies(int m) { return __builtin_constant_p (m) ? (m) * HZ / MSECS_PER_SEC : __msecs_to_jiffies(m); }
first case with a non-const main: .LFB13: .cfi_startproc subq $8, %rsp #, .cfi_def_cfa_offset 16 movq (%rsi), %rdi # *argv_1(D), xorl %eax, %eax # call atoi # movl $1717986919, %edx #, tmp68 movl %eax, %ecx #, m movl $.LC0, %edi #, imull %edx # tmp68 sarl $31, %ecx #, tmp70 xorl %eax, %eax # sarl $2, %edx #, tmp66 subl %ecx, %edx # tmp70, tmp66 movslq %edx, %rsi # tmp66, tmp71 call printf #
second with a constant: main: .LFB13: .cfi_startproc subq $8, %rsp #, .cfi_def_cfa_offset 16 xorl %esi, %esi # movl $.LC0, %edi #, xorl %eax, %eax # call printf #
giving it another run from scratch somewhere I simply screwed up or overlooked some detail.
thx! hofrat
| |