Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC doesn't make use of inc

The GCC compiler

$ gcc --version
gcc (GCC) 4.8.2
...

doesn't generate an inc assembly instruction, where it could actually be useful, like in this C program:

int main(int argc, char **argv)
{
    int sum = 0;
    int i;
    for(i = 0; i < 1000000000L; i++)                     <---- that "i++"
        sum += i;
    return sum;
}

Instead, it generates an add instruction:

0000000000000000 <main>:
   0:   31 d2                   xor    %edx,%edx
   2:   31 c0                   xor    %eax,%eax
   4:   0f 1f 40 00             nopl   0x0(%rax)
   8:   01 d0                   add    %edx,%eax
   a:   83 c2 01                add    $0x1,%edx         <---- HERE
   d:   81 fa 00 ca 9a 3b       cmp    $0x3b9aca00,%edx
  13:   75 f3                   jne    8 <main+0x8>
  15:   f3 c3                   repz retq 

Why does it do this?

EDIT: I used gcc -O2 to compile this. gcc -Os does indeed generate an inc instruction. Isn't using inc more a speed optimization than a space optimization?

like image 314
heinrich5991 Avatar asked Nov 10 '13 13:11

heinrich5991


2 Answers

Try it with -march=<your machine>. The result may be different.

However, note that add $1, %reg is not necessarily a poor choice. Although inc and dec have smaller encodings, which is attractive, they suffer from the fact that they only partially update flags, leading to false dependency problems. The Intel optimisation manual contains this comment (my emphasis):

The INC and DEC instructions modify only a subset of the bits in the flag register. This creates a dependence on all previous writes of the flag register. This is especially problematic when these instructions are on the critical path because they are used to change an address for a load on which many other instructions depend. Assembly/Compiler Coding Rule 33. (M impact, H generality) INC and DEC instructions should be replaced with ADD or SUB instructions, because ADD and SUB overwrite all flags, whereas INC and DEC do not, therefore creating false dependencies on earlier instructions that set the flags.

like image 110
gsg Avatar answered Sep 24 '22 11:09

gsg


It may does depend on the exact optimization settings you are using (or not using). GCC can either be told to optimise for time or space (although optimising for space can sometimes be an effective way to optimise for execution time!)

Just because an instruction is available for a specialist task, doesn't mean it's necessarily the most efficient one to use.

Some of the old x86 instructions are actually implemented in microcode, not in hardware any more, because they are rarely used and aren't worth implementing in hardware. But this can make them slower. I don't know whether inc is such an instruction.

Also, if you don't tell GCC which x86 processor model you are going to be running the code on, it will have to guess at something generic.

like image 22
Robin Green Avatar answered Sep 24 '22 11:09

Robin Green