======= 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 ` or :doc:`opt `. .. option:: -pass-remarks= Enables optimization remarks from passes whose name match the given (POSIX) regular expression. .. option:: -pass-remarks-missed= Enables missed optimization remarks from passes whose name match the given (POSIX) regular expression. .. option:: -pass-remarks-analysis= 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 `, and it can be accompanied by a :ref:`section ` in the object files to easily retrieve it. :doc:`llc ` and :doc:`opt ` support the following options: ``Basic options`` .. option:: -pass-remarks-output= Enables the serialization of remarks to a file specified in . By default, the output is serialized to :ref:`YAML `. .. option:: -pass-remarks-format= Specifies the output format of the serialized remarks. Supported formats: * :ref:`yaml ` (default) ``Content configuration`` .. option:: -pass-remarks-filter= 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= .. option:: -lto-pass-remarks-filter= .. option:: -lto-pass-remarks-format= .. option:: -lto-pass-remarks-with-hotness .. option:: -lto-pass-remarks-hotness-threshold :program:`gold-plugin` and :program:`lld` .. option:: -opt-remarks-filename= .. option:: -opt-remarks-filter= .. option:: -opt-remarks-format= .. option:: -opt-remarks-with-hotness .. _yamlremarks: YAML remarks ============ A typical remark serialized to YAML looks like this: .. code-block:: yaml --- ! Pass: Name: DebugLoc: { File: , Line: , Column: } Function: Hotness: Args: - : DebugLoc: { File: , Line: , Column: } The following entries are mandatory: * ````: can be ``Passed``, ``Missed``, ``Analysis``, ``AnalysisFPCommute``, ``AnalysisAliasing``, ``Failure``. * ````: the name of the pass that emitted this remark. * ````: the name of the remark coming from ````. * ````: the mangled name of the function. If a ``DebugLoc`` entry is specified, the following fields are required: * ```` * ```` * ```` If an ``arg`` entry is specified, the following fields are required: * ```` * ```` If a ``DebugLoc`` entry is specified within an ``arg`` entry, the following fields are required: * ```` * ```` * ```` 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 `. :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