Qt::_*ordering: de-pessimize conversion to std types

Instead of an if-else-if chain, use a switch and Q_UNREACHABLE_RETURN.
We don't need the GCC-8 workaround for Q_UNREACHABLE_RETURN in
constexpr here as GCC-8 doesn't have <compare>, yet, so it will never
compile this code.

Using this test:

  extern Qt::partial_ordering qt_partial_ordering() noexcept;
  std::partial_ordering qt2std() { return qt_partial_ordering(); }

I see these codegen improvements:

Clang -O2 before:
  qt2std():                             # @qt2std()
        pushq   %rax
        callq   qt_partial_ordering()@PLT
        testb   %al, %al
        je      .LBB36_3
        movzbl  %al, %ecx
        cmpl    55, %ecx
        jne     .LBB36_4
        popq    %rcx
        retq
  .LBB36_3:
        xorl    %eax, %eax
        popq    %rcx
        retq
  .LBB36_4:
        cmpb    , %al
        sete    %cl
        movb    , %al
        subb    %cl, %al
        popq    %rcx
        retq

Clang -O2 now:
  qt2std():
       jmp     qt_partial_ordering()@PLT  $# TAIL-CALL

GCC -O2 before:
  qt2std():
        subq    $8, %rsp
        call    qt_partial_ordering()@PLT
        cmpb    $-1, %al
        je      .L194
        testb   %al, %al
        jne     .L203
  .L194:
        addq    $8, %rsp
        ret
  .L203:
        cmpb    $1, %al
        movl    $2, %edx
        cmovne  %edx, %eax
        addq    $8, %rsp
        ret

GCC -O2 now:
  qt2std():
        subq    $8, %rsp
        call    qt_partial_ordering()@PLT
        cmpb    $-1, %al
        je      .L194
        cmpb    $1, %al
        je      .L194
        xorl    %edx, %edx
        cmpb    $2, %al
        cmovne  %edx, %eax
  .L194:
        addq    $8, %rsp
        ret

GCC needs -O3 to produce now:
  qt2std():
        subq    $8, %rsp
        call    qt_partial_ordering()@PLT
        addq    $8, %rsp

Change-Id: Ic8c57c6e1bc39e247999b45dc263a8a8aef07dd0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
bb10
Marc Mutz 2023-11-16 10:09:12 +01:00 committed by Ivan Solovev
parent 4b6f757020
commit 9c03935c9a
1 changed files with 19 additions and 25 deletions

View File

@ -266,15 +266,13 @@ public:
constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
{
if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Less)
return std::partial_ordering::less;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Equivalent)
return std::partial_ordering::equivalent;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Greater)
return std::partial_ordering::greater;
else if (static_cast<QtPrivate::Uncomparable>(m_order) == QtPrivate::Uncomparable::Unordered)
return std::partial_ordering::unordered;
return std::partial_ordering::unordered;
switch (m_order) {
case qToUnderlying(QtPrivate::Ordering::Less): return std::partial_ordering::less;
case qToUnderlying(QtPrivate::Ordering::Greater): return std::partial_ordering::greater;
case qToUnderlying(QtPrivate::Ordering::Equivalent): return std::partial_ordering::equivalent;
case qToUnderlying(QtPrivate::Uncomparable::Unordered): return std::partial_ordering::unordered;
}
Q_UNREACHABLE_RETURN(std::partial_ordering::unordered);
}
friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
@ -416,13 +414,12 @@ public:
constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
{
if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Less)
return std::weak_ordering::less;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Equivalent)
return std::weak_ordering::equivalent;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Greater)
return std::weak_ordering::greater;
return std::weak_ordering::equivalent;
switch (m_order) {
case qToUnderlying(QtPrivate::Ordering::Less): return std::weak_ordering::less;
case qToUnderlying(QtPrivate::Ordering::Greater): return std::weak_ordering::greater;
case qToUnderlying(QtPrivate::Ordering::Equivalent): return std::weak_ordering::equivalent;
}
Q_UNREACHABLE_RETURN(std::weak_ordering::equivalent);
}
friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
@ -596,15 +593,12 @@ public:
constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
{
if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Less)
return std::strong_ordering::less;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Equivalent)
return std::strong_ordering::equivalent;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Equal)
return std::strong_ordering::equal;
else if (static_cast<QtPrivate::Ordering>(m_order) == QtPrivate::Ordering::Greater)
return std::strong_ordering::greater;
return std::strong_ordering::equivalent;
switch (m_order) {
case qToUnderlying(QtPrivate::Ordering::Less): return std::strong_ordering::less;
case qToUnderlying(QtPrivate::Ordering::Greater): return std::strong_ordering::greater;
case qToUnderlying(QtPrivate::Ordering::Equal): return std::strong_ordering::equal;
}
Q_UNREACHABLE_RETURN(std::strong_ordering::equal);
}
friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept