| ======= |
| 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 |
| LLVMRemarkEntryDispose(Remark); // Release memory. |
| } |
| 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 |