llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.92k stars 11.52k forks source link

Missing optimization: Devirtualize functions if there's only one actual instantiated child class #94924

Open Alcaro opened 3 months ago

Alcaro commented 3 months ago
struct IUnknown {
    virtual void Release() = 0;
};

namespace {
    struct base_object : IUnknown {
        void Release() override
        {
            delete this;
        }
        virtual ~base_object() {}
    };

    class the_impl : public base_object {};
}

IUnknown* create_it() { return new the_impl(); }

Expected: Release() should see that the_impl is the only child class that's used, and devirtualize its dtor (then inline it and just call operator delete). GCC performs this optimization.

Actual: It calls into the vtable.

https://godbolt.org/z/vbYY4ezqE

Journeyman1337 commented 3 months ago

I think this is relevant:

https://blog.llvm.org/2017/03/devirtualization-in-llvm-and-clang.html

wangbyby commented 3 months ago

llvm has WholeProgramDevirtPass, but only used in lto/thinlto

Alcaro commented 3 months ago

I think this is relevant:

That it is, but it's also seven years old. Clang and LLVM have learned a lot since then, and I feel it's safe to revisit every 'can't optimize' from back then.

llvm has WholeProgramDevirtPass, but only used in lto/thinlto

Can't reproduce, it's not devirtualized with LTO either. https://godbolt.org/z/r6hP9Mzhc