forked from OSchip/llvm-project
306 lines
7.7 KiB
ReStructuredText
306 lines
7.7 KiB
ReStructuredText
=======
|
|
Remarks
|
|
=======
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
Introduction to the LLVM remark diagnostics
|
|
===========================================
|
|
|
|
LLVM is able to emit diagnostics from passes describing whether an optimization
|
|
has been performed or missed for a particular reason, which should give more
|
|
insight to users about what the compiler did during the compilation pipeline.
|
|
|
|
There are three main remark types:
|
|
|
|
``Passed``
|
|
|
|
Remarks that describe a successful optimization performed by the compiler.
|
|
|
|
:Example:
|
|
|
|
::
|
|
|
|
foo inlined into bar with (cost=always): always inline attribute
|
|
|
|
``Missed``
|
|
|
|
Remarks that describe an attempt to an optimization by the compiler that
|
|
could not be performed.
|
|
|
|
:Example:
|
|
|
|
::
|
|
|
|
foo not inlined into bar because it should never be inlined
|
|
(cost=never): noinline function attribute
|
|
|
|
``Analysis``
|
|
|
|
Remarks that describe the result of an analysis, that can bring more
|
|
information to the user regarding the generated code.
|
|
|
|
:Example:
|
|
|
|
::
|
|
|
|
16 stack bytes in function
|
|
|
|
::
|
|
|
|
10 instructions in function
|
|
|
|
Enabling optimization remarks
|
|
=============================
|
|
|
|
There are two modes that are supported for enabling optimization remarks in
|
|
LLVM: through remark diagnostics, or through serialized remarks.
|
|
|
|
Remark diagnostics
|
|
------------------
|
|
|
|
Optimization remarks can be emitted as diagnostics. These diagnostics will be
|
|
propagated to front-ends if desired, or emitted by tools like :doc:`llc
|
|
<CommandGuide/llc>` or :doc:`opt <CommandGuide/opt>`.
|
|
|
|
.. option:: -pass-remarks=<regex>
|
|
|
|
Enables optimization remarks from passes whose name match the given (POSIX)
|
|
regular expression.
|
|
|
|
.. option:: -pass-remarks-missed=<regex>
|
|
|
|
Enables missed optimization remarks from passes whose name match the given
|
|
(POSIX) regular expression.
|
|
|
|
.. option:: -pass-remarks-analysis=<regex>
|
|
|
|
Enables optimization analysis remarks from passes whose name match the given
|
|
(POSIX) regular expression.
|
|
|
|
Serialized remarks
|
|
------------------
|
|
|
|
While diagnostics are useful during development, it is often more useful to
|
|
refer to optimization remarks post-compilation, typically during performance
|
|
analysis.
|
|
|
|
For that, LLVM can serialize the remarks produced for each compilation unit to
|
|
a file that can be consumed later.
|
|
|
|
By default, the format of the serialized remarks is :ref:`YAML
|
|
<yamlremarks>`, and it can be accompanied by a :ref:`section <remarkssection>`
|
|
in the object files to easily retrieve it.
|
|
|
|
:doc:`llc <CommandGuide/llc>` and :doc:`opt <CommandGuide/opt>` support the
|
|
following options:
|
|
|
|
|
|
``Basic options``
|
|
|
|
.. option:: -pass-remarks-output=<filename>
|
|
|
|
Enables the serialization of remarks to a file specified in <filename>.
|
|
|
|
By default, the output is serialized to :ref:`YAML <yamlremarks>`.
|
|
|
|
.. option:: -pass-remarks-format=<format>
|
|
|
|
Specifies the output format of the serialized remarks.
|
|
|
|
Supported formats:
|
|
|
|
* :ref:`yaml <yamlremarks>` (default)
|
|
|
|
``Content configuration``
|
|
|
|
.. option:: -pass-remarks-filter=<regex>
|
|
|
|
Only passes whose name match the given (POSIX) regular expression will be
|
|
serialized to the final output.
|
|
|
|
.. option:: -pass-remarks-with-hotness
|
|
|
|
With PGO, include profile count in optimization remarks.
|
|
|
|
.. option:: -pass-remarks-hotness-threshold
|
|
|
|
The minimum profile count required for an optimization remark to be
|
|
emitted.
|
|
|
|
Other tools that support remarks:
|
|
|
|
:program:`llvm-lto`
|
|
|
|
.. option:: -lto-pass-remarks-output=<filename>
|
|
.. option:: -lto-pass-remarks-filter=<regex>
|
|
.. option:: -lto-pass-remarks-format=<format>
|
|
.. option:: -lto-pass-remarks-with-hotness
|
|
.. option:: -lto-pass-remarks-hotness-threshold
|
|
|
|
:program:`gold-plugin` and :program:`lld`
|
|
|
|
.. option:: -opt-remarks-filename=<filename>
|
|
.. option:: -opt-remarks-filter=<regex>
|
|
.. option:: -opt-remarks-format=<format>
|
|
.. option:: -opt-remarks-with-hotness
|
|
|
|
.. _yamlremarks:
|
|
|
|
YAML remarks
|
|
============
|
|
|
|
A typical remark serialized to YAML looks like this:
|
|
|
|
.. code-block:: yaml
|
|
|
|
--- !<TYPE>
|
|
Pass: <pass>
|
|
Name: <name>
|
|
DebugLoc: { File: <file>, Line: <line>, Column: <column> }
|
|
Function: <function>
|
|
Hotness: <hotness>
|
|
Args:
|
|
- <key>: <value>
|
|
DebugLoc: { File: <arg-file>, Line: <arg-line>, Column: <arg-column> }
|
|
|
|
The following entries are mandatory:
|
|
|
|
* ``<TYPE>``: can be ``Passed``, ``Missed``, ``Analysis``,
|
|
``AnalysisFPCommute``, ``AnalysisAliasing``, ``Failure``.
|
|
* ``<pass>``: the name of the pass that emitted this remark.
|
|
* ``<name>``: the name of the remark coming from ``<pass>``.
|
|
* ``<function>``: the mangled name of the function.
|
|
|
|
If a ``DebugLoc`` entry is specified, the following fields are required:
|
|
|
|
* ``<file>``
|
|
* ``<line>``
|
|
* ``<column>``
|
|
|
|
If an ``arg`` entry is specified, the following fields are required:
|
|
|
|
* ``<key>``
|
|
* ``<value>``
|
|
|
|
If a ``DebugLoc`` entry is specified within an ``arg`` entry, the following
|
|
fields are required:
|
|
|
|
* ``<arg-file>``
|
|
* ``<arg-line>``
|
|
* ``<arg-column>``
|
|
|
|
opt-viewer
|
|
==========
|
|
|
|
The ``opt-viewer`` directory contains a collection of tools that visualize and
|
|
summarize serialized remarks.
|
|
|
|
.. _optviewerpy:
|
|
|
|
opt-viewer.py
|
|
-------------
|
|
|
|
Output a HTML page which gives visual feedback on compiler interactions with
|
|
your program.
|
|
|
|
:Examples:
|
|
|
|
::
|
|
|
|
$ opt-viewer.py my_yaml_file.opt.yaml
|
|
|
|
::
|
|
|
|
$ opt-viewer.py my_build_dir/
|
|
|
|
|
|
opt-stats.py
|
|
------------
|
|
|
|
Output statistics about the optimization remarks in the input set.
|
|
|
|
:Example:
|
|
|
|
::
|
|
|
|
$ opt-stats.py my_yaml_file.opt.yaml
|
|
|
|
Total number of remarks 3
|
|
|
|
|
|
Top 10 remarks by pass:
|
|
inline 33%
|
|
asm-printer 33%
|
|
prologepilog 33%
|
|
|
|
Top 10 remarks:
|
|
asm-printer/InstructionCount 33%
|
|
inline/NoDefinition 33%
|
|
prologepilog/StackSize 33%
|
|
|
|
opt-diff.py
|
|
-----------
|
|
|
|
Produce a new YAML file which contains all of the changes in optimizations
|
|
between two YAML files.
|
|
|
|
Typically, this tool should be used to do diffs between:
|
|
|
|
* new compiler + fixed source vs old compiler + fixed source
|
|
* fixed compiler + new source vs fixed compiler + old source
|
|
|
|
This diff file can be displayed using :ref:`opt-viewer.py <optviewerpy>`.
|
|
|
|
:Example:
|
|
|
|
::
|
|
|
|
$ opt-diff.py my_opt_yaml1.opt.yaml my_opt_yaml2.opt.yaml -o my_opt_diff.opt.yaml
|
|
$ opt-viewer.py my_opt_diff.opt.yaml
|
|
|
|
.. _remarkssection:
|
|
|
|
Emitting remark diagnostics in the object file
|
|
==============================================
|
|
|
|
A section containing metadata on remark diagnostics will be emitted when
|
|
-remarks-section is passed. The section contains:
|
|
|
|
* a magic number: "REMARKS\\0"
|
|
* the version number: a little-endian uint64_t
|
|
* the total size of the string table (the size itself excluded):
|
|
little-endian uint64_t
|
|
* a list of null-terminated strings
|
|
* the absolute file path to the serialized remark diagnostics: a
|
|
null-terminated string.
|
|
|
|
The section is named:
|
|
|
|
* ``__LLVM,__remarks`` (MachO)
|
|
* ``.remarks`` (ELF)
|
|
|
|
C API
|
|
=====
|
|
|
|
LLVM provides a library that can be used to parse remarks through a shared
|
|
library named ``libRemarks``.
|
|
|
|
The typical usage through the C API is like the following:
|
|
|
|
.. code-block:: c
|
|
|
|
LLVMRemarkParserRef Parser = LLVMRemarkParserCreateYAML(Buf, Size);
|
|
LLVMRemarkEntryRef Remark = NULL;
|
|
while ((Remark = LLVMRemarkParserGetNext(Parser))) {
|
|
// use Remark
|
|
}
|
|
bool HasError = LLVMRemarkParserHasError(Parser);
|
|
LLVMRemarkParserDispose(Parser);
|
|
|
|
.. FIXME: add documentation for llvm-opt-report.
|
|
.. FIXME: add documentation for Passes supporting optimization remarks
|
|
.. FIXME: add documentation for IR Passes
|
|
.. FIXME: add documentation for CodeGen Passes
|