forked from OSchip/llvm-project
74 lines
3.8 KiB
ReStructuredText
74 lines
3.8 KiB
ReStructuredText
===================
|
|
Misexpect
|
|
===================
|
|
.. contents::
|
|
|
|
.. toctree::
|
|
:maxdepth: 1
|
|
|
|
When developers use ``llvm.expect`` intrinsics, i.e., through use of
|
|
``__builtin_expect(...)``, they are trying to communicate how their code is
|
|
expected to behave at runtime to the optimizer. These annotations, however, can
|
|
be incorrect for a variety of reasons: changes to the code base invalidate them
|
|
silently, the developer mis-annotated them (e.g., using ``LIKELY`` instead of
|
|
``UNLIKELY``), or perhaps they assumed something incorrectly when they wrote
|
|
the annotation. Regardless of why, it is useful to detect these situations so
|
|
that the optimizer can make more useful decisions about the code. MisExpect
|
|
diagnostics are intended to help developers identify and address these
|
|
situations, by comparing the use of the ``llvm.expect`` intrinsic to the ground
|
|
truth provided by a profiling input.
|
|
|
|
The MisExpect checks in the LLVM backend follow a simple procedure: if there is
|
|
a mismatch between the branch weights collected during profiling and those
|
|
supplied by an ``llvm.expect`` intrinsic, then it will emit a diagnostic
|
|
message to the user.
|
|
|
|
The most natural place to perform the verification is just prior to when
|
|
branch weights are assigned to the target instruction in the form of
|
|
branch weight metadata.
|
|
|
|
There are 3 key places in the LLVM backend where branch weights are
|
|
created and assigned based on profiling information or the use of the
|
|
``llvm.expect`` intrinsic, and our implementation focuses on these
|
|
places to perform the verification.
|
|
|
|
We calculate the threshold for emitting MisExpect related diagnostics
|
|
based on the values the compiler assigns to ``llvm.expect`` intrinsics,
|
|
which can be set through the ``-likely-branch-weight`` and
|
|
``-unlikely-branch-weight`` LLVM options. During verification, if the
|
|
profile weights mismatch the calculated threshold, then we will emit a
|
|
remark or warning detailing a potential performance regression. The
|
|
diagnostic also reports the percentage of the time the annotation was
|
|
correct during profiling to help developers reason about how to proceed.
|
|
|
|
The diagnostics are also available in the form of optimization remarks,
|
|
which can be serialized and processed through the ``opt-viewer.py``
|
|
scripts in LLVM.
|
|
|
|
.. option:: -pass-remarks=misexpect
|
|
|
|
Enables optimization remarks for misexpect when profiling data conflicts with
|
|
use of ``llvm.expect`` intrinsics.
|
|
|
|
|
|
.. option:: -pgo-warn-misexpect
|
|
|
|
Enables misexpect warnings when profiling data conflicts with use of
|
|
``llvm.expect`` intrinsics.
|
|
|
|
LLVM supports 4 types of profile formats: Frontend, IR, CS-IR, and
|
|
Sampling. MisExpect Diagnostics are compatible with all Profiling formats.
|
|
|
|
+----------------+--------------------------------------------------------------------------------------+
|
|
| Profile Type | Description |
|
|
+================+======================================================================================+
|
|
| Frontend | Profiling instrumentation added during compilation by the frontend, i.e. ``clang`` |
|
|
+----------------+--------------------------------------------------------------------------------------+
|
|
| IR | Profiling instrumentation added during by the LLVM backend |
|
|
+----------------+--------------------------------------------------------------------------------------+
|
|
| CS-IR | Context Sensitive IR based profiles |
|
|
+----------------+--------------------------------------------------------------------------------------+
|
|
| Sampling | Profiles collected through sampling with external tools, such as ``perf`` on Linux |
|
|
+----------------+--------------------------------------------------------------------------------------+
|
|
|