简体   繁体   中英

C++ Does the compiler optimize out known statements?

This question no doubt would constitute premature optimization, however I want to know what the compiler will do with this to learn more about how the compiler works.

In the below example, can I expect the compiler to produce 2 or 3 functions with the if statements removed, or is it always going to execute that if statement on every iteration of the loop? Is the compiler going to optimize out the if statement on the basis that the function is called only with a parameter that is known at compile time?

void myfunction(int a) {
   for (int i = 0; i < 1000000; ++i) {
      // here are various calculations that are the same regardless of a
      if (a == 0) {
         dosomething1(someValue);
      } else if (a == 1) {
         dosomething2(someValue);
      } else {
         dosomething3(someValue);
      }
   }
}

myfunction(0);
myfunction(1);

This depends entirely on the compiler and optimization level.

For example, GCC 10 will transform loops to hoist invariants out at -O3 level. We can see in this demo ( Godbolt link ) that it generated 3 separate loops essentially:

myfunction(int):
        push    rbp
        push    rbx
        mov     ebx, edi
        sub     rsp, 8
        test    edi, edi
        je      .L2
        cmp     edi, 1
        je      .L6
        xor     ebp, ebp
.L4:
        mov     edi, ebx
        xor     edi, ebp
        add     ebp, 1
        call    dosomething3(int)
        cmp     ebp, 1000000
        jne     .L4
.L1:
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret
.L2:
        mov     edi, ebx
        add     ebx, 1
        call    dosomething1(int)
        cmp     ebx, 1000000
        jne     .L2
        jmp     .L1
.L6:
        xor     ebx, ebx
.L3:
        mov     edi, ebx
        add     ebx, 1
        xor     edi, 1
        call    dosomething2(int)
        cmp     ebx, 1000000
        jne     .L3
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret

But at -O2 level the checks on a are inside the loop:

myfunction(int):
        push    rbp
        mov     ebp, edi
        push    rbx
        xor     ebx, ebx
        sub     rsp, 8
        jmp     .L5
.L2:
        mov     edi, ebp
        xor     edi, ebx
        cmp     ebp, 1
        je      .L9
        call    dosomething3(int)
.L3:
        add     ebx, 1
        cmp     ebx, 1000000
        je      .L10
.L5:
        test    ebp, ebp
        jne     .L2
        mov     edi, ebx
        add     ebx, 1
        call    dosomething1(int)
        cmp     ebx, 1000000
        jne     .L5
.L10:
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret
.L9:
        call    dosomething2(int)
        jmp     .L3

So you'd have to check how your specific compiler handles this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM