reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372
  373
  374
  375
  376
  377
  378
  379
  380
  381
  382
  383
  384
  385
  386
  387
  388
  389
  390
  391
  392
  393
  394
  395
  396
  397
  398
  399
  400
  401
  402
  403
  404
  405
  406
  407
  408
  409
  410
  411
  412
  413
  414
  415
  416
  417
  418
  419
  420
  421
  422
  423
  424
  425
  426
  427
  428
  429
  430
  431
  432
  433
  434
  435
  436
  437
  438
  439
  440
  441
  442
  443
  444
  445
  446
  447
  448
  449
  450
  451
  452
  453
  454
  455
  456
  457
  458
  459
  460
  461
  462
  463
  464
  465
  466
  467
  468
  469
  470
  471
  472
  473
  474
  475
  476
  477
  478
  479
  480
  481
  482
  483
  484
  485
  486
  487
  488
  489
  490
  491
  492
  493
  494
  495
  496
  497
  498
  499
  500
  501
  502
  503
  504
  505
  506
  507
  508
  509
  510
  511
  512
  513
  514
  515
  516
  517
  518
  519
  520
  521
  522
  523
  524
  525
  526
  527
  528
  529
  530
  531
  532
  533
  534
  535
  536
  537
  538
  539
  540
  541
  542
  543
  544
  545
  546
  547
  548
  549
  550
  551
  552
  553
  554
  555
  556
  557
  558
  559
  560
  561
  562
  563
  564
  565
  566
  567
  568
  569
  570
  571
  572
  573
  574
  575
  576
  577
  578
  579
  580
  581
  582
  583
  584
  585
  586
  587
  588
  589
  590
  591
  592
  593
  594
  595
  596
  597
  598
  599
  600
  601
  602
  603
  604
  605
  606
  607
  608
  609
  610
  611
  612
  613
  614
  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