Il 26/05/19 12:36, René J. V. Bertin ha scritto:
Giuseppe D'Angelo via Interest wrote:

Hi,

On the other hand, Q_ASSUME(cond) tells the compiler that cond is true,

After reading the MS doc I sort of understand how you can use the construct to
implement a Q_UNREACHABLE (but in the example given I don't see the codegen
advantage of `default: Q_UNREACHABLE` vs. not adding a `default:` at all).

There isn't usually a codegen advantage between the two (or maybe there is only in some corner cases; to my book that's a bug report for "missed optimization"). For instance: on compilers lacking a dedicated builtin, Q_ASSUME(x) is indeed implemented as

if (x) {} else { __builtin_unreachable(); }

which clearly shows the semantics of Q_ASSUME, and that it can be implemented in terms of Q_UNREACHABLE.




Look here at a possible example at how it can improve codegen:

https://gcc.godbolt.org/z/KlWBRY

Not really, I'm afraid.

The only thing that's evident to me from there is that there is much fewer
generated machine code when you add the assume statement. I don't see at all why
that would be, what difference it would make for the loop that it is always
iterated over a multiple of 16. I thought the difference might be in evaluating
the `i < count` expression, but even after trying to factor that out the
difference remains:
https://gcc.godbolt.org/z/2Zclp5

In my example, if we tell the compiler that count is a multiple of 16, then the compiler can do a better job at generating code. In the specifics, the compiler can use a vectorized loop using AVX to to the sum 8 integers at a time. If the compiler knows that count is a multiple of 16, then that loop is enough, and indeed only that loop gets emitted. If the compiler does NOT know, then it does the vectorized loop as much as it can, but then it has to deal with the remaining 0-7 integers, which get dealt in the following generated code, which is an unrolled for loop.

In your example, the compiler can easily deduce that i and count are _both_ multiple of 16 (because they have the same value), so it applies the same optimization. Maybe the codegen is slightly different due to the decreasing loop induction variable that could throw the optimizer off.


Take home message for me is that this is a construct that's probably useful only
if you have very intimate knowledge about code generation, and thus not very
cross-platform/compiler (and even less cross-architecture). Except for the
Q_UNREACHABLE thing.

The optimization is probably the most compelling aspect of it, because Q_ASSUMEs are left in release builds. The other aspect is of course an indication for who reads the code -- that you're making an assumption on certain conditions, so the following code is valid IFF those conditions hold.


What I was hoping it might do is what the Qt documentation suggests, a more
graceful version of a Q_ASSERT. That is, a version that does the usual abort in
debug builds, but becomes a regular if in production code. I've seen too many
examples of coding where a Q_ASSERT is used to guard against situations that are
*assumed* never to occur, and then forgotten (or the devs assume everyone else
uses debug/development builds). In many if not most of those cases it's trivial
to add a graceful handling of the situation.

In production code Q_ASSUME is left (as a hint to the compiler); Q_ASSERT disappears. That's why they're different macros (although, as you point out, conceptually they indicate the same thing -- that a condition is always true, else UB).

In debug builds, Q_ASSUME becomes a Q_ASSERT, so you can debug the case in which the assumption is false.


Hope this helps,

--
Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

Attachment: smime.p7s
Description: Firma crittografica S/MIME

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to