https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101049

            Bug ID: 101049
           Summary: std::variant:  missed optimization in std::visit() on
                    more than one variant
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vermaelen.wouter at gmail dot com
  Target Milestone: ---

// https://godbolt.org/z/T8f89fq1z
// --------------------------------------
#include <variant>

struct Base {};
struct A : Base { int a; };
struct B : Base {};
struct C : Base {};
struct D : Base {};

using V = std::variant<A, B, C, D>;

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };

bool operator==(const V& v1, const V& v2)
{
    return std::visit(overloaded{
        [](const A& x, const A& y) { return x.a == y.a; },
        [&](const Base&, const Base&) { return v1.index() == v2.index(); }
    }, v1, v2);
}
// --------------------------------------

The call to std::visit() is implemented using a table containing 4x4 = 16
function pointers. However 15 out of these 16 sub-functions are identical. It
would be nice if these would be shared.

Also (before sharing) in these 16 sub-functions the value of a sub-expression
like 'v1.index()' could be known during compile-time. It would also be nice if
the compiler could exploit this knowledge.

So ideally I'd like the compiler to produce only 3 different sub-functions:
        [](const A& x, const A& y) { return x.a == y.a; },
        []() { return true; }
        []() { return false; }
And then fill-in the table with 16 function-pointers to the appropriate of
these 3 functions.

Thanks.
  • [Bug libstdc++/101049] New:... vermaelen.wouter at gmail dot com via Gcc-bugs

Reply via email to