Tyler Shellberg
Tyler Shellberg

Reputation: 1356

Will GCC optimize away an inline accessor?

Let's say I have this class

class Point 
{
  inline float x() const { return v[0]; }
  inline float y() const { return v[1]; }
  inline float z() const { return v[2]; }

  float v[3];
};

And I do:

Point myPoint;
myPoint[0] = 5;

// unrelated code goes here

float myVal = myPoint.x() + 5;

Will GCC on -O2 or -O3 optimize away any calls to x() with just getting v[0]? IE:

float myVal = myPoint.v[0] + 5;

Or is there a reason why this is impossible?

Update: Should mention I do realize inline is more of a suggestion to the compiler than anything else, but was wondering anyways.

As an additional question, will templating this class have any effect on the optimizations that can be done?

Upvotes: 3

Views: 372

Answers (3)

Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29985

It may or may not be inlined. No guarantees there. But if you want it to be always inlined, use the [[gnu::always_inline]] attribute. See the docs here. Use this attribute only if you know what you're doing. In most cases it's best to let the compiler decide what optimizations are suitable.

Upvotes: 2

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123243

You can observe the difference here: https://godbolt.org/

Lets say you have this code (yours does not compile: missing ; and Point has no []):

struct Point 
{
  inline float x() const { return v[0]; }
  inline float y() const { return v[1]; }
  inline float z() const { return v[2]; }

  float v[3];
};

int main() {
    Point myPoint;
    myPoint.v[0] = 5;

    float myVal = myPoint.x() + 5;
    return myVal;
}

Then gcc 9.2 emits:

Point::x() const:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        movss   xmm0, DWORD PTR [rax]
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        movss   xmm0, DWORD PTR .LC0[rip]
        movss   DWORD PTR [rbp-16], xmm0
        lea     rax, [rbp-16]
        mov     rdi, rax
        call    Point::x() const
        movss   xmm1, DWORD PTR .LC0[rip]
        addss   xmm0, xmm1
        movss   DWORD PTR [rbp-4], xmm0
        movss   xmm0, DWORD PTR [rbp-4]
        cvttss2si       eax, xmm0
        leave
        ret
.LC0:
        .long   1084227584

I am not that proficient in reading assembler, but I thing comparing the above to the output with -O3 is convincing enough:

main:
        mov     eax, 10
        ret

The generated code can vary dramatically depending on the context, I just wanted to know if there was any fundamental reasons it could never or would always happen.

The above example already disproves the "never". "Always", however is hard to get. The guarantee you get is that the resulting code behaves as if the compiler translated your code without optimizations applied. With few exceptions optimizations are usually not guaranteed. To be really sure I would only rely on looking at the compilers output in the realistic scenario.

Upvotes: 2

Acorn
Acorn

Reputation: 26196

Will GCC optimize away an inline accessor?

All optimizing compilers will do so. It is a trivial optimization compared to other ones.

Or is there a reason why this is impossible?

There is no reason that makes it impossible, yet there is no guarantee either.

As an additional question, will templating this class have any effect on the optimizations that can be done?

No. But, of course, a compiler may have different inlining thresholds for templates.

Upvotes: 6

Related Questions