diff docs/Remarks.rst @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/Remarks.rst	Wed Aug 14 19:46:37 2019 +0900
@@ -0,0 +1,615 @@
+=======
+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)
+      * :ref:`yaml-strtab <yamlstrtabremarks>`
+      * :ref:`bitstream <bitstreamremarks>`
+
+``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
+
+Serialization modes
+===================
+
+There are two modes available for serializing remarks:
+
+``Separate``
+
+    In this mode, the remarks and the metadata are serialized separately. The
+    client is responsible for parsing the metadata first, then use the metadata
+    to correctly parse the remarks.
+
+``Standalone``
+
+    In this mode, the remarks and the metadata are serialized to the same
+    stream. The metadata will always come before the remarks.
+
+    The compiler does not support emitting standalone remarks. This mode is
+    more suited for post-processing tools like linkers, that can merge the
+    remarks for one whole project.
+
+.. _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>``
+
+.. _yamlstrtabremarks:
+
+YAML with a string table
+------------------------
+
+The YAML serialization supports the usage of a string table by using the
+``yaml-strtab`` format.
+
+This format replaces strings in the YAML output with integers representing the
+index in the string table that can be provided separately through metadata.
+
+The following entries can take advantage of the string table while respecting
+YAML rules:
+
+* ``<pass>``
+* ``<name>``
+* ``<function>``
+* ``<file>``
+* ``<value>``
+* ``<arg-file>``
+
+Currently, none of the tools in :ref:`the opt-viewer directory <optviewer>`
+support this format.
+
+.. _optviewer:
+
+YAML metadata
+-------------
+
+The metadata used together with the YAML format is:
+
+* 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
+
+Optional:
+
+* the absolute file path to the serialized remark diagnostics: a
+  null-terminated string.
+
+When the metadata is serialized separately from the remarks, the file path
+should be present and point to the file where the remarks are serialized to.
+
+In case the metadata only acts as a header to the remarks, the file path can be
+omitted.
+
+.. _bitstreamremarks:
+
+LLVM bitstream remarks
+======================
+
+This format is using :doc:`LLVM bitstream <BitCodeFormat>` to serialize remarks
+and their associated metadata.
+
+A bitstream remark stream can be identified by the magic number ``"RMRK"`` that
+is placed at the very beginning.
+
+The format for serializing remarks is composed of two different block types:
+
+.. _bitstreamremarksmetablock:
+
+META_BLOCK
+----------
+
+The block providing information about the rest of the content in the stream.
+
+Exactly one block is expected. Having multiple metadata blocks is an error.
+
+This block can contain the following records:
+
+.. _bitstreamremarksrecordmetacontainerinfo:
+
+``RECORD_META_CONTAINER_INFO``
+
+    The container version and type.
+
+    Version: u32
+
+    Type:    u2
+
+.. _bitstreamremarksrecordmetaremarkversion:
+
+``RECORD_META_REMARK_VERSION``
+
+    The version of the remark entries. This can change independently from the
+    container version.
+
+    Version: u32
+
+.. _bitstreamremarksrecordmetastrtab:
+
+``RECORD_META_STRTAB``
+
+    The string table used by the remark entries. The format of the string table
+    is a sequence of strings separated by ``\0``.
+
+.. _bitstreamremarksrecordmetaexternalfile:
+
+``RECORD_META_EXTERNAL_FILE``
+
+    The external remark file path that contains the remark blocks associated
+    with this metadata. This is an absolute path.
+
+.. _bitstreamremarksremarkblock:
+
+REMARK_BLOCK
+------------
+
+The block describing a remark entry.
+
+0 or more blocks per file are allowed. Each block will depend on the
+:ref:`META_BLOCK <bitstreamremarksmetablock>` in order to be parsed correctly.
+
+This block can contain the following records:
+
+``RECORD_REMARK_HEADER``
+
+    The header of the remark. This contains all the mandatory information about
+    a remark.
+
+    +---------------+---------------------------+
+    | Type          | u3                        |
+    +---------------+---------------------------+
+    | Remark name   | VBR6 (string table index) |
+    +---------------+---------------------------+
+    | Pass name     | VBR6 (string table index) |
+    +---------------+---------------------------+
+    | Function name | VBR6 (string table index) |
+    +---------------+---------------------------+
+
+``RECORD_REMARK_DEBUG_LOC``
+
+    The source location for the corresponding remark. This record is optional.
+
+    +--------+---------------------------+
+    | File   | VBR7 (string table index) |
+    +--------+---------------------------+
+    | Line   | u32                       |
+    +--------+---------------------------+
+    | Column | u32                       |
+    +--------+---------------------------+
+
+``RECORD_REMARK_HOTNESS``
+
+    The hotness of the remark. This record is optional.
+
+    +---------------+---------------------+
+    | Hotness | VBR8 (string table index) |
+    +---------------+---------------------+
+
+``RECORD_REMARK_ARG_WITH_DEBUGLOC``
+
+    A remark argument with an associated debug location.
+
+    +--------+---------------------------+
+    | Key    | VBR7 (string table index) |
+    +--------+---------------------------+
+    | Value  | VBR7 (string table index) |
+    +--------+---------------------------+
+    | File   | VBR7 (string table index) |
+    +--------+---------------------------+
+    | Line   | u32                       |
+    +--------+---------------------------+
+    | Column | u32                       |
+    +--------+---------------------------+
+
+``RECORD_REMARK_ARG_WITHOUT_DEBUGLOC``
+
+    A remark argument with an associated debug location.
+
+    +--------+---------------------------+
+    | Key    | VBR7 (string table index) |
+    +--------+---------------------------+
+    | Value  | VBR7 (string table index) |
+    +--------+---------------------------+
+
+The remark container
+--------------------
+
+Bitstream remarks are designed to be used in two different modes:
+
+``The separate mode``
+
+    The separate mode is the mode that is typically used during compilation. It
+    provides a way to serialize the remark entries to a stream while some
+    metadata is kept in memory to be emitted in the product of the compilation
+    (typically, an object file).
+
+``The standalone mode``
+
+    The standalone mode is typically stored and used after the distribution of
+    a program. It contains all the information that allows the parsing of all
+    the remarks without having any external dependencies.
+
+In order to support multiple modes, the format introduces the concept of a
+bitstream remark container type.
+
+.. _bitstreamremarksseparateremarksmeta:
+
+``SeparateRemarksMeta: the metadata emitted separately``
+
+    This container type expects only a :ref:`META_BLOCK <bitstreamremarksmetablock>` containing only:
+
+    * :ref:`RECORD_META_CONTAINER_INFO <bitstreamremarksrecordmetacontainerinfo>`
+    * :ref:`RECORD_META_STRTAB <bitstreamremarksrecordmetastrtab>`
+    * :ref:`RECORD_META_EXTERNAL_FILE <bitstreamremarksrecordmetaexternalfile>`
+
+    Typically, this is emitted in a section in the object files, allowing
+    clients to retrieve remarks and their associated metadata directly from
+    intermediate products.
+
+``SeparateRemarksFile: the remark entries emitted separately``
+
+    This container type expects only a :ref:`META_BLOCK <bitstreamremarksmetablock>` containing only:
+
+    * :ref:`RECORD_META_CONTAINER_INFO <bitstreamremarksrecordmetacontainerinfo>`
+    * :ref:`RECORD_META_REMARK_VERSION <bitstreamremarksrecordmetaremarkversion>`
+
+    This container type expects 0 or more :ref:`REMARK_BLOCK <bitstreamremarksremarkblock>`.
+
+    Typically, this is emitted in a side-file alongside an object file, and is
+    made to be able to stream to without increasing the memory consumption of
+    the compiler. This is referenced by the :ref:`RECORD_META_EXTERNAL_FILE
+    <bitstreamremarksrecordmetaexternalfile>` entry in the
+    :ref:`SeparateRemarksMeta <bitstreamremarksseparateremarksmeta>` container.
+
+When the parser tries to parse a container that contains the metadata for the
+separate remarks, it should parse the version and type, then keep the string
+table in memory while opening the external file, validating its metadata and
+parsing the remark entries.
+
+The container versions from the separate container should match in order to
+have a well-formed file.
+
+``Standalone: the metadata and the remark entries emitted together``
+
+    This container type expects only a :ref:`META_BLOCK <bitstreamremarksmetablock>` containing only:
+
+    * :ref:`RECORD_META_CONTAINER_INFO <bitstreamremarksrecordmetacontainerinfo>`
+    * :ref:`RECORD_META_REMARK_VERSION <bitstreamremarksrecordmetaremarkversion>`
+    * :ref:`RECORD_META_STRTAB <bitstreamremarksrecordmetastrtab>`
+
+    This container type expects 0 or more :ref:`REMARK_BLOCK <bitstreamremarksremarkblock>`.
+
+A complete output of :program:`llvm-bcanalyzer` on the different container types:
+
+``SeparateRemarksMeta``
+
+.. code-block:: none
+
+    <BLOCKINFO_BLOCK/>
+    <Meta BlockID=8 NumWords=13 BlockCodeSize=3>
+      <Container info codeid=1 abbrevid=4 op0=5 op1=0/>
+      <String table codeid=3 abbrevid=5/> blob data = 'pass\\x00key\\x00value\\x00'
+      <External File codeid=4 abbrevid=6/> blob data = '/path/to/file/name'
+    </Meta>
+
+``SeparateRemarksFile``
+
+.. code-block:: none
+
+    <BLOCKINFO_BLOCK/>
+    <Meta BlockID=8 NumWords=3 BlockCodeSize=3>
+      <Container info codeid=1 abbrevid=4 op0=0 op1=1/>
+      <Remark version codeid=2 abbrevid=5 op0=0/>
+    </Meta>
+    <Remark BlockID=9 NumWords=8 BlockCodeSize=4>
+      <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>
+      <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>
+      <Remark hotness codeid=7 abbrevid=6 op0=999999999/>
+      <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 op3=11 op4=66/>
+    </Remark>
+
+``Standalone``
+
+.. code-block:: none
+
+    <BLOCKINFO_BLOCK/>
+    <Meta BlockID=8 NumWords=15 BlockCodeSize=3>
+      <Container info codeid=1 abbrevid=4 op0=5 op1=2/>
+      <Remark version codeid=2 abbrevid=5 op0=30/>
+      <String table codeid=3 abbrevid=6/> blob data = 'pass\\x00remark\\x00function\\x00path\\x00key\\x00value\\x00argpath\\x00'
+    </Meta>
+    <Remark BlockID=9 NumWords=8 BlockCodeSize=4>
+      <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>
+      <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>
+      <Remark hotness codeid=7 abbrevid=6 op0=999999999/>
+      <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 op3=11 op4=66/>
+    </Remark>
+
+opt-viewer
+==========
+
+The ``opt-viewer`` directory contains a collection of tools that visualize and
+summarize serialized remarks.
+
+The tools only support the ``yaml`` format.
+
+.. _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 the metadata associated to the
+format used to serialize the remarks.
+
+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