[llvm-branch-commits] [llvm] [docs] Migrate 22 popular LLVM docs to MyST (PR #201244)
Reid Kleckner via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jun 3 13:49:59 PDT 2026
https://github.com/rnk updated https://github.com/llvm/llvm-project/pull/201244
>From ffa93a08ea0c134213cd967e9b033ac207d7a6c5 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Tue, 2 Jun 2026 21:42:53 +0000
Subject: [PATCH 1/3] [docs] Migrate 22 popular LLVM docs to MyST
This was done with LLM assistance.
I opened all 22 docs in a browser and scrolled through them, catching
and fixing a few errors.
---
llvm/docs/CMake.md | 1697 +++++-----
llvm/docs/CodeGenerator.md | 1966 ++++++------
llvm/docs/CodingStandards.md | 1771 +++++------
llvm/docs/CommandGuide/index.md | 197 +-
llvm/docs/Contributing.md | 227 +-
llvm/docs/DeveloperPolicy.md | 1970 ++++++------
llvm/docs/GettingInvolved.md | 536 ++--
llvm/docs/GettingStarted.md | 1051 +++----
llvm/docs/GettingStartedTutorials.md | 82 +-
llvm/docs/GitHub.md | 497 ++-
llvm/docs/Passes.md | 708 ++---
llvm/docs/ProgrammersManual.md | 4371 ++++++++++++--------------
llvm/docs/RFCProcess.md | 70 +-
llvm/docs/Reference.md | 415 ++-
llvm/docs/SourceLevelDebugging.md | 2861 ++++++++---------
llvm/docs/TableGen/index.md | 345 +-
llvm/docs/TestingGuide.md | 1191 +++----
llvm/docs/UserGuides.md | 567 ++--
llvm/docs/WritingAnLLVMBackend.md | 2625 ++++++++--------
llvm/docs/WritingAnLLVMNewPMPass.md | 310 +-
llvm/docs/WritingAnLLVMPass.md | 965 +++---
llvm/docs/conf.py | 7 +
llvm/docs/index.md | 130 +-
23 files changed, 11831 insertions(+), 12728 deletions(-)
diff --git a/llvm/docs/CMake.md b/llvm/docs/CMake.md
index 4d6aa2b99b9c9..2d79d65f5abba 100644
--- a/llvm/docs/CMake.md
+++ b/llvm/docs/CMake.md
@@ -1,997 +1,1104 @@
-========================
-Building LLVM with CMake
-========================
+# Building LLVM with CMake
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction
-============
+## Introduction
-`CMake <http://www.cmake.org/>`_ is a cross-platform build-generator tool. CMake
+[CMake](http://www.cmake.org/) is a cross-platform build-generator tool. CMake
does not build the project; it generates the files needed by your build tool
(GNU make, Visual Studio, etc.) for building LLVM.
-If **you are a new contributor**, please start with the :doc:`GettingStarted`
-page. This page is geared for existing contributors moving from the
-legacy configure/make system.
+If **you are a new contributor**, please start with the {doc}`GettingStarted`
+page. This page is geared for existing contributors moving from the legacy
+configure/make system.
If you are really anxious about getting a functional LLVM build, go to the
-`Quick start`_ section. If you are a CMake novice, start with `Basic CMake usage`_
-and then go back to the `Quick start`_ section once you know what you are doing. The
-`Options and variables`_ section is a reference for customizing your build. If
-you already have experience with CMake, this is the recommended starting point.
+[Quick start](#quick-start) section. If you are a CMake novice, start with
+[Basic CMake usage](#basic-cmake-usage) and then go back to the [Quick
+start](#quick-start) section once you know what you are doing. The [Options and
+variables](#options-and-variables) section is a reference for customizing your
+build. If you already have experience with CMake, this is the recommended
+starting point.
-This page is geared towards users of the LLVM CMake build. If you're looking for
-information about modifying the LLVM CMake build system, you may want to see the
-:doc:`CMakePrimer` page. It has a basic overview of the CMake language.
+This page is geared towards users of the LLVM CMake build. If you're looking
+for information about modifying the LLVM CMake build system, you may want to
+see the {doc}`CMakePrimer` page. It has a basic overview of the CMake language.
-.. _Quick start:
-
-Quick start
-===========
+(Quick start)=
+## Quick start
We use here the command-line, non-interactive CMake interface.
-#. `Download <http://www.cmake.org/cmake/resources/software.html>`_ and install
- CMake. Version 3.20.0 is the minimum required.
-
-#. Open a shell. Your development tools must be reachable from this shell
- through the ``PATH`` environment variable.
-
-#. Create a build directory. Building LLVM in the source
- directory is not supported. ``cd`` to this directory:
-
- .. code-block:: console
-
- $ mkdir mybuilddir
- $ cd mybuilddir
-
-#. Execute this command in the shell replacing `path/to/llvm/source/root` with
- the path to the root of your LLVM source tree:
+1. [Download](http://www.cmake.org/cmake/resources/software.html) and install
+ CMake. Version 3.20.0 is the minimum required.
- .. code-block:: console
+2. Open a shell. Your development tools must be reachable from this shell
+ through the `PATH` environment variable.
- $ cmake path/to/llvm/source/root
+3. Create a build directory. Building LLVM in the source
+ directory is not supported. `cd` to this directory:
- CMake will detect your development environment, perform a series of tests, and
- generate the files required for building LLVM. CMake will use default values
- for all build parameters. See the `Options and variables`_ section for
- a list of build parameters that you can modify.
+ ``` console
+ $ mkdir mybuilddir
+ $ cd mybuilddir
+ ```
- This can fail if CMake can't detect your toolset, or if it thinks that the
- environment is not sane enough. In this case, make sure that the toolset that
- you intend to use is the only one reachable from the shell, and that the shell
- itself is the correct one for your development environment. CMake will refuse
- to build MinGW makefiles if you have a POSIX shell reachable through the PATH
- environment variable, for instance. You can force CMake to use a given build
- tool; for instructions, see the `Usage`_ section, below. You may
- also wish to control which targets LLVM enables, or which LLVM
- components are built; see the `Frequently Used LLVM-related
- variables`_ below.
+4. Execute this command in the shell replacing `path/to/llvm/source/root` with
+ the path to the root of your LLVM source tree:
-#. After CMake has finished running, use IDE project files, or start
- the build from the build directory:
+ ``` console
+ $ cmake path/to/llvm/source/root
+ ```
- .. code-block:: console
+ CMake will detect your development environment, perform a series of tests,
+ and generate the files required for building LLVM. CMake will use default
+ values for all build parameters. See the [Options and
+ variables](#options-and-variables) section for a list of build parameters
+ that you can modify.
- $ cmake --build .
+ This can fail if CMake can't detect your toolset, or if it thinks that the
+ environment is not sane enough. In this case, make sure that the toolset
+ that you intend to use is the only one reachable from the shell, and that
+ the shell itself is the correct one for your development environment. CMake
+ will refuse to build MinGW makefiles if you have a POSIX shell reachable
+ through the PATH environment variable, for instance. You can force CMake to
+ use a given build tool; for instructions, see the [Usage](#Usage) section,
+ below. You may also wish to control which targets LLVM enables, or which
+ LLVM components are built; see the [Frequently Used LLVM-related
+ variables](#frequently-used-llvm-related-variables) below.
- The ``--build`` option tells ``cmake`` to invoke the underlying build
- tool (``make``, ``ninja``, ``xcodebuild``, ``msbuild``, etc.)
+5. After CMake has finished running, use IDE project files, or start
+ the build from the build directory:
- The underlying build tool can be invoked directly, of course, but
- the ``--build`` option is portable.
+ ``` console
+ $ cmake --build .
+ ```
-#. After LLVM has finished building, install it from the build directory:
+ The `--build` option tells `cmake` to invoke the underlying build
+ tool (`make`, `ninja`, `xcodebuild`, `msbuild`, etc.)
- .. code-block:: console
+ The underlying build tool can be invoked directly, of course, but
+ the `--build` option is portable.
- $ cmake --build . --target install
+6. After LLVM has finished building, install it from the build directory:
- The ``--target`` option with ``install`` parameter in addition to
- the ``--build`` option tells ``cmake`` to build the ``install`` target.
+ ``` console
+ $ cmake --build . --target install
+ ```
- It is possible to set a different install prefix at installation time
- by invoking the ``cmake_install.cmake`` script generated in the
- build directory:
+ The `--target` option with `install` parameter in addition to
+ the `--build` option tells `cmake` to build the `install` target.
- .. code-block:: console
+ It is possible to set a different install prefix at installation time by
+ invoking the `cmake_install.cmake` script generated in the build directory:
- $ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
+ ``` console
+ $ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
+ ```
-.. _Basic CMake usage:
-.. _Usage:
-
-Basic CMake usage
-=================
+(Basic CMake usage)=
+(Usage)=
+## Basic CMake usage
This section explains basic aspects of CMake for daily use.
CMake comes with extensive documentation, in the form of HTML files, and as
-online help accessible via the ``cmake`` executable itself. Execute ``cmake
---help`` for further help options.
+online help accessible via the `cmake` executable itself. Execute `cmake
+--help` for further help options.
CMake allows you to specify a build tool (e.g., GNU make, Visual Studio,
or Xcode). If not specified on the command line, CMake tries to guess which
build tool to use based on your environment. Once it has identified your
build tool, CMake uses the corresponding *Generator* to create files for your
build tool (e.g., Makefiles or Visual Studio or Xcode project files). You can
-explicitly specify the generator with the command line option ``-G "Name of the
-generator"``. To see a list of the available generators on your system, execute:
-
-.. code-block:: console
+explicitly specify the generator with the command line option `-G "Name of the
+generator"`. To see a list of the available generators on your system, execute:
- $ cmake --help
+``` console
+$ cmake --help
+```
This will list the generator names at the end of the help text.
Generators' names are case-sensitive and may contain spaces. For this reason,
-you should enter them exactly as they are listed in the ``cmake --help``
+you should enter them exactly as they are listed in the `cmake --help`
output, in quotes. For example, to generate project files specifically for
Visual Studio 12, you can execute:
-.. code-block:: console
-
- $ cmake -G "Visual Studio 12" path/to/llvm/source/root
+``` console
+$ cmake -G "Visual Studio 12" path/to/llvm/source/root
+```
A given development platform can have more than one adequate
-generator. If you use Visual Studio, "NMake Makefiles" is a generator you can use
+generator. If you use Visual Studio, \"NMake Makefiles\" is a generator you can use
for building with NMake. By default, CMake chooses the most specific generator
supported by your development environment. If you want an alternative generator,
-you must specify this to CMake with the ``-G`` option.
-
-.. todo::
-
- Explain variables and cache. Move explanation here from #options section.
+you must specify this to CMake with the `-G` option.
-.. _Options and variables:
+```{todo}
+Explain variables and cache. Move explanation here from #options section.
+```
-Options and variables
-=====================
+(Options and variables)=
+## Options and variables
Variables customize how the build will be generated. Options are boolean
variables, with possible values ON/OFF. Options and variables are defined on the
CMake command line like this:
-.. code-block:: console
-
- $ cmake -DVARIABLE=value path/to/llvm/source
+``` console
+$ cmake -DVARIABLE=value path/to/llvm/source
+```
You can set a variable after the initial CMake invocation to change its
value. You can also undefine a variable:
-.. code-block:: console
-
- $ cmake -UVARIABLE path/to/llvm/source
+``` console
+$ cmake -UVARIABLE path/to/llvm/source
+```
-Variables are stored in the CMake cache. This is a file named ``CMakeCache.txt``
-stored at the root of your build directory that is generated by ``cmake``.
+Variables are stored in the CMake cache. This is a file named `CMakeCache.txt`
+stored at the root of your build directory that is generated by `cmake`.
Editing it yourself is not recommended.
Variables are listed in the CMake cache and later in this document with
the variable name and type separated by a colon. You can also specify the
variable and type on the CMake command line:
-.. code-block:: console
+``` console
+$ cmake -DVARIABLE:TYPE=value path/to/llvm/source
+```
- $ cmake -DVARIABLE:TYPE=value path/to/llvm/source
+(cmake_frequently_used_variables)=
+### Frequently-used CMake variables
-.. _cmake_frequently_used_variables:
+Here are some of the CMake variables that are used often, along with a brief
+explanation. For full documentation, consult the CMake manual, or execute
+`cmake --help-variable VARIABLE_NAME`. See [Frequently Used LLVM-related
+Variables](#frequently-used-llvm-related-variables) below for information about
+commonly used variables that control features of LLVM and enabled subprojects.
-Frequently-used CMake variables
--------------------------------
+(cmake_build_type)=
-Here are some of the CMake variables that are used often, along with a
-brief explanation. For full documentation, consult the CMake manual,
-or execute ``cmake --help-variable VARIABLE_NAME``. See `Frequently
-Used LLVM-related Variables`_ below for information about commonly
-used variables that control features of LLVM and enabled subprojects.
+**CMAKE_BUILD_TYPE**:STRING
-.. _cmake_build_type:
+: This configures the optimization level for `make` or `ninja` builds.
-**CMAKE_BUILD_TYPE**:STRING
- This configures the optimization level for ``make`` or ``ninja`` builds.
-
- Possible values:
-
- =========================== ============= ========== ========== ==========================
- Build Type Optimizations Debug Info Assertions Best suited for
- =========================== ============= ========== ========== ==========================
- **Release** For Speed No No Users of LLVM and Clang
- **Debug** None Yes Yes Developers of LLVM
- **RelWithDebInfo** For Speed Yes No Users that also need Debug
- **MinSizeRel** For Size No No When disk space matters
- =========================== ============= ========== ========== ==========================
-
- * Optimizations make LLVM/Clang run faster but can be an impediment for
- step-by-step debugging.
- * Builds with debug information can use a lot of RAM and disk space and are
- usually slower to run. You can improve RAM usage by using ``lld``, see
- the :ref:`LLVM_USE_LINKER <llvm_use_linker>` option.
- * Assertions are internal checks to help you find bugs. They typically slow
- down LLVM and Clang when enabled but can be useful during development.
- You can manually set :ref:`LLVM_ENABLE_ASSERTIONS <llvm_enable_assertions>`
- to override the default from `CMAKE_BUILD_TYPE`.
-
- If you are using an IDE such as Visual Studio or Xcode, use
- the IDE settings to set the build type.
-
- Note: on Windows (building with MSVC or clang-cl), CMake's **RelWithDebInfo**
- setting does not enable the same optimizations as **Release**. Using the
- **Release** build type with :ref:`LLVM_ENABLE_PDB <llvm_enable_pdb>` set
- may be a better option.
+ Possible values:
+
+ | Build Type | Optimizations | Debug Info | Assertions | Best suited for |
+ |--------------------|---------------|------------|------------|----------------------------|
+ | **Release** | For Speed | No | No | Users of LLVM and Clang |
+ | **Debug** | None | Yes | Yes | Developers of LLVM |
+ | **RelWithDebInfo** | For Speed | Yes | No | Users that also need Debug |
+ | **MinSizeRel** | For Size | No | No | When disk space matters |
+
+ - Optimizations make LLVM/Clang run faster but can be an impediment for
+ step-by-step debugging.
+ - Builds with debug information can use a lot of RAM and disk space and are
+ usually slower to run. You can improve RAM usage by using `lld`, see
+ the {ref}`LLVM_USE_LINKER <llvm_use_linker>` option.
+ - Assertions are internal checks to help you find bugs. They typically
+ slow down LLVM and Clang when enabled but can be useful during
+ development. You can manually set {ref}`LLVM_ENABLE_ASSERTIONS
+ <llvm_enable_assertions>` to override the default from
+ `CMAKE_BUILD_TYPE`.
+
+ If you are using an IDE such as Visual Studio or Xcode, use the IDE
+ settings to set the build type.
+
+ Note: on Windows (building with MSVC or clang-cl), CMake's
+ **RelWithDebInfo** setting does not enable the same optimizations as
+ **Release**. Using the **Release** build type with {ref}`LLVM_ENABLE_PDB
+ <llvm_enable_pdb>` set may be a better option.
**CMAKE_INSTALL_PREFIX**:PATH
- Path where LLVM will be installed when the "install" target is built.
-**CMAKE_{C,CXX}_FLAGS**:STRING
- Extra flags to use when compiling C and C++ source files respectively.
+: Path where LLVM will be installed when the \"install\" target is built.
+
+**CMAKE\_{C,CXX}\_FLAGS**:STRING
+
+: Extra flags to use when compiling C and C++ source files respectively.
-**CMAKE_{C,CXX}_COMPILER**:STRING
- Specify the C and C++ compilers to use. If you have multiple
- compilers installed, CMake might not default to the one you wish to
- use.
+**CMAKE\_{C,CXX}\_COMPILER**:STRING
-.. _Frequently Used LLVM-related variables:
+: Specify the C and C++ compilers to use. If you have multiple compilers
+ installed, CMake might not default to the one you wish to use.
-Frequently Used LLVM-related variables
---------------------------------------
+(Frequently Used LLVM-related variables)=
+### Frequently Used LLVM-related variables
-The default configuration may not match your requirements. Here are
-LLVM variables that are frequently used to control that. The full
-description is in `LLVM-related variables`_ below.
+The default configuration may not match your requirements. Here are LLVM
+variables that are frequently used to control that. The full description is in
+[LLVM-related variables](#llvm-related-variables) below.
**LLVM_ENABLE_PROJECTS**:STRING
- Control which projects are enabled. For example, you may want to work on clang
- or lldb by specifying ``-DLLVM_ENABLE_PROJECTS="clang;lldb"``.
+
+: Control which projects are enabled. For example, you may want to work on
+ clang or lldb by specifying `-DLLVM_ENABLE_PROJECTS="clang;lldb"`.
**LLVM_ENABLE_RUNTIMES**:STRING
- Control which runtimes are enabled. For example, you may want to work on
- libc++ or libc++abi by specifying ``-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"``.
+
+: Control which runtimes are enabled. For example, you may want to work on
+ libc++ or libc++abi by specifying
+ `-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"`.
**LLVM_LIBDIR_SUFFIX**:STRING
- Extra suffix to append to the directory where libraries are to be
- installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64``
- to install libraries to ``/usr/lib64``.
-**LLVM_PARALLEL_{COMPILE,LINK}_JOBS**:STRING
- Building the llvm toolchain can use a lot of resources, particularly
- during linking. These options, when you use the Ninja generator, allow you
- to restrict the parallelism. For example, to avoid OOMs or going
- into swap, permit only one link job per 15 GB of RAM available on a
- 32 GB machine, specify ``-G Ninja -DLLVM_PARALLEL_LINK_JOBS=2``.
+: Extra suffix to append to the directory where libraries are to be
+ installed. On a 64-bit architecture, one could use
+ `-DLLVM_LIBDIR_SUFFIX=64` to install libraries to `/usr/lib64`.
+
+**LLVM_PARALLEL\_{COMPILE,LINK}\_JOBS**:STRING
+
+: Building the llvm toolchain can use a lot of resources, particularly during
+ linking. These options, when you use the Ninja generator, allow you to
+ restrict the parallelism. For example, to avoid OOMs or going into swap,
+ permit only one link job per 15 GB of RAM available on a 32 GB machine,
+ specify `-G Ninja -DLLVM_PARALLEL_LINK_JOBS=2`.
**LLVM_TARGETS_TO_BUILD**:STRING
- Control which targets are enabled. For example, you may only need to enable
- your native target with, for example, ``-DLLVM_TARGETS_TO_BUILD=X86``.
-.. _llvm_use_linker:
+: Control which targets are enabled. For example, you may only need to enable
+ your native target with, for example, `-DLLVM_TARGETS_TO_BUILD=X86`.
+
+(llvm_use_linker)=
**LLVM_USE_LINKER**:STRING
- Override the system's default linker. For instance, use ``lld`` with
- ``-DLLVM_USE_LINKER=lld``.
-Rarely-used CMake variables
----------------------------
+: Override the system's default linker. For instance, use `lld` with
+ `-DLLVM_USE_LINKER=lld`.
+
+### Rarely-used CMake variables
Here are some of the CMake variables that are rarely used, along with a brief
-explanation and LLVM-related notes. For full documentation, consult the CMake
-manual, or execute ``cmake --help-variable VARIABLE_NAME``.
+explanation and LLVM-related notes. For full documentation, consult the CMake
+manual, or execute `cmake --help-variable VARIABLE_NAME`.
**CMAKE_CXX_STANDARD**:STRING
- Sets the C++ standard to conform to when building LLVM.
- LLVM requires C++17 or higher. This defaults to 17.
+
+: Sets the C++ standard to conform to when building LLVM. LLVM requires C++17
+ or higher. This defaults to 17.
**CMAKE_INSTALL_BINDIR**:PATH
- The path to install executables, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to "bin".
+
+: The path to install executables, relative to the *CMAKE_INSTALL_PREFIX*.
+ Defaults to \"bin\".
**CMAKE_INSTALL_DOCDIR**:PATH
- The path to install documentation, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to "share/doc".
+
+: The path to install documentation, relative to the *CMAKE_INSTALL_PREFIX*.
+ Defaults to \"share/doc\".
**CMAKE_INSTALL_INCLUDEDIR**:PATH
- The path to install header files, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to "include".
+
+: The path to install header files, relative to the *CMAKE_INSTALL_PREFIX*.
+ Defaults to \"include\".
**CMAKE_INSTALL_MANDIR**:PATH
- The path to install manpage files, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to "share/man".
-.. _LLVM-related variables:
+: The path to install manpage files, relative to the *CMAKE_INSTALL_PREFIX*.
+ Defaults to \"share/man\".
-LLVM-related variables
------------------------
+(LLVM-related variables)=
+### LLVM-related variables
-These variables provide fine control over the build of LLVM and
-its enabled sub-projects. Nearly all of these variable names begin with
-``LLVM_``.
+These variables provide fine control over the build of LLVM and its enabled
+sub-projects. Nearly all of these variable names begin with `LLVM_`.
-.. _LLVM-related variables BUILD_SHARED_LIBS:
+(LLVM-related variables BUILD_SHARED_LIBS)=
**BUILD_SHARED_LIBS**:BOOL
- Flag indicating if each LLVM component (e.g. Support) is built as a shared
- library (ON) or as a static library (OFF). Its default value is OFF. On
- Windows, shared libraries may be used when building with MinGW, including
- mingw-w64, but not when building with the Microsoft toolchain.
- .. note:: ``BUILD_SHARED_LIBS`` is only recommended for use by LLVM developers.
- If you want to build LLVM as a shared library, you should use the
- ``LLVM_BUILD_LLVM_DYLIB`` option.
+: Flag indicating if each LLVM component (e.g. Support) is built as a shared
+ library (ON) or as a static library (OFF). Its default value is OFF. On
+ Windows, shared libraries may be used when building with MinGW, including
+ mingw-w64, but not when building with the Microsoft toolchain.
+
+ ```{note}
+ `BUILD_SHARED_LIBS` is only recommended for use by LLVM developers. If you want to build LLVM as a shared library, you should use the `LLVM_BUILD_LLVM_DYLIB` option.
+ ```
**LLVM_ABI_BREAKING_CHECKS**:STRING
- Used to decide if LLVM should be built with ABI breaking checks or
- not. Allowed values are `WITH_ASSERTS` (default), `FORCE_ON` and
- `FORCE_OFF`. `WITH_ASSERTS` turns on ABI breaking checks in an
- assertion-enabled build. `FORCE_ON` (`FORCE_OFF`) turns them on
- (off) irrespective of whether normal (`NDEBUG`-based) assertions are
- enabled or not. A version of LLVM built with ABI breaking checks
- is not ABI compatible with a version built without it.
+
+: Used to decide if LLVM should be built with ABI breaking checks or not.
+ Allowed values are `WITH_ASSERTS` (default), `FORCE_ON` and `FORCE_OFF`.
+ `WITH_ASSERTS` turns on ABI breaking checks in an assertion-enabled build.
+ `FORCE_ON` (`FORCE_OFF`) turns them on (off) irrespective of whether normal
+ (`NDEBUG`-based) assertions are enabled or not. A version of LLVM built
+ with ABI breaking checks is not ABI compatible with a version built without
+ it.
**LLVM_ADDITIONAL_BUILD_TYPES**:LIST
- Adding a semicolon-separated list of additional build types to this flag
- allows for them to be specified as values in ``CMAKE_BUILD_TYPE`` without
- encountering a fatal error during the configuration process.
+
+: Adding a semicolon-separated list of additional build types to this flag
+ allows for them to be specified as values in `CMAKE_BUILD_TYPE` without
+ encountering a fatal error during the configuration process.
**LLVM_APPEND_VC_REV**:BOOL
- Embed version control revision info (Git revision id).
- The version info is provided by the ``LLVM_REVISION`` macro in
- ``llvm/include/llvm/Support/VCSRevision.h``. Developers using git who don't
- need revision info can disable this option to avoid re-linking most binaries
- after a branch switch. Defaults to ON.
+
+: Embed version control revision info (Git revision id). The version info is
+ provided by the `LLVM_REVISION` macro in
+ `llvm/include/llvm/Support/VCSRevision.h`. Developers using git who don't
+ need revision info can disable this option to avoid re-linking most
+ binaries after a branch switch. Defaults to ON.
**LLVM_FORCE_VC_REPOSITORY**:STRING
- Set the git repository to include in version info rather than calling git to
- determine it.
+
+: Set the git repository to include in version info rather than calling git
+ to determine it.
**LLVM_FORCE_VC_REVISION**:STRING
- Force a specific Git revision id rather than calling git to determine it.
- This is useful in environments where git is not available or non-functional
- but the VC revision is available through other means.
+
+: Force a specific Git revision id rather than calling git to determine it.
+ This is useful in environments where git is not available or non-functional
+ but the VC revision is available through other means.
**LLVM_BUILD_32_BITS**:BOOL
- Build 32-bit executables and libraries on 64-bit systems. This option is
- available only on some 64-bit Unix systems. Defaults to OFF.
+
+: Build 32-bit executables and libraries on 64-bit systems. This option is
+ available only on some 64-bit Unix systems. Defaults to OFF.
**LLVM_BUILD_BENCHMARKS**:BOOL
- Adds benchmarks to the list of default targets. Defaults to OFF.
+
+: Adds benchmarks to the list of default targets. Defaults to OFF.
**LLVM_BUILD_DOCS**:BOOL
- Adds all *enabled* documentation targets (i.e., Doxygen and Sphinx targets) as
- dependencies of the default build targets. This results in all of the (enabled)
- documentation targets being built as part of a normal build. If the ``install``
- target is run, then this also enables all built documentation targets to be
- installed. Defaults to OFF. To enable a particular documentation target, see
- ``LLVM_ENABLE_SPHINX`` and ``LLVM_ENABLE_DOXYGEN``.
+
+: Adds all *enabled* documentation targets (i.e., Doxygen and Sphinx targets)
+ as dependencies of the default build targets. This results in all of the
+ (enabled) documentation targets being built as part of a normal build. If
+ the `install` target is run, then this also enables all built documentation
+ targets to be installed. Defaults to OFF. To enable a particular
+ documentation target, see `LLVM_ENABLE_SPHINX` and `LLVM_ENABLE_DOXYGEN`.
**LLVM_BUILD_EXAMPLES**:BOOL
- Include LLVM examples in the 'all' build target and install them as part of
- the ``install`` target. Defaults to OFF. Targets for building examples are
- still generated, this is controlled by *LLVM_INCLUDE_EXAMPLES*. Note that some
- examples might still be built as dependencies for tests.
+
+: Include LLVM examples in the 'all' build target and install them as part of
+ the `install` target. Defaults to OFF. Targets for building examples are
+ still generated, this is controlled by *LLVM_INCLUDE_EXAMPLES*. Note that
+ some examples might still be built as dependencies for tests.
**LLVM_BUILD_INSTRUMENTED_COVERAGE**:BOOL
- If enabled, `source-based code coverage
- <https://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_ instrumentation
- is enabled while building llvm. If CMake can locate the code coverage
- scripts and the llvm-cov and llvm-profdata tools that pair with your compiler,
- the build will also generate the `generate-coverage-report` target to generate
- the code coverage report for LLVM, and the `clear-profile-data` utility target
- to delete captured profile data. See documentation for
- *LLVM_CODE_COVERAGE_TARGETS* and *LLVM_COVERAGE_SOURCE_DIRS* for more
- information on configuring code coverage reports.
+
+: If enabled, [source-based code
+ coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html)
+ instrumentation is enabled while building llvm. If CMake can locate the
+ code coverage scripts and the llvm-cov and llvm-profdata tools that pair
+ with your compiler, the build will also generate the
+ `generate-coverage-report` target to generate the code coverage report for
+ LLVM, and the `clear-profile-data` utility target to delete captured
+ profile data. See documentation for *LLVM_CODE_COVERAGE_TARGETS* and
+ *LLVM_COVERAGE_SOURCE_DIRS* for more information on configuring code
+ coverage reports.
**LLVM_BUILD_LLVM_DYLIB**:BOOL
- If enabled, the target for building the libLLVM shared library is added.
- This library contains all of LLVM's components in a single shared library.
- Defaults to OFF. This cannot be used in conjunction with ``BUILD_SHARED_LIBS``.
- Tools will only be linked to the libLLVM shared library if ``LLVM_LINK_LLVM_DYLIB``
- is also ON.
- The components in the library can be customised by setting ``LLVM_DYLIB_COMPONENTS``
- to a list of the desired components.
- This option is not available on Windows.
+
+: If enabled, the target for building the libLLVM shared library is added.
+ This library contains all of LLVM's components in a single shared library.
+ Defaults to OFF. This cannot be used in conjunction with
+ `BUILD_SHARED_LIBS`. Tools will only be linked to the libLLVM shared
+ library if `LLVM_LINK_LLVM_DYLIB` is also ON. The components in the library
+ can be customised by setting `LLVM_DYLIB_COMPONENTS` to a list of the
+ desired components. This option is not available on Windows.
**LLVM_BUILD_TESTS**:BOOL
- Include LLVM unit tests in the 'all' build target. Defaults to OFF. Targets
- for building each unit test are generated in any case. You can build a
- specific unit test using the targets defined under *unittests*, such as
- ADTTests, IRTests, SupportTests, etc. (Search for ``add_llvm_unittest`` in
- the subdirectories of *unittests* for a complete list of unit tests.) It is
- possible to build all unit tests with the target *UnitTests*.
+
+: Include LLVM unit tests in the 'all' build target. Defaults to OFF. Targets
+ for building each unit test are generated in any case. You can build a
+ specific unit test using the targets defined under *unittests*, such as
+ ADTTests, IRTests, SupportTests, etc. (Search for `add_llvm_unittest` in
+ the subdirectories of *unittests* for a complete list of unit tests.) It is
+ possible to build all unit tests with the target *UnitTests*.
**LLVM_BUILD_TOOLS**:BOOL
- Build LLVM tools. Defaults to ON. Targets for building each tool are generated
- in any case. You can build a tool separately by invoking its target. For
- example, you can build *llvm-as* with a Makefile-based system by executing *make
- llvm-as* at the root of your build directory.
+
+: Build LLVM tools. Defaults to ON. Targets for building each tool are
+ generated in any case. You can build a tool separately by invoking its
+ target. For example, you can build *llvm-as* with a Makefile-based system
+ by executing *make llvm-as* at the root of your build directory.
**LLVM_CCACHE_BUILD**:BOOL
- If enabled and the ``ccache`` program is available, then LLVM will be
- built using ``ccache`` to speed up rebuilds of LLVM and its components.
- Defaults to OFF. The size and location of the cache maintained
- by ``ccache`` can be adjusted via the ``LLVM_CCACHE_MAXSIZE`` and ``LLVM_CCACHE_DIR``
- options, which are passed to the ``CCACHE_MAXSIZE`` and ``CCACHE_DIR`` environment
- variables, respectively.
+
+: If enabled and the `ccache` program is available, then LLVM will be built
+ using `ccache` to speed up rebuilds of LLVM and its components. Defaults to
+ OFF. The size and location of the cache maintained by `ccache` can be
+ adjusted via the `LLVM_CCACHE_MAXSIZE` and `LLVM_CCACHE_DIR` options, which
+ are passed to the `CCACHE_MAXSIZE` and `CCACHE_DIR` environment variables,
+ respectively.
**LLVM_CODE_COVERAGE_TARGETS**:STRING
- If set to a semicolon-separated list of targets, those targets will be used
- to drive the code coverage reports. If unset, the target list will be
- constructed using the LLVM build's CMake export list.
+
+: If set to a semicolon-separated list of targets, those targets will be used
+ to drive the code coverage reports. If unset, the target list will be
+ constructed using the LLVM build's CMake export list.
**LLVM_COVERAGE_SOURCE_DIRS**:STRING
- If set to a semicolon-separated list of directories, the coverage reports
- will limit code coverage summaries to just the listed directories. If unset,
- coverage reports will include all sources identified by the tooling.
+
+: If set to a semicolon-separated list of directories, the coverage reports
+ will limit code coverage summaries to just the listed directories. If
+ unset, coverage reports will include all sources identified by the tooling.
**LLVM_CREATE_XCODE_TOOLCHAIN**:BOOL
- macOS only: If enabled, CMake will generate a target named
- 'install-xcode-toolchain'. This target will create a directory at
- ``$CMAKE_INSTALL_PREFIX/Toolchains`` containing an xctoolchain directory which can
- be used to override the default system tools.
+
+: macOS only: If enabled, CMake will generate a target named
+ 'install-xcode-toolchain'. This target will create a directory at
+ `$CMAKE_INSTALL_PREFIX/Toolchains` containing an xctoolchain directory
+ which can be used to override the default system tools.
**LLVM_DEFAULT_TARGET_TRIPLE**:STRING
- LLVM target to use for code generation when no target is explicitly specified.
- It defaults to "host", meaning that it shall pick the architecture
- of the machine where LLVM is being built. If you are building a cross-compiler,
- set it to the target triple of your desired architecture.
+
+: LLVM target to use for code generation when no target is explicitly
+ specified. It defaults to \"host\", meaning that it shall pick the
+ architecture of the machine where LLVM is being built. If you are building
+ a cross-compiler, set it to the target triple of your desired architecture.
**LLVM_DOXYGEN_QCH_FILENAME**:STRING
- The filename of the Qt Compressed Help file that will be generated when
- ``-DLLVM_ENABLE_DOXYGEN=ON`` and
- ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`` are given. Defaults to
- ``org.llvm.qch``.
- This option is only useful in combination with
- ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON``;
- otherwise it has no effect.
+
+: The filename of the Qt Compressed Help file that will be generated when
+ `-DLLVM_ENABLE_DOXYGEN=ON` and `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON` are
+ given. Defaults to `org.llvm.qch`. This option is only useful in
+ combination with `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`; otherwise it has no
+ effect.
**LLVM_DOXYGEN_QHELPGENERATOR_PATH**:STRING
- The path to the ``qhelpgenerator`` executable. Defaults to whatever CMake's
- ``find_program()`` can find. This option is only useful in combination with
- ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON``; otherwise it has no
- effect.
+
+: The path to the `qhelpgenerator` executable. Defaults to whatever CMake's
+ `find_program()` can find. This option is only useful in combination with
+ `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`; otherwise it has no effect.
**LLVM_DOXYGEN_QHP_CUST_FILTER_NAME**:STRING
- See `Qt Help Project`_ for
- more information. Defaults to the CMake variable ``${PACKAGE_STRING}`` which
- is a combination of the package name and version string. This filter can then
- be used in Qt Creator to select only documentation from LLVM when browsing
- through all the help files that you might have loaded. This option is only
- useful in combination with ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON``;
- otherwise it has no effect.
-.. _Qt Help Project: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters
+: See [Qt Help
+ Project](http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters)
+ for more information. Defaults to the CMake variable `${PACKAGE_STRING}`
+ which is a combination of the package name and version string. This filter
+ can then be used in Qt Creator to select only documentation from LLVM when
+ browsing through all the help files that you might have loaded. This option
+ is only useful in combination with `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`;
+ otherwise it has no effect.
**LLVM_DOXYGEN_QHP_NAMESPACE**:STRING
- Namespace under which the intermediate Qt Help Project file lives. See `Qt
- Help Project`_
- for more information. Defaults to "org.llvm". This option is only useful in
- combination with ``-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON``; otherwise
- it has no effect.
+: Namespace under which the intermediate Qt Help Project file lives. See [Qt
+ Help
+ Project](http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters)
+ for more information. Defaults to \"org.llvm\". This option is only useful
+ in combination with `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`; otherwise it has no
+ effect.
-.. _llvm_enable_assertions:
+(llvm_enable_assertions)=
**LLVM_ENABLE_ASSERTIONS**:BOOL
- Enables code assertions. Defaults to ON if and only if ``CMAKE_BUILD_TYPE``
- is *Debug*.
+
+: Enables code assertions. Defaults to ON if and only if `CMAKE_BUILD_TYPE`
+ is *Debug*.
**LLVM_ENABLE_BINDINGS**:BOOL
- If disabled, do not try to build the OCaml bindings.
+
+: If disabled, do not try to build the OCaml bindings.
**LLVM_ENABLE_CURL**:
- Used to decide if LLVM tools, should support downloading information
- (particularly debug info from ``llvm-debuginfod``) over HTTP. Allowed
- values are ``OFF`` (default), ``ON``, and ``FORCE_ON`` (error if libcurl
- is not found).
+
+: Used to decide if LLVM tools, should support downloading information
+ (particularly debug info from `llvm-debuginfod`) over HTTP. Allowed values
+ are `OFF` (default), `ON`, and `FORCE_ON` (error if libcurl is not found).
**LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING**:STRING
- Enhances Debugify's ability to detect line number errors by storing extra
- information inside Instructions, removing false positives from Debugify's
- results at the cost of performance. Allowed values are `DISABLED` (default),
- `COVERAGE`, and `COVERAGE_AND_ORIGIN`. `COVERAGE` tracks whether and why a
- line number was intentionally dropped or not generated for an instruction,
- allowing Debugify to avoid reporting these as errors; this comes with a small
- performance cost of ~0.1%. `COVERAGE_AND_ORIGIN` additionally stores a
- stacktrace of the point where each DebugLoc is unintentionally dropped,
- allowing for much easier bug triaging at the cost of a ~10x performance
- slowdown. `COVERAGE` and `COVERAGE_AND_ORIGIN` are ABI-breaking options.
+
+: Enhances Debugify's ability to detect line number errors by storing extra
+ information inside Instructions, removing false positives from Debugify's
+ results at the cost of performance. Allowed values are `DISABLED`
+ (default), `COVERAGE`, and `COVERAGE_AND_ORIGIN`. `COVERAGE` tracks whether
+ and why a line number was intentionally dropped or not generated for an
+ instruction, allowing Debugify to avoid reporting these as errors; this
+ comes with a small performance cost of \~0.1%. `COVERAGE_AND_ORIGIN`
+ additionally stores a stacktrace of the point where each DebugLoc is
+ unintentionally dropped, allowing for much easier bug triaging at the cost
+ of a \~10x performance slowdown. `COVERAGE` and `COVERAGE_AND_ORIGIN` are
+ ABI-breaking options.
**LLVM_ENABLE_DIA_SDK**:BOOL
- Enable building with MSVC DIA SDK for PDB debugging support. Available
- only with MSVC. Defaults to ON.
+
+: Enable building with MSVC DIA SDK for PDB debugging support. Available only
+ with MSVC. Defaults to ON.
**LLVM_ENABLE_DOXYGEN**:BOOL
- Enables the generation of browsable HTML documentation using doxygen.
- Defaults to OFF.
+
+: Enables the generation of browsable HTML documentation using doxygen.
+ Defaults to OFF.
**LLVM_ENABLE_DOXYGEN_QT_HELP**:BOOL
- Enables the generation of a Qt Compressed Help file. Defaults to OFF.
- This affects the make target ``doxygen-llvm``. When enabled, apart from
- the normal HTML output generated by doxygen, this will produce a QCH file
- named ``org.llvm.qch``. You can then load this file into Qt Creator.
- This option is only useful in combination with ``-DLLVM_ENABLE_DOXYGEN=ON``;
- otherwise this has no effect.
+
+: Enables the generation of a Qt Compressed Help file. Defaults to OFF. This
+ affects the make target `doxygen-llvm`. When enabled, apart from the normal
+ HTML output generated by doxygen, this will produce a QCH file named
+ `org.llvm.qch`. You can then load this file into Qt Creator. This option is
+ only useful in combination with `-DLLVM_ENABLE_DOXYGEN=ON`; otherwise this
+ has no effect.
**LLVM_ENABLE_EH**:BOOL
- Build LLVM with exception-handling support. This is necessary if you wish to
- link against LLVM libraries and make use of C++ exceptions in your own code
- that need to propagate through LLVM code. Defaults to OFF.
+
+: Build LLVM with exception-handling support. This is necessary if you wish
+ to link against LLVM libraries and make use of C++ exceptions in your own
+ code that need to propagate through LLVM code. Defaults to OFF.
**LLVM_ENABLE_EXPENSIVE_CHECKS**:BOOL
- Enable additional time/memory expensive checking. Defaults to OFF.
+
+: Enable additional time/memory expensive checking. Defaults to OFF.
**LLVM_ENABLE_FFI**:BOOL
- Indicates whether the LLVM Interpreter will be linked with the Foreign Function
- Interface library (libffi) in order to enable calling external functions.
- If the library or its headers are installed in a custom
- location, you can also set the variables ``FFI_INCLUDE_DIR`` and
- ``FFI_LIBRARY_DIR`` to the directories where ``ffi.h`` and ``libffi.so`` can be found,
- respectively. Defaults to OFF.
+
+: Indicates whether the LLVM Interpreter will be linked with the Foreign
+ Function Interface library (libffi) in order to enable calling external
+ functions. If the library or its headers are installed in a custom
+ location, you can also set the variables `FFI_INCLUDE_DIR` and
+ `FFI_LIBRARY_DIR` to the directories where `ffi.h` and `libffi.so` can be
+ found, respectively. Defaults to OFF.
**LLVM_ENABLE_HTTPLIB**:BOOL
- Enables the optional cpp-httplib dependency which is used by llvm-debuginfod
- to serve debug info over HTTP. `cpp-httplib <https://github.com/yhirose/cpp-httplib>`_
- must be installed, or `httplib_ROOT` must be set. Defaults to OFF.
+
+: Enables the optional cpp-httplib dependency which is used by
+ llvm-debuginfod to serve debug info over HTTP.
+ [cpp-httplib](https://github.com/yhirose/cpp-httplib) must be installed, or
+ `httplib_ROOT` must be set. Defaults to OFF.
**LLVM_ENABLE_IDE**:BOOL
- Tell the build system that an IDE is being used. This in turn disables the
- creation of certain convenience build system targets, such as the various
- ``install-*`` and ``check-*`` targets, since IDEs don't always deal well with
- a large number of targets. This is usually autodetected, but it can be
- configured manually to explicitly control the generation of those targets.
+
+: Tell the build system that an IDE is being used. This in turn disables the
+ creation of certain convenience build system targets, such as the various
+ `install-*` and `check-*` targets, since IDEs don't always deal well with a
+ large number of targets. This is usually autodetected, but it can be
+ configured manually to explicitly control the generation of those targets.
**LLVM_ENABLE_LIBCXX**:BOOL
- If the host compiler and linker support the stdlib flag, ``-stdlib=libc++`` is
- passed to invocations of both so that the project is built using libc++
- instead of stdlibc++. Defaults to OFF.
+
+: If the host compiler and linker support the stdlib flag, `-stdlib=libc++`
+ is passed to invocations of both so that the project is built using libc++
+ instead of stdlibc++. Defaults to OFF.
**LLVM_ENABLE_LIBEDIT**:BOOL
- Controls whether to enable libedit support for command-line editing and history
- in LLVM tools. When ``ON``, forces libedit support to be enabled and will cause a
- CMake configuration error if libedit cannot be found. When ``OFF``, disables
- libedit support entirely. If not specified, LLVM will auto-detect libedit
- availability. Defaults to auto-detection.
+
+: Controls whether to enable libedit support for command-line editing and
+ history in LLVM tools. When `ON`, forces libedit support to be enabled and
+ will cause a CMake configuration error if libedit cannot be found. When
+ `OFF`, disables libedit support entirely. If not specified, LLVM will
+ auto-detect libedit availability. Defaults to auto-detection.
**LLVM_ENABLE_LIBPFM**:BOOL
- Enable building with libpfm to support hardware counter measurements in LLVM
- tools.
- Defaults to ON.
+
+: Enable building with libpfm to support hardware counter measurements in
+ LLVM tools. Defaults to ON.
**LLVM_ENABLE_LLD**:BOOL
- This option is equivalent to `-DLLVM_USE_LINKER=lld`, except during a 2-stage
- build where a dependency is added from the first stage to the second ensuring
- that lld is built before stage2 begins.
+
+: This option is equivalent to `-DLLVM_USE_LINKER=lld`, except during a
+ 2-stage build where a dependency is added from the first stage to the
+ second ensuring that lld is built before stage2 begins.
**LLVM_ENABLE_LLVM_LIBC**: BOOL
- If the LLVM libc overlay is installed in a location where the host linker
- can access it, all built executables will be linked against the LLVM libc
- overlay before linking against the system libc. Defaults to OFF.
+
+: If the LLVM libc overlay is installed in a location where the host linker
+ can access it, all built executables will be linked against the LLVM libc
+ overlay before linking against the system libc. Defaults to OFF.
**LLVM_ENABLE_LTO**:STRING
- Add ``-flto`` or ``-flto=`` flags to the compile and link command
- lines, enabling link-time optimization. Possible values are ``Off``,
- ``On``, ``Thin`` and ``Full``. Defaults to OFF.
+
+: Add `-flto` or `-flto=` flags to the compile and link command lines,
+ enabling link-time optimization. Possible values are `Off`, `On`, `Thin`
+ and `Full`. Defaults to OFF.
**LLVM_ENABLE_MODULES**:BOOL
- Compile with `Clang Header Modules
- <https://clang.llvm.org/docs/Modules.html>`_.
-.. _llvm_enable_pdb:
+: Compile with [Clang Header
+ Modules](https://clang.llvm.org/docs/Modules.html).
+
+(llvm_enable_pdb)=
**LLVM_ENABLE_PDB**:BOOL
- For Windows builds using MSVC or clang-cl, generate PDB files when
- :ref:`CMAKE_BUILD_TYPE <cmake_build_type>` is set to Release.
+
+: For Windows builds using MSVC or clang-cl, generate PDB files when
+ {ref}`CMAKE_BUILD_TYPE <cmake_build_type>` is set to Release.
**LLVM_ENABLE_PEDANTIC**:BOOL
- Enable pedantic mode. This disables compiler-specific extensions, if
- possible. Defaults to ON.
+
+: Enable pedantic mode. This disables compiler-specific extensions, if
+ possible. Defaults to ON.
**LLVM_ENABLE_PIC**:BOOL
- Add the ``-fPIC`` flag to the compiler command-line, if the compiler supports
- this flag. Some systems, like Windows, do not need this flag. Defaults to ON.
+
+: Add the `-fPIC` flag to the compiler command-line, if the compiler supports
+ this flag. Some systems, like Windows, do not need this flag. Defaults to
+ ON.
**LLVM_ENABLE_PROJECTS**:STRING
- Semicolon-separated list of projects to build, or *all* for building all
- (clang, lldb, lld, polly, etc) projects. This flag assumes that projects
- are checked out side-by-side and not nested, i.e. clang needs to be in
- parallel to llvm instead of nested in ``llvm/tools``. This feature allows
- having one build for only LLVM and another for clang+llvm using the same
- source checkout.
- The full list is:
+: Semicolon-separated list of projects to build, or *all* for building all
+ (clang, lldb, lld, polly, etc) projects. This flag assumes that projects
+ are checked out side-by-side and not nested, i.e. clang needs to be in
+ parallel to llvm instead of nested in `llvm/tools`. This feature allows
+ having one build for only LLVM and another for clang+llvm using the same
+ source checkout.
+
+ The full list is:
- ``bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly``
+ `bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly`
- .. note::
- Some projects listed here can also go in ``LLVM_ENABLE_RUNTIMES``. They
- should only appear in one of the two lists. If a project is a valid possibility
- for both, prefer putting it in ``LLVM_ENABLE_RUNTIMES``.
+ ```{note}
+ Some projects listed here can also go in `LLVM_ENABLE_RUNTIMES`. They should only appear in one of the two lists. If a project is a valid possibility for both, prefer putting it in `LLVM_ENABLE_RUNTIMES`.
+ ```
**LLVM_ENABLE_RTTI**:BOOL
- Build LLVM with run-time type information. Defaults to OFF.
+
+: Build LLVM with run-time type information. Defaults to OFF.
**LLVM_ENABLE_RUNTIMES**:STRING
- Build libc++, libc++abi, libunwind or compiler-rt using the just-built compiler.
- This is the correct way to build runtimes when putting together a toolchain.
- It will build the builtins separately from the other runtimes to preserve
- correct dependency ordering. If you want to build the runtimes using a system
- compiler, see the `libc++ documentation <https://libcxx.llvm.org/VendorDocumentation.html>`_.
- .. note::
- The list should not have duplicates with ``LLVM_ENABLE_PROJECTS``.
+: Build libc++, libc++abi, libunwind or compiler-rt using the just-built
+ compiler. This is the correct way to build runtimes when putting together a
+ toolchain. It will build the builtins separately from the other runtimes to
+ preserve correct dependency ordering. If you want to build the runtimes
+ using a system compiler, see the [libc++
+ documentation](https://libcxx.llvm.org/VendorDocumentation.html).
- To list all possible runtimes, include an invalid name. For example
- ``-DLLVM_ENABLE_RUNTIMES=notaruntime``. The resulting CMake error will list
- the possible runtime names.
+ ```{note}
+ The list should not have duplicates with `LLVM_ENABLE_PROJECTS`.
+ ```
- To enable all of the runtimes, use:
+ To list all possible runtimes, include an invalid name. For example
+ `-DLLVM_ENABLE_RUNTIMES=notaruntime`. The resulting CMake error will list
+ the possible runtime names.
- ``LLVM_ENABLE_RUNTIMES=all``
+ To enable all of the runtimes, use:
+
+ `LLVM_ENABLE_RUNTIMES=all`
**LLVM_ENABLE_SPHINX**:BOOL
- If specified, CMake will search for the ``sphinx-build`` executable and will make
- the ``SPHINX_OUTPUT_HTML`` and ``SPHINX_OUTPUT_MAN`` CMake options available.
- Defaults to OFF.
+
+: If specified, CMake will search for the `sphinx-build` executable and will
+ make the `SPHINX_OUTPUT_HTML` and `SPHINX_OUTPUT_MAN` CMake options
+ available. Defaults to OFF.
**LLVM_ENABLE_THREADS**:BOOL
- Build with threads support, if available. Defaults to ON.
+
+: Build with threads support, if available. Defaults to ON.
**LLVM_ENABLE_UNWIND_TABLES**:BOOL
- Enable unwind tables in the binary. Disabling unwind tables can reduce the
- size of the libraries. Defaults to ON.
+
+: Enable unwind tables in the binary. Disabling unwind tables can reduce the
+ size of the libraries. Defaults to ON.
**LLVM_ENABLE_WARNINGS**:BOOL
- Enable all compiler warnings. Defaults to ON.
+
+: Enable all compiler warnings. Defaults to ON.
**LLVM_ENABLE_WARNING_SUPPRESSIONS**:BOOL
- Suppress specific compiler warnings. When disabled, this
- prevents suppressing warnings with flags such as MSVC's ``-wd`` or GCC/Clang's ``-Wno-...``.
- Defaults to ON.
+
+: Suppress specific compiler warnings. When disabled, this prevents
+ suppressing warnings with flags such as MSVC's `-wd` or GCC/Clang's
+ `-Wno-...`. Defaults to ON.
**LLVM_ENABLE_WERROR**:BOOL
- Stop and fail the build, if a compiler warning is triggered. Defaults to OFF.
+
+: Stop and fail the build, if a compiler warning is triggered. Defaults to
+ OFF.
**LLVM_ENABLE_Z3_SOLVER**:BOOL
- If enabled, the Z3 constraint solver is activated for the Clang static analyzer.
- A recent version of the z3 library must be available on the system.
+
+: If enabled, the Z3 constraint solver is activated for the Clang static
+ analyzer. A recent version of the z3 library must be available on the
+ system.
**LLVM_ENABLE_ZLIB**:STRING
- Used to decide if LLVM tools should support compression/decompression with
- zlib. Allowed values are ``OFF``, ``ON`` (default, enable if zlib is found),
- and ``FORCE_ON`` (error if zlib is not found).
+
+: Used to decide if LLVM tools should support compression/decompression with
+ zlib. Allowed values are `OFF`, `ON` (default, enable if zlib is found),
+ and `FORCE_ON` (error if zlib is not found).
**LLVM_ENABLE_ZSTD**:STRING
- Used to decide if LLVM tools should support compression/decompression with
- zstd. Allowed values are ``OFF``, ``ON`` (default, enable if zstd is found),
- and ``FORCE_ON`` (error if zstd is not found).
+
+: Used to decide if LLVM tools should support compression/decompression with
+ zstd. Allowed values are `OFF`, `ON` (default, enable if zstd is found),
+ and `FORCE_ON` (error if zstd is not found).
**LLVM_EXPERIMENTAL_TARGETS_TO_BUILD**:STRING
- Semicolon-separated list of experimental targets to build and linked into
- llvm. This will build the experimental target without needing it to add to the
- list of all the targets available in the LLVM's main ``CMakeLists.txt``.
+
+: Semicolon-separated list of experimental targets to build and linked into
+ llvm. This will build the experimental target without needing it to add to
+ the list of all the targets available in the LLVM's main `CMakeLists.txt`.
**LLVM_EXTERNAL_PROJECTS**:STRING
- Semicolon-separated list of additional external projects to build as part of
- llvm. For each project, ``LLVM_EXTERNAL_<NAME>_SOURCE_DIR`` has to be specified
- with the path for the source code of the project. Example:
- ``-DLLVM_EXTERNAL_PROJECTS="Foo;Bar"
- -DLLVM_EXTERNAL_FOO_SOURCE_DIR=/src/foo
- -DLLVM_EXTERNAL_BAR_SOURCE_DIR=/src/bar``.
-
-**LLVM_EXTERNAL_{CLANG,LLD,POLLY}_SOURCE_DIR**:PATH
- These variables specify the path to the source directory for the external
- LLVM projects Clang, lld, and Polly, respectively, relative to the top-level
- source directory. If the in-tree subdirectory for an external project
- exists (e.g., ``llvm/tools/clang`` for Clang), then the corresponding variable
- will not be used. If the variable for an external project does not point
- to a valid path, then that project will not be built.
+
+: Semicolon-separated list of additional external projects to build as part
+ of llvm. For each project, `LLVM_EXTERNAL_<NAME>_SOURCE_DIR` has to be
+ specified with the path for the source code of the project. Example:
+ `-DLLVM_EXTERNAL_PROJECTS="Foo;Bar" -DLLVM_EXTERNAL_FOO_SOURCE_DIR=/src/foo
+ -DLLVM_EXTERNAL_BAR_SOURCE_DIR=/src/bar`.
+
+**LLVM_EXTERNAL\_{CLANG,LLD,POLLY}\_SOURCE_DIR**:PATH
+
+: These variables specify the path to the source directory for the external
+ LLVM projects Clang, lld, and Polly, respectively, relative to the
+ top-level source directory. If the in-tree subdirectory for an external
+ project exists (e.g., `llvm/tools/clang` for Clang), then the corresponding
+ variable will not be used. If the variable for an external project does not
+ point to a valid path, then that project will not be built.
**LLVM_EXTERNALIZE_DEBUGINFO**:BOOL
- Generate dSYM files and strip executables and libraries (Darwin only).
- Defaults to OFF.
+
+: Generate dSYM files and strip executables and libraries (Darwin only).
+ Defaults to OFF.
**LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES**:BOOL
- When building executables, preserve symbol exports. Defaults to ON.
- You can use this option to disable exported symbols from all
- executables (Darwin Only).
+
+: When building executables, preserve symbol exports. Defaults to ON. You can
+ use this option to disable exported symbols from all executables (Darwin
+ Only).
**LLVM_FORCE_USE_OLD_TOOLCHAIN**:BOOL
- If enabled, the compiler and standard library versions won't be checked. LLVM
- may not compile at all, or might fail at runtime due to known bugs in these
- toolchains.
+
+: If enabled, the compiler and standard library versions won't be checked.
+ LLVM may not compile at all, or might fail at runtime due to known bugs in
+ these toolchains.
**LLVM_INCLUDE_BENCHMARKS**:BOOL
- Generate build targets for the LLVM benchmarks. Defaults to ON.
+
+: Generate build targets for the LLVM benchmarks. Defaults to ON.
**LLVM_INCLUDE_EXAMPLES**:BOOL
- Generate build targets for the LLVM examples. Defaults to ON. You can use this
- option to disable the generation of build targets for the LLVM examples.
+
+: Generate build targets for the LLVM examples. Defaults to ON. You can use
+ this option to disable the generation of build targets for the LLVM
+ examples.
**LLVM_INCLUDE_TESTS**:BOOL
- Generate build targets for the LLVM unit tests. Defaults to ON. You can use
- this option to disable the generation of build targets for the LLVM unit
- tests.
+
+: Generate build targets for the LLVM unit tests. Defaults to ON. You can use
+ this option to disable the generation of build targets for the LLVM unit
+ tests.
**LLVM_INCLUDE_TOOLS**:BOOL
- Generate build targets for the LLVM tools. Defaults to ON. You can use this
- option to disable the generation of build targets for the LLVM tools.
+
+: Generate build targets for the LLVM tools. Defaults to ON. You can use this
+ option to disable the generation of build targets for the LLVM tools.
**LLVM_INDIVIDUAL_TEST_COVERAGE**:BOOL
- Enable individual test case coverage. When set to ON, code coverage data for
- each test case will be generated and stored in a separate directory under the
- config.test_exec_root path. This feature allows code coverage analysis of each
- individual test case. Defaults to OFF.
+
+: Enable individual test case coverage. When set to ON, code coverage data
+ for each test case will be generated and stored in a separate directory
+ under the config.test_exec_root path. This feature allows code coverage
+ analysis of each individual test case. Defaults to OFF.
**LLVM_INSTALL_BINUTILS_SYMLINKS**:BOOL
- Install symlinks from the binutils tool names to the corresponding LLVM tools.
- For example, ar will be symlinked to llvm-ar.
+
+: Install symlinks from the binutils tool names to the corresponding LLVM
+ tools. For example, ar will be symlinked to llvm-ar.
**LLVM_INSTALL_CCTOOLS_SYMLINKS**:BOOL
- Install symlinks from the cctools tool names to the corresponding LLVM tools.
- For example, lipo will be symlinked to llvm-lipo.
+
+: Install symlinks from the cctools tool names to the corresponding LLVM
+ tools. For example, lipo will be symlinked to llvm-lipo.
**LLVM_INSTALL_OCAMLDOC_HTML_DIR**:STRING
- The path to install OCamldoc-generated HTML documentation to. This path can
- either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to
- ``${CMAKE_INSTALL_DOCDIR}/llvm/ocaml-html``.
+
+: The path to install OCamldoc-generated HTML documentation to. This path can
+ either be absolute or relative to the `CMAKE_INSTALL_PREFIX`. Defaults to
+ `${CMAKE_INSTALL_DOCDIR}/llvm/ocaml-html`.
**LLVM_INSTALL_SPHINX_HTML_DIR**:STRING
- The path to install Sphinx-generated HTML documentation to. This path can
- either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to
- ``${CMAKE_INSTALL_DOCDIR}/llvm/html``.
+
+: The path to install Sphinx-generated HTML documentation to. This path can
+ either be absolute or relative to the `CMAKE_INSTALL_PREFIX`. Defaults to
+ `${CMAKE_INSTALL_DOCDIR}/llvm/html`.
**LLVM_INSTALL_UTILS**:BOOL
- If enabled, utility binaries like ``FileCheck`` and ``not`` will be installed
- to ``CMAKE_INSTALL_PREFIX``.
+
+: If enabled, utility binaries like `FileCheck` and `not` will be installed
+ to `CMAKE_INSTALL_PREFIX`.
**LLVM_INSTALL_DOXYGEN_HTML_DIR**:STRING
- The path to install Doxygen-generated HTML documentation to. This path can
- either be absolute or relative to the *CMAKE_INSTALL_PREFIX*. Defaults to
- ``${CMAKE_INSTALL_DOCDIR}/llvm/doxygen-html``.
+
+: The path to install Doxygen-generated HTML documentation to. This path can
+ either be absolute or relative to the *CMAKE_INSTALL_PREFIX*. Defaults to
+ `${CMAKE_INSTALL_DOCDIR}/llvm/doxygen-html`.
**LLVM_INTEGRATED_CRT_ALLOC**:PATH
- On Windows, allows embedding a different C runtime allocator into the LLVM
- tools and libraries. Using a lock-free allocator such as the ones listed below
- greatly decreases ThinLTO link time by about an order of magnitude. It also
- mildly improves Clang build times, by about 5-10%. At the moment, rpmalloc,
- snmalloc and mimalloc are supported. Use the path to `git clone` to select
- the respective allocator, for example:
- .. code-block:: console
+: On Windows, allows embedding a different C runtime allocator into the LLVM
+ tools and libraries. Using a lock-free allocator such as the ones listed
+ below greatly decreases ThinLTO link time by about an order of magnitude.
+ It also mildly improves Clang build times, by about 5-10%. At the moment,
+ rpmalloc, snmalloc and mimalloc are supported. Use the path to `git clone`
+ to select the respective allocator, for example:
+ ``` console
$ D:\git> git clone https://github.com/mjansson/rpmalloc
$ D:\llvm-project> cmake ... -DLLVM_INTEGRATED_CRT_ALLOC=D:\git\rpmalloc
+ ```
- This option needs to be used along with the static CRT, i.e., if building the
- Release target, add ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded``.
- Note that rpmalloc is also supported natively in-tree, see option below.
+ This option needs to be used along with the static CRT, i.e., if building
+ the Release target, add `-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded`. Note
+ that rpmalloc is also supported natively in-tree, see option below.
**LLVM_ENABLE_RPMALLOC**:BOOL
- Similar to LLVM_INTEGRATED_CRT_ALLOC, embeds the in-tree rpmalloc into the
- host toolchain as a C runtime allocator. The version currently used is
- rpmalloc 1.4.5. This option also implies linking with the static CRT, there's
- no need to provide CMAKE_MSVC_RUNTIME_LIBRARY.
+
+: Similar to LLVM_INTEGRATED_CRT_ALLOC, embeds the in-tree rpmalloc into the
+ host toolchain as a C runtime allocator. The version currently used is
+ rpmalloc 1.4.5. This option also implies linking with the static CRT,
+ there's no need to provide CMAKE_MSVC_RUNTIME_LIBRARY.
**LLVM_LINK_LLVM_DYLIB**:BOOL
- If enabled, tools will be linked with the libLLVM shared library. Defaults
- to OFF. Setting ``LLVM_LINK_LLVM_DYLIB`` to ON also sets ``LLVM_BUILD_LLVM_DYLIB``
- to ON.
- This option is not available on Windows.
-**LLVM_<target>_LINKER_FLAGS**:STRING
- Defines the set of linker flags that should be applied to a <target>.
+: If enabled, tools will be linked with the libLLVM shared library. Defaults
+ to OFF. Setting `LLVM_LINK_LLVM_DYLIB` to ON also sets
+ `LLVM_BUILD_LLVM_DYLIB` to ON. This option is not available on Windows.
+
+**LLVM\_\<target\>\_LINKER_FLAGS**:STRING
+
+: Defines the set of linker flags that should be applied to a \<target\>.
**LLVM_LIT_ARGS**:STRING
- Arguments given to lit. ``make check`` and ``make clang-test`` are affected.
- By default, ``'-sv --no-progress-bar'`` on Visual C++ and Xcode, ``'-sv'`` on
- others.
+
+: Arguments given to lit. `make check` and `make clang-test` are affected. By
+ default, `'-sv --no-progress-bar'` on Visual C++ and Xcode, `'-sv'` on
+ others.
**LLVM_LIT_TOOLS_DIR**:PATH
- The path to GnuWin32 tools for tests. Valid on Windows host. Defaults to
- the empty string, in which case lit will look for tools needed for tests
- (e.g., ``grep``, ``sort``, etc.) in your ``%PATH%``. If GnuWin32 is not in your
- ``%PATH%``, then you can set this variable to the GnuWin32 directory so that
- lit can find tools needed for tests in that directory.
+
+: The path to GnuWin32 tools for tests. Valid on Windows host. Defaults to
+ the empty string, in which case lit will look for tools needed for tests
+ (e.g., `grep`, `sort`, etc.) in your `%PATH%`. If GnuWin32 is not in your
+ `%PATH%`, then you can set this variable to the GnuWin32 directory so that
+ lit can find tools needed for tests in that directory.
**LLVM_NATIVE_TOOL_DIR**:STRING
- Full path to a directory containing executables for the build host
- (containing binaries such as ``llvm-tblgen`` and ``clang-tblgen``). This is
- intended for cross-compiling: if the user sets this variable and the
- directory contains executables with the expected names, no separate
- native versions of those executables will be built.
+
+: Full path to a directory containing executables for the build host
+ (containing binaries such as `llvm-tblgen` and `clang-tblgen`). This is
+ intended for cross-compiling: if the user sets this variable and the
+ directory contains executables with the expected names, no separate native
+ versions of those executables will be built.
**LLVM_NO_INSTALL_NAME_DIR_FOR_BUILD_TREE**:BOOL
- Defaults to ``OFF``. If set to ``ON``, CMake's default logic for library IDs
- on Darwin in the build tree will be used. Otherwise the install-time library
- IDs will be used in the build tree as well. Mainly useful when other CMake
- library ID control variables (e.g., ``CMAKE_INSTALL_NAME_DIR``) are being
- set to non-standard values.
+
+: Defaults to `OFF`. If set to `ON`, CMake's default logic for library IDs on
+ Darwin in the build tree will be used. Otherwise the install-time library
+ IDs will be used in the build tree as well. Mainly useful when other CMake
+ library ID control variables (e.g., `CMAKE_INSTALL_NAME_DIR`) are being set
+ to non-standard values.
**LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN**:BOOL
- Defaults to ``ON``. If set to ``ON``, Darwin shared libraries built through
- LLVM's CMake helpers use versioned dylib filenames and install names, matching
- the behavior on other Unix platforms more closely. If set to ``OFF``, Darwin
- keeps the legacy unversioned dylib install name, for compatibility with
- existing consumers that expect ``@rpath/libLLVM.dylib``.
-
-**LLVM_UNVERSIONED_{LIBLTO,LIBCLANG}_ON_DARWIN**:BOOL
- Default to ``ON``. When ``LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN`` is ``ON``,
- these keep ``libLTO`` and ``libclang``'s Darwin dylib identities
- unversioned. Set ``LLVM_UNVERSIONED_LIBLTO_ON_DARWIN`` to ``OFF`` to
- version ``libLTO`` using its Darwin ``LTO_VERSION`` policy instead. Set
- ``LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN`` to ``OFF`` to version
- ``libclang`` using its existing ABI version policy instead.
+
+: Defaults to `ON`. If set to `ON`, Darwin shared libraries built through
+ LLVM's CMake helpers use versioned dylib filenames and install names,
+ matching the behavior on other Unix platforms more closely. If set to
+ `OFF`, Darwin keeps the legacy unversioned dylib install name, for
+ compatibility with existing consumers that expect `@rpath/libLLVM.dylib`.
+
+**LLVM_UNVERSIONED\_{LIBLTO,LIBCLANG}\_ON_DARWIN**:BOOL
+
+: Default to `ON`. When `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN` is `ON`, these
+ keep `libLTO` and `libclang`'s Darwin dylib identities unversioned. Set
+ `LLVM_UNVERSIONED_LIBLTO_ON_DARWIN` to `OFF` to version `libLTO` using its
+ Darwin `LTO_VERSION` policy instead. Set
+ `LLVM_UNVERSIONED_LIBCLANG_ON_DARWIN` to `OFF` to version `libclang` using
+ its existing ABI version policy instead.
**LLVM_OPTIMIZED_TABLEGEN**:BOOL
- If enabled and building a debug or assert build, the CMake build system will
- generate a Release build tree to build a fully optimized tablegen for use
- during the build. Enabling this option can significantly speed up build times,
- especially when building LLVM in Debug configurations.
-**LLVM_PARALLEL_{COMPILE,LINK,TABLEGEN}_JOBS**:STRING
- Limit the maximum number of concurrent compilation, link or
- tablegen jobs respectively. The default total number of parallel jobs is
- determined by the number of logical CPUs.
+: If enabled and building a debug or assert build, the CMake build system
+ will generate a Release build tree to build a fully optimized tablegen for
+ use during the build. Enabling this option can significantly speed up build
+ times, especially when building LLVM in Debug configurations.
+
+**LLVM_PARALLEL\_{COMPILE,LINK,TABLEGEN}\_JOBS**:STRING
+
+: Limit the maximum number of concurrent compilation, link or tablegen jobs
+ respectively. The default total number of parallel jobs is determined by
+ the number of logical CPUs.
**LLVM_PROFDATA_FILE**:PATH
- Path to a profdata file to pass into clang's ``-fprofile-instr-use`` flag. This
- can only be specified if you're building with clang.
-
-**LLVM_RAM_PER_{COMPILE,LINK,TABLEGEN}_JOB**:STRING
- Limit the number of concurrent compile, link or tablegen jobs
- respectively, depending on available physical memory. The value
- specified is in MB. The respective
- ``LLVM_PARALLEL_{COMPILE,LINK,TABLEGEN}_JOBS`` variable is
- overwritten by computing the memory size divided by the
- specified value. The largest memory user is linking, but remember
- that jobs in the other categories might run in parallel with the link
- jobs, and you need to consider their memory requirements when
- in a memory-limited environment. Using a
- ``-DLLVM_RAM_PER_LINK_JOB=10000`` is a good approximation. On ELF
- platforms debug builds can reduce link-time memory pressure by also
- using ``LLVM_USE_SPLIT_DWARF``.
+
+: Path to a profdata file to pass into clang's `-fprofile-instr-use` flag.
+ This can only be specified if you're building with clang.
+
+**LLVM_RAM_PER\_{COMPILE,LINK,TABLEGEN}\_JOB**:STRING
+
+: Limit the number of concurrent compile, link or tablegen jobs respectively,
+ depending on available physical memory. The value specified is in MB. The
+ respective `LLVM_PARALLEL_{COMPILE,LINK,TABLEGEN}_JOBS` variable is
+ overwritten by computing the memory size divided by the specified value.
+ The largest memory user is linking, but remember that jobs in the other
+ categories might run in parallel with the link jobs, and you need to
+ consider their memory requirements when in a memory-limited environment.
+ Using a `-DLLVM_RAM_PER_LINK_JOB=10000` is a good approximation. On ELF
+ platforms debug builds can reduce link-time memory pressure by also using
+ `LLVM_USE_SPLIT_DWARF`.
**LLVM_REVERSE_ITERATION**:BOOL
- If enabled, all supported unordered llvm containers would be iterated in
- reverse order. This is useful for uncovering non-determinism caused by
- iteration of unordered containers.
+
+: If enabled, all supported unordered llvm containers would be iterated in
+ reverse order. This is useful for uncovering non-determinism caused by
+ iteration of unordered containers.
**LLVM_STATIC_LINK_CXX_STDLIB**:BOOL
- Statically link to the C++ standard library if possible. This uses the flag
- ``-static-libstdc++``, but a Clang host compiler will statically link to libc++
- if used in conjunction with the **LLVM_ENABLE_LIBCXX** flag. Defaults to OFF.
+
+: Statically link to the C++ standard library if possible. This uses the flag
+ `-static-libstdc++`, but a Clang host compiler will statically link to
+ libc++ if used in conjunction with the **LLVM_ENABLE_LIBCXX** flag.
+ Defaults to OFF.
**LLVM_TABLEGEN**:STRING
- Full path to a native TableGen executable (usually named ``llvm-tblgen``). This is
- intended for cross-compiling: if the user sets this variable, no native
- TableGen will be created.
+
+: Full path to a native TableGen executable (usually named `llvm-tblgen`).
+ This is intended for cross-compiling: if the user sets this variable, no
+ native TableGen will be created.
**LLVM_TARGET_ARCH**:STRING
- LLVM target to use for native code generation. This is required for JIT
- generation. It defaults to "host", meaning that it shall pick the architecture
- of the machine where LLVM is being built. If you are cross-compiling, set it
- to the target architecture name.
+
+: LLVM target to use for native code generation. This is required for JIT
+ generation. It defaults to \"host\", meaning that it shall pick the
+ architecture of the machine where LLVM is being built. If you are
+ cross-compiling, set it to the target architecture name.
**LLVM_TARGETS_TO_BUILD**:STRING
- Semicolon-separated list of targets to build, or *all* for building all
- targets. Case-sensitive. Defaults to *all*. Example:
- ``-DLLVM_TARGETS_TO_BUILD="X86;PowerPC"``.
- The full list, as of August 2025, is:
- ``AArch64;AMDGPU;ARM;AVR;BPF;Hexagon;Lanai;LoongArch;Mips;MSP430;NVPTX;PowerPC;RISCV;Sparc;SPIRV;SystemZ;VE;WebAssembly;X86;XCore``
-
- You can also specify ``host`` or ``Native`` to automatically detect and
- include the target corresponding to the host machine's architecture, or
- use ``all`` to include all available targets.
- For example, on an x86_64 machine, specifying ``-DLLVM_TARGETS_TO_BUILD=host``
- will include the ``X86`` target.
+
+: Semicolon-separated list of targets to build, or *all* for building all
+ targets. Case-sensitive. Defaults to *all*. Example:
+ `-DLLVM_TARGETS_TO_BUILD="X86;PowerPC"`. The full list, as of August 2025,
+ is:
+ `AArch64;AMDGPU;ARM;AVR;BPF;Hexagon;Lanai;LoongArch;Mips;MSP430;NVPTX;PowerPC;RISCV;Sparc;SPIRV;SystemZ;VE;WebAssembly;X86;XCore`
+
+ You can also specify `host` or `Native` to automatically detect and include
+ the target corresponding to the host machine's architecture, or use `all`
+ to include all available targets. For example, on an x86_64 machine,
+ specifying `-DLLVM_TARGETS_TO_BUILD=host` will include the `X86` target.
**LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN**:BOOL
- If enabled, the compiler version check will only warn when using a toolchain
- which is about to be deprecated, instead of emitting an error.
+
+: If enabled, the compiler version check will only warn when using a
+ toolchain which is about to be deprecated, instead of emitting an error.
**LLVM_UBSAN_FLAGS**:STRING
- Defines the set of compile flags used to enable UBSan. Only used if
- ``LLVM_USE_SANITIZER`` contains ``Undefined``. This can be used to override
- the default set of UBSan flags.
+
+: Defines the set of compile flags used to enable UBSan. Only used if
+ `LLVM_USE_SANITIZER` contains `Undefined`. This can be used to override the
+ default set of UBSan flags.
**LLVM_UNREACHABLE_OPTIMIZE**:BOOL
- This flag controls the behavior of ``llvm_unreachable()`` in a release build
- (when assertions are disabled in general). When ON (default) then
- ``llvm_unreachable()`` is considered "undefined behavior" and optimized as
- such. When OFF it is instead replaced with a guaranteed "trap".
+
+: This flag controls the behavior of `llvm_unreachable()` in a release build
+ (when assertions are disabled in general). When ON (default) then
+ `llvm_unreachable()` is considered \"undefined behavior\" and optimized as
+ such. When OFF it is instead replaced with a guaranteed \"trap\".
**LLVM_USE_INTEL_JITEVENTS**:BOOL
- Enable building support for Intel JIT Events API. Defaults to OFF.
+
+: Enable building support for Intel JIT Events API. Defaults to OFF.
**LLVM_USE_LINKER**:STRING
- Add ``-fuse-ld={name}`` to the link invocation. The possible values depend on
- your compiler. For clang, the value can be an absolute path to your custom
- linker, otherwise clang will prefix the name with ``ld.`` and apply its usual
- search. For example, to link LLVM with the Gold linker, cmake can be invoked
- with ``-DLLVM_USE_LINKER=gold``.
+
+: Add `-fuse-ld={name}` to the link invocation. The possible values depend on
+ your compiler. For clang, the value can be an absolute path to your custom
+ linker, otherwise clang will prefix the name with `ld.` and apply its usual
+ search. For example, to link LLVM with the Gold linker, cmake can be
+ invoked with `-DLLVM_USE_LINKER=gold`.
**LLVM_USE_OPROFILE**:BOOL
- Enable building OProfile JIT support. Defaults to OFF.
+
+: Enable building OProfile JIT support. Defaults to OFF.
**LLVM_USE_PERF**:BOOL
- Enable building support for Perf (linux profiling tool) JIT support. Defaults to OFF.
+
+: Enable building support for Perf (linux profiling tool) JIT support.
+ Defaults to OFF.
**LLVM_USE_RELATIVE_PATHS_IN_FILES**:BOOL
- Rewrite absolute source paths in sources and debug info to relative ones. The
- source prefix can be adjusted via the ``LLVM_SOURCE_PREFIX`` variable.
+
+: Rewrite absolute source paths in sources and debug info to relative ones.
+ The source prefix can be adjusted via the `LLVM_SOURCE_PREFIX` variable.
**LLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO**:BOOL
- Rewrite absolute source paths in debug info to relative ones. The source prefix
- can be adjusted via the ``LLVM_SOURCE_PREFIX`` variable.
+
+: Rewrite absolute source paths in debug info to relative ones. The source
+ prefix can be adjusted via the `LLVM_SOURCE_PREFIX` variable.
**LLVM_USE_SANITIZER**:STRING
- Define the sanitizer used to build LLVM binaries and tests. Possible values
- are ``Address``, ``HWAddress``, ``Memory``, ``MemoryWithOrigins``, ``Undefined``,
- ``Thread``, ``DataFlow``, ``Leaks``, and ``Address;Undefined``. Defaults to
- empty string.
+
+: Define the sanitizer used to build LLVM binaries and tests. Possible values
+ are `Address`, `HWAddress`, `Memory`, `MemoryWithOrigins`, `Undefined`,
+ `Thread`, `DataFlow`, `Leaks`, and `Address;Undefined`. Defaults to empty
+ string.
**LLVM_USE_SPLIT_DWARF**:BOOL
- If enabled CMake will pass ``-gsplit-dwarf`` to the compiler. This option
- reduces link-time memory usage by reducing the amount of debug information that
- the linker needs to resolve. It is recommended for platforms using the ELF object
- format, like Linux systems when linker memory usage is too high.
+
+: If enabled CMake will pass `-gsplit-dwarf` to the compiler. This option
+ reduces link-time memory usage by reducing the amount of debug information
+ that the linker needs to resolve. It is recommended for platforms using the
+ ELF object format, like Linux systems when linker memory usage is too high.
**SPHINX_EXECUTABLE**:STRING
- The path to the ``sphinx-build`` executable detected by CMake.
- For installation instructions, see
- https://www.sphinx-doc.org/en/master/usage/installation.html
+
+: The path to the `sphinx-build` executable detected by CMake. For
+ installation instructions, see
+ <https://www.sphinx-doc.org/en/master/usage/installation.html>
**SPHINX_OUTPUT_HTML**:BOOL
- If enabled (and ``LLVM_ENABLE_SPHINX`` is enabled) then the targets for
- building the documentation as HTML are added (but not built by default unless
- ``LLVM_BUILD_DOCS`` is enabled). There is a target for each project in the
- source tree that uses sphinx (e.g., ``docs-llvm-html``, ``docs-clang-html``
- and ``docs-lld-html``). Defaults to ON.
+
+: If enabled (and `LLVM_ENABLE_SPHINX` is enabled) then the targets for
+ building the documentation as HTML are added (but not built by default
+ unless `LLVM_BUILD_DOCS` is enabled). There is a target for each project in
+ the source tree that uses sphinx (e.g., `docs-llvm-html`, `docs-clang-html`
+ and `docs-lld-html`). Defaults to ON.
**SPHINX_OUTPUT_MAN**:BOOL
- If enabled (and ``LLVM_ENABLE_SPHINX`` is enabled) the targets for building
- the man pages are added (but not built by default unless ``LLVM_BUILD_DOCS``
- is enabled). Currently the only target added is ``docs-llvm-man``. Defaults
- to ON.
+
+: If enabled (and `LLVM_ENABLE_SPHINX` is enabled) the targets for building
+ the man pages are added (but not built by default unless `LLVM_BUILD_DOCS`
+ is enabled). Currently the only target added is `docs-llvm-man`. Defaults
+ to ON.
**SPHINX_WARNINGS_AS_ERRORS**:BOOL
- If enabled, then sphinx documentation warnings will be treated as
- errors. Defaults to ON.
-Advanced variables
-~~~~~~~~~~~~~~~~~~
+: If enabled, then sphinx documentation warnings will be treated as errors.
+ Defaults to ON.
+
+#### Advanced variables
These are niche, and changing them from their defaults is more likely to cause
-things to go wrong. They are also unstable across LLVM versions.
+things to go wrong. They are also unstable across LLVM versions.
**LLVM_EXAMPLES_INSTALL_DIR**:STRING
- The path for examples of using LLVM, relative to the *CMAKE_INSTALL_PREFIX*.
- Only matters if *LLVM_BUILD_EXAMPLES* is enabled.
- Defaults to "examples".
+
+: The path for examples of using LLVM, relative to the
+ *CMAKE_INSTALL_PREFIX*. Only matters if *LLVM_BUILD_EXAMPLES* is enabled.
+ Defaults to \"examples\".
**LLVM_TOOLS_INSTALL_DIR**:STRING
- The path to install the main LLVM tools, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to *CMAKE_INSTALL_BINDIR*.
+
+: The path to install the main LLVM tools, relative to the
+ *CMAKE_INSTALL_PREFIX*. Defaults to *CMAKE_INSTALL_BINDIR*.
**LLVM_UTILS_INSTALL_DIR**:STRING
- The path to install auxiliary LLVM utilities, relative to the *CMAKE_INSTALL_PREFIX*.
- Only matters if *LLVM_INSTALL_UTILS* is enabled.
- Defaults to *LLVM_TOOLS_INSTALL_DIR*.
-CMake Caches
-============
+: The path to install auxiliary LLVM utilities, relative to the
+ *CMAKE_INSTALL_PREFIX*. Only matters if *LLVM_INSTALL_UTILS* is enabled.
+ Defaults to *LLVM_TOOLS_INSTALL_DIR*.
+
+## CMake Caches
Recently, LLVM and Clang have been adding some more complicated build system
features. Utilizing these new features often involves a complicated chain of
CMake variables passed on the command line. Clang provides a collection of CMake
cache scripts to make these features more approachable.
-CMake cache files are utilized using CMake's ``-C`` flag:
-
-.. code-block:: console
+CMake cache files are utilized using CMake's `-C` flag:
- $ cmake -C <path to cache file> <path to sources>
+``` console
+$ cmake -C <path to cache file> <path to sources>
+```
CMake cache scripts are processed in an isolated scope, only cached variables
remain set when the main configuration runs. CMake cached variables do not reset
@@ -1000,242 +1107,242 @@ variables that are already set unless the FORCE option is specified.
A few notes about CMake Caches:
- Order of command line arguments is important
-
- - ``-D`` arguments specified before ``-C`` are set before the cache is processed and
- can be read inside the cache file
- - ``-D`` arguments specified after ``-C`` are set after the cache is processed and
- are unset inside the cache file
-
-- All ``-D`` arguments will override cache file settings
+ - `-D` arguments specified before `-C` are set before the cache is processed and
+ can be read inside the cache file
+ - `-D` arguments specified after `-C` are set after the cache is processed and
+ are unset inside the cache file
+- All `-D` arguments will override cache file settings
- CMAKE_TOOLCHAIN_FILE is evaluated after both the cache file and the command
- line arguments
-- It is recommended that all ``-D`` options be specified *before* ``-C``
+ line arguments
+- It is recommended that all `-D` options be specified *before* `-C`
For more information about some of the advanced build configurations supported
-via Cache files see :doc:`AdvancedBuilds`.
+via Cache files see {doc}`AdvancedBuilds`.
-Executing the Tests
-===================
+## Executing the Tests
Testing is performed when the *check-all* target is built. For instance, if you are
using Makefiles, execute this command in the root of your build directory:
-.. code-block:: console
+``` console
+$ make check-all
+```
- $ make check-all
+On Visual Studio, you may run tests by building the project \"check-all\".
+For more information about testing, see the {doc}`TestingGuide`.
-On Visual Studio, you may run tests by building the project "check-all".
-For more information about testing, see the :doc:`TestingGuide`.
+## Cross compiling
-Cross compiling
-===============
+See [this wiki
+page](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling)
+for generic instructions on how to cross-compile with CMake. It goes into
+detailed explanations and may seem daunting, but it is not. The wiki page has
+several examples including toolchain files. Go directly to the `Information how
+to set up various cross compiling toolchains` section for a quick solution.
-See `this wiki page <https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling>`_ for
-generic instructions on how to cross-compile with CMake. It goes into detailed
-explanations and may seem daunting, but it is not. The wiki page has
-several examples including toolchain files. Go directly to the
-``Information how to set up various cross compiling toolchains`` section
-for a quick solution.
+Also see the [LLVM-related variables](#llvm-related-variables) section for
+variables used when cross-compiling.
-Also see the `LLVM-related variables`_ section for variables used when
-cross-compiling.
-
-Embedding LLVM in your project
-==============================
+## Embedding LLVM in your project
From LLVM 3.5 onward, the CMake build system exports LLVM libraries as
importable CMake targets. This means that clients of LLVM can now reliably use
CMake to develop their own LLVM-based projects against an installed version of
LLVM regardless of how it was built.
-Here is a simple example of a ``CMakeLists.txt`` file that imports the LLVM libraries
-and uses them to build a simple application ``simple-tool``.
-
-.. code-block:: cmake
+Here is a simple example of a `CMakeLists.txt` file that imports the LLVM libraries
+and uses them to build a simple application `simple-tool`.
- cmake_minimum_required(VERSION 3.20.0)
- project(SimpleProject)
+``` cmake
+cmake_minimum_required(VERSION 3.20.0)
+project(SimpleProject)
- find_package(LLVM REQUIRED CONFIG)
+find_package(LLVM REQUIRED CONFIG)
- message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
- message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
- # Set your project compile flags.
- # E.g. if using the C++ header files
- # you will need to enable C++11 support
- # for your compiler.
+# Set your project compile flags.
+# E.g. if using the C++ header files
+# you will need to enable C++11 support
+# for your compiler.
- include_directories(${LLVM_INCLUDE_DIRS})
- separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
- add_definitions(${LLVM_DEFINITIONS_LIST})
+include_directories(${LLVM_INCLUDE_DIRS})
+separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
+add_definitions(${LLVM_DEFINITIONS_LIST})
- # Now build our tools
- add_executable(simple-tool tool.cpp)
+# Now build our tools
+add_executable(simple-tool tool.cpp)
- # Find the libraries that correspond to the LLVM components
- # that we wish to use
- llvm_map_components_to_libnames(llvm_libs support core irreader)
+# Find the libraries that correspond to the LLVM components
+# that we wish to use
+llvm_map_components_to_libnames(llvm_libs support core irreader)
- # Link against LLVM libraries
- target_link_libraries(simple-tool ${llvm_libs})
+# Link against LLVM libraries
+target_link_libraries(simple-tool ${llvm_libs})
+```
-The ``find_package(...)`` directive when used in CONFIG mode (as in the above
-example) will look for the ``LLVMConfig.cmake`` file in various locations (see
-CMake manual for details). It creates an ``LLVM_DIR`` cache entry to save the
-directory where ``LLVMConfig.cmake`` is found or allows the user to specify the
-directory (e.g., by passing ``-DLLVM_DIR=/usr/lib/cmake/llvm`` to
-the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``).
+The `find_package(...)` directive when used in CONFIG mode (as in the above
+example) will look for the `LLVMConfig.cmake` file in various locations (see
+CMake manual for details). It creates an `LLVM_DIR` cache entry to save the
+directory where `LLVMConfig.cmake` is found or allows the user to specify the
+directory (e.g., by passing `-DLLVM_DIR=/usr/lib/cmake/llvm` to
+the `cmake` command or by setting it directly in `ccmake` or `cmake-gui`).
This file is available in two different locations.
-* ``<LLVM_INSTALL_PACKAGE_DIR>/LLVMConfig.cmake`` where
- ``<LLVM_INSTALL_PACKAGE_DIR>`` is the location where LLVM CMake modules are
- installed as part of an installed version of LLVM. This is typically
- ``cmake/llvm/`` within the lib directory. On Linux, this is typically
- ``/usr/lib/cmake/llvm/LLVMConfig.cmake``.
-
-* ``<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake`` where
- ``<LLVM_BUILD_ROOT>`` is the root of the LLVM build tree. **Note: this is only
- available when building LLVM with CMake.**
+- `<LLVM_INSTALL_PACKAGE_DIR>/LLVMConfig.cmake` where
+ `<LLVM_INSTALL_PACKAGE_DIR>` is the location where LLVM CMake modules are
+ installed as part of an installed version of LLVM. This is typically
+ `cmake/llvm/` within the lib directory. On Linux, this is typically
+ `/usr/lib/cmake/llvm/LLVMConfig.cmake`.
+- `<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake` where
+ `<LLVM_BUILD_ROOT>` is the root of the LLVM build tree. **Note: this is
+ only available when building LLVM with CMake.**
If LLVM is installed in your operating system's normal installation prefix (e.g.
-on Linux this is usually ``/usr/``) ``find_package(LLVM ...)`` will
+on Linux this is usually `/usr/`) `find_package(LLVM ...)` will
automatically find LLVM if it is installed correctly. If LLVM is not installed
or you wish to build directly against the LLVM build tree you can use
-``LLVM_DIR`` as previously mentioned.
+`LLVM_DIR` as previously mentioned.
-The ``LLVMConfig.cmake`` file sets various useful variables. Notable variables
+The `LLVMConfig.cmake` file sets various useful variables. Notable variables
include:
-``LLVM_CMAKE_DIR``
- The path to the LLVM CMake directory (i.e., the directory containing
- ``LLVMConfig.cmake``).
+`LLVM_CMAKE_DIR`
-``LLVM_DEFINITIONS``
- A list of preprocessor defines that should be used when building against LLVM.
+: The path to the LLVM CMake directory (i.e., the directory containing
+ `LLVMConfig.cmake`).
-``LLVM_ENABLE_ASSERTIONS``
- This is set to ON if LLVM was built with assertions, otherwise OFF.
+`LLVM_DEFINITIONS`
-``LLVM_ENABLE_EH``
- This is set to ON if LLVM was built with exception handling (EH) enabled,
- otherwise OFF.
+: A list of preprocessor defines that should be used when building against
+ LLVM.
-``LLVM_ENABLE_RTTI``
- This is set to ON if LLVM was built with run time type information (RTTI),
- otherwise OFF.
+`LLVM_ENABLE_ASSERTIONS`
-``LLVM_INCLUDE_DIRS``
- A list of include paths to directories containing LLVM header files.
+: This is set to ON if LLVM was built with assertions, otherwise OFF.
-``LLVM_PACKAGE_VERSION``
- The LLVM version. This string can be used with CMake conditionals, e.g., ``if
- (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")``.
+`LLVM_ENABLE_EH`
-``LLVM_TOOLS_BINARY_DIR``
- The path to the directory containing the LLVM tools (e.g., ``llvm-as``).
+: This is set to ON if LLVM was built with exception handling (EH) enabled,
+ otherwise OFF.
-Notice that in the above example we link ``simple-tool`` against several LLVM
-libraries. The list of libraries is determined by using the
-``llvm_map_components_to_libnames()`` CMake function. For a list of available
-components look at the output of running ``llvm-config --components``.
+`LLVM_ENABLE_RTTI`
-Note that for LLVM < 3.5 ``llvm_map_components_to_libraries()`` was
-used instead of ``llvm_map_components_to_libnames()``. This is now deprecated
-and will be removed in a future version of LLVM.
+: This is set to ON if LLVM was built with run time type information (RTTI),
+ otherwise OFF.
-.. _cmake-out-of-source-pass:
+`LLVM_INCLUDE_DIRS`
-Developing LLVM passes out of source
-------------------------------------
+: A list of include paths to directories containing LLVM header files.
-You can develop LLVM passes out of LLVM's source tree (i.e., against an
-installed or built LLVM). An example of a project layout is provided below.
+`LLVM_PACKAGE_VERSION`
-.. code-block:: none
+: The LLVM version. This string can be used with CMake conditionals, e.g.,
+ `if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")`.
- <project dir>/
- |
- CMakeLists.txt
- <pass name>/
- |
- CMakeLists.txt
- Pass.cpp
- ...
+`LLVM_TOOLS_BINARY_DIR`
-Contents of ``<project dir>/CMakeLists.txt``:
+: The path to the directory containing the LLVM tools (e.g., `llvm-as`).
-.. code-block:: cmake
+Notice that in the above example we link `simple-tool` against several LLVM
+libraries. The list of libraries is determined by using the
+`llvm_map_components_to_libnames()` CMake function. For a list of available
+components look at the output of running `llvm-config --components`.
+
+Note that for LLVM \< 3.5 `llvm_map_components_to_libraries()` was
+used instead of `llvm_map_components_to_libnames()`. This is now deprecated
+and will be removed in a future version of LLVM.
- find_package(LLVM REQUIRED CONFIG)
+(cmake-out-of-source-pass)=
+### Developing LLVM passes out of source
- separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
- add_definitions(${LLVM_DEFINITIONS_LIST})
- include_directories(${LLVM_INCLUDE_DIRS})
+You can develop LLVM passes out of LLVM's source tree (i.e., against an
+installed or built LLVM). An example of a project layout is provided below.
- add_subdirectory(<pass name>)
+``` none
+<project dir>/
+ |
+ CMakeLists.txt
+ <pass name>/
+ |
+ CMakeLists.txt
+ Pass.cpp
+ ...
+```
-Contents of ``<project dir>/<pass name>/CMakeLists.txt``:
+Contents of `<project dir>/CMakeLists.txt`:
-.. code-block:: cmake
+``` cmake
+find_package(LLVM REQUIRED CONFIG)
- add_library(LLVMPassname MODULE Pass.cpp)
+separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
+add_definitions(${LLVM_DEFINITIONS_LIST})
+include_directories(${LLVM_INCLUDE_DIRS})
-Note if you intend for this pass to be merged into the LLVM source tree at some
-point in the future it might make more sense to use LLVM's internal
-``add_llvm_library`` function with the MODULE argument instead by...
+add_subdirectory(<pass name>)
+```
+Contents of `<project dir>/<pass name>/CMakeLists.txt`:
-Adding the following to ``<project dir>/CMakeLists.txt`` (after
-``find_package(LLVM ...)``)
+``` cmake
+add_library(LLVMPassname MODULE Pass.cpp)
+```
-.. code-block:: cmake
+Note if you intend for this pass to be merged into the LLVM source tree at some
+point in the future it might make more sense to use LLVM's internal
+`add_llvm_library` function with the MODULE argument instead by\...
- list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
- include(AddLLVM)
+Adding the following to `<project dir>/CMakeLists.txt` (after
+`find_package(LLVM ...)`)
-And then changing ``<project dir>/<pass name>/CMakeLists.txt`` to
+``` cmake
+list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
+include(AddLLVM)
+```
-.. code-block:: cmake
+And then changing `<project dir>/<pass name>/CMakeLists.txt` to
- add_llvm_library(LLVMPassname MODULE
- Pass.cpp
- )
+``` cmake
+add_llvm_library(LLVMPassname MODULE
+ Pass.cpp
+ )
+```
When you are done developing your pass, you may wish to integrate it
into the LLVM source tree. You can achieve it in two easy steps:
-#. Copying ``<pass name>`` folder into ``<LLVM root>/lib/Transforms`` directory.
-
-#. Adding ``add_subdirectory(<pass name>)`` line into
- ``<LLVM root>/lib/Transforms/CMakeLists.txt``.
+1. Copying `<pass name>` folder into `<LLVM root>/lib/Transforms` directory.
+2. Adding `add_subdirectory(<pass name>)` line into `<LLVM
+ root>/lib/Transforms/CMakeLists.txt`.
-Compiler/Platform-specific topics
-=================================
+## Compiler/Platform-specific topics
Notes for specific compilers and/or platforms.
-Windows
--------
+### Windows
**LLVM_COMPILER_JOBS**:STRING
- Specifies the maximum number of parallel compiler jobs to use per project
- when building with msbuild or Visual Studio. Only supported for the Visual
- Studio 2010 CMake generator. 0 means use all processors. Default is 0.
+
+: Specifies the maximum number of parallel compiler jobs to use per project
+ when building with msbuild or Visual Studio. Only supported for the Visual
+ Studio 2010 CMake generator. 0 means use all processors. Default is 0.
**CMAKE_MT**:STRING
- When compiling with clang-cl, CMake may use ``llvm-mt`` as the Manifest Tool
- when available. ```llvm-mt``` is only present when libxml2 is found at build-time.
- To ensure using Microsoft's Manifest Tool set `CMAKE_MT=mt`.
-Apple/OSX
----------
+: When compiling with clang-cl, CMake may use `llvm-mt` as the Manifest Tool
+ when available. `llvm-mt` is only present when libxml2 is found at
+ build-time. To ensure using Microsoft's Manifest Tool set `CMAKE_MT=mt`.
+
+### Apple/OSX
**CMAKE_OSX_SYSROOT**:STRING
- When compiling for OSX, in order for the test suite to find libSystem to link
- dylib tests you'll need to run CMake with ```xcrun --show-sdk-path``` as the
- string to pass in so that the testsuite can find your os libraries.
- This will show up as ```ld: library not found for -lSystem``` when running
- tests.
+: When compiling for OSX, in order for the test suite to find libSystem to
+ link dylib tests you'll need to run CMake with `` `xcrun --show-sdk-path
+ ``\` as the string to pass in so that the testsuite can find your os
+ libraries.
+
+ This will show up as `` `ld: library not found for -lSystem ``\` when
+ running tests.
diff --git a/llvm/docs/CodeGenerator.md b/llvm/docs/CodeGenerator.md
index d5a019dcb06ba..0dc033d4e5cb6 100644
--- a/llvm/docs/CodeGenerator.md
+++ b/llvm/docs/CodeGenerator.md
@@ -1,32 +1,28 @@
-==========================================
-The LLVM Target-Independent Code Generator
-==========================================
-
-.. role:: raw-html(raw)
- :format: html
-
-.. raw:: html
-
- <style>
- .unknown { background-color: #C0C0C0; text-align: center; }
- .unknown:before { content: "?" }
- .no { background-color: #C11B17 }
- .no:before { content: "N" }
- .partial { background-color: #F88017 }
- .yes { background-color: #0F0; }
- .yes:before { content: "Y" }
- .na { background-color: #6666FF; }
- .na:before { content: "N/A" }
- </style>
-
-.. contents::
- :local:
-
-.. warning::
- This is a work in progress.
-
-Introduction
-============
+# The LLVM Target-Independent Code Generator
+
+
+```{raw} html
+<style>
+ .unknown { background-color: #C0C0C0; text-align: center; }
+ .unknown:before { content: "?" }
+ .no { background-color: #C11B17 }
+ .no:before { content: "N" }
+ .partial { background-color: #F88017 }
+ .yes { background-color: #0F0; }
+ .yes:before { content: "Y" }
+ .na { background-color: #6666FF; }
+ .na:before { content: "N/A" }
+</style>
+```
+
+```{contents}
+:local:
+```
+
+```{warning}
+This is a work in progress.
+```
+## Introduction
The LLVM target-independent code generator is a framework that provides a suite
of reusable components for translating the LLVM internal representation to the
@@ -35,54 +31,53 @@ static compiler) or in binary machine code format (usable for a JIT
compiler). The LLVM target-independent code generator consists of six main
components:
-1. `Abstract target description`_ interfaces which capture important properties
+1. {ref}`Abstract target description <Abstract target description>` interfaces which capture important properties
about various aspects of the machine, independently of how they will be used.
- These interfaces are defined in ``include/llvm/Target/``.
+ These interfaces are defined in `include/llvm/Target/`.
-2. Classes used to represent the `code being generated`_ for a target. These
+2. Classes used to represent the {ref}`code being generated <code being generated>` for a target. These
classes are intended to be abstract enough to represent the machine code for
*any* target machine. These classes are defined in
- ``include/llvm/CodeGen/``. At this level, concepts like "constant pool
+ `include/llvm/CodeGen/`. At this level, concepts like "constant pool
entries" and "jump tables" are explicitly exposed.
3. Classes and algorithms used to represent code at the object file level, the
- `MC Layer`_. These classes represent assembly level constructs like labels,
+ {ref}`MC Layer <MC Layer>`. These classes represent assembly level constructs like labels,
sections, and instructions. At this level, concepts like "constant pool
entries" and "jump tables" don't exist.
-4. `Target-independent algorithms`_ used to implement various phases of native
+4. {ref}`Target-independent algorithms <Target-independent algorithms>` used to implement various phases of native
code generation (register allocation, scheduling, stack frame representation,
- etc). This code lives in ``lib/CodeGen/``.
+ etc). This code lives in `lib/CodeGen/`.
-5. `Implementations of the abstract target description interfaces`_ for
+5. {ref}`Implementations of the abstract target description interfaces <Implementations of the abstract target description interfaces>` for
particular targets. These machine descriptions make use of the components
provided by LLVM, and can optionally provide custom target-specific passes,
to build complete code generators for a specific target. Target descriptions
- live in ``lib/Target/``.
+ live in `lib/Target/`.
6. The target-independent JIT components. The LLVM JIT is completely target
- independent (it uses the ``TargetJITInfo`` structure to interface for
+ independent (it uses the `TargetJITInfo` structure to interface for
target-specific issues. The code for the target-independent JIT lives in
- ``lib/ExecutionEngine/JIT``.
+ `lib/ExecutionEngine/JIT`.
Depending on which part of the code generator you are interested in working on,
different pieces of this will be useful to you. In any case, you should be
-familiar with the `target description`_ and `machine code representation`_
+familiar with the {ref}`target description <target description>` and {ref}`machine code representation <machine code representation>`
classes. If you want to add a backend for a new target, you will need to
-`implement the target description`_ classes for your new target and understand
-the :doc:`LLVM code representation <LangRef>`. If you are interested in
-implementing a new `code generation algorithm`_, it should only depend on the
+{ref}`implement the target description <implement the target description>` classes for your new target and understand
+the {doc}`LLVM code representation <LangRef>`. If you are interested in
+implementing a new {ref}`code generation algorithm <code generation algorithm>`, it should only depend on the
target-description and machine code representation classes, ensuring that it is
portable.
-Required components in the code generator
------------------------------------------
+### Required components in the code generator
The two pieces of the LLVM code generator are the high-level interface to the
code generator and the set of reusable components that can be used to build
-target-specific backends. The two most important interfaces (:raw-html:`<tt>`
-`TargetMachine`_ :raw-html:`</tt>` and :raw-html:`<tt>` `DataLayout`_
-:raw-html:`</tt>`) are the only ones that are required to be defined for a
+target-specific backends. The two most important interfaces (
+{ref}`TargetMachine <TargetMachine>` and {ref}`DataLayout <DataLayout>`
+) are the only ones that are required to be defined for a
backend to fit into the LLVM system, but the others must be defined if the
reusable code generator components are going to be used.
@@ -101,16 +96,15 @@ built-in components. Doing so is not recommended at all, but could be required
for radically different targets that do not fit into the LLVM machine
description model: FPGAs for example.
-.. _high-level design of the code generator:
+(high-level design of the code generator)=
-The high-level design of the code generator
--------------------------------------------
+### The high-level design of the code generator
The LLVM target-independent code generator is designed to support efficient and
quality code generation for standard register-based microprocessors. Code
generation in this model is divided into the following stages:
-1. `Instruction Selection`_ --- This phase determines an efficient way to
+1. {ref}`Instruction Selection <Instruction Selection>` --- This phase determines an efficient way to
express the input LLVM code in the target instruction set. This stage
produces the initial code for the program in the target instruction set, then
makes use of virtual registers in SSA form and physical registers that
@@ -118,35 +112,35 @@ generation in this model is divided into the following stages:
calling conventions. This step turns the LLVM code into a DAG of target
instructions.
-2. `Scheduling and Formation`_ --- This phase takes the DAG of target
+2. {ref}`Scheduling and Formation <Scheduling and Formation>` --- This phase takes the DAG of target
instructions produced by the instruction selection phase, determines an
- ordering of the instructions, then emits the instructions as :raw-html:`<tt>`
- `MachineInstr`_\s :raw-html:`</tt>` with that ordering. Note that we
- describe this in the `instruction selection section`_ because it operates on
- a `SelectionDAG`_.
+ ordering of the instructions, then emits the instructions as
+ {ref}`MachineInstr <MachineInstr>`s with that ordering. Note that we
+ describe this in the {ref}`instruction selection section <instruction selection section>` because it operates on
+ a {ref}`SelectionDAG <SelectionDAG>`.
-3. `SSA-based Machine Code Optimizations`_ --- This optional stage consists of a
+3. {ref}`SSA-based Machine Code Optimizations <SSA-based Machine Code Optimizations>` --- This optional stage consists of a
series of machine-code optimizations that operate on the SSA-form produced by
the instruction selector. Optimizations like modulo-scheduling or peephole
optimization work here.
-4. `Register Allocation`_ --- The target code is transformed from an infinite
+4. {ref}`Register Allocation <Register Allocation>` --- The target code is transformed from an infinite
virtual register file in SSA form to the concrete register file used by the
target. This phase introduces spill code and eliminates all virtual register
references from the program.
-5. `Prolog/Epilog Code Insertion`_ --- Once the machine code has been generated
+5. {ref}`Prolog/Epilog Code Insertion <Prolog/Epilog Code Insertion>` --- Once the machine code has been generated
for the function and the amount of stack space required is known (used for
LLVM alloca's and spill slots), the prolog and epilog code for the function
can be inserted and "abstract stack location references" can be eliminated.
This stage is responsible for implementing optimizations like frame-pointer
elimination and stack packing.
-6. `Late Machine Code Optimizations`_ --- Optimizations that operate on "final"
+6. {ref}`Late Machine Code Optimizations <Late Machine Code Optimizations>` --- Optimizations that operate on "final"
machine code can go here, such as spill code scheduling and peephole
optimizations.
-7. `Code Emission`_ --- The final stage actually puts out the code for the
+7. {ref}`Code Emission <Code Emission>` --- The final stage actually puts out the code for the
current function, either in the target assembler format or in machine
code.
@@ -164,191 +158,179 @@ target-specific passes into the flow. For example, the X86 target uses a
special pass to handle the 80x87 floating point stack architecture. Other
targets with unusual requirements can be supported with custom passes as needed.
-Using TableGen for target description
--------------------------------------
+### Using TableGen for target description
The target description classes require a detailed description of the target
architecture. These target descriptions often have a large amount of common
-information (e.g., an ``add`` instruction is almost identical to a ``sub``
+information (e.g., an `add` instruction is almost identical to a `sub`
instruction). In order to allow the maximum amount of commonality to be
factored out, the LLVM code generator uses the
-:doc:`TableGen/index` tool to describe big chunks of the
+{doc}`TableGen/index` tool to describe big chunks of the
target machine, which allows the use of domain-specific and target-specific
abstractions to reduce the amount of repetition.
As LLVM continues to be developed and refined, we plan to move more and more of
-the target description to the ``.td`` form. Doing so gives us a number of
+the target description to the `.td` form. Doing so gives us a number of
advantages. The most important is that it makes it easier to port LLVM because
it reduces the amount of C++ code that has to be written, and the surface area
of the code generator that needs to be understood before someone can get
something working. Second, it makes it easier to change things. In particular,
-if tables and other things are all emitted by ``tblgen``, we only need a change
-in one place (``tblgen``) to update all of the targets to a new interface.
+if tables and other things are all emitted by `tblgen`, we only need a change
+in one place (`tblgen`) to update all of the targets to a new interface.
-.. _Abstract target description:
-.. _target description:
+(Abstract target description)=
+(target description)=
-Target description classes
-==========================
+## Target description classes
-The LLVM target description classes (located in the ``include/llvm/Target``
+The LLVM target description classes (located in the `include/llvm/Target`
directory) provide an abstract description of the target machine independent of
any particular client. These classes are designed to capture the *abstract*
properties of the target (such as the instructions and registers it has), and do
not incorporate any particular pieces of code generation algorithms.
-All of the target description classes (except the :raw-html:`<tt>` `DataLayout`_
-:raw-html:`</tt>` class) are designed to be subclassed by the concrete target
+All of the target description classes (except the {ref}`DataLayout <DataLayout>`
+class) are designed to be subclassed by the concrete target
implementation, and have virtual methods implemented. To get to these
-implementations, the :raw-html:`<tt>` `TargetMachine`_ :raw-html:`</tt>` class
+implementations, the {ref}`TargetMachine <TargetMachine>` class
provides accessors that should be implemented by the target.
-.. _TargetMachine:
+(TargetMachine)=
-The ``TargetMachine`` class
----------------------------
+### The `TargetMachine` class
-The ``TargetMachine`` class provides virtual methods that are used to access the
+The `TargetMachine` class provides virtual methods that are used to access the
target-specific implementations of the various target description classes via
-the ``get*Info`` methods (``getInstrInfo``, ``getRegisterInfo``,
-``getFrameInfo``, etc.). This class is designed to be specialized by a concrete
-target implementation (e.g., ``X86TargetMachine``) which implements the various
+the `get*Info` methods (`getInstrInfo`, `getRegisterInfo`,
+`getFrameInfo`, etc.). This class is designed to be specialized by a concrete
+target implementation (e.g., `X86TargetMachine`) which implements the various
virtual methods. The only required target description class is the
-:raw-html:`<tt>` `DataLayout`_ :raw-html:`</tt>` class, but if the code
+{ref}`DataLayout <DataLayout>` class, but if the code
generator components are to be used, the other interfaces should be implemented
as well.
-.. _DataLayout:
+(DataLayout)=
-The ``DataLayout`` class
-------------------------
+### The `DataLayout` class
-The ``DataLayout`` class is the only required target description class, and it
+The `DataLayout` class is the only required target description class, and it
is the only class that is not extensible (you cannot derive a new class from
-it). ``DataLayout`` specifies information about how the target lays out memory
+it). `DataLayout` specifies information about how the target lays out memory
for structures, the alignment requirements for various data types, the size of
pointers in the target, and whether the target is little-endian or
big-endian.
-.. _TargetLowering:
+(TargetLowering)=
-The ``TargetLowering`` class
-----------------------------
+### The `TargetLowering` class
-The ``TargetLowering`` class is used by SelectionDAG based instruction selectors
+The `TargetLowering` class is used by SelectionDAG based instruction selectors
primarily to describe how LLVM code should be lowered to SelectionDAG
operations. Among other things, this class indicates:
-* an initial register class to use for various ``ValueType``\s,
+* an initial register class to use for various `ValueType`s,
* which operations are natively supported by the target machine,
-* the return type of ``setcc`` operations,
+* the return type of `setcc` operations,
* the type to use for shift amounts, and
* various high-level characteristics, like whether it is profitable to turn
division by a constant into a multiplication sequence.
-.. _TargetRegisterInfo:
+(TargetRegisterInfo)=
-The ``TargetRegisterInfo`` class
---------------------------------
+### The `TargetRegisterInfo` class
-The ``TargetRegisterInfo`` class is used to describe the register file of the
+The `TargetRegisterInfo` class is used to describe the register file of the
target and any interactions between the registers.
Registers are represented in the code generator by unsigned integers. Physical
registers (those that actually exist in the target description) are unique
small numbers, and virtual registers are generally large. Note that
-register ``#0`` is reserved as a flag value.
+register `#0` is reserved as a flag value.
Each register in the processor description has an associated
-``TargetRegisterDesc`` entry, which provides a textual name for the register
+`TargetRegisterDesc` entry, which provides a textual name for the register
(used for assembly output and debugging dumps) and a set of aliases (used to
indicate whether one register overlaps with another).
-In addition to the per-register description, the ``TargetRegisterInfo`` class
+In addition to the per-register description, the `TargetRegisterInfo` class
exposes a set of processor-specific register classes (instances of the
-``TargetRegisterClass`` class). Each register class contains sets of registers
+`TargetRegisterClass` class). Each register class contains sets of registers
that have the same properties (for example, they are all 32-bit integer
registers). Each SSA virtual register created by the instruction selector has
an associated register class. When the register allocator runs, it replaces
virtual registers with a physical register in the set.
The target-specific implementations of these classes is auto-generated from a
-:doc:`TableGen/index` description of the register file.
+{doc}`TableGen/index` description of the register file.
-.. _TargetInstrInfo:
+(TargetInstrInfo)=
-The ``TargetInstrInfo`` class
------------------------------
+### The `TargetInstrInfo` class
-The ``TargetInstrInfo`` class is used to describe the machine instructions
+The `TargetInstrInfo` class is used to describe the machine instructions
supported by the target. Descriptions define things like the mnemonic for
the opcode, the number of operands, the list of implicit register uses and defs,
whether the instruction has certain target-independent properties (accesses
memory, is commutable, etc), and holds any target-specific flags.
-The ``TargetFrameLowering`` class
----------------------------------
+### The `TargetFrameLowering` class
-The ``TargetFrameLowering`` class is used to provide information about the stack
+The `TargetFrameLowering` class is used to provide information about the stack
frame layout of the target. It holds the direction of stack growth, the known
stack alignment on entry to each function, and the offset to the local area.
The offset to the local area is the offset from the stack pointer on function
entry to the first location where function data (local variables, spill
locations) can be stored.
-The ``TargetSubtarget`` class
------------------------------
+### The `TargetSubtarget` class
-The ``TargetSubtarget`` class is used to provide information about the specific
+The `TargetSubtarget` class is used to provide information about the specific
chip set being targeted. A sub-target informs code generation of which
instructions are supported, instruction latencies and instruction execution
itinerary; i.e., which processing units are used, in what order, and for how
long.
-The ``TargetJITInfo`` class
----------------------------
+### The `TargetJITInfo` class
-The ``TargetJITInfo`` class exposes an abstract interface used by the
+The `TargetJITInfo` class exposes an abstract interface used by the
Just-In-Time code generator to perform target-specific activities, such as
-emitting stubs. If a ``TargetMachine`` supports JIT code generation, it should
-provide one of these objects through the ``getJITInfo`` method.
+emitting stubs. If a `TargetMachine` supports JIT code generation, it should
+provide one of these objects through the `getJITInfo` method.
-.. _code being generated:
-.. _machine code representation:
+(code being generated)=
+(machine code representation)=
-Machine code description classes
-================================
+## Machine code description classes
At the high-level, LLVM code is translated to a machine-specific representation
-formed out of :raw-html:`<tt>` `MachineFunction`_ :raw-html:`</tt>`,
-:raw-html:`<tt>` `MachineBasicBlock`_ :raw-html:`</tt>`, and :raw-html:`<tt>`
-`MachineInstr`_ :raw-html:`</tt>` instances (defined in
-``include/llvm/CodeGen``). This representation is completely target agnostic,
+formed out of {ref}`MachineFunction <MachineFunction>`,
+{ref}`MachineBasicBlock <MachineBasicBlock>`, and
+{ref}`MachineInstr <MachineInstr>` instances (defined in
+`include/llvm/CodeGen`). This representation is completely target agnostic,
representing instructions in their most abstract form: an opcode and a series of
operands. This representation is designed to support both an SSA representation
for machine code, as well as a register allocated, non-SSA form.
-.. _MachineInstr:
+(MachineInstr)=
-The ``MachineInstr`` class
---------------------------
+### The `MachineInstr` class
-Target machine instructions are represented as instances of the ``MachineInstr``
+Target machine instructions are represented as instances of the `MachineInstr`
class. This class is an extremely abstract way of representing machine
instructions. In particular, it only keeps track of an opcode number and a set
of operands.
The opcode number is a simple unsigned integer that only has meaning to a
specific backend. All of the instructions for a target should be defined in the
-``*InstrInfo.td`` file for the target. The opcode enum values are auto-generated
-from this description. The ``MachineInstr`` class does not have any information
+`*InstrInfo.td` file for the target. The opcode enum values are auto-generated
+from this description. The `MachineInstr` class does not have any information
about how to interpret the instruction (i.e., what the semantics of the
-instruction are); for that you must refer to the :raw-html:`<tt>`
-`TargetInstrInfo`_ :raw-html:`</tt>` class.
+instruction are); for that you must refer to the
+{ref}`TargetInstrInfo <TargetInstrInfo>` class.
The operands of a machine instruction can be of several different types: a
register reference, a constant integer, a basic block reference, etc. In
@@ -358,109 +340,101 @@ addition, a machine operand should be marked as a def or a use of the value
By convention, the LLVM code generator orders instruction operands so that all
register definitions come before the register uses, even on architectures that
are normally printed in other orders. For example, the SPARC add instruction:
-"``add %i1, %i2, %i3``" adds the "%i1", and "%i2" registers and stores the
+"`add %i1, %i2, %i3`" adds the "%i1", and "%i2" registers and stores the
result into the "%i3" register. In the LLVM code generator, the operands should
-be stored as "``%i3, %i1, %i2``": with the destination first.
+be stored as "`%i3, %i1, %i2`": with the destination first.
Keeping destination (definition) operands at the beginning of the operand list
has several advantages. In particular, the debugging printer will print the
instruction like this:
-.. code-block:: llvm
-
- %r3 = add %i1, %i2
-
-Also if the first operand is a def, it is easier to `create instructions`_ whose
+```llvm
+%r3 = add %i1, %i2
+```
+Also if the first operand is a def, it is easier to {ref}`create instructions <create instructions>` whose
only def is the first operand.
-.. _create instructions:
+(create instructions)=
-Using the ``MachineInstrBuilder.h`` functions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Using the `MachineInstrBuilder.h` functions
-Machine instructions are created by using the ``BuildMI`` functions, located in
-the ``include/llvm/CodeGen/MachineInstrBuilder.h`` file. The ``BuildMI``
+Machine instructions are created by using the `BuildMI` functions, located in
+the `include/llvm/CodeGen/MachineInstrBuilder.h` file. The `BuildMI`
functions make it easy to build arbitrary machine instructions. Usage of the
-``BuildMI`` functions look like this:
-
-.. code-block:: c++
+`BuildMI` functions look like this:
- // Create a 'DestReg = mov 42' (rendered in X86 assembly as 'mov DestReg, 42')
- // instruction and insert it at the end of the given MachineBasicBlock.
- const TargetInstrInfo &TII = ...
- MachineBasicBlock &MBB = ...
- DebugLoc DL;
- MachineInstr *MI = BuildMI(MBB, DL, TII.get(X86::MOV32ri), DestReg).addImm(42);
+```c++
+// Create a 'DestReg = mov 42' (rendered in X86 assembly as 'mov DestReg, 42')
+// instruction and insert it at the end of the given MachineBasicBlock.
+const TargetInstrInfo &TII = ...
+MachineBasicBlock &MBB = ...
+DebugLoc DL;
+MachineInstr *MI = BuildMI(MBB, DL, TII.get(X86::MOV32ri), DestReg).addImm(42);
- // Create the same instr, but insert it before a specified iterator point.
- MachineBasicBlock::iterator MBBI = ...
- BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), DestReg).addImm(42);
+// Create the same instr, but insert it before a specified iterator point.
+MachineBasicBlock::iterator MBBI = ...
+BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), DestReg).addImm(42);
- // Create a 'cmp Reg, 0' instruction, no destination reg.
- MI = BuildMI(MBB, DL, TII.get(X86::CMP32ri8)).addReg(Reg).addImm(42);
+// Create a 'cmp Reg, 0' instruction, no destination reg.
+MI = BuildMI(MBB, DL, TII.get(X86::CMP32ri8)).addReg(Reg).addImm(42);
- // Create an 'sahf' instruction which takes no operands and stores nothing.
- MI = BuildMI(MBB, DL, TII.get(X86::SAHF));
-
- // Create a self looping branch instruction.
- BuildMI(MBB, DL, TII.get(X86::JNE)).addMBB(&MBB);
+// Create an 'sahf' instruction which takes no operands and stores nothing.
+MI = BuildMI(MBB, DL, TII.get(X86::SAHF));
+// Create a self looping branch instruction.
+BuildMI(MBB, DL, TII.get(X86::JNE)).addMBB(&MBB);
+```
If you need to add a definition operand (other than the optional destination
register), you must explicitly mark it as such:
-.. code-block:: c++
-
- MI.addReg(Reg, RegState::Define);
-
-Fixed (preassigned) registers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```c++
+MI.addReg(Reg, RegState::Define);
+```
+#### Fixed (preassigned) registers
One important issue that the code generator needs to be aware of is the presence
of fixed registers. In particular, there are often places in the instruction
stream where the register allocator *must* arrange for a particular value to be
in a particular register. This can occur due to limitations of the instruction
-set (e.g., the X86 can only do a 32-bit divide with the ``EAX``/``EDX``
+set (e.g., the X86 can only do a 32-bit divide with the `EAX`/`EDX`
registers), or external factors like calling conventions. In any case, the
instruction selector should emit code that copies a virtual register into or out
of a physical register when needed.
For example, consider this simple LLVM example:
-.. code-block:: llvm
-
- define i32 @test(i32 %X, i32 %Y) {
- %Z = sdiv i32 %X, %Y
- ret i32 %Z
- }
-
-The X86 instruction selector might produce this machine code for the ``div`` and
-``ret``:
-
-.. code-block:: text
-
- ;; Start of div
- %EAX = mov %reg1024 ;; Copy X (in reg1024) into EAX
- %reg1027 = sar %reg1024, 31
- %EDX = mov %reg1027 ;; Sign extend X into EDX
- idiv %reg1025 ;; Divide by Y (in reg1025)
- %reg1026 = mov %EAX ;; Read the result (Z) out of EAX
-
- ;; Start of ret
- %EAX = mov %reg1026 ;; 32-bit return value goes in EAX
- ret
-
+```llvm
+define i32 @test(i32 %X, i32 %Y) {
+ %Z = sdiv i32 %X, %Y
+ ret i32 %Z
+}
+```
+The X86 instruction selector might produce this machine code for the `div` and
+`ret`:
+
+```text
+;; Start of div
+%EAX = mov %reg1024 ;; Copy X (in reg1024) into EAX
+%reg1027 = sar %reg1024, 31
+%EDX = mov %reg1027 ;; Sign extend X into EDX
+idiv %reg1025 ;; Divide by Y (in reg1025)
+%reg1026 = mov %EAX ;; Read the result (Z) out of EAX
+
+;; Start of ret
+%EAX = mov %reg1026 ;; 32-bit return value goes in EAX
+ret
+```
By the end of code generation, the register allocator would coalesce the
registers and delete the resultant identity moves producing the following
code:
-.. code-block:: text
-
- ;; X is in EAX, Y is in ECX
- mov %EAX, %EDX
- sar %EDX, 31
- idiv %ECX
- ret
-
+```text
+;; X is in EAX, Y is in ECX
+mov %EAX, %EDX
+sar %EDX, 31
+idiv %ECX
+ret
+```
This approach is extremely general (if it can handle the X86 architecture, it
can handle anything!) and allows all of the target-specific knowledge about the
instruction stream to be isolated in the instruction selector. Note that
@@ -469,19 +443,17 @@ all physical registers are assumed dead on entry to and exit from basic blocks
(before register allocation). Thus, if you need a value to be live across basic
block boundaries, it *must* live in a virtual register.
-Call-clobbered registers
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Call-clobbered registers
Some machine instructions, like calls, clobber a large number of physical
-registers. Rather than adding ``<def,dead>`` operands for all of them, it is
-possible to use an ``MO_RegisterMask`` operand instead. The register mask
+registers. Rather than adding `<def,dead>` operands for all of them, it is
+possible to use an `MO_RegisterMask` operand instead. The register mask
operand holds a bit mask of preserved registers, and everything else is
considered to be clobbered by the instruction.
-Machine code in SSA form
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Machine code in SSA form
-``MachineInstr``'s are initially selected in SSA-form, and are maintained in
+`MachineInstr`'s are initially selected in SSA-form, and are maintained in
SSA-form until register allocation happens. For the most part, this is
trivially simple since LLVM is already in SSA form; LLVM PHI nodes become
machine code PHI nodes, and virtual registers are only allowed to have a single
@@ -490,33 +462,30 @@ definition.
After register allocation, machine code is no longer in SSA-form because there
are no virtual registers left in the code.
-.. _MachineBasicBlock:
+(MachineBasicBlock)=
-The ``MachineBasicBlock`` class
--------------------------------
+### The `MachineBasicBlock` class
-The ``MachineBasicBlock`` class contains a list of machine instructions
-(:raw-html:`<tt>` `MachineInstr`_ :raw-html:`</tt>` instances). It roughly
+The `MachineBasicBlock` class contains a list of machine instructions
+( {ref}`MachineInstr <MachineInstr>` instances). It roughly
corresponds to the LLVM code input to the instruction selector, but there can be
a one-to-many mapping (i.e., one LLVM basic block can map to multiple machine
-basic blocks). The ``MachineBasicBlock`` class has a "``getBasicBlock``" method,
+basic blocks). The `MachineBasicBlock` class has a "`getBasicBlock`" method,
which returns the LLVM basic block that it comes from.
-.. _MachineFunction:
+(MachineFunction)=
-The ``MachineFunction`` class
------------------------------
+### The `MachineFunction` class
-The ``MachineFunction`` class contains a list of machine basic blocks
-(:raw-html:`<tt>` `MachineBasicBlock`_ :raw-html:`</tt>` instances). It
+The `MachineFunction` class contains a list of machine basic blocks
+( {ref}`MachineBasicBlock <MachineBasicBlock>` instances). It
corresponds one-to-one with the LLVM function input to the instruction selector.
-In addition to a list of basic blocks, the ``MachineFunction`` contains a
-``MachineConstantPool``, a ``MachineFrameInfo``, a ``MachineFunctionInfo``, and
-a ``MachineRegisterInfo``. See ``include/llvm/CodeGen/MachineFunction.h`` for
+In addition to a list of basic blocks, the `MachineFunction` contains a
+`MachineConstantPool`, a `MachineFrameInfo`, a `MachineFunctionInfo`, and
+a `MachineRegisterInfo`. See `include/llvm/CodeGen/MachineFunction.h` for
more information.
-``MachineInstr Bundles``
-------------------------
+### `MachineInstr Bundles`
LLVM code generator can model sequences of instructions as MachineInstr
bundles. A MI bundle can model a VLIW group / pack which contains an arbitrary
@@ -526,41 +495,41 @@ separated (e.g., ARM Thumb2 IT blocks).
Conceptually a MI bundle is a MI with a number of other MIs nested within:
-::
-
- --------------
- | Bundle | ---------
- -------------- \
- | ----------------
- | | MI |
- | ----------------
- | |
- | ----------------
- | | MI |
- | ----------------
- | |
- | ----------------
- | | MI |
- | ----------------
- |
- --------------
- | Bundle | --------
- -------------- \
- | ----------------
- | | MI |
- | ----------------
- | |
- | ----------------
- | | MI |
- | ----------------
- | |
- | ...
- |
- --------------
- | Bundle | --------
- -------------- \
- |
- ...
+```
+--------------
+| Bundle | ---------
+-------------- \
+ | ----------------
+ | | MI |
+ | ----------------
+ | |
+ | ----------------
+ | | MI |
+ | ----------------
+ | |
+ | ----------------
+ | | MI |
+ | ----------------
+ |
+--------------
+| Bundle | --------
+-------------- \
+ | ----------------
+ | | MI |
+ | ----------------
+ | |
+ | ----------------
+ | | MI |
+ | ----------------
+ | |
+ | ...
+ |
+--------------
+| Bundle | --------
+-------------- \
+ |
+ ...
+```
MI bundle support does not change the physical representations of
MachineBasicBlock and MachineInstr. All the MIs (including top level and nested
@@ -592,31 +561,29 @@ effectively double the virtual register def and use lists. Bundles may
use virtual registers and be formed in SSA form, but may not be
appropriate for all use cases.
-.. _MC Layer:
+(MC Layer)=
-The "MC" Layer
-==============
+## The "MC" Layer
The MC Layer is used to represent and process code at the raw machine code
level, devoid of "high level" information like "constant pools", "jump tables",
"global variables" or anything like that. At this level, LLVM handles things
like label names, machine instructions, and sections in the object file. The
code in this layer is used for a number of important purposes: the tail end of
-the code generator uses it to write a ``.s`` or ``.o`` file, and it is also used by the
+the code generator uses it to write a `.s` or `.o` file, and it is also used by the
llvm-mc tool to implement standalone machine code assemblers and disassemblers.
This section describes some of the important classes. There are also a number
of important subsystems that interact at this layer, they are described later in
this manual.
-.. _MCStreamer:
+(MCStreamer)=
-The ``MCStreamer`` API
-----------------------
+### The `MCStreamer` API
MCStreamer is best thought of as an assembler API. It is an abstract API which
-is *implemented* in different ways (e.g., to output a ``.s`` file, output an ELF ``.o``
-file, etc) but whose API corresponds directly to what you see in a ``.s`` file.
+is *implemented* in different ways (e.g., to output a `.s` file, output an ELF `.o`
+file, etc) but whose API corresponds directly to what you see in a `.s` file.
MCStreamer has one method per directive, such as EmitLabel, EmitSymbolAttribute,
switchSection, emitValue (for .byte, .word), etc, which directly correspond to
assembly level directives. It also has an EmitInstruction method, which is used
@@ -624,21 +591,21 @@ to output an MCInst to the streamer.
This API is most important for two clients: the llvm-mc stand-alone assembler is
effectively a parser that parses a line, then invokes a method on MCStreamer. In
-the code generator, the `Code Emission`_ phase of the code generator lowers
+the code generator, the {ref}`Code Emission <Code Emission>` phase of the code generator lowers
higher level LLVM IR and Machine* constructs down to the MC layer, emitting
directives through MCStreamer.
On the implementation side of MCStreamer, there are two major implementations:
-one for writing out a ``.s`` file (MCAsmStreamer), and one for writing out a ``.o``
+one for writing out a `.s` file (MCAsmStreamer), and one for writing out a `.o`
file (MCObjectStreamer). MCAsmStreamer is a straightforward implementation
-that prints out a directive for each method (e.g., ``EmitValue -> .byte``), but
+that prints out a directive for each method (e.g., `EmitValue -> .byte`), but
MCObjectStreamer implements a full assembler.
For target-specific directives, the MCStreamer has a MCTargetStreamer instance.
Each target that needs it defines a class that inherits from it and is a lot
like MCStreamer itself: It has one method per directive and two classes that
inherit from it, a target object streamer and a target asm streamer. The target
-asm streamer just prints it (``emitFnStart -> .fnstart``), and the object
+asm streamer just prints it (`emitFnStart -> .fnstart`), and the object
streamer implements the assembler logic for it.
To make llvm use these classes, the target initialization must call
@@ -646,15 +613,13 @@ TargetRegistry::RegisterAsmStreamer and TargetRegistry::RegisterMCObjectStreamer
passing callbacks that allocate the corresponding target streamer and pass it
to createAsmStreamer or to the appropriate object streamer constructor.
-The ``MCContext`` class
------------------------
+### The `MCContext` class
The MCContext class is the owner of a variety of uniqued data structures at the
MC layer, including symbols, sections, etc. As such, this is the class that you
interact with to create symbols and sections. This class can not be subclassed.
-The ``MCSymbol`` class
-----------------------
+### The `MCSymbol` class
The MCSymbol class represents a symbol (aka label) in the assembly file. There
are two interesting kinds of symbols: assembler temporary symbols, and normal
@@ -667,45 +632,42 @@ MCSymbols are created by MCContext and uniqued there. This means that MCSymbols
can be compared for pointer equivalence to find out if they are the same symbol.
Note that pointer inequality does not guarantee the labels will end up at
different addresses though. It's perfectly legal to output something like this
-to the ``.s`` file:
-
-::
+to the `.s` file:
- foo:
- bar:
- .byte 4
+```
+foo:
+bar:
+ .byte 4
+```
In this case, both the foo and bar symbols will have the same address.
-The ``MCSection`` class
------------------------
+### The `MCSection` class
-The ``MCSection`` class represents an object-file specific section. It is
-subclassed by object file specific implementations (e.g., ``MCSectionMachO``,
-``MCSectionCOFF``, ``MCSectionELF``) and these are created and uniqued by
+The `MCSection` class represents an object-file specific section. It is
+subclassed by object file specific implementations (e.g., `MCSectionMachO`,
+`MCSectionCOFF`, `MCSectionELF`) and these are created and uniqued by
MCContext. The MCStreamer has a notion of the current section, which can be
changed with the SwitchToSection method (which corresponds to a ".section"
-directive in a ``.s`` file).
+directive in a `.s` file).
-.. _MCInst:
+(MCInst)=
-The ``MCInst`` class
---------------------
+### The `MCInst` class
-The ``MCInst`` class is a target-independent representation of an instruction.
-It is a simple class (much more so than `MachineInstr`_) that holds a
+The `MCInst` class is a target-independent representation of an instruction.
+It is a simple class (much more so than {ref}`MachineInstr <MachineInstr>`) that holds a
target-specific opcode and a vector of MCOperands. MCOperand, in turn, is a
simple discriminated union of three cases: 1) a simple immediate, 2) a target
-register ID, 3) a symbolic expression (e.g., "``Lfoo-Lbar+42``") as an MCExpr.
+register ID, 3) a symbolic expression (e.g., "`Lfoo-Lbar+42`") as an MCExpr.
MCInst is the common currency used to represent machine instructions at the MC
layer. It is the type used by the instruction encoder, the instruction printer,
and the type generated by the assembly parser and disassembler.
-.. _ObjectFormats:
+(ObjectFormats)=
-Object File Format
-------------------
+### Object File Format
The MC layer's object writers support a variety of object formats. Because of
target-specific aspects of object formats each target only supports a subset of
@@ -718,36 +680,31 @@ and WebAssembly).
The table below captures a snapshot of object file support in LLVM:
- .. table:: Object File Formats
+```{table} Object File Formats
+| Format | Supported Targets |
+| --- | --- |
+| `COFF` | AArch64, ARM, X86 |
+| `DXContainer` | DirectX |
+| `ELF` | AArch64, AMDGPU, ARM, AVR, BPF, CSKY, Hexagon, Lanai, LoongArch, M86k, MSP430, MIPS, PowerPC, RISCV, SPARC, SystemZ, VE, X86 |
+| `GOFF` | SystemZ |
+| `MachO` | AArch64, ARM, X86 |
+| `SPIR-V` | SPIRV |
+| `WASM` | WebAssembly |
+| `XCOFF` | PowerPC |
+```
+(Target-independent algorithms)=
+(code generation algorithm)=
- ================== ========================================================
- Format Supported Targets
- ================== ========================================================
- ``COFF`` AArch64, ARM, X86
- ``DXContainer`` DirectX
- ``ELF`` AArch64, AMDGPU, ARM, AVR, BPF, CSKY, Hexagon, Lanai, LoongArch, M86k, MSP430, MIPS, PowerPC, RISCV, SPARC, SystemZ, VE, X86
- ``GOFF`` SystemZ
- ``MachO`` AArch64, ARM, X86
- ``SPIR-V`` SPIRV
- ``WASM`` WebAssembly
- ``XCOFF`` PowerPC
- ================== ========================================================
+## Target-independent code generation algorithms
-.. _Target-independent algorithms:
-.. _code generation algorithm:
+This section documents the phases described in the
+{ref}`high-level design of the code generator <high-level design of the code generator>`.
+It explains how they work and some of the rationale behind their design.
-Target-independent code generation algorithms
-=============================================
+(Instruction Selection)=
+(instruction selection section)=
-This section documents the phases described in the `high-level design of the
-code generator`_. It explains how they work and some of the rationale behind
-their design.
-
-.. _Instruction Selection:
-.. _instruction selection section:
-
-Instruction Selection
----------------------
+### Instruction Selection
Instruction Selection is the process of translating LLVM code presented to the
code generator into target-specific machine instructions. There are several
@@ -755,17 +712,16 @@ well-known ways to do this in the literature. LLVM uses a SelectionDAG based
instruction selector.
Portions of the DAG instruction selector are generated from the target
-description (``*.td``) files. Our goal is for the entire instruction selector
-to be generated from these ``.td`` files, though currently there are still
+description (`*.td`) files. Our goal is for the entire instruction selector
+to be generated from these `.td` files, though currently there are still
things that require custom C++ code.
-`GlobalISel <https://llvm.org/docs/GlobalISel/index.html>`_ is another
+[GlobalISel](https://llvm.org/docs/GlobalISel/index.html) is another
instruction selection framework.
-.. _SelectionDAG:
+(SelectionDAG)=
-Introduction to SelectionDAGs
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Introduction to SelectionDAGs
The SelectionDAG provides an abstraction for code representation in a way that
is amenable to instruction selection using automatic techniques
@@ -773,30 +729,30 @@ is amenable to instruction selection using automatic techniques
well-suited to other phases of code generation; in particular, instruction
scheduling (SelectionDAG's are very close to scheduling DAGs post-selection).
Additionally, the SelectionDAG provides a host representation where a large
-variety of very-low-level (but target-independent) `optimizations`_ may be
+variety of very-low-level (but target-independent) {ref}`optimizations <optimizations>` may be
performed; ones which require extensive information about the instructions
efficiently supported by the target.
The SelectionDAG is a Directed-Acyclic-Graph whose nodes are instances of the
-``SDNode`` class. The primary payload of the ``SDNode`` is its operation code
+`SDNode` class. The primary payload of the `SDNode` is its operation code
(Opcode) that indicates what operation the node performs and the operands to the
operation. The various operation node types are described at the top of the
-``include/llvm/CodeGen/ISDOpcodes.h`` file.
+`include/llvm/CodeGen/ISDOpcodes.h` file.
Although most operations define a single value, each node in the graph may
define multiple values. For example, a combined div/rem operation will define
both the dividend and the remainder. Many other situations require multiple
values as well. Each node also has some number of operands, which are edges to
the node defining the used value. Because nodes may define multiple values,
-edges are represented by instances of the ``SDValue`` class, which is a
-``<SDNode, unsigned>`` pair, indicating the node and result value being used,
-respectively. Each value produced by an ``SDNode`` has an associated ``MVT``
+edges are represented by instances of the `SDValue` class, which is a
+`<SDNode, unsigned>` pair, indicating the node and result value being used,
+respectively. Each value produced by an `SDNode` has an associated `MVT`
(Machine Value Type) indicating what the type of the value is.
SelectionDAGs contain two different kinds of values: those that represent data
flow and those that represent control flow dependencies. Data values are simple
edges with an integer or floating point value type. Control edges are
-represented as "chain" edges which are of type ``MVT::Other``. These edges
+represented as "chain" edges which are of type `MVT::Other`. These edges
provide an ordering between nodes that have side effects (such as loads, stores,
calls, returns, etc). All nodes that have side effects should take a token
chain as input and produce a new one as output. By convention, token chain
@@ -806,7 +762,7 @@ machine nodes have their chain after the instruction's operands, and
may be followed by glue nodes.
A SelectionDAG has designated "Entry" and "Root" nodes. The Entry node is
-always a marker node with an Opcode of ``ISD::EntryToken``. The Root node is
+always a marker node with an Opcode of `ISD::EntryToken`. The Root node is
the final side-effecting node in the token chain. For example, in a single basic
block function it would be the return node.
@@ -814,42 +770,42 @@ One important concept for SelectionDAGs is the notion of a "legal" vs.
"illegal" DAG. A legal DAG for a target is one that only uses supported
operations and supported types. On a 32-bit PowerPC, for example, a DAG with a
value of type i1, i8, i16, or i64 would be illegal, as would a DAG that uses a
-SREM or UREM operation. The `legalize types`_ and `legalize operations`_ phases
+SREM or UREM operation. The {ref}`legalize types <legalize types>` and {ref}`legalize operations <legalize operations>` phases
are responsible for turning an illegal DAG into a legal DAG.
-.. _SelectionDAG-Process:
+(SelectionDAG-Process)=
-SelectionDAG Instruction Selection Process
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG Instruction Selection Process
SelectionDAG-based instruction selection consists of the following steps:
-#. `Build initial DAG`_ --- This stage performs a simple translation from the
+1. {ref}`Build initial DAG <Build initial DAG>` --- This stage performs a simple translation from the
input LLVM code to an illegal SelectionDAG.
-#. `Optimize SelectionDAG`_ --- This stage performs simple optimizations on the
+1. {ref}`Optimize SelectionDAG <Optimize SelectionDAG>` --- This stage performs simple optimizations on the
SelectionDAG to simplify it, and recognize meta instructions (like rotates
- and ``div``/``rem`` pairs) for targets that support these meta operations.
- This makes the resultant code more efficient and the `select instructions
- from DAG`_ phase (below) simpler.
+ and `div`/`rem` pairs) for targets that support these meta operations.
+ This makes the resultant code more efficient and the
+ {ref}`select instructions from DAG <Select instructions from DAG>` phase
+ (below) simpler.
-#. `Legalize SelectionDAG Types`_ --- This stage transforms SelectionDAG nodes
+1. {ref}`Legalize SelectionDAG Types <Legalize SelectionDAG Types>` --- This stage transforms SelectionDAG nodes
to eliminate any types that are unsupported on the target.
-#. `Optimize SelectionDAG`_ --- The SelectionDAG optimizer is run to clean up
+1. {ref}`Optimize SelectionDAG <Optimize SelectionDAG>` --- The SelectionDAG optimizer is run to clean up
redundancies exposed by type legalization.
-#. `Legalize SelectionDAG Ops`_ --- This stage transforms SelectionDAG nodes to
+1. {ref}`Legalize SelectionDAG Ops <Legalize SelectionDAG Ops>` --- This stage transforms SelectionDAG nodes to
eliminate any operations that are unsupported on the target.
-#. `Optimize SelectionDAG`_ --- The SelectionDAG optimizer is run to eliminate
+1. {ref}`Optimize SelectionDAG <Optimize SelectionDAG>` --- The SelectionDAG optimizer is run to eliminate
inefficiencies introduced by operation legalization.
-#. `Select instructions from DAG`_ --- Finally, the target instruction selector
+1. {ref}`Select instructions from DAG <Select instructions from DAG>` --- Finally, the target instruction selector
matches the DAG operations to target instructions. This process translates
the target-independent input DAG into another DAG of target instructions.
-#. `SelectionDAG Scheduling and Formation`_ --- The last phase assigns a linear
+1. {ref}`SelectionDAG Scheduling and Formation <SelectionDAG Scheduling and Formation>` --- The last phase assigns a linear
order to the instructions in the target-instruction DAG and emits them into
the MachineFunction being compiled. This step uses traditional prepass
scheduling techniques.
@@ -857,59 +813,57 @@ SelectionDAG-based instruction selection consists of the following steps:
After all of these steps are complete, the SelectionDAG is destroyed and the
rest of the code generation passes are run.
-One of the most common ways to debug these steps is using ``-debug-only=isel``,
+One of the most common ways to debug these steps is using `-debug-only=isel`,
which prints out the DAG, along with other information like debug info,
-after each of these steps. Alternatively, ``-debug-only=isel-dump`` shows only
+after each of these steps. Alternatively, `-debug-only=isel-dump` shows only
the DAG dumps, but the results can be filtered by function names using
-``-filter-print-funcs=<function names>``.
+`-filter-print-funcs=<function names>`.
One great way to visualize what is going on here is to take advantage of a few
LLC command line options. The following options pop up a window displaying the
SelectionDAG at specific times (if you only get errors printed to the console
-while using this, you probably `need to configure your
-system <ProgrammersManual.html#viewing-graphs-while-debugging-code>`_ to add support for it).
+while using this, you probably {ref}`need to configure your system <ViewGraph>`
+to add support for it).
-* ``-view-dag-combine1-dags`` displays the DAG after being built, before the
+* `-view-dag-combine1-dags` displays the DAG after being built, before the
first optimization pass.
-* ``-view-legalize-dags`` displays the DAG before Legalization.
+* `-view-legalize-dags` displays the DAG before Legalization.
-* ``-view-dag-combine2-dags`` displays the DAG before the second optimization
+* `-view-dag-combine2-dags` displays the DAG before the second optimization
pass.
-* ``-view-isel-dags`` displays the DAG before the Select phase.
+* `-view-isel-dags` displays the DAG before the Select phase.
-* ``-view-sched-dags`` displays the DAG before Scheduling.
+* `-view-sched-dags` displays the DAG before Scheduling.
-The ``-view-sunit-dags`` displays the Scheduler's dependency graph. This graph
+The `-view-sunit-dags` displays the Scheduler's dependency graph. This graph
is based on the final SelectionDAG, with nodes that must be scheduled together
bundled into a single scheduling-unit node, and with immediate operands and
other nodes that aren't relevant for scheduling omitted.
-The option ``-filter-view-dags`` allows to select the name of the basic block
+The option `-filter-view-dags` allows to select the name of the basic block
that you are interested in visualizing and filters all the previous
-``view-*-dags`` options.
+`view-*-dags` options.
-.. _Build initial DAG:
+(Build initial DAG)=
-Initial SelectionDAG Construction
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Initial SelectionDAG Construction
-The initial SelectionDAG is na\ :raw-html:`ï`\ vely peephole expanded from
-the LLVM input by the ``SelectionDAGBuilder`` class. The intent of this pass
+The initial SelectionDAG is naïvely peephole expanded from
+the LLVM input by the `SelectionDAGBuilder` class. The intent of this pass
is to expose as much low-level, target-specific details to the SelectionDAG as
-possible. This pass is mostly hard-coded (e.g., an LLVM ``add`` turns into an
-``SDNode add`` while a ``getelementptr`` is expanded into the obvious
+possible. This pass is mostly hard-coded (e.g., an LLVM `add` turns into an
+`SDNode add` while a `getelementptr` is expanded into the obvious
arithmetic). This pass requires target-specific hooks to lower calls, returns,
-varargs, etc. For these features, the :raw-html:`<tt>` `TargetLowering`_
-:raw-html:`</tt>` interface is used.
+varargs, etc. For these features, the {ref}`TargetLowering <TargetLowering>`
+ interface is used.
-.. _legalize types:
-.. _Legalize SelectionDAG Types:
-.. _Legalize SelectionDAG Ops:
+(legalize types)=
+(Legalize SelectionDAG Types)=
+(Legalize SelectionDAG Ops)=
-SelectionDAG LegalizeTypes Phase
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG LegalizeTypes Phase
The Legalize phase is in charge of converting a DAG to only use the types that
are natively supported by the target.
@@ -931,14 +885,13 @@ all the way down to single-element parts with no supported vector type being
found, the elements are converted to scalars ("scalarizing").
A target implementation tells the legalizer which types are supported (and which
-register class to use for them) by calling the ``addRegisterClass`` method in
-its ``TargetLowering`` constructor.
+register class to use for them) by calling the `addRegisterClass` method in
+its `TargetLowering` constructor.
-.. _legalize operations:
-.. _Legalizer:
+(legalize operations)=
+(Legalizer)=
-SelectionDAG Legalize Phase
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG Legalize Phase
The Legalize phase is in charge of converting a DAG to only use the operations
that are natively supported by the target.
@@ -953,7 +906,7 @@ implement the legalization ("custom").
A target implementation tells the legalizer which operations are not supported
(and which of the above three actions to take) by calling the
-``setOperationAction`` method in its ``TargetLowering`` constructor.
+`setOperationAction` method in its `TargetLowering` constructor.
If a target has legal vector types, it is expected to produce efficient machine
code for common forms of the shufflevector IR instruction using those types.
@@ -964,34 +917,33 @@ handled include:
* Vector select --- Each element of the vector is chosen from either of the
corresponding elements of the 2 input vectors. This operation may also be
known as a "blend" or "bitwise select" in target assembly. This type of shuffle
- maps directly to the ``shuffle_vector`` SelectionDAG node.
+ maps directly to the `shuffle_vector` SelectionDAG node.
* Insert subvector --- A vector is placed into a longer vector type starting
- at index 0. This type of shuffle maps directly to the ``insert_subvector``
- SelectionDAG node with the ``index`` operand set to 0.
+ at index 0. This type of shuffle maps directly to the `insert_subvector`
+ SelectionDAG node with the `index` operand set to 0.
* Extract subvector --- A vector is pulled from a longer vector type starting
- at index 0. This type of shuffle maps directly to the ``extract_subvector``
- SelectionDAG node with the ``index`` operand set to 0.
+ at index 0. This type of shuffle maps directly to the `extract_subvector`
+ SelectionDAG node with the `index` operand set to 0.
* Splat --- All elements of the vector have identical scalar elements. This
operation may also be known as a "broadcast" or "duplicate" in target assembly.
The shufflevector IR instruction may change the vector length, so this operation
- may map to multiple SelectionDAG nodes including ``shuffle_vector``,
- ``concat_vectors``, ``insert_subvector``, and ``extract_subvector``.
+ may map to multiple SelectionDAG nodes including `shuffle_vector`,
+ `concat_vectors`, `insert_subvector`, and `extract_subvector`.
Prior to the existence of the Legalize passes, we required that every target
-`selector`_ supported and handled every operator and type even if they are not
+{ref}`selector <selector>` supported and handled every operator and type even if they are not
natively supported. The introduction of the Legalize phases allows all of the
canonicalization patterns to be shared across targets, and makes it very easy to
optimize the canonicalized code because it is still in the form of a DAG.
-.. _optimizations:
-.. _Optimize SelectionDAG:
-.. _selector:
+(optimizations)=
+(Optimize SelectionDAG)=
+(selector)=
-SelectionDAG Optimization Phase: the DAG Combiner
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG Optimization Phase: the DAG Combiner
The SelectionDAG optimization phase is run multiple times for code generation,
immediately after the DAG is built and once after each legalization. The first
@@ -1006,71 +958,68 @@ zero extension instructions. We currently use ad-hoc techniques, but could move
to more rigorous techniques in the future. Here are some good papers on the
subject:
-"`Widening integer arithmetic <http://www.eecs.harvard.edu/~nr/pubs/widen-abstract.html>`_" :raw-html:`<br>`
-Kevin Redwine and Norman Ramsey :raw-html:`<br>`
+"[Widening integer arithmetic](http://www.eecs.harvard.edu/~nr/pubs/widen-abstract.html)" \
+Kevin Redwine and Norman Ramsey \
International Conference on Compiler Construction (CC) 2004
-"`Effective sign extension elimination <http://portal.acm.org/citation.cfm?doid=512529.512552>`_" :raw-html:`<br>`
-Motohiro Kawahito, Hideaki Komatsu, and Toshio Nakatani :raw-html:`<br>`
+"[Effective sign extension elimination](http://portal.acm.org/citation.cfm?doid=512529.512552)" \
+Motohiro Kawahito, Hideaki Komatsu, and Toshio Nakatani \
Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language Design
and Implementation.
-.. _Select instructions from DAG:
+(Select instructions from DAG)=
-SelectionDAG Select Phase
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG Select Phase
The Select phase is the bulk of the target-specific code for instruction
selection. This phase takes a legal SelectionDAG as input, pattern matches the
instructions supported by the target to this DAG, and produces a new DAG of
target code. For example, consider the following LLVM fragment:
-.. code-block:: llvm
-
- %t1 = fadd float %W, %X
- %t2 = fmul float %t1, %Y
- %t3 = fadd float %t2, %Z
-
+```llvm
+%t1 = fadd float %W, %X
+%t2 = fmul float %t1, %Y
+%t3 = fadd float %t2, %Z
+```
This LLVM code corresponds to a SelectionDAG that looks basically like this:
-.. code-block:: text
-
- (fadd:f32 (fmul:f32 (fadd:f32 W, X), Y), Z)
-
+```text
+(fadd:f32 (fmul:f32 (fadd:f32 W, X), Y), Z)
+```
If a target supports floating point multiply-and-add (FMA) operations, one of
the adds can be merged with the multiply. On the PowerPC, for example, the
output of the instruction selector might look like this DAG:
-::
+```
+(FMADDS (FADDS W, X), Y, Z)
+```
- (FMADDS (FADDS W, X), Y, Z)
-
-The ``FMADDS`` instruction is a ternary instruction that multiplies its first
+The `FMADDS` instruction is a ternary instruction that multiplies its first
two operands and adds the third (as single-precision floating-point numbers).
-The ``FADDS`` instruction is a simple binary single-precision add instruction.
+The `FADDS` instruction is a simple binary single-precision add instruction.
To perform this pattern match, the PowerPC backend includes the following
instruction definitions:
-.. code-block:: text
- :emphasize-lines: 4-5,9
-
- def FMADDS : AForm_1<59, 29,
- (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
- "fmadds $FRT, $FRA, $FRC, $FRB",
- [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC),
- F4RC:$FRB))]>;
- def FADDS : AForm_2<59, 21,
- (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
- "fadds $FRT, $FRA, $FRB",
- [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>;
-
+```{code-block} text
+:emphasize-lines: 4-5,9
+
+def FMADDS : AForm_1<59, 29,
+ (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB),
+ "fmadds $FRT, $FRA, $FRC, $FRB",
+ [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC),
+ F4RC:$FRB))]>;
+def FADDS : AForm_2<59, 21,
+ (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB),
+ "fadds $FRT, $FRA, $FRB",
+ [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>;
+```
The highlighted portion of the instruction definitions indicates the pattern
-used to match the instructions. The DAG operators (like ``fmul``/``fadd``)
-are defined in the ``include/llvm/Target/TargetSelectionDAG.td`` file.
-"``F4RC``" is the register class of the input and result values.
+used to match the instructions. The DAG operators (like `fmul`/`fadd`)
+are defined in the `include/llvm/Target/TargetSelectionDAG.td` file.
+"`F4RC`" is the register class of the input and result values.
The TableGen DAG instruction selector generator reads the instruction patterns
-in the ``.td`` file and automatically builds parts of the pattern matching code
+in the `.td` file and automatically builds parts of the pattern matching code
for your target. It has the following strengths:
* At compiler-compile time, it analyzes your instruction patterns and tells you
@@ -1078,64 +1027,65 @@ for your target. It has the following strengths:
* It can handle arbitrary constraints on operands for the pattern match. In
particular, it is straightforward to say things like "match any immediate
- that is a 13-bit sign-extended value". For examples, see the ``immSExt16``
- and related ``tblgen`` classes in the PowerPC backend.
+ that is a 13-bit sign-extended value". For examples, see the `immSExt16`
+ and related `tblgen` classes in the PowerPC backend.
* It knows several important identities for the patterns defined. For example,
- it knows that addition is commutative, so it allows the ``FMADDS`` pattern
- above to match "``(fadd X, (fmul Y, Z))``" as well as "``(fadd (fmul X, Y),
- Z)``", without the target author having to specially handle this case.
+ it knows that addition is commutative, so it allows the `FMADDS` pattern
+ above to match "`(fadd X, (fmul Y, Z))`" as well as
+ "`(fadd (fmul X, Y), Z)`", without the target author having to specially
+ handle this case.
* It has a full-featured type-inferencing system. In particular, you should
rarely have to explicitly tell the system what type parts of your patterns
- are. In the ``FMADDS`` case above, we didn't have to tell ``tblgen`` that all
+ are. In the `FMADDS` case above, we didn't have to tell `tblgen` that all
of the nodes in the pattern are of type 'f32'. It was able to infer and
- propagate this knowledge from the fact that ``F4RC`` has type 'f32'.
+ propagate this knowledge from the fact that `F4RC` has type 'f32'.
* Targets can define their own (and rely on built-in) "pattern fragments".
Pattern fragments are chunks of reusable patterns that get inlined into your
- patterns during compiler-compile time. For example, the integer "``(not
- x)``" operation is actually defined as a pattern fragment that expands as
- "``(xor x, -1)``", since the SelectionDAG does not have a native '``not``'
+ patterns during compiler-compile time. For example, the integer "`(not x)`"
+ operation is actually defined as a pattern fragment that expands as
+ "`(xor x, -1)`", since the SelectionDAG does not have a native '`not`'
operation. Targets can define their own short-hand fragments as they see fit.
- See the definition of '``not``' and '``ineg``' for examples.
+ See the definition of '`not`' and '`ineg`' for examples.
* In addition to instructions, targets can specify arbitrary patterns that map
to one or more instructions using the 'Pat' class. For example, the PowerPC
has no way to load an arbitrary integer immediate into a register in one
instruction. To tell tblgen how to do this, it defines:
- ::
-
- // Arbitrary immediate support. Implement in terms of LIS/ORI.
- def : Pat<(i32 imm:$imm),
- (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;
+ ```
+ // Arbitrary immediate support. Implement in terms of LIS/ORI.
+ def : Pat<(i32 imm:$imm),
+ (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;
+ ```
If none of the single-instruction patterns for loading an immediate into a
register match, this will be used. This rule says "match an arbitrary i32
- immediate, turning it into an ``ORI`` ('or a 16-bit immediate') and an ``LIS``
+ immediate, turning it into an `ORI` ('or a 16-bit immediate') and an `LIS`
('load 16-bit immediate, where the immediate is shifted to the left 16 bits')
- instruction". To make this work, the ``LO16``/``HI16`` node transformations
+ instruction". To make this work, the `LO16`/`HI16` node transformations
are used to manipulate the input immediate (in this case, take the high or low
16-bits of the immediate).
* When using the 'Pat' class to map a pattern to an instruction that has one
- or more complex operands (like e.g., `X86 addressing mode`_), the pattern may
- either specify the operand as a whole using a ``ComplexPattern``, or else it
+ or more complex operands (like e.g., {ref}`X86 addressing mode <X86 addressing mode>`), the pattern may
+ either specify the operand as a whole using a `ComplexPattern`, or else it
may specify the components of the complex operand separately. The latter is
done e.g., for pre-increment instructions by the PowerPC back end:
- ::
-
- def STWU : DForm_1<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, memri:$dst),
- "stwu $rS, $dst", LdStStoreUpd, []>,
- RegConstraint<"$dst.reg = $ea_res">;
+ ```
+ def STWU : DForm_1<37, (outs ptr_rc:$ea_res), (ins GPRC:$rS, memri:$dst),
+ "stwu $rS, $dst", LdStStoreUpd, []>,
+ RegConstraint<"$dst.reg = $ea_res">;
- def : Pat<(pre_store GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff),
- (STWU GPRC:$rS, iaddroff:$ptroff, ptr_rc:$ptrreg)>;
+ def : Pat<(pre_store GPRC:$rS, ptr_rc:$ptrreg, iaddroff:$ptroff),
+ (STWU GPRC:$rS, iaddroff:$ptroff, ptr_rc:$ptrreg)>;
+ ```
- Here, the pair of ``ptroff`` and ``ptrreg`` operands is matched onto the
- complex operand ``dst`` of class ``memri`` in the ``STWU`` instruction.
+ Here, the pair of `ptroff` and `ptrreg` operands is matched onto the
+ complex operand `dst` of class `memri` in the `STWU` instruction.
* While the system does automate a lot, it still allows you to write custom C++
code to match special cases if there is something that is hard to
@@ -1145,20 +1095,20 @@ While it has many strengths, the system currently has some limitations,
primarily because it is a work in progress and is not yet finished:
* Overall, there is no way to define or match SelectionDAG nodes that define
- multiple values (e.g., ``SMUL_LOHI``, ``LOAD``, ``CALL``, etc). This is the
+ multiple values (e.g., `SMUL_LOHI`, `LOAD`, `CALL`, etc). This is the
biggest reason that you currently still *have to* write custom C++ code
for your instruction selector.
* There is no great way to support matching complex addressing modes yet. In
the future, we will extend pattern fragments to allow them to define multiple
- values (e.g., the four operands of the `X86 addressing mode`_, which are
+ values (e.g., the four operands of the {ref}`X86 addressing mode <X86 addressing mode>`, which are
currently matched with custom C++ code). In addition, we'll extend fragments
so that a fragment can match multiple different patterns.
-* We don't automatically infer flags like ``isStore``/``isLoad`` yet.
+* We don't automatically infer flags like `isStore`/`isLoad` yet.
* We don't automatically generate the set of supported registers and operations
- for the `Legalizer`_ yet.
+ for the {ref}`Legalizer <Legalizer>` yet.
* We don't have a way of tying in custom legalized nodes yet.
@@ -1167,47 +1117,42 @@ useful for most of the binary and logical operations in typical instruction
sets. If you run into any problems or can't figure out how to do something,
please let Chris know!
-.. _Scheduling and Formation:
-.. _SelectionDAG Scheduling and Formation:
+(Scheduling and Formation)=
+(SelectionDAG Scheduling and Formation)=
-SelectionDAG Scheduling and Formation Phase
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### SelectionDAG Scheduling and Formation Phase
The scheduling phase takes the DAG of target instructions from the selection
phase and assigns an order. The scheduler can pick an order depending on
various constraints of the machines (i.e., order for minimal register pressure or
try to cover instruction latencies). Once an order is established, the DAG is
-converted to a list of :raw-html:`<tt>` `MachineInstr`_\s :raw-html:`</tt>` and
+converted to a list of {ref}`MachineInstr <MachineInstr>`s and
the SelectionDAG is destroyed.
Note that this phase is logically separate from the instruction selection phase,
but is tied to it closely in the code because it operates on SelectionDAGs.
-Future directions for the SelectionDAG
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Future directions for the SelectionDAG
-#. Optional function-at-a-time selection.
+1. Optional function-at-a-time selection.
-#. Auto-generate entire selector from ``.td`` file.
+1. Auto-generate entire selector from `.td` file.
-.. _SSA-based Machine Code Optimizations:
+(SSA-based Machine Code Optimizations)=
-SSA-based Machine Code Optimizations
-------------------------------------
+### SSA-based Machine Code Optimizations
To Be Written
-Live Intervals
---------------
+### Live Intervals
Live Intervals are the ranges (intervals) where a variable is *live*. They are
-used by some `register allocator`_ passes to determine if two or more virtual
+used by some {ref}`register allocator <register allocator>` passes to determine if two or more virtual
registers which require the same physical register are live at the same point in
the program (i.e., they conflict). When this situation occurs, one virtual
register must be *spilled*.
-Live Variable Analysis
-^^^^^^^^^^^^^^^^^^^^^^
+#### Live Variable Analysis
The first step in determining the live intervals of variables is to calculate
the set of registers that are immediately dead after the instruction (i.e., the
@@ -1228,67 +1173,63 @@ Physical registers may be live in to or out of a function. Live in values are
typically arguments in registers. Live out values are typically return values in
registers. Live in values are marked as such, and are given a dummy "defining"
instruction during live intervals analysis. If the last basic block of a
-function is a ``return``, then it's marked as using all live out values in the
+function is a `return`, then it's marked as using all live out values in the
function.
-``PHI`` nodes need to be handled specially, because the calculation of the live
+`PHI` nodes need to be handled specially, because the calculation of the live
variable information from a depth first traversal of the CFG of the function
-won't guarantee that a virtual register used by the ``PHI`` node is defined
-before it's used. When a ``PHI`` node is encountered, only the definition is
+won't guarantee that a virtual register used by the `PHI` node is defined
+before it's used. When a `PHI` node is encountered, only the definition is
handled, because the uses will be handled in other basic blocks.
-For each ``PHI`` node of the current basic block, we simulate an assignment at
+For each `PHI` node of the current basic block, we simulate an assignment at
the end of the current basic block and traverse the successor basic blocks. If a
-successor basic block has a ``PHI`` node and one of the ``PHI`` node's operands
+successor basic block has a `PHI` node and one of the `PHI` node's operands
is coming from the current basic block, then the variable is marked as *alive*
within the current basic block and all of its predecessor basic blocks, until
the basic block with the defining instruction is encountered.
-Live Intervals Analysis
-^^^^^^^^^^^^^^^^^^^^^^^
+#### Live Intervals Analysis
We now have the information available to perform the live intervals analysis and
build the live intervals themselves. We start off by numbering the basic blocks
and machine instructions. We then handle the "live-in" values. These are in
physical registers, so the physical register is assumed to be killed by the end
of the basic block. Live intervals for virtual registers are computed for some
-ordering of the machine instructions ``[1, N]``. A live interval is an interval
-``[i, j)``, where ``1 >= i >= j > N``, for which a variable is live.
-
-.. note::
- More to come...
+ordering of the machine instructions `[1, N]`. A live interval is an interval
+`[i, j)`, where `1 >= i >= j > N`, for which a variable is live.
-.. _Register Allocation:
-.. _register allocator:
+```{note}
+More to come...
+```
+(Register Allocation)=
+(register allocator)=
-Register Allocation
--------------------
+### Register Allocation
The *Register Allocation problem* consists in mapping a program
-:raw-html:`<b><tt>` P\ :sub:`v`\ :raw-html:`</tt></b>`, that can use an unbounded
-number of virtual registers, to a program :raw-html:`<b><tt>` P\ :sub:`p`\
-:raw-html:`</tt></b>` that contains a finite (possibly small) number of physical
+P{sub}`v`, that can use an unbounded
+number of virtual registers, to a program P{sub}`p` that contains a finite (possibly small) number of physical
registers. Each target architecture has a different number of physical
registers. If the number of physical registers is not enough to accommodate all
the virtual registers, some of them will have to be mapped into memory. These
virtuals are called *spilled virtuals*.
-How registers are represented in LLVM
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### How registers are represented in LLVM
In LLVM, physical registers are denoted by integer numbers that normally range
from 1 to 1023. To see how this numbering is defined for a particular
-architecture, you can read the ``GenRegisterNames.inc`` file for that
+architecture, you can read the `GenRegisterNames.inc` file for that
architecture. For instance, by inspecting
-``lib/Target/X86/X86GenRegisterInfo.inc`` we see that the 32-bit register
-``EAX`` is denoted by 43, and the MMX register ``MM0`` is mapped to 65.
+`lib/Target/X86/X86GenRegisterInfo.inc` we see that the 32-bit register
+`EAX` is denoted by 43, and the MMX register `MM0` is mapped to 65.
Some architectures contain registers that share the same physical location. A
notable example is the X86 platform. For instance, in the X86 architecture, the
-registers ``EAX``, ``AX`` and ``AL`` share the first eight bits. These physical
+registers `EAX`, `AX` and `AL` share the first eight bits. These physical
registers are marked as *aliased* in LLVM. Given a particular architecture, you
-can check which registers are aliased by inspecting its ``RegisterInfo.td``
-file. Moreover, the class ``MCRegAliasIterator`` enumerates all the physical
+can check which registers are aliased by inspecting its `RegisterInfo.td`
+file. Moreover, the class `MCRegAliasIterator` enumerates all the physical
registers aliased to a register.
Physical registers, in LLVM, are grouped in *Register Classes*. Elements in the
@@ -1296,56 +1237,54 @@ same register class are functionally equivalent, and can be interchangeably
used. Each virtual register can only be mapped to physical registers of a
particular class. For instance, in the X86 architecture, some virtuals can only
be allocated to 8-bit registers. A register class is described by
-``TargetRegisterClass`` objects. To discover if a virtual register is
+`TargetRegisterClass` objects. To discover if a virtual register is
compatible with a given physical, this code can be used:
-.. code-block:: c++
-
- bool RegMapping_Fer::compatible_class(MachineFunction &mf,
- unsigned v_reg,
- unsigned p_reg) {
- assert(TargetRegisterInfo::isPhysicalRegister(p_reg) &&
- "Target register must be physical");
- const TargetRegisterClass *trc = mf.getRegInfo().getRegClass(v_reg);
- return trc->contains(p_reg);
- }
-
+```c++
+bool RegMapping_Fer::compatible_class(MachineFunction &mf,
+ unsigned v_reg,
+ unsigned p_reg) {
+ assert(TargetRegisterInfo::isPhysicalRegister(p_reg) &&
+ "Target register must be physical");
+ const TargetRegisterClass *trc = mf.getRegInfo().getRegClass(v_reg);
+ return trc->contains(p_reg);
+}
+```
Sometimes, mostly for debugging purposes, it is useful to change the number of
physical registers available in the target architecture. This must be done
-statically, inside the ``TargetRegisterInfo.td`` file. Just ``grep`` for
-``RegisterClass``, the last parameter of which is a list of registers. Just
+statically, inside the `TargetRegisterInfo.td` file. Just `grep` for
+`RegisterClass`, the last parameter of which is a list of registers. Just
commenting some out is one simple way to avoid them being used. A more polite
way is to explicitly exclude some registers from the *allocation order*. See the
-definition of the ``GR8`` register class in
-``lib/Target/X86/X86RegisterInfo.td`` for an example of this.
+definition of the `GR8` register class in
+`lib/Target/X86/X86RegisterInfo.td` for an example of this.
Virtual registers are also denoted by integer numbers. Contrary to physical
registers, different virtual registers never share the same number. Whereas
-physical registers are statically defined in a ``TargetRegisterInfo.td`` file
+physical registers are statically defined in a `TargetRegisterInfo.td` file
and cannot be created by the application developer, that is not the case with
virtual registers. In order to create new virtual registers, use the method
-``MachineRegisterInfo::createVirtualRegister()``. This method will return a new
-virtual register. Use an ``IndexedMap<Foo, VirtReg2IndexFunctor>`` to hold
+`MachineRegisterInfo::createVirtualRegister()`. This method will return a new
+virtual register. Use an `IndexedMap<Foo, VirtReg2IndexFunctor>` to hold
information per virtual register. If you need to enumerate all virtual
-registers, use the function ``TargetRegisterInfo::index2VirtReg()`` to find the
+registers, use the function `TargetRegisterInfo::index2VirtReg()` to find the
virtual register numbers:
-.. code-block:: c++
-
- for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
- unsigned VirtReg = TargetRegisterInfo::index2VirtReg(i);
- stuff(VirtReg);
- }
-
+```c++
+ for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
+ unsigned VirtReg = TargetRegisterInfo::index2VirtReg(i);
+ stuff(VirtReg);
+ }
+```
Before register allocation, the operands of an instruction are mostly virtual
registers, although physical registers may also be used. In order to check if a
given machine operand is a register, use the boolean function
-``MachineOperand::isRegister()``. To obtain the integer code of a register, use
-``MachineOperand::getReg()``. An instruction may define or use a register. For
-instance, ``ADD reg:1026 := reg:1025 reg:1024`` defines the registers 1024, and
+`MachineOperand::isRegister()`. To obtain the integer code of a register, use
+`MachineOperand::getReg()`. An instruction may define or use a register. For
+instance, `ADD reg:1026 := reg:1025 reg:1024` defines the registers 1024, and
uses registers 1025 and 1026. Given a register operand, the method
-``MachineOperand::isUse()`` informs if that register is being used by the
-instruction. The method ``MachineOperand::isDef()`` informs if that registers is
+`MachineOperand::isUse()` informs if that register is being used by the
+instruction. The method `MachineOperand::isDef()` informs if that registers is
being defined.
We will call physical registers present in the LLVM bitcode before register
@@ -1354,27 +1293,26 @@ different situations, for instance, to pass parameters of functions calls, and
to store results of particular instructions. There are two types of pre-colored
registers: the ones *implicitly* defined, and those *explicitly*
defined. Explicitly defined registers are normal operands, and can be accessed
-with ``MachineInstr::getOperand(int)::getReg()``. In order to check which
+with `MachineInstr::getOperand(int)::getReg()`. In order to check which
registers are implicitly defined by an instruction, use the
-``TargetInstrInfo::get(opcode)::ImplicitDefs``, where ``opcode`` is the opcode
+`TargetInstrInfo::get(opcode)::ImplicitDefs`, where `opcode` is the opcode
of the target instruction. One important difference between explicit and
implicit physical registers is that the latter are defined statically for each
instruction, whereas the former may vary depending on the program being
compiled. For example, an instruction that represents a function call will
always implicitly define or use the same set of physical registers. To read the
registers implicitly used by an instruction, use
-``TargetInstrInfo::get(opcode)::ImplicitUses``. Pre-colored registers impose
+`TargetInstrInfo::get(opcode)::ImplicitUses`. Pre-colored registers impose
constraints on any register allocation algorithm. The register allocator must
make sure that none of them are overwritten by the values of virtual registers
while still alive.
-Mapping virtual registers to physical registers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Mapping virtual registers to physical registers
There are two ways to map virtual registers to physical registers (or to memory
slots). The first way, that we will call *direct mapping*, is based on the use
-of methods of the classes ``TargetRegisterInfo``, and ``MachineOperand``. The
-second way, that we will call *indirect mapping*, relies on the ``VirtRegMap``
+of methods of the classes `TargetRegisterInfo`, and `MachineOperand`. The
+second way, that we will call *indirect mapping*, relies on the `VirtRegMap`
class in order to insert loads and stores sending and getting values to and from
memory.
@@ -1383,18 +1321,18 @@ allocator; however, it is more error prone, and demands more implementation
work. Basically, the programmer will have to specify where load and store
instructions should be inserted in the target function being compiled in order
to get and store values in memory. To assign a physical register to a virtual
-register present in a given operand, use ``MachineOperand::setReg(p_reg)``. To
-insert a store instruction, use ``TargetInstrInfo::storeRegToStackSlot(...)``,
-and to insert a load instruction, use ``TargetInstrInfo::loadRegFromStackSlot``.
+register present in a given operand, use `MachineOperand::setReg(p_reg)`. To
+insert a store instruction, use `TargetInstrInfo::storeRegToStackSlot(...)`,
+and to insert a load instruction, use `TargetInstrInfo::loadRegFromStackSlot`.
The indirect mapping shields the application developer from the complexities of
inserting load and store instructions. In order to map a virtual register to a
-physical one, use ``VirtRegMap::assignVirt2Phys(vreg, preg)``. In order to map
+physical one, use `VirtRegMap::assignVirt2Phys(vreg, preg)`. In order to map
a certain virtual register to memory, use
-``VirtRegMap::assignVirt2StackSlot(vreg)``. This method will return the stack
-slot where ``vreg``'s value will be located. If it is necessary to map another
+`VirtRegMap::assignVirt2StackSlot(vreg)`. This method will return the stack
+slot where `vreg`'s value will be located. If it is necessary to map another
virtual register to the same stack slot, use
-``VirtRegMap::assignVirt2StackSlot(vreg, stack_location)``. One important point
+`VirtRegMap::assignVirt2StackSlot(vreg, stack_location)`. One important point
to consider when using the indirect mapping, is that even if a virtual register
is mapped to memory, it still needs to be mapped to a physical register. This
physical register is the location where the virtual register is supposed to be
@@ -1406,39 +1344,37 @@ object to place load and store instructions in the code. Every virtual that has
been mapped to a stack slot will be stored to memory after being defined and will
be loaded before being used. The implementation of the spiller tries to recycle
load/store instructions, avoiding unnecessary instructions. For an example of
-how to invoke the spiller, see ``RegAllocLinearScan::runOnMachineFunction`` in
-``lib/CodeGen/RegAllocLinearScan.cpp``.
+how to invoke the spiller, see `RegAllocLinearScan::runOnMachineFunction` in
+`lib/CodeGen/RegAllocLinearScan.cpp`.
-Handling two address instructions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Handling two address instructions
With very rare exceptions (e.g., function calls), the LLVM machine code
instructions are three address instructions. That is, each instruction is
expected to define at most one register, and to use at most two registers.
However, some architectures use two address instructions. In this case, the
defined register is also one of the used registers. For instance, an instruction
-such as ``ADD %EAX, %EBX``, in X86 is actually equivalent to ``%EAX = %EAX +
-%EBX``.
+such as `ADD %EAX, %EBX`, in X86 is actually equivalent to
+`%EAX = %EAX + %EBX`.
In order to produce correct code, LLVM must convert three address instructions
that represent two address instructions into true two address instructions. LLVM
-provides the pass ``TwoAddressInstructionPass`` for this specific purpose. It
+provides the pass `TwoAddressInstructionPass` for this specific purpose. It
must be run before register allocation takes place. After its execution, the
resulting code may no longer be in SSA form. This happens, for instance, in
-situations where an instruction such as ``%a = ADD %b %c`` is converted to two
+situations where an instruction such as `%a = ADD %b %c` is converted to two
instructions such as:
-::
+```
+%a = MOVE %b
+%a = ADD %a %c
+```
- %a = MOVE %b
- %a = ADD %a %c
-
-Notice that, internally, the second instruction is represented as ``ADD
-%a[def/use] %c``. I.e., the register operand ``%a`` is both used and defined by
+Notice that, internally, the second instruction is represented as
+`ADD %a[def/use] %c`. I.e., the register operand `%a` is both used and defined by
the instruction.
-The SSA deconstruction phase
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The SSA deconstruction phase
An important transformation that happens during register allocation is called
the *SSA Deconstruction Phase*. The SSA form simplifies many analyses that are
@@ -1451,36 +1387,34 @@ There are many ways in which PHI instructions can safely be removed from the
target code. The most traditional PHI deconstruction algorithm replaces PHI
instructions with copy instructions. That is the strategy adopted by LLVM. The
SSA deconstruction algorithm is implemented in
-``lib/CodeGen/PHIElimination.cpp``. In order to invoke this pass, the identifier
-``PHIEliminationID`` must be marked as required in the code of the register
+`lib/CodeGen/PHIElimination.cpp`. In order to invoke this pass, the identifier
+`PHIEliminationID` must be marked as required in the code of the register
allocator.
-Instruction folding
-^^^^^^^^^^^^^^^^^^^
+#### Instruction folding
*Instruction folding* is an optimization performed during register allocation
that removes unnecessary copy instructions. For instance, a sequence of
instructions such as:
-::
-
- %EBX = LOAD %mem_address
- %EAX = COPY %EBX
+```
+%EBX = LOAD %mem_address
+%EAX = COPY %EBX
+```
can be safely substituted by the single instruction:
-::
-
- %EAX = LOAD %mem_address
+```
+%EAX = LOAD %mem_address
+```
Instructions can be folded with the
-``TargetRegisterInfo::foldMemoryOperand(...)`` method. Care must be taken when
+`TargetRegisterInfo::foldMemoryOperand(...)` method. Care must be taken when
folding instructions; a folded instruction can be quite different from the
-original instruction. See ``LiveIntervals::addIntervalsForSpills`` in
-``lib/CodeGen/LiveIntervalAnalysis.cpp`` for an example of its use.
+original instruction. See `LiveIntervals::addIntervalsForSpills` in
+`lib/CodeGen/LiveIntervalAnalysis.cpp` for an example of its use.
-Built in register allocators
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Built in register allocators
The LLVM infrastructure provides the application developer with three different
register allocators:
@@ -1505,26 +1439,22 @@ register allocators:
the register allocation problem under consideration, solving this using a PBQP
solver, and mapping the solution back to a register assignment.
-The type of register allocator used in ``llc`` can be chosen with the command
-line option ``-regalloc=...``:
-
-.. code-block:: bash
-
- $ llc -regalloc=linearscan file.bc -o ln.s
- $ llc -regalloc=fast file.bc -o fa.s
- $ llc -regalloc=pbqp file.bc -o pbqp.s
-
-.. _Prolog/Epilog Code Insertion:
+The type of register allocator used in `llc` can be chosen with the command
+line option `-regalloc=...`:
-Prolog/Epilog Code Insertion
-----------------------------
+```bash
+$ llc -regalloc=linearscan file.bc -o ln.s
+$ llc -regalloc=fast file.bc -o fa.s
+$ llc -regalloc=pbqp file.bc -o pbqp.s
+```
+(Prolog/Epilog Code Insertion)=
-.. note::
+### Prolog/Epilog Code Insertion
- To Be Written
-
-Compact Unwind
---------------
+```{note}
+To Be Written
+```
+### Compact Unwind
Throwing an exception requires *unwinding* out of a function. The information on
how to unwind a given function is traditionally expressed in DWARF unwind
@@ -1537,76 +1467,74 @@ unwind* and requires just 4-bytes per function.
The compact unwind encoding is a 32-bit value, which is encoded in an
architecture-specific way. It specifies which registers to restore and from
where, and how to unwind out of the function. When the linker creates a final
-linked image, it will create a ``__TEXT,__unwind_info`` section. This section is
+linked image, it will create a `__TEXT,__unwind_info` section. This section is
a small and fast way for the runtime to access unwind info for any given
function. If we emit compact unwind info for the function, that compact unwind
-info will be encoded in the ``__TEXT,__unwind_info`` section. If we emit DWARF
-unwind info, the ``__TEXT,__unwind_info`` section will contain the offset of the
-FDE in the ``__TEXT,__eh_frame`` section in the final linked image.
+info will be encoded in the `__TEXT,__unwind_info` section. If we emit DWARF
+unwind info, the `__TEXT,__unwind_info` section will contain the offset of the
+FDE in the `__TEXT,__eh_frame` section in the final linked image.
For X86, there are three modes for the compact unwind encoding:
-*Function with a Frame Pointer (``EBP`` or ``RBP``)*
- ``EBP/RBP``-based frame, where ``EBP/RBP`` is pushed onto the stack
- immediately after the return address, then ``ESP/RSP`` is moved to
- ``EBP/RBP``. Thus to unwind, ``ESP/RSP`` is restored with the current
- ``EBP/RBP`` value, then ``EBP/RBP`` is restored by popping the stack, and the
- return is done by popping the stack once more into the PC. All non-volatile
- registers that need to be restored must have been saved in a small range on
- the stack that starts ``EBP-4`` to ``EBP-1020`` (``RBP-8`` to
- ``RBP-1020``). The offset (divided by 4 in 32-bit mode and 8 in 64-bit mode)
- is encoded in bits 16-23 (mask: ``0x00FF0000``). The registers saved are
- encoded in bits 0-14 (mask: ``0x00007FFF``) as five 3-bit entries from the
- following table:
-
- ============== ============= ===============
- Compact Number i386 Register x86-64 Register
- ============== ============= ===============
- 1 ``EBX`` ``RBX``
- 2 ``ECX`` ``R12``
- 3 ``EDX`` ``R13``
- 4 ``EDI`` ``R14``
- 5 ``ESI`` ``R15``
- 6 ``EBP`` ``RBP``
- ============== ============= ===============
-
-*Frameless with a Small Constant Stack Size (``EBP`` or ``RBP`` is not used as a frame pointer)*
- To return, a constant (encoded in the compact unwind encoding) is added to the
- ``ESP/RSP``. Then the return is done by popping the stack into the PC. All
- non-volatile registers that need to be restored must have been saved on the
- stack immediately after the return address. The stack size (divided by 4 in
- 32-bit mode and 8 in 64-bit mode) is encoded in bits 16-23 (mask:
- ``0x00FF0000``). There is a maximum stack size of 1024 bytes in 32-bit mode
- and 2048 in 64-bit mode. The number of registers saved is encoded in bits 9-12
- (mask: ``0x00001C00``). Bits 0-9 (mask: ``0x000003FF``) contain which
- registers were saved and their order. (See the
- ``encodeCompactUnwindRegistersWithoutFrame()`` function in
- ``lib/Target/X86FrameLowering.cpp`` for the encoding algorithm.)
-
-*Frameless with a Large Constant Stack Size (``EBP`` or ``RBP`` is not used as a frame pointer)*
- This case is like the "Frameless with a Small Constant Stack Size" case, but
- the stack size is too large to encode in the compact unwind encoding. Instead
- it requires that the function contains "``subl $nnnnnn, %esp``" in its
- prolog. The compact encoding contains the offset to the ``$nnnnnn`` value in
- the function in bits 9-12 (mask: ``0x00001C00``).
-
-.. _Late Machine Code Optimizations:
-
-Late Machine Code Optimizations
--------------------------------
-
-.. note::
-
- To Be Written
-
-.. _Code Emission:
-
-Code Emission
--------------
+*Function with a Frame Pointer (`EBP` or `RBP`)*
+
+`EBP/RBP`-based frame, where `EBP/RBP` is pushed onto the stack
+immediately after the return address, then `ESP/RSP` is moved to
+`EBP/RBP`. Thus to unwind, `ESP/RSP` is restored with the current
+`EBP/RBP` value, then `EBP/RBP` is restored by popping the stack, and the
+return is done by popping the stack once more into the PC. All non-volatile
+registers that need to be restored must have been saved in a small range on
+the stack that starts `EBP-4` to `EBP-1020` (`RBP-8` to
+`RBP-1020`). The offset (divided by 4 in 32-bit mode and 8 in 64-bit mode)
+is encoded in bits 16-23 (mask: `0x00FF0000`). The registers saved are
+encoded in bits 0-14 (mask: `0x00007FFF`) as five 3-bit entries from the
+following table:
+
+| Compact Number | i386 Register | x86-64 Register |
+| --- | --- | --- |
+| 1 | `EBX` | `RBX` |
+| 2 | `ECX` | `R12` |
+| 3 | `EDX` | `R13` |
+| 4 | `EDI` | `R14` |
+| 5 | `ESI` | `R15` |
+| 6 | `EBP` | `RBP` |
+
+*Frameless with a Small Constant Stack Size (`EBP` or `RBP` is not used as a frame pointer)*
+
+To return, a constant (encoded in the compact unwind encoding) is added to the
+`ESP/RSP`. Then the return is done by popping the stack into the PC. All
+non-volatile registers that need to be restored must have been saved on the
+stack immediately after the return address. The stack size (divided by 4 in
+32-bit mode and 8 in 64-bit mode) is encoded in bits 16-23 (mask:
+`0x00FF0000`). There is a maximum stack size of 1024 bytes in 32-bit mode
+and 2048 in 64-bit mode. The number of registers saved is encoded in bits 9-12
+(mask: `0x00001C00`). Bits 0-9 (mask: `0x000003FF`) contain which
+registers were saved and their order. (See the
+`encodeCompactUnwindRegistersWithoutFrame()` function in
+`lib/Target/X86FrameLowering.cpp` for the encoding algorithm.)
+
+*Frameless with a Large Constant Stack Size (`EBP` or `RBP` is not used as a frame pointer)*
+
+This case is like the "Frameless with a Small Constant Stack Size" case, but
+the stack size is too large to encode in the compact unwind encoding. Instead
+it requires that the function contains "`subl $nnnnnn, %esp`" in its
+prolog. The compact encoding contains the offset to the `$nnnnnn` value in
+the function in bits 9-12 (mask: `0x00001C00`).
+
+(Late Machine Code Optimizations)=
+
+### Late Machine Code Optimizations
+
+```{note}
+To Be Written
+```
+(Code Emission)=
+
+### Code Emission
The code emission step of code generation is responsible for lowering from the
-code generator abstractions (like `MachineFunction`_, `MachineInstr`_, etc) down
-to the abstractions used by the MC layer (`MCInst`_, `MCStreamer`_, etc). This
+code generator abstractions (like {ref}`MachineFunction <MachineFunction>`, {ref}`MachineInstr <MachineInstr>`, etc) down
+to the abstractions used by the MC layer ({ref}`MCInst <MCInst>`, {ref}`MCStreamer <MCStreamer>`, etc). This
is done with a combination of several different classes: the (misnamed)
target-independent AsmPrinter class, target-specific subclasses of AsmPrinter
(such as SparcAsmPrinter), and the TargetLoweringObjectFile class.
@@ -1615,7 +1543,7 @@ Since the MC layer works at the level of abstraction of object files, it doesn't
have a notion of functions, global variables etc. Instead, it thinks about
labels, directives, and instructions. A key class used at this time is the
MCStreamer class. This is an abstract API that is implemented in different ways
-(e.g., to output a ``.s`` file, output an ELF ``.o`` file, etc) that is effectively an
+(e.g., to output a `.s` file, output an ELF `.o` file, etc) that is effectively an
"assembler API". MCStreamer has one method per directive, such as EmitLabel,
EmitSymbolAttribute, switchSection, etc, which directly correspond to assembly
level directives.
@@ -1623,7 +1551,7 @@ level directives.
If you are interested in implementing a code generator for a target, there are
three important things that you have to implement for your target:
-#. First, you need a subclass of AsmPrinter for your target. This class
+1. First, you need a subclass of AsmPrinter for your target. This class
implements the general lowering process converting MachineFunction's into MC
label constructs. The AsmPrinter base class provides a number of useful
methods and routines, and also allows you to override the lowering process in
@@ -1631,14 +1559,14 @@ three important things that you have to implement for your target:
implementing an ELF, COFF, or MachO target, because the
TargetLoweringObjectFile class implements much of the common logic.
-#. Second, you need to implement an instruction printer for your target. The
- instruction printer takes an `MCInst`_ and renders it to a raw_ostream as
+1. Second, you need to implement an instruction printer for your target. The
+ instruction printer takes an {ref}`MCInst <MCInst>` and renders it to a raw_ostream as
text. Most of this is automatically generated from the .td file (when you
- specify something like "``add $dst, $src1, $src2``" in the instructions), but
+ specify something like "`add $dst, $src1, $src2`" in the instructions), but
you need to implement routines to print operands.
-#. Third, you need to implement code that lowers a `MachineInstr`_ to an MCInst,
- usually implemented in "<target>MCInstLower.cpp". This lowering process is
+1. Third, you need to implement code that lowers a {ref}`MachineInstr <MachineInstr>` to an MCInst,
+ usually implemented in `<target>MCInstLower.cpp`. This lowering process is
often target specific, and is responsible for turning jump table entries,
constant pool indices, global variable addresses, etc into MCLabels as
appropriate. This translation layer is also responsible for expanding pseudo
@@ -1648,29 +1576,26 @@ three important things that you have to implement for your target:
Finally, at your choosing, you can also implement a subclass of MCCodeEmitter
which lowers MCInst's into machine code bytes and relocations. This is
-important if you want to support direct ``.o`` file emission, or would like to
+important if you want to support direct `.o` file emission, or would like to
implement an assembler for your target.
-Emitting function stack size information
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Emitting function stack size information
A section containing metadata on function stack sizes will be emitted when
-``TargetLoweringObjectFile::StackSizesSection`` is not null, and
-``TargetOptions::EmitStackSizeSection`` is set (-stack-size-section). The
+`TargetLoweringObjectFile::StackSizesSection` is not null, and
+`TargetOptions::EmitStackSizeSection` is set (-stack-size-section). The
section will contain an array of pairs of function symbol values (pointer size)
and stack sizes (unsigned LEB128). The stack size values only include the space
allocated in the function prologue. Functions with dynamic stack allocations are
not included.
-Emitting function call graph information
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Emitting function call graph information
A section containing metadata on function call graph will be emitted when
-``TargetOptions::EmitCallGraphSection`` is set (--call-graph-section). Layout of
-this section is documented in detail at :doc:`CallGraphSection`.
+`TargetOptions::EmitCallGraphSection` is set (--call-graph-section). Layout of
+this section is documented in detail at {doc}`CallGraphSection`.
-VLIW Packetizer
----------------
+### VLIW Packetizer
In a Very Long Instruction Word (VLIW) architecture, the compiler is responsible
for mapping instructions to functional-units available on the architecture. To
@@ -1678,8 +1603,7 @@ that end, the compiler creates groups of instructions called *packets* or
*bundles*. The VLIW packetizer in LLVM is a target-independent mechanism to
enable the packetization of machine instructions.
-Mapping from instructions to functional units
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Mapping from instructions to functional units
Instructions in a VLIW target can typically be mapped to multiple functional
units. During the process of packetizing, the compiler must be able to reason
@@ -1691,8 +1615,7 @@ at compiler build time. These tables can then be queried by the provided
machine-independent API to determine if an instruction can be accommodated in a
packet.
-How the packetization tables are generated and used
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### How the packetization tables are generated and used
The packetizer reads instruction classes from a target's itineraries and creates
a deterministic finite automaton (DFA) to represent the state of a packet. A DFA
@@ -1705,17 +1628,16 @@ legal mapping of functional units to instructions, then the DFA contains a
corresponding transition. The absence of a transition indicates that a legal
mapping does not exist and that the instruction cannot be added to the packet.
-To generate tables for a VLIW target, add *Target*\ GenDFAPacketizer.inc as a
+To generate tables for a VLIW target, add *Target*GenDFAPacketizer.inc as a
target to the Makefile in the target directory. The exported API provides three
-functions: ``DFAPacketizer::clearResources()``,
-``DFAPacketizer::reserveResources(MachineInstr *MI)``, and
-``DFAPacketizer::canReserveResources(MachineInstr *MI)``. These functions allow
+functions: `DFAPacketizer::clearResources()`,
+`DFAPacketizer::reserveResources(MachineInstr *MI)`, and
+`DFAPacketizer::canReserveResources(MachineInstr *MI)`. These functions allow
a target packetizer to add an instruction to an existing packet and to check
whether an instruction can be added to a packet. See
-``llvm/CodeGen/DFAPacketizer.h`` for more information.
+`llvm/CodeGen/DFAPacketizer.h` for more information.
-Implementing a Native Assembler
-===============================
+## Implementing a Native Assembler
Though you're probably reading this because you want to write or maintain a
compiler backend, LLVM also fully supports building a native assembler.
@@ -1724,16 +1646,12 @@ We've tried hard to automate the generation of the assembler from the .td files
part of the manual and repetitive data entry can be factored and shared with the
compiler.
-Instruction Parsing
--------------------
+### Instruction Parsing
-.. note::
-
- To Be Written
-
-
-Instruction Alias Processing
-----------------------------
+```{note}
+To Be Written
+```
+### Instruction Alias Processing
Once the instruction is parsed, it enters the MatchInstructionImpl function.
The MatchInstructionImpl function performs alias processing and then performs actual
@@ -1747,8 +1665,7 @@ complex/powerful). Generally you want to use the first alias mechanism that
meets the needs of your instruction, because it will allow a more concise
description.
-Mnemonic Aliases
-^^^^^^^^^^^^^^^^
+#### Mnemonic Aliases
The first phase of alias processing is simple instruction mnemonic remapping for
classes of instructions which are allowed with two different mnemonics. This
@@ -1757,44 +1674,43 @@ output mnemonic. It isn't possible for this form of alias to look at the
operands at all, so the remapping must apply for all forms of a given mnemonic.
Mnemonic aliases are defined simply, for example X86 has:
-::
-
- def : MnemonicAlias<"cbw", "cbtw">;
- def : MnemonicAlias<"smovq", "movsq">;
- def : MnemonicAlias<"fldcww", "fldcw">;
- def : MnemonicAlias<"fucompi", "fucomip">;
- def : MnemonicAlias<"ud2a", "ud2">;
+```
+def : MnemonicAlias<"cbw", "cbtw">;
+def : MnemonicAlias<"smovq", "movsq">;
+def : MnemonicAlias<"fldcww", "fldcw">;
+def : MnemonicAlias<"fucompi", "fucomip">;
+def : MnemonicAlias<"ud2a", "ud2">;
+```
... and many others. With a MnemonicAlias definition, the mnemonic is remapped
simply and directly. Though MnemonicAlias's can't look at any aspect of the
instruction (such as the operands) they can depend on global modes (the same
ones supported by the matcher), through a Requires clause:
-::
-
- def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
- def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
+```
+def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
+def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
+```
In this example, the mnemonic gets mapped into a different one depending on
the current instruction set.
-Instruction Aliases
-^^^^^^^^^^^^^^^^^^^
+#### Instruction Aliases
The most general phase of alias processing occurs while matching is happening:
it provides new forms for the matcher to match along with a specific instruction
to generate. An instruction alias has two parts: the string to match and the
instruction to generate. For example:
-::
-
- def : InstAlias<"movsx $src, $dst", (MOVSX16rr8W GR16:$dst, GR8 :$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX16rm8W GR16:$dst, i8mem:$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX32rr8 GR32:$dst, GR8 :$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX32rr16 GR32:$dst, GR16 :$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX64rr8 GR64:$dst, GR8 :$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX64rr16 GR64:$dst, GR16 :$src)>;
- def : InstAlias<"movsx $src, $dst", (MOVSX64rr32 GR64:$dst, GR32 :$src)>;
+```
+def : InstAlias<"movsx $src, $dst", (MOVSX16rr8W GR16:$dst, GR8 :$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX16rm8W GR16:$dst, i8mem:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX32rr8 GR32:$dst, GR8 :$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX32rr16 GR32:$dst, GR16 :$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr8 GR64:$dst, GR8 :$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr16 GR64:$dst, GR16 :$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr32 GR64:$dst, GR32 :$src)>;
+```
This shows a powerful example of the instruction aliases, matching the same
mnemonic in multiple different ways depending on what operands are present in
@@ -1802,12 +1718,12 @@ the assembly. The result of instruction aliases can include operands in a
different order than the destination instruction, and can use an input multiple
times, for example:
-::
-
- def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg)>;
- def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;
- def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg)>;
- def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg)>;
+```
+def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg)>;
+def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;
+def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg)>;
+def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg)>;
+```
This example also shows that tied operands are only listed once. In the X86
backend, XOR8rr has two input GR8's and one output GR8 (where an input is tied
@@ -1816,16 +1732,16 @@ for tied operands. The result of an instruction alias can also use immediates
and fixed physical registers which are added as simple immediate operands in the
result, for example:
-::
-
- // Fixed Immediate operand.
- def : InstAlias<"aad", (AAD8i8 10)>;
+```
+// Fixed Immediate operand.
+def : InstAlias<"aad", (AAD8i8 10)>;
- // Fixed register operand.
- def : InstAlias<"fcomi", (COM_FIr ST1)>;
+// Fixed register operand.
+def : InstAlias<"fcomi", (COM_FIr ST1)>;
- // Simple alias.
- def : InstAlias<"fcomi $reg", (COM_FIr RST:$reg)>;
+// Simple alias.
+def : InstAlias<"fcomi $reg", (COM_FIr RST:$reg)>;
+```
Instruction aliases can also have a Requires clause to make them subtarget
specific.
@@ -1835,39 +1751,35 @@ alias rather than what's being aliased. It typically leads to better, more
readable code. If it's better to print out what's being aliased, then pass a '0'
as the third parameter to the InstAlias definition.
-Instruction Matching
---------------------
-
-.. note::
-
- To Be Written
+### Instruction Matching
-.. _Implementations of the abstract target description interfaces:
-.. _implement the target description:
+```{note}
+To Be Written
+```
+(Implementations of the abstract target description interfaces)=
+(implement the target description)=
-Target-specific Implementation Notes
-====================================
+## Target-specific Implementation Notes
This section of the document explains features or design decisions that are
specific to the code generator for a particular target.
-.. _tail call section:
+(tail call section)=
-Tail call optimization
-----------------------
+### Tail call optimization
Tail call optimization, callee reusing the stack of the caller, is currently
supported on x86/x86-64, PowerPC, AArch64, and WebAssembly. It is performed on
x86/x86-64, PowerPC, and AArch64 if:
-* Caller and callee have the calling convention ``fastcc``, ``cc 10`` (GHC
- calling convention), ``cc 11`` (HiPE calling convention), ``tailcc``, or
- ``swifttailcc``.
+* Caller and callee have the calling convention `fastcc`, `cc 10` (GHC
+ calling convention), `cc 11` (HiPE calling convention), `tailcc`, or
+ `swifttailcc`.
* The call is a tail call - in tail position (ret immediately follows call and
ret uses value of call or is void).
-* Option ``-tailcallopt`` is enabled or the calling convention is ``tailcc``.
+* Option `-tailcallopt` is enabled or the calling convention is `tailcc`.
* Platform-specific constraints are met.
@@ -1902,39 +1814,37 @@ AArch64 constraints:
Example:
-Call as ``llc -tailcallopt test.ll``.
-
-.. code-block:: llvm
-
- declare fastcc i32 @tailcallee(i32 inreg %a1, i32 inreg %a2, i32 %a3, i32 %a4)
+Call as `llc -tailcallopt test.ll`.
- define fastcc i32 @tailcaller(i32 %in1, i32 %in2) {
- %l1 = add i32 %in1, %in2
- %tmp = tail call fastcc i32 @tailcallee(i32 inreg %in1, i32 inreg %in2, i32 %in1, i32 %l1)
- ret i32 %tmp
- }
+```llvm
+declare fastcc i32 @tailcallee(i32 inreg %a1, i32 inreg %a2, i32 %a3, i32 %a4)
-Implications of ``-tailcallopt``:
+define fastcc i32 @tailcaller(i32 %in1, i32 %in2) {
+ %l1 = add i32 %in1, %in2
+ %tmp = tail call fastcc i32 @tailcallee(i32 inreg %in1, i32 inreg %in2, i32 %in1, i32 %l1)
+ ret i32 %tmp
+}
+```
+Implications of `-tailcallopt`:
To support tail call optimization in situations where the callee has more
arguments than the caller a 'callee pops arguments' convention is used. This
-currently causes each ``fastcc`` call that is not tail call optimized (because
+currently causes each `fastcc` call that is not tail call optimized (because
one or more of above constraints are not met) to be followed by a readjustment
of the stack. So performance might be worse in such cases.
-Sibling call optimization
--------------------------
+### Sibling call optimization
Sibling call optimization is a restricted form of tail call optimization.
Unlike tail call optimization described in the previous section, it can be
-performed automatically on any tail calls when ``-tailcallopt`` option is not
+performed automatically on any tail calls when `-tailcallopt` option is not
specified.
Sibling call optimization is currently performed on x86/x86-64 when the
following constraints are met:
-* Caller and callee have the same calling convention. It can be either ``c`` or
- ``fastcc``.
+* Caller and callee have the same calling convention. It can be either `c` or
+ `fastcc`.
* The call is a tail call - in tail position (ret immediately follows call and
ret uses value of call or is void).
@@ -1947,25 +1857,22 @@ following constraints are met:
Example:
-.. code-block:: llvm
-
- declare i32 @bar(i32, i32)
+```llvm
+declare i32 @bar(i32, i32)
- define i32 @foo(i32 %a, i32 %b, i32 %c) {
- entry:
- %0 = tail call i32 @bar(i32 %a, i32 %b)
- ret i32 %0
- }
+define i32 @foo(i32 %a, i32 %b, i32 %c) {
+entry:
+ %0 = tail call i32 @bar(i32 %a, i32 %b)
+ ret i32 %0
+}
+```
+### The X86 backend
-The X86 backend
----------------
-
-The X86 code generator lives in the ``lib/Target/X86`` directory. This code
+The X86 code generator lives in the `lib/Target/X86` directory. This code
generator is capable of targeting a variety of x86-32 and x86-64 processors, and
includes support for ISA extensions such as MMX and SSE.
-X86 Target Triples supported
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### X86 Target Triples supported
The following are the known target triples that are supported by the X86
backend. This is not an exhaustive list, and it would be useful to add those
@@ -1985,8 +1892,7 @@ that people test.
* **x86_64-unknown-linux-gnu** --- Linux
-X86 Calling Conventions supported
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### X86 Calling Conventions supported
The following target-specific calling conventions are known to backend:
@@ -2000,36 +1906,34 @@ The following target-specific calling conventions are known to backend:
others via stack. Callee is responsible for stack cleaning. This convention is
used by MSVC by default for methods in its ABI (CC ID = 70).
-.. _X86 addressing mode:
+(X86 addressing mode)=
-Representing X86 addressing modes in MachineInstrs
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Representing X86 addressing modes in MachineInstrs
The x86 has a very flexible way of accessing memory. It is capable of forming
memory addresses of the following expression directly in integer instructions
(which use ModR/M addressing):
-::
-
- SegmentReg: Base + [1,2,4,8] * IndexReg + Disp32
+```
+SegmentReg: Base + [1,2,4,8] * IndexReg + Disp32
+```
In order to represent this, LLVM tracks no less than 5 operands for each memory
-operand of this form. This means that the "load" form of '``mov``' has the
-following ``MachineOperand``\s in this order:
-
-::
+operand of this form. This means that the "load" form of '`mov`' has the
+following `MachineOperand`s in this order:
- Index: 0 | 1 2 3 4 5
- Meaning: DestReg, | BaseReg, Scale, IndexReg, Displacement Segment
- OperandTy: VirtReg, | VirtReg, UnsImm, VirtReg, SignExtImm PhysReg
+```
+Index: 0 | 1 2 3 4 5
+Meaning: DestReg, | BaseReg, Scale, IndexReg, Displacement Segment
+OperandTy: VirtReg, | VirtReg, UnsImm, VirtReg, SignExtImm PhysReg
+```
Stores, and all other instructions, treat the four memory operands in the same
way and in the same order. If the segment register is unspecified (regno = 0),
then no segment override is generated. "Lea" operations do not have a segment
register specified, so they only have 4 operands for their memory reference.
-X86 address spaces supported
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### X86 address spaces supported
x86 has a feature which provides the ability to perform loads and stores to
different address spaces via the x86 segment registers. A segment override
@@ -2041,14 +1945,14 @@ represented by address space 256, the FS-segment is represented by address space
257, and the SS-segment is represented by address space 258. Other x86 segments
have yet to be allocated address space numbers.
-While these address spaces may seem similar to TLS via the ``thread_local``
+While these address spaces may seem similar to TLS via the `thread_local`
keyword, and often use the same underlying hardware, there are some fundamental
differences.
-The ``thread_local`` keyword applies to global variables and specifies that they
+The `thread_local` keyword applies to global variables and specifies that they
are to be allocated in thread-local memory. There are no type qualifiers
involved, and these variables can be pointed to with normal pointers and
-accessed with normal loads and stores. The ``thread_local`` keyword is
+accessed with normal loads and stores. The `thread_local` keyword is
target-independent at the LLVM IR level (though LLVM doesn't yet have
implementations of it for some configurations)
@@ -2065,41 +1969,35 @@ Some operating systems and runtime environments use (or may in the future use)
the FS/GS-segment registers for various low-level purposes, so care should be
taken when considering them.
-Instruction naming
-^^^^^^^^^^^^^^^^^^
+#### Instruction naming
An instruction name consists of the base name, a default operand size, and a
character per operand with an optional special size. For example:
-::
+```
+ADD8rr -> add, 8-bit register, 8-bit register
+IMUL16rmi -> imul, 16-bit register, 16-bit memory, 16-bit immediate
+IMUL16rmi8 -> imul, 16-bit register, 16-bit memory, 8-bit immediate
+MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory
+```
- ADD8rr -> add, 8-bit register, 8-bit register
- IMUL16rmi -> imul, 16-bit register, 16-bit memory, 16-bit immediate
- IMUL16rmi8 -> imul, 16-bit register, 16-bit memory, 8-bit immediate
- MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory
+### The PowerPC backend
-The PowerPC backend
--------------------
-
-The PowerPC code generator lives in the ``lib/Target/PowerPC`` directory. The code
+The PowerPC code generator lives in the `lib/Target/PowerPC` directory. The code
generation is retargetable to several variations or *subtargets* of the PowerPC
ISA; including ppc32, ppc64 and altivec.
-LLVM PowerPC ABI
-^^^^^^^^^^^^^^^^
+#### LLVM PowerPC ABI
LLVM follows the AIX PowerPC ABI, with two deviations. LLVM uses a PC relative
(PIC) or static addressing for accessing global values, so no TOC (r2) is
used. Second, r31 is used as a frame pointer to allow dynamic growth of a stack
frame. LLVM takes advantage of having no TOC to provide space to save the frame
pointer in the PowerPC linkage area of the caller frame. Other details of
-PowerPC ABI can be found at `PowerPC ABI
-<http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html>`_\
-. Note: This link describes the 32-bit ABI. The 64-bit ABI is similar except
+PowerPC ABI can be found at [PowerPC ABI](http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html). Note: This link describes the 32-bit ABI. The 64-bit ABI is similar except
space for GPRs are 8 bytes wide (not 4) and r13 is reserved for system use.
-Frame Layout
-^^^^^^^^^^^^
+#### Frame Layout
The size of a PowerPC frame is usually fixed for the duration of a function's
invocation. Since the frame is fixed size, all references into the frame can be
@@ -2112,29 +2010,15 @@ that space allocated for altivec vectors will be properly aligned.
An invocation frame is laid out as follows (low memory at top):
-:raw-html:`<table border="1" cellspacing="0">`
-:raw-html:`<tr>`
-:raw-html:`<td>Linkage<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>Parameter area<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>Dynamic area<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>Locals area<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>Saved registers area<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr style="border-style: none hidden none hidden;">`
-:raw-html:`<td><br></td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>Previous Frame<br><br></td>`
-:raw-html:`</tr>`
-:raw-html:`</table>`
+| Stack frame area |
+| --- |
+| Linkage |
+| Parameter area |
+| Dynamic area |
+| Locals area |
+| Saved registers area |
+| |
+| Previous Frame |
The *linkage* area is used by a callee to save special registers prior to
allocating its own frame. Only three entries are relevant to LLVM. The first
@@ -2149,61 +2033,25 @@ GPR, thus the linkage area is 24 bytes long in 32-bit mode and 48 bytes in
32-bit linkage area:
-:raw-html:`<table border="1" cellspacing="0">`
-:raw-html:`<tr>`
-:raw-html:`<td>0</td>`
-:raw-html:`<td>Saved SP (r1)</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>4</td>`
-:raw-html:`<td>Saved CR</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>8</td>`
-:raw-html:`<td>Saved LR</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>12</td>`
-:raw-html:`<td>Reserved</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>16</td>`
-:raw-html:`<td>Reserved</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>20</td>`
-:raw-html:`<td>Saved FP (r31)</td>`
-:raw-html:`</tr>`
-:raw-html:`</table>`
+| Offset | Contents |
+| --- | --- |
+| 0 | Saved SP (r1) |
+| 4 | Saved CR |
+| 8 | Saved LR |
+| 12 | Reserved |
+| 16 | Reserved |
+| 20 | Saved FP (r31) |
64-bit linkage area:
-:raw-html:`<table border="1" cellspacing="0">`
-:raw-html:`<tr>`
-:raw-html:`<td>0</td>`
-:raw-html:`<td>Saved SP (r1)</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>8</td>`
-:raw-html:`<td>Saved CR</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>16</td>`
-:raw-html:`<td>Saved LR</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>24</td>`
-:raw-html:`<td>Reserved</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>32</td>`
-:raw-html:`<td>Reserved</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>40</td>`
-:raw-html:`<td>Saved FP (r31)</td>`
-:raw-html:`</tr>`
-:raw-html:`</table>`
+| Offset | Contents |
+| --- | --- |
+| 0 | Saved SP (r1) |
+| 8 | Saved CR |
+| 16 | Saved LR |
+| 24 | Reserved |
+| 32 | Reserved |
+| 40 | Saved FP (r31) |
The *parameter area* is used to store arguments being passed to a callee
function. Following the PowerPC ABI, the first few arguments are actually
@@ -2235,8 +2083,7 @@ The *locals area* is where the llvm compiler reserves space for local variables.
The *saved registers area* is where the llvm compiler spills callee saved
registers on entry to the callee.
-Prolog/Epilog
-^^^^^^^^^^^^^
+#### Prolog/Epilog
The llvm prolog and epilog are the same as described in the PowerPC ABI, with
the following exceptions. Callee saved registers are spilled after the frame is
@@ -2245,15 +2092,12 @@ targets. The base pointer callee saved register r31 is saved in the TOC slot of
linkage area. This simplifies allocation of space for the base pointer and
makes it convenient to locate programmatically and during debugging.
-Dynamic Allocation
-^^^^^^^^^^^^^^^^^^
-
-.. note::
+#### Dynamic Allocation
- TODO - More to come.
-
-The NVPTX backend
------------------
+```{note}
+TODO - More to come.
+```
+### The NVPTX backend
The NVPTX code generator under lib/Target/NVPTX is an open-source version of
the NVIDIA NVPTX code generator for LLVM. It is contributed by NVIDIA and is
@@ -2266,43 +2110,20 @@ the official NVIDIA toolchain.
Code Generator Options:
-:raw-html:`<table border="1" cellspacing="0">`
-:raw-html:`<tr>`
-:raw-html:`<th>Option</th>`
-:raw-html:`<th>Description</th>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>sm_20</td>`
-:raw-html:`<td align="left">Set shader model/compute capability to 2.0</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>sm_21</td>`
-:raw-html:`<td align="left">Set shader model/compute capability to 2.1</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>sm_30</td>`
-:raw-html:`<td align="left">Set shader model/compute capability to 3.0</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>sm_35</td>`
-:raw-html:`<td align="left">Set shader model/compute capability to 3.5</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>ptx30</td>`
-:raw-html:`<td align="left">Target PTX 3.0</td>`
-:raw-html:`</tr>`
-:raw-html:`<tr>`
-:raw-html:`<td>ptx31</td>`
-:raw-html:`<td align="left">Target PTX 3.1</td>`
-:raw-html:`</tr>`
-:raw-html:`</table>`
-
-The extended Berkeley Packet Filter (eBPF) backend
---------------------------------------------------
+| Option | Description |
+| --- | --- |
+| sm_20 | Set shader model/compute capability to 2.0 |
+| sm_21 | Set shader model/compute capability to 2.1 |
+| sm_30 | Set shader model/compute capability to 3.0 |
+| sm_35 | Set shader model/compute capability to 3.5 |
+| ptx30 | Target PTX 3.0 |
+| ptx31 | Target PTX 3.1 |
+
+### The extended Berkeley Packet Filter (eBPF) backend
Extended BPF (or eBPF) is similar to the original ("classic") BPF (cBPF) used
to filter network packets. The
-`bpf() system call <http://man7.org/linux/man-pages/man2/bpf.2.html>`_
+[bpf() system call](http://man7.org/linux/man-pages/man2/bpf.2.html)
performs a range of operations related to eBPF. For both cBPF and eBPF
programs, the Linux kernel statically analyzes the programs before loading
them, in order to ensure that they cannot harm the running system. eBPF is
@@ -2310,134 +2131,133 @@ a 64-bit RISC instruction set designed for one to one mapping to 64-bit CPUs.
Opcodes are 8-bit encoded, and 87 instructions are defined. There are 10
registers, grouped by function as outlined below.
-::
-
- R0 return value from in-kernel functions; exit value for eBPF program
- R1 - R5 function call arguments to in-kernel functions
- R6 - R9 callee-saved registers preserved by in-kernel functions
- R10 stack frame pointer (read only)
+```
+R0 return value from in-kernel functions; exit value for eBPF program
+R1 - R5 function call arguments to in-kernel functions
+R6 - R9 callee-saved registers preserved by in-kernel functions
+R10 stack frame pointer (read only)
+```
-Instruction encoding (arithmetic and jump)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Instruction encoding (arithmetic and jump)
eBPF is reusing most of the opcode encoding from classic to simplify conversion
of classic BPF to eBPF. For arithmetic and jump instructions the 8-bit 'code'
field is divided into three parts:
-::
-
- +----------------+--------+--------------------+
- | 4 bits | 1 bit | 3 bits |
- | operation code | source | instruction class |
- +----------------+--------+--------------------+
- (MSB) (LSB)
+```
++----------------+--------+--------------------+
+| 4 bits | 1 bit | 3 bits |
+| operation code | source | instruction class |
++----------------+--------+--------------------+
+(MSB) (LSB)
+```
Three LSB bits store instruction class which is one of:
-::
-
- BPF_LD 0x0
- BPF_LDX 0x1
- BPF_ST 0x2
- BPF_STX 0x3
- BPF_ALU 0x4
- BPF_JMP 0x5
- (unused) 0x6
- BPF_ALU64 0x7
+```
+BPF_LD 0x0
+BPF_LDX 0x1
+BPF_ST 0x2
+BPF_STX 0x3
+BPF_ALU 0x4
+BPF_JMP 0x5
+(unused) 0x6
+BPF_ALU64 0x7
+```
When BPF_CLASS(code) == BPF_ALU or BPF_ALU64 or BPF_JMP,
4th bit encodes source operand
-::
-
- BPF_X 0x1 use src_reg register as source operand
- BPF_K 0x0 use 32-bit immediate as source operand
+```
+BPF_X 0x1 use src_reg register as source operand
+BPF_K 0x0 use 32-bit immediate as source operand
+```
and four MSB bits store operation code
-::
-
- BPF_ADD 0x0 add
- BPF_SUB 0x1 subtract
- BPF_MUL 0x2 multiply
- BPF_DIV 0x3 divide
- BPF_OR 0x4 bitwise logical OR
- BPF_AND 0x5 bitwise logical AND
- BPF_LSH 0x6 left shift
- BPF_RSH 0x7 right shift (zero extended)
- BPF_NEG 0x8 arithmetic negation
- BPF_MOD 0x9 modulo
- BPF_XOR 0xa bitwise logical XOR
- BPF_MOV 0xb move register to register
- BPF_ARSH 0xc right shift (sign extended)
- BPF_END 0xd endianness conversion
+```
+BPF_ADD 0x0 add
+BPF_SUB 0x1 subtract
+BPF_MUL 0x2 multiply
+BPF_DIV 0x3 divide
+BPF_OR 0x4 bitwise logical OR
+BPF_AND 0x5 bitwise logical AND
+BPF_LSH 0x6 left shift
+BPF_RSH 0x7 right shift (zero extended)
+BPF_NEG 0x8 arithmetic negation
+BPF_MOD 0x9 modulo
+BPF_XOR 0xa bitwise logical XOR
+BPF_MOV 0xb move register to register
+BPF_ARSH 0xc right shift (sign extended)
+BPF_END 0xd endianness conversion
+```
If BPF_CLASS(code) == BPF_JMP, BPF_OP(code) is one of
-::
-
- BPF_JA 0x0 unconditional jump
- BPF_JEQ 0x1 jump ==
- BPF_JGT 0x2 jump >
- BPF_JGE 0x3 jump >=
- BPF_JSET 0x4 jump if (DST & SRC)
- BPF_JNE 0x5 jump !=
- BPF_JSGT 0x6 jump signed >
- BPF_JSGE 0x7 jump signed >=
- BPF_CALL 0x8 function call
- BPF_EXIT 0x9 function return
-
-Instruction encoding (load, store)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+BPF_JA 0x0 unconditional jump
+BPF_JEQ 0x1 jump ==
+BPF_JGT 0x2 jump >
+BPF_JGE 0x3 jump >=
+BPF_JSET 0x4 jump if (DST & SRC)
+BPF_JNE 0x5 jump !=
+BPF_JSGT 0x6 jump signed >
+BPF_JSGE 0x7 jump signed >=
+BPF_CALL 0x8 function call
+BPF_EXIT 0x9 function return
+```
+
+#### Instruction encoding (load, store)
For load and store instructions the 8-bit 'code' field is divided as:
-::
-
- +--------+--------+-------------------+
- | 3 bits | 2 bits | 3 bits |
- | mode | size | instruction class |
- +--------+--------+-------------------+
- (MSB) (LSB)
+```
++--------+--------+-------------------+
+| 3 bits | 2 bits | 3 bits |
+| mode | size | instruction class |
++--------+--------+-------------------+
+(MSB) (LSB)
+```
Size modifier is one of
-::
-
- BPF_W 0x0 word
- BPF_H 0x1 half word
- BPF_B 0x2 byte
- BPF_DW 0x3 double word
+```
+BPF_W 0x0 word
+BPF_H 0x1 half word
+BPF_B 0x2 byte
+BPF_DW 0x3 double word
+```
Mode modifier is one of
-::
-
- BPF_IMM 0x0 immediate
- BPF_ABS 0x1 used to access packet data
- BPF_IND 0x2 used to access packet data
- BPF_MEM 0x3 memory
- (reserved) 0x4
- (reserved) 0x5
- BPF_XADD 0x6 exclusive add
+```
+BPF_IMM 0x0 immediate
+BPF_ABS 0x1 used to access packet data
+BPF_IND 0x2 used to access packet data
+BPF_MEM 0x3 memory
+(reserved) 0x4
+(reserved) 0x5
+BPF_XADD 0x6 exclusive add
+```
-Packet data access (BPF_ABS, BPF_IND)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Packet data access (BPF_ABS, BPF_IND)
-Two non-generic instructions: (BPF_ABS | <size> | BPF_LD) and
-(BPF_IND | <size> | BPF_LD) which are used to access packet data.
+Two non-generic instructions: (`BPF_ABS | <size> | BPF_LD`) and
+(`BPF_IND | <size> | BPF_LD`) which are used to access packet data.
Register R6 is an implicit input that must contain pointer to sk_buff.
Register R0 is an implicit output which contains the data fetched
from the packet. Registers R1-R5 are scratch registers and must not
-be used to store the data across BPF_ABS | BPF_LD or BPF_IND | BPF_LD
+be used to store the data across `BPF_ABS | BPF_LD` or `BPF_IND | BPF_LD`
instructions. These instructions have implicit program exit condition
as well. When eBPF program is trying to access the data beyond
the packet boundary, the interpreter will abort the execution of the program.
-BPF_IND | BPF_W | BPF_LD is equivalent to:
- R0 = ntohl(\*(u32 \*) (((struct sk_buff \*) R6)->data + src_reg + imm32))
+`BPF_IND | BPF_W | BPF_LD` is equivalent to:
-eBPF maps
-^^^^^^^^^
+```
+R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32))
+```
+
+#### eBPF maps
eBPF maps are provided for sharing data between kernel and user-space.
Currently implemented types are hash and array, with potential extension to
@@ -2445,8 +2265,7 @@ support bloom filters, radix trees, etc. A map is defined by its type,
maximum number of elements, key size and value size in bytes. eBPF syscall
supports create, update, find and delete functions on maps.
-Function calls
-^^^^^^^^^^^^^^
+#### Function calls
Function call arguments are passed using up to five registers (R1 - R5).
The return value is passed in a dedicated register (R0). Four additional
@@ -2458,25 +2277,24 @@ using the read-only frame pointer R10. eBPF registers map 1:1 to hardware
registers on x86_64 and other 64-bit architectures. For example, x86_64
in-kernel JIT maps them as
-::
-
- R0 - rax
- R1 - rdi
- R2 - rsi
- R3 - rdx
- R4 - rcx
- R5 - r8
- R6 - rbx
- R7 - r13
- R8 - r14
- R9 - r15
- R10 - rbp
+```
+R0 - rax
+R1 - rdi
+R2 - rsi
+R3 - rdx
+R4 - rcx
+R5 - r8
+R6 - rbx
+R7 - r13
+R8 - r14
+R9 - r15
+R10 - rbp
+```
since x86_64 ABI mandates rdi, rsi, rdx, rcx, r8, r9 for argument passing
and rbx, r12 - r15 are callee saved.
-Program start
-^^^^^^^^^^^^^
+#### Program start
An eBPF program receives a single argument and contains
a single eBPF main routine; the program does not contain eBPF functions.
@@ -2486,17 +2304,15 @@ a limited number of kernel function calls. Prior to running an eBPF program,
a verifier performs static analysis to prevent loops in the code and
to ensure valid register usage and operand types.
-The AMDGPU backend
-------------------
+### The AMDGPU backend
-The AMDGPU code generator lives in the ``lib/Target/AMDGPU``
+The AMDGPU code generator lives in the `lib/Target/AMDGPU`
directory. This code generator is capable of targeting a variety of
-AMD GPU processors. Refer to :doc:`AMDGPUUsage` for more information.
+AMD GPU processors. Refer to {doc}`AMDGPUUsage` for more information.
-The Lightweight Fault Isolation (LFI) sub-architecture
-------------------------------------------------------
+### The Lightweight Fault Isolation (LFI) sub-architecture
LFI is a sub-architecture available for certain backends that allows programs
compiled for the target to run in a sandboxed environment that is within the
-same address space as host code. Refer to :doc:`LFI` for more information about
+same address space as host code. Refer to {doc}`LFI` for more information about
LFI.
diff --git a/llvm/docs/CodingStandards.md b/llvm/docs/CodingStandards.md
index 2cffcdd96b1dd..aac3f32c9c8de 100644
--- a/llvm/docs/CodingStandards.md
+++ b/llvm/docs/CodingStandards.md
@@ -1,12 +1,10 @@
-=====================
-LLVM Coding Standards
-=====================
+# LLVM Coding Standards
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction
-============
+## Introduction
This document describes coding standards that are used in the LLVM project.
Although no coding standards should be regarded as absolute requirements to be
@@ -18,14 +16,14 @@ While this document may provide guidance for some mechanical formatting issues,
whitespace, or other "microscopic details", these are not fixed standards.
Always follow the golden rule:
-.. _Golden Rule:
+(Golden Rule)=
- **If you are extending, enhancing, or bug fixing already implemented code,
- use the style that is already being used so that the source is uniform and
- easy to follow.**
+> **If you are extending, enhancing, or bug fixing already implemented code,
+> use the style that is already being used so that the source is uniform and
+> easy to follow.**
-Note that some code bases (e.g. ``libc++``) have special reasons to deviate
-from the coding standards. For example, in the case of ``libc++``, this is
+Note that some code bases (e.g. `libc++`) have special reasons to deviate
+from the coding standards. For example, in the case of `libc++`, this is
because the naming and other conventions are dictated by the C++ standard.
There are some conventions that are not uniformly followed in the code base
@@ -40,8 +38,7 @@ make code review easier.
The ultimate goal of these guidelines is to increase the readability and
maintainability of our common source base.
-Languages, Libraries, and Standards
-===================================
+## Languages, Libraries, and Standards
Most source code in LLVM and other LLVM projects using these coding standards
is C++ code. There are some places where C code is used either due to
@@ -53,15 +50,14 @@ choice.
For automation, build systems, and utility scripts, Python is preferred and
is widely used in the LLVM repository already.
-C++ Standard Versions
----------------------
+### C++ Standard Versions
Unless otherwise documented, LLVM subprojects are written using standard C++17
code and avoid unnecessary vendor-specific extensions.
Nevertheless, we restrict ourselves to features which are available in the
-major toolchains supported as host compilers (see :doc:`GettingStarted` page,
-section `Software`).
+major toolchains supported as host compilers (see {doc}`GettingStarted` page,
+section [Software](project:GettingStarted.md#software)).
Each toolchain provides a good reference for what it accepts:
@@ -76,7 +72,7 @@ Each toolchain provides a good reference for what it accepts:
* MSVC: https://learn.microsoft.com/cpp/overview/visual-cpp-language-conformance
Additionally, there are compiler comparison tables of supported C++ features on
-`cppreference.com <https://en.cppreference.com/w/cpp/compiler_support/17>`_.
+[cppreference.com](https://en.cppreference.com/w/cpp/compiler_support/17).
To keep track with the evolution of the standard, newer C++ versions can be used
to build LLVM. However, our support focuses on the minimum supported C++
@@ -85,8 +81,7 @@ latest version of the supported toolchains and possibly not across all the
subprojects.
-C++ Standard Library
---------------------
+### C++ Standard Library
Instead of implementing custom data structures, we encourage the use of C++
standard library facilities or LLVM support libraries whenever they are
@@ -94,60 +89,63 @@ available for a particular task. LLVM and related projects emphasize and rely
on the standard library facilities and the LLVM support libraries as much as
possible.
-LLVM support libraries (for example, `ADT
-<https://github.com/llvm/llvm-project/tree/main/llvm/include/llvm/ADT>`_)
+LLVM support libraries (for example, [ADT])
implement specialized data structures or functionality missing in the standard
-library. Such libraries are usually implemented in the ``llvm`` namespace and
+library. Such libraries are usually implemented in the `llvm` namespace and
follow the expected standard interface when there is one.
+[ADT]: https://github.com/llvm/llvm-project/tree/main/llvm/include/llvm/ADT
+
When both C++ and the LLVM support libraries provide similar functionality, and
there isn't a specific reason to favor the C++ implementation, it is generally
-preferable to use the LLVM library. For example, ``llvm::DenseMap`` should
-almost always be used instead of ``std::map`` or ``std::unordered_map``, and
-``llvm::SmallVector`` should usually be used instead of ``std::vector``.
+preferable to use the LLVM library. For example, `llvm::DenseMap` should
+almost always be used instead of `std::map` or `std::unordered_map`, and
+`llvm::SmallVector` should usually be used instead of `std::vector`.
We explicitly avoid some standard facilities, like the I/O streams, and instead
-use LLVM's streams library (raw_ostream_). More detailed information on these
-subjects is available in the :doc:`ProgrammersManual`.
+use LLVM's streams library ({ref}`raw_ostream <raw_ostream>`). More detailed information on these
+subjects is available in the {doc}`ProgrammersManual`.
For more information about LLVM's data structures and the tradeoffs they make,
-please consult `that section of the programmer's manual
-<https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task>`_.
+please consult [that section of the programmer's manual].
+
+[that section of the programmer's manual]: https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task
-Python version and Source Code Formatting
------------------------------------------
+### Python version and Source Code Formatting
-The current minimum version of Python required is documented in the :doc:`GettingStarted`
+The current minimum version of Python required is documented in the {doc}`GettingStarted`
section. Python code in the LLVM repository should only use language features
available in this version of Python.
The Python code within the LLVM repository should adhere to the formatting guidelines
-outlined in `PEP 8 <https://peps.python.org/pep-0008/>`_.
+outlined in [PEP 8](https://peps.python.org/pep-0008/).
For consistency and to limit churn, code should be automatically formatted with
-the `black <https://github.com/psf/black>`_ utility, which is PEP 8 compliant.
-Use its default rules. For example, avoid specifying ``--line-length`` even
+the [black](https://github.com/psf/black) utility, which is PEP 8 compliant.
+Use its default rules. For example, avoid specifying `--line-length` even
though it does not default to 80. The default rules can change between major
versions of black. In order to avoid unnecessary churn in the formatting rules,
we currently use black version 23.x in LLVM.
When contributing a patch unrelated to formatting, you should format only the
-Python code that the patch modifies. For this purpose, use the `darker
-<https://pypi.org/project/darker/>`_ utility, which runs default black rules
+Python code that the patch modifies. For this purpose, use the [darker]
+utility, which runs default black rules
over only the modified Python code. Doing so should ensure the patch will pass
the Python format checks in LLVM's pre-commit CI, which also uses darker. When
contributing a patch specifically for reformatting Python files, use black,
which currently only supports formatting entire files.
+[darker]: https://pypi.org/project/darker/
+
Here are some quick examples, but see the black and darker documentation for
details:
-.. code-block:: bash
-
- $ pip install black=='23.*' darker # install black 23.x and darker
- $ darker test.py # format uncommitted changes
- $ darker -r HEAD^ test.py # also format changes from last commit
- $ black test.py # format entire file
+```bash
+$ pip install black=='23.*' darker # install black 23.x and darker
+$ darker test.py # format uncommitted changes
+$ darker -r HEAD^ test.py # also format changes from last commit
+$ black test.py # format entire file
+```
Instead of individual file names, you can specify directories to
darker, and it will find the changed files. However, if a directory is
@@ -155,79 +153,72 @@ large, like a clone of the LLVM repository, darker can be painfully
slow. In that case, you might wish to use git to list changed files.
For example:
-.. code-block:: bash
-
- $ darker -r HEAD^ $(git diff --name-only --diff-filter=d HEAD^)
+```bash
+$ darker -r HEAD^ $(git diff --name-only --diff-filter=d HEAD^)
+```
-Mechanical Source Issues
-========================
+## Mechanical Source Issues
-Source Code Formatting
-----------------------
+### Source Code Formatting
-Commenting
-^^^^^^^^^^
+#### Commenting
Comments are important for readability and maintainability. When writing comments,
write them as English prose, using proper capitalization, punctuation, etc.
Aim to describe what the code is trying to do and why, not *how* it does it at
a micro level. Here are a few important things to document:
-.. _header file comment:
+(header file comment)=
-File Headers
-""""""""""""
+##### File Headers
Every source file should have a header on it that describes the basic purpose of
the file. The standard header looks like this:
-.. code-block:: c++
-
- //===----------------------------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// This file contains the declaration of the Instruction class, which is the
- /// base class for all of the VM instructions.
- ///
- //===----------------------------------------------------------------------===//
+```c++
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of the Instruction class, which is the
+/// base class for all of the VM instructions.
+///
+//===----------------------------------------------------------------------===//
+```
The first section in the file is a concise note that defines the license that the
file is released under. This makes it perfectly clear what terms the source
code can be distributed under and should not be modified in any way.
-The main body is a `Doxygen <http://www.doxygen.nl/>`_ comment (identified by
-the ``///`` comment marker instead of the usual ``//``) describing the purpose
-of the file. The first sentence (or a passage beginning with ``\brief``) is
+The main body is a [Doxygen](http://www.doxygen.nl/) comment (identified by
+the `///` comment marker instead of the usual `//`) describing the purpose
+of the file. The first sentence (or a passage beginning with `\brief`) is
used as an abstract. Any additional information should be separated by a blank
line. If an algorithm is based on a paper or is described in another source,
provide a reference.
-Header Guard
-""""""""""""
+##### Header Guard
The header file's guard should be the all-caps path that a user of this header
would #include, using '_' instead of path separator and extension marker.
For example, the header file
-``llvm/include/llvm/Analysis/Utils/Local.h`` would be ``#include``-ed as
-``#include "llvm/Analysis/Utils/Local.h"``, so its guard is
-``LLVM_ANALYSIS_UTILS_LOCAL_H``.
+`llvm/include/llvm/Analysis/Utils/Local.h` would be `#include`-ed as
+`#include "llvm/Analysis/Utils/Local.h"`, so its guard is
+`LLVM_ANALYSIS_UTILS_LOCAL_H`.
-Class overviews
-"""""""""""""""
+##### Class overviews
Classes are a fundamental part of an object-oriented design. As such, a
class definition should have a comment block that explains what the class is
used for and how it works. Every non-trivial class is expected to have a
-``doxygen`` comment block.
+`doxygen` comment block.
-Method information
-""""""""""""""""""
+##### Method information
Methods and global functions should also be documented. A quick note about
what it does and a description of the edge cases is all that is necessary here.
@@ -237,97 +228,95 @@ the code itself.
Good things to talk about here are what happens when something unexpected
happens, for instance, does the method return null?
-Comment Formatting
-^^^^^^^^^^^^^^^^^^
+#### Comment Formatting
-In general, prefer C++-style comments (``//`` for normal comments, ``///`` for
-``doxygen`` documentation comments). There are a few cases when it is
-useful to use C-style (``/* */``) comments, however:
+In general, prefer C++-style comments (`//` for normal comments, `///` for
+`doxygen` documentation comments). There are a few cases when it is
+useful to use C-style (`/* */`) comments, however:
-#. When writing C code to be compatible with C89.
+1. When writing C code to be compatible with C89.
-#. When writing a header file that may be ``#include``\d by a C source file.
+1. When writing a header file that may be `#include`d by a C source file.
-#. When writing a source file that is used by a tool that only accepts C-style
+1. When writing a source file that is used by a tool that only accepts C-style
comments.
-#. When documenting the significance of constants used as actual parameters in
- a call. This is most helpful for ``bool`` parameters, or passing ``0`` or
- ``nullptr``. The comment should contain the parameter name, which ought to be
+1. When documenting the significance of constants used as actual parameters in
+ a call. This is most helpful for `bool` parameters, or passing `0` or
+ `nullptr`. The comment should contain the parameter name, which ought to be
meaningful. For example, it's not clear what the parameter means in this call:
- .. code-block:: c++
-
- Object.emitName(nullptr);
+ ```c++
+ Object.emitName(nullptr);
+ ```
An in-line C-style comment makes the intent obvious:
- .. code-block:: c++
-
- Object.emitName(/*Prefix=*/nullptr);
+ ```c++
+ Object.emitName(/*Prefix=*/nullptr);
+ ```
Commenting out large blocks of code is discouraged, but if you really have to do
this (for documentation purposes or as a suggestion for debug printing), use
-``#if 0`` and ``#endif``. These nest properly and are better behaved in general
+`#if 0` and `#endif`. These nest properly and are better behaved in general
than C-style comments.
-Doxygen Use in Documentation Comments
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Doxygen Use in Documentation Comments
-Use the ``\file`` command to turn the standard file header into a file-level
+Use the `\file` command to turn the standard file header into a file-level
comment.
Include descriptive paragraphs for all public interfaces (public classes,
member and non-member functions). Avoid restating the information that can be
inferred from the API name or signature. The first sentence (or a paragraph
-beginning with ``\brief``) is used as an abstract. Try to use a single
-sentence as the ``\brief`` adds visual clutter. Put detailed discussion into
+beginning with `\brief`) is used as an abstract. Try to use a single
+sentence as the `\brief` adds visual clutter. Put detailed discussion into
separate paragraphs.
A minimal documentation comment:
-.. code-block:: c++
-
- /// Sets the xyzzy property to \p Baz.
- void setXyzzy(bool Baz);
+```c++
+/// Sets the xyzzy property to \p Baz.
+void setXyzzy(bool Baz);
+```
Only include code examples, function parameters and return values when it
provides additional information, such as intent, usage, or behavior that’s
non-obvious. Use descriptive function and argument names to
eliminate the need for documentation comments when possible.
-To refer to parameter names inside a paragraph, use the ``\p name`` command.
-Don't use the ``\arg name`` command since it starts a new paragraph that
+To refer to parameter names inside a paragraph, use the `\p name` command.
+Don't use the `\arg name` command since it starts a new paragraph that
contains documentation for the parameter.
-Wrap non-inline code examples in ``\code ... \endcode``.
+Wrap non-inline code examples in `\code ... \endcode`.
To document a function parameter, start a new paragraph with the
-``\param name`` command. If the parameter is used as an out or an in/out
-parameter, use the ``\param [out] name`` or ``\param [in,out] name`` command,
+`\param name` command. If the parameter is used as an out or an in/out
+parameter, use the `\param [out] name` or `\param [in,out] name` command,
respectively.
-To describe function return value, start a new paragraph with the ``\returns``
+To describe function return value, start a new paragraph with the `\returns`
command.
A documentation comment that uses all Doxygen features in a preferred way:
-.. code-block:: c++
-
- /// Does foo and bar.
- ///
- /// Does not do foo the usual way if \p Baz is true.
- ///
- /// Typical usage:
- /// \code
- /// fooBar(false, "quux", Res);
- /// \endcode
- ///
- /// \param Quux kind of foo to do.
- /// \param [out] Result filled with bar sequence on foo success.
- ///
- /// \returns true on success.
- bool fooBar(bool Baz, StringRef Quux, std::vector<int> &Result);
+```c++
+/// Does foo and bar.
+///
+/// Does not do foo the usual way if \p Baz is true.
+///
+/// Typical usage:
+/// \code
+/// fooBar(false, "quux", Res);
+/// \endcode
+///
+/// \param Quux kind of foo to do.
+/// \param [out] Result filled with bar sequence on foo success.
+///
+/// \returns true on success.
+bool fooBar(bool Baz, StringRef Quux, std::vector<int> &Result);
+```
Don't duplicate the documentation comment in the header file and in the
implementation file. Put the documentation comments for public APIs into the
@@ -343,34 +332,33 @@ to the correct declaration.
Avoid:
-.. code-block:: c++
-
- // Example.h:
+```c++
+// Example.h:
- // example - Does something important.
- void example();
+// example - Does something important.
+void example();
- // Example.cpp:
+// Example.cpp:
- // example - Does something important.
- void example() { ... }
+// example - Does something important.
+void example() { ... }
+```
Preferred:
-.. code-block:: c++
+```c++
+// Example.h:
- // Example.h:
+/// Does something important.
+void example();
- /// Does something important.
- void example();
+// Example.cpp:
- // Example.cpp:
+/// Builds a B-tree in order to do foo. See paper by...
+void example() { ... }
+```
- /// Builds a B-tree in order to do foo. See paper by...
- void example() { ... }
-
-Error and Warning Messages
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Error and Warning Messages
Clear diagnostic messages are important to help users identify and fix issues in
their inputs. Use succinct but correct English prose that gives the user the
@@ -382,16 +370,16 @@ end in one otherwise. Sentences which end with different punctuation, such as
For example, this is a good error message:
-.. code-block:: none
-
- error: file.o: section header 3 is corrupt. Size is 10 when it should be 20
+```text
+error: file.o: section header 3 is corrupt. Size is 10 when it should be 20
+```
This is a bad message, since it does not provide useful information and uses the
wrong style:
-.. code-block:: none
-
- error: file.o: Corrupt section header.
+```text
+error: file.o: Corrupt section header.
+```
As with other coding standards, individual projects, such as the Clang Static
Analyzer, may have preexisting styles that do not conform to this. If a
@@ -400,54 +388,52 @@ that style instead. Otherwise, this standard applies to all LLVM tools,
including clang, clang-tidy, and so on.
If the tool or project does not have existing functions to emit warnings or
-errors, use the error and warning handlers provided in ``Support/WithColor.h``
+errors, use the error and warning handlers provided in `Support/WithColor.h`
to ensure they are printed in the appropriate style, rather than printing to
stderr directly.
-When using ``report_fatal_error``, follow the same standards for the message as
-regular error messages. Assertion messages and ``llvm_unreachable`` calls do not
+When using `report_fatal_error`, follow the same standards for the message as
+regular error messages. Assertion messages and `llvm_unreachable` calls do not
necessarily need to follow these same styles as they are automatically
formatted, and thus these guidelines may not be suitable.
-``#include`` Style
-^^^^^^^^^^^^^^^^^^
+#### `#include` Style
-Immediately after the `header file comment`_ (and include guards if working on a
-header file), the `minimal list of #includes`_ required by the file should be
-listed. We prefer these ``#include``\s to be listed in this order:
+Immediately after the {ref}`header file comment <header file comment>` (and include guards if working on a
+header file), the {ref}`minimal list of #includes <minimal list of #includes>` required by the file should be
+listed. We prefer these `#include`s to be listed in this order:
-.. _Main Module Header:
-.. _Local/Private Headers:
+(Main Module Header)=
+(Local/Private Headers)=
-#. Main Module Header
-#. Local/Private Headers
-#. LLVM project/subproject headers (``clang/...``, ``lldb/...``, ``llvm/...``, etc)
-#. System ``#include``\s
+1. Main Module Header
+1. Local/Private Headers
+1. LLVM project/subproject headers (`clang/...`, `lldb/...`, `llvm/...`, etc)
+1. System `#include`s
and each category should be sorted lexicographically by the full path.
-The `Main Module Header`_ file applies to ``.cpp`` files which implement an
-interface defined by a ``.h`` file. This ``#include`` should always be included
+The {ref}`Main Module Header <Main Module Header>` file applies to `.cpp` files which implement an
+interface defined by a `.h` file. This `#include` should always be included
**first** regardless of where it lives on the file system. By including a
-header file first in the ``.cpp`` files that implement the interfaces, we ensure
+header file first in the `.cpp` files that implement the interfaces, we ensure
that the header does not have any hidden dependencies which are not explicitly
-``#include``\d in the header, but should be. It is also a form of documentation
-in the ``.cpp`` file to indicate where the interfaces it implements are defined.
+`#include`d in the header, but should be. It is also a form of documentation
+in the `.cpp` file to indicate where the interfaces it implements are defined.
LLVM project and subproject headers should be grouped from most specific to least
specific, for the same reasons described above. For example, LLDB depends on
both clang and LLVM, and clang depends on LLVM. So an LLDB source file should
-include ``lldb`` headers first, followed by ``clang`` headers, followed by
-``llvm`` headers, to reduce the possibility (for example) of an LLDB header
+include `lldb` headers first, followed by `clang` headers, followed by
+`llvm` headers, to reduce the possibility (for example) of an LLDB header
accidentally picking up a missing include due to the previous inclusion of that
header in the main source file or some earlier header file. clang should
similarly include its own headers before including llvm headers. This rule
applies to all LLVM subprojects.
-.. _fit into 80 columns:
+(fit into 80 columns)=
-Source Code Width
-^^^^^^^^^^^^^^^^^
+#### Source Code Width
Write your code to fit within 80 columns.
@@ -472,8 +458,7 @@ If your reformatting is causing unnecessary changes in subsequent lines, please
Unecessary changes in TD files cause unnecessary churn in the file history and force recompilation of many unnecessary files.
It also causes unnecessary changes in forks working on the same TD files, which makes it harder to rebase and merge later.
-Whitespace
-^^^^^^^^^^
+#### Whitespace
In all cases, prefer spaces to tabs in source files. People have different
preferred indentation levels, and different styles of indentation that they
@@ -481,15 +466,14 @@ like; this is fine. What isn't fine is that different editors/viewers expand
tabs out to different tab stops. This can cause your code to look completely
unreadable, and it is not worth dealing with.
-As always, follow the `Golden Rule`_ above: follow the style of existing code
+As always, follow the {ref}`Golden Rule <Golden Rule>` above: follow the style of existing code
if you are modifying and extending it.
Do not add trailing whitespace. Some common editors will automatically remove
trailing whitespace when saving a file which causes unrelated changes to appear
in diffs and commits.
-Format Lambdas Like Blocks Of Code
-""""""""""""""""""""""""""""""""""
+##### Format Lambdas Like Blocks Of Code
When formatting a multi-line lambda, format it like a block of code. If there
is only one multi-line lambda in a statement, and there are no expressions
@@ -497,42 +481,41 @@ lexically after it in the statement, drop the indent to the standard two space
indent for a block of code, as if it were an if-block opened by the preceding
part of the statement:
-.. code-block:: c++
-
- std::sort(foo.begin(), foo.end(), [&](Foo a, Foo b) -> bool {
- if (a.blah < b.blah)
- return true;
- if (a.baz < b.baz)
- return true;
- return a.bam < b.bam;
- });
+```c++
+std::sort(foo.begin(), foo.end(), [&](Foo a, Foo b) -> bool {
+ if (a.blah < b.blah)
+ return true;
+ if (a.baz < b.baz)
+ return true;
+ return a.bam < b.bam;
+});
+```
To take best advantage of this formatting, if you are designing an API which
accepts a continuation or single callable argument (be it a function object, or
-a ``std::function``), it should be the last argument if at all possible.
+a `std::function`), it should be the last argument if at all possible.
If there are multiple multi-line lambdas in a statement, or additional
parameters after the lambda, indent the block two spaces from the indent of the
-``[]``:
-
-.. code-block:: c++
-
- dyn_switch(V->stripPointerCasts(),
- [] (PHINode *PN) {
- // process phis...
- },
- [] (SelectInst *SI) {
- // process selects...
- },
- [] (LoadInst *LI) {
- // process loads...
- },
- [] (AllocaInst *AI) {
- // process allocas...
- });
-
-Braced Initializer Lists
-""""""""""""""""""""""""
+`[]`:
+
+```c++
+dyn_switch(V->stripPointerCasts(),
+ [] (PHINode *PN) {
+ // process phis...
+ },
+ [] (SelectInst *SI) {
+ // process selects...
+ },
+ [] (LoadInst *LI) {
+ // process loads...
+ },
+ [] (AllocaInst *AI) {
+ // process allocas...
+ });
+```
+
+##### Braced Initializer Lists
Starting from C++11, there are significantly more uses of braced lists to
perform initialization. For example, they can be used to construct aggregate
@@ -547,141 +530,136 @@ formatting braced initialization lists: act as if the braces were parentheses
in a function call. The formatting rules exactly match those already well
understood for formatting nested function calls. Examples:
-.. code-block:: c++
-
- foo({a, b, c}, {1, 2, 3});
+```c++
+foo({a, b, c}, {1, 2, 3});
- llvm::Constant *Mask[] = {
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 0),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 1),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 2)};
+llvm::Constant *Mask[] = {
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 0),
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 1),
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(getLLVMContext()), 2)};
+```
This formatting scheme also makes it particularly easy to get predictable,
-consistent, and automatic formatting with tools like `Clang Format`_.
+consistent, and automatic formatting with tools like [Clang Format].
-.. _Clang Format: https://clang.llvm.org/docs/ClangFormat.html
+[Clang Format]: https://clang.llvm.org/docs/ClangFormat.html
-Language and Compiler Issues
-----------------------------
+### Language and Compiler Issues
-Treat Compiler Warnings Like Errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Treat Compiler Warnings Like Errors
Compiler warnings are often useful and help improve the code. Those that are
not useful, can be often suppressed with a small code change. For example, an
-assignment in the ``if`` condition is often a typo:
+assignment in the `if` condition is often a typo:
-.. code-block:: c++
-
- if (V = getValue()) {
- ...
- }
+```c++
+if (V = getValue()) {
+ ...
+}
+```
Several compilers will print a warning for the code above. It can be suppressed
by adding parentheses:
-.. code-block:: c++
-
- if ((V = getValue())) {
- ...
- }
+```c++
+if ((V = getValue())) {
+ ...
+}
+```
-Write Portable Code
-^^^^^^^^^^^^^^^^^^^
+#### Write Portable Code
In almost all cases, it is possible to write completely portable code. When
you need to rely on non-portable code, put it behind a well-defined and
well-documented interface.
-Do not use RTTI or Exceptions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Do not use RTTI or Exceptions
In an effort to reduce code and executable size, LLVM does not use exceptions
-or RTTI (`runtime type information
-<https://en.wikipedia.org/wiki/Run-time_type_information>`_, for example,
-``dynamic_cast<>``).
+or RTTI ([runtime type information], for example,
+`dynamic_cast<>`).
+
+[runtime type information]: https://en.wikipedia.org/wiki/Run-time_type_information
That said, LLVM does make extensive use of a hand-rolled form of RTTI that use
-templates like :ref:`isa\<>, cast\<>, and dyn_cast\<> <isa>`.
+templates like [isa<>, cast<>, and dyn_cast<>](project:ProgrammersManual.md#the-isa-cast-and-dyn-cast-templates).
This form of RTTI is opt-in and can be
-:doc:`added to any class <HowToSetUpLLVMStyleRTTI>`.
+{doc}`added to any class <HowToSetUpLLVMStyleRTTI>`.
-Prefer C++-style casts
-^^^^^^^^^^^^^^^^^^^^^^
+#### Prefer C++-style casts
-When casting, use ``static_cast``, ``reinterpret_cast``, and ``const_cast``,
+When casting, use `static_cast`, `reinterpret_cast`, and `const_cast`,
rather than C-style casts. There are two exceptions to this:
-* When casting to ``void`` to suppress warnings about unused variables (as an
- alternative to ``[[maybe_unused]]``). Prefer C-style casts in this instance.
- Note that if the variable is unused because it's used only in ``assert``, use
- ``[[maybe_unused]]`` instead of a C-style void cast.
+* When casting to `void` to suppress warnings about unused variables (as an
+ alternative to `[[maybe_unused]]`). Prefer C-style casts in this instance.
+ Note that if the variable is unused because it's used only in `assert`, use
+ `[[maybe_unused]]` instead of a C-style void cast.
* When casting between integral types (including enums that are not strongly-
typed), functional-style casts are permitted as an alternative to
- ``static_cast``.
+ `static_cast`.
-.. _static constructor:
+(static constructor)=
-Do not use Static Constructors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Do not use Static Constructors
Static constructors and destructors (e.g., global variables whose types have a
constructor or destructor) should not be added to the code base, and should be
removed wherever possible.
-Globals in different source files are initialized in an `arbitrary order
-<https://yosefk.com/c++fqa/ctors.html#fqa-10.12>`_, making the code more
+Globals in different source files are initialized in an [arbitrary order],
+making the code more
difficult to reason about.
+[arbitrary order]: https://yosefk.com/c++fqa/ctors.html#fqa-10.12
+
Static constructors have a negative impact on the launch time of programs that use
LLVM as a library. We would really like for there to be zero cost for linking
in an additional LLVM target or other library into an application, but static
constructors undermine this goal.
-Use of ``class`` and ``struct`` Keywords
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use of `class` and `struct` Keywords
-In C++, the ``class`` and ``struct`` keywords can be used almost
+In C++, the `class` and `struct` keywords can be used almost
interchangeably. The only difference is when they are used to declare a class:
-``class`` makes all members private by default while ``struct`` makes all
+`class` makes all members private by default while `struct` makes all
members public by default.
-* All declarations and definitions of a given ``class`` or ``struct`` must use
+* All declarations and definitions of a given `class` or `struct` must use
the same keyword. For example:
-.. code-block:: c++
+```c++
+// Avoid if `Example` is defined as a struct.
+class Example;
- // Avoid if `Example` is defined as a struct.
- class Example;
+// OK.
+struct Example;
- // OK.
- struct Example;
+struct Example { ... };
+```
- struct Example { ... };
+* `struct` should be used when *all* members are declared public.
-* ``struct`` should be used when *all* members are declared public.
+```c++
+// Avoid using `struct` here, use `class` instead.
+struct Foo {
+private:
+ int Data;
+public:
+ Foo() : Data(0) { }
+ int getData() const { return Data; }
+ void setData(int D) { Data = D; }
+};
-.. code-block:: c++
+// OK to use `struct`: all members are public.
+struct Bar {
+ int Data;
+ Bar() : Data(0) { }
+};
+```
- // Avoid using `struct` here, use `class` instead.
- struct Foo {
- private:
- int Data;
- public:
- Foo() : Data(0) { }
- int getData() const { return Data; }
- void setData(int D) { Data = D; }
- };
-
- // OK to use `struct`: all members are public.
- struct Bar {
- int Data;
- Bar() : Data(0) { }
- };
-
-Do not use Braced Initializer Lists to Call a Constructor
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Do not use Braced Initializer Lists to Call a Constructor
Starting from C++11 there is a "generalized initialization syntax" which allows
calling constructors using braced initializer lists. Do not use these to call
@@ -693,70 +671,67 @@ don't use a braced initializer list. Instead, use a braced initializer list
(without any type for temporaries) when doing aggregate initialization or
something notionally equivalent. Examples:
-.. code-block:: c++
+```c++
+class Foo {
+public:
+ // Construct a Foo by reading data from the disk in the whizbang format, ...
+ Foo(std::string filename);
- class Foo {
- public:
- // Construct a Foo by reading data from the disk in the whizbang format, ...
- Foo(std::string filename);
+ // Construct a Foo by looking up the Nth element of some global data ...
+ Foo(int N);
- // Construct a Foo by looking up the Nth element of some global data ...
- Foo(int N);
+ // ...
+};
- // ...
- };
+// The Foo constructor call is reading a file, don't use braces to call it.
+llvm::fill(foo, Foo("name"));
- // The Foo constructor call is reading a file, don't use braces to call it.
- llvm::fill(foo, Foo("name"));
-
- // The pair is being constructed like an aggregate, use braces.
- bar_map.insert({my_key, my_value});
+// The pair is being constructed like an aggregate, use braces.
+bar_map.insert({my_key, my_value});
+```
If you use a braced initializer list when initializing a variable, use an equals before the open curly brace:
-.. code-block:: c++
-
- int data[] = {0, 1, 2, 3};
+```c++
+int data[] = {0, 1, 2, 3};
+```
-Use ``auto`` Type Deduction to Make Code More Readable
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use `auto` Type Deduction to Make Code More Readable
-Some are advocating a policy of "almost always ``auto``" in C++11; however, LLVM
-uses a more moderate stance. Use ``auto`` if and only if it makes the code more
-readable or easier to maintain. Don't "almost always" use ``auto``, but do use
-``auto`` with initializers like ``cast<Foo>(...)`` or other places where the
-type is already obvious from the context. Another time when ``auto`` works well
+Some are advocating a policy of "almost always `auto`" in C++11; however, LLVM
+uses a more moderate stance. Use `auto` if and only if it makes the code more
+readable or easier to maintain. Don't "almost always" use `auto`, but do use
+`auto` with initializers like `cast<Foo>(...)` or other places where the
+type is already obvious from the context. Another time when `auto` works well
for these purposes is when the type would have been abstracted away anyway,
-often behind a container's typedef such as ``std::vector<T>::iterator``.
+often behind a container's typedef such as `std::vector<T>::iterator`.
Similarly, C++14 adds generic lambda expressions where parameter types can be
-``auto``. Use these where you would have used a template.
+`auto`. Use these where you would have used a template.
-Beware unnecessary copies with ``auto``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Beware unnecessary copies with `auto`
-The convenience of ``auto`` makes it easy to forget that its default behavior
-is a copy. Particularly in range-based ``for`` loops, careless copies are
+The convenience of `auto` makes it easy to forget that its default behavior
+is a copy. Particularly in range-based `for` loops, careless copies are
expensive.
-Use ``auto &`` for values and ``auto *`` for pointers unless you need to make a
+Use `auto &` for values and `auto *` for pointers unless you need to make a
copy.
-.. code-block:: c++
+```c++
+// Typically there's no reason to copy.
+for (const auto &Val : Container) observe(Val);
+for (auto &Val : Container) Val.change();
- // Typically there's no reason to copy.
- for (const auto &Val : Container) observe(Val);
- for (auto &Val : Container) Val.change();
+// Remove the reference if you really want a new copy.
+for (auto Val : Container) { Val.change(); saveSomewhere(Val); }
- // Remove the reference if you really want a new copy.
- for (auto Val : Container) { Val.change(); saveSomewhere(Val); }
+// Copy pointers, but make it clear that they're pointers.
+for (const auto *Ptr : Container) observe(*Ptr);
+for (auto *Ptr : Container) Ptr->change();
+```
- // Copy pointers, but make it clear that they're pointers.
- for (const auto *Ptr : Container) observe(*Ptr);
- for (auto *Ptr : Container) Ptr->change();
-
-Beware of non-determinism due to ordering of pointers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Beware of non-determinism due to ordering of pointers
In general, there is no relative ordering among pointers. As a result,
when unordered containers like sets and maps are used with pointer keys
@@ -767,31 +742,27 @@ debug the compiler.
In case an ordered result is expected, remember to
sort an unordered container before iteration. Or use ordered containers
-like ``vector``/``MapVector``/``SetVector`` if you want to iterate pointer
+like `vector`/`MapVector`/`SetVector` if you want to iterate pointer
keys.
-Beware of non-deterministic sorting order of equal elements
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Beware of non-deterministic sorting order of equal elements
-``std::sort`` uses a non-stable sorting algorithm in which the order of equal
-elements is not guaranteed to be preserved. Thus using ``std::sort`` for a
+`std::sort` uses a non-stable sorting algorithm in which the order of equal
+elements is not guaranteed to be preserved. Thus using `std::sort` for a
container having equal elements may result in non-deterministic behavior.
To uncover such instances of non-determinism, LLVM has introduced a new
-``llvm::sort`` wrapper function. For an ``EXPENSIVE_CHECKS`` build this will randomly
-shuffle the container before sorting. Default to using ``llvm::sort`` instead
-of ``std::sort``.
+`llvm::sort` wrapper function. For an `EXPENSIVE_CHECKS` build this will randomly
+shuffle the container before sorting. Default to using `llvm::sort` instead
+of `std::sort`.
-Style Issues
-============
+## Style Issues
-The High-Level Issues
----------------------
+### The High-Level Issues
-Self-contained Headers
-^^^^^^^^^^^^^^^^^^^^^^
+#### Self-contained Headers
-Header files should be self-contained (compile on their own) and end in ``.h``.
-Non-header files that are meant for inclusion should end in ``.inc`` and be
+Header files should be self-contained (compile on their own) and end in `.h`.
+Non-header files that are meant for inclusion should end in `.inc` and be
used sparingly.
All header files should be self-contained. Users and refactoring tools should
@@ -804,17 +775,16 @@ locations, such as the middle of another file. They might not use header
guards, and might not include their prerequisites. Name such files with the
.inc extension. Use sparingly, and prefer self-contained headers when possible.
-In general, a header should be implemented by one or more ``.cpp`` files. Each
-of these ``.cpp`` files should include the header that defines their interface
+In general, a header should be implemented by one or more `.cpp` files. Each
+of these `.cpp` files should include the header that defines their interface
first. This ensures that all of the dependencies of the header have been
properly added to the header itself, and are not implicit. System headers
should be included after user headers for a translation unit.
-Library Layering
-^^^^^^^^^^^^^^^^
+#### Library Layering
-A directory of header files (for example, ``include/llvm/Foo``) defines a
-library (``Foo``). One library (both
+A directory of header files (for example, `include/llvm/Foo`) defines a
+library (`Foo`). One library (both
its headers and implementation) should only use things from the libraries
listed in its dependencies.
@@ -829,27 +799,26 @@ doesn't enforce header file circular dependencies created by inline functions.
A good way to answer the "is this layered correctly" would be to consider
whether a Unix linker would succeed at linking the program if all inline
functions were defined out-of-line. (& for all valid orderings of dependencies
-- since linking resolution is linear, it's possible that some implicit
+— since linking resolution is linear, it's possible that some implicit
dependencies can sneak through: A depends on B and C, so valid orderings are
"C B A" or "B C A", in both cases the explicit dependencies come before their
use. But in the first case, B could still link successfully if it implicitly
depended on C, or the opposite in the second case)
-.. _minimal list of #includes:
+(minimal list of #includes)=
-``#include`` as Little as Possible
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### `#include` as Little as Possible
-``#include`` hurts compile time performance. Don't do it unless you have to,
+`#include` hurts compile time performance. Don't do it unless you have to,
especially in header files.
But wait! Sometimes you need to have the definition of a class to use it, or to
-inherit from it. In these cases go ahead and ``#include`` that header file. Be
+inherit from it. In these cases go ahead and `#include` that header file. Be
aware, however, that there are many cases where you don't need to have the full
definition of a class. If you are using a pointer or reference to a class, you
don't need the header file. If you are simply returning a class instance from a
prototyped function or method, you don't need it. In fact, for most cases, you
-simply don't need the definition of a class. And not ``#include``\ing speeds up
+simply don't need the definition of a class. And not `#include`ing speeds up
compilation.
It is easy to try to go overboard on this recommendation, however. You
@@ -860,11 +829,10 @@ header, make sure to include your module header **first** in the implementation
file (as mentioned above). This way there won't be any hidden dependencies that
you'll find out about later.
-Keep "Internal" Headers Private
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Keep "Internal" Headers Private
Many modules have a complex implementation that causes them to use more than one
-implementation (``.cpp``) file. It is often tempting to put the internal
+implementation (`.cpp`) file. It is often tempting to put the internal
communication interface (helper classes, extra functions, etc) in the public
module header file. Don't do this!
@@ -872,58 +840,57 @@ If you really need to do something like this, put a private header file in the
same directory as the source files, and include it locally. This ensures that
your private interface remains private and undisturbed by outsiders.
-.. note::
-
- It's okay to put extra implementation methods in a public class itself. Just
- make them private (or protected) and all is well.
+```{note}
+It's okay to put extra implementation methods in a public class itself. Just
+make them private (or protected) and all is well.
+```
-Use Namespace Qualifiers to Define Previously Declared Symbols
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use Namespace Qualifiers to Define Previously Declared Symbols
When providing an out-of-line definition for various symbols (variables,
functions, opaque classes) in a source file, do not open namespace blocks in the
source file. Instead, use namespace qualifiers to help ensure that your
definition matches an existing declaration. Do this:
-.. code-block:: c++
-
- // Foo.h
- namespace llvm {
- extern int FooVal;
- int foo(const char *s);
+```c++
+// Foo.h
+namespace llvm {
+extern int FooVal;
+int foo(const char *s);
- namespace detail {
- class FooImpl;
- } // namespace detail
- } // namespace llvm
+namespace detail {
+class FooImpl;
+} // namespace detail
+} // namespace llvm
- // Foo.cpp
- #include "Foo.h"
- using namespace llvm;
+// Foo.cpp
+#include "Foo.h"
+using namespace llvm;
- int llvm::FooVal;
+int llvm::FooVal;
- int llvm::foo(const char *s) {
- // ...
- }
+int llvm::foo(const char *s) {
+ // ...
+}
- class detail::FooImpl {
- // ...
- }
+class detail::FooImpl {
+ // ...
+}
+```
Doing this helps to avoid bugs where the definition does not match the
declaration from the header. For example, the following C++ code defines a new
-overload of ``llvm::foo`` instead of providing a definition for the existing
+overload of `llvm::foo` instead of providing a definition for the existing
function declared in the header:
-.. code-block:: c++
-
- // Foo.cpp
- #include "Foo.h"
- namespace llvm {
- int foo(char *s) { // Mismatch between "const char *" and "char *"
- }
- } // namespace llvm
+```c++
+// Foo.cpp
+#include "Foo.h"
+namespace llvm {
+int foo(char *s) { // Mismatch between "const char *" and "char *"
+}
+} // namespace llvm
+```
This error will not be caught until the build is nearly complete, when the
linker fails to find a definition for any uses of the original function. If the
@@ -933,34 +900,33 @@ been caught immediately when the definition was compiled.
Class method implementations must already name the class and new overloads
cannot be introduced out of line, so this recommendation does not apply to them.
-.. _early exits:
+(early exits)=
-Use Early Exits and ``continue`` to Simplify Code
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use Early Exits and `continue` to Simplify Code
When reading code, keep in mind how much state and how many previous decisions
have to be remembered by the reader to understand a block of code. Aim to
reduce indentation where possible when it doesn't make it more difficult to
understand the code. One great way to do this is by making use of early exits
-and the ``continue`` keyword in long loops. Consider this code that does not
+and the `continue` keyword in long loops. Consider this code that does not
use an early exit:
-.. code-block:: c++
-
- Value *doSomething(Instruction *I) {
- if (!I->isTerminator() &&
- I->hasOneUse() && doOtherThing(I)) {
- ... some long code ....
- }
-
- return 0;
+```c++
+Value *doSomething(Instruction *I) {
+ if (!I->isTerminator() &&
+ I->hasOneUse() && doOtherThing(I)) {
+ ... some long code ....
}
-This code has several problems if the body of the ``'if'`` is large. When
+ return 0;
+}
+```
+
+This code has several problems if the body of the `'if'` is large. When
you're looking at the top of the function, it isn't immediately clear that this
*only* does interesting things with non-terminator instructions, and only
applies to things with the other predicates. Second, it is relatively difficult
-to describe (in comments) why these predicates are important because the ``if``
+to describe (in comments) why these predicates are important because the `if`
statement makes it difficult to lay out the comments. Third, when you're deep
within the body of the code, it is indented an extra level. Finally, when
reading the top of the function, it isn't clear what the result is if the
@@ -969,191 +935,189 @@ it returns null.
It is much preferred to format the code like this:
-.. code-block:: c++
-
- Value *doSomething(Instruction *I) {
- // Terminators never need 'something' done to them because ...
- if (I->isTerminator())
- return 0;
+```c++
+Value *doSomething(Instruction *I) {
+ // Terminators never need 'something' done to them because ...
+ if (I->isTerminator())
+ return 0;
- // We conservatively avoid transforming instructions with multiple uses
- // because goats like cheese.
- if (!I->hasOneUse())
- return 0;
+ // We conservatively avoid transforming instructions with multiple uses
+ // because goats like cheese.
+ if (!I->hasOneUse())
+ return 0;
- // This is really just here for example.
- if (!doOtherThing(I))
- return 0;
+ // This is really just here for example.
+ if (!doOtherThing(I))
+ return 0;
- ... some long code ....
- }
+ ... some long code ....
+}
+```
-This fixes these problems. A similar problem frequently happens in ``for``
+This fixes these problems. A similar problem frequently happens in `for`
loops. A silly example is something like this:
-.. code-block:: c++
-
- for (Instruction &I : BB) {
- if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
- Value *LHS = BO->getOperand(0);
- Value *RHS = BO->getOperand(1);
- if (LHS != RHS) {
- ...
- }
+```c++
+for (Instruction &I : BB) {
+ if (auto *BO = dyn_cast<BinaryOperator>(&I)) {
+ Value *LHS = BO->getOperand(0);
+ Value *RHS = BO->getOperand(1);
+ if (LHS != RHS) {
+ ...
}
}
+}
+```
When you have very, very small loops, this sort of structure is fine. But if it
exceeds more than 10-15 lines, it becomes difficult for people to read and
understand at a glance. The problem with this sort of code is that it gets very
nested very quickly. This means that the reader of the code has to keep a lot of
context in their brain to remember what is going immediately on in the loop,
-because they don't know if/when the ``if`` conditions will have ``else``\s etc.
+because they don't know if/when the `if` conditions will have `else`s etc.
It is strongly preferred to structure the loop like this:
-.. code-block:: c++
+```c++
+for (Instruction &I : BB) {
+ auto *BO = dyn_cast<BinaryOperator>(&I);
+ if (!BO) continue;
- for (Instruction &I : BB) {
- auto *BO = dyn_cast<BinaryOperator>(&I);
- if (!BO) continue;
-
- Value *LHS = BO->getOperand(0);
- Value *RHS = BO->getOperand(1);
- if (LHS == RHS) continue;
+ Value *LHS = BO->getOperand(0);
+ Value *RHS = BO->getOperand(1);
+ if (LHS == RHS) continue;
- ...
- }
+ ...
+}
+```
This has all the benefits of using early exits for functions: it reduces the nesting
of the loop, it makes it easier to describe why the conditions are true, and it
-makes it obvious to the reader that there is no ``else`` coming up that they
+makes it obvious to the reader that there is no `else` coming up that they
have to push context into their brain for. If a loop is large, this can be a
big understandability win.
-Don't use ``else`` after a ``return``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Don't use `else` after a `return`
For similar reasons as above (reduction of indentation and easier reading), please
-do not use ``'else'`` or ``'else if'`` after something that interrupts control
-flow --- like ``return``, ``break``, ``continue``, ``goto``, etc. For example:
-
-.. code-block:: c++
-
- case 'J': {
- if (Signed) {
- Type = Context.getsigjmp_bufType();
- if (Type.isNull()) {
- Error = ASTContext::GE_Missing_sigjmp_buf;
- return QualType();
- } else {
- break; // Unnecessary.
- }
+do not use `'else'` or `'else if'` after something that interrupts control
+flow --- like `return`, `break`, `continue`, `goto`, etc. For example:
+
+```c++
+case 'J': {
+ if (Signed) {
+ Type = Context.getsigjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_sigjmp_buf;
+ return QualType();
+ } else {
+ break; // Unnecessary.
+ }
+ } else {
+ Type = Context.getjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_jmp_buf;
+ return QualType();
} else {
- Type = Context.getjmp_bufType();
- if (Type.isNull()) {
- Error = ASTContext::GE_Missing_jmp_buf;
- return QualType();
- } else {
- break; // Unnecessary.
- }
+ break; // Unnecessary.
}
}
+}
+```
It is better to write it like this:
-.. code-block:: c++
-
- case 'J':
- if (Signed) {
- Type = Context.getsigjmp_bufType();
- if (Type.isNull()) {
- Error = ASTContext::GE_Missing_sigjmp_buf;
- return QualType();
- }
- } else {
- Type = Context.getjmp_bufType();
- if (Type.isNull()) {
- Error = ASTContext::GE_Missing_jmp_buf;
- return QualType();
- }
+```c++
+case 'J':
+ if (Signed) {
+ Type = Context.getsigjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_sigjmp_buf;
+ return QualType();
}
- break;
-
-Or better yet (in this case) as:
-
-.. code-block:: c++
-
- case 'J':
- if (Signed)
- Type = Context.getsigjmp_bufType();
- else
- Type = Context.getjmp_bufType();
-
+ } else {
+ Type = Context.getjmp_bufType();
if (Type.isNull()) {
- Error = Signed ? ASTContext::GE_Missing_sigjmp_buf :
- ASTContext::GE_Missing_jmp_buf;
+ Error = ASTContext::GE_Missing_jmp_buf;
return QualType();
}
- break;
+ }
+ break;
+```
+
+Or better yet (in this case) as:
+
+```c++
+case 'J':
+ if (Signed)
+ Type = Context.getsigjmp_bufType();
+ else
+ Type = Context.getjmp_bufType();
+
+ if (Type.isNull()) {
+ Error = Signed ? ASTContext::GE_Missing_sigjmp_buf :
+ ASTContext::GE_Missing_jmp_buf;
+ return QualType();
+ }
+ break;
+```
The idea is to reduce indentation and the amount of code you have to keep track
of when reading the code.
-Note: this advice does not apply to a ``constexpr if`` statement. The
-substatement of the ``else`` clause may be a discarded statement, so removing
-the ``else`` can cause unexpected template instantiations. Thus, the following
+Note: this advice does not apply to a `constexpr if` statement. The
+substatement of the `else` clause may be a discarded statement, so removing
+the `else` can cause unexpected template instantiations. Thus, the following
example is correct:
-.. code-block:: c++
+```c++
+template<typename T>
+static constexpr bool VarTempl = true;
- template<typename T>
- static constexpr bool VarTempl = true;
+template<typename T>
+int func() {
+ if constexpr (VarTempl<T>)
+ return 1;
+ else
+ static_assert(!VarTempl<T>);
+}
+```
- template<typename T>
- int func() {
- if constexpr (VarTempl<T>)
- return 1;
- else
- static_assert(!VarTempl<T>);
- }
-
-Turn Predicate Loops into Predicate Functions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Turn Predicate Loops into Predicate Functions
It is very common to write small loops that just compute a boolean value. There
are a number of ways that people commonly write these, but an example of this
sort of thing is:
-.. code-block:: c++
-
- bool FoundFoo = false;
- for (unsigned I = 0, E = BarList.size(); I != E; ++I)
- if (BarList[I]->isFoo()) {
- FoundFoo = true;
- break;
- }
-
- if (FoundFoo) {
- ...
+```c++
+bool FoundFoo = false;
+for (unsigned I = 0, E = BarList.size(); I != E; ++I)
+ if (BarList[I]->isFoo()) {
+ FoundFoo = true;
+ break;
}
+if (FoundFoo) {
+ ...
+}
+```
+
Instead of this sort of loop, we prefer to use a predicate function (which may
-be `static`_) that uses `early exits`_:
+be {ref}`static <static>`) that uses {ref}`early exits <early exits>`:
-.. code-block:: c++
+```c++
+/// \returns true if the specified list has an element that is a foo.
+static bool containsFoo(const std::vector<Bar*> &List) {
+ for (unsigned I = 0, E = List.size(); I != E; ++I)
+ if (List[I]->isFoo())
+ return true;
+ return false;
+}
+...
- /// \returns true if the specified list has an element that is a foo.
- static bool containsFoo(const std::vector<Bar*> &List) {
- for (unsigned I = 0, E = List.size(); I != E; ++I)
- if (List[I]->isFoo())
- return true;
- return false;
- }
+if (containsFoo(BarList)) {
...
-
- if (containsFoo(BarList)) {
- ...
- }
+}
+```
There are many reasons for doing this: it reduces indentation and factors out
code which can often be shared by other code that checks for the same predicate.
@@ -1165,11 +1129,9 @@ being faced with the in-line details of how we check to see if the BarList
contains a foo, we can trust the function name and continue reading with better
locality.
-The Low-Level Issues
---------------------
+### The Low-Level Issues
-Name Types, Functions, Variables, and Enumerators Properly
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Name Types, Functions, Variables, and Enumerators Properly
Poorly-chosen names can mislead the reader and cause bugs. We cannot stress
enough how important it is to use *descriptive* names. Pick names that match
@@ -1178,74 +1140,73 @@ abbreviations unless they are well known. After picking a good name, make sure
to use consistent capitalization for the name, as inconsistency requires clients
to either memorize the APIs or to look it up to find the exact spelling.
-In general, names should be in camel case (e.g. ``TextFileReader`` and
-``isLValue()``). Different kinds of declarations have different rules:
+In general, names should be in camel case (e.g. `TextFileReader` and
+`isLValue()`). Different kinds of declarations have different rules:
* **Type names** (including classes, structs, enums, typedefs, etc) should be
- nouns and start with an upper-case letter (e.g. ``TextFileReader``).
+ nouns and start with an upper-case letter (e.g. `TextFileReader`).
* **Variable names** should be nouns (as they represent state). The name should
- be camel case, and start with an upper-case letter (e.g. ``Leader`` or
- ``Boats``).
+ be camel case, and start with an upper-case letter (e.g. `Leader` or
+ `Boats`).
* **Function names** should be verb phrases (as they represent actions), and
command-like function should be imperative. The name should be camel case,
- and start with a lowercase letter (e.g. ``openFile()`` or ``isFoo()``).
+ and start with a lowercase letter (e.g. `openFile()` or `isFoo()`).
-* **Enum declarations** (e.g. ``enum Foo {...}``) are types, so they should
+* **Enum declarations** (e.g. `enum Foo {...}`) are types, so they should
follow the naming conventions for types. A common use for enums is as a
discriminator for a union, or an indicator of a subclass. When an enum is
- used for something like this, it should have a ``Kind`` suffix
- (e.g. ``ValueKind``).
+ used for something like this, it should have a `Kind` suffix
+ (e.g. `ValueKind`).
-* **Enumerators** (e.g. ``enum { Foo, Bar }``) and **public member variables**
+* **Enumerators** (e.g. `enum { Foo, Bar }`) and **public member variables**
should start with an upper-case letter, just like types. Unless the
enumerators are defined in their own small namespace or inside a class,
enumerators should have a prefix corresponding to the enum declaration name.
- For example, ``enum ValueKind { ... };`` may contain enumerators like
- ``VK_Argument``, ``VK_BasicBlock``, etc. Enumerators that are just
+ For example, `enum ValueKind { ... };` may contain enumerators like
+ `VK_Argument`, `VK_BasicBlock`, etc. Enumerators that are just
convenience constants are exempt from the requirement for a prefix. For
instance:
- .. code-block:: c++
-
- enum {
- MaxSize = 42,
- Density = 12
- };
+ ```c++
+ enum {
+ MaxSize = 42,
+ Density = 12
+ };
+ ```
As an exception, classes that mimic STL classes can have member names in STL's
-style of lowercase words separated by underscores (e.g. ``begin()``,
-``push_back()``, and ``empty()``). Classes that provide multiple
-iterators should add a singular prefix to ``begin()`` and ``end()``
-(e.g. ``global_begin()`` and ``use_begin()``).
+style of lowercase words separated by underscores (e.g. `begin()`,
+`push_back()`, and `empty()`). Classes that provide multiple
+iterators should add a singular prefix to `begin()` and `end()`
+(e.g. `global_begin()` and `use_begin()`).
Here are some examples:
-.. code-block:: c++
-
- class VehicleMaker {
- ...
- Factory<Tire> F; // Avoid: a non-descriptive abbreviation.
- Factory<Tire> Factory; // Better: more descriptive.
- Factory<Tire> TireFactory; // Even better: if VehicleMaker has more than one
- // kind of factories.
- };
-
- Vehicle makeVehicle(VehicleType Type) {
- VehicleMaker M; // Might be OK if scope is small.
- Tire Tmp1 = M.makeTire(); // Avoid: 'Tmp1' provides no information.
- Light Headlight = M.makeLight("head"); // Good: descriptive.
- ...
- }
+```c++
+class VehicleMaker {
+ ...
+ Factory<Tire> F; // Avoid: a non-descriptive abbreviation.
+ Factory<Tire> Factory; // Better: more descriptive.
+ Factory<Tire> TireFactory; // Even better: if VehicleMaker has more than one
+ // kind of factories.
+};
+
+Vehicle makeVehicle(VehicleType Type) {
+ VehicleMaker M; // Might be OK if scope is small.
+ Tire Tmp1 = M.makeTire(); // Avoid: 'Tmp1' provides no information.
+ Light Headlight = M.makeLight("head"); // Good: descriptive.
+ ...
+}
+```
-Assert Liberally
-^^^^^^^^^^^^^^^^
+#### Assert Liberally
-Use the "``assert``" macro to its fullest. Check all of your preconditions and
+Use the "`assert`" macro to its fullest. Check all of your preconditions and
assumptions. You never know when a bug (not necessarily even yours) might be
caught early by an assertion, which reduces debugging time dramatically. The
-"``<cassert>``" header file is probably already included by the header files you
+"`<cassert>`" header file is probably already included by the header files you
are using, so it doesn't cost anything to use it.
To further assist with debugging, make sure to put some kind of error message in
@@ -1253,147 +1214,144 @@ the assertion statement, which is printed if the assertion is tripped. This
helps the poor debugger make sense of why an assertion is being made and
enforced, and hopefully what to do about it. Here is one complete example:
-.. code-block:: c++
-
- inline Value *getOperand(unsigned I) {
- assert(I < Operands.size() && "getOperand() out of range!");
- return Operands[I];
- }
+```c++
+inline Value *getOperand(unsigned I) {
+ assert(I < Operands.size() && "getOperand() out of range!");
+ return Operands[I];
+}
+```
Here are more examples:
-.. code-block:: c++
-
- assert(Ty->isPointerType() && "Can't allocate a non-pointer type!");
+```c++
+assert(Ty->isPointerType() && "Can't allocate a non-pointer type!");
- assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
+assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
- assert(idx < getNumSuccessors() && "Successor # out of range!");
+assert(idx < getNumSuccessors() && "Successor # out of range!");
- assert(V1.getType() == V2.getType() && "Constant types must be identical!");
+assert(V1.getType() == V2.getType() && "Constant types must be identical!");
- assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");
+assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");
+```
You get the idea.
In the past, asserts were used to indicate a piece of code that should not be
reached. These were typically of the form:
-.. code-block:: c++
-
- assert(0 && "Invalid radix for integer literal");
+```c++
+assert(0 && "Invalid radix for integer literal");
+```
This has a few issues, the main one being that some compilers might not
understand the assertion, or warn about a missing return in builds where
assertions are compiled out.
-Today, we have something much better: ``llvm_unreachable``:
+Today, we have something much better: `llvm_unreachable`:
-.. code-block:: c++
-
- llvm_unreachable("Invalid radix for integer literal");
+```c++
+llvm_unreachable("Invalid radix for integer literal");
+```
When assertions are enabled, this will print the message if it's ever reached
and then exit the program. When assertions are disabled (i.e. in release
-builds), ``llvm_unreachable`` becomes a hint to compilers to skip generating
+builds), `llvm_unreachable` becomes a hint to compilers to skip generating
code for this branch. If the compiler does not support this, it will fall back
to the "abort" implementation.
-Use ``llvm_unreachable`` to mark a specific point in code that should never be
+Use `llvm_unreachable` to mark a specific point in code that should never be
reached. This is especially desirable for addressing warnings about unreachable
branches, etc., but can be used whenever reaching a particular code path is
unconditionally a bug (not originating from user input; see below) of some kind.
-Use of ``assert`` should always include a testable predicate (as opposed to
-``assert(false)``).
+Use of `assert` should always include a testable predicate (as opposed to
+`assert(false)`).
If the error condition can be triggered by user input then the
-recoverable error mechanism described in :doc:`ProgrammersManual` should be
-used instead. In cases where this is not practical, ``report_fatal_error`` may
+recoverable error mechanism described in {doc}`ProgrammersManual` should be
+used instead. In cases where this is not practical, `report_fatal_error` may
be used.
Another issue is that values used only by assertions will produce an "unused
value" warning when assertions are disabled. For example, this code will warn:
-.. code-block:: c++
-
- unsigned Size = V.size();
- assert(Size > 42 && "Vector smaller than it should be");
+```c++
+unsigned Size = V.size();
+assert(Size > 42 && "Vector smaller than it should be");
- bool NewToSet = Myset.insert(Value);
- assert(NewToSet && "The value shouldn't be in the set yet");
+bool NewToSet = Myset.insert(Value);
+assert(NewToSet && "The value shouldn't be in the set yet");
+```
These are two interesting different cases. In the first case, the call to
-``V.size()`` is only useful for the assert, and we don't want it executed when
+`V.size()` is only useful for the assert, and we don't want it executed when
assertions are disabled. Code like this should move the call into the assert
itself. In the second case, the side effects of the call must happen whether
the assert is enabled or not. In this case, the value should be defined using
-the ``[[maybe_unused]]`` attribute to suppress the warning. To be specific, it is
+the `[[maybe_unused]]` attribute to suppress the warning. To be specific, it is
preferred to write the code like this:
-.. code-block:: c++
-
- assert(V.size() > 42 && "Vector smaller than it should be");
+```c++
+assert(V.size() > 42 && "Vector smaller than it should be");
- [[maybe_unused]] bool NewToSet = Myset.insert(Value);
- assert(NewToSet && "The value shouldn't be in the set yet");
+[[maybe_unused]] bool NewToSet = Myset.insert(Value);
+assert(NewToSet && "The value shouldn't be in the set yet");
+```
-In C code where ``[[maybe_unused]]`` is not supported, use ``void`` cast to
+In C code where `[[maybe_unused]]` is not supported, use `void` cast to
suppress an unused variable warning as follows:
-.. code-block:: c
+```c
+LLVMValueRef Value = LLVMMetadataAsValue(Context, NodeMD);
+assert(LLVMIsAValueAsMetadata(Value) != NULL);
+(void)Value;
+```
- LLVMValueRef Value = LLVMMetadataAsValue(Context, NodeMD);
- assert(LLVMIsAValueAsMetadata(Value) != NULL);
- (void)Value;
-
-Do Not Use ``using namespace std``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Do Not Use `using namespace std`
In LLVM, we prefer to explicitly prefix all identifiers from the standard
-namespace with an "``std::``" prefix, rather than rely on "``using namespace
-std;``".
+namespace with an "`std::`" prefix, rather than rely on "`using namespace
+std;`".
-In header files, adding a ``'using namespace XXX'`` directive pollutes the
-namespace of any source file that ``#include``\s the header, creating
+In header files, adding a `'using namespace XXX'` directive pollutes the
+namespace of any source file that `#include`s the header, creating
maintenance issues.
-In implementation files (e.g. ``.cpp`` files), the rule is more of a stylistic
+In implementation files (e.g. `.cpp` files), the rule is more of a stylistic
rule, but is still important. Basically, using explicit namespace prefixes
makes the code **clearer**, because it is immediately obvious what facilities
are being used and where they are coming from. And **more portable**, because
namespace clashes cannot occur between LLVM code and other namespaces. The
portability rule is important because different standard library implementations
expose different symbols (potentially ones they shouldn't), and future revisions
-to the C++ standard will add more symbols to the ``std`` namespace. As such, we
-never use ``'using namespace std;'`` in LLVM.
+to the C++ standard will add more symbols to the `std` namespace. As such, we
+never use `'using namespace std;'` in LLVM.
-The exception to the general rule (i.e. it's not an exception for the ``std``
+The exception to the general rule (i.e. it's not an exception for the `std`
namespace) is for implementation files. For example, all of the code in the
LLVM project implements code that lives in the 'llvm' namespace. As such, it is
-ok, and actually clearer, for the ``.cpp`` files to have a ``'using namespace
-llvm;'`` directive at the top, after the ``#include``\s. This reduces
+ok, and actually clearer, for the `.cpp` files to have a `'using namespace
+llvm;'` directive at the top, after the `#include`s. This reduces
indentation in the body of the file for source editors that indent based on
braces, and keeps the conceptual context cleaner. The general form of this rule
-is that any ``.cpp`` file that implements code in any namespace may use that
+is that any `.cpp` file that implements code in any namespace may use that
namespace (and its parents'), but should not use any others.
-Provide a Virtual Method Anchor for Classes in Headers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Provide a Virtual Method Anchor for Classes in Headers
If a class is defined in a header file and has a vtable (either it has virtual
methods or it derives from classes with virtual methods), it must always have at
least one out-of-line virtual method in the class. Without this, the compiler
-will copy the vtable and RTTI into every ``.o`` file that ``#include``\s the
-header, bloating ``.o`` file sizes and increasing link times.
+will copy the vtable and RTTI into every `.o` file that `#include`s the
+header, bloating `.o` file sizes and increasing link times.
-Don't use default labels in fully covered switches over enumerations
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Don't use default labels in fully covered switches over enumerations
-``-Wswitch`` warns if a switch, without a default label, over an enumeration
+`-Wswitch` warns if a switch, without a default label, over an enumeration
does not cover every enumeration value. If you write a default label on a fully
-covered switch over an enumeration then the ``-Wswitch`` warning won't fire
+covered switch over an enumeration then the `-Wswitch` warning won't fire
when new elements are added to that enumeration. To help avoid adding these
-kinds of defaults, Clang has the warning ``-Wcovered-switch-default`` which is
+kinds of defaults, Clang has the warning `-Wcovered-switch-default` which is
off by default but turned on when building LLVM with a version of Clang that
supports the warning.
@@ -1401,53 +1359,51 @@ A knock-on effect of this stylistic requirement is that when building LLVM with
GCC you may get warnings related to "control may reach end of non-void function"
if you return from each case of a covered switch-over-enum because GCC assumes
that the enum expression may take any representable value, not just those of
-individual enumerators. To suppress this warning, use ``llvm_unreachable`` after
+individual enumerators. To suppress this warning, use `llvm_unreachable` after
the switch.
-Use range-based ``for`` loops wherever possible
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use range-based `for` loops wherever possible
-The introduction of range-based ``for`` loops in C++11 means that explicit
-manipulation of iterators is rarely necessary. We use range-based ``for``
+The introduction of range-based `for` loops in C++11 means that explicit
+manipulation of iterators is rarely necessary. We use range-based `for`
loops wherever possible for all newly added code. For example:
-.. code-block:: c++
-
- BasicBlock *BB = ...
- for (Instruction &I : *BB)
- ... use I ...
+```c++
+BasicBlock *BB = ...
+for (Instruction &I : *BB)
+ ... use I ...
+```
-Usage of ``std::for_each()``/``llvm::for_each()`` functions is discouraged,
+Usage of `std::for_each()`/`llvm::for_each()` functions is discouraged,
unless the callable object already exists.
-Don't evaluate ``end()`` every time through a loop
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Don't evaluate `end()` every time through a loop
-In cases where range-based ``for`` loops can't be used and it is necessary
+In cases where range-based `for` loops can't be used and it is necessary
to write an explicit iterator-based loop, pay close attention to whether
-``end()`` is re-evaluated on each loop iteration. One common mistake is to
+`end()` is re-evaluated on each loop iteration. One common mistake is to
write a loop in this style:
-.. code-block:: c++
+```c++
+BasicBlock *BB = ...
+for (auto I = BB->begin(); I != BB->end(); ++I)
+ ... use I ...
+```
- BasicBlock *BB = ...
- for (auto I = BB->begin(); I != BB->end(); ++I)
- ... use I ...
-
-The problem with this construct is that it evaluates "``BB->end()``" every time
+The problem with this construct is that it evaluates "`BB->end()`" every time
through the loop. Instead of writing the loop like this, we strongly prefer
loops to be written so that they evaluate it once before the loop starts. A
convenient way to do this is like so:
-.. code-block:: c++
-
- BasicBlock *BB = ...
- for (auto I = BB->begin(), E = BB->end(); I != E; ++I)
- ... use I ...
+```c++
+BasicBlock *BB = ...
+for (auto I = BB->begin(), E = BB->end(); I != E; ++I)
+ ... use I ...
+```
The observant may quickly point out that these two loops may have different
semantics: if the container (a basic block in this case) is being mutated, then
-"``BB->end()``" may change its value every time through the loop and the second
+"`BB->end()`" may change its value every time through the loop and the second
loop may not in fact be correct. If you actually do depend on this behavior,
please write the loop in the first form and add a comment indicating that you
did it intentionally.
@@ -1457,7 +1413,7 @@ form has two problems. First, it may be less efficient than evaluating it at the
start of the loop. In this case, the cost is probably minor --- a few extra
loads every time through the loop. However, if the base expression is more
complex, then the cost can rise quickly. I've seen loops where the end
-expression was actually something like: "``SomeMap[X]->end()``" and map lookups
+expression was actually something like: "`SomeMap[X]->end()`" and map lookups
really aren't cheap. By writing it in the second form consistently, you
eliminate the issue entirely and don't even have to think about it.
@@ -1471,112 +1427,105 @@ understand what it does.
While the second form of the loop is a few extra keystrokes, we do strongly
prefer it.
-``#include <iostream>`` is Forbidden
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### `#include <iostream>` is Forbidden
-The use of ``#include <iostream>`` in library files is hereby **forbidden**,
-because many common implementations transparently inject a `static constructor`_
+The use of `#include <iostream>` in library files is hereby **forbidden**,
+because many common implementations transparently inject a {ref}`static constructor <static constructor>`
into every translation unit that includes it.
-Note that using the other stream headers (``<sstream>`` for example) is not
-problematic in this regard --- just ``<iostream>``. However, ``raw_ostream``
+Note that using the other stream headers (`<sstream>` for example) is not
+problematic in this regard --- just `<iostream>`. However, `raw_ostream`
provides various APIs that are better performing for almost every use than
-``std::ostream`` style APIs.
-
-.. note::
+`std::ostream` style APIs.
- New code should always use `raw_ostream`_ for writing, or the
- ``llvm::MemoryBuffer`` API for reading files.
+```{note}
+New code should always use {ref}`raw_ostream <raw_ostream>` for writing, or the
+`llvm::MemoryBuffer` API for reading files.
+```
-.. _raw_ostream:
+(raw_ostream)=
-Use ``raw_ostream``
-^^^^^^^^^^^^^^^^^^^
+#### Use `raw_ostream`
LLVM includes a lightweight, simple, and efficient stream implementation in
-``llvm/Support/raw_ostream.h``, which provides all of the common features of
-``std::ostream``. All new code should use ``raw_ostream`` instead of
-``ostream``.
+`llvm/Support/raw_ostream.h`, which provides all of the common features of
+`std::ostream`. All new code should use `raw_ostream` instead of
+`ostream`.
-Unlike ``std::ostream``, ``raw_ostream`` is not a template and can be forward
-declared as ``class raw_ostream``. Public headers should generally not include
-the ``raw_ostream`` header, but use forward declarations and constant references
-to ``raw_ostream`` instances.
+Unlike `std::ostream`, `raw_ostream` is not a template and can be forward
+declared as `class raw_ostream`. Public headers should generally not include
+the `raw_ostream` header, but use forward declarations and constant references
+to `raw_ostream` instances.
-Avoid ``std::endl``
-^^^^^^^^^^^^^^^^^^^
+#### Avoid `std::endl`
-The ``std::endl`` modifier, when used with ``iostreams`` outputs a newline to
+The `std::endl` modifier, when used with `iostreams` outputs a newline to
the output stream specified. In addition to doing this, however, it also
flushes the output stream. In other words, these are equivalent:
-.. code-block:: c++
-
- std::cout << std::endl;
- std::cout << '\n' << std::flush;
+```c++
+std::cout << std::endl;
+std::cout << '\n' << std::flush;
+```
Most of the time, you probably have no reason to flush the output stream, so
-it's better to use a literal ``'\n'``.
+it's better to use a literal `'\n'`.
-Don't use ``inline`` when defining a function in a class definition
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Don't use `inline` when defining a function in a class definition
A member function defined in a class definition is implicitly inline, so don't
-put the ``inline`` keyword in this case.
+put the `inline` keyword in this case.
Don't:
-.. code-block:: c++
-
- class Foo {
- public:
- inline void bar() {
- // ...
- }
- };
+```c++
+class Foo {
+public:
+ inline void bar() {
+ // ...
+ }
+};
+```
Do:
-.. code-block:: c++
-
- class Foo {
- public:
- void bar() {
- // ...
- }
- };
+```c++
+class Foo {
+public:
+ void bar() {
+ // ...
+ }
+};
+```
-Microscopic Details
--------------------
+### Microscopic Details
This section describes preferred low-level formatting guidelines along with
reasoning on why we prefer them.
-Spaces Before Parentheses
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Spaces Before Parentheses
Put a space before an open parenthesis only in control flow statements, but not
in normal function call expressions and function-like macros. For example:
-.. code-block:: c++
-
- if (X) ...
- for (I = 0; I != 100; ++I) ...
- while (LLVMRocks) ...
+```c++
+if (X) ...
+for (I = 0; I != 100; ++I) ...
+while (LLVMRocks) ...
- somefunc(42);
- assert(3 != 4 && "laws of math are failing me");
+somefunc(42);
+assert(3 != 4 && "laws of math are failing me");
- A = foo(42, 92) + bar(X);
+A = foo(42, 92) + bar(X);
+```
The reason for doing this is not completely arbitrary. This style makes control
flow operators stand out more, and makes expressions flow better.
-Prefer Preincrement
-^^^^^^^^^^^^^^^^^^^
+#### Prefer Preincrement
-Hard fast rule: Preincrement (``++X``) may be no slower than postincrement
-(``X++``) and could very well be a lot faster than it. Use preincrementation
+Hard fast rule: Preincrement (`++X`) may be no slower than postincrement
+(`X++`) and could very well be a lot faster than it. Use preincrementation
whenever possible.
The semantics of postincrement include making a copy of the value being
@@ -1587,36 +1536,35 @@ copying an iterator could invoke the copy ctor's of these as well). In general,
get in the habit of always using preincrement, and you won't have a problem.
-Namespace Indentation
-^^^^^^^^^^^^^^^^^^^^^
+#### Namespace Indentation
In general, we strive to reduce indentation wherever possible. This is useful
-because we want code to `fit into 80 columns`_ without excessive wrapping, but
+because we want code to {ref}`fit into 80 columns <fit into 80 columns>` without excessive wrapping, but
also because it makes it easier to understand the code. To facilitate this and
avoid some insanely deep nesting on occasion, don't indent namespaces. If it
helps readability, feel free to add a comment indicating what namespace is
-being closed by a ``}``. For example:
+being closed by a `}`. For example:
-.. code-block:: c++
+```c++
+namespace llvm {
+namespace knowledge {
- namespace llvm {
- namespace knowledge {
+/// This class represents things that Smith can have an intimate
+/// understanding of and contains the data associated with it.
+class Grokable {
+...
+public:
+ explicit Grokable() { ... }
+ virtual ~Grokable() = 0;
- /// This class represents things that Smith can have an intimate
- /// understanding of and contains the data associated with it.
- class Grokable {
...
- public:
- explicit Grokable() { ... }
- virtual ~Grokable() = 0;
- ...
+};
- };
-
- } // namespace knowledge
- } // namespace llvm
+} // namespace knowledge
+} // namespace llvm
+```
Feel free to skip the closing comment when the namespace being closed is
obvious for any reason. For example, the outer-most namespace in a header file
@@ -1624,21 +1572,20 @@ is rarely a source of confusion. But namespaces both anonymous and named in
source files that are being closed half way through the file probably could use
clarification.
-.. _static:
+(static)=
-Restrict Visibility
-^^^^^^^^^^^^^^^^^^^
+#### Restrict Visibility
Functions and variables should have the most restricted visibility possible.
-For class members, that means using appropriate ``private``, ``protected``, or
-``public`` keyword to restrict their access.
+For class members, that means using appropriate `private`, `protected`, or
+`public` keyword to restrict their access.
For non-member functions, variables, and classes, that means restricting
-visibility to a single ``.cpp`` file if it is not referenced outside that file.
+visibility to a single `.cpp` file if it is not referenced outside that file.
Visibility of file-scope non-member variables and functions can be restricted to
-the current translation unit by using either the ``static`` keyword or an anonymous
+the current translation unit by using either the `static` keyword or an anonymous
namespace.
Anonymous namespaces are a great language feature that tells the C++
@@ -1646,8 +1593,8 @@ compiler that the contents of the namespace are only visible within the current
translation unit, allowing more aggressive optimization and eliminating the
possibility of symbol name collisions.
-Anonymous namespaces are to C++ as ``static`` is to C functions and global
-variables. While ``static`` is available in C++, anonymous namespaces are more
+Anonymous namespaces are to C++ as `static` is to C functions and global
+variables. While `static` is available in C++, anonymous namespaces are more
general: they can make entire classes private to a file.
The problem with anonymous namespaces is that they naturally want to encourage
@@ -1659,57 +1606,56 @@ chunk of the file.
Because of this, we have a simple guideline: make anonymous namespaces as small
as possible, and only use them for class declarations. For example:
-.. code-block:: c++
-
- namespace {
- class StringSort {
+```c++
+namespace {
+class StringSort {
+...
+public:
+ StringSort(...)
+ bool operator<(const char *RHS) const;
+};
+} // namespace
+
+static void runHelper() {
...
- public:
- StringSort(...)
- bool operator<(const char *RHS) const;
- };
- } // namespace
-
- static void runHelper() {
- ...
- }
+}
- bool StringSort::operator<(const char *RHS) const {
- ...
- }
+bool StringSort::operator<(const char *RHS) const {
+ ...
+}
+```
Avoid putting declarations other than classes into anonymous namespaces:
-.. code-block:: c++
-
- namespace {
+```c++
+namespace {
- // ... many declarations ...
+// ... many declarations ...
- void runHelper() {
- ...
- }
+void runHelper() {
+ ...
+}
- // ... many declarations ...
+// ... many declarations ...
- } // namespace
+} // namespace
+```
-When you are looking at ``runHelper`` in the middle of a large C++ file,
+When you are looking at `runHelper` in the middle of a large C++ file,
you have no immediate way to tell if this function is local to the file.
In contrast, when the function is marked static, you don't need to cross-reference
faraway places in the file to tell that the function is local:
-.. code-block:: c++
-
- static void runHelper() {
- ...
- }
+```c++
+static void runHelper() {
+ ...
+}
+```
-Don't Use Braces on Simple Single-Statement Bodies of if/else/loop Statements
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Don't Use Braces on Simple Single-Statement Bodies of if/else/loop Statements
-When writing the body of an ``if``, ``else``, or ``for``/``while`` loop
+When writing the body of an `if`, `else`, or `for`/`while` loop
statement, we aim to reduce unnecessary line noise.
**Omit braces when:**
@@ -1717,7 +1663,7 @@ statement, we aim to reduce unnecessary line noise.
* The body consists of a single **simple** statement.
* The single statement is not preceded by a comment.
(Hoist comments above the control statement if you can.)
-* An ``else`` clause, if present, also meets the above criteria (single
+* An `else` clause, if present, also meets the above criteria (single
simple statement, no associated comments).
**Use braces in all other cases, including:**
@@ -1726,121 +1672,120 @@ statement, we aim to reduce unnecessary line noise.
* Single-statement bodies with non-hoistable comments
* Complex single-statement bodies (e.g., deep nesting, complex nested
loops)
-* Inconsistent bracing within ``if``/``else if``/``else`` chains (if one
+* Inconsistent bracing within `if`/`else if`/`else` chains (if one
block requires braces, all must)
-* ``if`` statements ending with a nested ``if`` lacking an ``else`` (to
+* `if` statements ending with a nested `if` lacking an `else` (to
prevent "dangling else")
The examples below provide guidelines for these cases:
-.. code-block:: c++
-
- // Omit the braces since the body is simple and clearly associated with the
- // `if`.
- if (isa<FunctionDecl>(D))
- handleFunctionDecl(D);
- else if (isa<VarDecl>(D))
- handleVarDecl(D);
-
- // Here we document the condition itself and not the body.
- if (isa<VarDecl>(D)) {
- // It is necessary that we explain the situation with this surprisingly long
- // comment, so it would be unclear without the braces whether the following
- // statement is in the scope of the `if`.
- // Because the condition is documented, we can't really hoist this
- // comment that applies to the body above the `if`.
- handleOtherDecl(D);
- }
-
- // Use braces on the outer `if` to avoid a potential dangling `else`
- // situation.
- if (isa<VarDecl>(D)) {
- if (shouldProcessAttr(A))
- handleAttr(A);
- }
-
- // Use braces for the `if` block to keep it uniform with the `else` block.
- if (isa<FunctionDecl>(D)) {
- handleFunctionDecl(D);
- } else {
- // In this `else` case, it is necessary that we explain the situation with
- // this surprisingly long comment, so it would be unclear without the braces
- // whether the following statement is in the scope of the `if`.
- handleOtherDecl(D);
- }
-
- // Use braces for the `else if` and `else` block to keep it uniform with the
- // `if` block.
- if (isa<FunctionDecl>(D)) {
- verifyFunctionDecl(D);
- handleFunctionDecl(D);
- } else if (isa<GlobalVarDecl>(D)) {
- handleGlobalVarDecl(D);
- } else {
- handleOtherDecl(D);
- }
-
- // This should also omit braces. The `for` loop contains only a single
- // statement, so it shouldn't have braces. The `if` also only contains a
- // single simple statement (the `for` loop), so it also should omit braces.
- if (isa<FunctionDecl>(D))
- for (auto *A : D.attrs())
- handleAttr(A);
-
- // Use braces for a `do-while` loop and its enclosing statement.
- if (Tok->is(tok::l_brace)) {
- do {
- Tok = Tok->Next;
- } while (Tok);
- }
-
- // Use braces for the outer `if` since the nested `for` is braced.
- if (isa<FunctionDecl>(D)) {
- for (auto *A : D.attrs()) {
- // In this `for` loop body, it is necessary that we explain the situation
- // with this surprisingly long comment, forcing braces on the `for` block.
- handleAttr(A);
- }
- }
-
- // Use braces on the outer block because there are more than two levels of
- // nesting.
- if (isa<FunctionDecl>(D)) {
- for (auto *A : D.attrs())
- for (ssize_t i : llvm::seq<ssize_t>(count))
- handleAttrOnDecl(D, A, i);
- }
-
- // Use braces on the outer block because of a nested `if`; otherwise, the
- // compiler would warn: `add explicit braces to avoid dangling else`
- if (auto *D = dyn_cast<FunctionDecl>(D)) {
- if (shouldProcess(D))
- handleVarDecl(D);
- else
- markAsIgnored(D);
+```c++
+// Omit the braces since the body is simple and clearly associated with the
+// `if`.
+if (isa<FunctionDecl>(D))
+ handleFunctionDecl(D);
+else if (isa<VarDecl>(D))
+ handleVarDecl(D);
+
+// Here we document the condition itself and not the body.
+if (isa<VarDecl>(D)) {
+ // It is necessary that we explain the situation with this surprisingly long
+ // comment, so it would be unclear without the braces whether the following
+ // statement is in the scope of the `if`.
+ // Because the condition is documented, we can't really hoist this
+ // comment that applies to the body above the `if`.
+ handleOtherDecl(D);
+}
+
+// Use braces on the outer `if` to avoid a potential dangling `else`
+// situation.
+if (isa<VarDecl>(D)) {
+ if (shouldProcessAttr(A))
+ handleAttr(A);
+}
+
+// Use braces for the `if` block to keep it uniform with the `else` block.
+if (isa<FunctionDecl>(D)) {
+ handleFunctionDecl(D);
+} else {
+ // In this `else` case, it is necessary that we explain the situation with
+ // this surprisingly long comment, so it would be unclear without the braces
+ // whether the following statement is in the scope of the `if`.
+ handleOtherDecl(D);
+}
+
+// Use braces for the `else if` and `else` block to keep it uniform with the
+// `if` block.
+if (isa<FunctionDecl>(D)) {
+ verifyFunctionDecl(D);
+ handleFunctionDecl(D);
+} else if (isa<GlobalVarDecl>(D)) {
+ handleGlobalVarDecl(D);
+} else {
+ handleOtherDecl(D);
+}
+
+// This should also omit braces. The `for` loop contains only a single
+// statement, so it shouldn't have braces. The `if` also only contains a
+// single simple statement (the `for` loop), so it also should omit braces.
+if (isa<FunctionDecl>(D))
+ for (auto *A : D.attrs())
+ handleAttr(A);
+
+// Use braces for a `do-while` loop and its enclosing statement.
+if (Tok->is(tok::l_brace)) {
+ do {
+ Tok = Tok->Next;
+ } while (Tok);
+}
+
+// Use braces for the outer `if` since the nested `for` is braced.
+if (isa<FunctionDecl>(D)) {
+ for (auto *A : D.attrs()) {
+ // In this `for` loop body, it is necessary that we explain the situation
+ // with this surprisingly long comment, forcing braces on the `for` block.
+ handleAttr(A);
}
+}
+
+// Use braces on the outer block because there are more than two levels of
+// nesting.
+if (isa<FunctionDecl>(D)) {
+ for (auto *A : D.attrs())
+ for (ssize_t i : llvm::seq<ssize_t>(count))
+ handleAttrOnDecl(D, A, i);
+}
+
+// Use braces on the outer block because of a nested `if`; otherwise, the
+// compiler would warn: `add explicit braces to avoid dangling else`
+if (auto *D = dyn_cast<FunctionDecl>(D)) {
+ if (shouldProcess(D))
+ handleVarDecl(D);
+ else
+ markAsIgnored(D);
+}
+```
-Use Unix line endings for files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Use Unix line endings for files
Use Unix line endings for all files. CRLF line endings are allowed as an
exception for test files that intend to test CRLF handling or when the file
-format requires it (like ``.bat`` or ``.rc`` files).
+format requires it (like `.bat` or `.rc` files).
-See Also
-========
+## See Also
A lot of these comments and recommendations have been culled from other sources.
Two particularly important books for our work are:
-#. `Effective C++
- <https://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0321334876>`_
+1. [Effective C++]
by Scott Meyers. Also interesting and useful are "More Effective C++" and
"Effective STL" by the same author.
-#. `Large-Scale C++ Software Design
- <https://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620>`_
+1. [Large-Scale C++ Software Design]
by John Lakos
+[Effective C++]: https://www.amazon.com/Effective-Specific-Addison-Wesley-Professional-Computing/dp/0321334876
+[Large-Scale C++ Software Design]: https://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620
+
If you get some free time, and you haven't read them: do so, you might learn
something.
diff --git a/llvm/docs/CommandGuide/index.md b/llvm/docs/CommandGuide/index.md
index 5421b133e96c3..6b126837343e2 100644
--- a/llvm/docs/CommandGuide/index.md
+++ b/llvm/docs/CommandGuide/index.md
@@ -1,105 +1,104 @@
-LLVM Command Guide
-------------------
+# LLVM Command Guide
The following documents are command descriptions for all of the LLVM tools.
These pages describe how to use the LLVM commands and what their options are.
Note that these pages do not describe all of the options available for all
-tools. To get a complete listing, pass the ``--help`` (general options) or
-``--help-hidden`` (general and debugging options) arguments to the tool you are
+tools. To get a complete listing, pass the `--help` (general options) or
+`--help-hidden` (general and debugging options) arguments to the tool you are
interested in.
-Basic Commands
-~~~~~~~~~~~~~~
-
-.. toctree::
- :maxdepth: 1
-
- dsymutil
- llc
- lli
- llubi
- llvm-as
- llvm-cgdata
- llvm-config
- llvm-cov
- llvm-cxxmap
- llvm-debuginfo-analyzer
- llvm-diff
- llvm-dis
- llvm-dwarfdump
- llvm-dwarfutil
- llvm-extract-bundle-entry
- llvm-ir2vec
- llvm-lib
- llvm-libtool-darwin
- llvm-link
- llvm-lipo
- llvm-mc
- llvm-mca
- llvm-opt-report
- llvm-otool
- llvm-profdata
- llvm-readobj
- llvm-reduce
- llvm-stress
- llvm-symbolizer
- opt
-
-GNU binutils replacements
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. toctree::
- :maxdepth: 1
-
- llvm-addr2line
- llvm-ar
- llvm-cxxfilt
- llvm-install-name-tool
- llvm-nm
- llvm-objcopy
- llvm-objdump
- llvm-ranlib
- llvm-readelf
- llvm-size
- llvm-strings
- llvm-strip
-
-Debugging Tools
-~~~~~~~~~~~~~~~
-
-.. toctree::
- :maxdepth: 1
-
- llvm-extract
- llvm-bcanalyzer
- llvm-reduce
-
-Developer Tools
-~~~~~~~~~~~~~~~
-
-.. toctree::
- :maxdepth: 1
-
- FileCheck
- tblgen
- clang-tblgen
- lldb-tblgen
- llvm-tblgen
- mlir-tblgen
- lit
- llvm-exegesis
- llvm-ifs
- llvm-locstats
- llvm-test-mustache-spec
- llvm-pdbutil
- llvm-profgen
- llvm-tli-checker
- llvm-offload-binary
-
-Remarks Tools
-~~~~~~~~~~~~~~
-
-.. toctree::
- :maxdepth: 1
-
- llvm-remarkutil
+## Basic Commands
+
+```{toctree}
+:maxdepth: 1
+
+dsymutil
+llc
+lli
+llubi
+llvm-as
+llvm-cgdata
+llvm-config
+llvm-cov
+llvm-cxxmap
+llvm-debuginfo-analyzer
+llvm-diff
+llvm-dis
+llvm-dwarfdump
+llvm-dwarfutil
+llvm-extract-bundle-entry
+llvm-ir2vec
+llvm-lib
+llvm-libtool-darwin
+llvm-link
+llvm-lipo
+llvm-mc
+llvm-mca
+llvm-opt-report
+llvm-otool
+llvm-profdata
+llvm-readobj
+llvm-reduce
+llvm-stress
+llvm-symbolizer
+opt
+```
+
+## GNU binutils replacements
+
+```{toctree}
+:maxdepth: 1
+
+llvm-addr2line
+llvm-ar
+llvm-cxxfilt
+llvm-install-name-tool
+llvm-nm
+llvm-objcopy
+llvm-objdump
+llvm-ranlib
+llvm-readelf
+llvm-size
+llvm-strings
+llvm-strip
+```
+
+## Debugging Tools
+
+```{toctree}
+:maxdepth: 1
+
+llvm-extract
+llvm-bcanalyzer
+llvm-reduce
+```
+
+## Developer Tools
+
+```{toctree}
+:maxdepth: 1
+
+FileCheck
+tblgen
+clang-tblgen
+lldb-tblgen
+llvm-tblgen
+mlir-tblgen
+lit
+llvm-exegesis
+llvm-ifs
+llvm-locstats
+llvm-test-mustache-spec
+llvm-pdbutil
+llvm-profgen
+llvm-tli-checker
+llvm-offload-binary
+```
+
+## Remarks Tools
+
+```{toctree}
+:maxdepth: 1
+
+llvm-remarkutil
+```
diff --git a/llvm/docs/Contributing.md b/llvm/docs/Contributing.md
index b6475e2f6c3a7..9455b9d1dc37f 100644
--- a/llvm/docs/Contributing.md
+++ b/llvm/docs/Contributing.md
@@ -1,124 +1,125 @@
-==================================
-Contributing to LLVM
-==================================
+---
+myst:
+ enable_extensions:
+ - deflist
+---
+
+# Contributing to LLVM
Thank you for your interest in contributing to LLVM! There are multiple ways to
contribute, and we appreciate all contributions. If you have questions,
-you can either use the `Forum`_ or, for a more interactive chat, go to our
-`Discord server`_.
+you can either use the [Forum] or, for a more interactive chat, go to our
+[Discord server].
-If you want to contribute code, please familiarize yourself with the :doc:`DeveloperPolicy`.
+If you want to contribute code, please familiarize yourself with the {doc}`DeveloperPolicy`.
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Ways to Contribute
-==================
+## Ways to Contribute
-Bug Reports
------------
+### Bug Reports
If you are working with LLVM and run into a bug, we definitely want to know
about it. Please follow the instructions in
-:doc:`HowToSubmitABug` to create a bug report.
+{doc}`HowToSubmitABug` to create a bug report.
-Bug Fixes
----------
+### Bug Fixes
If you are interested in contributing code to LLVM, bugs labeled with the
-`good first issue`_ keyword in the `bug tracker`_ are a good way to get familiar with
+[good first issue] keyword in the [bug tracker] are a good way to get familiar with
the code base. If you are interested in fixing a bug, please comment on it to
let people know you are working on it.
Then try to reproduce and fix the bug with upstream LLVM. Start by building
-LLVM from source as described in :doc:`GettingStarted` and
+LLVM from source as described in {doc}`GettingStarted` and
use the built binaries to reproduce the failure described in the bug. Use
a debug build (`-DCMAKE_BUILD_TYPE=Debug`) or a build with assertions
(`-DLLVM_ENABLE_ASSERTIONS=On`, enabled for Debug builds).
-Reporting a Security Issue
---------------------------
+### Reporting a Security Issue
-There is a separate process to submit security-related bugs, see :ref:`report-security-issue`.
+There is a separate process to submit security-related bugs, see {ref}`report-security-issue`.
-Bigger Pieces of Work
----------------------
+### Bigger Pieces of Work
If you are interested in taking on a bigger piece of work, a list of
-interesting projects is maintained at the `LLVM's Open Projects page`_. If
+interesting projects is maintained at the [LLVM's Open Projects page]. If
you are interested in working on any of these projects, please post on the
-`Forum`_, so that we know the project is being worked on.
+[Forum], so that we know the project is being worked on.
-.. _submit_patch:
+(submit_patch)=
-How to Submit a Patch
-=====================
+## How to Submit a Patch
Once you have a patch ready, it is time to submit it. The patch should:
* include a small unit test
-* conform to the :doc:`CodingStandards`. You can use the `clang-format-diff.py`_ or `git-clang-format`_ tools to automatically format your patch properly.
+* conform to the {doc}`CodingStandards`. You can use the [clang-format-diff.py] or [git-clang-format] tools to automatically format your patch properly.
* not contain any unrelated changes
* be an isolated change. Independent changes should be submitted as separate patches as this makes reviewing easier.
-* have a single commit, up-to-date with the upstream ``origin/main`` branch, and don't have merges.
+* have a single commit, up-to-date with the upstream `origin/main` branch, and don't have merges.
-.. _format patches:
+(format patches)=
Before sending a patch for review, please also ensure it is
-formatted properly. We use ``clang-format`` for this, which has git integration
-through the ``git-clang-format`` script. On some systems, it may already be
+formatted properly. We use `clang-format` for this, which has git integration
+through the `git-clang-format` script. On some systems, it may already be
installed (or be installable via your package manager). If so, you can simply
run it -- the following command will format only the code changed in the most
recent commit:
-.. code-block:: console
-
- % git clang-format HEAD~1
+```console
+% git clang-format HEAD~1
+```
-.. note::
- For some patches, formatting them may add changes that obscure the intent of
- the patch. For example, adding to an enum that was not previously formatted
- may result in the entire enum being reformatted. This happens because not all
- of the LLVM Project conforms to LLVM's clang-format style at this time.
+```{note}
+For some patches, formatting them may add changes that obscure the intent of
+the patch. For example, adding to an enum that was not previously formatted
+may result in the entire enum being reformatted. This happens because not all
+of the LLVM Project conforms to LLVM's clang-format style at this time.
- If you think that this might be the case for your changes, or are unsure, we
- recommend that you add the formatting changes as a **separate commit** within
- the Pull Request.
+If you think that this might be the case for your changes, or are unsure, we
+recommend that you add the formatting changes as a **separate commit** within
+the Pull Request.
- Reviewers may request that this formatting commit be made into a separate Pull
- Request that will be merged before your actual changes.
+Reviewers may request that this formatting commit be made into a separate Pull
+Request that will be merged before your actual changes.
- This means that if the formatting changes are the first commit, you will have
- an easier time doing this. If they are not, that is ok too, but you will have
- to do a bit more work to separate it out.
+This means that if the formatting changes are the first commit, you will have
+an easier time doing this. If they are not, that is ok too, but you will have
+to do a bit more work to separate it out.
+```
-Note that ``git clang-format`` modifies the files, but does not commit them --
+Note that `git clang-format` modifies the files, but does not commit them --
you will likely want to run one of the following to add the changes to a commit:
-.. code-block:: console
+```console
+# To create a new commit.
+% git commit -a
+# To add to the most recent commit.
+% git commit --amend -a
+```
- # To create a new commit.
- % git commit -a
- # To add to the most recent commit.
- % git commit --amend -a
-
-.. note::
- If you don't already have ``clang-format`` or ``git clang-format`` installed
- on your system, the ``clang-format`` binary will be built alongside clang, and
- the git integration can be run from
- ``clang/tools/clang-format/git-clang-format``.
+```{note}
+If you don't already have `clang-format` or `git clang-format` installed
+on your system, the `clang-format` binary will be built alongside clang, and
+the git integration can be run from
+`clang/tools/clang-format/git-clang-format`.
+```
The LLVM project has migrated to GitHub Pull Requests as its review process.
For more information about the workflow of using GitHub Pull Requests see our
-:ref:`GitHub <github-reviews>` documentation. We still have a read-only
-`LLVM's Phabricator <https://reviews.llvm.org>`_ instance.
+{ref}`GitHub <github-reviews>` documentation. We still have a read-only
+[LLVM's Phabricator](https://reviews.llvm.org) instance.
To make sure the right people see your patch, please select suitable reviewers
and add them to your patch when requesting a review.
Suitable reviewers are the maintainers of the project you are modifying, and
anyone else working in the area your patch touches. To find maintainers, look for
-the ``Maintainers.md`` file in the root of the project's
-sub-directory. For example, LLVM's is ``llvm/Maintainers.md`` and
-clang-tools-extra's is ``clang-tools-extra/Maintainers.md``.
+the `Maintainers.md` file in the root of the project's
+sub-directory. For example, LLVM's is `llvm/Maintainers.md` and
+clang-tools-extra's is `clang-tools-extra/Maintainers.md`.
If you are a new contributor, you will not be able to select reviewers in such a
way, in which case you can still get the attention of potential reviewers by CC'ing
@@ -135,32 +136,32 @@ explicitly, as reviewers' default assumption is that you are able to merge your
own PR.
For more information on LLVM's code-review process, please see
-:doc:`CodeReview`.
+{doc}`CodeReview`.
-.. _commit_from_git:
+(commit_from_git)=
-For developers to commit changes from Git
------------------------------------------
+### For developers to commit changes from Git
-.. note::
- See also :ref:`GitHub <github-reviews>` for more details on merging your changes
- into LLVM project monorepo.
+```{note}
+See also {ref}`GitHub <github-reviews>` for more details on merging your changes
+into LLVM project monorepo.
+```
Once a pull request is approved, you can select the "Squash and merge" button in the
GitHub web interface.
-When pushing directly from the command-line to the ``main`` branch, you will need
+When pushing directly from the command-line to the `main` branch, you will need
to rebase your change. LLVM has a linear-history policy, which means
-that merge commits are not allowed, and the ``main`` branch is configured to reject
+that merge commits are not allowed, and the `main` branch is configured to reject
pushes that include merges.
GitHub will display a message that looks like this:
-.. code-block:: console
-
- remote: Bypassed rule violations for refs/heads/main:
- remote:
- remote: - Required status check “buildkite/github-pull-requests” is expected.
+```console
+remote: Bypassed rule violations for refs/heads/main:
+remote:
+remote: - Required status check “buildkite/github-pull-requests” is expected.
+```
This can seem scary, but this is just an artifact of the GitHub setup: it is
intended as a warning for people merging pull-requests with failing CI. We can't
@@ -168,56 +169,52 @@ disable it for people pushing on the command-line.
Please ask for help if you're having trouble with your particular git workflow.
-.. _git_pre_push_hook:
+(git_pre_push_hook)=
-Git pre-push hook
-^^^^^^^^^^^^^^^^^
+#### Git pre-push hook
We include an optional pre-push hook that runs some sanity checks on the revisions
you are about to push and asks for confirmation if you push multiple commits at once.
You can set it up (on Unix systems) by running from the repository root:
-.. code-block:: console
+```console
+% ln -sf ../../llvm/utils/git/pre-push.py .git/hooks/pre-push
+```
- % ln -sf ../../llvm/utils/git/pre-push.py .git/hooks/pre-push
-
-Helpful Information About LLVM
-==============================
-:doc:`LLVM's documentation <index>` provides a wealth of information about LLVM's internals as
+## Helpful Information About LLVM
+{doc}`LLVM's documentation <index>` provides a wealth of information about LLVM's internals as
well as various user guides. The pages listed below should provide a good overview
of LLVM's high-level design, as well as its internals:
-:doc:`GettingStarted`
- Discusses how to get up and running quickly with the LLVM infrastructure.
- Everything from unpacking and compilation of the distribution to execution
- of some tools.
+{doc}`GettingStarted`
+: Discusses how to get up and running quickly with the LLVM infrastructure.
+ Everything from unpacking and compilation of the distribution to execution
+ of some tools.
-:doc:`LangRef`
- Defines the LLVM intermediate representation.
+{doc}`LangRef`
+: Defines the LLVM intermediate representation.
-:doc:`ProgrammersManual`
- Introduction to the general layout of the LLVM sourcebase, important classes
+{doc}`ProgrammersManual`
+: Introduction to the general layout of the LLVM sourcebase, important classes
and APIs, and some tips & tricks.
-`LLVM for Grad Students`__
- This is an introduction to the LLVM infrastructure by Adrian Sampson. While it
+[LLVM for Grad Students]
+: This is an introduction to the LLVM infrastructure by Adrian Sampson. While it
has been written for grad students, it provides a good, compact overview of
LLVM's architecture, LLVM's IR and how to write a new pass.
- .. __: http://www.cs.cornell.edu/~asampson/blog/llvm.html
-
-`Intro to LLVM`__
- Book chapter providing a compiler hacker's introduction to LLVM.
-
- .. __: http://www.aosabook.org/en/llvm.html
-
-.. _Forum: https://discourse.llvm.org
-.. _Discord server: https://discord.gg/xS7Z362
-.. _irc.oftc.net: irc://irc.oftc.net/llvm
-.. _good first issue: https://github.com/llvm/llvm-project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
-.. _bug tracker: https://github.com/llvm/llvm-project/issues
-.. _clang-format-diff.py: https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-format/clang-format-diff.py
-.. _git-clang-format: https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-format/git-clang-format
-.. _LLVM's GitHub: https://github.com/llvm/llvm-project
-.. _LLVM's Phabricator (read-only): https://reviews.llvm.org/
-.. _LLVM's Open Projects page: https://llvm.org/OpenProjects.html#what
+[Intro to LLVM]
+: Book chapter providing a compiler hacker's introduction to LLVM.
+
+[Forum]: https://discourse.llvm.org
+[Discord server]: https://discord.gg/xS7Z362
+[irc.oftc.net]: irc://irc.oftc.net/llvm
+[good first issue]: https://github.com/llvm/llvm-project/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
+[bug tracker]: https://github.com/llvm/llvm-project/issues
+[clang-format-diff.py]: https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-format/clang-format-diff.py
+[git-clang-format]: https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-format/git-clang-format
+[LLVM's GitHub]: https://github.com/llvm/llvm-project
+[LLVM's Phabricator (read-only)]: https://reviews.llvm.org/
+[LLVM's Open Projects page]: https://llvm.org/OpenProjects.html#what
+[LLVM for Grad Students]: http://www.cs.cornell.edu/~asampson/blog/llvm.html
+[Intro to LLVM]: http://www.aosabook.org/en/llvm.html
diff --git a/llvm/docs/DeveloperPolicy.md b/llvm/docs/DeveloperPolicy.md
index e302b2d79dc1b..8e0faecc22be4 100644
--- a/llvm/docs/DeveloperPolicy.md
+++ b/llvm/docs/DeveloperPolicy.md
@@ -1,112 +1,100 @@
-.. _developer_policy:
+(developer_policy)=
+# LLVM Developer Policy
-=====================
-LLVM Developer Policy
-=====================
+```{contents}
+:local:
+```
-.. contents::
- :local:
-
-Introduction
-============
+## Introduction
This document contains the LLVM Developer Policy which defines the project's
policy towards developers and their contributions. The intent of this policy is
to eliminate miscommunication, rework, and confusion that might arise from the
-distributed nature of LLVM's development. By stating the policy in clear terms,
+distributed nature of LLVM's development. By stating the policy in clear terms,
we hope each developer can know ahead of time what to expect when making LLVM
-contributions. This policy covers all llvm.org subprojects, including Clang,
+contributions. This policy covers all llvm.org subprojects, including Clang,
LLDB, libc++, MLIR, etc.
The developer policy supports the following LLVM project objectives:
-#. Attract both users and new contributors to the LLVM project.
-
-#. Help people contribute to LLVM by documenting our development practices.
-
-#. Maintain the stability, performance, and quality of the ``main`` branch.
+1. Attract both users and new contributors to the LLVM project.
+2. Help people contribute to LLVM by documenting our development practices.
+3. Maintain the stability, performance, and quality of the `main` branch.
+4. Establish the project's {ref}`copyright, license, and patent
+ policies <copyright-license-patents>` policies.
-#. Establish the project's :ref:`copyright, license, and patent
- policies <copyright-license-patents>` policies.
+## Developer Policies
-Developer Policies
-==================
-
-Communication Channels
-----------------------
+### Communication Channels
LLVM is a large project with many subcomponents, and it has a wide array of
communication channels that you can use to keep track of recent developments,
upcoming projects, new designs, enhancements, and other community business.
-First and foremost is the `LLVM Discourse forums`_, which is the successor
-to our former mailing lists (llvm-dev@, cfe-dev@, lldb-dev@, etc). This is
-probably the most vital and active communication channel to our highly
-distributed open source project. It enables long-form asynchronous text
-communication, and this is where people tend to propose major changes or
-propose new designs in the form of RFCs (Request For Comment), which are
-described later. Please be aware that the Discourse forums are public and
+First and foremost is the [LLVM Discourse forums](https://discourse.llvm.org),
+which is the successor to our former mailing lists (llvm-dev@, cfe-dev@,
+lldb-dev@, etc). This is probably the most vital and active communication
+channel to our highly distributed open source project. It enables long-form
+asynchronous text communication, and this is where people tend to propose major
+changes or propose new designs in the form of RFCs (Request For Comment), which
+are described later. Please be aware that the Discourse forums are public and
archived, and that notices of confidentiality or non-disclosure cannot be
respected.
-We accept code contributions as :ref:`GitHub Pull Requests <github-reviews>`.
+We accept code contributions as {ref}`GitHub Pull Requests <github-reviews>`.
Our project is generally too large to subscribe to all github notifications, so
if you want to be notified of pull requests affecting specific parts of the
-code, you can join
-one of the `pr-subscribers-* <https://github.com/orgs/llvm/teams?query=pr-subscribers>`_
-GitHub teams. This `mapping <https://github.com/llvm/llvm-project/blob/main/.github/new-prs-labeler.yml>`_
+code, you can join one of the
+[pr-subscribers-\*](https://github.com/orgs/llvm/teams?query=pr-subscribers)
+GitHub teams. This
+[mapping](https://github.com/llvm/llvm-project/blob/main/.github/new-prs-labeler.yml)
documents the paths that trigger notifications for each of the listed teams.
-Missing features and bugs are tracked through our `GitHub issue tracker
-<https://github.com/llvm/llvm-project/issues>`_. You can subscribe for
-notification for specific components by joining one of the `issue-subscribers-*
-<https://github.com/orgs/llvm/teams?query=issue-subscribers>`_ teams. You may
-also subscribe to the `llvm-bugs
-<http://lists.llvm.org/mailman/listinfo/llvm-bugs>`_ email list to subscribe to
-the firehose of all issue notifications, which some community members use to
-perform custom filtering.
+Missing features and bugs are tracked through our [GitHub issue
+tracker](https://github.com/llvm/llvm-project/issues). You can subscribe for
+notification for specific components by joining one of the
+[issue-subscribers-\*](https://github.com/orgs/llvm/teams?query=issue-subscribers)
+teams. You may also subscribe to the
+[llvm-bugs](http://lists.llvm.org/mailman/listinfo/llvm-bugs) email list to
+subscribe to the firehose of all issue notifications, which some community
+members use to perform custom filtering.
Beyond the asynchronous written communication channels, LLVM has a Discord
server for real-time chat communication, as well as a community calendar with
-many regular workgroup video calls and office hours. See :doc:`GettingInvolved`
+many regular workgroup video calls and office hours. See {doc}`GettingInvolved`
for more information on other ways to engage with the community.
-.. _patch:
-
-Making and Submitting a Patch
------------------------------
+(patch)=
+### Making and Submitting a Patch
Patches are submitted to GitHub and reviewed using Pull Requests. Follow the
-:ref:`Getting Started Guide <sources>` to check out sources, make a patch, and
-then follow the :ref:`GitHub Pull Request <github-reviews>` guide to upload a
+{ref}`Getting Started Guide <sources>` to check out sources, make a patch, and
+then follow the {ref}`GitHub Pull Request <github-reviews>` guide to upload a
pull request.
Here are some tips to enable a successful code review:
-* :ref:`Include a test <include a testcase>`. This tends to be one of the first
- things a reviewer will ask for and look at to understand what a new patch
- does.
-
-* Identify 2-3 individuals to review the patch. Look through the relevant
- :ref:`Maintainers` file or browse git blame for likely stakeholders for the
- code you want to modify, and add ``@username`` to a PR comment to notify them
- of your PR if you are unable to add reviewers yourself due to GitHub permissions.
-
-* To avoid precommit CI failures due to merge conflicts, base your patches on a
- recent commit from ``main``. If you want to make changes to a release branch,
- land a change in ``main`` first and then follow the
- :ref:`backporting instructions <backporting>`.
-
-See :doc:`CodeReview` for more info on what to expect.
+- {ref}`Include a test <include a testcase>`. This tends to be one of the
+first things a reviewer will ask for and look at to understand what a new patch
+does.
+- Identify 2-3 individuals to review the patch. Look through the relevant
+ {ref}`Maintainers` file or browse git blame for likely stakeholders for the
+ code you want to modify, and add `@username` to a PR comment to notify them
+ of your PR if you are unable to add reviewers yourself due to GitHub
+ permissions.
+- To avoid precommit CI failures due to merge conflicts, base your patches on
+ a recent commit from `main`. If you want to make changes to a release
+ branch, land a change in `main` first and then follow the {ref}`backporting
+ instructions <backporting>`.
+
+See {doc}`CodeReview` for more info on what to expect.
When submitting patches, please do not add confidentiality or non-disclosure
-notices to the patches themselves. These notices conflict with the LLVM
+notices to the patches themselves. These notices conflict with the LLVM
licensing terms and may result in your contribution being excluded.
-.. _github-email-address:
-
-Email Addresses
----------------
+(github-email-address)=
+### Email Addresses
The LLVM project uses email to communicate to contributors outside of the
GitHub platform about their past contributions. Primarily, our buildbot
@@ -114,24 +102,20 @@ infrastructure uses emails to contact contributors about build and test
failures.
Therefore, the LLVM community requires contributors to have a public email
-address associated with their GitHub commits, so please ensure that "Keep my
-email addresses private" is disabled in your `account settings
-<https://github.com/settings/emails>`_. There are many free email forwarding
-services available if you wish to keep your identity private.
+address associated with their GitHub commits, so please ensure that \"Keep my
+email addresses private\" is disabled in your [account
+settings](https://github.com/settings/emails). There are many free email
+forwarding services available if you wish to keep your identity private.
-.. _code review:
-
-Code Reviews
-------------
+(code review)=
+### Code Reviews
LLVM uses code review, which is a generally accepted software engineering best
-practice for maintaining high code quality. Please see :doc:`CodeReview` for
+practice for maintaining high code quality. Please see {doc}`CodeReview` for
more information on LLVM's code review process.
-.. _maintainers:
-
-Maintainers
------------
+(maintainers)=
+### Maintainers
The LLVM Project aims to evolve features quickly while continually being in a
release-ready state. In order to accomplish this, the project needs volunteers
@@ -141,22 +125,21 @@ products.
Maintainers are those volunteers; they are regular contributors who volunteer
to take on additional community responsibilities beyond code contributions.
Community members can find active and inactive maintainers for a project in the
-``Maintainers.md`` file at the root directory of the individual project.
+`Maintainers.md` file at the root directory of the individual project.
Maintainers are volunteering to take on the following shared responsibilities
within an area of a project:
-* ensure that commits receive high-quality review, either by the maintainer
- or by someone else,
-* help to confirm and comment on issues,
-* mediate code review disagreements through collaboration with other
- maintainers (and other reviewers) to come to a consensus on how best to
- proceed with disputed changes,
-* actively engage with relevant RFCs,
-* aid release managers with backporting and other release-related
- activities,
-* be a point of contact for contributors who need help (answering questions
- on Discord/Discourse or holding office hours).
+- ensure that commits receive high-quality review, either by the maintainer
+ or by someone else,
+- help to confirm and comment on issues,
+- mediate code review disagreements through collaboration with other
+ maintainers (and other reviewers) to come to a consensus on how best to
+ proceed with disputed changes,
+- actively engage with relevant RFCs,
+- aid release managers with backporting and other release-related activities,
+- be a point of contact for contributors who need help (answering questions
+ on Discord/Discourse or holding office hours).
Each top-level project in the monorepo will specify one or more
lead maintainers who are responsible for ensuring community needs are
@@ -172,10 +155,10 @@ project should be discontinued.
All contributors with commit access to the LLVM Project are eligible to be a
maintainer. However, we are looking for people who can commit to:
-* engaging in their responsibilities the majority of the days in a month,
-* ensuring that they, and the community members they interact with, abide by the
- :ref:`LLVM Community Code of Conduct`, and
-* performing these duties for at least three months.
+- engaging in their responsibilities the majority of the days in a month,
+- ensuring that they, and the community members they interact with, abide by
+ the {ref}`LLVM Community Code of Conduct`, and
+- performing these duties for at least three months.
We recognize that priorities shift, job changes happen, burnout is real,
extended vacations are a blessing, and people's lives are generally complex.
@@ -190,165 +173,150 @@ proposed area(s). The PR will be accepted so long as at least one maintainer in
the same project vouches for their ability to perform the responsibilities and
there are no explicit objections raised by the community.
-*To step down as a maintainer*, you can move your name to the "inactive
-maintainers" section of the ``Maintainers.md`` file for
-the project, or remove your name entirely; no PR review is necessary.
-Additionally, any maintainer who has not been actively performing their
-responsibilities over an extended period of time can be moved to the "inactive
-maintainers" section by another active maintainer within that project with
-agreement from one other active maintainer within that project. If there is
-only one active maintainer for a project, please post on Discourse to solicit
-wider community feedback about the removal and future direction for the project.
-However, please discuss the situation with the inactive maintainer before such
-removal to avoid accidental miscommunications. If the inactive maintainer is
-unreachable, no discussion with them is required. Stepping down or being removed
-as a maintainer is normal and does not prevent someone from resuming their
-activities as a maintainer in the future.
+*To step down as a maintainer*, you can move your name to the \"inactive
+maintainers\" section of the `Maintainers.md` file for the project, or remove
+your name entirely; no PR review is necessary. Additionally, any maintainer who
+has not been actively performing their responsibilities over an extended period
+of time can be moved to the \"inactive maintainers\" section by another active
+maintainer within that project with agreement from one other active maintainer
+within that project. If there is only one active maintainer for a project,
+please post on Discourse to solicit wider community feedback about the removal
+and future direction for the project. However, please discuss the situation
+with the inactive maintainer before such removal to avoid accidental
+miscommunications. If the inactive maintainer is unreachable, no discussion
+with them is required. Stepping down or being removed as a maintainer is normal
+and does not prevent someone from resuming their activities as a maintainer in
+the future.
*To resume activities as a maintainer*, you can post a PR moving your name from
-the "inactive maintainers" section of the ``Maintainers.md``
-file to the active maintainers list. Because the volunteer
-was already previously accepted, they will be re-accepted so long as at least
-one maintainer in the same project approves the PR and there are no explicit
-objections raised by the community.
-
-.. _include a testcase:
+the \"inactive maintainers\" section of the `Maintainers.md` file to the
+active maintainers list. Because the volunteer was already previously accepted,
+they will be re-accepted so long as at least one maintainer in the same project
+approves the PR and there are no explicit objections raised by the community.
-Test Cases
-----------
+(include a testcase)=
+### Test Cases
Developers are required to create test cases for any bugs fixed and any new
-features added. Some tips for getting your testcase approved:
-
-* All feature and regression test cases are added to the ``test`` subdirectory
- of each LLVM subproject, i.e. ``llvm-project/llvm/test`` for LLVM itself. The
- appropriate sub-directory should be selected (see the
- :doc:`Testing Guide <TestingGuide>` for details).
-
-* We prefer that functional changes are tested using ``FileCheck`` and the tool
- that fits most closely with the code being modified. For example, ``opt`` is
- used to test IR transformations, ``llc`` for backend changes, and ``clang``
- for frontend changes. Some components have scripts for generating and
- updating golden tests in the ``utils/`` subproject directory, i.e.
- `mlir/utils/generate-test-checks.py <https://github.com/llvm/llvm-project/blob/main/mlir/utils/generate-test-checks.py>`_
- and `llvm/utils/update_llc_test_checks.py <https://github.com/llvm/llvm-project/blob/main/llvm/utils/update_llc_test_checks.py>`_
-
-* Some subprojects such as ``clang`` and ``clangd`` have project specific
- testing tools, like the ``clang -verify`` flag (`docs
- <https://clang.llvm.org/docs/InternalsManual.html#verifying-diagnostics>`_)
- and the ``clangd -lit-test``
- flag, which are preferred over ``FileCheck``.
-
-* Changes to libraries, such as Support, which are not directly observable
- through tool invocations, are often best tested with unit tests. Unit tests
- are located under the ``unittests`` subdirectory of each subproject.
-
-* Test cases should be targeted. Large inputs exhibiting bugs should be reduced
- with tools like ``llvm-reduce`` before committing them to the suite. It is not
- acceptable to place an entire failing program into ``llvm/test`` as this
- creates a *time-to-test* burden on all developers. Please keep them short.
-
-* Avoid adding links to resources that are not available to the entire
- community, such as links to private bug trackers, internal corporate
- documentation, etc. Instead, add sufficient comments to the test to provide
- the context behind such links.
+features added. Some tips for getting your testcase approved:
+
+- All feature and regression test cases are added to the `test` subdirectory
+ of each LLVM subproject, i.e. `llvm-project/llvm/test` for LLVM itself. The
+ appropriate sub-directory should be selected (see the {doc}`Testing Guide
+ <TestingGuide>` for details).
+- We prefer that functional changes are tested using `FileCheck` and the tool
+ that fits most closely with the code being modified. For example, `opt` is
+ used to test IR transformations, `llc` for backend changes, and `clang`
+ for frontend changes. Some components have scripts for generating and
+ updating golden tests in the `utils/` subproject directory, i.e.
+ [mlir/utils/generate-test-checks.py](https://github.com/llvm/llvm-project/blob/main/mlir/utils/generate-test-checks.py)
+ and
+ [llvm/utils/update_llc_test_checks.py](https://github.com/llvm/llvm-project/blob/main/llvm/utils/update_llc_test_checks.py)
+- Some subprojects such as `clang` and `clangd` have project specific testing
+ tools, like the `clang -verify` flag
+ ([docs](https://clang.llvm.org/docs/InternalsManual.html#verifying-diagnostics))
+ and the `clangd -lit-test` flag, which are preferred over `FileCheck`.
+- Changes to libraries, such as Support, which are not directly observable
+ through tool invocations, are often best tested with unit tests. Unit tests
+ are located under the `unittests` subdirectory of each subproject.
+- Test cases should be targeted. Large inputs exhibiting bugs should be
+ reduced with tools like `llvm-reduce` before committing them to the suite.
+ It is not acceptable to place an entire failing program into `llvm/test` as
+ this creates a *time-to-test* burden on all developers. Please keep them
+ short.
+- Avoid adding links to resources that are not available to the entire
+ community, such as links to private bug trackers, internal corporate
+ documentation, etc. Instead, add sufficient comments to the test to provide
+ the context behind such links.
As a project, we prefer to separate tests into small in-tree tests, and large
out-of-tree integration tests. More extensive integration test cases (e.g.,
-entire applications, benchmarks, etc) should be added to the `llvm-test-suite
-<https://github.com/llvm/llvm-test-suite>`_ repository. The
-``llvm-test-suite`` repository is for integration and application testing
+entire applications, benchmarks, etc) should be added to the
+[llvm-test-suite](https://github.com/llvm/llvm-test-suite) repository. The
+`llvm-test-suite` repository is for integration and application testing
(correctness, performance, etc) testing, not feature or regression testing. It
also serves to separate out third party code that falls under a different
license.
-Release Notes
--------------
+### Release Notes
Many projects in LLVM communicate important changes to users through release
-notes, typically found in ``docs/ReleaseNotes.rst`` for the project. Changes to
+notes, typically found in `docs/ReleaseNotes.rst` for the project. Changes to
a project that are user-facing, or that users may wish to know about, should be
added to the project's release notes at the author's or code reviewer's
discretion, preferably as part of the commit landing the changes. Examples of
changes that would typically warrant adding a release note (this list is not
exhaustive):
-* Adding, removing, or modifying command-line options.
-* Adding, removing, or regrouping a diagnostic.
-* Fixing a bug that potentially has significant user-facing impact (please link
- to the issue fixed in the bug database).
-* Adding or removing optimizations that have widespread impact or enables new
- programming paradigms.
-* Modifying a C stable API.
-* Notifying users about a potentially disruptive change expected to be made in
- a future release, such as removal of a deprecated feature. In this case, the
- release note should be added to a ``Potentially Breaking Changes`` section of
- the notes with sufficient information and examples to demonstrate the
- potential disruption. Additionally, any new entries to this section should be
- announced in the `Announcements <https://discourse.llvm.org/c/announce/>`_
- channel on Discourse. See :ref:`breaking` for more details.
+- Adding, removing, or modifying command-line options.
+- Adding, removing, or regrouping a diagnostic.
+- Fixing a bug that potentially has significant user-facing impact (please link
+ to the issue fixed in the bug database).
+- Adding or removing optimizations that have widespread impact or enables new
+ programming paradigms.
+- Modifying a C stable API.
+- Notifying users about a potentially disruptive change expected to be made
+ in a future release, such as removal of a deprecated feature. In this case,
+ the release note should be added to a `Potentially Breaking Changes`
+ section of the notes with sufficient information and examples to
+ demonstrate the potential disruption. Additionally, any new entries to this
+ section should be announced in the
+ [Announcements](https://discourse.llvm.org/c/announce/) channel on
+ Discourse. See {ref}`breaking` for more details.
Code reviewers are encouraged to request a release note if they think one is
warranted when performing a code review.
-Quality
--------
+### Quality
The minimum quality standards that any change must satisfy before being
committed to the main development branch are:
-#. Code must adhere to the :doc:`LLVM Coding Standards <CodingStandards>`.
-
-#. Code must compile cleanly (no errors, no warnings) on at least one platform.
-
-#. Bug fixes and new features should `include a testcase`_ so we know if the
- fix/feature ever regresses in the future.
-
-#. Pull requests should build and pass premerge checks. For first-time
- contributors, this will require an initial cursory review to run the checks.
-
-#. Ensure that links in source code and test files point to publicly available
- resources and are used primarily to add additional information rather than to
- supply critical context. The surrounding comments should be sufficient to
- provide the context behind such links.
+1. Code must adhere to the {doc}`LLVM Coding Standards <CodingStandards>`.
+2. Code must compile cleanly (no errors, no warnings) on at least one
+ platform.
+3. Bug fixes and new features should {ref}`include a testcase <include a
+ testcase>` so we know if the fix/feature ever regresses in the future.
+4. Pull requests should build and pass premerge checks. For first-time
+ contributors, this will require an initial cursory review to run the
+ checks.
+5. Ensure that links in source code and test files point to publicly available
+ resources and are used primarily to add additional information rather than to
+ supply critical context. The surrounding comments should be sufficient to
+ provide the context behind such links.
Additionally, the committer is responsible for addressing any problems found in
-the future that the change is responsible for. For example:
-
-* The code needs to compile cleanly and pass tests on all stable `LLVM
- buildbots <https://lab.llvm.org/buildbot/>`_.
-
-* The changes should not cause any correctness regressions in the
- `llvm-test-suite <https://github.com/llvm/llvm-test-suite>`_
- and must not cause any major performance regressions.
-
-* The change set should not cause performance or correctness regressions for the
- LLVM tools. See `llvm-compile-time-tracker.com <https://llvm-compile-time-tracker.com>`_
-
-* The changes should not cause performance or correctness regressions in code
- compiled by LLVM on all applicable targets.
-
-* You are expected to address any `GitHub Issues
- <https://github.com/llvm/llvm-project/issues>`_ that result from your change.
-
-Our build bots and `nightly testing infrastructure
-<https://llvm.org/docs/lnt/intro.html>`_ find many of these issues. Build bots
-will directly email you if a group of commits that included yours caused a
-failure. You are expected to check the build bot messages to see if they are
-your fault and, if so, fix the breakage. However, keep in mind that if you
-receive such an email, it is highly likely that your change is not at fault.
-Changes are batched together precisely because these tests are generally too
-expensive to run continuously for every change.
+the future that the change is responsible for. For example:
+
+- The code needs to compile cleanly and pass tests on all stable [LLVM
+ buildbots](https://lab.llvm.org/buildbot/).
+- The changes should not cause any correctness regressions in the
+ [llvm-test-suite](https://github.com/llvm/llvm-test-suite) and must not
+ cause any major performance regressions.
+- The change set should not cause performance or correctness regressions for
+ the LLVM tools. See
+ [llvm-compile-time-tracker.com](https://llvm-compile-time-tracker.com)
+- The changes should not cause performance or correctness regressions in code
+ compiled by LLVM on all applicable targets.
+- You are expected to address any [GitHub
+ Issues](https://github.com/llvm/llvm-project/issues) that result from your
+ change.
+
+Our build bots and [nightly testing
+infrastructure](https://llvm.org/docs/lnt/intro.html) find many of these
+issues. Build bots will directly email you if a group of commits that included
+yours caused a failure. You are expected to check the build bot messages to see
+if they are your fault and, if so, fix the breakage. However, keep in mind that
+if you receive such an email, it is highly likely that your change is not at
+fault. Changes are batched together precisely because these tests are generally
+too expensive to run continuously for every change.
Commits that violate these quality standards may be reverted (see below). This
is necessary when the change blocks other developers from making progress. The
developer is welcome to re-commit the change after the problem has been fixed.
-
-.. _commit messages:
-
-Commit messages
----------------
+(commit messages)=
+### Commit messages
Although we don't enforce the format of commit messages, we prefer that
you follow these guidelines to help review, search in logs, email formatting
@@ -358,61 +326,54 @@ projects.
Commit messages should communicate briefly what the change does, but they
should really emphasize why a change is being made and provide useful context.
Commit messages should be thoughtfully written and specific, rather than vague.
-For example, "bits were not set right" will leave the reviewer wondering about
-which bits, and why they weren't right, while "Correctly set overflow bits in
-TargetInfo" conveys almost all there is to the change.
+For example, \"bits were not set right\" will leave the reviewer wondering about
+which bits, and why they weren't right, while \"Correctly set overflow bits in
+TargetInfo\" conveys almost all there is to the change.
Below are some guidelines about the format of the message itself:
-* Separate the commit message into title and body separated by a blank line.
-
-* In the situation where there are multiple authors, or in the rare situation
- you are submitting a change for someone else (e.g., after putting an old
- patch from someone else through review yourself), please use the `git
- tag 'Co-authored-by:' to list the additional authors
- <https://github.blog/2018-01-29-commit-together-with-co-authors/>`_.
- See `Attribution of Changes`_ for more information including the method we
- used for attribution before the project migrated to git.
-
-* The title should be concise. Because all commits are emailed to the list with
- the first line as the subject, long titles are frowned upon. Short titles
- also look better in `git log`.
-
-* When the changes are restricted to a specific part of the code (e.g. a
- back-end or optimization pass), it is customary to add a tag to the
- beginning of the line in square brackets. For example, "[SCEV] ..."
- or "[OpenMP] ...". This helps email filters and searches for post-commit
- reviews.
-
-* The body should be concise, but explanatory, including a complete
- rationale. Unless it is required to understand the change, examples,
- code snippets and gory details should be left to bug comments, web
- review or the mailing list.
-
-* Text formatting and spelling should follow the same rules as documentation
- and in-code comments, ex. capitalization, full stop, etc.
-
-* If the commit is a bug fix on top of another recently committed patch, or a
- revert or reapply of a patch, include the git commit hash of the prior
- related commit. This could be as simple as "Revert commit NNNN because it
- caused issue #".
-
-* If the patch has been reviewed, add a link to its review page, as shown
- `here <https://www.llvm.org/docs/Phabricator.html#committing-a-change>`__.
- If the patch fixes a bug in GitHub Issues, we encourage adding a reference to
- the issue being closed, as described
- `here <https://llvm.org/docs/BugLifeCycle.html#resolving-closing-bugs>`__.
-
-* It is also acceptable to add other metadata to the commit message to automate
- processes, including for downstream consumers. This metadata can include
- links to resources that are not available to the entire community. However,
- such links and/or metadata should not be used in place of making the commit
- message self-explanatory. Note that such non-public links should not be
- included in the submitted code.
-
-* Avoid 'tagging' someone's username in your commits and PR descriptions
- (e.g., `@<someUser>`), doing so results in that account receiving a notification
- every time the commit is cherry-picked and/or pushed to a fork.
+- Separate the commit message into title and body separated by a blank line.
+- In the situation where there are multiple authors, or in the rare situation
+ you are submitting a change for someone else (e.g., after putting an old
+ patch from someone else through review yourself), please use the [git tag
+ 'Co-authored-by:' to list the additional
+ authors](https://github.blog/2018-01-29-commit-together-with-co-authors/).
+ See [Attribution of Changes](#attribution-of-changes) for more information
+ including the method we used for attribution before the project migrated to
+ git.
+- The title should be concise. Because all commits are emailed to the list with
+ the first line as the subject, long titles are frowned upon. Short titles
+ also look better in `git log`.
+- When the changes are restricted to a specific part of the code (e.g. a
+ back-end or optimization pass), it is customary to add a tag to the
+ beginning of the line in square brackets. For example, \"\[SCEV\] \...\" or
+ \"\[OpenMP\] \...\". This helps email filters and searches for post-commit
+ reviews.
+- The body should be concise, but explanatory, including a complete
+ rationale. Unless it is required to understand the change, examples, code
+ snippets and gory details should be left to bug comments, web review or the
+ mailing list.
+- Text formatting and spelling should follow the same rules as documentation
+ and in-code comments, ex. capitalization, full stop, etc.
+- If the commit is a bug fix on top of another recently committed patch, or a
+ revert or reapply of a patch, include the git commit hash of the prior
+ related commit. This could be as simple as \"Revert commit NNNN because it
+ caused issue #\".
+- If the patch has been reviewed, add a link to its review page, as shown
+ [here](https://www.llvm.org/docs/Phabricator.html#committing-a-change). If
+ the patch fixes a bug in GitHub Issues, we encourage adding a reference to
+ the issue being closed, as described
+ [here](https://llvm.org/docs/BugLifeCycle.html#resolving-closing-bugs).
+- It is also acceptable to add other metadata to the commit message to automate
+ processes, including for downstream consumers. This metadata can include
+ links to resources that are not available to the entire community. However,
+ such links and/or metadata should not be used in place of making the commit
+ message self-explanatory. Note that such non-public links should not be
+ included in the submitted code.
+- Avoid 'tagging' someone's username in your commits and PR descriptions
+ (e.g., `@<someUser>`), doing so results in that account receiving a
+ notification every time the commit is cherry-picked and/or pushed to a
+ fork.
LLVM uses a squash workflow for pull requests, so as the pull request evolves
during review, it's important to update the pull request description over the
@@ -424,161 +385,157 @@ squashing and merging PRs.
For minor violations of these recommendations, the community normally favors
reminding the contributor of this policy over reverting.
-.. _revert_policy:
-
-Patch reversion policy
-----------------------
+(revert_policy)=
+### Patch reversion policy
As a community, we strongly value having the tip of tree in a good state while
-allowing rapid iterative development. As such, we tend to make much heavier
+allowing rapid iterative development. As such, we tend to make much heavier
use of reverts to keep the tree healthy than some other open source projects,
and our norms are a bit different.
How should you respond if someone reverted your change?
-* Remember, it is normal and healthy to have patches reverted. Having a patch
- reverted does not necessarily mean you did anything wrong.
-* We encourage explicitly thanking the person who reverted the patch for doing
- the task on your behalf.
-* If you need more information to address the problem, please follow up in the
- original commit thread with the reverting patch author.
+- Remember, it is normal and healthy to have patches reverted. Having a patch
+ reverted does not necessarily mean you did anything wrong.
+- We encourage explicitly thanking the person who reverted the patch for doing
+ the task on your behalf.
+- If you need more information to address the problem, please follow up in the
+ original commit thread with the reverting patch author.
When should you revert your own change?
-* Any time you learn of a serious problem with a change, you should revert it.
- We strongly encourage "revert to green" as opposed to "fixing forward". We
- encourage reverting first, investigating offline, and then reapplying the
- fixed patch - possibly after another round of review if warranted.
-* If you break a buildbot in a way which can't be quickly fixed, please revert.
-* If a test case that demonstrates a problem is reported in the commit thread,
- please revert and investigate offline.
-* If you receive substantial :ref:`post-commit review <post_commit_review>`
- feedback, please revert and address said feedback before recommitting.
- (Possibly after another round of review.)
-* If you are asked to revert by another contributor, please revert and discuss
- the merits of the request offline (unless doing so would further destabilize
- tip of tree).
+- Any time you learn of a serious problem with a change, you should revert
+ it. We strongly encourage \"revert to green\" as opposed to \"fixing
+ forward\". We encourage reverting first, investigating offline, and then
+ reapplying the fixed patch - possibly after another round of review if
+ warranted.
+- If you break a buildbot in a way which can't be quickly fixed, please
+ revert.
+- If a test case that demonstrates a problem is reported in the commit thread,
+ please revert and investigate offline.
+- If you receive substantial {ref}`post-commit review <post_commit_review>`
+ feedback, please revert and address said feedback before recommitting.
+ (Possibly after another round of review.)
+- If you are asked to revert by another contributor, please revert and
+ discuss the merits of the request offline (unless doing so would further
+ destabilize tip of tree).
When should you revert someone else's change?
-* In general, if the author themselves would revert the change per these
- guidelines, we encourage other contributors to do so as a courtesy to the
- author. This is one of the major cases where our norms differ from others;
- we generally consider reverting a normal part of development. We don't
- expect contributors to be always available, and the assurance that a
- problematic patch will be reverted and we can return to it at our next
- opportunity enables this.
+- In general, if the author themselves would revert the change per these
+ guidelines, we encourage other contributors to do so as a courtesy to the
+ author. This is one of the major cases where our norms differ from others;
+ we generally consider reverting a normal part of development. We don't
+ expect contributors to be always available, and the assurance that a
+ problematic patch will be reverted and we can return to it at our next
+ opportunity enables this.
What are the expectations around a revert?
-* Use your best judgment. If you're uncertain, please start an email on
- the commit thread asking for assistance. We aren't trying to enumerate
- every case, but rather give a set of guidelines.
-* You should be sure that reverting the change improves the stability of tip
- of tree. Sometimes, reverting one change in a series can worsen things
- instead of improving them. We expect reasonable judgment to ensure that
- the proper patch or set of patches is being reverted.
-* The commit message for the reverting commit should explain why patch
- is being reverted.
-* It is customary to respond to the original commit email mentioning the
- revert. This serves as both a notice to the original author that their
- patch was reverted, and helps others following llvm-commits track context.
-* Ideally, you should have a publicly reproducible test case ready to share.
- Where possible, we encourage sharing of test cases in commit threads, or
- in PRs. We encourage the reverter to minimize the test case and to prune
- dependencies where practical. This even applies when reverting your own
- patch; documenting the reasons for others who might be following along
- is critical.
-* It is not considered reasonable to revert without at least the promise to
- provide a means for the patch author to debug the root issue. If a situation
- arises where a public reproducer can not be shared for some reason (e.g.
- requires hardware patch author doesn't have access to, sharp regression in
- compile time of internal workload, etc.), the reverter is expected to be
- proactive about working with the patch author to debug and test candidate
- patches.
-* Reverts should be reasonably timely. A change submitted two hours ago
- can be reverted without prior discussion. A change submitted two years ago
- should not be. Where exactly the transition point is is hard to say, but
- it's probably in the handful of days in tree territory. If you are unsure,
- we encourage you to reply to the commit thread, give the author a bit to
- respond, and then proceed with the revert if the author doesn't seem to be
- actively responding.
-* When re-applying a reverted patch, the commit message should be updated to
- indicate the problem that was addressed and how it was addressed.
-
-.. _obtaining_commit_access:
-
-Obtaining Commit Access
------------------------
-
-Once you have 3 or more merged pull requests, you may use `this link
-<https://github.com/llvm/llvm-project/issues/new?title=Request%20Commit%20Access%20For%20%3Cuser%3E&body=%23%23%23%20Why%20Are%20you%20requesting%20commit%20access%20?>`_
-to file an issue and request commit access. Replace the <user> string in the title
-with your github username, and explain why you are requesting commit access in
-the issue description. Once the issue is created, you will need to get two
-current contributors to support your request before commit access will be granted.
-
-Reviewers of your committed patches will automatically be CCed upon creating the issue.
-Most commonly these reviewers will provide the necessary approval, but approvals
-from other LLVM committers are also acceptable. Those reviewing the application are
-confirming that you have indeed had three patches committed, and that based on interactions
-on those reviews and elsewhere in the LLVM community they have no concern about you
-adhering to our Developer Policy and Code of Conduct. Reviewers should clearly state their
-reasoning for accepting or rejecting the request, and finish with a clear statement such
-as "I approve of this request", "LGTM", or "I do not approve of this request".
-
+- Use your best judgment. If you're uncertain, please start an email on
+ the commit thread asking for assistance. We aren't trying to enumerate
+ every case, but rather give a set of guidelines.
+- You should be sure that reverting the change improves the stability of tip
+ of tree. Sometimes, reverting one change in a series can worsen things
+ instead of improving them. We expect reasonable judgment to ensure that
+ the proper patch or set of patches is being reverted.
+- The commit message for the reverting commit should explain why patch is
+ being reverted.
+- It is customary to respond to the original commit email mentioning the
+ revert. This serves as both a notice to the original author that their
+ patch was reverted, and helps others following llvm-commits track context.
+- Ideally, you should have a publicly reproducible test case ready to share.
+ Where possible, we encourage sharing of test cases in commit threads, or in
+ PRs. We encourage the reverter to minimize the test case and to prune
+ dependencies where practical. This even applies when reverting your own
+ patch; documenting the reasons for others who might be following along is
+ critical.
+- It is not considered reasonable to revert without at least the promise to
+ provide a means for the patch author to debug the root issue. If a
+ situation arises where a public reproducer can not be shared for some
+ reason (e.g. requires hardware patch author doesn't have access to, sharp
+ regression in compile time of internal workload, etc.), the reverter is
+ expected to be proactive about working with the patch author to debug and
+ test candidate patches.
+- Reverts should be reasonably timely. A change submitted two hours ago
+ can be reverted without prior discussion. A change submitted two years ago
+ should not be. Where exactly the transition point is is hard to say, but
+ it's probably in the handful of days in tree territory. If you are unsure,
+ we encourage you to reply to the commit thread, give the author a bit to
+ respond, and then proceed with the revert if the author doesn't seem to be
+ actively responding.
+- When re-applying a reverted patch, the commit message should be updated to
+ indicate the problem that was addressed and how it was addressed.
+
+(obtaining_commit_access)=
+### Obtaining Commit Access
+
+Once you have 3 or more merged pull requests, you may use [this
+link](https://github.com/llvm/llvm-project/issues/new?title=Request%20Commit%20Access%20For%20%3Cuser%3E&body=%23%23%23%20Why%20Are%20you%20requesting%20commit%20access%20?)
+to file an issue and request commit access. Replace the \<user\> string in the
+title with your github username, and explain why you are requesting commit
+access in the issue description. Once the issue is created, you will need to
+get two current contributors to support your request before commit access will
+be granted.
+
+Reviewers of your committed patches will automatically be CCed upon creating
+the issue. Most commonly these reviewers will provide the necessary approval,
+but approvals from other LLVM committers are also acceptable. Those reviewing
+the application are confirming that you have indeed had three patches
+committed, and that based on interactions on those reviews and elsewhere in the
+LLVM community they have no concern about you adhering to our Developer Policy
+and Code of Conduct. Reviewers should clearly state their reasoning for
+accepting or rejecting the request, and finish with a clear statement such as
+\"I approve of this request\", \"LGTM\", or \"I do not approve of this
+request\".
If approved, a GitHub invitation will be sent to your
GitHub account. In case you don't get notification from GitHub, go to
-`Invitation Link <https://github.com/orgs/llvm/invitation>`_ directly. Once
+[Invitation Link](https://github.com/orgs/llvm/invitation) directly. Once
you accept the invitation, you'll get commit access.
-Prior to obtaining commit access, it is common practice to request that
-someone with commit access commits on your behalf. When doing so, please
-provide the name and email address you would like to use in the Author
-property of the commit.
+Prior to obtaining commit access, it is common practice to request that someone
+with commit access commits on your behalf. When doing so, please provide the
+name and email address you would like to use in the Author property of the
+commit.
-For external tracking purposes, committed changes are automatically reflected on
-a commits mailing list soon after the commit lands (e.g.
-llvm-commits at lists.llvm.org). Note that these mailing lists are moderated, and
-it is not unusual for a large commit to require a moderator to approve the
+For external tracking purposes, committed changes are automatically reflected
+on a commits mailing list soon after the commit lands (e.g.
+<llvm-commits at lists.llvm.org>). Note that these mailing lists are moderated,
+and it is not unusual for a large commit to require a moderator to approve the
email, so do not be concerned if a commit does not immediately appear in the
archives.
If you have recently been granted commit access, these policies apply:
-#. You are granted *commit-after-approval* to all parts of LLVM. For
- information on how to get approval for a patch, please see :doc:`CodeReview`.
- When approved, you may commit it yourself.
-
-#. You are allowed to commit patches without approval which you think are
- obvious. This is clearly a subjective decision --- we simply expect you to
- use good judgement. Examples include: fixing build breakage, reverting
- obviously broken patches, documentation/comment changes, any other minor
- changes. Avoid committing formatting- or whitespace-only changes outside of
- code you plan to make subsequent changes to. Also, try to separate
- formatting or whitespace changes from functional changes, either by
- correcting the format first (ideally) or afterward. Such changes should be
- highly localized and the commit message should clearly state that the commit
- is not intended to change functionality, usually by stating it is
- :ref:`NFC <nfc>`.
-
-#. You are allowed to commit patches without approval to those portions of LLVM
- that you have contributed or maintain (i.e., have been assigned
- responsibility for), with the proviso that such commits must not break the
- build. This is a "trust but verify" policy, and commits of this nature are
- reviewed after they are committed.
-
-#. Multiple violations of these policies or a single egregious violation may
- cause commit access to be revoked.
-
-In any case, your changes are still subject to `code review`_ (either before or
-after they are committed, depending on the nature of the change). You are
-encouraged to review other peoples' patches as well, but you aren't required
-to do so.
-
-Obtaining Other Access or Permissions
--------------------------------------
+1. You are granted *commit-after-approval* to all parts of LLVM. For
+ information on how to get approval for a patch, please see
+ {doc}`CodeReview`. When approved, you may commit it yourself.
+2. You are allowed to commit patches without approval which you think are
+ obvious. This is clearly a subjective decision \-\-- we simply expect you to
+ use good judgement. Examples include: fixing build breakage, reverting
+ obviously broken patches, documentation/comment changes, any other minor
+ changes. Avoid committing formatting- or whitespace-only changes outside of
+ code you plan to make subsequent changes to. Also, try to separate
+ formatting or whitespace changes from functional changes, either by
+ correcting the format first (ideally) or afterward. Such changes should be
+ highly localized and the commit message should clearly state that the commit
+ is not intended to change functionality, usually by stating it is
+ {ref}`NFC <nfc>`.
+3. You are allowed to commit patches without approval to those portions of LLVM
+ that you have contributed or maintain (i.e., have been assigned
+ responsibility for), with the proviso that such commits must not break the
+ build. This is a \"trust but verify\" policy, and commits of this nature are
+ reviewed after they are committed.
+4. Multiple violations of these policies or a single egregious violation may
+ cause commit access to be revoked.
+
+In any case, your changes are still subject to {ref}`code review <code review>`
+(either before or after they are committed, depending on the nature of the
+change). You are encouraged to review other peoples' patches as well, but you
+aren't required to do so.
+
+### Obtaining Other Access or Permissions
To obtain access other than commit access, you can raise an issue like the one
for obtaining commit access. However, instead of including PRs you have authored,
@@ -588,29 +545,25 @@ For example, if you are helping to triage issues and want the ability to add
labels, include links to issues you have triaged previously and explain how
having this ability would help that work.
-.. _discuss the change/gather consensus:
-
-Proposing Major Changes (RFCs)
-------------------------------
+(discuss the change/gather consensus)=
+### Proposing Major Changes (RFCs)
The design of LLVM is carefully controlled to ensure that all the pieces fit
together well and are as consistent as possible. If you plan to make a major
change to the way LLVM works or want to add a major new extension, it is a good
idea to get consensus with the development community before you invest
-significant effort in an implementation. Prototype implementations, however, can
-often be helpful in making design discussions more concrete by demonstrating
-what is possible.
+significant effort in an implementation. Prototype implementations, however,
+can often be helpful in making design discussions more concrete by
+demonstrating what is possible.
LLVM is a large community with many stakeholders, and before landing any major
change, it is important to discuss the design of a change publicly with the
-community. This is done by posting a Request For Comments (RFC) on the `LLVM
-Discourse forums`_. See the :doc:`RFC process <RFCProcess>` documentation for
-more details.
-
-.. _incremental-changes:
+community. This is done by posting a Request For Comments (RFC) on the [LLVM
+Discourse forums](https://discourse.llvm.org). See the {doc}`RFC process
+<RFCProcess>` documentation for more details.
-Incremental Development
------------------------
+(incremental-changes)=
+### Incremental Development
In the LLVM project, we prefer the incremental development approach, where
significant changes are developed in-tree incrementally. The alternative
@@ -618,58 +571,49 @@ approach of implementing features in long-lived development branches or forks
is discouraged, although we have accepted features developed this way in the
past. Long-term development branches have a number of drawbacks:
-#. Branches must have mainline merged into them periodically. If the branch
- development and mainline development occur in the same pieces of code,
- resolving merge conflicts can take a lot of time.
-
-#. Other people in the community tend to ignore work on branches.
-
-#. Huge changes (produced when a branch is merged back onto mainline) are
- extremely difficult to `code review`_.
-
-#. Branches are not routinely tested by our nightly tester infrastructure.
-
-#. Changes developed as monolithic large changes often don't work until the
- entire set of changes is done. Breaking it down into a set of smaller
- changes increases the odds that any of the work will be committed to the main
- repository.
+1. Branches must have mainline merged into them periodically. If the branch
+ development and mainline development occur in the same pieces of code,
+ resolving merge conflicts can take a lot of time.
+2. Other people in the community tend to ignore work on branches.
+3. Huge changes (produced when a branch is merged back onto mainline) are
+ extremely difficult to {ref}`code review <code review>`.
+4. Branches are not routinely tested by our nightly tester infrastructure.
+5. Changes developed as monolithic large changes often don't work until the
+ entire set of changes is done. Breaking it down into a set of smaller
+ changes increases the odds that any of the work will be committed to the
+ main repository.
To address these problems, LLVM uses an incremental development style and we
require contributors to follow this practice when making a large/invasive
-change. Some tips:
-
-* Large/invasive changes usually have a number of secondary changes that are
- required before the big change can be made (e.g. API cleanup, etc). These
- sorts of changes can often be done before the major change is done,
- independently of that work.
-
-* The remaining inter-related work should be decomposed into unrelated sets of
- changes if possible. Once this is done, define the first increment and get
- consensus on what the end goal of the change is.
-
-* Each change in the set can be stand alone (e.g. to fix a bug), or part of a
- planned series of changes that works towards the development goal.
-
-* Each change should be kept as small as possible. This simplifies your work
- (into a logical progression), simplifies code review and reduces the chance
- that you will get negative feedback on the change. Small increments also
- facilitate the maintenance of a high quality code base.
-
-* Often, an independent precursor to a big change is to add a new API and slowly
- migrate clients to use the new API. Each change to use the new API is often
- "obvious" and can be committed without review. Once the new API is in place
- and used, it is much easier to replace the underlying implementation of the
- API. This implementation change is logically separate from the API
- change.
-
-If you are interested in making a large change, and this scares you, please make
-sure to first `discuss the change/gather consensus`_ then ask about the best way
-to go about making the change.
-
-.. _breaking:
-
-Making Potentially Breaking Changes
------------------------------------
+change. Some tips:
+
+- Large/invasive changes usually have a number of secondary changes that are
+ required before the big change can be made (e.g. API cleanup, etc). These
+ sorts of changes can often be done before the major change is done,
+ independently of that work.
+- The remaining inter-related work should be decomposed into unrelated sets of
+ changes if possible. Once this is done, define the first increment and get
+ consensus on what the end goal of the change is.
+- Each change in the set can be stand alone (e.g. to fix a bug), or part of a
+ planned series of changes that works towards the development goal.
+- Each change should be kept as small as possible. This simplifies your work
+ (into a logical progression), simplifies code review and reduces the chance
+ that you will get negative feedback on the change. Small increments also
+ facilitate the maintenance of a high quality code base.
+- Often, an independent precursor to a big change is to add a new API and
+ slowly migrate clients to use the new API. Each change to use the new API
+ is often \"obvious\" and can be committed without review. Once the new API
+ is in place and used, it is much easier to replace the underlying
+ implementation of the API. This implementation change is logically separate
+ from the API change.
+
+If you are interested in making a large change, and this scares you, please
+make sure to first {ref}`discuss the change/gather consensus <discuss the
+change/gather consensus>` then ask about the best way to go about making the
+change.
+
+(breaking)=
+### Making Potentially Breaking Changes
Please help notify users and vendors of potential disruptions when upgrading to
a newer version of a tool. For example, deprecating a feature that is expected
@@ -678,52 +622,51 @@ a diagnostic from a warning to an error, switching important default behavior,
or any other potentially disruptive situation thought to be worth raising
awareness of. For such changes, the following should be done:
-* When performing the code review for the change, please add any applicable
- "vendors" github team to the review for their awareness. The purpose of these
- groups is to give vendors early notice that potentially disruptive changes
- are being considered but have not yet been accepted. Vendors can give early
- testing feedback on the changes to alert us to unacceptable breakages. The
- current list of vendor groups is:
-
- * `Clang vendors <https://github.com/orgs/llvm/teams/clang-vendors>`_
- * `libc++ vendors <https://github.com/orgs/llvm/teams/libcxx-vendors>`_
-
- People interested in joining the vendors group can do so by clicking the
- "Join team" button on the linked github pages above.
-
-* When committing the change to the repository, add appropriate information
- about the potentially breaking changes to the ``Potentially Breaking Changes``
- section of the project's release notes. The release note should have
- information about what the change is, what is potentially disruptive about
- it, as well as any code examples, links, and motivation that is appropriate
- to share with users. This helps users to learn about potential issues with
- upgrading to that release.
-
-* After the change has been committed to the repository, the potentially
- disruptive changes described in the release notes should be posted to the
- `Announcements <https://discourse.llvm.org/c/announce/>`_ channel on
- Discourse. The post should be tagged with the ``potentially-breaking`` label
- and a label specific to the project (such as ``clang``, ``llvm``, etc). This
- is another mechanism by which we can give pre-release notice to users about
- potentially disruptive changes. It is a lower-traffic alternative to the
- joining "vendors" group. To automatically be notified of new announcements
- with the ``potentially-breaking`` label, go to your user preferences page in
- Discourse, and add the label to one of the watch categories under
- ``Notifications->Tags``.
-
-Attribution of Changes
-----------------------
+- When performing the code review for the change, please add any applicable
+ \"vendors\" github team to the review for their awareness. The purpose of
+ these groups is to give vendors early notice that potentially disruptive
+ changes are being considered but have not yet been accepted. Vendors can
+ give early testing feedback on the changes to alert us to unacceptable
+ breakages. The current list of vendor groups is:
+
+ - [Clang vendors](https://github.com/orgs/llvm/teams/clang-vendors)
+ - [libc++ vendors](https://github.com/orgs/llvm/teams/libcxx-vendors)
+
+ People interested in joining the vendors group can do so by clicking the
+ \"Join team\" button on the linked github pages above.
+
+- When committing the change to the repository, add appropriate information
+ about the potentially breaking changes to the `Potentially Breaking Changes`
+ section of the project's release notes. The release note should have
+ information about what the change is, what is potentially disruptive about
+ it, as well as any code examples, links, and motivation that is appropriate
+ to share with users. This helps users to learn about potential issues with
+ upgrading to that release.
+
+- After the change has been committed to the repository, the potentially
+ disruptive changes described in the release notes should be posted to the
+ [Announcements](https://discourse.llvm.org/c/announce/) channel on
+ Discourse. The post should be tagged with the `potentially-breaking` label
+ and a label specific to the project (such as `clang`, `llvm`, etc). This is
+ another mechanism by which we can give pre-release notice to users about
+ potentially disruptive changes. It is a lower-traffic alternative to the
+ joining \"vendors\" group. To automatically be notified of new
+ announcements with the `potentially-breaking` label, go to your user
+ preferences page in Discourse, and add the label to one of the watch
+ categories under `Notifications->Tags`.
+
+### Attribution of Changes
When contributors submit a patch to an LLVM project, other developers with
-commit access may merge the PR for the author (based on the
-progression of code review, etc.). GitHub will automatically ensure that
-authorship is preserved, and one does not need to take any further action. We
-do not want the source code to be littered with random attributions "this code
-written by J. Random Hacker" (this is noisy and distracting). In practice, the
-revision control system keeps a perfect history of who changed what, and the
-CREDITS.txt file describes higher-level contributions. If you need to adjust
-authorship for any reason, please follow the attribution of changes in the
-simple manner as outlined by the `commit messages`_ section. Overall, please do
+commit access may merge the PR for the author (based on the progression of code
+review, etc.). GitHub will automatically ensure that authorship is preserved,
+and one does not need to take any further action. We do not want the source
+code to be littered with random attributions \"this code written by J. Random
+Hacker\" (this is noisy and distracting). In practice, the revision control
+system keeps a perfect history of who changed what, and the CREDITS.txt file
+describes higher-level contributions. If you need to adjust authorship for any
+reason, please follow the attribution of changes in the simple manner as
+outlined by the [commit messages](#commit-messages) section. Overall, please do
not add contributor names to the source code.
Also, don't commit patches authored by others unless they have submitted the
@@ -733,21 +676,20 @@ etc.). The author should first submit them as a GitHub issue, to the relevant
category on Discourse, or ideally as a GitHub Pull Request. If someone sends you
a patch privately, encourage them to submit it as a GitHub PR first.
-Our previous version control system (subversion) did not distinguish between the
-author and the committer like git does. As such, older commits used a different
-attribution mechanism. The previous method was to include "Patch by John Doe."
-in a separate line of the commit message and there are automated processes that
-rely on this format.
+Our previous version control system (subversion) did not distinguish between
+the author and the committer like git does. As such, older commits used a
+different attribution mechanism. The previous method was to include \"Patch by
+John Doe.\" in a separate line of the commit message and there are automated
+processes that rely on this format.
-Bans
-----
+### Bans
The goal of a ban is to protect people in the community from having to interact
-with people who are consistently not respecting the
-:ref:`LLVM Community Code of Conduct` in LLVM project spaces. Contributions of
-any variety (pull requests, issue reports, forum posts, etc.) require
-interacting with the community. Therefore, we do not accept any form of direct
-contribution from a banned individual.
+with people who are consistently not respecting the {ref}`LLVM Community Code
+of Conduct` in LLVM project spaces. Contributions of any variety (pull
+requests, issue reports, forum posts, etc.) require interacting with the
+community. Therefore, we do not accept any form of direct contribution from a
+banned individual.
Indirect contributions are permissible only by someone taking full ownership of
such a contribution and they are responsible for all related interactions with
@@ -756,122 +698,100 @@ the community regarding that contribution.
Trying to evade a non-permanent ban results in getting banned permanently.
When in doubt how to act in a specific instance, please reach out to
-conduct at llvm.org for advice.
+<conduct at llvm.org> for advice.
-
-.. _IR backwards compatibility:
-
-IR Backwards Compatibility
---------------------------
+(IR backwards compatibility)=
+### IR Backwards Compatibility
When the IR format has to be changed, keep in mind that we try to maintain some
backwards compatibility. The rules are intended as a balance between convenience
for llvm users and not imposing a big burden on llvm developers:
-* The textual format is not backwards compatible. We don't change it too often,
- but there are no specific promises.
-
-* Additions and changes to the IR should be reflected in
- ``test/Bitcode/compatibility.ll``.
-
-* The current LLVM version supports loading any bitcode since version 3.0.
-
-* After each X.Y release, ``compatibility.ll`` must be copied to
- ``compatibility-X.Y.ll``. The corresponding bitcode file should be assembled
- using the X.Y build and committed as ``compatibility-X.Y.ll.bc``.
-
-* Newer releases can ignore features from older releases, but they cannot
- miscompile them. For example, if nsw is ever replaced with something else,
- dropping it would be a valid way to upgrade the IR.
-
-* Debug metadata is special in that it is currently dropped during upgrades.
-
-* Non-debug metadata is defined to be safe to drop, so a valid way to upgrade
- it is to drop it. That is not very user friendly and a bit more effort is
- expected, but no promises are made.
-
-* Legacy bitcode may have degraded performance when compared to
- the compiled output with the legacy compiler.
-
-C API Changes
--------------
-
-* Stability Guarantees: The C API is, in general, a "best effort" for stability.
- This means that we make every attempt to keep the C API stable, but that
- stability will be limited by the abstractness of the interface and the
- stability of the C++ API that it wraps. In practice, this means that things
- like "create debug info" or "create this type of instruction" are likely to be
- less stable than "take this IR file and JIT it for my current machine".
-
-* Release stability: We won't break the C API on the release branch with patches
- that go on that branch, with the exception that we will fix an unintentional
- C API break that will keep the release consistent with both the previous and
- next release.
-
-* Testing: Patches to the C API are expected to come with tests just like any
- other patch.
-
-* Including new things into the API: If an LLVM subcomponent has a C API already
- included, then expanding that C API is acceptable. Adding C API for
- subcomponents that don't currently have one needs to be discussed on the
- `LLVM Discourse forums`_ for design and maintainability feedback prior to implementation.
-
-* Documentation: Any changes to the C API are required to be documented in the
- release notes so that it's clear to external users who do not follow the
- project how the C API is changing and evolving.
-
-.. _toolchain:
-
-Updating Toolchain Requirements
--------------------------------
+- The textual format is not backwards compatible. We don't change it too often,
+ but there are no specific promises.
+- Additions and changes to the IR should be reflected in
+ `test/Bitcode/compatibility.ll`.
+- The current LLVM version supports loading any bitcode since version 3.0.
+- After each X.Y release, `compatibility.ll` must be copied to
+ `compatibility-X.Y.ll`. The corresponding bitcode file should be assembled
+ using the X.Y build and committed as `compatibility-X.Y.ll.bc`.
+- Newer releases can ignore features from older releases, but they cannot
+ miscompile them. For example, if nsw is ever replaced with something else,
+ dropping it would be a valid way to upgrade the IR.
+- Debug metadata is special in that it is currently dropped during upgrades.
+- Non-debug metadata is defined to be safe to drop, so a valid way to upgrade
+ it is to drop it. That is not very user friendly and a bit more effort is
+ expected, but no promises are made.
+- Legacy bitcode may have degraded performance when compared to
+ the compiled output with the legacy compiler.
+
+### C API Changes
+
+- Stability Guarantees: The C API is, in general, a \"best effort\" for
+ stability. This means that we make every attempt to keep the C API stable,
+ but that stability will be limited by the abstractness of the interface and
+ the stability of the C++ API that it wraps. In practice, this means that
+ things like \"create debug info\" or \"create this type of instruction\"
+ are likely to be less stable than \"take this IR file and JIT it for my
+ current machine\".
+- Release stability: We won't break the C API on the release branch with
+ patches that go on that branch, with the exception that we will fix an
+ unintentional C API break that will keep the release consistent with both
+ the previous and next release.
+- Testing: Patches to the C API are expected to come with tests just like any
+ other patch.
+- Including new things into the API: If an LLVM subcomponent has a C API
+ already included, then expanding that C API is acceptable. Adding C API for
+ subcomponents that don't currently have one needs to be discussed on the
+ [LLVM Discourse forums](https://discourse.llvm.org) for design and
+ maintainability feedback prior to implementation.
+- Documentation: Any changes to the C API are required to be documented in the
+ release notes so that it's clear to external users who do not follow the
+ project how the C API is changing and evolving.
+
+(toolchain)=
+### Updating Toolchain Requirements
We intend to require newer toolchains as time goes by. This means LLVM's
codebase can use newer versions of C++ as they get standardized. Requiring newer
toolchains to build LLVM can be painful for those building LLVM; therefore, it
will only be done through the following process:
- * It is a general goal to support LLVM and GCC versions from the last 3 years
- at a minimum. This time-based guideline is not strict: we may support much
- older compilers, or decide to support fewer versions.
-
- * An RFC is sent to the `LLVM Discourse forums`_
-
- - Detail upsides of the version increase (e.g. which newer C++ language or
- library features LLVM should use; avoid miscompiles in particular compiler
- versions, etc).
- - Detail downsides on important platforms (e.g. Ubuntu LTS status).
- - See the :doc:`RFC process <RFCProcess>` documentation for more details.
-
- * Once the RFC reaches consensus, update the CMake toolchain version checks as
- well as the :doc:`getting started<GettingStarted>` guide. This provides a
- softer transition path for developers compiling LLVM, because the
- error can be turned into a warning using a CMake flag. This is an important
- step: LLVM still doesn't have code which requires the new toolchains, but it
- soon will. If you compile LLVM but don't read the forums, we should
- tell you!
-
- * Ensure that at least one LLVM release has had this soft-error. Not all
- developers compile LLVM top-of-tree. These release-bound developers should
- also be told about upcoming changes.
-
- * Turn the soft-error into a hard-error after said LLVM release has branched.
-
- * Update the :doc:`coding standards<CodingStandards>` to allow the new
- features we've explicitly approved in the RFC.
-
- * Start using the new features in LLVM's codebase.
-
-Here's a `sample RFC
-<https://discourse.llvm.org/t/rfc-migrating-past-c-11/50943>`_ and the
-`corresponding change <https://reviews.llvm.org/D57264>`_.
-
-.. _ci-usage:
-
-Working with the CI system
---------------------------
+- It is a general goal to support LLVM and GCC versions from the last 3
+ years at a minimum. This time-based guideline is not strict: we may
+ support much older compilers, or decide to support fewer versions.
+- An RFC is sent to the [LLVM Discourse forums](https://discourse.llvm.org)
+ - Detail upsides of the version increase (e.g. which newer C++ language
+ or library features LLVM should use; avoid miscompiles in particular
+ compiler versions, etc).
+ - Detail downsides on important platforms (e.g. Ubuntu LTS status).
+ - See the {doc}`RFC process <RFCProcess>` documentation for more
+ details.
+- Once the RFC reaches consensus, update the CMake toolchain version checks
+ as well as the {doc}`getting started<GettingStarted>` guide. This
+ provides a softer transition path for developers compiling LLVM, because
+ the error can be turned into a warning using a CMake flag. This is an
+ important step: LLVM still doesn't have code which requires the new
+ toolchains, but it soon will. If you compile LLVM but don't read the
+ forums, we should tell you!
+- Ensure that at least one LLVM release has had this soft-error. Not all
+ developers compile LLVM top-of-tree. These release-bound developers
+ should also be told about upcoming changes.
+- Turn the soft-error into a hard-error after said LLVM release has
+ branched.
+- Update the {doc}`coding standards<CodingStandards>` to allow the new
+ features we've explicitly approved in the RFC.
+- Start using the new features in LLVM's codebase.
+
+Here's a [sample
+RFC](https://discourse.llvm.org/t/rfc-migrating-past-c-11/50943) and the
+[corresponding change](https://reviews.llvm.org/D57264).
+
+(ci-usage)=
+### Working with the CI system
The main continuous integration (CI) tool for the LLVM project is the
-`LLVM Buildbot <https://lab.llvm.org/buildbot/>`_. It uses different *builders*
+[LLVM Buildbot](https://lab.llvm.org/buildbot/). It uses different *builders*
to cover a wide variety of sub-projects and configurations. The builds are
executed on different *workers*. Builders and workers are configured and
provided by community members.
@@ -884,61 +804,61 @@ their patch with every possible configuration.
*If your commit broke the build:*
-* Fix the build as soon as possible as this might block other contributors or
- downstream users.
-* If you need more time to analyze and fix the bug, please revert your change to
- unblock others.
+- Fix the build as soon as possible as this might block other contributors or
+ downstream users.
+- If you need more time to analyze and fix the bug, please revert your change
+ to unblock others.
*If someone else broke the build and this blocks your work*
-* Comment on the code review in `GitHub <https://github.com/llvm/llvm-project/pulls>`_
- (if available) or email the author, explain the problem and how this impacts
- you. Add a link to the broken build and the error message so folks can
- understand the problem.
-* Revert the commit if this blocks your work, see revert_policy_ .
+- Comment on the code review in
+ [GitHub](https://github.com/llvm/llvm-project/pulls) (if available) or
+ email the author, explain the problem and how this impacts you. Add a link
+ to the broken build and the error message so folks can understand the
+ problem.
+- Revert the commit if this blocks your work, see
+ [revert_policy](#revert_policy) .
*If a build/worker is permanently broken*
-* 1st step: contact the owner of the worker. You can find the name and contact
- information for the *Admin* of worker on the page of the build in the
- *Worker* tab:
+- 1st step: contact the owner of the worker. You can find the name and
+ contact information for the *Admin* of worker on the page of the build in
+ the *Worker* tab:
- .. image:: buildbot_worker_contact.png
+ 
-* 2nd step: If the owner does not respond or fix the worker, please escalate
- to Galina Kostanova, the maintainer of the BuildBot master.
-* 3rd step: If Galina could not help you, please escalate to the
- `Infrastructure Working Group <mailto:iwg at llvm.org>`_.
+- 2nd step: If the owner does not respond or fix the worker, please escalate
+ to Galina Kostanova, the maintainer of the BuildBot master.
-.. _new-llvm-components:
+- 3rd step: If Galina could not help you, please escalate to the
+ [Infrastructure Working Group](mailto:iwg at llvm.org).
-Introducing New Components into LLVM
-====================================
+(new-llvm-components)=
+## Introducing New Components into LLVM
The LLVM community is a vibrant and exciting place to be, and we look to be
inclusive of new projects and foster new communities, and increase
collaboration across industry and academia.
That said, we need to strike a balance between being inclusive of new ideas and
-people and the cost of ongoing maintenance that new code requires. As such, we
-have a general :doc:`support policy<SupportPolicy>` for introducing major new
+people and the cost of ongoing maintenance that new code requires. As such, we
+have a general {doc}`support policy<SupportPolicy>` for introducing major new
components into the LLVM world, depending on the degree of detail and
responsibility required. *Core* projects need a higher degree of scrutiny
than *peripheral* projects, and the latter may have additional differences.
-However, this is really only intended to cover common cases
-that we have seen arise: different situations are different, and we are open
-to discussing unusual cases as well - just start an RFC thread on the
-`LLVM Discourse forums`_.
+However, this is really only intended to cover common cases that we have seen
+arise: different situations are different, and we are open to discussing
+unusual cases as well - just start an RFC thread on the [LLVM Discourse
+forums](https://discourse.llvm.org).
-Adding a New Target
--------------------
+### Adding a New Target
LLVM is very receptive to new targets, even experimental ones, but a number of
problems can appear when adding new large portions of code, and back-ends are
normally added in bulk. New targets need the same level of support as other
*core* parts of the compiler, so they are covered in the *core tier* of our
-:doc:`support policy<SupportPolicy>`.
+{doc}`support policy<SupportPolicy>`.
We have found that landing large pieces of new code and then trying to fix
emergent problems in-tree is problematic for a variety of reasons. For these
@@ -947,74 +867,64 @@ proven stable, and later moved to non-experimental.
The differences between both classes are:
-* Experimental targets are not built by default (they need to be explicitly
- enabled at CMake time).
-
-* Test failures, bugs, and build breakages that only appear when the
- experimental target is enabled, caused by changes unrelated to the target, are
- the responsibility of the community behind the target to fix.
+- Experimental targets are not built by default (they need to be explicitly
+ enabled at CMake time).
+- Test failures, bugs, and build breakages that only appear when the
+ experimental target is enabled, caused by changes unrelated to the target, are
+ the responsibility of the community behind the target to fix.
The basic rules for a back-end to be upstreamed in **experimental** mode are:
-* Every target must have at least one :ref:`maintainer<maintainers>`. The
- `Maintainers.md` file has to be updated as part of the first merge. These
- maintainers make sure that changes to the target get reviewed and steers the
- overall effort.
-
-* There must be an active community behind the target. This community
- will help maintain the target by providing buildbots, fixing
- bugs, answering the LLVM community's questions and making sure the new
- target doesn't break any of the other targets, or generic code. This
- behavior is expected to continue throughout the lifetime of the
- target's code.
-
-* The code must be free of contentious issues, for example, large
- changes in how the IR behaves or should be formed by the front-ends,
- unless agreed by the majority of the community via refactoring of the
- (:doc:`IR standard<LangRef>`) **before** the merge of the new target changes,
- following the :ref:`IR backwards compatibility`.
-
-* The code conforms to all of the policies laid out in this developer policy
- document, including license, patent, and coding standards.
-
-* The target should have either reasonable documentation on how it
- works (ISA, ABI, etc.) or a publicly available simulator/hardware
- (either free or cheap enough) - preferably both. This allows
- developers to validate assumptions, understand constraints and review code
- that can affect the target.
+- Every target must have at least one {ref}`maintainer<maintainers>`. The
+ `Maintainers.md` file has to be updated as part of the first merge. These
+ maintainers make sure that changes to the target get reviewed and steers
+ the overall effort.
+- There must be an active community behind the target. This community will
+ help maintain the target by providing buildbots, fixing bugs, answering the
+ LLVM community's questions and making sure the new target doesn't break any
+ of the other targets, or generic code. This behavior is expected to
+ continue throughout the lifetime of the target's code.
+- The code must be free of contentious issues, for example, large
+ changes in how the IR behaves or should be formed by the front-ends,
+ unless agreed by the majority of the community via refactoring of the
+ ({doc}`IR standard<LangRef>`) **before** the merge of the new target changes,
+ following the {ref}`IR backwards compatibility`.
+- The code conforms to all of the policies laid out in this developer policy
+ document, including license, patent, and coding standards.
+- The target should have either reasonable documentation on how it works
+ (ISA, ABI, etc.) or a publicly available simulator/hardware (either free or
+ cheap enough) - preferably both. This allows developers to validate
+ assumptions, understand constraints and review code that can affect the
+ target.
In addition, the rules for a back-end to be promoted to **official** are:
-* The target must have addressed every other minimum requirement and
- have been stable in tree for at least 3 months. This cool down
- period is to make sure that the back-end and the target community can
- endure continuous upstream development for the foreseeable future.
-
-* The target's code must have been completely adapted to this policy
- as well as the :doc:`coding standards<CodingStandards>`. Any exceptions that
- were made to move into experimental mode must have been fixed **before**
- becoming official.
-
-* The test coverage needs to be broad and well written (small tests,
- well documented). The build target ``check-all`` must pass with the
- new target built, and where applicable, the ``test-suite`` must also
- pass without errors, in at least one configuration (publicly
- demonstrated, for example, via buildbots).
-
-* Public buildbots need to be created and actively maintained, unless
- the target requires no additional buildbots (ex. ``check-all`` covers
- all tests). The more relevant and public the new target's CI infrastructure
- is, the more the LLVM community will embrace it.
+- The target must have addressed every other minimum requirement and
+ have been stable in tree for at least 3 months. This cool down
+ period is to make sure that the back-end and the target community can
+ endure continuous upstream development for the foreseeable future.
+- The target's code must have been completely adapted to this policy
+ as well as the {doc}`coding standards<CodingStandards>`. Any exceptions that
+ were made to move into experimental mode must have been fixed **before**
+ becoming official.
+- The test coverage needs to be broad and well written (small tests, well
+ documented). The build target `check-all` must pass with the new target
+ built, and where applicable, the `test-suite` must also pass without
+ errors, in at least one configuration (publicly demonstrated, for example,
+ via buildbots).
+- Public buildbots need to be created and actively maintained, unless
+ the target requires no additional buildbots (ex. `check-all` covers
+ all tests). The more relevant and public the new target's CI infrastructure
+ is, the more the LLVM community will embrace it.
To **continue** as a supported and official target:
-* The maintainer(s) must continue following these rules throughout the lifetime
- of the target. Continuous violations of aforementioned rules and policies
- could lead to complete removal of the target from the code base.
-
-* Degradation in support, documentation or test coverage will make the target as
- nuisance to other targets and be considered a candidate for deprecation and
- ultimately removed.
+- The maintainer(s) must continue following these rules throughout the lifetime
+ of the target. Continuous violations of aforementioned rules and policies
+ could lead to complete removal of the target from the code base.
+- Degradation in support, documentation or test coverage will make the target
+ as nuisance to other targets and be considered a candidate for deprecation
+ and ultimately removed.
In essence, these rules are necessary for targets to gain and retain their
status, but also markers to define bit-rot, and will be used to clean up the
@@ -1023,144 +933,148 @@ tree from unmaintained targets.
Those wishing to add a new target to LLVM must follow the procedure below:
1. Read this section and make sure your target follows all requirements. For
- minor issues, your community will be responsible for making all necessary
- adjustments soon after the initial merge.
-2. Send a request for comment (RFC) to the `LLVM Discourse forums`_ describing
- your target and how it follows all the requirements and what work has been
- done and will need to be done to accommodate the official target requirements.
- Make sure to expose any and all controversial issues, changes needed in the
- base code, table gen, etc. See the :doc:`RFC process <RFCProcess>`
- documentation for more details.
+ minor issues, your community will be responsible for making all necessary
+ adjustments soon after the initial merge.
+2. Send a request for comment (RFC) to the [LLVM Discourse
+ forums](https://discourse.llvm.org) describing your target and how it
+ follows all the requirements and what work has been done and will need to
+ be done to accommodate the official target requirements. Make sure to
+ expose any and all controversial issues, changes needed in the base code,
+ table gen, etc. See the {doc}`RFC process <RFCProcess>` documentation for
+ more details.
3. Once the response is positive, the LLVM community can start reviewing the
- actual patches (but they can be prepared before, to support the RFC). Create
- a sequence of N patches, numbered '1/N' to 'N/N' (make sure N is an actual
- number, not the letter 'N'), that completes the basic structure of the target.
-4. The initial patch should add documentation, maintainers, and triple support in
- clang and LLVM. The following patches add TableGen infrastructure to describe
- the target and lower instructions to assembly. The final patch must show that
- the target can lower correctly with extensive LIT tests (IR to MIR, MIR to
- ASM, etc).
+ actual patches (but they can be prepared before, to support the RFC).
+ Create a sequence of N patches, numbered '1/N' to 'N/N' (make sure N is an
+ actual number, not the letter 'N'), that completes the basic structure of
+ the target.
+4. The initial patch should add documentation, maintainers, and triple support
+ in clang and LLVM. The following patches add TableGen infrastructure to
+ describe the target and lower instructions to assembly. The final patch
+ must show that the target can lower correctly with extensive LIT tests (IR
+ to MIR, MIR to ASM, etc).
5. Some patches may be approved before others, but only after *all* patches are
- approved that the whole set can be merged in one go. This is to guarantee
- that all changes are good as a single block.
+ approved that the whole set can be merged in one go. This is to guarantee
+ that all changes are good as a single block.
6. After the initial merge, the target community can stop numbering patches and
- start working asynchronously on the target to complete support. They should
- still seek review from those who helped them in the initial phase, to make
- sure the progress is still consistent.
-7. Once all official requirements have been fulfilled (as above), the maintainers
- should request the target to be enabled by default by sending another RFC to
- the `LLVM Discourse forums`_.
+ start working asynchronously on the target to complete support. They should
+ still seek review from those who helped them in the initial phase, to make
+ sure the progress is still consistent.
+7. Once all official requirements have been fulfilled (as above), the
+ maintainers should request the target to be enabled by default by sending
+ another RFC to the [LLVM Discourse forums](https://discourse.llvm.org).
-Adding an Established Project To the LLVM Monorepo
---------------------------------------------------
+### Adding an Established Project To the LLVM Monorepo
-The `LLVM monorepo <https://github.com/llvm/llvm-project>`_ is the centerpoint
+The [LLVM monorepo](https://github.com/llvm/llvm-project) is the centerpoint
of development in the LLVM world, and has all of the primary LLVM components,
-including the LLVM optimizer and code generators, Clang, LLDB, etc. `Monorepos
-in general <https://en.wikipedia.org/wiki/Monorepo>`_ are great because they
+including the LLVM optimizer and code generators, Clang, LLDB, etc. [Monorepos
+in general](https://en.wikipedia.org/wiki/Monorepo) are great because they
allow atomic commits to the project, simplify CI, and make it easier for
subcommunities to collaborate.
Like new targets, most projects already in the monorepo are considered to be in
-the *core tier* of our :doc:`support policy<SupportPolicy>`. The burden to add
+the *core tier* of our {doc}`support policy<SupportPolicy>`. The burden to add
things to the LLVM monorepo needs to be very high - code that is added to this
-repository is checked out by everyone in the community. As such, we hold
-components to a high bar similar to "official targets", they:
-
- * Must be generally aligned with the mission of the LLVM project to advance
- compilers, languages, tools, runtimes, etc.
- * Must conform to all of the policies laid out in this developer policy
- document, including license, patent, coding standards, and code of conduct.
- * Must have an active community that maintains the code, including established
- maintainers.
- * Should have reasonable documentation about how it works, including a high
- quality README file.
- * Should have CI to catch breakage within the project itself or due to
- underlying LLVM dependencies.
- * Should have code free of issues the community finds contentious, or be on a
- clear path to resolving them.
- * Must be proposed through the LLVM RFC process, and have its addition approved
- by the LLVM community - this ultimately mediates the resolution of the
- "should" concerns above. See the :doc:`RFC process <RFCProcess>`
- documentation for more details.
+repository is checked out by everyone in the community. As such, we hold
+components to a high bar similar to \"official targets\", they:
+
+- Must be generally aligned with the mission of the LLVM project to advance
+ compilers, languages, tools, runtimes, etc.
+- Must conform to all of the policies laid out in this developer policy
+ document, including license, patent, coding standards, and code of
+ conduct.
+- Must have an active community that maintains the code, including
+ established maintainers.
+- Should have reasonable documentation about how it works, including a high
+ quality README file.
+- Should have CI to catch breakage within the project itself or due to
+ underlying LLVM dependencies.
+- Should have code free of issues the community finds contentious, or be on
+ a clear path to resolving them.
+- Must be proposed through the LLVM RFC process, and have its addition
+ approved by the LLVM community - this ultimately mediates the resolution
+ of the \"should\" concerns above. See the {doc}`RFC process <RFCProcess>`
+ documentation for more details.
If you have a project that you think would make sense to add to the LLVM
-monorepo, please start an RFC topic on the `LLVM Discourse forums`_ to kick off
-the discussion. This process can take some time and iteration - please don’t
-be discouraged or intimidated by that!
+monorepo, please start an RFC topic on the [LLVM Discourse
+forums](https://discourse.llvm.org) to kick off the discussion. This process
+can take some time and iteration - please don't be discouraged or intimidated
+by that!
If you have an earlier stage project that you think is aligned with LLVM, please
-see the "Incubating New Projects" section.
+see the \"Incubating New Projects\" section.
-Incubating New Projects
------------------------
+### Incubating New Projects
The burden to add a new project to the LLVM monorepo is intentionally very high,
-but that can have a chilling effect on new and innovative projects. To help
-foster these sorts of projects, LLVM supports an "incubator" process that is
-much easier to get started with. It provides space for potentially valuable,
+but that can have a chilling effect on new and innovative projects. To help
+foster these sorts of projects, LLVM supports an \"incubator\" process that is
+much easier to get started with. It provides space for potentially valuable,
new top-level and sub-projects to reach a critical mass before they have enough
-code to prove their utility and grow a community. This also allows
+code to prove their utility and grow a community. This also allows
collaboration between teams that already have permissions to make contributions
to projects under the LLVM umbrella.
Projects which can be considered for the LLVM incubator meet the following
criteria:
- * Must be generally aligned with the mission of the LLVM project to advance
- compilers, languages, tools, runtimes, etc.
- * Must conform to the license, patent, and code of conduct policies laid out
- in this developer policy document.
- * Must have a documented charter and development plan, e.g. in the form of a
- README file, mission statement, and/or manifesto.
- * Should conform to coding standards, incremental development process, and
- other expectations.
- * Should have a sense of the community that it hopes to eventually foster, and
- there should be interest from members with different affiliations /
- organizations.
- * Should have a feasible path to eventually graduate as a dedicated top-level
- or sub-project within the `LLVM monorepo
- <https://github.com/llvm/llvm-project>`_.
- * Should include a notice (e.g. in the project README or web page) that the
- project is in ‘incubation status’ and is not included in LLVM releases (see
- suggested wording below).
- * Must be proposed through the LLVM RFC process, and have its addition
- approved by the LLVM community - this ultimately mediates the resolution of
- the "should" concerns above. See the :doc:`RFC process <RFCProcess>`
- documentation for more details.
+- Must be generally aligned with the mission of the LLVM project to advance
+ compilers, languages, tools, runtimes, etc.
+- Must conform to the license, patent, and code of conduct policies laid
+ out in this developer policy document.
+- Must have a documented charter and development plan, e.g. in the form of
+ a README file, mission statement, and/or manifesto.
+- Should conform to coding standards, incremental development process, and
+ other expectations.
+- Should have a sense of the community that it hopes to eventually foster,
+ and there should be interest from members with different affiliations /
+ organizations.
+- Should have a feasible path to eventually graduate as a dedicated
+ top-level or sub-project within the [LLVM
+ monorepo](https://github.com/llvm/llvm-project).
+- Should include a notice (e.g. in the project README or web page) that the
+ project is in 'incubation status' and is not included in LLVM releases
+ (see suggested wording below).
+- Must be proposed through the LLVM RFC process, and have its addition
+ approved by the LLVM community - this ultimately mediates the resolution
+ of the \"should\" concerns above. See the {doc}`RFC process <RFCProcess>`
+ documentation for more details.
That said, the project need not have any code to get started, and need not have
-an established community at all! Furthermore, incubating projects may pass
-through transient states that violate the "Should" guidelines above, or would
+an established community at all! Furthermore, incubating projects may pass
+through transient states that violate the \"Should\" guidelines above, or would
otherwise make them unsuitable for direct inclusion in the monorepo (e.g.
dependencies that have not yet been factored appropriately, leveraging
experimental components or APIs that are not yet upstream, etc).
When approved, the llvm-admin group can grant the new project:
- * A new repository in the LLVM Github Organization - but not the LLVM monorepo.
- * New mailing list, discourse forum, and/or discord chat hosted with other LLVM
- forums.
- * Other infrastructure integration can be discussed on a case-by-case basis.
+
+: - A new repository in the LLVM Github Organization - but not the LLVM
+ monorepo.
+ - New mailing list, discourse forum, and/or discord chat hosted with
+ other LLVM forums.
+ - Other infrastructure integration can be discussed on a case-by-case
+ basis.
Graduation to the mono-repo would follow existing processes and standards for
-becoming a first-class part of the monorepo. Similarly, an incubating project
-may be eventually retired, but no process has been established for that yet. If
-and when this comes up, please start an RFC discussion on the `LLVM Discourse forums`_.
+becoming a first-class part of the monorepo. Similarly, an incubating project
+may be eventually retired, but no process has been established for that yet. If
+and when this comes up, please start an RFC discussion on the [LLVM Discourse
+forums](https://discourse.llvm.org).
This process is very new - please expect the details to change, it is always
-safe to ask on the `LLVM Discourse forums`_ about this.
+safe to ask on the [LLVM Discourse forums](https://discourse.llvm.org) about
+this.
Suggested disclaimer for the project README and the main project web page:
-::
+ This project is participating in the LLVM Incubator process: as such, it is
+ not part of any official LLVM release. While incubation status is not
+ necessarily a reflection of the completeness or stability of the code, it
+ does indicate that the project is not yet endorsed as a component of LLVM.
- This project is participating in the LLVM Incubator process: as such, it is
- not part of any official LLVM release. While incubation status is not
- necessarily a reflection of the completeness or stability of the code, it
- does indicate that the project is not yet endorsed as a component of LLVM.
-
-Adding or enabling a new LLVM pass
-----------------------------------
+### Adding or enabling a new LLVM pass
The guidelines here are primarily targeted at the enablement of new major
passes in the target-independent optimization pipeline. Small additions, or
@@ -1176,71 +1090,69 @@ specific uses of LLVM, such as GC support passes.)
The recommended workflow is:
1. Implement a basic version of the pass and add it to the pass pipeline behind
- a flag that is disabled by default. The initial version should focus on
- handling simple cases correctly and efficiently.
+ a flag that is disabled by default. The initial version should focus on
+ handling simple cases correctly and efficiently.
2. Enable the pass by default. Separating this step allows easily disabling the
- pass if issues are encountered, without having to revert the entire
- implementation.
+ pass if issues are encountered, without having to revert the entire
+ implementation.
3. Incrementally extend the pass with new functionality. As the pass is already
- enabled, it becomes easier to identify the specific change that has caused a
- regression in correctness, optimization quality or compile-time.
-
-When enabling a pass, certain requirements must be met (in no particular order):
-
- * **Maintenance:** The pass (and any analyses it depends on) must have at
- least one maintainer.
- * **Usefulness:** There should be evidence that the pass improves performance
- (or whatever metric it optimizes for) on real-world workloads. Improvements
- seen only on synthetic benchmarks may be insufficient.
- * **Compile-Time:** The pass should not have a large impact on compile-time,
- where the evaluation of what "large" means is up to reviewer discretion, and
- may differ based on the value the pass provides. In any case, it is expected
- that a concerted effort has been made to mitigate the compile-time impact,
- both for the average case, and for pathological cases.
- * **Correctness:** The pass should have no known correctness issues (except
- global correctness issues that affect all of LLVM). If an old pass is being
- enabled (rather than implementing a new one incrementally), additional due
- diligence is required. The pass should be fully reviewed to ensure that it
- still complies with current quality standards. Fuzzing with disabled
- profitability checks may help gain additional confidence in the
- implementation.
+ enabled, it becomes easier to identify the specific change that has caused a
+ regression in correctness, optimization quality or compile-time.
+
+When enabling a pass, certain requirements must be met (in no particular
+order):
+
+- **Maintenance:** The pass (and any analyses it depends on) must have at
+ least one maintainer.
+- **Usefulness:** There should be evidence that the pass improves
+ performance (or whatever metric it optimizes for) on real-world
+ workloads. Improvements seen only on synthetic benchmarks may be
+ insufficient.
+- **Compile-Time:** The pass should not have a large impact on
+ compile-time, where the evaluation of what \"large\" means is up to
+ reviewer discretion, and may differ based on the value the pass provides.
+ In any case, it is expected that a concerted effort has been made to
+ mitigate the compile-time impact, both for the average case, and for
+ pathological cases.
+- **Correctness:** The pass should have no known correctness issues (except
+ global correctness issues that affect all of LLVM). If an old pass is
+ being enabled (rather than implementing a new one incrementally),
+ additional due diligence is required. The pass should be fully reviewed
+ to ensure that it still complies with current quality standards. Fuzzing
+ with disabled profitability checks may help gain additional confidence in
+ the implementation.
If non-trivial issues are found in a newly enabled pass, it may be temporarily
disabled again, until the issues have been resolved.
-.. _copyright-license-patents:
-
-Copyright, License, and Patents
-===============================
+(copyright-license-patents)=
+## Copyright, License, and Patents
-.. note::
+```{note}
- This section deals with legal matters but does not provide legal advice. We
- are not lawyers --- please seek legal counsel from a licensed attorney.
+This section deals with legal matters but does not provide legal advice. We are not lawyers \-\-- please seek legal counsel from a licensed attorney.
+```
-This section addresses the issues of copyright, license and patents for the LLVM
-project. The copyright for the code is held by the contributors of
-the code. The code is licensed under permissive `open source licensing terms`_,
-namely the Apache-2.0 with LLVM-exception license, which includes a copyright
-and `patent license`_. When you contribute code to the LLVM project, you
-license it under these terms.
+This section addresses the issues of copyright, license and patents for the
+LLVM project. The copyright for the code is held by the contributors of the
+code. The code is licensed under permissive {ref}`open source licensing terms
+<open source licensing terms>`, namely the Apache-2.0 with LLVM-exception
+license, which includes a copyright and {ref}`patent license <patent license>`.
+When you contribute code to the LLVM project, you license it under these terms.
-In certain circumstances, code licensed under other licenses can be added
-to the codebase. However, this may only be done with approval of the LLVM
+In certain circumstances, code licensed under other licenses can be added to
+the codebase. However, this may only be done with approval of the LLVM
Foundation Board of Directors, and contributors should plan for the approval
-process to take at least 4-6 weeks. If you would like to contribute code
-under a different license, please create a pull request with the code
-you want to contribute and email board at llvm.org requesting a review.
-
-If you have questions or comments about these topics, please ask on the
-`LLVM Discourse forums`_. However,
-please realize that most compiler developers are not lawyers, and therefore you
-will not be getting official legal advice.
+process to take at least 4-6 weeks. If you would like to contribute code under
+a different license, please create a pull request with the code you want to
+contribute and email <board at llvm.org> requesting a review.
-.. _LLVM Discourse forums: https://discourse.llvm.org
+If you have questions or comments about these topics, please ask on the [LLVM
+Discourse forums](https://discourse.llvm.org). However, please realize that
+most compiler developers are not lawyers, and therefore you will not be getting
+official legal advice.
-Copyright
----------
+### Copyright
The LLVM project does not collect copyright assignments, which means that the
copyright for the code in the project is held by the respective contributors.
@@ -1250,55 +1162,52 @@ the terms of the open source license you contributed it under: the license for
your contributions cannot be changed in the future without your approval.
Because the LLVM project does not require copyright assignments, changing the
-LLVM license requires tracking down the
-contributors to LLVM and getting them to agree that a license change is
-acceptable for their contributions. We feel that a high burden for relicensing
-is good for the project, because contributors do not have to fear that their
-code will be used in a way with which they disagree.
+LLVM license requires tracking down the contributors to LLVM and getting them
+to agree that a license change is acceptable for their contributions. We feel
+that a high burden for relicensing is good for the project, because
+contributors do not have to fear that their code will be used in a way with
+which they disagree.
-Embedded Copyright or 'Contributed by' Statements
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Embedded Copyright or 'Contributed by' Statements
The LLVM project does not accept contributions that include in-source copyright
notices except where such notices are part of a larger external project being
added as a vendored dependency.
LLVM source code lives for a long time and is edited by many people, the best
-way to track contributions is through revision control history.
-See the `Attribution of Changes`_ section for more information about attributing
-changes to authors other than the committer.
+way to track contributions is through revision control history. See the
+[Attribution of Changes](#attribution-of-changes) section for more information
+about attributing changes to authors other than the committer.
-Relicensing
------------
+### Relicensing
The last paragraph notwithstanding, the LLVM Project is in the middle of a large
effort to change licenses, which aims to solve several problems:
-* The old licenses made it difficult to move code from (e.g.) the compiler to
- runtime libraries, because runtime libraries used a different license from the
- rest of the compiler.
-* Some contributions were not submitted to LLVM due to concerns that
- the patent grant required by the project was overly broad.
-* The patent grant was unique to the LLVM Project, not written by a lawyer, and
- was difficult to determine what protection was provided (if any).
+- The old licenses made it difficult to move code from (e.g.) the compiler to
+ runtime libraries, because runtime libraries used a different license from
+ the rest of the compiler.
+- Some contributions were not submitted to LLVM due to concerns that
+ the patent grant required by the project was overly broad.
+- The patent grant was unique to the LLVM Project, not written by a lawyer, and
+ was difficult to determine what protection was provided (if any).
The scope of relicensing is all code that is considered part of the LLVM
project, including the main LLVM repository, runtime libraries (compiler_rt,
-OpenMP, etc), Polly, and all other subprojects. There are a few exceptions:
-
-* Code imported from other projects (e.g. Google Test, Autoconf, etc) will
- remain as it is. This code isn't developed as part of the LLVM project, it
- is used by LLVM.
-* Some subprojects are impractical or uninteresting to relicense (e.g. llvm-gcc
- and dragonegg). These will be split off from the LLVM project (e.g. to
- separate GitHub projects), allowing interested people to continue their
- development elsewhere.
-
-To relicense LLVM, we will be seeking approval from all of the copyright holders
-of code in the repository, or potentially remove/rewrite code if we cannot.
-This is a large
-and challenging project which will take a significant amount of time to
-complete.
+OpenMP, etc), Polly, and all other subprojects. There are a few exceptions:
+
+- Code imported from other projects (e.g. Google Test, Autoconf, etc) will
+ remain as it is. This code isn't developed as part of the LLVM project, it
+ is used by LLVM.
+- Some subprojects are impractical or uninteresting to relicense (e.g.
+ llvm-gcc and dragonegg). These will be split off from the LLVM project
+ (e.g. to separate GitHub projects), allowing interested people to continue
+ their development elsewhere.
+
+To relicense LLVM, we will be seeking approval from all of the copyright
+holders of code in the repository, or potentially remove/rewrite code if we
+cannot. This is a large and challenging project which will take a significant
+amount of time to complete.
Starting on 2024-06-01 (first of June 2024), new contributions only need to
be covered by the new LLVM license, i.e. Apache-2.0 WITH LLVM-exception.
@@ -1307,177 +1216,162 @@ both the new license and the legacy license.
If you are a contributor to LLVM with contributions committed before 2019-01-19
and have not done so already, please do follow the instructions at
-https://foundation.llvm.org/docs/relicensing/, under section "Individual
-Relicensing Agreement" to relicense your contributions under the new license.
-
-
-.. _open source licensing terms:
-
-New LLVM Project License Framework
-----------------------------------
-
-Contributions to LLVM are licensed under the `Apache License, Version 2.0
-<https://www.apache.org/licenses/LICENSE-2.0>`_, with two limited
-exceptions intended to ensure that LLVM is very permissively licensed.
-Collectively, the name of this license is "Apache 2.0 License with LLVM
-exceptions". The exceptions read:
-
-::
-
- ---- LLVM Exceptions to the Apache 2.0 License ----
-
- As an exception, if, as a result of your compiling your source code, portions
- of this Software are embedded into an Object form of such source code, you
- may redistribute such embedded portions in such Object form without complying
- with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
-
- In addition, if you combine or link compiled forms of this Software with
- software that is licensed under the GPLv2 ("Combined Software") and if a
- court of competent jurisdiction determines that the patent provision (Section
- 3), the indemnity provision (Section 9) or other Section of the License
- conflicts with the conditions of the GPLv2, you may retroactively and
- prospectively choose to deem waived or otherwise exclude such Section(s) of
- the License, but only in their entirety and only with respect to the Combined
- Software.
-
+<https://foundation.llvm.org/docs/relicensing/>, under section \"Individual
+Relicensing Agreement\" to relicense your contributions under the new license.
+
+(open source licensing terms)=
+### New LLVM Project License Framework
+
+Contributions to LLVM are licensed under the [Apache License, Version
+2.0](https://www.apache.org/licenses/LICENSE-2.0), with two limited exceptions
+intended to ensure that LLVM is very permissively licensed. Collectively, the
+name of this license is \"Apache 2.0 License with LLVM exceptions\". The
+exceptions read:
+
+ ---- LLVM Exceptions to the Apache 2.0 License ----
+
+ As an exception, if, as a result of your compiling your source code, portions
+ of this Software are embedded into an Object form of such source code, you
+ may redistribute such embedded portions in such Object form without complying
+ with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+ In addition, if you combine or link compiled forms of this Software with
+ software that is licensed under the GPLv2 ("Combined Software") and if a
+ court of competent jurisdiction determines that the patent provision (Section
+ 3), the indemnity provision (Section 9) or other Section of the License
+ conflicts with the conditions of the GPLv2, you may retroactively and
+ prospectively choose to deem waived or otherwise exclude such Section(s) of
+ the License, but only in their entirety and only with respect to the Combined
+ Software.
We intend to keep LLVM perpetually open source and available under a permissive
license - this fosters the widest adoption of LLVM by
**allowing commercial products to be derived from LLVM** with few restrictions
-and without a requirement for making any derived works also open source. In
-particular, LLVM's license is not a "copyleft" license like the GPL.
+and without a requirement for making any derived works also open source. In
+particular, LLVM's license is not a \"copyleft\" license like the GPL.
-The "Apache 2.0 License with LLVM exceptions" allows you to:
+The \"Apache 2.0 License with LLVM exceptions\" allows you to:
-* freely download and use LLVM (in whole or in part) for personal, internal, or
- commercial purposes.
-* include LLVM in packages or distributions you create.
-* combine LLVM with code licensed under every other major open source
- license (including BSD, MIT, GPLv2, GPLv3...).
-* make changes to LLVM code without being required to contribute it back
- to the project - contributions are appreciated though!
+- freely download and use LLVM (in whole or in part) for personal, internal,
+ or commercial purposes.
+- include LLVM in packages or distributions you create.
+- combine LLVM with code licensed under every other major open source
+ license (including BSD, MIT, GPLv2, GPLv3\...).
+- make changes to LLVM code without being required to contribute it back
+ to the project - contributions are appreciated though!
However, it imposes these limitations on you:
-* You must retain the copyright notice if you redistribute LLVM: You cannot
- strip the copyright headers off or replace them with your own.
-* Binaries that include LLVM must reproduce the copyright notice (e.g. in an
- included README file or in an "About" box), unless the LLVM code was added as
- a by-product of compilation. For example, if an LLVM runtime library like
- compiler_rt or libc++ was automatically included into your application by the
- compiler, you do not need to attribute it.
-* You can't use our names to promote your products (LLVM derived or not) -
- though you can make truthful statements about your use of the LLVM code,
- without implying our sponsorship.
-* There's no warranty on LLVM at all.
-
-We want LLVM code to be widely used, and believe that this provides a model that
-is great for contributors and users of the project. For more information about
-the Apache 2.0 License, please see the `Apache License FAQ
-<http://www.apache.org/foundation/license-faq.html>`_, maintained by the
+- You must retain the copyright notice if you redistribute LLVM: You cannot
+ strip the copyright headers off or replace them with your own.
+- Binaries that include LLVM must reproduce the copyright notice (e.g. in an
+ included README file or in an \"About\" box), unless the LLVM code was added as
+ a by-product of compilation. For example, if an LLVM runtime library like
+ compiler_rt or libc++ was automatically included into your application by the
+ compiler, you do not need to attribute it.
+- You can't use our names to promote your products (LLVM derived or not) -
+ though you can make truthful statements about your use of the LLVM code,
+ without implying our sponsorship.
+- There's no warranty on LLVM at all.
+
+We want LLVM code to be widely used, and believe that this provides a model
+that is great for contributors and users of the project. For more information
+about the Apache 2.0 License, please see the [Apache License
+FAQ](http://www.apache.org/foundation/license-faq.html), maintained by the
Apache Project.
-.. _patent license:
+(patent license)=
+### Patents
-Patents
--------
-
-Section 3 of the Apache 2.0 license is a patent grant under which
-contributors of code to the project contribute the rights to use any of
-their patents that would otherwise be infringed by that code contribution
-(protecting uses of that code). Further, the patent grant is revoked
-from anyone who files a patent lawsuit about code in LLVM - this protects the
-community by providing a "patent commons" for the code base and reducing the
-odds of patent lawsuits in general.
+Section 3 of the Apache 2.0 license is a patent grant under which contributors
+of code to the project contribute the rights to use any of their patents that
+would otherwise be infringed by that code contribution (protecting uses of that
+code). Further, the patent grant is revoked from anyone who files a patent
+lawsuit about code in LLVM - this protects the community by providing a
+\"patent commons\" for the code base and reducing the odds of patent lawsuits
+in general.
The license specifically scopes which patents are included with code
-contributions. To help explain this, the `Apache License FAQ
-<http://www.apache.org/foundation/license-faq.html>`_ explains this scope using
-some questions and answers, which we reproduce here for your convenience (for
-reference, the "ASF" is the Apache Software Foundation, the guidance still
-holds though)::
-
- Q1: If I own a patent and contribute to a Work, and, at the time my
- contribution is included in that Work, none of my patent's claims are subject
- to Apache's Grant of Patent License, is there a way any of those claims would
- later become subject to the Grant of Patent License solely due to subsequent
- contributions by other parties who are not licensees of that patent.
-
- A1: No.
-
- Q2: If at any time after my contribution, I am able to license other patent
- claims that would have been subject to Apache's Grant of Patent License if
- they were licensable by me at the time of my contribution, do those other
- claims become subject to the Grant of Patent License?
-
- A2: Yes.
-
- Q3: If I own or control a licensable patent and contribute code to a specific
- Apache product, which of my patent claims are subject to Apache's Grant of
- Patent License?
-
- A3: The only patent claims that are licensed to the ASF are those you own or
- have the right to license that read on your contribution or on the
- combination of your contribution with the specific Apache product to which
- you contributed as it existed at the time of your contribution. No additional
- patent claims become licensed as a result of subsequent combinations of your
- contribution with any other software. Note, however, that licensable patent
- claims include those that you acquire in the future, as long as they read on
- your original contribution as made at the original time. Once a patent claim
- is subject to Apache's Grant of Patent License, it is licensed under the
- terms of that Grant to the ASF and to recipients of any software distributed
- by the ASF for any Apache software product whatsoever.
-
-.. _legacy:
-
-Legacy License Structure
-------------------------
-
-.. note::
- The code base was previously licensed under the Terms described here.
- We are in the middle of relicensing to a new approach (described above).
- More than 99% of all contributions made to LLVM are covered by the Apache-2.0
- WITH LLVM-exception license. A small portion of LLVM code remains exclusively
- covered by the legacy license. Contributions after 2024-06-01 are covered
- exclusively by the new license._
+contributions. To help explain this, the [Apache License
+FAQ](http://www.apache.org/foundation/license-faq.html) explains this scope
+using some questions and answers, which we reproduce here for your convenience
+(for reference, the \"ASF\" is the Apache Software Foundation, the guidance
+still holds though):
+
+ Q1: If I own a patent and contribute to a Work, and, at the time my
+ contribution is included in that Work, none of my patent's claims are subject
+ to Apache's Grant of Patent License, is there a way any of those claims would
+ later become subject to the Grant of Patent License solely due to subsequent
+ contributions by other parties who are not licensees of that patent.
+
+ A1: No.
+
+ Q2: If at any time after my contribution, I am able to license other patent
+ claims that would have been subject to Apache's Grant of Patent License if
+ they were licensable by me at the time of my contribution, do those other
+ claims become subject to the Grant of Patent License?
+
+ A2: Yes.
+
+ Q3: If I own or control a licensable patent and contribute code to a specific
+ Apache product, which of my patent claims are subject to Apache's Grant of
+ Patent License?
+
+ A3: The only patent claims that are licensed to the ASF are those you own or
+ have the right to license that read on your contribution or on the
+ combination of your contribution with the specific Apache product to which
+ you contributed as it existed at the time of your contribution. No additional
+ patent claims become licensed as a result of subsequent combinations of your
+ contribution with any other software. Note, however, that licensable patent
+ claims include those that you acquire in the future, as long as they read on
+ your original contribution as made at the original time. Once a patent claim
+ is subject to Apache's Grant of Patent License, it is licensed under the
+ terms of that Grant to the ASF and to recipients of any software distributed
+ by the ASF for any Apache software product whatsoever.
+
+(legacy)=
+### Legacy License Structure
+
+```{note}
+
+The code base was previously licensed under the Terms described here. We are in the middle of relicensing to a new approach (described above). More than 99% of all contributions made to LLVM are covered by the Apache-2.0 WITH LLVM-exception license. A small portion of LLVM code remains exclusively covered by the legacy license. Contributions after 2024-06-01 are covered exclusively by the new license.\_
+```
We intend to keep LLVM perpetually open source and to use a permissive open
-source license. The code in
-LLVM is available under the `University of Illinois/NCSA Open Source License
-<http://www.opensource.org/licenses/UoI-NCSA.php>`_, which boils down to
+source license. The code in LLVM is available under the [University of
+Illinois/NCSA Open Source
+License](http://www.opensource.org/licenses/UoI-NCSA.php), which boils down to
this:
-* You can freely distribute LLVM.
-* You must retain the copyright notice if you redistribute LLVM.
-* Binaries derived from LLVM must reproduce the copyright notice (e.g. in an
- included README file).
-* You can't use our names to promote your LLVM derived products.
-* There's no warranty on LLVM at all.
+- You can freely distribute LLVM.
+- You must retain the copyright notice if you redistribute LLVM.
+- Binaries derived from LLVM must reproduce the copyright notice (e.g. in an
+ included README file).
+- You can't use our names to promote your LLVM derived products.
+- There's no warranty on LLVM at all.
We believe this fosters the widest adoption of LLVM because it **allows
commercial products to be derived from LLVM** with few restrictions and without
a requirement for making any derived works also open source (i.e. LLVM's
-license is not a "copyleft" license like the GPL). We suggest that you read the
-`License <http://www.opensource.org/licenses/UoI-NCSA.php>`_ if further
+license is not a \"copyleft\" license like the GPL). We suggest that you read the
+[License](http://www.opensource.org/licenses/UoI-NCSA.php) if further
clarification is needed.
In addition to the UIUC license, the runtime library components of LLVM
-(**compiler_rt, libc++, and libclc**) are also licensed under the `MIT License
-<http://www.opensource.org/licenses/mit-license.php>`_, which does not contain
-the binary redistribution clause. As a user of these runtime libraries, it
-means that you can choose to use the code under either license (and thus don't
-need the binary redistribution clause), and as a contributor to the code that
-you agree that any contributions to these libraries be licensed under both
-licenses. We feel that this is important for runtime libraries, because they
+(**compiler_rt, libc++, and libclc**) are also licensed under the [MIT
+License](http://www.opensource.org/licenses/mit-license.php), which does not
+contain the binary redistribution clause. As a user of these runtime libraries,
+it means that you can choose to use the code under either license (and thus
+don't need the binary redistribution clause), and as a contributor to the code
+that you agree that any contributions to these libraries be licensed under both
+licenses. We feel that this is important for runtime libraries, because they
are implicitly linked into applications and therefore should not subject those
applications to the binary redistribution clause. This also means that it is ok
-to move code from (e.g.) libc++ to the LLVM core without concern, but that code
+to move code from (e.g.) libc++ to the LLVM core without concern, but that code
cannot be moved from the LLVM core to libc++ without the copyright owner's
permission.
-.. _ai contributions:
-
-AI generated contributions
---------------------------
+(ai contributions)=
+### AI generated contributions
-This section has moved into a :doc:`separate policy document <AIToolPolicy>`.
+This section has moved into a {doc}`separate policy document <AIToolPolicy>`.
diff --git a/llvm/docs/GettingInvolved.md b/llvm/docs/GettingInvolved.md
index aec6c87a1424e..fde5c240b5536 100644
--- a/llvm/docs/GettingInvolved.md
+++ b/llvm/docs/GettingInvolved.md
@@ -1,149 +1,160 @@
-Getting Involved
-================
+# Getting Involved
LLVM welcomes contributions of all kinds. To get started, please review the following topics:
-.. contents::
- :local:
+```{contents}
+:local:
+```
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- Contributing
- DeveloperPolicy
- CodeReview
- SupportPolicy
- SphinxQuickstartTemplate
- HowToSubmitABug
- BugLifeCycle
- CodingStandards
- GitHub
- GitBisecting
- GitRepositoryPolicy
+Contributing
+DeveloperPolicy
+CodeReview
+SupportPolicy
+SphinxQuickstartTemplate
+HowToSubmitABug
+BugLifeCycle
+CodingStandards
+GitHub
+GitBisecting
+GitRepositoryPolicy
+```
-:doc:`Contributing`
- An overview on how to contribute to LLVM.
+* {doc}`Contributing`
-:doc:`DeveloperPolicy`
- The LLVM project's policy towards developers and their contributions.
+ An overview on how to contribute to LLVM.
-:doc:`CodeReview`
- The LLVM project's code-review process.
+* {doc}`DeveloperPolicy`
-:doc:`SupportPolicy`
- The LLVM support policy for core and non-core components.
+ The LLVM project's policy towards developers and their contributions.
+
+* {doc}`CodeReview`
+
+ The LLVM project's code-review process.
+
+* {doc}`SupportPolicy`
+
+ The LLVM support policy for core and non-core components.
+
+* {doc}`SphinxQuickstartTemplate`
-:doc:`SphinxQuickstartTemplate`
A template + tutorial for writing new Sphinx documentation. It is meant
to be read in source form.
-:doc:`HowToSubmitABug`
- Instructions for properly submitting information about any bugs you run into
- in the LLVM system.
+* {doc}`HowToSubmitABug`
+
+ Instructions for properly submitting information about any bugs you run into
+ in the LLVM system.
+
+* {doc}`BugLifeCycle`
-:doc:`BugLifeCycle`
- Describes how bugs are reported, triaged, and closed.
+ Describes how bugs are reported, triaged, and closed.
+
+* {doc}`CodingStandards`
-:doc:`CodingStandards`
Details the LLVM coding standards and provides useful information on writing
efficient C++ code.
-:doc:`GitHub`
+* {doc}`GitHub`
+
Describes how to use the llvm-project repository and code reviews on GitHub.
-:doc:`GitBisecting`
- Describes how to use ``git bisect`` on LLVM's repository.
+* {doc}`GitBisecting`
+
+ Describes how to use `git bisect` on LLVM's repository.
-:doc:`GitRepositoryPolicy`
- Collection of policies around the git repositories.
+* {doc}`GitRepositoryPolicy`
-.. _development-process:
+ Collection of policies around the git repositories.
-Development Process
--------------------
+(development-process)=
+
+## Development Process
Information about LLVM's development process.
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
+
+Projects
+HowToReleaseLLVM
+ReleaseProcess
+HowToAddABuilder
+ReleaseNotes
+```
- Projects
- HowToReleaseLLVM
- ReleaseProcess
- HowToAddABuilder
- ReleaseNotes
+* {doc}`Projects`
-:doc:`Projects`
How-to guide and templates for new projects that *use* the LLVM
infrastructure. The templates (directory organization, Makefiles, and test
- tree) allow the project code to be located outside (or inside) the ``llvm/``
+ tree) allow the project code to be located outside (or inside) the `llvm/`
tree, while using LLVM header files and libraries.
-:doc:`HowToReleaseLLVM`
+* {doc}`HowToReleaseLLVM`
+
This is a guide to preparing LLVM releases. Most developers can ignore it.
-:doc:`ReleaseProcess`
+* {doc}`ReleaseProcess`
+
This is a guide to validate a new release, during the release process. Most developers can ignore it.
-:doc:`HowToAddABuilder`
- Instructions for adding new builder to LLVM buildbot master.
+* {doc}`HowToAddABuilder`
+
+ Instructions for adding new builder to LLVM buildbot master.
+
+* {doc}`Release notes for the current release <ReleaseNotes>`
-:doc:`Release notes for the current release <ReleaseNotes>`
- This describes new features, known bugs, and other limitations.
+ This describes new features, known bugs, and other limitations.
-.. _lists-forums:
+(lists-forums)=
-Forums & Mailing Lists
-----------------------
+## Forums & Mailing Lists
If you can't find what you need in these docs, try consulting the
Discourse forums. There are also commit mailing lists for all commits to the LLVM Project.
-The :doc:`CodeOfConduct` applies to all these forums and mailing lists.
+The {doc}`CodeOfConduct` applies to all these forums and mailing lists.
+
+* [LLVM Discourse](https://discourse.llvm.org/)
-`LLVM Discourse`__
The forums for all things LLVM and related sub-projects. There are categories and subcategories for a wide variety of areas within LLVM. You can also view tags or search for a specific topic.
- .. __: https://discourse.llvm.org/
+* [Commits Archive (llvm-commits)](http://lists.llvm.org/pipermail/llvm-commits/)
-`Commits Archive (llvm-commits)`__
This list contains all commit messages that are made when LLVM developers
commit code changes to the repository. It also serves as a forum for
patch review (i.e., send patches here). It is useful for those who want to
stay on the bleeding edge of LLVM development. This list is very high
volume.
- .. __: http://lists.llvm.org/pipermail/llvm-commits/
+* [Bugs & Patches Archive (llvm-bugs)](http://lists.llvm.org/pipermail/llvm-bugs/)
-`Bugs & Patches Archive (llvm-bugs)`__
This list gets emailed every time a bug is opened and closed. It is
higher volume than the LLVM-dev list.
- .. __: http://lists.llvm.org/pipermail/llvm-bugs/
+* [LLVM Announcements](https://discourse.llvm.org/c/announce/46)
-`LLVM Announcements`__
If you just want project-wide announcements such as releases, developers meetings, or blog posts, then you should check out the Announcement category on LLVM Discourse.
- .. __: https://discourse.llvm.org/c/announce/46
-
-.. _online-sync-ups:
+(online-sync-ups)=
-Online Sync-Ups
----------------
+## Online Sync-Ups
A number of regular calls are organized on specific topics. It should be
expected that the range of topics will change over time. At the time of
writing, the following sync-ups are organized.
-The :doc:`CodeOfConduct` applies to all online sync-ups.
+The {doc}`CodeOfConduct` applies to all online sync-ups.
If you'd like to organize a new sync-up, please add the info in the table
below. Please also create a calendar event for it and invite calendar at llvm.org
-to the event, so that it'll show up on the :ref:`llvm-community-calendar`.
-Please see :ref:`llvm-community-calendar-host-guidance` for more guidance on
+to the event, so that it'll show up on the {ref}`llvm-community-calendar`.
+Please see {ref}`llvm-community-calendar-host-guidance` for more guidance on
what to add to your calendar invite.
-.. list-table:: LLVM regular sync-up calls
- :widths: 25 25 25 25
- :header-rows: 1
+```{list-table} LLVM regular sync-up calls
+:widths: 25 25 25 25
+:header-rows: 1
* - Topic
- Frequency
@@ -151,116 +162,116 @@ what to add to your calendar invite.
- Minutes/docs link
* - Loop Optimization Working Group
- Every first Wednesday of the month
- - `ics <./_static/LoopOptWG_invite.ics>`__
- - `Minutes/docs <https://docs.google.com/document/d/1sdzoyB11s0ccTZ3fobqctDpgJmRoFcz0sviKxqczs4g/edit>`__
+ - [ics](./_static/LoopOptWG_invite.ics)
+ - [Minutes/docs](https://docs.google.com/document/d/1sdzoyB11s0ccTZ3fobqctDpgJmRoFcz0sviKxqczs4g/edit)
* - RISC-V
- Every 2 weeks on Thursday
- - `ics <https://calendar.google.com/calendar/ical/lowrisc.org_0n5pkesfjcnp0bh5hps1p0bd80%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/b/1?cid=bG93cmlzYy5vcmdfMG41cGtlc2ZqY25wMGJoNWhwczFwMGJkODBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ>`__
- - `Minutes/docs <https://docs.google.com/document/d/1G3ocHm2zE6AYTS2N3_3w2UxFnSEyKkcF57siLWe-NVs>`__
+ - [ics](https://calendar.google.com/calendar/ical/lowrisc.org_0n5pkesfjcnp0bh5hps1p0bd80%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/b/1?cid=bG93cmlzYy5vcmdfMG41cGtlc2ZqY25wMGJoNWhwczFwMGJkODBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ)
+ - [Minutes/docs](https://docs.google.com/document/d/1G3ocHm2zE6AYTS2N3_3w2UxFnSEyKkcF57siLWe-NVs)
* - ML Guided Compiler Optimizations
- Monthly
-
- - `Minutes/docs <https://docs.google.com/document/d/1JecbplF09l3swTjze-UVeLh4L48svJxGVy4mz_e9Rhs/edit?usp=gmail#heading=h.ts9cmcjbir1j>`__
- * - `LLVM security group <https://llvm.org/docs/Security.html>`__
+ - [Minutes/docs](https://docs.google.com/document/d/1JecbplF09l3swTjze-UVeLh4L48svJxGVy4mz_e9Rhs/edit?usp=gmail#heading=h.ts9cmcjbir1j)
+ * - [LLVM security group](https://llvm.org/docs/Security.html)
- Monthly, every 3rd Tuesday
- - `ics <https://calendar.google.com/calendar/ical/eoh3m9k1l6vqbd1fkp94fv5q74%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=eoh3m9k1l6vqbd1fkp94fv5q74%40group.calendar.google.com>`__
- - `Minutes/docs <https://discourse.llvm.org/t/llvm-security-group-public-sync-ups/62735>`__
- * - `CIRCT <https://github.com/llvm/circt>`__
+ - [ics](https://calendar.google.com/calendar/ical/eoh3m9k1l6vqbd1fkp94fv5q74%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=eoh3m9k1l6vqbd1fkp94fv5q74%40group.calendar.google.com)
+ - [Minutes/docs](https://discourse.llvm.org/t/llvm-security-group-public-sync-ups/62735)
+ * - [CIRCT](https://github.com/llvm/circt)
- Weekly, on Wednesday
-
- - `Minutes/docs <https://docs.google.com/document/d/1fOSRdyZR2w75D87yU2Ma9h2-_lEPL4NxvhJGJd-s5pk/edit#heading=h.mulvhjtr8dk9>`__
+ - [Minutes/docs](https://docs.google.com/document/d/1fOSRdyZR2w75D87yU2Ma9h2-_lEPL4NxvhJGJd-s5pk/edit#heading=h.mulvhjtr8dk9)
* - flang
- - Multiple meeting series, `documented here <https://github.com/llvm/llvm-project/blob/main/flang/docs/GettingInvolved.md#calls>`__
+ - Multiple meeting series, [documented here](https://github.com/llvm/llvm-project/blob/main/flang/docs/GettingInvolved.md#calls)
-
-
* - OpenMP
- - Multiple meeting series, `documented here <https://openmp.llvm.org/docs/SupportAndFAQ.html>`__
+ - Multiple meeting series, [documented here](https://openmp.llvm.org/docs/SupportAndFAQ.html)
-
-
* - LLVM Alias Analysis
- Every 4 weeks on Tuesdays
- - `ics <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201103/a3499a67/attachment-0001.ics>`__
- - `Minutes/docs <https://docs.google.com/document/d/17U-WvX8qyKc3S36YUKr3xfF-GHunWyYowXbxEdpHscw>`__
+ - [ics](http://lists.llvm.org/pipermail/llvm-dev/attachments/20201103/a3499a67/attachment-0001.ics)
+ - [Minutes/docs](https://docs.google.com/document/d/17U-WvX8qyKc3S36YUKr3xfF-GHunWyYowXbxEdpHscw)
* - LLVM Pointer Authentication
- Every month on Mondays
- - `ics <https://calendar.google.com/calendar/ical/fr1qtmrmt2s9odufjvurkb6j70%40group.calendar.google.com/public/basic.ics>`__
- - `Minutes/docs <https://discourse.llvm.org/t/llvm-pointer-authentication-sync-ups/62661>`__
+ - [ics](https://calendar.google.com/calendar/ical/fr1qtmrmt2s9odufjvurkb6j70%40group.calendar.google.com/public/basic.ics)
+ - [Minutes/docs](https://discourse.llvm.org/t/llvm-pointer-authentication-sync-ups/62661)
* - LLVM Embedded Toolchains
- Every 4 weeks on Thursdays
- - `ics <https://drive.google.com/file/d/1uNa-PFYkhAfT83kR2Nc4Fi706TAQFBEL/view?usp=sharing>`__
- `gcal <https://calendar.google.com/calendar/u/0?cid=ZDQyc3ZlajJmbjIzNG1jaTUybjFsdjA2dWNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ>`__
- - `Minutes/docs <https://docs.google.com/document/d/1GahxppHJ7o1O_fn1Mbidu1DHEg7V2aOr92LXCtNV1_o/edit?usp=sharing>`__
+ - [ics](https://drive.google.com/file/d/1uNa-PFYkhAfT83kR2Nc4Fi706TAQFBEL/view?usp=sharing)
+ [gcal](https://calendar.google.com/calendar/u/0?cid=ZDQyc3ZlajJmbjIzNG1jaTUybjFsdjA2dWNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ)
+ - [Minutes/docs](https://docs.google.com/document/d/1GahxppHJ7o1O_fn1Mbidu1DHEg7V2aOr92LXCtNV1_o/edit?usp=sharing)
* - Clang C and C++ Language Working Group
- 1st and 3rd Wednesday of the month
- - `gcal <https://calendar.google.com/calendar/u/0?cid=cW1lZGg0ZXNpMnIyZDN2aTVydGVrdWF1YzRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ>`__
- - `Minutes/docs <https://docs.google.com/document/d/1x5-RbOC6-jnI_NcJ9Dp4pSmGhhNe7lUevuWUIB46TeM/edit?usp=sharing>`__
+ - [gcal](https://calendar.google.com/calendar/u/0?cid=cW1lZGg0ZXNpMnIyZDN2aTVydGVrdWF1YzRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ)
+ - [Minutes/docs](https://docs.google.com/document/d/1x5-RbOC6-jnI_NcJ9Dp4pSmGhhNe7lUevuWUIB46TeM/edit?usp=sharing)
* - LLVM SPIR-V Backend Working Group
- Every week on Monday
-
- - `Meeting details/agenda <https://docs.google.com/document/d/1UjX-LAwPjJ75Nmb8a5jz-Qrm-pPtKtQw0k1S1Lop9jU/edit?usp=sharing>`__
+ - [Meeting details/agenda](https://docs.google.com/document/d/1UjX-LAwPjJ75Nmb8a5jz-Qrm-pPtKtQw0k1S1Lop9jU/edit?usp=sharing)
* - SYCL Upstream Working Group
- Every 2 weeks on Mondays
- - `gcal <https://calendar.google.com/calendar/u/0?cid=c3ljbC5sbHZtLndnQGdtYWlsLmNvbQ>`__
- - `Meeting details/agenda <https://docs.google.com/document/d/1ivYDSn_5ChTeiZ7TiO64WC_jYJnGwAUiT9Ngi9cAdFU/edit?usp=sharing>`__
+ - [gcal](https://calendar.google.com/calendar/u/0?cid=c3ljbC5sbHZtLndnQGdtYWlsLmNvbQ)
+ - [Meeting details/agenda](https://docs.google.com/document/d/1ivYDSn_5ChTeiZ7TiO64WC_jYJnGwAUiT9Ngi9cAdFU/edit?usp=sharing)
* - Formal Semantics Working Group
- Every 2 weeks on Mondays
- - `gcal <https://calendar.google.com/calendar/event?eid=aHJpNnNzb3Zia3FtNzNuYjdpbmJtZG5nZGVfMjAyNjA1MDRUMTUzMDAwWiBjYWxlbmRhckBsbHZtLm9yZw>`__
- - `Meeting notes <https://docs.google.com/document/d/1muS2gZ7PUhbypbl0bmjb2J-UUzY7K8AO9a8RHVw_Mjo/edit?tab=t.0>`__
+ - [gcal](https://calendar.google.com/calendar/event?eid=aHJpNnNzb3Zia3FtNzNuYjdpbmJtZG5nZGVfMjAyNjA1MDRUMTUzMDAwWiBjYWxlbmRhckBsbHZtLm9yZw)
+ - [Meeting notes](https://docs.google.com/document/d/1muS2gZ7PUhbypbl0bmjb2J-UUzY7K8AO9a8RHVw_Mjo/edit?tab=t.0)
* - Vectorizer Improvement Working Group
- 3rd Tuesday of the month
- - `ics <https://www.icloud.com/iclouddrive/032PeZzdN6U4uRMwJRJPrS2Lw#Vectorizer_Improvements>`__
- - `Meeting details/agenda: <https://docs.google.com/document/d/1Glzy2JiWuysbD-HBWGUOkZqT09GJ4_Ljodr0lXD5XfQ/edit>`__
- * - `LLVM Qualification Working Group <https://llvm.org/docs/QualGroup.html>`__
+ - [ics](https://www.icloud.com/iclouddrive/032PeZzdN6U4uRMwJRJPrS2Lw#Vectorizer_Improvements)
+ - [Meeting details/agenda:](https://docs.google.com/document/d/1Glzy2JiWuysbD-HBWGUOkZqT09GJ4_Ljodr0lXD5XfQ/edit)
+ * - [LLVM Qualification Working Group](https://llvm.org/docs/QualGroup.html)
- Monthly: 2nd Tuesday (EU/Asia) and 2nd Friday JST / Thursday (Americas)
- - `ics <https://calendar.google.com/calendar/ical/f731f5b57956a132f6c553ed30f496b16e1018f831be13eb6c4b896c108a6626%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=f731f5b57956a132f6c553ed30f496b16e1018f831be13eb6c4b896c108a6626%40group.calendar.google.com&ctz=Asia%2FTokyo>`__
- - `Minutes/docs <https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148>`__
+ - [ics](https://calendar.google.com/calendar/ical/f731f5b57956a132f6c553ed30f496b16e1018f831be13eb6c4b896c108a6626%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=f731f5b57956a132f6c553ed30f496b16e1018f831be13eb6c4b896c108a6626%40group.calendar.google.com&ctz=Asia%2FTokyo)
+ - [Minutes/docs](https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148)
* - MLIR C/C++ Frontend Working Group
- Monthly, usually 1st Monday of the month
- - `ics <https://calendar.google.com/calendar/ical/jvceakm3kbpku3f4jrsv1lkigo%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=jvceakm3kbpku3f4jrsv1lkigo%40group.calendar.google.com&ctz=America%2FLos_Angeles>`__
- - `Minutes/docs <https://docs.google.com/document/d/1-flHK3TjQUrkSO2Fdt4webZ2zCyeXxpTLMiRQbMW7hE>`__
+ - [ics](https://calendar.google.com/calendar/ical/jvceakm3kbpku3f4jrsv1lkigo%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=jvceakm3kbpku3f4jrsv1lkigo%40group.calendar.google.com&ctz=America%2FLos_Angeles)
+ - [Minutes/docs](https://docs.google.com/document/d/1-flHK3TjQUrkSO2Fdt4webZ2zCyeXxpTLMiRQbMW7hE)
* - ClangIR Upstreaming Coordination Meeting
- Every 2 weeks on Mondays
- - `ics <https://calendar.google.com/calendar/ical/c_673c6cd64474c0aff173bf8fa609559f93d654e0984d9d91d71abd32d28c0486%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=c_673c6cd64474c0aff173bf8fa609559f93d654e0984d9d91d71abd32d28c0486%40group.calendar.google.com&ctz=America%2FLos_Angeles>`__
+ - [ics](https://calendar.google.com/calendar/ical/c_673c6cd64474c0aff173bf8fa609559f93d654e0984d9d91d71abd32d28c0486%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=c_673c6cd64474c0aff173bf8fa609559f93d654e0984d9d91d71abd32d28c0486%40group.calendar.google.com&ctz=America%2FLos_Angeles)
-
* - GlobalISel
- Every 2nd Tuesday of the month
- - `gcal <https://calendar.google.com/calendar/u/0?cid=YWZjNzhmMzE4MDNlNTAyNGY1NmE1MDIyODY0YTYwZmJmYzRjYTEwNTE1NmUxODA2NzBkYTliY2ZhYTVkNjk0NUBncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`__
- - `Meeting details/agenda <https://docs.google.com/document/d/1Ry8O4-Tm5BFj9AMjr8qTQFU80z-ptiNQ62687NaIvLs/edit?usp=sharing>`__
+ - [gcal](https://calendar.google.com/calendar/u/0?cid=YWZjNzhmMzE4MDNlNTAyNGY1NmE1MDIyODY0YTYwZmJmYzRjYTEwNTE1NmUxODA2NzBkYTliY2ZhYTVkNjk0NUBncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
+ - [Meeting details/agenda](https://docs.google.com/document/d/1Ry8O4-Tm5BFj9AMjr8qTQFU80z-ptiNQ62687NaIvLs/edit?usp=sharing)
* - Clang Static Analysis Working Group
- Every 2 weeks on Tuesdays
- - `ics <https://calendar.google.com/calendar/ical/9c23f3a54dbb4fbac3801c50094fc43118a37c186f5c65b2898cd0fc251c8610%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/u/0?cid=OWMyM2YzYTU0ZGJiNGZiYWMzODAxYzUwMDk0ZmM0MzExOGEzN2MxODZmNWM2NWIyODk4Y2QwZmMyNTFjODYxMEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`__
- - `Meeting notes <https://docs.google.com/document/d/1ijI8pWeyidmhFOd5Ndgvr5AziZwrMCbt2oUehv8qHmw/edit?usp=sharing>`__
+ - [ics](https://calendar.google.com/calendar/ical/9c23f3a54dbb4fbac3801c50094fc43118a37c186f5c65b2898cd0fc251c8610%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/u/0?cid=OWMyM2YzYTU0ZGJiNGZiYWMzODAxYzUwMDk0ZmM0MzExOGEzN2MxODZmNWM2NWIyODk4Y2QwZmMyNTFjODYxMEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
+ - [Meeting notes](https://docs.google.com/document/d/1ijI8pWeyidmhFOd5Ndgvr5AziZwrMCbt2oUehv8qHmw/edit?usp=sharing)
* - LLVM Memory Safety Working Group
- Every 4 weeks on Thursdays
- - `ics <https://calendar.google.com/calendar/ical/2d77f9a2624d18cd46e5299d15cc0fa0c90dca53fd68802261d52121d21a0573%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/u/0?cid=MmQ3N2Y5YTI2MjRkMThjZDQ2ZTUyOTlkMTVjYzBmYTBjOTBkY2E1M2ZkNjg4MDIyNjFkNTIxMjFkMjFhMDU3M0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`__
- - `Meeting notes <https://docs.google.com/document/d/1DkCik6BTnO-cox_9y_BTKzPaJJOo_hBxiNFP3lInvOM/edit?usp=sharing>`__
- * - `Lifetime Safety Breakout Group <https://github.com/orgs/llvm/projects/39>`__
+ - [ics](https://calendar.google.com/calendar/ical/2d77f9a2624d18cd46e5299d15cc0fa0c90dca53fd68802261d52121d21a0573%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/u/0?cid=MmQ3N2Y5YTI2MjRkMThjZDQ2ZTUyOTlkMTVjYzBmYTBjOTBkY2E1M2ZkNjg4MDIyNjFkNTIxMjFkMjFhMDU3M0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
+ - [Meeting notes](https://docs.google.com/document/d/1DkCik6BTnO-cox_9y_BTKzPaJJOo_hBxiNFP3lInvOM/edit?usp=sharing)
+ * - [Lifetime Safety Breakout Group](https://github.com/orgs/llvm/projects/39)
- Every 2 weeks on Wednesdays
- - `ics <https://calendar.google.com/calendar/ical/2d77f9a2624d18cd46e5299d15cc0fa0c90dca53fd68802261d52121d21a0573%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/u/0?cid=MmQ3N2Y5YTI2MjRkMThjZDQ2ZTUyOTlkMTVjYzBmYTBjOTBkY2E1M2ZkNjg4MDIyNjFkNTIxMjFkMjFhMDU3M0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`__
- - `Meeting notes <https://docs.google.com/document/d/1DkCik6BTnO-cox_9y_BTKzPaJJOo_hBxiNFP3lInvOM/edit?tab=t.nvvd6cfloi81>`__
+ - [ics](https://calendar.google.com/calendar/ical/2d77f9a2624d18cd46e5299d15cc0fa0c90dca53fd68802261d52121d21a0573%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/u/0?cid=MmQ3N2Y5YTI2MjRkMThjZDQ2ZTUyOTlkMTVjYzBmYTBjOTBkY2E1M2ZkNjg4MDIyNjFkNTIxMjFkMjFhMDU3M0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t)
+ - [Meeting notes](https://docs.google.com/document/d/1DkCik6BTnO-cox_9y_BTKzPaJJOo_hBxiNFP3lInvOM/edit?tab=t.nvvd6cfloi81)
+```
For event owners, our Discord bot also supports sending automated announcements
-of upcoming sync-ups. Please see the :ref:`discord-bot-event-pings` section for
+of upcoming sync-ups. Please see the {ref}`discord-bot-event-pings` section for
info.
-Past online sync-ups
-^^^^^^^^^^^^^^^^^^^^
+### Past online sync-ups
Some online sync-ups are no longer happening. We keep pointing to them here to
keep track of the meeting notes and in case anyone would want to revive them in
the future.
-.. list-table:: LLVM no-longer-happening sync-up calls
- :widths: 25 25 25 25
- :header-rows: 1
+```{list-table} LLVM no-longer-happening sync-up calls
+:widths: 25 25 25 25
+:header-rows: 1
* - Topic
- Frequency
@@ -268,42 +279,42 @@ the future.
- Minutes/docs link
* - Scalable Vectors and Arm SVE
- Monthly, every 3rd Tuesday
- - `ics <https://calendar.google.com/calendar/ical/bjms39pe6k6bo5egtsp7don414%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/u/0/embed?src=bjms39pe6k6bo5egtsp7don414@group.calendar.google.com>`__
- - `Minutes/docs <https://docs.google.com/document/d/1UPH2Hzou5RgGT8XfO39OmVXKEibWPfdYLELSaHr3xzo/edit>`__
+ - [ics](https://calendar.google.com/calendar/ical/bjms39pe6k6bo5egtsp7don414%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/u/0/embed?src=bjms39pe6k6bo5egtsp7don414@group.calendar.google.com)
+ - [Minutes/docs](https://docs.google.com/document/d/1UPH2Hzou5RgGT8XfO39OmVXKEibWPfdYLELSaHr3xzo/edit)
* - MemorySSA in LLVM
- Every 8 weeks on Mondays
- - `ics <https://calendar.google.com/calendar/ical/c_1mincouiltpa24ac14of14lhi4%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=c_1mincouiltpa24ac14of14lhi4%40group.calendar.google.com>`__
- - `Minutes/docs <https://docs.google.com/document/d/1-uEEZfmRdPThZlctOq9eXlmUaSSAAi8oKxhrPY_lpjk/edit#>`__
+ - [ics](https://calendar.google.com/calendar/ical/c_1mincouiltpa24ac14of14lhi4%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=c_1mincouiltpa24ac14of14lhi4%40group.calendar.google.com)
+ - [Minutes/docs](https://docs.google.com/document/d/1-uEEZfmRdPThZlctOq9eXlmUaSSAAi8oKxhrPY_lpjk/edit#)
* - Vector Predication
- Every 2 weeks on Tuesdays, 3pm UTC
-
- - `Minutes/docs <https://docs.google.com/document/d/1q26ToudQjnqN5x31zk8zgq_s0lem1-BF8pQmciLa4k8/edit?usp=sharing>`__
- * - `MLIR <https://mlir.llvm.org>`__ design meetings
+ - [Minutes/docs](https://docs.google.com/document/d/1q26ToudQjnqN5x31zk8zgq_s0lem1-BF8pQmciLa4k8/edit?usp=sharing)
+ * - [MLIR](https://mlir.llvm.org) design meetings
- Weekly, on Thursdays
-
- - `Minutes/docs <https://docs.google.com/document/d/1y_9f1AbfgcoVdJh4_aM6-BaSHvrHl8zuA5G4jv_94K8/edit#heading=h.cite1kolful9>`__
+ - [Minutes/docs](https://docs.google.com/document/d/1y_9f1AbfgcoVdJh4_aM6-BaSHvrHl8zuA5G4jv_94K8/edit#heading=h.cite1kolful9)
+```
-.. _office-hours:
+(office-hours)=
-Office hours
-------------
+## Office hours
A number of experienced LLVM contributors make themselves available for a chat
on a regular schedule, to anyone who is looking for some guidance. Please find
the list of who is available when, through which medium, and what their area of
expertise is. Don't be too shy to dial in!
-Office hours are also listed on the :ref:`llvm-community-calendar`. Of course,
+Office hours are also listed on the {ref}`llvm-community-calendar`. Of course,
people take time off from time to time, so if you dial in and you don't find
anyone present, chances are they happen to be off that day.
-The :doc:`CodeOfConduct` applies to all office hours.
+The {doc}`CodeOfConduct` applies to all office hours.
-.. list-table:: LLVM office hours
- :widths: 15 40 15 15 15
- :header-rows: 1
+```{list-table} LLVM office hours
+:widths: 15 40 15 15 15
+:header-rows: 1
* - Name
- In-scope topics
@@ -315,92 +326,92 @@ The :doc:`CodeOfConduct` applies to all office hours.
submitting talks; and other general LLVM-related topics. Arm/AArch64
codegen. LLVM security group. LLVM Office Hours.
- Every 2nd and 4th Wednesday of the month at 9.30am CET, for 30 minutes.
- `ics <https://user.fm/calendar/v1-eac36694e3024854a9402da023f9e0fa/Kristof%20Beyls%20LLVM%20office%20hours.ics>`__
- - `Jitsi <https://meet.jit.si/KristofBeylsLLVMOfficeHour>`__
+ [ics](https://user.fm/calendar/v1-eac36694e3024854a9402da023f9e0fa/Kristof%20Beyls%20LLVM%20office%20hours.ics)
+ - [Jitsi](https://meet.jit.si/KristofBeylsLLVMOfficeHour)
- English, Flemish, Dutch
* - Alina Sbirlea
- General questions on how to contribute to LLVM; women in compilers;
MemorySSA, BatchAA, various loop passes, new pass manager.
- Monthly, 2nd Tuesdays, 10.00am PT/7:00pm CET, for 30 minutes.
- `ics <https://calendar.google.com/calendar/ical/c_pm6e7160iq7n5fcm1s6m3rjhh4%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=c_pm6e7160iq7n5fcm1s6m3rjhh4%40group.calendar.google.com>`__
- - `GoogleMeet <https://meet.google.com/hhk-xpdj-gvx>`__
+ [ics](https://calendar.google.com/calendar/ical/c_pm6e7160iq7n5fcm1s6m3rjhh4%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=c_pm6e7160iq7n5fcm1s6m3rjhh4%40group.calendar.google.com)
+ - [GoogleMeet](https://meet.google.com/hhk-xpdj-gvx)
- English, Romanian
* - Aaron Ballman (he/him)
- Clang internals; frontend attributes; clang-tidy; clang-query; AST matchers
- Monthly, 2nd Monday and 3rd Friday of the month at 10:00am Eastern and again at 2:00pm Eastern, for 60 minutes.
- `ics <https://calendar.google.com/calendar/ical/npgke5dug0uliud0qapptmps58%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=npgke5dug0uliud0qapptmps58%40group.calendar.google.com>`__
- - `GoogleMeet <https://meet.google.com/xok-iqne-gmi>`__
+ [ics](https://calendar.google.com/calendar/ical/npgke5dug0uliud0qapptmps58%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=npgke5dug0uliud0qapptmps58%40group.calendar.google.com)
+ - [GoogleMeet](https://meet.google.com/xok-iqne-gmi)
- English, Norwegian (not fluently)
* - Johannes Doerfert (he/him)
- OpenMP, LLVM-IR, interprocedural optimizations, Attributor, workshops, research, ...
- Every week, Wednesdays 9:30am (Pacific Time), for 1 hour.
- `ics <https://drive.google.com/file/d/1E_QkRvirmdJzlXf2EKBUX-v8Xj7-eW3v/view?usp=sharing>`__
- - `MS Teams <https://teams.microsoft.com/l/meetup-join/19%3ameeting_MTMxNzU4MWYtYzViNS00OTM2LWJmNWQtMjg5ZWFhNGVjNzgw%40thread.v2/0?context=%7b%22Tid%22%3a%22a722dec9-ae4e-4ae3-9d75-fd66e2680a63%22%2c%22Oid%22%3a%22885bda30-ce8e-46db-aa7e-15de0474831a%22%7d>`__
+ [ics](https://drive.google.com/file/d/1E_QkRvirmdJzlXf2EKBUX-v8Xj7-eW3v/view?usp=sharing)
+ - [MS Teams](https://teams.microsoft.com/l/meetup-join/19%3ameeting_MTMxNzU4MWYtYzViNS00OTM2LWJmNWQtMjg5ZWFhNGVjNzgw%40thread.v2/0?context=%7b%22Tid%22%3a%22a722dec9-ae4e-4ae3-9d75-fd66e2680a63%22%2c%22Oid%22%3a%22885bda30-ce8e-46db-aa7e-15de0474831a%22%7d)
- English, German
* - Tobias Grosser
- General questions on how to contribute to LLVM/MLIR, Polly, Loop Optimization, FPL, Research in LLVM, PhD in CS, Summer of Code.
- Monthly, last Monday of the month at 18:00 London time (typically 9am PT), for 30 minutes.
- - `Video Call <https://meet.grosser.science/LLVMOfficeHours>`__
+ - [Video Call](https://meet.grosser.science/LLVMOfficeHours)
- English, German, Spanish, French
* - Alexey Bader
- SYCL compiler, offload tools, OpenCL and SPIR-V, how to contribute.
- Monthly, 2nd Monday of the month at 9:30am PT, for 30 minutes.
- - `GoogleMeet <https://meet.google.com/pdz-xhns-uus>`__
+ - [GoogleMeet](https://meet.google.com/pdz-xhns-uus)
- English, Russian
* - Maksim Panchenko
- BOLT internals, IR, new passes, proposals, etc.
- Monthly, 2nd Wednesday of the month at 11:00am PT, for 30 minutes.
- - `Zoom <https://fb.zoom.us/j/97065697120?pwd=NTFaUWJjZW9uVkJuaVlPTE9qclE3dz09>`__
+ - [Zoom](https://fb.zoom.us/j/97065697120?pwd=NTFaUWJjZW9uVkJuaVlPTE9qclE3dz09)
- English, Russian
* - Quentin Colombet (he/him)
- LLVM/MLIR; Codegen (Instruction selection (GlobalISel/SDISel), Machine IR,
Register allocation, etc.); Optimizations; MCA
- Monthly, 1st Wednesday of the month at 8.00am PT, for 30 minutes.
- `ics <https://calendar.google.com/calendar/ical/48c4ad60290a4df218e51e1ceec1106fe317b0ebc76938d9273592053f38204e%40group.calendar.google.com/public/basic.ics>`__
- `gcal <https://calendar.google.com/calendar/embed?src=48c4ad60290a4df218e51e1ceec1106fe317b0ebc76938d9273592053f38204e%40group.calendar.google.com>`__
- - `Google meet <https://meet.google.com/cbz-grrp-obs>`__
+ [ics](https://calendar.google.com/calendar/ical/48c4ad60290a4df218e51e1ceec1106fe317b0ebc76938d9273592053f38204e%40group.calendar.google.com/public/basic.ics)
+ [gcal](https://calendar.google.com/calendar/embed?src=48c4ad60290a4df218e51e1ceec1106fe317b0ebc76938d9273592053f38204e%40group.calendar.google.com)
+ - [Google meet](https://meet.google.com/cbz-grrp-obs)
- English, French
* - Phoebe Wang (she/her)
- X86 backend, General questions to X86, women in compilers.
- Monthly, 3rd Wednesday of the month at 8:30am Beijing time, for 30 minutes.
- - `MS Teams <https://teams.microsoft.com/l/meetup-join/19%3ameeting_NWQ0MjU0NjYtZjUyMi00YTU3LThmM2EtY2Y2YTE4NGM3NmFi%40thread.v2/0?context=%7b%22Tid%22%3a%2246c98d88-e344-4ed4-8496-4ed7712e255d%22%2c%22Oid%22%3a%227b309d9c-a9bb-44c8-a940-ab97eef42d4d%22%7d>`__
+ - [MS Teams](https://teams.microsoft.com/l/meetup-join/19%3ameeting_NWQ0MjU0NjYtZjUyMi00YTU3LThmM2EtY2Y2YTE4NGM3NmFi%40thread.v2/0?context=%7b%22Tid%22%3a%2246c98d88-e344-4ed4-8496-4ed7712e255d%22%2c%22Oid%22%3a%227b309d9c-a9bb-44c8-a940-ab97eef42d4d%22%7d)
- English, Chinese
* - Amara Emerson
- GlobalISel questions.
- Monthly, 4th Wednesday of the month at 9:30am PT, for 30 minutes.
- - `Google meet <https://meet.google.com/pdd-dibg-cwv>`__
+ - [Google meet](https://meet.google.com/pdd-dibg-cwv)
- English
* - Maksim Levental and Jeremy Kun
- - MLIR newcomers and general discussion (`livestreamed <https://www.youtube.com/playlist?list=PLhxO86S3jsX2k7kOhZaV-qKWm8tNsUdAE>`__)
+ - MLIR newcomers and general discussion ([livestreamed](https://www.youtube.com/playlist?list=PLhxO86S3jsX2k7kOhZaV-qKWm8tNsUdAE))
- Every two weeks, Wednesdays at 2:00pm US Pacific, for 90 minutes.
- - Livestream chat or `Google meet <https://meet.google.com/wit-tvzc-dwc>`__
+ - Livestream chat or [Google meet](https://meet.google.com/wit-tvzc-dwc)
- English
* - Renato Golin
- General LLVM, MLIR & Linalg, distributed computing, research, socials.
- Every first Friday of the month, 14:00 UK time, for 60 minutes.
- - `Google meet <https://meet.google.com/jps-twgq-ivz>`__
+ - [Google meet](https://meet.google.com/jps-twgq-ivz)
- English, Portuguese
+```
For event owners, our Discord bot also supports sending automated announcements
-of upcoming office hours. Please see the :ref:`discord-bot-event-pings` section
+of upcoming office hours. Please see the {ref}`discord-bot-event-pings` section
for info.
-Guidance for office hours hosts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Guidance for office hours hosts
* If you're interested in becoming an office hours host, please add your
information to the list above. Please create a calendar event for it and
invite calendar at llvm.org to the event so that it'll show up on the
- :ref:`llvm-community-calendar`.
- Please see :ref:`llvm-community-calendar-host-guidance` for more guidance on
+ {ref}`llvm-community-calendar`.
+ Please see {ref}`llvm-community-calendar-host-guidance` for more guidance on
what to add to your calendar invite.
* When starting an office hours session, if you haven't set up the Discord bot
integration, consider typing something like "*Hi, I'm available for chats in
the next half hour at* video chat URL. *I'm looking forward to having
conversations on the video chat or here.*" on the
- `#office-hours Discord channel <https://discord.com/channels/636084430946959380/976196303681896538>`__.
+ [#office-hours Discord channel](https://discord.com/channels/636084430946959380/976196303681896538).
Doing this can help:
* overcome potential anxiety to call in for a first time,
@@ -411,66 +422,66 @@ Guidance for office hours hosts
from the list above.
-Discord
--------
+## Discord
Users and developers of the LLVM project (including subprojects such as Clang)
-can be found on the community's `Discord <https://discord.gg/xS7Z362>`_
+can be found on the community's [Discord](https://discord.gg/xS7Z362)
chat server. The server is actively moderated.
The #buildbot-status channel has a bot for
-`LLVM buildbot <http://lab.llvm.org/buildbot/#/console>`_ status changes. The
+[LLVM buildbot](http://lab.llvm.org/buildbot/#/console) status changes. The
bot will update the channel with a link to a build bot when a build goes from
passing to failing and again when the build goes from failing back to passing.
It is a great way to actively monitor the status of the build.
The bot also supports @mention-ing you when your email appears on a blamelist.
-For more details, DM ``help`` to the bot.
+For more details, DM `help` to the bot.
-.. _discord-bot-event-pings:
+(discord-bot-event-pings)=
-Discord bot event pings
-^^^^^^^^^^^^^^^^^^^^^^^
+### Discord bot event pings
Our Discord bot supports automatically sending messages about upcoming events
-on `the LLVM community calendar <https://calendar.google.com/calendar/u/0/embed?src=calendar@llvm.org>`_
+on [the LLVM community calendar](https://calendar.google.com/calendar/u/0/embed?src=calendar@llvm.org)
to Discord. This behavior is controlled on a per-event basis, by metadata in the
event's description. Each piece of metadata should be on its own line in the
event description.
The currently supported metadata is:
-- ``discord-bot-event-type`` - **Required**. Specifies the event type. Valid
- values are ``office-hours`` and ``sync-up``.
-- ``discord-bot-channels-to-mention`` - **Sometimes required**. A
+- `discord-bot-event-type` - **Required**. Specifies the event type. Valid
+ values are `office-hours` and `sync-up`.
+- `discord-bot-channels-to-mention` - **Sometimes required**. A
comma-separated list of Discord channels to post notifications in. If your
- ``discord-bot-event-type`` is ``office-hours``, the ``#office-hours`` channel
+ `discord-bot-event-type` is `office-hours`, the `#office-hours` channel
will be implicitly appended to this list (ergo, you don't need to specify this
item). Otherwise, you must specify a value here.
-- ``discord-bot-mention`` - **Optional**. A comma-separated list of people to
+- `discord-bot-mention` - **Optional**. A comma-separated list of people to
ping on each event notification. All names mentioned must be Discord
- usernames, and must have a leading ``@``. e.g., ``@foo, @bar``.
-- ``discord-bot-reminder-time-before-start`` - **Optional**. The number of
+ usernames, and must have a leading `@`. e.g., `@foo, @bar`.
+- `discord-bot-reminder-time-before-start` - **Optional**. The number of
minutes before the beginning of an event to send a ping. This should be
formatted as an integer. Defaults to 30.
-- ``discord-bot-message`` - **Optional**. Text to append to all event pings.
+- `discord-bot-message` - **Optional**. Text to append to all event pings.
-An example of an event description with valid metadata is::
+An example of an event description with valid metadata is:
- Regular office hours to chat with people about LLVM! We can help with
- questions, troubleshooting bugs, etc.
+```text
+Regular office hours to chat with people about LLVM! We can help with
+questions, troubleshooting bugs, etc.
- discord-bot-channels-to-mention: #beginners, #foo
- discord-bot-event-type: office-hours
- discord-bot-mention: @gburgessiv, @bar
- discord-bot-message: Come join us for office hours!
- discord-bot-reminder-time-before-start: 5
+discord-bot-channels-to-mention: #beginners, #foo
+discord-bot-event-type: office-hours
+discord-bot-mention: @gburgessiv, @bar
+discord-bot-message: Come join us for office hours!
+discord-bot-reminder-time-before-start: 5
+```
This metadata will prompt the Discord bot to:
-* send pings 5 minutes before the given event starts, mentioning ``@gburgessiv``
- and ``@bar`` in the ping
-* send the pings to the ``#beginners``, ``#foo``, and ``#office-hours`` channels
+* send pings 5 minutes before the given event starts, mentioning `@gburgessiv`
+ and `@bar` in the ping
+* send the pings to the `#beginners`, `#foo`, and `#office-hours` channels
* include the text "Come join us for office hours!" in the ping
A few minutes before sending a ping, the bot will double-check that the event
@@ -479,79 +490,82 @@ hasn't been cancelled.
If you need help troubleshooting, or have feature requests/questions, please
feel free to ping @gburgessiv!
-.. _meetups-social-events:
+(meetups-social-events)=
-Meetups and social events
--------------------------
+## Meetups and social events
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- MeetupGuidelines
+MeetupGuidelines
+```
-Besides developer `meetings and conferences <https://llvm.org/devmtg/>`_,
+Besides developer [meetings and conferences](https://llvm.org/devmtg/),
there are several user groups called
-`LLVM Socials <https://www.meetup.com/pro/llvm/>`_. We greatly encourage you to
+[LLVM Socials](https://www.meetup.com/pro/llvm/). We greatly encourage you to
join one in your city. Or start a new one if there is none:
-:doc:`MeetupGuidelines`
+{doc}`MeetupGuidelines`
-.. _community-proposals:
+(community-proposals)=
-Community wide proposals
-------------------------
+## Community wide proposals
Proposals for large-scale changes in how the community behaves and how the work flow
can be better.
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
+
+Proposals/GitHubMove
+BugpointRedesign
+Proposals/TestSuite
+Proposals/VariableNames
+Proposals/VectorPredication
+```
- Proposals/GitHubMove
- BugpointRedesign
- Proposals/TestSuite
- Proposals/VariableNames
- Proposals/VectorPredication
+* {doc}`Proposals/GitHubMove`
-:doc:`Proposals/GitHubMove`
- Proposal to move from SVN/Git to GitHub.
+ Proposal to move from SVN/Git to GitHub.
-:doc:`BugpointRedesign`
- Design doc for a redesign of the Bugpoint tool.
+* {doc}`BugpointRedesign`
-:doc:`Proposals/TestSuite`
- Proposals for additional benchmarks/programs for llvm's test-suite.
+ Design doc for a redesign of the Bugpoint tool.
-:doc:`Proposals/VariableNames`
- Proposal to change the variable names coding standard.
+* {doc}`Proposals/TestSuite`
-:doc:`Proposals/VectorPredication`
- Proposal for predicated vector instructions in LLVM.
+ Proposals for additional benchmarks/programs for llvm's test-suite.
-.. _llvm-community-calendar:
+* {doc}`Proposals/VariableNames`
-LLVM community calendar
------------------------
+ Proposal to change the variable names coding standard.
+
+* {doc}`Proposals/VectorPredication`
+
+ Proposal for predicated vector instructions in LLVM.
+
+(llvm-community-calendar)=
+
+## LLVM community calendar
We aim to maintain a public calendar view of all events happening in the LLVM
-community such as :ref:`online-sync-ups` and :ref:`office-hours`. The calendar
+community such as {ref}`online-sync-ups` and {ref}`office-hours`. The calendar
can be found at
https://calendar.google.com/calendar/u/0/embed?src=calendar@llvm.org and can
also be seen inline below:
-.. raw:: html
-
- <iframe src="https://calendar.google.com/calendar/embed?height=600&wkst=1&bgcolor=%23ffffff&ctz=UTC&showCalendars=0&showDate=1&showNav=1&src=Y2FsZW5kYXJAbGx2bS5vcmc&color=%23039BE5" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"></iframe>
+```{raw} html
+<iframe src="https://calendar.google.com/calendar/embed?height=600&wkst=1&bgcolor=%23ffffff&ctz=UTC&showCalendars=0&showDate=1&showNav=1&src=Y2FsZW5kYXJAbGx2bS5vcmc&color=%23039BE5" style="border:solid 1px #777" width="800" height="600" frameborder="0" scrolling="no"></iframe>
+```
Note that the web view of the LLVM community calendar shows events in
Coordinated Universal Time (UTC). If you use Google Calendar, consider
subscribing to it with the + button in the bottom-right corner to view all
events in your local time zone alongside your other calendars.
-.. _llvm-community-calendar-host-guidance:
+(llvm-community-calendar-host-guidance)=
-Guidance on what to put into LLVM community calendar invites
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Guidance on what to put into LLVM community calendar invites
To add your event, create a calendar event for it and invite calendar at llvm.org
on it. Your event should then show up on the community calendar.
@@ -560,7 +574,7 @@ Please put the following pieces of information in your calendar invite:
* Write a single paragraph describing what the event is about. Include things
such as who the event is for and what sort of topics are discussed.
-* State explicitly that the :doc:`CodeOfConduct` applies to this event.
+* State explicitly that the {doc}`CodeOfConduct` applies to this event.
* Make it clear who:
* the organizer is.
@@ -573,25 +587,25 @@ Please put the following pieces of information in your calendar invite:
* If you're hosting a sync-up or office hours event and would like it to be
announced by the Discord bot, add the relevant metadata (full descriptions
- available in the :ref:`discord-bot-event-pings` section).
+ available in the {ref}`discord-bot-event-pings` section).
An example invite looks as follows
-.. code-block:: none
-
- This event is a meetup for all developers of LLDB. Meeting agendas are posted
- on Discourse before the event.
+```text
+This event is a meetup for all developers of LLDB. Meeting agendas are posted
+on Discourse before the event.
- Attendees must adhere to the LLVM Code of Conduct
- (https://llvm.org/docs/CodeOfConduct.html). For any Code of Conduct reports,
- please contact the organizers and also email conduct at llvm.org.
+Attendees must adhere to the LLVM Code of Conduct
+(https://llvm.org/docs/CodeOfConduct.html). For any Code of Conduct reports,
+please contact the organizers and also email conduct at llvm.org.
- Agenda/Meeting Minutes: Link to minutes
+Agenda/Meeting Minutes: Link to minutes
- Organizer(s): First Surname (name at email.com)
+Organizer(s): First Surname (name at email.com)
- discord-bot-channels-to-mention: #lldb
- discord-bot-event-type: sync-up
- discord-bot-mention: @host-username, @another-host
- discord-bot-message: Come join us to chat about LLDB!
- discord-bot-reminder-time-before-start: 30
+discord-bot-channels-to-mention: #lldb
+discord-bot-event-type: sync-up
+discord-bot-mention: @host-username, @another-host
+discord-bot-message: Come join us to chat about LLDB!
+discord-bot-reminder-time-before-start: 30
+```
diff --git a/llvm/docs/GettingStarted.md b/llvm/docs/GettingStarted.md
index fffa5a0d8280e..ddc5fb73610e1 100644
--- a/llvm/docs/GettingStarted.md
+++ b/llvm/docs/GettingStarted.md
@@ -1,12 +1,10 @@
-====================================
-Getting Started with the LLVM System
-====================================
+# Getting Started with the LLVM System
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Overview
-========
+## Overview
Welcome to the LLVM project!
@@ -16,127 +14,121 @@ files needed to process intermediate representations and convert them into
object files. Tools include an assembler, disassembler, bitcode analyzer, and
bitcode optimizer. It also contains basic regression tests.
-C-like languages use the `Clang <https://clang.llvm.org/>`_ front end. This
+C-like languages use the [Clang](https://clang.llvm.org/) front end. This
component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode
-- and from there into object files, using LLVM.
Other components include:
-the `libc++ C++ standard library <https://libcxx.llvm.org>`_,
-the `LLD linker <https://lld.llvm.org>`_, and more.
+the [libc++ C++ standard library](https://libcxx.llvm.org),
+the [LLD linker](https://lld.llvm.org), and more.
-.. _sources:
+(sources)=
+## Getting the Source Code and Building LLVM
-Getting the Source Code and Building LLVM
-=========================================
+1. Check out LLVM (including subprojects like Clang):
-#. Check out LLVM (including subprojects like Clang):
-
- * ``git clone https://github.com/llvm/llvm-project.git``
+ * `git clone https://github.com/llvm/llvm-project.git`
* Or, on Windows:
- ``git clone --config core.autocrlf=false
- https://github.com/llvm/llvm-project.git``
+ `git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git`
* To save storage and speed up the checkout time, you may want to do a
- `shallow clone <https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt>`_.
+ [shallow clone](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt).
For example, to get the latest revision of the LLVM project, use
- ``git clone --depth 1 https://github.com/llvm/llvm-project.git``
+ `git clone --depth 1 https://github.com/llvm/llvm-project.git`
* You are likely not interested in the user branches in the repo (used for
stacked pull requests and reverts), you can filter them from your
`git fetch` (or `git pull`) with this configuration:
- .. code-block:: console
-
- git config --add remote.origin.fetch '^refs/heads/users/*'
- git config --add remote.origin.fetch '^refs/heads/revert-*'
-
-#. Configure and build LLVM and Clang:
+ ```console
+ git config --add remote.origin.fetch '^refs/heads/users/*'
+ git config --add remote.origin.fetch '^refs/heads/revert-*'
+ ```
+1. Configure and build LLVM and Clang:
- * ``cd llvm-project``
- * ``cmake -S llvm -B build -G <generator> [options]``
+ * `cd llvm-project`
+ * `cmake -S llvm -B build -G <generator> [options]`
Some common build system generators are:
- * ``Ninja`` --- for generating `Ninja <https://ninja-build.org>`_
+ * `Ninja` --- for generating [Ninja](https://ninja-build.org)
build files. Most llvm developers use Ninja.
- * ``Unix Makefiles`` --- for generating make-compatible parallel makefiles.
- * ``Visual Studio`` --- for generating Visual Studio projects and
+ * `Unix Makefiles` --- for generating make-compatible parallel makefiles.
+ * `Visual Studio` --- for generating Visual Studio projects and
solutions.
- * ``Xcode`` --- for generating Xcode projects.
+ * `Xcode` --- for generating Xcode projects.
- * See the `CMake docs
- <https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html>`_
+ * See the [CMake docs](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html)
for a more comprehensive list.
Some common options:
- * ``-DLLVM_ENABLE_PROJECTS='...'`` --- A semicolon-separated list of the LLVM
+ * `-DLLVM_ENABLE_PROJECTS='...'` --- A semicolon-separated list of the LLVM
subprojects you'd like to additionally build. Can include any of: clang,
clang-tools-extra, lldb, lld, polly, or cross-project-tests.
For example, to build LLVM, Clang, and LLD, use
- ``-DLLVM_ENABLE_PROJECTS="clang;lld"``.
+ `-DLLVM_ENABLE_PROJECTS="clang;lld"`.
- * ``-DCMAKE_INSTALL_PREFIX=directory`` --- Specify for *directory* the full
+ * `-DCMAKE_INSTALL_PREFIX=directory` --- Specify for *directory* the full
pathname of where you want the LLVM tools and libraries to be installed
- (default ``/usr/local``).
+ (default `/usr/local`).
- * ``-DCMAKE_BUILD_TYPE=type`` --- Controls the optimization level and debug
- information of the build. Valid options for *type* are ``Debug``,
- ``Release``, ``RelWithDebInfo``, and ``MinSizeRel``. For more detailed
- information, see :ref:`CMAKE_BUILD_TYPE <cmake_build_type>`.
+ * `-DCMAKE_BUILD_TYPE=type` --- Controls the optimization level and debug
+ information of the build. Valid options for *type* are `Debug`,
+ `Release`, `RelWithDebInfo`, and `MinSizeRel`. For more detailed
+ information, see {ref}`CMAKE_BUILD_TYPE <cmake_build_type>`.
- * ``-DLLVM_ENABLE_ASSERTIONS=ON`` --- Compile with assertion checks enabled
+ * `-DLLVM_ENABLE_ASSERTIONS=ON` --- Compile with assertion checks enabled
(default is ON for Debug builds, OFF for all other build types).
- * ``-DLLVM_USE_LINKER=lld`` --- Link with the `lld linker`_, assuming it
+ * `-DLLVM_USE_LINKER=lld` --- Link with the [lld linker](https://lld.llvm.org), assuming it
is installed on your system. This can dramatically speed up link times
if the default linker is slow.
- * ``-DLLVM_PARALLEL_{COMPILE,LINK,TABLEGEN}_JOBS=N`` --- Limit the number of
+ * `-DLLVM_PARALLEL_{COMPILE,LINK,TABLEGEN}_JOBS=N` --- Limit the number of
compile/link/tablegen jobs running in parallel at the same time. This is
especially important for linking since linking can use lots of memory. If
you run into memory issues building LLVM, try setting this to limit the
maximum number of compile/link/tablegen jobs running at the same time.
- * ``cmake --build build [--target <target>]`` or the build system specified
+ * `cmake --build build [--target <target>]` or the build system specified
above directly.
- * The default target (i.e. ``cmake --build build`` or ``make -C build``)
+ * The default target (i.e. `cmake --build build` or `make -C build`)
will build all of LLVM.
- * The ``check-all`` target (i.e. ``ninja check-all``) will run the
+ * The `check-all` target (i.e. `ninja check-all`) will run the
regression tests to ensure everything is in working order.
* CMake will generate build targets for each tool and library, and most
- LLVM sub-projects generate their own ``check-<project>`` target.
+ LLVM sub-projects generate their own `check-<project>` target.
* Running a serial build will be **slow**. To improve speed, try running a
- parallel build. That's done by default in Ninja; for ``make``, use the
- option ``-j NN``, where ``NN`` is the number of parallel jobs, e.g. the
+ parallel build. That's done by default in Ninja; for `make`, use the
+ option `-j NN`, where `NN` is the number of parallel jobs, e.g. the
number of available CPUs.
* A basic CMake and build/test invocation which only builds LLVM and no other
subprojects:
- ``cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug``
+ `cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug`
- ``ninja -C build check-llvm``
+ `ninja -C build check-llvm`
This will set up an LLVM build with debugging info, then compile LLVM and
run LLVM tests.
- * For more detailed information on CMake options, see `CMake <CMake.html>`__
+ * For more detailed information on CMake options, see {doc}`CMake <CMake>`
- * If you get build or test failures, see `below`_.
+ * If you get build or test failures, see {ref}`below <below>`.
-Consult the `Getting Started with LLVM`_ section for detailed information on
-configuring and compiling LLVM. Go to `Directory Layout`_ to learn about the
+Consult the {ref}`Getting Started with LLVM <Getting Started with LLVM>` section for detailed information on
+configuring and compiling LLVM. Go to {ref}`Directory Layout <Program Layout>` to learn about the
layout of the source code tree.
-Stand-alone Builds
-------------------
+### Stand-alone Builds
Stand-alone builds allow you to build a sub-project against a pre-built
version of the clang or llvm libraries that is already present on your
@@ -144,8 +136,8 @@ system.
You can use the source code from a standard checkout of the llvm-project
(as described above) to do stand-alone builds, but you may also build
-from a :ref:`sparse checkout<workflow-multicheckout-nocommit>` or from the
-tarballs available on the `releases <https://github.com/llvm/llvm-project/releases/>`_
+from a {ref}`sparse checkout <workflow-multicheckout-nocommit>` or from the
+tarballs available on the [releases](https://github.com/llvm/llvm-project/releases/)
page.
For stand-alone builds, you must have an llvm install that is configured
@@ -153,125 +145,115 @@ properly to be consumable by stand-alone builds of the other projects.
This could be a distro-provided LLVM install, or you can build it yourself,
like this:
-.. code-block:: console
-
- cmake -G Ninja -S path/to/llvm-project/llvm -B $builddir \
- -DLLVM_INSTALL_UTILS=ON \
- -DCMAKE_INSTALL_PREFIX=/path/to/llvm/install/prefix \
- < other options >
-
- ninja -C $builddir install
+```console
+cmake -G Ninja -S path/to/llvm-project/llvm -B $builddir \
+ -DLLVM_INSTALL_UTILS=ON \
+ -DCMAKE_INSTALL_PREFIX=/path/to/llvm/install/prefix \
+ < other options >
+ninja -C $builddir install
+```
Once llvm is installed, to configure a project for a stand-alone build, invoke CMake like this:
-.. code-block:: console
-
- cmake -G Ninja -S path/to/llvm-project/$subproj \
- -B $buildir_subproj \
- -DLLVM_EXTERNAL_LIT=/path/to/lit \
- -DLLVM_ROOT=/path/to/llvm/install/prefix
-
+```console
+cmake -G Ninja -S path/to/llvm-project/$subproj \
+ -B $buildir_subproj \
+ -DLLVM_EXTERNAL_LIT=/path/to/lit \
+ -DLLVM_ROOT=/path/to/llvm/install/prefix
+```
Notice that:
* The stand-alone build needs to happen in a folder that is not the
original folder where LLVM was built
(`$builddir!=$builddir_subproj`).
-* ``LLVM_ROOT`` should point to the prefix of your llvm installation,
- so for example, if llvm is installed into ``/usr/bin`` and
- ``/usr/lib64``, then you should pass ``-DLLVM_ROOT=/usr/``.
-* Both the ``LLVM_ROOT`` and ``LLVM_EXTERNAL_LIT`` options are
+* `LLVM_ROOT` should point to the prefix of your llvm installation,
+ so for example, if llvm is installed into `/usr/bin` and
+ `/usr/lib64`, then you should pass `-DLLVM_ROOT=/usr/`.
+* Both the `LLVM_ROOT` and `LLVM_EXTERNAL_LIT` options are
required to do stand-alone builds for all sub-projects. Additional
required options for each sub-project can be found in the table
below.
-The ``check-$subproj`` and ``install`` build targets are supported for the
+The `check-$subproj` and `install` build targets are supported for the
sub-projects listed in the table below.
-============ ======================== ======================
-Sub-Project Required Sub-Directories Required CMake Options
-============ ======================== ======================
-llvm llvm, cmake, third-party LLVM_INSTALL_UTILS=ON
-clang clang, cmake CLANG_INCLUDE_TESTS=ON (Required for check-clang only)
-lld lld, cmake
-============ ======================== ======================
+| Sub-Project | Required Sub-Directories | Required CMake Options |
+| --- | --- | --- |
+| llvm | llvm, cmake, third-party | LLVM_INSTALL_UTILS=ON |
+| clang | clang, cmake | CLANG_INCLUDE_TESTS=ON (Required for check-clang only) |
+| lld | lld, cmake | |
Example of building stand-alone `clang`:
-.. code-block:: console
-
- #!/bin/sh
+```console
+#!/bin/sh
- build_llvm=`pwd`/build-llvm
- build_clang=`pwd`/build-clang
- installprefix=`pwd`/install
- llvm=`pwd`/llvm-project
- mkdir -p $build_llvm
- mkdir -p $installprefix
+build_llvm=`pwd`/build-llvm
+build_clang=`pwd`/build-clang
+installprefix=`pwd`/install
+llvm=`pwd`/llvm-project
+mkdir -p $build_llvm
+mkdir -p $installprefix
- cmake -G Ninja -S $llvm/llvm -B $build_llvm \
- -DLLVM_INSTALL_UTILS=ON \
- -DCMAKE_INSTALL_PREFIX=$installprefix \
- -DCMAKE_BUILD_TYPE=Release
+cmake -G Ninja -S $llvm/llvm -B $build_llvm \
+ -DLLVM_INSTALL_UTILS=ON \
+ -DCMAKE_INSTALL_PREFIX=$installprefix \
+ -DCMAKE_BUILD_TYPE=Release
- ninja -C $build_llvm install
+ninja -C $build_llvm install
- cmake -G Ninja -S $llvm/clang -B $build_clang \
- -DLLVM_EXTERNAL_LIT=$build_llvm/utils/lit \
- -DLLVM_ROOT=$installprefix
+cmake -G Ninja -S $llvm/clang -B $build_clang \
+ -DLLVM_EXTERNAL_LIT=$build_llvm/utils/lit \
+ -DLLVM_ROOT=$installprefix
- ninja -C $build_clang
-
-Requirements
-============
+ninja -C $build_clang
+```
+## Requirements
Before you begin to use the LLVM system, review the requirements below.
This may save you some trouble by knowing ahead of time what hardware and
software you will need.
-Hardware
---------
+### Hardware
LLVM is known to work on the following host platforms:
-================== ===================== ==============================
-OS Arch Compilers
-================== ===================== ==============================
-Linux x86\ :sup:`1` GCC, Clang
-Linux amd64 GCC, Clang
-Linux ARM GCC, Clang
-Linux AArch64 GCC, Clang
-Linux LoongArch GCC, Clang
-Linux Mips GCC, Clang
-Linux PowerPC GCC, Clang
-Linux RISC-V GCC, Clang
-Linux SystemZ GCC, Clang
-Solaris V9 (Ultrasparc) GCC
-DragonFlyBSD amd64 GCC, Clang
-FreeBSD x86\ :sup:`1` GCC, Clang
-FreeBSD amd64 GCC, Clang
-FreeBSD AArch64 GCC, Clang
-NetBSD x86\ :sup:`1` GCC, Clang
-NetBSD amd64 GCC, Clang
-OpenBSD x86\ :sup:`1` GCC, Clang
-OpenBSD amd64 GCC, Clang
-macOS\ :sup:`2` PowerPC GCC
-macOS x86 GCC, Clang
-macOS arm64 Clang
-Cygwin/Win32 x86\ :sup:`1, 3` GCC
-Windows x86\ :sup:`1` Visual Studio
-Windows x64 x86-64 Visual Studio, Clang\ :sup:`4`
-Windows on Arm ARM64 Visual Studio, Clang\ :sup:`4`
-================== ===================== ==============================
-
-.. note::
-
- #. Code generation supported for Pentium processors and up
- #. Code generation supported for 32-bit ABI only
- #. To use LLVM modules on a Win32-based system, you may configure LLVM
- with ``-DBUILD_SHARED_LIBS=On``.
- #. Visual Studio alone can compile LLVM. When using Clang, you
- must also have Visual Studio installed.
-
+| OS | Arch | Compilers |
+| --- | --- | --- |
+| Linux | x86{sup}`1` | GCC, Clang |
+| Linux | amd64 | GCC, Clang |
+| Linux | ARM | GCC, Clang |
+| Linux | AArch64 | GCC, Clang |
+| Linux | LoongArch | GCC, Clang |
+| Linux | Mips | GCC, Clang |
+| Linux | PowerPC | GCC, Clang |
+| Linux | RISC-V | GCC, Clang |
+| Linux | SystemZ | GCC, Clang |
+| Solaris | V9 (Ultrasparc) | GCC |
+| DragonFlyBSD | amd64 | GCC, Clang |
+| FreeBSD | x86{sup}`1` | GCC, Clang |
+| FreeBSD | amd64 | GCC, Clang |
+| FreeBSD | AArch64 | GCC, Clang |
+| NetBSD | x86{sup}`1` | GCC, Clang |
+| NetBSD | amd64 | GCC, Clang |
+| OpenBSD | x86{sup}`1` | GCC, Clang |
+| OpenBSD | amd64 | GCC, Clang |
+| macOS{sup}`2` | PowerPC | GCC |
+| macOS | x86 | GCC, Clang |
+| macOS | arm64 | Clang |
+| Cygwin/Win32 | x86{sup}`1, 3` | GCC |
+| Windows | x86{sup}`1` | Visual Studio |
+| Windows x64 | x86-64 | Visual Studio, Clang{sup}`4` |
+| Windows on Arm | ARM64 | Visual Studio, Clang{sup}`4` |
+
+```{note}
+1. Code generation supported for Pentium processors and up
+1. Code generation supported for 32-bit ABI only
+1. To use LLVM modules on a Win32-based system, you may configure LLVM
+ with `-DBUILD_SHARED_LIBS=On`.
+1. Visual Studio alone can compile LLVM. When using Clang, you
+ must also have Visual Studio installed.
+```
Note that Debug builds require a lot of time and disk space. An LLVM-only build
will need about 1-3 GB of space. A full build of LLVM and Clang will need around
15-20 GB of disk space. The exact space requirements will vary by system. (It
@@ -287,8 +269,7 @@ assemble, disassemble, analyze, and optimize LLVM bitcode. Code generation
should work as well, although the generated native code may not work on your
platform.
-Software
---------
+### Software
Compiling LLVM requires that you have several software packages installed. The
table below lists those required packages. The Package column is the usual name
@@ -296,26 +277,23 @@ for the software package that LLVM depends on. The Version column provides
"known to work" versions of the package. The Notes column describes how LLVM
uses the package and provides other details.
-=========================================================== ============ ==========================================
-Package Version Notes
-=========================================================== ============ ==========================================
-`CMake <http://cmake.org/>`_ >=3.20.0 Makefile/workspace generator
-`python <http://www.python.org/>`_ >=3.8 Automated test suite\ :sup:`1`
-`zlib <http://zlib.net>`_ >=1.2.3.4 Compression library\ :sup:`2`
-`GNU Make <http://savannah.gnu.org/projects/make>`_ 3.79, 3.79.1 Makefile/build processor\ :sup:`3`
-`PyYAML <https://pypi.org/project/PyYAML/>`_ >=5.1 Header generator\ :sup:`4`
-=========================================================== ============ ==========================================
-
-.. note::
-
- #. Only needed if you want to run the automated test suite in the
- ``llvm/test`` directory, or if you plan to utilize any Python libraries,
- utilities, or bindings.
- #. Optional, adds compression/uncompression capabilities to selected LLVM
- tools.
- #. Optional, you can use any other build tool supported by CMake.
- #. Only needed when building libc with New Headergen. Mainly used by libc.
-
+| Package | Version | Notes |
+| --- | --- | --- |
+| [CMake](http://cmake.org/) | >=3.20.0 | Makefile/workspace generator |
+| [python](http://www.python.org/) | >=3.8 | Automated test suite{sup}`1` |
+| [zlib](http://zlib.net) | >=1.2.3.4 | Compression library{sup}`2` |
+| [GNU Make](http://savannah.gnu.org/projects/make) | 3.79, 3.79.1 | Makefile/build processor{sup}`3` |
+| [PyYAML](https://pypi.org/project/PyYAML/) | >=5.1 | Header generator{sup}`4` |
+
+```{note}
+1. Only needed if you want to run the automated test suite in the
+ `llvm/test` directory, or if you plan to utilize any Python libraries,
+ utilities, or bindings.
+1. Optional, adds compression/uncompression capabilities to selected LLVM
+ tools.
+1. Optional, you can use any other build tool supported by CMake.
+1. Only needed when building libc with New Headergen. Mainly used by libc.
+```
Additionally, your compilation host is expected to have the usual plethora of
Unix utilities. Specifically:
@@ -344,20 +322,17 @@ Unix utilities. Specifically:
* **unzip** --- unzip command for distribution checking
* **zip** --- zip command for distribution generation
-.. _below:
-.. _check here:
-
-.. _host_cpp_toolchain:
-
-Host C++ Toolchain, both Compiler and Standard Library
-------------------------------------------------------
+(below)=
+(check here)=
+(host_cpp_toolchain)=
+### Host C++ Toolchain, both Compiler and Standard Library
LLVM is very demanding of the host C++ compiler, and as such tends to expose
bugs in the compiler. We also attempt to follow improvements and developments in
the C++ language and library reasonably closely. As such, we require a modern
host C++ toolchain, both compiler and standard library, in order to build LLVM.
-LLVM is written using the subset of C++ documented in :doc:`coding
+LLVM is written using the subset of C++ documented in {doc}`coding
standards<CodingStandards>`. To enforce this language version, we check the most
popular host toolchains for specific minimum versions in our build systems:
@@ -378,23 +353,23 @@ We track certain versions of software that are *known* to fail when used as
part of the host toolchain. These even include linkers at times.
**GNU ld 2.16.X**. Some 2.16.X versions of the ld linker will produce very long
-warning messages complaining that some "``.gnu.linkonce.t.*``" symbol was
+warning messages complaining that some "`.gnu.linkonce.t.*`" symbol was
defined in a discarded section. You can safely ignore these messages as they are
erroneous and the linkage is correct. These messages disappear using ld 2.17.
-**GNU binutils 2.17**: Binutils 2.17 contains `a bug
-<http://sourceware.org/bugzilla/show_bug.cgi?id=3111>`__ which causes huge link
+**GNU binutils 2.17**: Binutils 2.17 contains [a bug] which causes huge link
times (minutes instead of seconds) when building LLVM. We recommend upgrading
to a newer version (2.17.50.0.4 or later).
-**GNU Binutils 2.19.1 Gold**: This version of Gold contained `a bug
-<http://sourceware.org/bugzilla/show_bug.cgi?id=9836>`__ which causes
+**GNU Binutils 2.19.1 Gold**: This version of Gold contained [a bug][gold-bug] which causes
intermittent failures when building LLVM with position independent code. The
symptom is an error about cyclic dependencies. We recommend upgrading to a
newer version of Gold.
-Getting a Modern Host C++ Toolchain
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+[a bug]: http://sourceware.org/bugzilla/show_bug.cgi?id=3111
+[gold-bug]: http://sourceware.org/bugzilla/show_bug.cgi?id=9836
+
+#### Getting a Modern Host C++ Toolchain
This section mostly applies to Linux and older BSDs. On macOS, you should
have a sufficiently modern Xcode, or you will likely need to upgrade until you
@@ -415,98 +390,89 @@ initial host in a bootstrap, and then using Clang (and potentially libc++).
The first step is to get a recent GCC toolchain installed. The most common
distribution on which users have struggled with the version requirements is
Ubuntu Precise, 12.04 LTS. For this distribution, one easy option is to install
-the `toolchain testing PPA`_ and use it to install a modern GCC. There is
-a really nice discussion of this on the `ask ubuntu stack exchange`_ and a
-`github gist`_ with updated commands. However, not all users can use PPAs and
+the [toolchain testing PPA] and use it to install a modern GCC. There is
+a really nice discussion of this on the [ask ubuntu stack exchange] and a
+[github gist] with updated commands. However, not all users can use PPAs and
there are many other distributions, so it may be necessary (or just useful, if
you're here you *are* doing compiler development after all) to build and install
GCC from source. It is also quite easy to do these days.
-.. _toolchain testing PPA:
- https://launchpad.net/~ubuntu-toolchain-r/+archive/test
-.. _ask ubuntu stack exchange:
- https://askubuntu.com/questions/466651/how-do-i-use-the-latest-gcc-on-ubuntu/581497#58149
-.. _github gist:
- https://gist.github.com/application2000/73fd6f4bf1be6600a2cf9f56315a2d91
+[toolchain testing PPA]: https://launchpad.net/~ubuntu-toolchain-r/+archive/test
+[ask ubuntu stack exchange]: https://askubuntu.com/questions/466651/how-do-i-use-the-latest-gcc-on-ubuntu/581497#58149
+[github gist]: https://gist.github.com/application2000/73fd6f4bf1be6600a2cf9f56315a2d91
Easy steps for installing a specific version of GCC:
-.. code-block:: console
-
- % gcc_version=7.4.0
- % wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2
- % wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2.sig
- % wget https://ftp.gnu.org/gnu/gnu-keyring.gpg
- % signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-${gcc_version}.tar.bz2.sig`
- % if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi
- % tar -xvjf gcc-${gcc_version}.tar.bz2
- % cd gcc-${gcc_version}
- % ./contrib/download_prerequisites
- % cd ..
- % mkdir gcc-${gcc_version}-build
- % cd gcc-${gcc_version}-build
- % $PWD/../gcc-${gcc_version}/configure --prefix=$HOME/toolchains --enable-languages=c,c++
- % make -j$(nproc)
- % make install
-
-For more details, check out the excellent `GCC wiki entry`_, where I got most
+```console
+% gcc_version=7.4.0
+% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2
+% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2.sig
+% wget https://ftp.gnu.org/gnu/gnu-keyring.gpg
+% signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-${gcc_version}.tar.bz2.sig`
+% if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi
+% tar -xvjf gcc-${gcc_version}.tar.bz2
+% cd gcc-${gcc_version}
+% ./contrib/download_prerequisites
+% cd ..
+% mkdir gcc-${gcc_version}-build
+% cd gcc-${gcc_version}-build
+% $PWD/../gcc-${gcc_version}/configure --prefix=$HOME/toolchains --enable-languages=c,c++
+% make -j$(nproc)
+% make install
+```
+For more details, check out the excellent [GCC wiki entry], where I got most
of this information from.
-.. _GCC wiki entry:
- https://gcc.gnu.org/wiki/InstallingGCC
+[GCC wiki entry]: https://gcc.gnu.org/wiki/InstallingGCC
Once you have a GCC toolchain, configure your build of LLVM to use the new
toolchain for your host compiler and C++ standard library. Because the new
version of libstdc++ is not on the system library search path, you need to pass
-extra linker flags so that it can be found at link time (``-L``) and at runtime
-(``-rpath``). If you are using CMake, this invocation should produce working
+extra linker flags so that it can be found at link time (`-L`) and at runtime
+(`-rpath`). If you are using CMake, this invocation should produce working
binaries:
-.. code-block:: console
-
- % mkdir build
- % cd build
- % CC=$HOME/toolchains/bin/gcc CXX=$HOME/toolchains/bin/g++ \
- cmake .. -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,$HOME/toolchains/lib64 -L$HOME/toolchains/lib64"
-
+```console
+% mkdir build
+% cd build
+% CC=$HOME/toolchains/bin/gcc CXX=$HOME/toolchains/bin/g++ \
+ cmake .. -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,$HOME/toolchains/lib64 -L$HOME/toolchains/lib64"
+```
If you fail to set rpath, most LLVM binaries will fail on startup with a message
from the loader similar to ``libstdc++.so.6: version `GLIBCXX_3.4.20' not
-found``. This means you need to tweak the ``-rpath`` linker flag.
+found``. This means you need to tweak the `-rpath` linker flag.
This method will add an absolute path to the rpath of all executables. That's
fine for local development. If you want to distribute the binaries you build
-so that they can run on older systems, copy ``libstdc++.so.6`` into the
-``lib/`` directory. All of LLVM's shipping binaries have an rpath pointing at
-``$ORIGIN/../lib``, so they will find ``libstdc++.so.6`` there. Non-distributed
-binaries don't have an rpath set and won't find ``libstdc++.so.6``. Pass
-``-DLLVM_LOCAL_RPATH="$HOME/toolchains/lib64"`` to CMake to add an absolute
-path to ``libstdc++.so.6`` as above. Since these binaries are not distributed,
+so that they can run on older systems, copy `libstdc++.so.6` into the
+`lib/` directory. All of LLVM's shipping binaries have an rpath pointing at
+`$ORIGIN/../lib`, so they will find `libstdc++.so.6` there. Non-distributed
+binaries don't have an rpath set and won't find `libstdc++.so.6`. Pass
+`-DLLVM_LOCAL_RPATH="$HOME/toolchains/lib64"` to CMake to add an absolute
+path to `libstdc++.so.6` as above. Since these binaries are not distributed,
having an absolute local path is fine for them.
When you build Clang, you will need to give *it* access to a modern C++
standard library in order to use it as your new host in part of a bootstrap.
There are two easy ways to do this, either build (and install) libc++ along
-with Clang and then use it with the ``-stdlib=libc++`` compile and link flag,
-or install Clang into the same prefix (``$HOME/toolchains`` above) as GCC.
+with Clang and then use it with the `-stdlib=libc++` compile and link flag,
+or install Clang into the same prefix (`$HOME/toolchains` above) as GCC.
Clang will look within its own prefix for libstdc++ and use it if found. You
can also add an explicit prefix for Clang to look in for a GCC toolchain with
-the ``--gcc-toolchain=/opt/my/gcc/prefix`` flag, passing it to both compile and
+the `--gcc-toolchain=/opt/my/gcc/prefix` flag, passing it to both compile and
link commands when using your just-built-Clang to bootstrap.
-.. _Getting Started with LLVM:
-
-Getting Started with LLVM
-=========================
+(Getting Started with LLVM)=
+## Getting Started with LLVM
The remainder of this guide is meant to get you up and running with LLVM and to
give you some basic information about the LLVM environment.
-The later sections of this guide describe the `general layout`_ of the LLVM
-source tree, a `simple example`_ using the LLVM toolchain, and `links`_ to find
+The later sections of this guide describe the {ref}`general layout <general layout>` of the LLVM
+source tree, a {ref}`simple example <simple example>` using the LLVM toolchain, and {ref}`links <links>` to find
more information about LLVM or to get help via e-mail.
-Terminology and Notation
-------------------------
+### Terminology and Notation
Throughout this manual, the following names are used to denote paths specific to
the local system and working environment. *These are not environment variables
@@ -514,157 +480,146 @@ you need to set but just strings used in the rest of this document below*. In
any of the examples below, simply replace each of these names with the
appropriate pathname on your local system. All these paths are absolute:
-``SRC_ROOT``
+* `SRC_ROOT`
This is the top-level directory of the LLVM source tree.
-``OBJ_ROOT``
+* `OBJ_ROOT`
This is the top-level directory of the LLVM object tree (i.e. the tree where
object files and compiled programs will be placed. It can be the same as
SRC_ROOT).
-Sending patches
-^^^^^^^^^^^^^^^
+#### Sending patches
-See :ref:`Contributing <submit_patch>`.
+See {ref}`Contributing <submit_patch>`.
-Bisecting commits
-^^^^^^^^^^^^^^^^^
+#### Bisecting commits
-See `Bisecting LLVM code <GitBisecting.html>`_ for how to use ``git bisect``
+See {doc}`Bisecting LLVM code <GitBisecting>` for how to use `git bisect`
on LLVM.
-Reverting a change
-^^^^^^^^^^^^^^^^^^
+#### Reverting a change
When reverting changes using git, the default message will say "This reverts
commit XYZ". Leave this at the end of the commit message, but add some details
before it as to why the commit is being reverted. A brief explanation and/or
links to bots that demonstrate the problem are sufficient.
-Local LLVM Configuration
-------------------------
+### Local LLVM Configuration
Once checked out repository, the LLVM suite source code must be configured
-before being built. This process uses CMake. Unlike the normal ``configure``
+before being built. This process uses CMake. Unlike the normal `configure`
script, CMake generates the build files in whatever format you request as well
-as various ``*.inc`` files, and ``llvm/include/llvm/Config/config.h.cmake``.
+as various `*.inc` files, and `llvm/include/llvm/Config/config.h.cmake`.
-Variables are passed to ``cmake`` on the command line using the format
-``-D<variable name>=<value>``. The following variables are some common options
+Variables are passed to `cmake` on the command line using the format
+`-D<variable name>=<value>`. The following variables are some common options
used by people developing LLVM.
-* ``CMAKE_C_COMPILER``
-* ``CMAKE_CXX_COMPILER``
-* ``CMAKE_BUILD_TYPE``
-* ``CMAKE_INSTALL_PREFIX``
-* ``Python3_EXECUTABLE``
-* ``LLVM_TARGETS_TO_BUILD``
-* ``LLVM_ENABLE_PROJECTS``
-* ``LLVM_ENABLE_RUNTIMES``
-* ``LLVM_ENABLE_DOXYGEN``
-* ``LLVM_ENABLE_SPHINX``
-* ``LLVM_BUILD_LLVM_DYLIB``
-* ``LLVM_LINK_LLVM_DYLIB``
-* ``LLVM_PARALLEL_LINK_JOBS``
-* ``LLVM_OPTIMIZED_TABLEGEN``
-
-See :ref:`the list of frequently-used CMake variables <cmake_frequently_used_variables>`
+* `CMAKE_C_COMPILER`
+* `CMAKE_CXX_COMPILER`
+* `CMAKE_BUILD_TYPE`
+* `CMAKE_INSTALL_PREFIX`
+* `Python3_EXECUTABLE`
+* `LLVM_TARGETS_TO_BUILD`
+* `LLVM_ENABLE_PROJECTS`
+* `LLVM_ENABLE_RUNTIMES`
+* `LLVM_ENABLE_DOXYGEN`
+* `LLVM_ENABLE_SPHINX`
+* `LLVM_BUILD_LLVM_DYLIB`
+* `LLVM_LINK_LLVM_DYLIB`
+* `LLVM_PARALLEL_LINK_JOBS`
+* `LLVM_OPTIMIZED_TABLEGEN`
+
+See {ref}`the list of frequently-used CMake variables <cmake_frequently_used_variables>`
for more information.
To configure LLVM, follow these steps:
-#. Change directory into the object root directory:
-
- .. code-block:: console
-
- % cd OBJ_ROOT
+1. Change directory into the object root directory:
-#. Run the ``cmake``:
+ ```console
+ % cd OBJ_ROOT
+ ```
+1. Run the `cmake`:
- .. code-block:: console
-
- % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=<type> -DCMAKE_INSTALL_PREFIX=/install/path
- [other options] SRC_ROOT
-
-Compiling the LLVM Suite Source Code
-------------------------------------
+ ```console
+ % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=<type> -DCMAKE_INSTALL_PREFIX=/install/path
+ [other options] SRC_ROOT
+ ```
+### Compiling the LLVM Suite Source Code
Unlike with autotools, with CMake your build type is defined at configuration.
If you want to change your build type, you can re-run CMake with the following
invocation:
- .. code-block:: console
-
- % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=<type> SRC_ROOT
-
+ ```console
+ % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=<type> SRC_ROOT
+ ```
Between runs, CMake preserves the values set for all options. CMake has the
following build types defined:
-Debug
+* Debug
These builds are the default. The build system will compile the tools and
libraries unoptimized, with debugging information, and asserts enabled.
-Release
+* Release
For these builds, the build system will compile the tools and libraries
with optimizations enabled and not generate debug info. CMakes default
optimization level is -O3. This can be configured by setting the
- ``CMAKE_CXX_FLAGS_RELEASE`` variable on the CMake command line.
+ `CMAKE_CXX_FLAGS_RELEASE` variable on the CMake command line.
-RelWithDebInfo
+* RelWithDebInfo
These builds are useful when debugging. They generate optimized binaries with
debug information. CMakes default optimization level is -O2. This can be
- configured by setting the ``CMAKE_CXX_FLAGS_RELWITHDEBINFO`` variable on the
+ configured by setting the `CMAKE_CXX_FLAGS_RELWITHDEBINFO` variable on the
CMake command line.
Once you have LLVM configured, you can build it by entering the *OBJ_ROOT*
directory and issuing the following command:
-.. code-block:: console
-
- % make
-
-If the build fails, please `check here`_ to see if you are using a version of
+```console
+% make
+```
+If the build fails, please {ref}`check here <check here>` to see if you are using a version of
GCC that is known not to compile LLVM.
If you have multiple processors in your machine, you may wish to use some of the
parallel build options provided by GNU Make. For example, you could use the
command:
-.. code-block:: console
-
- % make -j2
-
+```console
+% make -j2
+```
There are several special targets which are useful when working with the LLVM
source code:
-``make clean``
+* `make clean`
Removes all files generated by the build. This includes object files,
generated C/C++ files, libraries, and executables.
-``make install``
+* `make install`
Installs LLVM header files, libraries, tools, and documentation in a hierarchy
- under ``$PREFIX``, specified with ``CMAKE_INSTALL_PREFIX``, which
- defaults to ``/usr/local``.
+ under `$PREFIX`, specified with `CMAKE_INSTALL_PREFIX`, which
+ defaults to `/usr/local`.
-``make docs-llvm-html``
+* `make docs-llvm-html`
- If configured with ``-DLLVM_ENABLE_SPHINX=On``, this will generate a directory
- at ``OBJ_ROOT/docs/html`` which contains the HTML formatted documentation.
+ If configured with `-DLLVM_ENABLE_SPHINX=On`, this will generate a directory
+ at `OBJ_ROOT/docs/html` which contains the HTML formatted documentation.
-Cross-Compiling LLVM
---------------------
+### Cross-Compiling LLVM
It is possible to cross-compile LLVM itself. That is, you can create LLVM
executables and libraries to be hosted on a platform different from the platform
where they are built (a Canadian Cross build). To generate build files for
-cross-compiling CMake provides a variable ``CMAKE_TOOLCHAIN_FILE`` which can
+cross-compiling CMake provides a variable `CMAKE_TOOLCHAIN_FILE` which can
define compiler flags and variables used during the CMake test operations.
The result of such a build is executables that are not runnable on the build
@@ -672,23 +627,22 @@ host but can be executed on the target. As an example, the following CMake
invocation can generate build files targeting iOS. This will work on macOS
with the latest Xcode:
-.. code-block:: console
-
- % cmake -G "Ninja" -DCMAKE_OSX_ARCHITECTURES="armv7;armv7s;arm64"
- -DCMAKE_TOOLCHAIN_FILE=<PATH_TO_LLVM>/cmake/platforms/iOS.cmake
- -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_RUNTIME=Off -DLLVM_INCLUDE_TESTS=Off
- -DLLVM_INCLUDE_EXAMPLES=Off -DLLVM_ENABLE_BACKTRACES=Off [options]
- <PATH_TO_LLVM>
-
+```console
+% cmake -G "Ninja" -DCMAKE_OSX_ARCHITECTURES="armv7;armv7s;arm64"
+ -DCMAKE_TOOLCHAIN_FILE=<PATH_TO_LLVM>/cmake/platforms/iOS.cmake
+ -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_RUNTIME=Off -DLLVM_INCLUDE_TESTS=Off
+ -DLLVM_INCLUDE_EXAMPLES=Off -DLLVM_ENABLE_BACKTRACES=Off [options]
+ <PATH_TO_LLVM>
+```
Note: There are some additional flags that need to be passed when building for
iOS due to limitations in the iOS SDK.
-Check :doc:`HowToCrossCompileLLVM` and `Clang docs on how to cross-compile in general
-<https://clang.llvm.org/docs/CrossCompilation.html>`_ for more information
-about cross-compiling.
+Check {doc}`HowToCrossCompileLLVM` and [Clang docs on how to cross-compile in general]
+for more information about cross-compiling.
+
+[Clang docs on how to cross-compile in general]: https://clang.llvm.org/docs/CrossCompilation.html
-The Location of LLVM Object Files
----------------------------------
+### The Location of LLVM Object Files
The LLVM build system is capable of sharing a single LLVM source tree among
several LLVM builds. Hence, it is possible to build LLVM for several different
@@ -696,78 +650,73 @@ platforms or configurations using the same source tree.
* Change directory to where the LLVM object files should live:
- .. code-block:: console
-
- % cd OBJ_ROOT
-
-* Run ``cmake``:
-
- .. code-block:: console
-
- % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release SRC_ROOT
+ ```console
+ % cd OBJ_ROOT
+ ```
+* Run `cmake`:
+ ```console
+ % cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release SRC_ROOT
+ ```
The LLVM build will create a structure underneath *OBJ_ROOT* that matches the
LLVM source tree. At each level where source files are present in the source
-tree there will be a corresponding ``CMakeFiles`` directory in the *OBJ_ROOT*.
+tree there will be a corresponding `CMakeFiles` directory in the *OBJ_ROOT*.
Underneath that directory there is another directory with a name ending in
-``.dir`` under which you'll find object files for each source.
+`.dir` under which you'll find object files for each source.
For example:
- .. code-block:: console
-
- % cd llvm_build_dir
- % find lib/Support/ -name APFloat*
- lib/Support/CMakeFiles/LLVMSupport.dir/APFloat.cpp.o
-
-Optional Configuration Items
-----------------------------
+ ```console
+ % cd llvm_build_dir
+ % find lib/Support/ -name APFloat*
+ lib/Support/CMakeFiles/LLVMSupport.dir/APFloat.cpp.o
+ ```
+### Optional Configuration Items
-If you're running on a Linux system that supports the `binfmt_misc
-<http://en.wikipedia.org/wiki/binfmt_misc>`_
+If you're running on a Linux system that supports the [binfmt_misc]
module, and you have root access on the system, you can set your system up to
execute LLVM bitcode files directly. To do this, use commands like this (the
first command may not be required if you are already using the module):
-.. code-block:: console
-
- % mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
- % echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
- % chmod u+x hello.bc (if needed)
- % ./hello.bc
+[binfmt_misc]: http://en.wikipedia.org/wiki/binfmt_misc
+```console
+% mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
+% echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
+% chmod u+x hello.bc (if needed)
+% ./hello.bc
+```
This allows you to execute LLVM bitcode files directly. On Debian, you can also
use this command instead of the 'echo' command above:
-.. code-block:: console
-
- % sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
+```console
+% sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
+```
+(Program Layout)=
+(general layout)=
+## Directory Layout
-.. _Program Layout:
-.. _general layout:
+One useful source of information about the LLVM source base is the LLVM [doxygen]
+documentation available at <https://llvm.org/doxygen/>. The following is a
+brief introduction to code layout:
-Directory Layout
-================
+[doxygen]: http://www.doxygen.org/
-One useful source of information about the LLVM source base is the LLVM `doxygen
-<http://www.doxygen.org/>`_ documentation available at
-`<https://llvm.org/doxygen/>`_. The following is a brief introduction to code
-layout:
+### `llvm/cmake`
-``llvm/cmake``
---------------
Generates system build files.
-``llvm/cmake/modules``
+* `llvm/cmake/modules`
+
Build configuration for llvm user defined options. Checks compiler version and
linker flags.
-``llvm/cmake/platforms``
+* `llvm/cmake/platforms`
+
Toolchain configuration for Android NDK, iOS systems and non-Windows hosts to
target MSVC.
-``llvm/examples``
------------------
+### `llvm/examples`
- Some simple examples showing how to use LLVM as a compiler for a custom
language - including lowering, optimization, and code generation.
@@ -777,416 +726,390 @@ Generates system build files.
including a hand-written lexer, parser, AST, as well as code generation
support using LLVM- both static (ahead of time) and various approaches to
Just In Time (JIT) compilation.
- `Kaleidoscope Tutorial for complete beginner
- <https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index.html>`_.
+ [Kaleidoscope Tutorial for complete beginner](https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index.html).
-- BuildingAJIT: Examples of the `BuildingAJIT tutorial
- <https://llvm.org/docs/tutorial/BuildingAJIT1.html>`_ that shows how LLVM’s
+- BuildingAJIT: Examples of the [BuildingAJIT tutorial] that shows how LLVM’s
ORC JIT APIs interact with other parts of LLVM. It also teaches how to
recombine them to build a custom JIT that is suited to your use-case.
-``llvm/include``
-----------------
+[BuildingAJIT tutorial]: https://llvm.org/docs/tutorial/BuildingAJIT1.html
+
+### `llvm/include`
Public header files exported from the LLVM library. The three main subdirectories:
-``llvm/include/llvm``
+* `llvm/include/llvm`
All LLVM-specific header files, and subdirectories for different portions of
- LLVM: ``Analysis``, ``CodeGen``, ``Target``, ``Transforms``, etc...
+ LLVM: `Analysis`, `CodeGen`, `Target`, `Transforms`, etc...
-``llvm/include/llvm/Support``
+* `llvm/include/llvm/Support`
Generic support libraries provided with LLVM but not necessarily specific to
LLVM. For example, some C++ STL utilities and a Command Line option processing
library store header files here.
-``llvm/include/llvm/Config``
+* `llvm/include/llvm/Config`
- Header files configured by ``cmake``. They wrap "standard" UNIX and
+ Header files configured by `cmake`. They wrap "standard" UNIX and
C header files. Source code can include these header files which
- automatically take care of the conditional #includes that ``cmake``
+ automatically take care of the conditional #includes that `cmake`
generates.
-``llvm/lib``
-------------
+### `llvm/lib`
Most source files are here. By putting code in libraries, LLVM makes it easy to
-share code among the `tools`_.
+share code among the [tools](#tools).
-``llvm/lib/IR/``
+* `llvm/lib/IR/`
Core LLVM source files that implement core classes like Instruction and
BasicBlock.
-``llvm/lib/AsmParser/``
+* `llvm/lib/AsmParser/`
Source code for the LLVM assembly language parser library.
-``llvm/lib/Bitcode/``
+* `llvm/lib/Bitcode/`
Code for reading and writing bitcode.
-``llvm/lib/Analysis/``
+* `llvm/lib/Analysis/`
A variety of program analyses, such as Call Graphs, Induction Variables,
Natural Loop Identification, etc.
-``llvm/lib/Transforms/``
+* `llvm/lib/Transforms/`
IR-to-IR program transformations, such as Aggressive Dead Code Elimination,
Sparse Conditional Constant Propagation, Inlining, Loop Invariant Code Motion,
Dead Global Elimination, and many others.
-``llvm/lib/Target/``
+* `llvm/lib/Target/`
Files describing target architectures for code generation. For example,
- ``llvm/lib/Target/X86`` holds the X86 machine description.
+ `llvm/lib/Target/X86` holds the X86 machine description.
-``llvm/lib/CodeGen/``
+* `llvm/lib/CodeGen/`
The major parts of the code generator: Instruction Selector, Instruction
Scheduling, and Register Allocation.
-``llvm/lib/MC/``
+* `llvm/lib/MC/`
The libraries represent and process code at machine code level. Handles
assembly and object-file emission.
-``llvm/lib/ExecutionEngine/``
+* `llvm/lib/ExecutionEngine/`
Libraries for directly executing bitcode at runtime in interpreted and
JIT-compiled scenarios.
-``llvm/lib/Support/``
+* `llvm/lib/Support/`
- Source code that corresponds to the header files in ``llvm/include/ADT/``
- and ``llvm/include/Support/``.
+ Source code that corresponds to the header files in `llvm/include/ADT/`
+ and `llvm/include/Support/`.
-``llvm/bindings``
-----------------------
+### `llvm/bindings`
Contains bindings for the LLVM compiler infrastructure to allow
programs written in languages other than C or C++ to take advantage of the LLVM
infrastructure.
The LLVM project provides language bindings for OCaml and Python.
-``llvm/projects``
------------------
+### `llvm/projects`
Projects not strictly part of LLVM but shipped with LLVM. This is also the
directory for creating your own LLVM-based projects which leverage the LLVM
build system.
-``llvm/test``
--------------
+### `llvm/test`
Feature and regression tests and other sanity checks on LLVM infrastructure. These
are intended to run quickly and cover a lot of territory without being exhaustive.
-``test-suite``
---------------
+### `test-suite`
A comprehensive correctness, performance, and benchmarking test suite
-for LLVM. This comes in a ``separate git repository
-<https://github.com/llvm/llvm-test-suite>``, because it contains a
+for LLVM. This comes in a [separate git repository], because it contains a
large amount of third-party code under a variety of licenses. For
-details see the :doc:`Testing Guide <TestingGuide>` document.
+details see the {doc}`Testing Guide <TestingGuide>` document.
-.. _tools:
+[separate git repository]: https://github.com/llvm/llvm-test-suite
-``llvm/tools``
---------------
+(tools)=
+### `llvm/tools`
Executables built out of the libraries
above, which form the main part of the user interface. You can always get help
-for a tool by typing ``tool_name -help``. The following is a brief introduction
+for a tool by typing `tool_name -help`. The following is a brief introduction
to the most important tools. More detailed information is in
-the `Command Guide <CommandGuide/index.html>`_.
+the {doc}`Command Guide <CommandGuide/index>`.
-``llvm-reduce``
+* `llvm-reduce`
- ``llvm-reduce`` is used to debug optimization passes or code generation backends
+ `llvm-reduce` is used to debug optimization passes or code generation backends
by narrowing down the given test case to the minimum number of passes and/or
instructions that still cause a problem, whether it is a crash or
- miscompilation. See `<HowToSubmitABug.html>`_ for more information on using
- ``llvm-reduce``.
+ miscompilation. See {doc}`HowToSubmitABug.html <HowToSubmitABug>` for more information on using
+ `llvm-reduce`.
-``llvm-ar``
+* `llvm-ar`
The archiver produces an archive containing the given LLVM bitcode files,
optionally with an index for faster lookup.
-``llvm-as``
+* `llvm-as`
The assembler transforms the human-readable LLVM assembly to LLVM bitcode.
-``llvm-dis``
+* `llvm-dis`
The disassembler transforms the LLVM bitcode to human-readable LLVM assembly.
-``llvm-link``
+* `llvm-link`
- ``llvm-link``, not surprisingly, links multiple LLVM modules into a single
+ `llvm-link`, not surprisingly, links multiple LLVM modules into a single
program.
-``lli``
+* `lli`
- ``lli`` is the LLVM interpreter, which can directly execute LLVM bitcode
+ `lli` is the LLVM interpreter, which can directly execute LLVM bitcode
(although very slowly...). For architectures that support it (currently x86,
- Sparc, and PowerPC), by default, ``lli`` will function as a Just-In-Time
+ Sparc, and PowerPC), by default, `lli` will function as a Just-In-Time
compiler (if the functionality was compiled in), and will execute the code
*much* faster than the interpreter.
-``llc``
+* `llc`
- ``llc`` is the LLVM backend compiler, which translates LLVM bitcode to a
+ `llc` is the LLVM backend compiler, which translates LLVM bitcode to a
native code assembly file.
-``opt``
+* `opt`
- ``opt`` reads LLVM bitcode, applies a series of LLVM to LLVM transformations
+ `opt` reads LLVM bitcode, applies a series of LLVM to LLVM transformations
(which are specified on the command line), and outputs the resultant
- bitcode. '``opt -help``' is a good way to get a list of the
+ bitcode. '`opt -help`' is a good way to get a list of the
program transformations available in LLVM.
- ``opt`` can also run a specific analysis on an input LLVM bitcode
+ `opt` can also run a specific analysis on an input LLVM bitcode
file and print the results. Primarily useful for debugging
analyses, or familiarizing yourself with what an analysis does.
-``llvm/utils``
---------------
+### `llvm/utils`
Utilities for working with LLVM source code; some are part of the build process
because they are code generators for parts of the infrastructure.
-``codegen-diff``
+* `codegen-diff`
- ``codegen-diff`` finds differences between code that LLC
+ `codegen-diff` finds differences between code that LLC
generates and code that LLI generates. This is useful if you are
debugging one of them, assuming that the other generates correct output. For
- the full user manual, run ```perldoc codegen-diff'``.
+ the full user manual, run `` `perldoc codegen-diff' ``.
-``emacs/``
+* `emacs/`
Emacs and XEmacs syntax highlighting for LLVM assembly files and TableGen
- description files. See the ``README`` for information on using them.
+ description files. See the `README` for information on using them.
-``getsrcs.sh``
+* `getsrcs.sh`
Finds and outputs all non-generated source files,
useful if one wishes to do a lot of development across directories
and does not want to find each file. One way to use it is to run,
- for example: ``xemacs `utils/getsources.sh``` from the top of the LLVM source
+ for example: ``xemacs `utils/getsources.sh` `` from the top of the LLVM source
tree.
-``llvmgrep``
+* `llvmgrep`
- Performs an ``egrep -H -n`` on each source file in LLVM and
- passes to it a regular expression provided on ``llvmgrep``'s command
+ Performs an `egrep -H -n` on each source file in LLVM and
+ passes to it a regular expression provided on `llvmgrep`'s command
line. This is an efficient way of searching the source base for a
particular regular expression.
-``TableGen/``
+* `TableGen/`
Contains the tool used to generate register
descriptions, instruction set descriptions, and even assemblers from common
TableGen description files.
-``vim/``
+* `vim/`
vim syntax-highlighting for LLVM assembly files
- and TableGen description files. See the ``README`` for how to use them.
+ and TableGen description files. See the `README` for how to use them.
-.. _simple example:
-
-An Example Using the LLVM Tool Chain
-====================================
+(simple example)=
+## An Example Using the LLVM Tool Chain
This section gives an example of using LLVM with the Clang front end.
-Example with clang
-------------------
-
-#. First, create a simple C file, name it 'hello.c':
-
- .. code-block:: c
-
- #include <stdio.h>
-
- int main() {
- printf("hello world\n");
- return 0;
- }
-
-#. Next, compile the C file into a native executable:
-
- .. code-block:: console
-
- % clang hello.c -o hello
-
- .. note::
-
- Clang works just like GCC by default. The standard ``-S`` and ``-c`` arguments
- work as usual (producing a native ``.s`` or ``.o`` file, respectively).
-
-#. Next, compile the C file into an LLVM bitcode file:
-
- .. code-block:: console
-
- % clang -O3 -emit-llvm hello.c -c -o hello.bc
-
- The ``-emit-llvm`` option can be used with the ``-S`` or ``-c`` options to emit an LLVM
- ``.ll`` or ``.bc`` file (respectively) for the code. This allows you to use
- the `standard LLVM tools <CommandGuide/index.html>`_ on the bitcode file.
-
-#. Run the program in both forms. To run the program, use:
-
- .. code-block:: console
-
- % ./hello
-
+### Example with clang
+
+1. First, create a simple C file, name it 'hello.c':
+
+ ```c
+ #include <stdio.h>
+
+ int main() {
+ printf("hello world\n");
+ return 0;
+ }
+ ```
+1. Next, compile the C file into a native executable:
+
+ ```console
+ % clang hello.c -o hello
+ ```
+ ```{note}
+ Clang works just like GCC by default. The standard `-S` and `-c` arguments
+ work as usual (producing a native `.s` or `.o` file, respectively).
+ ```
+1. Next, compile the C file into an LLVM bitcode file:
+
+ ```console
+ % clang -O3 -emit-llvm hello.c -c -o hello.bc
+ ```
+ The `-emit-llvm` option can be used with the `-S` or `-c` options to emit an LLVM
+ `.ll` or `.bc` file (respectively) for the code. This allows you to use
+ the {doc}`standard LLVM tools <CommandGuide/index>` on the bitcode file.
+
+1. Run the program in both forms. To run the program, use:
+
+ ```console
+ % ./hello
+ ```
and
- .. code-block:: console
-
- % lli hello.bc
-
- The second example shows how to invoke the LLVM JIT, :doc:`lli
- <CommandGuide/lli>`.
-
-#. Use the ``llvm-dis`` utility to take a look at the LLVM assembly code:
+ ```console
+ % lli hello.bc
+ ```
+ The second example shows how to invoke the LLVM JIT, {doc}`lli <CommandGuide/lli>`.
- .. code-block:: console
+1. Use the `llvm-dis` utility to take a look at the LLVM assembly code:
- % llvm-dis < hello.bc | less
+ ```console
+ % llvm-dis < hello.bc | less
+ ```
+1. Compile the program to native assembly using the LLC code generator:
-#. Compile the program to native assembly using the LLC code generator:
+ ```console
+ % llc hello.bc -o hello.s
+ ```
+1. Assemble the native assembly language file into a program:
- .. code-block:: console
+ ```console
+ % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.native # On Solaris
- % llc hello.bc -o hello.s
-
-#. Assemble the native assembly language file into a program:
-
- .. code-block:: console
-
- % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.native # On Solaris
-
- % gcc hello.s -o hello.native # On others
-
-#. Execute the native code program:
-
- .. code-block:: console
-
- % ./hello.native
+ % gcc hello.s -o hello.native # On others
+ ```
+1. Execute the native code program:
+ ```console
+ % ./hello.native
+ ```
Note that using clang to compile directly to native code (i.e. when the
- ``-emit-llvm`` option is not present) does steps 6/7/8 for you.
+ `-emit-llvm` option is not present) does steps 6/7/8 for you.
-Common Problems
-===============
+## Common Problems
If you are having problems building or using LLVM, or if you have any other
-general questions about LLVM, please consult the `Frequently Asked
-Questions <FAQ.html>`_ page.
+general questions about LLVM, please consult the {doc}`Frequently Asked Questions <FAQ>` page.
If you are having problems with limited memory and build time, please try
-building with ``ninja`` instead of ``make``. Please consider configuring the
+building with `ninja` instead of `make`. Please consider configuring the
following options with CMake:
- * ``-G Ninja``
+ * `-G Ninja`
Setting this option will allow you to build with ninja instead of make.
Building with ninja significantly improves your build time, especially with
incremental builds, and improves your memory usage.
- * ``-DLLVM_USE_LINKER``
+ * `-DLLVM_USE_LINKER`
- Setting this option to ``lld`` will significantly reduce linking time for LLVM
+ Setting this option to `lld` will significantly reduce linking time for LLVM
executables, particularly on Linux and Windows. If you are building LLVM
for the first time and lld is not available to you as a binary package, then
you may want to use the gold linker as a faster alternative to GNU ld.
- * ``-DCMAKE_BUILD_TYPE``
+ * `-DCMAKE_BUILD_TYPE`
Controls optimization level and debug information of the build. This setting
- can affect RAM and disk usage, see :ref:`CMAKE_BUILD_TYPE <cmake_build_type>`
+ can affect RAM and disk usage, see {ref}`CMAKE_BUILD_TYPE <cmake_build_type>`
for more information.
- * ``-DLLVM_ENABLE_ASSERTIONS``
+ * `-DLLVM_ENABLE_ASSERTIONS`
- This option defaults to ``ON`` for Debug builds and defaults to ``OFF`` for Release
+ This option defaults to `ON` for Debug builds and defaults to `OFF` for Release
builds. As mentioned in the previous option, using the Release build type and
enabling assertions may be a good alternative to using the Debug build type.
- * ``-DLLVM_PARALLEL_LINK_JOBS``
+ * `-DLLVM_PARALLEL_LINK_JOBS`
Set this equal to number of jobs you wish to run simultaneously. This is
- similar to the ``-j`` option used with ``make``, but only for link jobs. This option
+ similar to the `-j` option used with `make`, but only for link jobs. This option
can only be used with ninja. You may wish to use a very low number of jobs,
as this will greatly reduce the amount of memory used during the build
- process. If you have limited memory, you may wish to set this to ``1``.
+ process. If you have limited memory, you may wish to set this to `1`.
- * ``-DLLVM_TARGETS_TO_BUILD``
+ * `-DLLVM_TARGETS_TO_BUILD`
Set this equal to the target you wish to build. You may wish to set this to
- only your host architecture. For example ``X86`` if you are using an Intel or
+ only your host architecture. For example `X86` if you are using an Intel or
AMD machine. You will find a full list of targets within the
- `llvm-project/llvm/lib/Target <https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target>`_
+ [llvm-project/llvm/lib/Target](https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target)
directory.
- * ``-DLLVM_OPTIMIZED_TABLEGEN``
+ * `-DLLVM_OPTIMIZED_TABLEGEN`
- Set this to ``ON`` to generate a fully optimized TableGen compiler during your
- build, even if that build is a ``Debug`` build. This will significantly improve
+ Set this to `ON` to generate a fully optimized TableGen compiler during your
+ build, even if that build is a `Debug` build. This will significantly improve
your build time. You should not enable this if your intention is to debug the
TableGen compiler.
- * ``-DLLVM_ENABLE_PROJECTS``
+ * `-DLLVM_ENABLE_PROJECTS`
- Set this equal to the projects you wish to compile (e.g. ``clang``, ``lld``, etc.) If
+ Set this equal to the projects you wish to compile (e.g. `clang`, `lld`, etc.) If
compiling more than one project, separate the items with a semicolon. Should
you run into issues with the semicolon, try surrounding it with single quotes.
- * ``-DLLVM_ENABLE_RUNTIMES``
+ * `-DLLVM_ENABLE_RUNTIMES`
- Set this equal to the runtimes you wish to compile (e.g. ``libcxx``, ``libcxxabi``, etc.)
+ Set this equal to the runtimes you wish to compile (e.g. `libcxx`, `libcxxabi`, etc.)
If compiling more than one runtime, separate the items with a semicolon. Should
you run into issues with the semicolon, try surrounding it with single quotes.
- * ``-DCLANG_ENABLE_STATIC_ANALYZER``
+ * `-DCLANG_ENABLE_STATIC_ANALYZER`
- Set this option to ``OFF`` if you do not require the clang static analyzer. This
+ Set this option to `OFF` if you do not require the clang static analyzer. This
should improve your build time slightly.
- * ``-DLLVM_USE_SPLIT_DWARF``
+ * `-DLLVM_USE_SPLIT_DWARF`
- Consider setting this to ``ON`` if you require a debug build, as this will ease
+ Consider setting this to `ON` if you require a debug build, as this will ease
memory pressure on the linker. This will make linking much faster, as the
binaries will not contain any of the debug information. Instead, the debug
- information is in a separate DWARF object file (with the extension ``.dwo``).
+ information is in a separate DWARF object file (with the extension `.dwo`).
This only applies to host platforms using ELF, such as Linux.
- * ``-DBUILD_SHARED_LIBS``
+ * `-DBUILD_SHARED_LIBS`
- Setting this to ``ON`` will build shared libraries instead of static
+ Setting this to `ON` will build shared libraries instead of static
libraries. This will ease memory pressure on the linker. However, this should
only be used when developing llvm. See
- :ref:`BUILD_SHARED_LIBS <LLVM-related variables BUILD_SHARED_LIBS>`
+ {ref}`BUILD_SHARED_LIBS <LLVM-related variables BUILD_SHARED_LIBS>`
for more information.
-.. _links:
-
-Links
-=====
+(links)=
+## Links
This document is just an **introduction** on how to use LLVM to do some simple
things... there are many more interesting and complicated things that you can do
that aren't documented here (but we'll gladly accept a patch if you want to
write something up!). For more information about LLVM, check out:
-* `LLVM Homepage <https://llvm.org/>`_
-* `LLVM Doxygen Tree <https://llvm.org/doxygen/>`_
-* `Starting a Project that Uses LLVM <https://llvm.org/docs/Projects.html>`_
+* [LLVM Homepage](https://llvm.org/)
+* [LLVM Doxygen Tree](https://llvm.org/doxygen/)
+* {doc}`Starting a Project that Uses LLVM <Projects>`
diff --git a/llvm/docs/GettingStartedTutorials.md b/llvm/docs/GettingStartedTutorials.md
index 61253e39c34d4..2f74eed4856e2 100644
--- a/llvm/docs/GettingStartedTutorials.md
+++ b/llvm/docs/GettingStartedTutorials.md
@@ -1,47 +1,53 @@
-Getting Started/Tutorials
-=========================
+---
+myst:
+ enable_extensions:
+ - deflist
+---
+
+# Getting Started/Tutorials
For those new to the LLVM system.
-.. toctree::
- :hidden:
-
- CompilerWriterInfo
- Frontend/PerformanceTips
- GettingStarted
- GettingStartedVS
- ProgrammersManual
- DebuggingLLVM
- tutorial/index
- MyFirstTypoFix
-
-:doc:`GettingStarted`
- Discusses how to get up and running quickly with the LLVM infrastructure.
- Everything from unpacking and compilation of the distribution to execution
- of some tools.
-
-:doc:`tutorial/index`
- Tutorials about using LLVM. Includes a tutorial about making a custom
- language with LLVM.
-
-:doc:`ProgrammersManual`
- Introduction to the general layout of the LLVM sourcebase, important classes
+```{toctree}
+:hidden:
+
+CompilerWriterInfo
+Frontend/PerformanceTips
+GettingStarted
+GettingStartedVS
+ProgrammersManual
+DebuggingLLVM
+tutorial/index
+MyFirstTypoFix
+```
+
+{doc}`GettingStarted`
+: Discusses how to get up and running quickly with the LLVM infrastructure.
+ Everything from unpacking and compilation of the distribution to execution
+ of some tools.
+
+{doc}`tutorial/index`
+: Tutorials about using LLVM. Includes a tutorial about making a custom
+ language with LLVM.
+
+{doc}`ProgrammersManual`
+: Introduction to the general layout of the LLVM sourcebase, important classes
and APIs, and some tips & tricks.
-:doc:`DebuggingLLVM`
- Provides information about how to debug LLVM.
+{doc}`DebuggingLLVM`
+: Provides information about how to debug LLVM.
-:doc:`Frontend/PerformanceTips`
- A collection of tips for frontend authors on how to generate IR
- which LLVM is able to effectively optimize.
+{doc}`Frontend/PerformanceTips`
+: A collection of tips for frontend authors on how to generate IR
+ which LLVM is able to effectively optimize.
-:doc:`GettingStartedVS`
- An addendum to the main Getting Started guide for those using Visual Studio
- on Windows.
+{doc}`GettingStartedVS`
+: An addendum to the main Getting Started guide for those using Visual Studio
+ on Windows.
-:doc:`CompilerWriterInfo`
- A list of helpful links for compiler writers.
+{doc}`CompilerWriterInfo`
+: A list of helpful links for compiler writers.
-:doc:`MyFirstTypoFix`
- This tutorial will guide you through the process of making a change to
- LLVM, and contributing it back to the LLVM project.
+{doc}`MyFirstTypoFix`
+: This tutorial will guide you through the process of making a change to
+ LLVM, and contributing it back to the LLVM project.
diff --git a/llvm/docs/GitHub.md b/llvm/docs/GitHub.md
index c3a9cb8560269..2d1df8518832e 100644
--- a/llvm/docs/GitHub.md
+++ b/llvm/docs/GitHub.md
@@ -1,51 +1,50 @@
-.. _github-reviews:
+(github-reviews)=
-======================
-LLVM GitHub User Guide
-======================
+# LLVM GitHub User Guide
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction
-============
-The LLVM Project uses `GitHub <https://github.com/>`_ for
-`Source Code <https://github.com/llvm/llvm-project>`_,
-`Releases <https://github.com/llvm/llvm-project/releases>`_,
-`Issue Tracking <https://github.com/llvm/llvm-project/issues>`_., and
-`Code Reviews <https://github.com/llvm/llvm-project/pulls>`_.
+## Introduction
+
+The LLVM Project uses [GitHub](https://github.com/) for
+[Source Code](https://github.com/llvm/llvm-project),
+[Releases](https://github.com/llvm/llvm-project/releases),
+[Issue Tracking](https://github.com/llvm/llvm-project/issues)., and
+[Code Reviews](https://github.com/llvm/llvm-project/pulls).
This page describes how the LLVM Project users and developers can
participate in the project using GitHub.
-Before your first PR
-====================
+## Before your first PR
Please ensure that you have set a valid email address in your GitHub account,
-see :ref:`github-email-address`.
+see {ref}`github-email-address`.
+
+## Pull Requests
-Pull Requests
-=============
The LLVM project is using GitHub Pull Requests for Code Reviews. This document
describes the typical workflow of creating a Pull Request and getting it reviewed
and accepted. This is meant as an overview of the GitHub workflow, for complete
-documentation refer to `GitHub's documentation <https://docs.github.com/pull-requests>`_.
+documentation refer to [GitHub's documentation](https://docs.github.com/pull-requests).
-.. note::
- If you are using a Pull Request for purposes other than review
- (eg: precommit CI results, convenient web-based reverts, etc)
- add the `skip-precommit-approval <https://github.com/llvm/llvm-project/labels?q=skip-precommit-approval>`_
- label to the PR.
+```{note}
+If you are using a Pull Request for purposes other than review
+(eg: precommit CI results, convenient web-based reverts, etc)
+add the [skip-precommit-approval](https://github.com/llvm/llvm-project/labels?q=skip-precommit-approval)
+label to the PR.
+```
+
+### GitHub Tools
-GitHub Tools
-------------
You can interact with GitHub in several ways: via git command line tools,
-the web browser, `GitHub Desktop <https://desktop.github.com/>`_, or the
-`GitHub CLI <https://cli.github.com>`_. This guide will cover the git command line
+the web browser, [GitHub Desktop](https://desktop.github.com/), or the
+[GitHub CLI](https://cli.github.com). This guide will cover the git command line
tools and the GitHub CLI.
-Creating Pull Requests
-----------------------
+### Creating Pull Requests
+
Keep in mind that when creating a pull request, it should generally only contain one
self-contained commit initially.
This makes it easier for reviewers to understand the introduced changes and
@@ -54,32 +53,32 @@ for the project. If you have multiple changes you want to introduce, it's
recommended to create separate pull requests for each change.
Create a local branch per commit you want to submit and then push that branch
-to your `fork <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks>`_
+to your [fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks)
of the llvm-project and
-`create a pull request from the fork <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork>`_.
+[create a pull request from the fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork).
As GitHub uses the first line of the commit message truncated to 72 characters
as the pull request title, you may have to edit to reword or to undo this
truncation.
-Creating Pull Requests with GitHub CLI
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-With the CLI it's enough to create the branch locally and then run:
+#### Creating Pull Requests with GitHub CLI
-::
+With the CLI it's enough to create the branch locally and then run:
- gh pr create
+```console
+gh pr create
+```
When prompted select to create and use your own fork and follow
the instructions to add more information needed.
-.. note::
+```{note}
+When you let the GitHub CLI create a fork of llvm-project to
+your user, it will change the git "remotes" so that "origin" points
+to your fork and "upstream" points to the main llvm-project repository.
+```
- When you let the GitHub CLI create a fork of llvm-project to
- your user, it will change the git "remotes" so that "origin" points
- to your fork and "upstream" points to the main llvm-project repository.
+### Updating Pull Requests
-Updating Pull Requests
-----------------------
In order to update your pull request, the only thing you need to do is to push
your new commits to the branch in your fork. That will automatically update
the pull request. You can also use the Update Branch button in GitHub's Pull
@@ -88,7 +87,7 @@ Request UI, but be aware that it will create a merge commit on your branch.
When updating a pull request, you should push additional "fix up" commits to
your branch instead of force pushing. This makes it easier for GitHub to
track the context of previous review comments. Consider using the
-`built-in support for fixups <https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---fixupamendrewordltcommitgt>`_
+[built-in support for fixups](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---fixupamendrewordltcommitgt)
in git.
If you create fix up or merge commits, you must squash and merge before
@@ -100,14 +99,14 @@ fix below.
When pushing to your branch, make sure you push to the correct fork. Check your
remotes with:
-::
-
- git remote -v
+```console
+git remote -v
+```
And make sure you push to the remote that's pointing to your fork.
-Rebasing Pull Requests and Force Pushes
----------------------------------------
+### Rebasing Pull Requests and Force Pushes
+
In general, you should avoid rebasing a Pull Request and force pushing to the
branch that's the root of the Pull Request during the review. This action will
make the context of the old changes and comments harder to find and read. If
@@ -120,37 +119,37 @@ or in some dependent code.
After your PR is reviewed and accepted, you want to rebase your branch to ensure
you won't encounter merge conflicts when landing the PR.
-.. note::
- This guide assumes that the PR branch only has 1 author. If you are
- collaborating with others on a single branch, be careful how and when you push
- changes. ``--force-with-lease`` may be useful in this situation.
+```{note}
+This guide assumes that the PR branch only has 1 author. If you are
+collaborating with others on a single branch, be careful how and when you push
+changes. `--force-with-lease` may be useful in this situation.
+```
-Approvals
----------
+### Approvals
Before merging a PR you must have the required approvals. See
-:ref:`lgtm_how_a_patch_is_accepted` for more details.
+{ref}`lgtm_how_a_patch_is_accepted` for more details.
-Landing your change
--------------------
+### Landing your change
After your PR is approved, ensure that:
* The PR title and description describe the final changes. These will be used
as the title and message of the final squashed commit. The titles and
messages of commits in the PR will **not** be used.
- * You have set a valid email address in your GitHub account, see :ref:`github-email-address`.
+ * You have set a valid email address in your GitHub account, see {ref}`github-email-address`.
-.. note::
- The LLVM Project monorepo on GitHub is configured to always use "Squash
- and Merge" as the pull request merge option when using the web interface.
- With this option, GitHub uses the PR summary as the default commit
- message.
+```{note}
+The LLVM Project monorepo on GitHub is configured to always use "Squash
+and Merge" as the pull request merge option when using the web interface.
+With this option, GitHub uses the PR summary as the default commit
+message.
- Users with write access who can merge PRs have a final opportunity to edit
- the commit title and message before merging. However, this option is not
- available to contributors without write access.
+Users with write access who can merge PRs have a final opportunity to edit
+the commit title and message before merging. However, this option is not
+available to contributors without write access.
+```
At this point, you can merge your changes. If you do not have write permissions
for the repository, the merge button in GitHub's web interface will be
@@ -170,7 +169,7 @@ commonly used first:
Afterwards you can select the option `Delete branch` to delete the branch
from your fork.
-* `Interactive rebase <https://git-scm.com/docs/git-rebase#_interactive_mode>`_
+* [Interactive rebase](https://git-scm.com/docs/git-rebase#_interactive_mode)
with fixups. This is the recommended method since you can control the final
commit message and check that the final commit looks as you expect. When
your local state is correct, remember to force-push to your branch and press
@@ -179,9 +178,9 @@ commonly used first:
* Merge using the GitHub command line interface. Switch to your branch locally
and run:
- ::
-
- gh pr merge --squash --delete-branch
+ ```console
+ gh pr merge --squash --delete-branch
+ ```
If you observe an error message from the above informing you that your pull
request is not mergeable, then that is likely because upstream has been
@@ -189,26 +188,26 @@ commonly used first:
merge conflict. You must first resolve this merge conflict in order to merge
your pull request. In order to do that:
- ::
-
- git fetch upstream
- git rebase upstream/main
+ ```console
+ git fetch upstream
+ git rebase upstream/main
+ ```
Then fix the source files causing merge conflicts and make sure to rebuild and
retest the result. Then:
- ::
-
- git add <files with resolved merge conflicts>
- git rebase --continue
+ ```console
+ git add <files with resolved merge conflicts>
+ git rebase --continue
+ ```
Finally, you'll need to force push to your branch one more time before you can
merge:
- ::
-
- git push --force
- gh pr merge --squash --delete-branch
+ ```console
+ git push --force
+ gh pr merge --squash --delete-branch
+ ```
This force push may ask if you intend to push hundreds, or potentially
thousands of patches (depending on how long it's been since your pull request
@@ -217,10 +216,9 @@ commonly used first:
request will understand that you're rebasing just your patches, and display
this result correctly with a note that a force push did occur.
-.. _github_branches:
+(github_branches)=
-Branches
-========
+## Branches
It is possible to create branches in `llvm/llvm-project/` that start with
`users/<username>/`, however this is intended to be able to support "stacked"
@@ -228,31 +226,31 @@ pull-request. Do not create any branches in the `llvm/llvm-project` repository
otherwise, please use a fork (see above). User branches that aren't
associated with a pull-request **will be deleted**.
-.. _stacked_pull_requests:
+(stacked_pull_requests)=
-Stacked Pull Requests
-=====================
+## Stacked Pull Requests
To separate related changes or to break down a larger PR into smaller, reviewable
pieces, use "stacked pull requests" — this helps make the review process
smoother.
-.. note::
- The LLVM Project monorepo on GitHub is configured to always use "Squash and
- Merge" as the pull request merge option. As a result, each PR results in
- exactly one commit being merged into the project.
+```{note}
+The LLVM Project monorepo on GitHub is configured to always use "Squash and
+Merge" as the pull request merge option. As a result, each PR results in
+exactly one commit being merged into the project.
- This means that stacked pull requests are the only available option for
- landing a series of related changes. In contrast, submitting a PR with
- multiple commits and merging them as-is (without squashing) is not supported
- in LLVM.
+This means that stacked pull requests are the only available option for
+landing a series of related changes. In contrast, submitting a PR with
+multiple commits and merging them as-is (without squashing) is not supported
+in LLVM.
+```
While GitHub does not natively support stacked pull requests, there are several
common alternatives.
To illustrate, assume that you are working on two branches in your fork of the
-``llvm/llvm-project`` repository, and you want to eventually merge both into
-``main``:
+`llvm/llvm-project` repository, and you want to eventually merge both into
+`main`:
- `feature_1`, which contains commit `feature_commit_1`
- `feature_2`, which contains commit `feature_commit_2` and depends on
@@ -260,10 +258,10 @@ To illustrate, assume that you are working on two branches in your fork of the
Your options are as follows:
-#. Use user branches in ``llvm/llvm-project``
+1. Use user branches in `llvm/llvm-project`
Create user branches in the main repository, as described
- :ref:`above<github_branches>`. Then:
+ {ref}`above <github_branches>`. Then:
- Open a pull request from `users/<username>/feature_1` → `main`
- Open another from `users/<username>/feature_2` → `users/<username>/feature_1`
@@ -275,9 +273,9 @@ Your options are as follows:
perform this step using the web interface.
This approach requires commit access. See how to obtain it
- `here <https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access>`_.
+ [here](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access).
-#. Two PRs with a dependency note
+2. Two PRs with a dependency note
Create PR_1 for `feature_1` and PR_2 for `feature_2`. In PR_2, include a
note in the PR summary indicating that it depends on PR_1 (e.g.,
@@ -287,44 +285,43 @@ Your options are as follows:
and which are new, e.g. "The first N commits are from the base PR". This
helps reviewers focus only on the incremental changes.
-#. Use a stacked PR tool
+3. Use a stacked PR tool
Use tools like SPR or Graphite (described below) to automate managing
stacked PRs. These tools are also based on using user branches
- in ``llvm/llvm-project``.
+ in `llvm/llvm-project`.
-.. note::
- When not using user branches, GitHub will not display proper diffs for
- subsequent PRs in a stack. Instead, it will show a combined diff that
- includes all commits from earlier PRs.
+```{note}
+When not using user branches, GitHub will not display proper diffs for
+subsequent PRs in a stack. Instead, it will show a combined diff that
+includes all commits from earlier PRs.
- As described above, it is the PR author’s responsibility to clearly indicate
- which commits are relevant to the current PR.
- For example: “The first N commits are from the base PR.”
+As described above, it is the PR author’s responsibility to clearly indicate
+which commits are relevant to the current PR.
+For example: “The first N commits are from the base PR.”
- You can avoid this issue by using user branches directly in the
- ``llvm/llvm-project`` repository.
+You can avoid this issue by using user branches directly in the
+`llvm/llvm-project` repository.
+```
-Using Graphite for stacked Pull Requests
-----------------------------------------
+### Using Graphite for stacked Pull Requests
-`Graphite <https://app.graphite.dev/>`_ is a stacked pull request tool supported
-by the LLVM repo (the other being `reviewable.io <https://reviewable.io>`_).
+[Graphite](https://app.graphite.dev/) is a stacked pull request tool supported
+by the LLVM repo (the other being [reviewable.io](https://reviewable.io)).
-Graphite will want to create branches under ``llvm/llvm-project`` rather than your
+Graphite will want to create branches under `llvm/llvm-project` rather than your
private fork, so the guidance above, about branch naming, is critical, otherwise
-``gt submit`` (i.e. publish your PRs for review) will fail.
+`gt submit` (i.e. publish your PRs for review) will fail.
-Use ``gt config`` then ``Branch naming settings`` and ``Set a prefix for branch names``.
-Include the last ``/``.
+Use `gt config` then `Branch naming settings` and `Set a prefix for branch names`.
+Include the last `/`.
If you didn't do the above and Graphite created non-prefixed branches, a simple way to
-unblock is to rename (``git -m <old name> <new name>``), and then checkout the branch
-and ``gt track``.
+unblock is to rename (`git -m <old name> <new name>`), and then checkout the branch
+and `gt track`.
-Pre-merge Continuous Integration (CI)
--------------------------------------
+### Pre-merge Continuous Integration (CI)
Multiple checks will be applied on a pull-request, either for linting/formatting
or some build and tests. None of these are perfect and you will encounter
@@ -342,112 +339,110 @@ project.
However, please make sure you do not force-merge any changes that have clear
test failures directly linked to your changes. Our policy is still to keep the
-``main`` branch in a good condition, and introducing failures to be fixed later
+`main` branch in a good condition, and introducing failures to be fixed later
violates that policy.
-Problems After Landing Your Change
-==================================
+## Problems After Landing Your Change
Even though your PR passed the pre-commit checks and is approved by reviewers, it
may cause problems for some configurations after it lands. You will be notified
if this happens and the community is ready to help you fix the problems.
This process is described in detail
-:ref:`here <MyFirstTypoFix Issues After Landing Your PR>`.
+{ref}`here <MyFirstTypoFix Issues After Landing Your PR>`.
+
+### Checking out another PR locally
-Checking out another PR locally
--------------------------------
Sometimes you want to review another person's PR on your local machine to run
tests or inspect code in your preferred editor. This is easily done with the
CLI:
-::
-
- gh pr checkout <PR Number>
+```console
+gh pr checkout <PR Number>
+```
This is also possible with the web interface and the normal git command line
tools, but the process is a bit more complicated. See GitHub's
-`documentation <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally?platform=linux&tool=webui#modifying-an-inactive-pull-request-locally>`_
+[documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally?platform=linux&tool=webui#modifying-an-inactive-pull-request-locally)
on the topic.
-Example Pull Request with GitHub CLI
-====================================
-Here is an example for creating a Pull Request with the GitHub CLI:
+## Example Pull Request with GitHub CLI
-::
+Here is an example for creating a Pull Request with the GitHub CLI:
- # Clone the repo
- gh repo clone llvm/llvm-project
+```console
+# Clone the repo
+gh repo clone llvm/llvm-project
- # Switch to the repo and create a new branch
- cd llvm-project
- git switch -c my_change
+# Switch to the repo and create a new branch
+cd llvm-project
+git switch -c my_change
- # Create your changes
- $EDITOR file.cpp
+# Create your changes
+$EDITOR file.cpp
- # Don't forget clang-format
- git clang-format
+# Don't forget clang-format
+git clang-format
- # and don't forget running your tests
- ninja check-llvm
+# and don't forget running your tests
+ninja check-llvm
- # Commit, use a good commit message
- git commit file.cpp
+# Commit, use a good commit message
+git commit file.cpp
- # Create the PR, select to use your own fork when prompted.
- # If you don't have a fork, gh will create one for you.
- gh pr create
+# Create the PR, select to use your own fork when prompted.
+# If you don't have a fork, gh will create one for you.
+gh pr create
- # If you get any review comments, come back to the branch and
- # adjust them.
- git switch my_change
- $EDITOR file.cpp
+# If you get any review comments, come back to the branch and
+# adjust them.
+git switch my_change
+$EDITOR file.cpp
- # Commit your changes
- git commit file.cpp -m "Code Review adjustments"
+# Commit your changes
+git commit file.cpp -m "Code Review adjustments"
- # Format changes
- git clang-format HEAD~
+# Format changes
+git clang-format HEAD~
- # Recommit if any formatting changes
- git commit -a --amend
+# Recommit if any formatting changes
+git commit -a --amend
- # Push your changes to your fork branch, be mindful of
- # your remotes here, if you don't remember what points to your
- # fork, use git remote -v to see. Usually origin points to your
- # fork and upstream to llvm/llvm-project
- git push origin my_change
+# Push your changes to your fork branch, be mindful of
+# your remotes here, if you don't remember what points to your
+# fork, use git remote -v to see. Usually origin points to your
+# fork and upstream to llvm/llvm-project
+git push origin my_change
+```
Before merging the PR, it is recommended that you rebase locally and re-run test
checks:
-::
-
- # Add upstream as a remote (if you don't have it already)
- git remote add upstream https://github.com/llvm/llvm-project.git
+```console
+# Add upstream as a remote (if you don't have it already)
+git remote add upstream https://github.com/llvm/llvm-project.git
- # Make sure you have all the latest changes
- git fetch upstream && git rebase -i upstream/main
+# Make sure you have all the latest changes
+git fetch upstream && git rebase -i upstream/main
- # Make sure tests pass with latest changes and your change
- ninja check
+# Make sure tests pass with latest changes and your change
+ninja check
- # Push the rebased changes to your fork.
- git push origin my_change --force
+# Push the rebased changes to your fork.
+git push origin my_change --force
- # Now merge it
- gh pr merge --squash --delete-branch
+# Now merge it
+gh pr merge --squash --delete-branch
+```
See more in-depth information about how to contribute in the following documentation:
-* :doc:`Contributing`
-* :doc:`MyFirstTypoFix`
+* {doc}`Contributing`
+* {doc}`MyFirstTypoFix`
-Example Pull Request with git
-====================================
+## Example Pull Request with git
Instead of using the GitHub CLI to create a PR, you can push your code to a
remote branch on your fork and create the PR to upstream using the GitHub web
@@ -455,98 +450,97 @@ interface.
Here is an example of making a PR using git and the GitHub web interface:
-First follow the instructions to `fork the repository <https://docs.github.com/en/get-started/quickstart/fork-a-repo?tool=webui#forking-a-repository>`_.
+First follow the instructions to [fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo?tool=webui#forking-a-repository).
-Next follow the instructions to `clone your forked repository <https://docs.github.com/en/get-started/quickstart/fork-a-repo?tool=webui#cloning-your-forked-repository>`_.
+Next follow the instructions to [clone your forked repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo?tool=webui#cloning-your-forked-repository).
Once you've cloned your forked repository,
-::
-
- # Switch to the forked repo
- cd llvm-project
+```console
+# Switch to the forked repo
+cd llvm-project
- # Create a new branch
- git switch -c my_change
+# Create a new branch
+git switch -c my_change
- # Create your changes
- $EDITOR file.cpp
+# Create your changes
+$EDITOR file.cpp
- # Don't forget clang-format
- git clang-format
+# Don't forget clang-format
+git clang-format
- # and don't forget running your tests
- ninja check-llvm
+# and don't forget running your tests
+ninja check-llvm
- # Commit, use a good commit message
- git commit file.cpp
+# Commit, use a good commit message
+git commit file.cpp
- # Push your changes to your fork branch, be mindful of
- # your remotes here, if you don't remember what points to your
- # fork, use git remote -v to see. Usually origin points to your
- # fork and upstream to llvm/llvm-project
- git push origin my_change
+# Push your changes to your fork branch, be mindful of
+# your remotes here, if you don't remember what points to your
+# fork, use git remote -v to see. Usually origin points to your
+# fork and upstream to llvm/llvm-project
+git push origin my_change
+```
Navigate to the URL printed to the console from the git push command in the last step.
Create a pull request from your branch to llvm::main.
-::
-
- # If you get any review comments, come back to the branch and
- # adjust them.
- git switch my_change
- $EDITOR file.cpp
+```console
+# If you get any review comments, come back to the branch and
+# adjust them.
+git switch my_change
+$EDITOR file.cpp
- # Commit your changes
- git commit file.cpp -m "Code Review adjustments"
+# Commit your changes
+git commit file.cpp -m "Code Review adjustments"
- # Format changes
- git clang-format HEAD~
+# Format changes
+git clang-format HEAD~
- # Recommit if any formatting changes
- git commit -a --amend
+# Recommit if any formatting changes
+git commit -a --amend
- # Re-run tests and make sure nothing broke.
- ninja check
+# Re-run tests and make sure nothing broke.
+ninja check
- # Push your changes to your fork branch, be mindful of
- # your remotes here, if you don't remember what points to your
- # fork, use git remote -v to see. Usually origin points to your
- # fork and upstream to llvm/llvm-project
- git push origin my_change
+# Push your changes to your fork branch, be mindful of
+# your remotes here, if you don't remember what points to your
+# fork, use git remote -v to see. Usually origin points to your
+# fork and upstream to llvm/llvm-project
+git push origin my_change
+```
Before merging the PR, it is recommended that you rebase locally and re-run test
checks:
-::
+```console
+# Add upstream as a remote (if you don't have it already)
+git remote add upstream https://github.com/llvm/llvm-project.git
- # Add upstream as a remote (if you don't have it already)
- git remote add upstream https://github.com/llvm/llvm-project.git
+# Make sure you have all the latest changes
+git fetch upstream && git rebase -i upstream/main
- # Make sure you have all the latest changes
- git fetch upstream && git rebase -i upstream/main
+# Make sure tests pass with latest changes and your change
+ninja check
- # Make sure tests pass with latest changes and your change
- ninja check
-
- # Push the rebased changes to your fork.
- git push origin my_change --force
+# Push the rebased changes to your fork.
+git push origin my_change --force
+```
Once your PR is approved, rebased, and tests are passing, click `Squash and
Merge` on your PR in the GitHub web interface.
See more in-depth information about how to contribute in the following documentation:
-* :doc:`Contributing`
-* :doc:`MyFirstTypoFix`
+* {doc}`Contributing`
+* {doc}`MyFirstTypoFix`
+
+## Releases
-Releases
-========
+(backporting)=
-.. _backporting:
+### Backporting Fixes to the Release Branches
-Backporting Fixes to the Release Branches
------------------------------------------
You can use special comments on issues or pull requests to make backport
requests for the release branches. To do this, after your pull request has been
merged:
@@ -556,9 +550,9 @@ merged:
2. Add a comment to it in the following format:
-::
-
- /cherry-pick <commit> <commit> <...>
+```console
+/cherry-pick <commit> <commit> <...>
+```
This command takes one or more git commit hashes as arguments and will attempt
to cherry-pick the commit(s) to the release branch. If the commit(s) fail to
@@ -570,14 +564,13 @@ If a commit you want to backport does not apply cleanly, you may resolve
the conflicts locally and then create a pull request against the release
branch. Just make sure to add the release milestone to the pull request.
-Getting admin access to CI infrastructure
-=========================================
+## Getting admin access to CI infrastructure
Any individual who is responsible for setting up and/or maintaining CI
infrastructure for a LLVM project can request to be granted the CI/CD role by
-the LLVM infrastructure area team. The request can be made by creating `a
-Github issue <https://github.com/llvm/llvm-project/issues/new>`_ and using the
-``infrastructure`` label. Applicants must include a justification for why the
+the LLVM infrastructure area team. The request can be made by creating [a
+Github issue](https://github.com/llvm/llvm-project/issues/new) and using the
+`infrastructure` label. Applicants must include a justification for why the
role is being requested. Applications are reviewed on a case-by-case basis by
the LLVM infrastructure area team and the role can be revoked at any point as
the area team sees fit.
diff --git a/llvm/docs/Passes.md b/llvm/docs/Passes.md
index 66a682983d9d5..a54de72ba3018 100644
--- a/llvm/docs/Passes.md
+++ b/llvm/docs/Passes.md
@@ -1,21 +1,24 @@
-====================================
-LLVM's Analysis and Transform Passes
-====================================
+# LLVM's Analysis and Transform Passes
-.. contents::
- :local:
+```{contents}
+:local:
+```
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- KernelInfo
- LoopFusion
+KernelInfo
+LoopFusion
-Introduction
-============
-.. warning:: This document is not updated frequently, and the list of passes
- is most likely incomplete. It is possible to list passes known by the opt
- tool using ``opt -print-passes``.
+```
+
+## Introduction
+
+```{warning}
+This document is not updated frequently, and the list of passes
+is most likely incomplete. It is possible to list passes known by the opt
+tool using `opt -print-passes`.
+```
This document serves as a high-level summary of the optimization features that
LLVM provides. Optimizations are implemented as Passes that traverse some
@@ -30,13 +33,11 @@ are neither analysis nor transform passes. The table of contents above
provides a quick summary of each pass and links to the more complete pass
description later in the document.
-Analysis Passes
-===============
+## Analysis Passes
This section describes the LLVM Analysis Passes.
-``aa-eval``: Exhaustive Alias Analysis Precision Evaluator
-----------------------------------------------------------
+### `aa-eval`: Exhaustive Alias Analysis Precision Evaluator
This is a simple N^2 alias analysis accuracy evaluator. Basically, for each
function in the program, it simply queries to see how the alias analysis
@@ -46,127 +47,109 @@ function.
This is inspired and adapted from code by: Naveen Neelakantam, Francesco
Spadini, and Wojciech Stryjewski.
-``basic-aa``: Basic Alias Analysis (stateless AA impl)
-------------------------------------------------------
+### `basic-aa`: Basic Alias Analysis (stateless AA impl)
A basic alias analysis pass that implements identities (two different globals
cannot alias, etc), but does no stateful analysis.
-``basiccg``: Basic CallGraph Construction
------------------------------------------
+### `basiccg`: Basic CallGraph Construction
Yet to be written.
-.. _passes-da:
+(passes-da)=
-``da``: Dependence Analysis
----------------------------
+### `da`: Dependence Analysis
Dependence analysis framework, which is used to detect dependencies in memory
accesses.
-``domfrontier``: Dominance Frontier Construction
-------------------------------------------------
+### `domfrontier`: Dominance Frontier Construction
This pass is a simple dominator construction algorithm for finding forward
dominator frontiers.
-``domtree``: Dominator Tree Construction
-----------------------------------------
+### `domtree`: Dominator Tree Construction
This pass is a simple dominator construction algorithm for finding forward
dominators.
-``dot-callgraph``: Print Call Graph to "dot" file
--------------------------------------------------
+### `dot-callgraph`: Print Call Graph to "dot" file
-This pass, only available in ``opt``, prints the call graph into a ``.dot``
+This pass, only available in `opt`, prints the call graph into a `.dot`
graph. This graph can then be processed with the "dot" tool to convert it to
postscript or some other suitable format.
-``dot-cfg``: Print CFG of function to "dot" file
-------------------------------------------------
+### `dot-cfg`: Print CFG of function to "dot" file
-This pass, only available in ``opt``, prints the control flow graph into a
-``.dot`` graph. This graph can then be processed with the :program:`dot` tool
+This pass, only available in `opt`, prints the control flow graph into a
+`.dot` graph. This graph can then be processed with the {program}`dot` tool
to convert it to postscript or some other suitable format.
-Additionally, the ``-cfg-func-name=<substring>`` option can be used to filter the
+Additionally, the `-cfg-func-name=<substring>` option can be used to filter the
functions that are printed. All functions that contain the specified substring
will be printed.
-``dot-cfg-only``: Print CFG of function to "dot" file (with no function bodies)
--------------------------------------------------------------------------------
+### `dot-cfg-only`: Print CFG of function to "dot" file (with no function bodies)
-This pass, only available in ``opt``, prints the control flow graph into a
-``.dot`` graph, omitting the function bodies. This graph can then be processed
-with the :program:`dot` tool to convert it to postscript or some other suitable
+This pass, only available in `opt`, prints the control flow graph into a
+`.dot` graph, omitting the function bodies. This graph can then be processed
+with the {program}`dot` tool to convert it to postscript or some other suitable
format.
-Additionally, the ``-cfg-func-name=<substring>`` option can be used to filter the
+Additionally, the `-cfg-func-name=<substring>` option can be used to filter the
functions that are printed. All functions that contain the specified substring
will be printed.
-``dot-dom``: Print dominance tree of function to "dot" file
------------------------------------------------------------
+### `dot-dom`: Print dominance tree of function to "dot" file
-This pass, only available in ``opt``, prints the dominator tree into a ``.dot``
-graph. This graph can then be processed with the :program:`dot` tool to
+This pass, only available in `opt`, prints the dominator tree into a `.dot`
+graph. This graph can then be processed with the {program}`dot` tool to
convert it to postscript or some other suitable format.
-``dot-dom-only``: Print dominance tree of function to "dot" file (with no function bodies)
-------------------------------------------------------------------------------------------
+### `dot-dom-only`: Print dominance tree of function to "dot" file (with no function bodies)
-This pass, only available in ``opt``, prints the dominator tree into a ``.dot``
+This pass, only available in `opt`, prints the dominator tree into a `.dot`
graph, omitting the function bodies. This graph can then be processed with the
-:program:`dot` tool to convert it to postscript or some other suitable format.
+{program}`dot` tool to convert it to postscript or some other suitable format.
-``dot-post-dom``: Print postdominance tree of function to "dot" file
---------------------------------------------------------------------
+### `dot-post-dom`: Print postdominance tree of function to "dot" file
-This pass, only available in ``opt``, prints the post dominator tree into a
-``.dot`` graph. This graph can then be processed with the :program:`dot` tool
+This pass, only available in `opt`, prints the post dominator tree into a
+`.dot` graph. This graph can then be processed with the {program}`dot` tool
to convert it to postscript or some other suitable format.
-``dot-post-dom-only``: Print postdominance tree of function to "dot" file (with no function bodies)
----------------------------------------------------------------------------------------------------
+### `dot-post-dom-only`: Print postdominance tree of function to "dot" file (with no function bodies)
-This pass, only available in ``opt``, prints the post dominator tree into a
-``.dot`` graph, omitting the function bodies. This graph can then be processed
-with the :program:`dot` tool to convert it to postscript or some other suitable
+This pass, only available in `opt`, prints the post dominator tree into a
+`.dot` graph, omitting the function bodies. This graph can then be processed
+with the {program}`dot` tool to convert it to postscript or some other suitable
format.
-``globals-aa``: Simple mod/ref analysis for globals
----------------------------------------------------
+### `globals-aa`: Simple mod/ref analysis for globals
This simple pass provides alias and mod/ref information for global values that
do not have their address taken, and keeps track of whether functions read or
write memory (are "pure"). For this simple (but very common) case, we can
provide pretty accurate and useful information.
-``instcount``: Counts the various types of ``Instruction``\ s
--------------------------------------------------------------
+### `instcount`: Counts the various types of `Instruction`s
This pass collects the count of all instructions and reports them.
-``iv-users``: Induction Variable Users
---------------------------------------
+### `iv-users`: Induction Variable Users
Bookkeeping for "interesting" users of expressions computed from induction
variables.
-``kernel-info``: GPU Kernel Info
---------------------------------
+### `kernel-info`: GPU Kernel Info
Reports various statistics for codes compiled for GPUs. This pass is
-:doc:`documented separately<KernelInfo>`.
+{doc}`documented separately <KernelInfo>`.
-``lazy-value-info``: Lazy Value Information Analysis
-----------------------------------------------------
+### `lazy-value-info`: Lazy Value Information Analysis
Interface for lazy computation of value constraint information.
-``lint``: Statically lint-checks LLVM IR
-----------------------------------------
+### `lint`: Statically lint-checks LLVM IR
This pass statically checks for common and easily-identified constructs which
produce undefined or likely unintended behavior in LLVM IR.
@@ -187,137 +170,119 @@ obvious. If an optimization pass appears to be introducing a warning, it may
be that the optimization pass is merely exposing an existing condition in the
code.
-This code may be run before :ref:`instcombine <passes-instcombine>`. In many
+This code may be run before {ref}`instcombine <passes-instcombine>`. In many
cases, instcombine checks for the same kinds of things and turns instructions
with undefined behavior into unreachable (or equivalent). Because of this,
this pass makes some effort to look through bitcasts and so on.
-``loops``: Natural Loop Information
------------------------------------
+### `loops`: Natural Loop Information
This analysis is used to identify natural loops and determine the loop depth of
various nodes of the CFG. Note that the loops identified may actually be
several natural loops that share the same header node... not just a single
natural loop.
-``memdep``: Memory Dependence Analysis
---------------------------------------
+### `memdep`: Memory Dependence Analysis
An analysis that determines, for a given memory operation, what preceding
memory operations it depends on. It builds on alias analysis information, and
tries to provide a lazy, caching interface to a common kind of alias
information query.
-``print<module-debuginfo>``: Decodes module-level debug info
-------------------------------------------------------------
+### `print<module-debuginfo>`: Decodes module-level debug info
This pass decodes the debug info metadata in a module and prints it to standard output in a
(sufficiently-prepared-) human-readable form.
-``postdomtree``: Post-Dominator Tree Construction
--------------------------------------------------
+### `postdomtree`: Post-Dominator Tree Construction
This pass is a simple post-dominator construction algorithm for finding
post-dominators.
-``print<alias-sets>``: Alias Set Printer
-----------------------------------------
+### `print<alias-sets>`: Alias Set Printer
Yet to be written.
-``print-callgraph``: Print a call graph
----------------------------------------
+### `print-callgraph`: Print a call graph
-This pass, only available in ``opt``, prints the call graph to standard error
+This pass, only available in `opt`, prints the call graph to standard error
in a human-readable form.
-``print-callgraph-sccs``: Print SCCs of the Call Graph
-------------------------------------------------------
+### `print-callgraph-sccs`: Print SCCs of the Call Graph
-This pass, only available in ``opt``, prints the SCCs of the call graph to
+This pass, only available in `opt`, prints the SCCs of the call graph to
standard error in a human-readable form.
-``print<cfg-sccs>``: Print SCCs of each function CFG
-----------------------------------------------------
+### `print<cfg-sccs>`: Print SCCs of each function CFG
-This pass, only available in ``opt``, prints the SCCs of each function CFG to
+This pass, only available in `opt`, prints the SCCs of each function CFG to
standard error in a human-readable form.
-``function(print)``: Print function to stderr
----------------------------------------------
+### `function(print)`: Print function to stderr
-The ``PrintFunctionPass`` class is designed to be pipelined with other
-``FunctionPasses``, and prints out the functions of the module as they are
+The `PrintFunctionPass` class is designed to be pipelined with other
+`FunctionPasses`, and prints out the functions of the module as they are
processed.
-``module(print)``: Print module to stderr
------------------------------------------
+### `module(print)`: Print module to stderr
This pass simply prints out the entire module when it is executed.
-``regions``: Detect single entry single exit regions
-----------------------------------------------------
+### `regions`: Detect single entry single exit regions
-The ``RegionInfo`` pass detects single entry single exit regions in a function,
+The `RegionInfo` pass detects single entry single exit regions in a function,
where a region is defined as any subgraph that is connected to the remaining
graph at only two spots. Furthermore, a hierarchical region tree is built.
-.. _passes-scalar-evolution:
+(passes-scalar-evolution)=
-``scalar-evolution``: Scalar Evolution Analysis
------------------------------------------------
+### `scalar-evolution`: Scalar Evolution Analysis
-The ``ScalarEvolution`` analysis can be used to analyze and categorize scalar
+The `ScalarEvolution` analysis can be used to analyze and categorize scalar
expressions in loops. It specializes in recognizing general induction
-variables, representing them with the abstract and opaque ``SCEV`` class.
+variables, representing them with the abstract and opaque `SCEV` class.
Given this analysis, trip counts of loops and other important properties can be
obtained.
This analysis is primarily useful for induction variable substitution and
strength reduction.
-``scev-aa``: ScalarEvolution-based Alias Analysis
--------------------------------------------------
+### `scev-aa`: ScalarEvolution-based Alias Analysis
-Simple alias analysis implemented in terms of ``ScalarEvolution`` queries.
+Simple alias analysis implemented in terms of `ScalarEvolution` queries.
This differs from traditional loop dependence analysis in that it tests for
dependencies within a single iteration of a loop, rather than dependencies
between different iterations.
-``ScalarEvolution`` has a more complete understanding of pointer arithmetic
-than ``BasicAliasAnalysis``' collection of ad-hoc analyses.
+`ScalarEvolution` has a more complete understanding of pointer arithmetic
+than `BasicAliasAnalysis`' collection of ad-hoc analyses.
-``stack-safety``: Stack Safety Analysis
----------------------------------------
+### `stack-safety`: Stack Safety Analysis
-The ``StackSafety`` analysis can be used to determine if stack allocated
+The `StackSafety` analysis can be used to determine if stack allocated
variables can be considered safe from memory access bugs.
This analysis' primary purpose is to be used by sanitizers to avoid unnecessary
instrumentation of safe variables.
-Transform Passes
-================
+## Transform Passes
This section describes the LLVM Transform Passes.
-``adce``: Aggressive Dead Code Elimination
-------------------------------------------
+### `adce`: Aggressive Dead Code Elimination
-ADCE aggressively tries to eliminate code. This pass is similar to :ref:`DCE
-<passes-dce>` but it assumes that values are dead until proven otherwise. This
-is similar to :ref:`SCCP <passes-sccp>`, except applied to the liveness of
+ADCE aggressively tries to eliminate code. This pass is similar to
+{ref}`DCE <passes-dce>` but it assumes that values are dead until proven otherwise. This
+is similar to {ref}`SCCP <passes-sccp>`, except applied to the liveness of
values.
-``always-inline``: Inliner for ``always_inline`` functions
-----------------------------------------------------------
+### `always-inline`: Inliner for `always_inline` functions
A custom inliner that handles only functions that are marked as "always
inline".
-``argpromotion``: Promote 'by reference' arguments to scalars
--------------------------------------------------------------
+### `argpromotion`: Promote 'by reference' arguments to scalars
This pass promotes "by reference" arguments to be "by value" arguments. In
practice, this means looking for internal functions that have pointer
@@ -338,8 +303,7 @@ stored to (returning the value instead), but does not currently. This case
would be best handled when and if LLVM starts supporting multiple return values
from functions.
-``block-placement``: Profile Guided Basic Block Placement
----------------------------------------------------------
+### `block-placement`: Profile Guided Basic Block Placement
This pass is a very simple profile guided basic block placement algorithm. The
idea is to put frequently executed blocks together at the start of the function
@@ -347,40 +311,35 @@ and hopefully increase the number of fall-through conditional branches. If
there is no profile information for a particular function, this pass basically
orders blocks in depth-first order.
-``break-crit-edges``: Break critical edges in CFG
--------------------------------------------------
+### `break-crit-edges`: Break critical edges in CFG
Break all of the critical edges in the CFG by inserting a dummy basic block.
It may be "required" by passes that cannot deal with critical edges. This
transformation obviously invalidates the CFG, but can update forward dominator
(set, immediate dominators, tree, and frontier) information.
-``codegenprepare``: Optimize for code generation
-------------------------------------------------
+### `codegenprepare`: Optimize for code generation
This pass munges the code in the input function to better prepare it for
SelectionDAG-based code generation. This works around limitations in its
basic-block-at-a-time approach. It should eventually be removed.
-``constmerge``: Merge Duplicate Global Constants
-------------------------------------------------
+### `constmerge`: Merge Duplicate Global Constants
Merges duplicate global constants together into a single constant that is
shared. This is useful because some passes (i.e., TraceValues) insert a lot of
string constants into the program, regardless of whether or not an existing
string is available.
-.. _passes-dce:
+(passes-dce)=
-``dce``: Dead Code Elimination
-------------------------------
+### `dce`: Dead Code Elimination
Dead code elimination is similar to dead instruction elimination, but it
rechecks instructions that were used by removed instructions to see if they
are newly dead.
-``deadargelim``: Dead Argument Elimination
-------------------------------------------
+### `deadargelim`: Dead Argument Elimination
This pass deletes dead arguments from internal functions. Dead argument
elimination removes arguments which are directly dead, as well as arguments
@@ -390,28 +349,25 @@ pass also deletes dead arguments in a similar way.
This pass is often useful as a cleanup pass to run after aggressive
interprocedural passes, which add possibly-dead arguments.
-``dse``: Dead Store Elimination
--------------------------------
+### `dse`: Dead Store Elimination
A trivial dead store elimination that only considers basic-block local
redundant stores.
-.. _passes-function-attrs:
+(passes-function-attrs)=
-``function-attrs``: Deduce function attributes
-----------------------------------------------
+### `function-attrs`: Deduce function attributes
A simple interprocedural pass which walks the call-graph, looking for functions
which do not access or only read non-local memory, and marking them
-``readnone``/``readonly``. In addition, it marks function arguments (of
-pointer type) "``nocapture``" if a call to the function does not create any
+`readnone`/`readonly`. In addition, it marks function arguments (of
+pointer type) "`nocapture`" if a call to the function does not create any
copies of the pointer value that outlive the call. This more or less means
that the pointer is only dereferenced, and not returned from the function or
stored in a global. This pass is implemented as a bottom-up traversal of the
call-graph.
-``globaldce``: Dead Global Elimination
---------------------------------------
+### `globaldce`: Dead Global Elimination
This transform is designed to eliminate unreachable internal globals from the
program. It uses an aggressive algorithm, searching out globals that are known
@@ -419,23 +375,20 @@ to be alive. After it finds all of the globals which are needed, it deletes
whatever is left over. This allows it to delete recursive chunks of the
program which are unreachable.
-``globalopt``: Global Variable Optimizer
-----------------------------------------
+### `globalopt`: Global Variable Optimizer
This pass transforms simple global variables that never have their address
taken. If obviously true, it marks read/write globals as constant, deletes
variables only stored to, etc.
-``gvn``: Global Value Numbering
--------------------------------
+### `gvn`: Global Value Numbering
This pass performs global value numbering to eliminate fully and partially
redundant instructions. It also performs redundant load elimination.
-.. _passes-indvars:
+(passes-indvars)=
-``indvars``: Canonicalize Induction Variables
----------------------------------------------
+### `indvars`: Canonicalize Induction Variables
This transformation analyzes and transforms the induction variables (and
computations derived from them) into simpler forms suitable for subsequent
@@ -456,16 +409,14 @@ changes:
* The exit condition for the loop is canonicalized to compare the induction
value against the exit value. This turns loops like:
- .. code-block:: c++
-
- for (i = 7; i*i < 1000; ++i)
-
- into
-
- .. code-block:: c++
-
- for (i = 0; i != 25; ++i)
+ ```c++
+ for (i = 7; i*i < 1000; ++i)
+ into
+ ```
+ ```c++
+ for (i = 0; i != 25; ++i)
+ ```
* Any use outside of the loop of an expression derived from the indvar is
changed to compute the derived value outside of the loop, eliminating the
dependence on the exit value of the induction variable. If the only purpose
@@ -477,94 +428,85 @@ desired loop transformations have been performed. Additionally, on targets
where it is profitable, the loop could be transformed to count down to zero
(the "do loop" optimization).
-``inline``: Function Integration/Inlining
------------------------------------------
+### `inline`: Function Integration/Inlining
Bottom-up inlining of functions into callees.
-.. _passes-instcombine:
+(passes-instcombine)=
-``instcombine``: Combine redundant instructions
------------------------------------------------
+### `instcombine`: Combine redundant instructions
Combine instructions to form fewer, simpler instructions. This pass does not
modify the CFG. This pass is where algebraic simplification happens.
This pass combines things like:
-.. code-block:: llvm
-
- %Y = add i32 %X, 1
- %Z = add i32 %Y, 1
-
+```llvm
+%Y = add i32 %X, 1
+%Z = add i32 %Y, 1
+```
into:
-.. code-block:: llvm
-
- %Z = add i32 %X, 2
-
+```llvm
+%Z = add i32 %X, 2
+```
This is a simple worklist-driven algorithm.
This pass guarantees that the following canonicalizations are performed on the
program:
-#. If a binary operator has a constant operand, it is moved to the right-hand
+1. If a binary operator has a constant operand, it is moved to the right-hand
side.
-#. Bitwise operators with constant operands are always grouped so that shifts
- are performed first, then ``or``\ s, then ``and``\ s, then ``xor``\ s.
-#. Compare instructions are converted from ``<``, ``>``, ``≤``, or ``≥`` to
- ``=`` or ``≠`` if possible.
-#. All ``cmp`` instructions on boolean values are replaced with logical
+1. Bitwise operators with constant operands are always grouped so that shifts
+ are performed first, then `or`s, then `and`s, then `xor`s.
+1. Compare instructions are converted from `<`, `>`, `≤`, or `≥` to
+ `=` or `≠` if possible.
+1. All `cmp` instructions on boolean values are replaced with logical
operations.
-#. ``add X, X`` is represented as ``mul X, 2`` ⇒ ``shl X, 1``
-#. Multiplies with a constant power-of-two argument are transformed into
+1. `add X, X` is represented as `mul X, 2` ⇒ `shl X, 1`
+1. Multiplies with a constant power-of-two argument are transformed into
shifts.
-#. … etc.
+1. … etc.
This pass can also simplify calls to specific well-known function calls (e.g.
-runtime library functions). For example, a call ``exit(3)`` that occurs within
-the ``main()`` function can be transformed into simply ``return 3``. Whether or
+runtime library functions). For example, a call `exit(3)` that occurs within
+the `main()` function can be transformed into simply `return 3`. Whether or
not library calls are simplified is controlled by the
-:ref:`-function-attrs <passes-function-attrs>` pass and LLVM's knowledge of
+{ref}`-function-attrs <passes-function-attrs>` pass and LLVM's knowledge of
library calls on different targets.
-.. _passes-aggressive-instcombine:
+(passes-aggressive-instcombine)=
-``aggressive-instcombine``: Combine expression patterns
---------------------------------------------------------
+### `aggressive-instcombine`: Combine expression patterns
Combine expression patterns to form expressions with fewer, simpler instructions.
-For example, this pass reduces the width of expressions post-dominated by ``TruncInst``
+For example, this pass reduces the width of expressions post-dominated by `TruncInst`
into smaller width when applicable.
It differs from instcombine pass in that it can modify CFG and contains pattern
optimization that requires higher complexity than the O(1), thus, it should run fewer
times than instcombine pass.
-``internalize``: Internalize Global Symbols
--------------------------------------------
+### `internalize`: Internalize Global Symbols
This pass loops over all of the functions in the input module, looking for a
main function. If a main function is found, all other functions and all global
variables with initializers are marked as internal.
-``ipsccp``: Interprocedural Sparse Conditional Constant Propagation
--------------------------------------------------------------------
+### `ipsccp`: Interprocedural Sparse Conditional Constant Propagation
-An interprocedural variant of :ref:`Sparse Conditional Constant Propagation
-<passes-sccp>`.
+An interprocedural variant of
+{ref}`Sparse Conditional Constant Propagation <passes-sccp>`.
-``normalize``: Transforms IR into a normal form that's easier to diff
----------------------------------------------------------------------
+### `normalize`: Transforms IR into a normal form that's easier to diff
This pass aims to transform LLVM Modules into a normal form by reordering and
renaming instructions while preserving the same semantics. The normalizer makes
it easier to spot semantic differences while diffing two modules which have
undergone two different passes.
-``jump-threading``: Jump Threading
-----------------------------------
+### `jump-threading`: Jump Threading
Jump threading tries to find distinct threads of control flow running through a
basic block. This pass looks at blocks that have multiple predecessors and
@@ -575,46 +517,42 @@ block.
An example of when this can occur is code like this:
-.. code-block:: c++
-
- if () { ...
- X = 4;
- }
- if (X < 3) {
-
+```c++
+if () { ...
+ X = 4;
+}
+if (X < 3) {
+```
In this case, the unconditional branch at the end of the first if can be
revectored to the false side of the second if.
-.. _passes-lcssa:
+(passes-lcssa)=
-``lcssa``: Loop-Closed SSA Form Pass
-------------------------------------
+### `lcssa`: Loop-Closed SSA Form Pass
This pass transforms loops by placing phi nodes at the end of the loops for all
values that are live across the loop boundary. For example, it turns the left
into the right code:
-.. code-block:: c++
-
- for (...) for (...)
- if (c) if (c)
- X1 = ... X1 = ...
- else else
- X2 = ... X2 = ...
- X3 = phi(X1, X2) X3 = phi(X1, X2)
- ... = X3 + 4 X4 = phi(X3)
- ... = X4 + 4
-
+```c++
+for (...) for (...)
+ if (c) if (c)
+ X1 = ... X1 = ...
+ else else
+ X2 = ... X2 = ...
+ X3 = phi(X1, X2) X3 = phi(X1, X2)
+... = X3 + 4 X4 = phi(X3)
+ ... = X4 + 4
+```
This is still valid LLVM; the extra phi nodes are purely redundant, and will be
-trivially eliminated by ``InstCombine``. The major benefit of this
+trivially eliminated by `InstCombine`. The major benefit of this
transformation is that it makes many other loop optimizations, such as
-``LoopUnswitch``\ ing, simpler. You can read more in the
-:ref:`loop terminology section for the LCSSA form <loop-terminology-lcssa>`.
+`LoopUnswitch`ing, simpler. You can read more in the
+{ref}`loop terminology section for the LCSSA form <loop-terminology-lcssa>`.
-.. _passes-licm:
+(passes-licm)=
-``licm``: Loop Invariant Code Motion
-------------------------------------
+### `licm`: Loop Invariant Code Motion
This pass performs loop invariant code motion, attempting to remove as much
code from the body of a loop as possible. It does this by either hoisting code
@@ -630,49 +568,45 @@ also handles other optimizations than LICM that increase live-ranges.
This pass uses alias analysis for two purposes:
-#. Moving loop invariant loads and calls out of loops. If we can determine
+1. Moving loop invariant loads and calls out of loops. If we can determine
that a load or call inside of a loop never aliases anything stored to, we
can hoist it or sink it like any other instruction.
-#. Scalar Promotion of Memory. If there is a store instruction inside of the
+1. Scalar Promotion of Memory. If there is a store instruction inside of the
loop, we try to move the store to happen AFTER the loop instead of inside of
the loop. This can only happen if a few conditions are true:
- #. The pointer stored through is loop invariant.
- #. There are no stores or loads in the loop which *may* alias the pointer.
+ 1. The pointer stored through is loop invariant.
+ 1. There are no stores or loads in the loop which *may* alias the pointer.
There are no calls in the loop which mod/ref the pointer.
If these conditions are true, we can promote the loads and stores in the
loop of the pointer to use a temporary alloca'd variable. We then use the
- :ref:`mem2reg <passes-mem2reg>` functionality to construct the appropriate
+ {ref}`mem2reg <passes-mem2reg>` functionality to construct the appropriate
SSA form for the variable.
-``loop-deletion``: Delete dead loops
-------------------------------------
+### `loop-deletion`: Delete dead loops
This file implements the Dead Loop Deletion Pass. This pass is responsible for
eliminating loops with non-infinite computable trip counts that have no side
effects or volatile instructions, and do not contribute to the computation of
the function's return value.
-.. _passes-loop-extract:
+(passes-loop-extract)=
-``loop-extract``: Extract loops into new functions
---------------------------------------------------
+### `loop-extract`: Extract loops into new functions
-A pass wrapper around the ``ExtractLoop()`` scalar transformation to extract
+A pass wrapper around the `ExtractLoop()` scalar transformation to extract
each top-level loop into its own new function. If the loop is the *only* loop
in a given function, it is not touched. This is a pass most useful for
debugging via bugpoint.
-``loop-fusion``: Loop Fusion
-----------------------------
+### `loop-fusion`: Loop Fusion
Merges adjacent loops when it can prove the transformation preserves the
-program's semantics. This pass is :doc:`documented separately<LoopFusion>`.
+program's semantics. This pass is {doc}`documented separately <LoopFusion>`.
-``loop-reduce``: Loop Strength Reduction
-----------------------------------------
+### `loop-reduce`: Loop Strength Reduction
This pass performs a strength reduction on array references inside loops that
have as one or more of their components the loop induction variable. This is
@@ -680,28 +614,26 @@ accomplished by creating a new value to hold the initial value of the array
access for the first iteration, and then creating a new GEP instruction in the
loop to increment the value by the appropriate amount.
-.. _passes-loop-rotate:
+(passes-loop-rotate)=
-``loop-rotate``: Rotate Loops
------------------------------
+### `loop-rotate`: Rotate Loops
A simple loop rotation transformation. A summary of it can be found in
-:ref:`Loop Terminology for Rotated Loops <loop-terminology-loop-rotate>`.
+{ref}`Loop Terminology for Rotated Loops <loop-terminology-loop-rotate>`.
-.. _passes-loop-simplify:
+(passes-loop-simplify)=
-``loop-simplify``: Canonicalize natural loops
----------------------------------------------
+### `loop-simplify`: Canonicalize natural loops
This pass performs several transformations to transform natural loops into a
simpler form, which makes subsequent analyses and transformations simpler and
more effective. A summary of it can be found in
-:ref:`Loop Terminology, Loop Simplify Form <loop-terminology-loop-simplify>`.
+{ref}`Loop Terminology, Loop Simplify Form <loop-terminology-loop-simplify>`.
Loop pre-header insertion guarantees that there is a single, non-critical entry
edge from outside of the loop to the loop header. This simplifies a number of
-analyses and transformations, such as :ref:`LICM <passes-licm>`.
+analyses and transformations, such as {ref}`LICM <passes-licm>`.
Loop exit-block insertion guarantees that all exit blocks from the loop (blocks
which are outside of the loop that have predecessors inside of the loop) only
@@ -711,51 +643,46 @@ into LICM.
This pass also guarantees that loops will have exactly one backedge.
-Note that the :ref:`simplifycfg <passes-simplifycfg>` pass will clean up blocks
+Note that the {ref}`simplifycfg <passes-simplifycfg>` pass will clean up blocks
which are split out but end up being unnecessary, so usage of this pass should
not pessimize generated code.
This pass obviously modifies the CFG, but updates loop information and
dominator information.
-``loop-unroll``: Unroll loops
------------------------------
+### `loop-unroll`: Unroll loops
This pass implements a simple loop unroller. It works best when loops have
-been canonicalized by the :ref:`indvars <passes-indvars>` pass, allowing it to
+been canonicalized by the {ref}`indvars <passes-indvars>` pass, allowing it to
determine the trip counts of loops easily.
-``loop-unroll-and-jam``: Unroll and Jam loops
----------------------------------------------
+### `loop-unroll-and-jam`: Unroll and Jam loops
This pass implements a simple unroll and jam classical loop optimisation pass.
It transforms a loop from:
-.. code-block:: c++
-
- for i.. i+= 1 for i.. i+= 4
- for j.. for j..
- code(i, j) code(i, j)
- code(i+1, j)
- code(i+2, j)
- code(i+3, j)
- remainder loop
-
+```c++
+for i.. i+= 1 for i.. i+= 4
+ for j.. for j..
+ code(i, j) code(i, j)
+ code(i+1, j)
+ code(i+2, j)
+ code(i+3, j)
+ remainder loop
+```
Which can be seen as unrolling the outer loop and "jamming" (fusing) the inner
loops into one. When variables or loads can be shared in the new inner loop, this
can lead to significant performance improvements. It uses
-:ref:`Dependence Analysis <passes-da>` for proving the transformations are safe.
+{ref}`Dependence Analysis <passes-da>` for proving the transformations are safe.
-``lower-global-dtors``: Lower global destructors
-------------------------------------------------
+### `lower-global-dtors`: Lower global destructors
-This pass lowers global module destructors (``llvm.global_dtors``) by creating
+This pass lowers global module destructors (`llvm.global_dtors`) by creating
wrapper functions that are registered as global constructors in
-``llvm.global_ctors`` and which contain a call to ``__cxa_atexit`` to register
+`llvm.global_ctors` and which contain a call to `__cxa_atexit` to register
their destructor functions.
-``lower-atomic``: Lower atomic intrinsics to non-atomic form
-------------------------------------------------------------
+### `lower-atomic`: Lower atomic intrinsics to non-atomic form
This pass lowers atomic intrinsics to non-atomic form for use in a known
non-preemptible environment.
@@ -765,42 +692,37 @@ this would require knowledge of the entire call graph of the program including
any libraries which may not be available in bitcode form); it simply lowers
every atomic intrinsic.
-``lower-invoke``: Lower invokes to calls, for unwindless code generators
-------------------------------------------------------------------------
+### `lower-invoke`: Lower invokes to calls, for unwindless code generators
This transformation is designed for use by code generators which do not yet
-support stack unwinding. This pass converts ``invoke`` instructions to
-``call`` instructions, so that any exception-handling ``landingpad`` blocks
-become dead code (which can be removed by running the ``-simplifycfg`` pass
+support stack unwinding. This pass converts `invoke` instructions to
+`call` instructions, so that any exception-handling `landingpad` blocks
+become dead code (which can be removed by running the `-simplifycfg` pass
afterwards).
-``lower-switch``: Lower ``SwitchInst``\ s to branches
------------------------------------------------------
+### `lower-switch`: Lower `SwitchInst`s to branches
Rewrites switch instructions with a sequence of branches, which allows targets
to get away with not implementing the switch instruction until it is
convenient.
-.. _passes-mem2reg:
+(passes-mem2reg)=
-``mem2reg``: Promote Memory to Register
----------------------------------------
+### `mem2reg`: Promote Memory to Register
This file promotes memory references to be register references. It promotes
-alloca instructions which only have loads and stores as uses. An ``alloca`` is
+alloca instructions which only have loads and stores as uses. An `alloca` is
transformed by using dominator frontiers to place phi nodes, then traversing
the function in depth-first order to rewrite loads and stores as appropriate.
This is just the standard SSA construction algorithm to construct "pruned" SSA
form.
-``memcpyopt``: MemCpy Optimization
-----------------------------------
+### `memcpyopt`: MemCpy Optimization
-This pass performs various transformations related to eliminating ``memcpy``
-calls, or transforming sets of stores into ``memset``\ s.
+This pass performs various transformations related to eliminating `memcpy`
+calls, or transforming sets of stores into `memset`s.
-``mergefunc``: Merge Functions
-------------------------------
+### `mergefunc`: Merge Functions
This pass looks for equivalent functions that are mergeable and folds them.
@@ -820,26 +742,23 @@ Lookup routine has O(log(n)) complexity, while whole merging process has
complexity of O(n*log(n)).
Read
-:doc:`this <MergeFunctions>`
+{doc}`this <MergeFunctions>`
article for more details.
-``mergereturn``: Unify function exit nodes
-------------------------------------------
+### `mergereturn`: Unify function exit nodes
-Ensure that functions have at most one ``ret`` instruction in them.
+Ensure that functions have at most one `ret` instruction in them.
Additionally, it keeps track of which node is the new exit node of the CFG.
-``partial-inliner``: Partial Inliner
-------------------------------------
+### `partial-inliner`: Partial Inliner
-This pass performs partial inlining, typically by inlining an ``if`` statement
+This pass performs partial inlining, typically by inlining an `if` statement
that surrounds the body of the function.
-``reassociate``: Reassociate expressions
-----------------------------------------
+### `reassociate`: Reassociate expressions
This pass reassociates commutative expressions in an order that is designed to
-promote better constant propagation, GCSE, :ref:`LICM <passes-licm>`, PRE, etc.
+promote better constant propagation, GCSE, {ref}`LICM <passes-licm>`, PRE, etc.
For example: 4 + (x + 5) ⇒ x + (4 + 5)
@@ -849,35 +768,31 @@ corresponding to the reverse post-order traversal of the current function (start
at 2), which effectively gives values in deep loops higher rank than values not
in loops.
-``rel-lookup-table-converter``: Relative lookup table converter
----------------------------------------------------------------
+### `rel-lookup-table-converter`: Relative lookup table converter
This pass converts lookup tables to PIC-friendly relative lookup tables.
-``reg2mem``: Demote all values to stack slots
----------------------------------------------
+### `reg2mem`: Demote all values to stack slots
This file demotes all registers to memory references. It is intended to be the
-inverse of :ref:`mem2reg <passes-mem2reg>`. By converting to ``load``
-instructions, the only values live across basic blocks are ``alloca``
-instructions and ``load`` instructions before ``phi`` nodes. It is intended
+inverse of {ref}`mem2reg <passes-mem2reg>`. By converting to `load`
+instructions, the only values live across basic blocks are `alloca`
+instructions and `load` instructions before `phi` nodes. It is intended
that this should make CFG hacking much easier. To make later hacking easier,
-the entry block is split into two, such that all introduced ``alloca``
+the entry block is split into two, such that all introduced `alloca`
instructions (and nothing else) are in the entry block.
-``sroa``: Scalar Replacement of Aggregates
-------------------------------------------
+### `sroa`: Scalar Replacement of Aggregates
The well-known scalar replacement of aggregates transformation. This transform
-breaks up ``alloca`` instructions of aggregate type (structure or array) into
-individual ``alloca`` instructions for each member if possible. Then, if
-possible, it transforms the individual ``alloca`` instructions into nice clean
+breaks up `alloca` instructions of aggregate type (structure or array) into
+individual `alloca` instructions for each member if possible. Then, if
+possible, it transforms the individual `alloca` instructions into nice clean
scalar SSA form.
-.. _passes-sccp:
+(passes-sccp)=
-``sccp``: Sparse Conditional Constant Propagation
--------------------------------------------------
+### `sccp`: Sparse Conditional Constant Propagation
Sparse conditional constant propagation and merging, which can be summarized
as:
@@ -888,12 +803,11 @@ as:
* Proves conditional branches to be unconditional
Note that this pass has a habit of making definitions be dead. It is a good
-idea to run a :ref:`DCE <passes-dce>` pass sometime after running this pass.
+idea to run a {ref}`DCE <passes-dce>` pass sometime after running this pass.
-.. _passes-simplifycfg:
+(passes-simplifycfg)=
-``simplifycfg``: Simplify the CFG
----------------------------------
+### `simplifycfg`: Simplify the CFG
Performs dead code elimination and basic block merging. Specifically:
@@ -903,39 +817,35 @@ Performs dead code elimination and basic block merging. Specifically:
* Eliminates PHI nodes for basic blocks with a single predecessor.
* Eliminates a basic block that only contains an unconditional branch.
-``sink``: Code sinking
-----------------------
+### `sink`: Code sinking
This pass moves instructions into successor blocks, when possible, so that they
aren't executed on paths where their results aren't needed.
-.. _passes-simple-loop-unswitch:
+(passes-simple-loop-unswitch)=
-``simple-loop-unswitch``: Unswitch loops
-----------------------------------------
+### `simple-loop-unswitch`: Unswitch loops
This pass transforms loops that contain branches on loop-invariant conditions
to have multiple loops. For example, it turns the left into the right code:
-.. code-block:: c++
-
- for (...) if (lic)
- A for (...)
- if (lic) A; B; C
- B else
- C for (...)
- A; C
-
+```c++
+for (...) if (lic)
+ A for (...)
+ if (lic) A; B; C
+ B else
+ C for (...)
+ A; C
+```
This can increase the size of the code exponentially (doubling it every time a
loop is unswitched) so we only unswitch if the resultant code will be smaller
than a threshold.
-This pass expects :ref:`LICM <passes-licm>` to be run before it to hoist
+This pass expects {ref}`LICM <passes-licm>` to be run before it to hoist
invariant conditions out of the loop, to make the unswitching opportunity
obvious.
-``strip``: Strip all symbols from a module
-------------------------------------------
+### `strip`: Strip all symbols from a module
Performs code stripping. This transformation can delete:
@@ -947,84 +857,73 @@ Note that this transformation makes code much less readable, so it should only
be used in situations where the strip utility would be used, such as reducing
code size or making it harder to reverse engineer code.
-``strip-dead-debug-info``: Strip debug info for unused symbols
---------------------------------------------------------------
+### `strip-dead-debug-info`: Strip debug info for unused symbols
Performs code stripping. Similar to strip, but only strips debug info for
unused symbols.
-``strip-dead-prototypes``: Strip Unused Function Prototypes
------------------------------------------------------------
+### `strip-dead-prototypes`: Strip Unused Function Prototypes
This pass loops over all of the functions in the input module, looking for dead
declarations and removes them. Dead declarations are declarations of functions
for which no implementation is available (i.e., declarations for unused library
functions).
-``strip-debug-declare``: Strip all ``llvm.dbg.declare`` intrinsics and
-``#dbg_declare`` records.
--------------------------------------------------------------------
+### `strip-debug-declare`: Strip all `llvm.dbg.declare` intrinsics and `#dbg_declare` records.
Performs code stripping. Similar to strip, but only strips
-``llvm.dbg.declare`` intrinsics.
+`llvm.dbg.declare` intrinsics.
-``strip-nondebug``: Strip all symbols, except dbg symbols, from a module
-------------------------------------------------------------------------
+### `strip-nondebug`: Strip all symbols, except dbg symbols, from a module
Performs code stripping. Similar to strip, but dbg info is preserved.
-``tailcallelim``: Tail Call Elimination
----------------------------------------
+### `tailcallelim`: Tail Call Elimination
This file transforms calls of the current function (self recursion) followed by
a return instruction with a branch to the entry of the function, creating a
loop. This pass also implements the following extensions to the basic
algorithm:
-#. Trivial instructions between the call and return do not prevent the
+1. Trivial instructions between the call and return do not prevent the
transformation from taking place, though currently the analysis cannot
support moving any really useful instructions (only dead ones).
-#. This pass transforms functions that are prevented from being tail recursive
+1. This pass transforms functions that are prevented from being tail recursive
by an associative expression to use an accumulator variable, thus compiling
the typical naive factorial or fib implementation into efficient code.
-#. TRE is performed if the function returns void, if the return returns the
+1. TRE is performed if the function returns void, if the return returns the
result returned by the call, or if the function returns a run-time constant
on all exits from the function. It is possible, though unlikely, that the
return returns something else (like constant 0), and can still be TRE'd. It
can be TRE'd if *all other* return instructions in the function return the
exact same value.
-#. If it can prove that callees do not access their caller stack frame, they
+1. If it can prove that callees do not access their caller stack frame, they
are marked as eligible for tail call elimination (by the code generator).
-Utility Passes
-==============
+## Utility Passes
This section describes the LLVM Utility Passes.
-``deadarghaX0r``: Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
------------------------------------------------------------------------
+### `deadarghaX0r`: Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
Same as dead argument elimination, but deletes arguments to functions which are
external. This is only for use by `bugpoint`.
-``extract-blocks``: Extract Basic Blocks From Module (for bugpoint use)
------------------------------------------------------------------------
+### `extract-blocks`: Extract Basic Blocks From Module (for bugpoint use)
This pass is used by bugpoint to extract all blocks from the module into their
own functions.
-``instnamer``: Assign names to anonymous instructions
------------------------------------------------------
+### `instnamer`: Assign names to anonymous instructions
This is a little utility pass that gives instructions names, this is mostly
useful when diffing the effect of an optimization because deleting an unnamed
instruction can change all other instruction numbering, making the diff very
noisy.
-.. _passes-verify:
+(passes-verify)=
-``verify``: Module Verifier
----------------------------
+### `verify`: Module Verifier
Verifies LLVM IR code. This is useful to run after an optimization which is
undergoing testing. Note that llvm-as verifies its input before emitting
@@ -1032,77 +931,70 @@ bitcode, and also that malformed bitcode is likely to make LLVM crash. All
language front-ends are therefore encouraged to verify their output before
performing optimizing transformations.
-#. Both of a binary operator's parameters are of the same type.
-#. Verify that the indices of mem access instructions match other operands.
-#. Verify that arithmetic and other things are only performed on first-class
+1. Both of a binary operator's parameters are of the same type.
+1. Verify that the indices of mem access instructions match other operands.
+1. Verify that arithmetic and other things are only performed on first-class
types. Verify that shifts and logicals only happen on integrals f.e.
-#. All of the constants in a switch statement are of the correct type.
-#. The code is in valid SSA form.
-#. It is illegal to put a label into any other type (like a structure) or to
+1. All of the constants in a switch statement are of the correct type.
+1. The code is in valid SSA form.
+1. It is illegal to put a label into any other type (like a structure) or to
return one.
-#. Only phi nodes can be self referential: ``%x = add i32 %x``, ``%x`` is
+1. Only phi nodes can be self referential: `%x = add i32 %x`, `%x` is
invalid.
-#. PHI nodes must have an entry for each predecessor, with no extras.
-#. PHI nodes must be the first thing in a basic block, all grouped together.
-#. PHI nodes must have at least one entry.
-#. All basic blocks should only end with terminator insts, not contain them.
-#. The entry node to a function must not have predecessors.
-#. All Instructions must be embedded into a basic block.
-#. Functions cannot take a void-typed parameter.
-#. Verify that a function's argument list agrees with its declared type.
-#. It is illegal to specify a name for a void value.
-#. It is illegal to have an internal global value with no initializer.
-#. It is illegal to have a ``ret`` instruction that returns a value that does
+1. PHI nodes must have an entry for each predecessor, with no extras.
+1. PHI nodes must be the first thing in a basic block, all grouped together.
+1. PHI nodes must have at least one entry.
+1. All basic blocks should only end with terminator insts, not contain them.
+1. The entry node to a function must not have predecessors.
+1. All Instructions must be embedded into a basic block.
+1. Functions cannot take a void-typed parameter.
+1. Verify that a function's argument list agrees with its declared type.
+1. It is illegal to specify a name for a void value.
+1. It is illegal to have an internal global value with no initializer.
+1. It is illegal to have a `ret` instruction that returns a value that does
not agree with the function return value type.
-#. Function call argument types match the function prototype.
-#. All other things that are tested by asserts spread about the code.
+1. Function call argument types match the function prototype.
+1. All other things that are tested by asserts spread about the code.
Note that this does not provide full security verification (like Java), but
instead just tries to ensure that code is well-formed.
-.. _passes-view-cfg:
+(passes-view-cfg)=
-``view-cfg``: View CFG of function
-----------------------------------
+### `view-cfg`: View CFG of function
Displays the control flow graph using the GraphViz tool.
-Additionally, the ``-cfg-func-name=<substring>`` option can be used to filter the
+Additionally, the `-cfg-func-name=<substring>` option can be used to filter the
functions that are displayed. All functions that contain the specified substring
will be displayed.
-``view-cfg-only``: View CFG of function (with no function bodies)
------------------------------------------------------------------
+### `view-cfg-only`: View CFG of function (with no function bodies)
Displays the control flow graph using the GraphViz tool, but omitting function
bodies.
-Additionally, the ``-cfg-func-name=<substring>`` option can be used to filter the
+Additionally, the `-cfg-func-name=<substring>` option can be used to filter the
functions that are displayed. All functions that contain the specified substring
will be displayed.
-``view-dom``: View dominance tree of function
----------------------------------------------
+### `view-dom`: View dominance tree of function
Displays the dominator tree using the GraphViz tool.
-``view-dom-only``: View dominance tree of function (with no function bodies)
-----------------------------------------------------------------------------
+### `view-dom-only`: View dominance tree of function (with no function bodies)
Displays the dominator tree using the GraphViz tool, but omitting function
bodies.
-``view-post-dom``: View postdominance tree of function
-------------------------------------------------------
+### `view-post-dom`: View postdominance tree of function
Displays the post dominator tree using the GraphViz tool.
-``view-post-dom-only``: View postdominance tree of function (with no function bodies)
--------------------------------------------------------------------------------------
+### `view-post-dom-only`: View postdominance tree of function (with no function bodies)
Displays the post dominator tree using the GraphViz tool, but omitting function
bodies.
-``transform-warning``: Report missed forced transformations
------------------------------------------------------------
+### `transform-warning`: Report missed forced transformations
Emits warnings about not yet applied forced transformations (e.g. from
-``#pragma omp simd``).
+`#pragma omp simd`).
diff --git a/llvm/docs/ProgrammersManual.md b/llvm/docs/ProgrammersManual.md
index ce786a5b7b681..20f3092dba945 100644
--- a/llvm/docs/ProgrammersManual.md
+++ b/llvm/docs/ProgrammersManual.md
@@ -1,17 +1,14 @@
-========================
-LLVM Programmer's Manual
-========================
+# LLVM Programmer's Manual
-.. contents::
- :local:
+```{contents}
+:local:
+```
+````{warning}
+This is always a work in progress.
+````
+(introduction)=
-.. warning::
- This is always a work in progress.
-
-.. _introduction:
-
-Introduction
-============
+## Introduction
This document is meant to highlight some of the important classes and interfaces
available in the LLVM source-base. This manual is not intended to explain what
@@ -23,29 +20,25 @@ This document should get you oriented so that you can find your way in the
continuously growing source code that makes up the LLVM infrastructure. Note
that this manual is not intended to serve as a replacement for reading the
source code, so if you think there should be a method in one of these classes to
-do something, but it's not listed, check the source. Links to the `doxygen
-<https://llvm.org/doxygen/>`__ sources are provided to make this as easy as
+do something, but it's not listed, check the source. Links to the [doxygen](https://llvm.org/doxygen/) sources are provided to make this as easy as
possible.
The first section of this document describes general information that is useful
to know when working in the LLVM infrastructure, and the second describes the
Core LLVM classes. In the future this manual will be extended with information
describing how to use extension libraries, such as dominator information, CFG
-traversal routines, and useful utilities like the ``InstVisitor`` (`doxygen
-<https://llvm.org/doxygen/InstVisitor_8h_source.html>`__) template.
+traversal routines, and useful utilities like the `InstVisitor` ([doxygen](https://llvm.org/doxygen/InstVisitor_8h_source.html)) template.
-.. _general:
+(general)=
-General Information
-===================
+## General Information
This section contains general information that is useful if you are working in
the LLVM source-base, but that isn't specific to any particular API.
-.. _stl:
+(stl)=
-The C++ Standard Template Library
----------------------------------
+### The C++ Standard Template Library
LLVM makes heavy use of the C++ Standard Template Library (STL), perhaps much
more than you are used to, or have seen before. Because of this, you might want
@@ -55,367 +48,335 @@ the subject that you can get, so it will not be discussed in this document.
Here are some useful links:
-#. `cppreference.com
- <https://en.cppreference.com/w/>`_ - an excellent
+1. [cppreference.com](https://en.cppreference.com/w/) - an excellent
reference for the STL and other parts of the standard C++ library.
-#. `cplusplus.com
- <https://cplusplus.com/reference/>`_ - another excellent
+1. [cplusplus.com](https://cplusplus.com/reference/) - another excellent
reference like the one above.
-#. `C++ In a Nutshell <http://www.tempest-sw.com/cpp/>`_ - This is an O'Reilly
+1. [C++ In a Nutshell](http://www.tempest-sw.com/cpp/) - This is an O'Reilly
book in the making. It has a decent Standard Library Reference that rivals
Dinkumware's, and is unfortunately no longer free since the book has been
published.
-#. `C++ Frequently Asked Questions <https://www.parashift.com/c++-faq-lite/>`_.
+1. [C++ Frequently Asked Questions](https://www.parashift.com/c++-faq-lite/).
-#. `Bjarne Stroustrup's C++ Page
- <https://www.stroustrup.com/C++.html>`_.
+1. [Bjarne Stroustrup's C++ Page](https://www.stroustrup.com/C++.html).
-#. `Bruce Eckel's Thinking in C++, 2nd ed. Volume 2.
- (even better, get the book)
- <https://archive.org/details/TICPP2ndEdVolTwo>`_.
+1. [Bruce Eckel's Thinking in C++, 2nd ed. Volume 2. (even better, get the book)](https://archive.org/details/TICPP2ndEdVolTwo).
-You are also encouraged to take a look at the :doc:`LLVM Coding Standards
-<CodingStandards>` guide which focuses on how to write maintainable code more
+You are also encouraged to take a look at the {doc}`LLVM Coding Standards <CodingStandards>` guide which focuses on how to write maintainable code more
than where to put your curly braces.
-.. _resources:
+(resources)=
-Other useful references
------------------------
+### Other useful references
-#. `Using static and shared libraries across platforms
- <http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html>`_
+1. [Using static and shared libraries across platforms](http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html)
-.. _apis:
+(apis)=
-Important and useful LLVM APIs
-==============================
+## Important and useful LLVM APIs
Here we highlight some LLVM APIs that are generally useful and good to know
about when writing transformations.
-.. _isa:
+(isa)=
-The ``isa<>``, ``cast<>`` and ``dyn_cast<>`` templates
-------------------------------------------------------
+### The `isa<>`, `cast<>` and `dyn_cast<>` templates
The LLVM source-base makes extensive use of a custom form of RTTI. These
-templates have many similarities to the C++ ``dynamic_cast<>`` operator, but
+templates have many similarities to the C++ `dynamic_cast<>` operator, but
they don't have some drawbacks (primarily stemming from the fact that
-``dynamic_cast<>`` only works on classes that have a v-table). Because they are
+`dynamic_cast<>` only works on classes that have a v-table). Because they are
used so often, you must know what they do and how they work. All of these
-templates are defined in the ``llvm/Support/Casting.h`` (`doxygen
-<https://llvm.org/doxygen/Casting_8h_source.html>`__) file (note that you very
+templates are defined in the `llvm/Support/Casting.h` ([doxygen](https://llvm.org/doxygen/Casting_8h_source.html)) file (note that you very
rarely have to include this file directly).
-``isa<>``:
- The ``isa<>`` operator works exactly like the Java "``instanceof``" operator.
- It returns ``true`` or ``false`` depending on whether a reference or pointer points to
+`isa<>`:
+ The `isa<>` operator works exactly like the Java "`instanceof`" operator.
+ It returns `true` or `false` depending on whether a reference or pointer points to
an instance of the specified class. This can be very useful for constraint
checking of various sorts (example below). It's a variadic operator, so you
can specify more than one class to check if the reference or pointer points
to an instance of one of the classes specified.
-``cast<>``:
- The ``cast<>`` operator is a "checked cast" operation. It converts a pointer
+`cast<>`:
+ The `cast<>` operator is a "checked cast" operation. It converts a pointer
or reference from a base class to a derived class, causing an assertion
failure if it is not really an instance of the right type. This should be
used in cases where you have some information that makes you believe that
- something is of the right type. An example of the ``isa<>`` and ``cast<>``
+ something is of the right type. An example of the `isa<>` and `cast<>`
template is:
- .. code-block:: c++
-
- static bool isLoopInvariant(const Value *V, const Loop *L) {
- if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
- return true;
+ ```cpp
+ static bool isLoopInvariant(const Value *V, const Loop *L) {
+ if (isa<Constant>(V) || isa<Argument>(V) || isa<GlobalValue>(V))
+ return true;
- // Alternate, more compact form.
- if (isa<Constant, Argument, GlobalValue>(V))
- return true;
+ // Alternate, more compact form.
+ if (isa<Constant, Argument, GlobalValue>(V))
+ return true;
- // Otherwise, it must be an instruction.
- return !L->contains(cast<Instruction>(V)->getParent());
- }
-
- Note that you should **not** use an ``isa<>`` test followed by a ``cast<>``;
- for that use the ``dyn_cast<>`` operator.
+ // Otherwise, it must be an instruction.
+ return !L->contains(cast<Instruction>(V)->getParent());
+ }
+ ```
+ Note that you should **not** use an `isa<>` test followed by a `cast<>`;
+ for that use the `dyn_cast<>` operator.
-``dyn_cast<>``:
- The ``dyn_cast<>`` operator is a "checking cast" operation. It checks to see
+`dyn_cast<>`:
+ The `dyn_cast<>` operator is a "checking cast" operation. It checks to see
if the operand is of the specified type, and if so, returns a pointer to it
(this operator does not work with references). If the operand is not of the
correct type, a null pointer is returned. Thus, this works very much like
- the ``dynamic_cast<>`` operator in C++, and should be used in the same
- circumstances. Typically, the ``dyn_cast<>`` operator is used in an ``if``
+ the `dynamic_cast<>` operator in C++, and should be used in the same
+ circumstances. Typically, the `dyn_cast<>` operator is used in an `if`
statement or some other flow control statement like this:
- .. code-block:: c++
-
- if (auto *AI = dyn_cast<AllocationInst>(Val)) {
- // ...
- }
-
- This form of the ``if`` statement effectively combines together a call to
- ``isa<>`` and a call to ``cast<>`` into one statement, which is very
+ ```cpp
+ if (auto *AI = dyn_cast<AllocationInst>(Val)) {
+ // ...
+ }
+ ```
+ This form of the `if` statement effectively combines together a call to
+ `isa<>` and a call to `cast<>` into one statement, which is very
convenient.
- Note that the ``dyn_cast<>`` operator, like C++'s ``dynamic_cast<>`` or Java's
- ``instanceof`` operator, can be abused. In particular, you should not use big
- chained ``if/then/else`` blocks to check for lots of different variants of
+ Note that the `dyn_cast<>` operator, like C++'s `dynamic_cast<>` or Java's
+ `instanceof` operator, can be abused. In particular, you should not use big
+ chained `if/then/else` blocks to check for lots of different variants of
classes. If you find yourself wanting to do this, it is much cleaner and more
- efficient to use the ``InstVisitor`` class to dispatch over the instruction
+ efficient to use the `InstVisitor` class to dispatch over the instruction
type directly.
-``isa_and_present<>``:
- The ``isa_and_present<>`` operator works just like the ``isa<>`` operator,
+`isa_and_present<>`:
+ The `isa_and_present<>` operator works just like the `isa<>` operator,
except that it allows for a null pointer as an argument (which it then
- returns ``false``). This can sometimes be useful, allowing you to combine
- several null checks into one. Similar to ``isa<>`` operator, you can specify
+ returns `false`). This can sometimes be useful, allowing you to combine
+ several null checks into one. Similar to `isa<>` operator, you can specify
more than one class to check.
-``cast_if_present<>``:
- The ``cast_if_present<>`` operator works just like the ``cast<>`` operator,
+`cast_if_present<>`:
+ The `cast_if_present<>` operator works just like the `cast<>` operator,
except that it allows for a null pointer as an argument (which it then
propagates). This can sometimes be useful, allowing you to combine several
null checks into one.
-``dyn_cast_if_present<>``:
- The ``dyn_cast_if_present<>`` operator works just like the ``dyn_cast<>``
+`dyn_cast_if_present<>`:
+ The `dyn_cast_if_present<>` operator works just like the `dyn_cast<>`
operator, except that it allows for a null pointer as an argument (which it
then propagates). This can sometimes be useful, allowing you to combine
several null checks into one.
These five templates can be used with any classes, whether they have a v-table
or not. If you want to add support for these templates, see the document
-:doc:`How to set up LLVM-style RTTI for your class hierarchy
-<HowToSetUpLLVMStyleRTTI>`
+{doc}`How to set up LLVM-style RTTI for your class hierarchy <HowToSetUpLLVMStyleRTTI>`
-.. _string_apis:
+(string_apis)=
-Passing strings (the ``StringRef`` and ``Twine`` classes)
----------------------------------------------------------
+### Passing strings (the `StringRef` and `Twine` classes)
Although LLVM generally does not do much string manipulation, we do have several
important APIs which take strings. Two important examples are the Value class
--- which has names for instructions, functions, etc. -- and the ``StringMap``
+-- which has names for instructions, functions, etc. -- and the `StringMap`
class which is used extensively in LLVM and Clang.
These are generic classes, and they need to be able to accept strings which may
-have embedded null characters. Therefore, they cannot simply take a ``const
-char *``, and taking a ``const std::string&`` requires clients to perform a heap
+have embedded null characters. Therefore, they cannot simply take a `const
+char *`, and taking a `const std::string&` requires clients to perform a heap
allocation which is usually unnecessary. Instead, many LLVM APIs use a
-``StringRef`` or a ``const Twine&`` for passing strings efficiently.
+`StringRef` or a `const Twine&` for passing strings efficiently.
-.. _StringRef:
+(StringRef)=
-The ``StringRef`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `StringRef` class
-The ``StringRef`` data type represents a reference to a constant string (a
+The `StringRef` data type represents a reference to a constant string (a
character array and a length) and supports the common operations available on
-``std::string``, but does not require heap allocation.
+`std::string`, but does not require heap allocation.
It can be implicitly constructed using a C style null-terminated string, an
-``std::string``, or explicitly with a character pointer and length. For
-example, the ``StringMap`` find function is declared as:
-
-.. code-block:: c++
-
- iterator find(StringRef Key);
+`std::string`, or explicitly with a character pointer and length. For
+example, the `StringMap` find function is declared as:
+```cpp
+iterator find(StringRef Key);
+```
and clients can call it using any one of:
-.. code-block:: c++
-
- Map.find("foo"); // Lookup "foo"
- Map.find(std::string("bar")); // Lookup "bar"
- Map.find(StringRef("\0baz", 4)); // Lookup "\0baz"
-
-Similarly, APIs which need to return a string may return a ``StringRef``
-instance, which can be used directly or converted to an ``std::string`` using
-the ``str`` member function. See ``llvm/ADT/StringRef.h`` (`doxygen
-<https://llvm.org/doxygen/StringRef_8h_source.html>`__) for more
+```cpp
+Map.find("foo"); // Lookup "foo"
+Map.find(std::string("bar")); // Lookup "bar"
+Map.find(StringRef("\0baz", 4)); // Lookup "\0baz"
+```
+Similarly, APIs which need to return a string may return a `StringRef`
+instance, which can be used directly or converted to an `std::string` using
+the `str` member function. See `llvm/ADT/StringRef.h` ([doxygen](https://llvm.org/doxygen/StringRef_8h_source.html)) for more
information.
-You should rarely use the ``StringRef`` class directly. Because it contains
+You should rarely use the `StringRef` class directly. Because it contains
pointers to external memory, it is not generally safe to store an instance of the
class (unless you know that the external storage will not be freed).
-``StringRef`` is small and pervasive enough in LLVM that it should always be
+`StringRef` is small and pervasive enough in LLVM that it should always be
passed by value.
-The ``Twine`` class
-^^^^^^^^^^^^^^^^^^^
+#### The `Twine` class
-The ``Twine`` (`doxygen <https://llvm.org/doxygen/classllvm_1_1Twine.html>`__)
+The `Twine` ([doxygen](https://llvm.org/doxygen/classllvm_1_1Twine.html))
class is an efficient way for APIs to accept concatenated strings. For example,
a common LLVM paradigm is to name one instruction based on the name of another
instruction with a suffix, for example:
-.. code-block:: c++
-
- New = CmpInst::Create(..., SO->getName() + ".cmp");
-
-The ``Twine`` class is effectively a lightweight `rope
-<http://en.wikipedia.org/wiki/Rope_(computer_science)>`_ which points to
+```cpp
+New = CmpInst::Create(..., SO->getName() + ".cmp");
+```
+The `Twine` class is effectively a lightweight [rope](http://en.wikipedia.org/wiki/Rope_(computer_science)) which points to
temporary (stack allocated) objects. Twines can be implicitly constructed as
the result of the plus operator applied to strings (i.e., a C strings, an
-``std::string``, or a ``StringRef``). The twine delays the actual concatenation
+`std::string`, or a `StringRef`). The twine delays the actual concatenation
of strings until it is actually required, at which point it can be efficiently
rendered directly into a character array. This avoids unnecessary heap
allocation involved in constructing the temporary results of string
-concatenation. See ``llvm/ADT/Twine.h`` (`doxygen
-<https://llvm.org/doxygen/Twine_8h_source.html>`__) and :ref:`here <dss_twine>`
+concatenation. See `llvm/ADT/Twine.h` ([doxygen](https://llvm.org/doxygen/Twine_8h_source.html)) and {ref}`here <dss_twine>`
for more information.
-As with a ``StringRef``, ``Twine`` objects point to external memory and should
+As with a `StringRef`, `Twine` objects point to external memory and should
almost never be stored or mentioned directly. They are intended solely for use
when defining a function which should be able to efficiently accept concatenated
strings.
-.. _formatting_strings:
+(formatting_strings)=
-Formatting strings (the ``formatv`` function)
----------------------------------------------
+### Formatting strings (the `formatv` function)
While LLVM doesn't necessarily do a lot of string manipulation and parsing, it
does do a lot of string formatting. From diagnostic messages, to llvm tool
-outputs such as ``llvm-readobj`` to printing verbose disassembly listings and
+outputs such as `llvm-readobj` to printing verbose disassembly listings and
LLDB runtime logging, the need for string formatting is pervasive.
-The ``formatv`` is similar in spirit to ``printf``, but uses a different syntax
-which borrows heavily from Python and C#. Unlike ``printf`` it deduces the type
+The `formatv` is similar in spirit to `printf`, but uses a different syntax
+which borrows heavily from Python and C#. Unlike `printf` it deduces the type
to be formatted at compile time, so it does not need a format specifier such as
-``%d``. This reduces the mental overhead of trying to construct portable format
-strings, especially for platform-specific types like ``size_t`` or pointer types.
-Unlike both ``printf`` and Python, it additionally fails to compile if LLVM does
+`%d`. This reduces the mental overhead of trying to construct portable format
+strings, especially for platform-specific types like `size_t` or pointer types.
+Unlike both `printf` and Python, it additionally fails to compile if LLVM does
not know how to format the type. These two properties ensure that the function
is both safer and simpler to use than traditional formatting methods such as
-the ``printf`` family of functions.
+the `printf` family of functions.
-Simple formatting
-^^^^^^^^^^^^^^^^^
+#### Simple formatting
-A call to ``formatv`` involves a single **format string** consisting of 0 or more
+A call to `formatv` involves a single **format string** consisting of 0 or more
**replacement sequences**, followed by a variable length list of **replacement values**.
-A replacement sequence is a string of the form ``{N[[,align]:style]}``.
+A replacement sequence is a string of the form `{N[[,align]:style]}`.
-``N`` refers to the 0-based index of the argument from the list of replacement
+`N` refers to the 0-based index of the argument from the list of replacement
values. Note that this means it is possible to reference the same parameter
multiple times, possibly with different style and/or alignment options, in any order.
-``align`` is an optional string specifying the width of the field to format
+`align` is an optional string specifying the width of the field to format
the value into, and the alignment of the value within the field. It is specified as
an optional **alignment style** followed by a positive integral **field width**. The
-alignment style can be one of the characters ``-`` (left align), ``=`` (center align),
-or ``+`` (right align). The default is right aligned.
+alignment style can be one of the characters `-` (left align), `=` (center align),
+or `+` (right align). The default is right aligned.
-``style`` is an optional string consisting of a type specific that controls the
+`style` is an optional string consisting of a type specific that controls the
formatting of the value. For example, to format a floating point value as a percentage,
-you can use the style option ``P``.
+you can use the style option `P`.
-Custom formatting
-^^^^^^^^^^^^^^^^^
+#### Custom formatting
There are two ways to customize the formatting behavior for a type.
-1. Provide a template specialization of ``llvm::format_provider<T>`` for your
- type ``T`` with the appropriate static format method.
+1. Provide a template specialization of `llvm::format_provider<T>` for your
+ type `T` with the appropriate static format method.
- .. code-block:: c++
-
- namespace llvm {
- template<>
- struct format_provider<MyFooBar> {
- static void format(const MyFooBar &V, raw_ostream &Stream, StringRef Style) {
- // Do whatever is necessary to format `V` into `Stream`
- }
- };
- void foo() {
- MyFooBar X;
- std::string S = formatv("{0}", X);
+ ```cpp
+ namespace llvm {
+ template<>
+ struct format_provider<MyFooBar> {
+ static void format(const MyFooBar &V, raw_ostream &Stream, StringRef Style) {
+ // Do whatever is necessary to format `V` into `Stream`
}
+ };
+ void foo() {
+ MyFooBar X;
+ std::string S = formatv("{0}", X);
}
-
+ }
+ ```
This is a useful extensibility mechanism for adding support for formatting your own
custom types with your own custom Style options. But it does not help when you want
to extend the mechanism for formatting a type that the library already knows how to
format. For that, we need something else.
-2. Provide a **format adapter** inheriting from ``llvm::FormatAdapter<T>``.
-
- .. code-block:: c++
+2. Provide a **format adapter** inheriting from `llvm::FormatAdapter<T>`.
- namespace anything {
- struct format_int_custom : public llvm::FormatAdapter<int> {
- explicit format_int_custom(int N) : llvm::FormatAdapter<int>(N) {}
- void format(llvm::raw_ostream &Stream, StringRef Style) override {
- // Do whatever is necessary to format ``this->Item`` into ``Stream``
- }
- };
- }
- namespace llvm {
- void foo() {
- std::string S = formatv("{0}", anything::format_int_custom(42));
+ ```cpp
+ namespace anything {
+ struct format_int_custom : public llvm::FormatAdapter<int> {
+ explicit format_int_custom(int N) : llvm::FormatAdapter<int>(N) {}
+ void format(llvm::raw_ostream &Stream, StringRef Style) override {
+ // Do whatever is necessary to format ``this->Item`` into ``Stream``
}
+ };
+ }
+ namespace llvm {
+ void foo() {
+ std::string S = formatv("{0}", anything::format_int_custom(42));
}
-
- If the type is detected to be derived from ``FormatAdapter<T>``, ``formatv``
+ }
+ ```
+ If the type is detected to be derived from `FormatAdapter<T>`, `formatv`
will call the
- ``format`` method on the argument passing in the specified style. This allows
+ `format` method on the argument passing in the specified style. This allows
one to provide custom formatting of any type, including one which already has
a builtin format provider.
-``formatv`` Examples
-^^^^^^^^^^^^^^^^^^^^
+#### `formatv` Examples
Below is intended to provide an incomplete set of examples demonstrating
-the usage of ``formatv``. More information can be found by reading the
+the usage of `formatv`. More information can be found by reading the
doxygen documentation or by looking at the unit test suite.
-.. code-block:: c++
-
- std::string S;
- // Simple formatting of basic types and implicit string conversion.
- S = formatv("{0} ({1:P})", 7, 0.35); // S == "7 (35.00%)"
+```cpp
+std::string S;
+// Simple formatting of basic types and implicit string conversion.
+S = formatv("{0} ({1:P})", 7, 0.35); // S == "7 (35.00%)"
- // Out-of-order referencing and multi-referencing
- outs() << formatv("{0} {2} {1} {0}", 1, "test", 3); // prints "1 3 test 1"
+// Out-of-order referencing and multi-referencing
+outs() << formatv("{0} {2} {1} {0}", 1, "test", 3); // prints "1 3 test 1"
- // Left, right, and center alignment
- S = formatv("{0,7}", 'a'); // S == " a";
- S = formatv("{0,-7}", 'a'); // S == "a ";
- S = formatv("{0,=7}", 'a'); // S == " a ";
- S = formatv("{0,+7}", 'a'); // S == " a";
+// Left, right, and center alignment
+S = formatv("{0,7}", 'a'); // S == " a";
+S = formatv("{0,-7}", 'a'); // S == "a ";
+S = formatv("{0,=7}", 'a'); // S == " a ";
+S = formatv("{0,+7}", 'a'); // S == " a";
- // Custom styles
- S = formatv("{0:N} - {0:x} - {1:E}", 12345, 123908342); // S == "12,345 - 0x3039 - 1.24E8"
+// Custom styles
+S = formatv("{0:N} - {0:x} - {1:E}", 12345, 123908342); // S == "12,345 - 0x3039 - 1.24E8"
- // Adapters
- S = formatv("{0}", fmt_align(42, AlignStyle::Center, 7)); // S == " 42 "
- S = formatv("{0}", fmt_repeat("hi", 3)); // S == "hihihi"
- S = formatv("{0}", fmt_pad("hi", 2, 6)); // S == " hi "
+// Adapters
+S = formatv("{0}", fmt_align(42, AlignStyle::Center, 7)); // S == " 42 "
+S = formatv("{0}", fmt_repeat("hi", 3)); // S == "hihihi"
+S = formatv("{0}", fmt_pad("hi", 2, 6)); // S == " hi "
- // Ranges
- std::vector<int> V = {8, 9, 10};
- S = formatv("{0}", make_range(V.begin(), V.end())); // S == "8, 9, 10"
- S = formatv("{0:$[+]}", make_range(V.begin(), V.end())); // S == "8+9+10"
- S = formatv("{0:$[ + ]@[x]}", make_range(V.begin(), V.end())); // S == "0x8 + 0x9 + 0xA"
+// Ranges
+std::vector<int> V = {8, 9, 10};
+S = formatv("{0}", make_range(V.begin(), V.end())); // S == "8, 9, 10"
+S = formatv("{0:$[+]}", make_range(V.begin(), V.end())); // S == "8+9+10"
+S = formatv("{0:$[ + ]@[x]}", make_range(V.begin(), V.end())); // S == "0x8 + 0x9 + 0xA"
+```
+(error_apis)=
-.. _error_apis:
-
-Error handling
---------------
+### Error handling
Proper error handling helps us identify bugs in our code, and helps end users
understand errors in their tool usage. Errors fall into two broad categories:
*programmatic* and *recoverable*, with different strategies for handling and
reporting.
-Programmatic Errors
-^^^^^^^^^^^^^^^^^^^
+#### Programmatic Errors
Programmatic errors are violations of program invariants or API contracts, and
represent bugs within the program itself. Our aim is to document invariants, and
@@ -423,47 +384,42 @@ to abort quickly at the point of failure (providing some basic diagnostic) when
invariants are broken at runtime.
The fundamental tools for handling programmatic errors are assertions and the
-``llvm_unreachable`` function. Assertions are used to express invariant conditions,
+`llvm_unreachable` function. Assertions are used to express invariant conditions,
and should include a message describing the invariant:
-.. code-block:: c++
-
- assert(isPhysReg(R) && "All virt regs should have been allocated already.");
-
-The ``llvm_unreachable`` function can be used to document areas of control flow
+```cpp
+assert(isPhysReg(R) && "All virt regs should have been allocated already.");
+```
+The `llvm_unreachable` function can be used to document areas of control flow
that should never be entered if the program invariants hold:
-.. code-block:: c++
-
- enum { Foo, Bar, Baz } X = foo();
-
- switch (X) {
- case Foo: /* Handle Foo */; break;
- case Bar: /* Handle Bar */; break;
- default:
- llvm_unreachable("X should be Foo or Bar here");
- }
-
-Additionally, ``reportFatalInternalError`` can be used to report invariant
+```cpp
+enum { Foo, Bar, Baz } X = foo();
+
+switch (X) {
+ case Foo: /* Handle Foo */; break;
+ case Bar: /* Handle Bar */; break;
+ default:
+ llvm_unreachable("X should be Foo or Bar here");
+}
+```
+Additionally, `reportFatalInternalError` can be used to report invariant
violations even in builds that do not enable assertions:
-.. code-block:: c++
-
- if (VerifyFooAnalysis && !Foo.verify()) {
- reportFatalInternalError("Analysis 'foo' not preserved");
- }
-
-Additionally, ``checkNotNull`` can be used to check/document that a pointer
+```cpp
+if (VerifyFooAnalysis && !Foo.verify()) {
+ reportFatalInternalError("Analysis 'foo' not preserved");
+}
+```
+Additionally, `checkNotNull` can be used to check/document that a pointer
is never supposed to be null inline.
-.. code-block:: c++
-
- setMyPointer("key", Pointer);
- // [...]
- Type *P = checkNotNull(getMyPointer("key"));
-
-Recoverable Errors
-^^^^^^^^^^^^^^^^^^
+```cpp
+setMyPointer("key", Pointer);
+// [...]
+Type *P = checkNotNull(getMyPointer("key"));
+```
+#### Recoverable Errors
Recoverable errors represent an error in the program's environment, for example,
a resource failure (a missing file, a dropped network connection, etc.), or
@@ -472,169 +428,161 @@ the program that can handle them appropriately. Handling the error may be
as simple as reporting the issue to the user, or it may involve attempts at
recovery.
-.. note::
-
- While it would be ideal to use this error handling scheme throughout
- LLVM, there are places where this hasn't been practical to apply. In
- situations where you absolutely must emit a non-programmatic error and
- the ``Error`` model isn't workable you can call ``reportFatalUsageError``,
- which will call installed error handlers, print a message, and exit the
- program. The use of ``reportFatalUsageError`` in this case is discouraged.
-
-Recoverable errors are modeled using LLVM's ``Error`` scheme. This scheme
+````{note}
+While it would be ideal to use this error handling scheme throughout
+LLVM, there are places where this hasn't been practical to apply. In
+situations where you absolutely must emit a non-programmatic error and
+the `Error` model isn't workable you can call `reportFatalUsageError`,
+which will call installed error handlers, print a message, and exit the
+program. The use of `reportFatalUsageError` in this case is discouraged.
+````
+Recoverable errors are modeled using LLVM's `Error` scheme. This scheme
represents errors using function return values, similar to classic C integer
-error codes, or C++'s ``std::error_code``. However, the ``Error`` class is
+error codes, or C++'s `std::error_code`. However, the `Error` class is
actually a lightweight wrapper for user-defined error types, allowing arbitrary
information to be attached to describe the error. This is similar to the way C++
exceptions allow throwing of user-defined types.
-Success values are created by calling ``Error::success()``, E.g.:
-
-.. code-block:: c++
-
- Error foo() {
- // Do something.
- // Return success.
- return Error::success();
- }
+Success values are created by calling `Error::success()`, E.g.:
+```cpp
+Error foo() {
+ // Do something.
+ // Return success.
+ return Error::success();
+}
+```
Success values are very cheap to construct and return - they have minimal
impact on program performance.
-Failure values are constructed using ``make_error<T>``, where ``T`` is any class
-that inherits from the ``ErrorInfo`` utility, E.g.:
-
-.. code-block:: c++
+Failure values are constructed using `make_error<T>`, where `T` is any class
+that inherits from the `ErrorInfo` utility, E.g.:
- class BadFileFormat : public ErrorInfo<BadFileFormat> {
- public:
- static char ID;
- std::string Path;
-
- BadFileFormat(StringRef Path) : Path(Path.str()) {}
+```cpp
+class BadFileFormat : public ErrorInfo<BadFileFormat> {
+public:
+ static char ID;
+ std::string Path;
- void log(raw_ostream &OS) const override {
- OS << Path << " is malformed";
- }
+ BadFileFormat(StringRef Path) : Path(Path.str()) {}
- std::error_code convertToErrorCode() const override {
- return make_error_code(object_error::parse_failed);
- }
- };
-
- char BadFileFormat::ID; // This should be declared in the C++ file.
+ void log(raw_ostream &OS) const override {
+ OS << Path << " is malformed";
+ }
- Error printFormattedFile(StringRef Path) {
- if (<check for valid format>)
- return make_error<BadFileFormat>(Path);
- // print file contents.
- return Error::success();
+ std::error_code convertToErrorCode() const override {
+ return make_error_code(object_error::parse_failed);
}
+};
+
+char BadFileFormat::ID; // This should be declared in the C++ file.
+Error printFormattedFile(StringRef Path) {
+ if (<check for valid format>)
+ return make_error<BadFileFormat>(Path);
+ // print file contents.
+ return Error::success();
+}
+```
Error values can be implicitly converted to bool: true for error, false for
success, enabling the following idiom:
-.. code-block:: c++
+```cpp
+Error mayFail();
- Error mayFail();
-
- Error foo() {
- if (auto Err = mayFail())
- return Err;
- // Success! We can proceed.
- ...
-
-For functions that can fail but need to return a value the ``Expected<T>``
+Error foo() {
+ if (auto Err = mayFail())
+ return Err;
+ // Success! We can proceed.
+ ...
+```
+For functions that can fail but need to return a value the `Expected<T>`
utility can be used. Values of this type can be constructed with either a
-``T``, or an ``Error``. Expected<T> values are also implicitly convertible to
-boolean, but with the opposite convention to ``Error``: true for success, false
-for error. If success, the ``T`` value can be accessed via the dereference
-operator. If failure, the ``Error`` value can be extracted using the
-``takeError()`` method. Idiomatic usage looks like:
-
-.. code-block:: c++
-
- Expected<FormattedFile> openFormattedFile(StringRef Path) {
- // If badly formatted, return an error.
- if (auto Err = checkFormat(Path))
- return std::move(Err);
- // Otherwise return a FormattedFile instance.
- return FormattedFile(Path);
- }
-
- Error processFormattedFile(StringRef Path) {
- // Try to open a formatted file
- if (auto FileOrErr = openFormattedFile(Path)) {
- // On success, grab a reference to the file and continue.
- auto &File = *FileOrErr;
- ...
- } else
- // On error, extract the Error value and return it.
- return FileOrErr.takeError();
- }
-
-If an ``Expected<T>`` value is in success mode then the ``takeError()`` method
-will return a success value. Using this fact, the above function can be
-rewritten as:
-
-.. code-block:: c++
-
- Error processFormattedFile(StringRef Path) {
- // Try to open a formatted file
- auto FileOrErr = openFormattedFile(Path);
- if (auto Err = FileOrErr.takeError())
- // On error, extract the Error value and return it.
- return Err;
+`T`, or an `Error`. Expected<T> values are also implicitly convertible to
+boolean, but with the opposite convention to `Error`: true for success, false
+for error. If success, the `T` value can be accessed via the dereference
+operator. If failure, the `Error` value can be extracted using the
+`takeError()` method. Idiomatic usage looks like:
+
+```cpp
+Expected<FormattedFile> openFormattedFile(StringRef Path) {
+ // If badly formatted, return an error.
+ if (auto Err = checkFormat(Path))
+ return std::move(Err);
+ // Otherwise return a FormattedFile instance.
+ return FormattedFile(Path);
+}
+
+Error processFormattedFile(StringRef Path) {
+ // Try to open a formatted file
+ if (auto FileOrErr = openFormattedFile(Path)) {
// On success, grab a reference to the file and continue.
auto &File = *FileOrErr;
...
- }
+ } else
+ // On error, extract the Error value and return it.
+ return FileOrErr.takeError();
+}
+```
+If an `Expected<T>` value is in success mode then the `takeError()` method
+will return a success value. Using this fact, the above function can be
+rewritten as:
+```cpp
+Error processFormattedFile(StringRef Path) {
+ // Try to open a formatted file
+ auto FileOrErr = openFormattedFile(Path);
+ if (auto Err = FileOrErr.takeError())
+ // On error, extract the Error value and return it.
+ return Err;
+ // On success, grab a reference to the file and continue.
+ auto &File = *FileOrErr;
+ ...
+}
+```
This second form is often more readable for functions that involve multiple
-``Expected<T>`` values as it limits the indentation required.
+`Expected<T>` values as it limits the indentation required.
-If an ``Expected<T>`` value will be moved into an existing variable then the
-``moveInto()`` method avoids the need to name an extra variable. This is
-useful to enable ``operator->()`` if the ``Expected<T>`` value has pointer-like
+If an `Expected<T>` value will be moved into an existing variable then the
+`moveInto()` method avoids the need to name an extra variable. This is
+useful to enable `operator->()` if the `Expected<T>` value has pointer-like
semantics. For example:
-.. code-block:: c++
-
- Expected<std::unique_ptr<MemoryBuffer>> openBuffer(StringRef Path);
- Error processBuffer(StringRef Buffer);
+```cpp
+Expected<std::unique_ptr<MemoryBuffer>> openBuffer(StringRef Path);
+Error processBuffer(StringRef Buffer);
- Error processBufferAtPath(StringRef Path) {
- // Try to open a buffer.
- std::unique_ptr<MemoryBuffer> MB;
- if (auto Err = openBuffer(Path).moveInto(MB))
+Error processBufferAtPath(StringRef Path) {
+ // Try to open a buffer.
+ std::unique_ptr<MemoryBuffer> MB;
+ if (auto Err = openBuffer(Path).moveInto(MB))
+ // On error, return the Error value.
+ return Err;
+ // On success, use MB.
+ return processBuffer(MB->getBuffer());
+}
+```
+This third form works with any type that can be assigned to from `T&&`. This
+can be useful if the `Expected<T>` value needs to be stored in an already-declared
+`std::optional<T>`. For example:
+
+```cpp
+Expected<StringRef> extractClassName(StringRef Definition);
+struct ClassData {
+ StringRef Definition;
+ std::optional<StringRef> LazyName;
+ ...
+ Error initialize() {
+ if (auto Err = extractClassName(Path).moveInto(LazyName))
// On error, return the Error value.
return Err;
- // On success, use MB.
- return processBuffer(MB->getBuffer());
- }
-
-This third form works with any type that can be assigned to from ``T&&``. This
-can be useful if the ``Expected<T>`` value needs to be stored in an already-declared
-``std::optional<T>``. For example:
-
-.. code-block:: c++
-
- Expected<StringRef> extractClassName(StringRef Definition);
- struct ClassData {
- StringRef Definition;
- std::optional<StringRef> LazyName;
+ // On success, LazyName has been initialized.
...
- Error initialize() {
- if (auto Err = extractClassName(Path).moveInto(LazyName))
- // On error, return the Error value.
- return Err;
- // On success, LazyName has been initialized.
- ...
- }
- };
-
-All ``Error`` instances, whether success or failure, must be either checked or
-moved from (via ``std::move`` or a return) before they are destructed.
+ }
+};
+```
+All `Error` instances, whether success or failure, must be either checked or
+moved from (via `std::move` or a return) before they are destructed.
Accidentally discarding an unchecked error will cause a program to abort at the
point where the unchecked value's destructor is run, making it easy to identify
and fix violations of this rule.
@@ -642,525 +590,487 @@ and fix violations of this rule.
Success values are considered checked once they have been tested (by invoking
the boolean conversion operator):
-.. code-block:: c++
-
- if (auto Err = mayFail(...))
- return Err; // Failure value - move error to caller.
+```cpp
+if (auto Err = mayFail(...))
+ return Err; // Failure value - move error to caller.
- // Safe to continue: Err was checked.
-
-In contrast, the following code will always cause an abort, even if ``mayFail``
+// Safe to continue: Err was checked.
+```
+In contrast, the following code will always cause an abort, even if `mayFail`
returns a success value:
-.. code-block:: c++
-
- mayFail();
- // Program will always abort here, even if mayFail() returns Success, since
- // the value is not checked.
-
+```cpp
+mayFail();
+// Program will always abort here, even if mayFail() returns Success, since
+// the value is not checked.
+```
Failure values are considered checked once a handler for the error type has
been activated:
-.. code-block:: c++
-
- handleErrors(
- processFormattedFile(...),
- [](const BadFileFormat &BFF) {
- report("Unable to process " + BFF.Path + ": bad format");
- },
- [](const FileNotFound &FNF) {
- report("File not found " + FNF.Path);
- });
-
-The ``handleErrors`` function takes an error as its first argument, followed by
+```cpp
+handleErrors(
+ processFormattedFile(...),
+ [](const BadFileFormat &BFF) {
+ report("Unable to process " + BFF.Path + ": bad format");
+ },
+ [](const FileNotFound &FNF) {
+ report("File not found " + FNF.Path);
+ });
+```
+The `handleErrors` function takes an error as its first argument, followed by
a variadic list of "handlers", each of which must be a callable type (a
function, lambda, or class with a call operator) with one argument. The
-``handleErrors`` function will visit each handler in the sequence and check its
+`handleErrors` function will visit each handler in the sequence and check its
argument type against the dynamic type of the error, running the first handler
that matches. This is the same decision process that is used to decide which catch
clause to run for a C++ exception.
-Since the list of handlers passed to ``handleErrors`` may not cover every error
-type that can occur, the ``handleErrors`` function also returns an Error value
+Since the list of handlers passed to `handleErrors` may not cover every error
+type that can occur, the `handleErrors` function also returns an Error value
that must be checked or propagated. If the error value that is passed to
-``handleErrors`` does not match any of the handlers it will be returned from
-``handleErrors``. Idiomatic use of ``handleErrors`` thus looks like:
-
-.. code-block:: c++
-
- if (auto Err =
- handleErrors(
- processFormattedFile(...),
- [](const BadFileFormat &BFF) {
- report("Unable to process " + BFF.Path + ": bad format");
- },
- [](const FileNotFound &FNF) {
- report("File not found " + FNF.Path);
- }))
- return Err;
-
+`handleErrors` does not match any of the handlers it will be returned from
+`handleErrors`. Idiomatic use of `handleErrors` thus looks like:
+
+```cpp
+if (auto Err =
+ handleErrors(
+ processFormattedFile(...),
+ [](const BadFileFormat &BFF) {
+ report("Unable to process " + BFF.Path + ": bad format");
+ },
+ [](const FileNotFound &FNF) {
+ report("File not found " + FNF.Path);
+ }))
+ return Err;
+```
In cases where you truly know that the handler list is exhaustive, the
-``handleAllErrors`` function can be used instead. This is identical to
-``handleErrors`` except that it will terminate the program if an unhandled
-error is passed in, and can therefore return void. The ``handleAllErrors``
+`handleAllErrors` function can be used instead. This is identical to
+`handleErrors` except that it will terminate the program if an unhandled
+error is passed in, and can therefore return void. The `handleAllErrors`
function should generally be avoided: the introduction of a new error type
elsewhere in the program can easily turn a formerly exhaustive list of errors
into a non-exhaustive list, risking unexpected program termination. Where
-possible, use ``handleErrors`` and propagate unknown errors up the stack instead.
+possible, use `handleErrors` and propagate unknown errors up the stack instead.
For tool code, where errors can be handled by printing an error message then
-exiting with an error code, the :ref:`ExitOnError <err_exitonerr>` utility
-may be a better choice than ``handleErrors``, as it simplifies control flow when
+exiting with an error code, the {ref}`ExitOnError <err_exitonerr>` utility
+may be a better choice than `handleErrors`, as it simplifies control flow when
calling fallible functions.
In situations where it is known that a particular call to a fallible function
will always succeed (for example, a call to a function that can only fail on a
subset of inputs with an input that is known to be safe) the
-:ref:`cantFail <err_cantfail>` functions can be used to remove the error type,
+{ref}`cantFail <err_cantfail>` functions can be used to remove the error type,
simplifying control flow.
-StringError
-"""""""""""
+##### StringError
Many kinds of errors have no recovery strategy; the only action that can be
taken is to report them to the user so that the user can attempt to fix the
environment. In this case, representing the error as a string makes perfect
-sense. LLVM provides the ``StringError`` class for this purpose. It takes two
-arguments: A string error message, and an equivalent ``std::error_code`` for
-interoperability. It also provides a ``createStringError`` function to simplify
+sense. LLVM provides the `StringError` class for this purpose. It takes two
+arguments: A string error message, and an equivalent `std::error_code` for
+interoperability. It also provides a `createStringError` function to simplify
common usage of this class:
-.. code-block:: c++
-
- // These two lines of code are equivalent:
- make_error<StringError>("Bad executable", errc::executable_format_error);
- createStringError(errc::executable_format_error, "Bad executable");
-
+```cpp
+// These two lines of code are equivalent:
+make_error<StringError>("Bad executable", errc::executable_format_error);
+createStringError(errc::executable_format_error, "Bad executable");
+```
If you're certain that the error you're building will never need to be converted
-to a ``std::error_code``, you can use the ``inconvertibleErrorCode()`` function:
-
-.. code-block:: c++
-
- createStringError(inconvertibleErrorCode(), "Bad executable");
+to a `std::error_code`, you can use the `inconvertibleErrorCode()` function:
+```cpp
+createStringError(inconvertibleErrorCode(), "Bad executable");
+```
This should be done only after careful consideration. If any attempt is made to
-convert this error to a ``std::error_code`` it will trigger immediate program
+convert this error to a `std::error_code` it will trigger immediate program
termination. Unless you are certain that your errors will not need
-interoperability you should look for an existing ``std::error_code`` that you
+interoperability you should look for an existing `std::error_code` that you
can convert to, and even (as painful as it is) consider introducing a new one as
a stopgap measure.
-``createStringError`` can take ``printf`` style format specifiers to provide a
+`createStringError` can take `printf` style format specifiers to provide a
formatted message:
-.. code-block:: c++
-
- createStringError(errc::executable_format_error,
- "Bad executable: %s", FileName);
+```cpp
+createStringError(errc::executable_format_error,
+ "Bad executable: %s", FileName);
+```
+##### Interoperability with std::error_code and ErrorOr
-Interoperability with std::error_code and ErrorOr
-"""""""""""""""""""""""""""""""""""""""""""""""""
-
-Many existing LLVM APIs use ``std::error_code`` and its partner ``ErrorOr<T>``
-(which plays the same role as ``Expected<T>``, but wraps a ``std::error_code``
-rather than an ``Error``). The infectious nature of error types means that an
-attempt to change one of these functions to return ``Error`` or ``Expected<T>``
+Many existing LLVM APIs use `std::error_code` and its partner `ErrorOr<T>`
+(which plays the same role as `Expected<T>`, but wraps a `std::error_code`
+rather than an `Error`). The infectious nature of error types means that an
+attempt to change one of these functions to return `Error` or `Expected<T>`
instead often results in an avalanche of changes to callers, callers of callers,
-and so on. (The first such attempt, returning an ``Error`` from
+and so on. (The first such attempt, returning an `Error` from
MachOObjectFile's constructor, was abandoned after the diff reached 3000 lines,
impacted half a dozen libraries, and was still growing).
-To solve this problem, the ``Error``/``std::error_code`` interoperability requirement was
-introduced. Two pairs of functions allow any ``Error`` value to be converted to a
-``std::error_code``, any ``Expected<T>`` to be converted to an ``ErrorOr<T>``, and vice
+To solve this problem, the `Error`/`std::error_code` interoperability requirement was
+introduced. Two pairs of functions allow any `Error` value to be converted to a
+`std::error_code`, any `Expected<T>` to be converted to an `ErrorOr<T>`, and vice
versa:
-.. code-block:: c++
-
- std::error_code errorToErrorCode(Error Err);
- Error errorCodeToError(std::error_code EC);
-
- template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> TOrErr);
- template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> TOrEC);
-
+```cpp
+std::error_code errorToErrorCode(Error Err);
+Error errorCodeToError(std::error_code EC);
+template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> TOrErr);
+template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> TOrEC);
+```
Using these APIs it is easy to make surgical patches that update individual
-functions from ``std::error_code`` to ``Error``, and from ``ErrorOr<T>`` to
-``Expected<T>``.
+functions from `std::error_code` to `Error`, and from `ErrorOr<T>` to
+`Expected<T>`.
-Returning Errors from error handlers
-""""""""""""""""""""""""""""""""""""
+##### Returning Errors from error handlers
-Error recovery attempts may themselves fail. For that reason, ``handleErrors``
+Error recovery attempts may themselves fail. For that reason, `handleErrors`
actually recognises three different forms of handler signature:
-.. code-block:: c++
-
- // Error must be handled, no new errors produced:
- void(UserDefinedError &E);
+```cpp
+// Error must be handled, no new errors produced:
+void(UserDefinedError &E);
- // Error must be handled, new errors can be produced:
- Error(UserDefinedError &E);
+// Error must be handled, new errors can be produced:
+Error(UserDefinedError &E);
- // Original error can be inspected, then re-wrapped and returned (or a new
- // error can be produced):
- Error(std::unique_ptr<UserDefinedError> E);
-
-Any error returned from a handler will be returned from the ``handleErrors``
+// Original error can be inspected, then re-wrapped and returned (or a new
+// error can be produced):
+Error(std::unique_ptr<UserDefinedError> E);
+```
+Any error returned from a handler will be returned from the `handleErrors`
function so that it can be handled itself or propagated up the stack.
-.. _err_exitonerr:
+(err_exitonerr)=
-Using ExitOnError to simplify tool code
-"""""""""""""""""""""""""""""""""""""""
+##### Using ExitOnError to simplify tool code
-Library code should never call ``exit`` for a recoverable error; however, in tool
+Library code should never call `exit` for a recoverable error; however, in tool
code (especially command line tools) this can be a reasonable approach. Calling
-``exit`` upon encountering an error dramatically simplifies control flow as the
+`exit` upon encountering an error dramatically simplifies control flow as the
error no longer needs to be propagated up the stack. This allows code to be
written in a straight-line style, as long as each fallible call is wrapped in a
-check and call to exit. The ``ExitOnError`` class supports this pattern by
-providing call operators that inspect ``Error`` values, stripping the error away
-in the success case and logging to ``stderr`` then exiting in the failure case.
-
-To use this class, declare a global ``ExitOnError`` variable in your program:
-
-.. code-block:: c++
+check and call to exit. The `ExitOnError` class supports this pattern by
+providing call operators that inspect `Error` values, stripping the error away
+in the success case and logging to `stderr` then exiting in the failure case.
- ExitOnError ExitOnErr;
+To use this class, declare a global `ExitOnError` variable in your program:
-Calls to fallible functions can then be wrapped with a call to ``ExitOnErr``,
+```cpp
+ExitOnError ExitOnErr;
+```
+Calls to fallible functions can then be wrapped with a call to `ExitOnErr`,
turning them into non-failing calls:
-.. code-block:: c++
-
- Error mayFail();
- Expected<int> mayFail2();
-
- void foo() {
- ExitOnErr(mayFail());
- int X = ExitOnErr(mayFail2());
- }
-
-On failure, the error's log message will be written to ``stderr``, optionally
-preceded by a string "banner" that can be set by calling the ``setBanner`` method. A
-mapping can also be supplied from ``Error`` values to exit codes using the
-``setExitCodeMapper`` method:
-
-.. code-block:: c++
-
- int main(int argc, char *argv[]) {
- ExitOnErr.setBanner(std::string(argv[0]) + " error:");
- ExitOnErr.setExitCodeMapper(
- [](const Error &Err) {
- if (Err.isA<BadFileFormat>())
- return 2;
- return 1;
- });
-
-Use ``ExitOnError`` in your tool code where possible as it can greatly improve
+```cpp
+Error mayFail();
+Expected<int> mayFail2();
+
+void foo() {
+ ExitOnErr(mayFail());
+ int X = ExitOnErr(mayFail2());
+}
+```
+On failure, the error's log message will be written to `stderr`, optionally
+preceded by a string "banner" that can be set by calling the `setBanner` method. A
+mapping can also be supplied from `Error` values to exit codes using the
+`setExitCodeMapper` method:
+
+```cpp
+int main(int argc, char *argv[]) {
+ ExitOnErr.setBanner(std::string(argv[0]) + " error:");
+ ExitOnErr.setExitCodeMapper(
+ [](const Error &Err) {
+ if (Err.isA<BadFileFormat>())
+ return 2;
+ return 1;
+ });
+```
+Use `ExitOnError` in your tool code where possible as it can greatly improve
readability.
-.. _err_cantfail:
+(err_cantfail)=
-Using cantFail to simplify safe callsites
-"""""""""""""""""""""""""""""""""""""""""
+##### Using cantFail to simplify safe callsites
Some functions may only fail for a subset of their inputs, so calls using known
safe inputs can be assumed to succeed.
The cantFail functions encapsulate this by wrapping an assertion that their
-argument is a success value and, in the case of ``Expected<T>``, unwrapping the
-``T`` value:
+argument is a success value and, in the case of `Expected<T>`, unwrapping the
+`T` value:
-.. code-block:: c++
+```cpp
+Error onlyFailsForSomeXValues(int X);
+Expected<int> onlyFailsForSomeXValues2(int X);
- Error onlyFailsForSomeXValues(int X);
- Expected<int> onlyFailsForSomeXValues2(int X);
-
- void foo() {
- cantFail(onlyFailsForSomeXValues(KnownSafeValue));
- int Y = cantFail(onlyFailsForSomeXValues2(KnownSafeValue));
- ...
- }
-
-Like the ExitOnError utility, ``cantFail`` simplifies control flow. Their treatment
+void foo() {
+ cantFail(onlyFailsForSomeXValues(KnownSafeValue));
+ int Y = cantFail(onlyFailsForSomeXValues2(KnownSafeValue));
+ ...
+}
+```
+Like the ExitOnError utility, `cantFail` simplifies control flow. Their treatment
of error cases is very different, however: Where ExitOnError is guaranteed to
-terminate the program on an error input, ``cantFail`` simply asserts that the result
+terminate the program on an error input, `cantFail` simply asserts that the result
is success. In debug builds this will result in an assertion failure if an error
-is encountered. In release builds, the behavior of ``cantFail`` for failure values is
-undefined. As such, care must be taken in the use of ``cantFail``: clients must be
-certain that a ``cantFail`` wrapped call really can not fail with the given
+is encountered. In release builds, the behavior of `cantFail` for failure values is
+undefined. As such, care must be taken in the use of `cantFail`: clients must be
+certain that a `cantFail` wrapped call really can not fail with the given
arguments.
-Use of the ``cantFail`` functions should be rare in library code, but they are
+Use of the `cantFail` functions should be rare in library code, but they are
likely to be of more use in tool and unit-test code where inputs and/or
mocked-up classes or functions may be known to be safe.
-Fallible constructors
-"""""""""""""""""""""
+##### Fallible constructors
Some classes require resource acquisition or other complex initialization that
can fail during construction. Unfortunately constructors can't return errors,
and having clients test objects after they're constructed to ensure that they're
valid is error prone as it's all too easy to forget the test. To work around
-this, use the named constructor idiom and return an ``Expected<T>``:
+this, use the named constructor idiom and return an `Expected<T>`:
-.. code-block:: c++
+```cpp
+class Foo {
+public:
- class Foo {
- public:
-
- static Expected<Foo> Create(Resource R1, Resource R2) {
- Error Err = Error::success();
- Foo F(R1, R2, Err);
- if (Err)
- return std::move(Err);
- return std::move(F);
- }
+ static Expected<Foo> Create(Resource R1, Resource R2) {
+ Error Err = Error::success();
+ Foo F(R1, R2, Err);
+ if (Err)
+ return std::move(Err);
+ return std::move(F);
+ }
- private:
+private:
- Foo(Resource R1, Resource R2, Error &Err) {
- ErrorAsOutParameter EAO(&Err);
- if (auto Err2 = R1.acquire()) {
- Err = std::move(Err2);
- return;
- }
- Err = R2.acquire();
+ Foo(Resource R1, Resource R2, Error &Err) {
+ ErrorAsOutParameter EAO(&Err);
+ if (auto Err2 = R1.acquire()) {
+ Err = std::move(Err2);
+ return;
}
- };
-
-
-Here, the named constructor passes an ``Error`` by reference into the actual
+ Err = R2.acquire();
+ }
+};
+```
+Here, the named constructor passes an `Error` by reference into the actual
constructor, which the constructor can then use to return errors. The
-``ErrorAsOutParameter`` utility sets the ``Error`` value's checked flag on entry
+`ErrorAsOutParameter` utility sets the `Error` value's checked flag on entry
to the constructor so that the error can be assigned to, then resets it on exit
to force the client (the named constructor) to check the error.
By using this idiom, clients attempting to construct a Foo receive either a
well-formed Foo or an Error, never an object in an invalid state.
-Propagating and consuming errors based on types
-"""""""""""""""""""""""""""""""""""""""""""""""
+##### Propagating and consuming errors based on types
In some contexts, certain types of errors are known to be benign. For example,
when walking an archive, some clients may be happy to skip over badly formatted
object files rather than terminating the walk immediately. Skipping badly
formatted objects could be achieved using an elaborate handler method, but the
-``Error.h`` header provides two utilities that make this idiom much cleaner: the
-type inspection method, ``isA``, and the ``consumeError`` function:
-
-.. code-block:: c++
-
- Error walkArchive(Archive A) {
- for (unsigned I = 0; I != A.numMembers(); ++I) {
- auto ChildOrErr = A.getMember(I);
- if (auto Err = ChildOrErr.takeError()) {
- if (Err.isA<BadFileFormat>())
- consumeError(std::move(Err))
- else
- return Err;
- }
- auto &Child = *ChildOrErr;
- // Use Child
- ...
+`Error.h` header provides two utilities that make this idiom much cleaner: the
+type inspection method, `isA`, and the `consumeError` function:
+
+```cpp
+Error walkArchive(Archive A) {
+ for (unsigned I = 0; I != A.numMembers(); ++I) {
+ auto ChildOrErr = A.getMember(I);
+ if (auto Err = ChildOrErr.takeError()) {
+ if (Err.isA<BadFileFormat>())
+ consumeError(std::move(Err))
+ else
+ return Err;
}
- return Error::success();
+ auto &Child = *ChildOrErr;
+ // Use Child
+ ...
}
+ return Error::success();
+}
+```
+##### Concatenating Errors with joinErrors
-Concatenating Errors with joinErrors
-""""""""""""""""""""""""""""""""""""
-
-In the archive walking example above, ``BadFileFormat`` errors are simply
+In the archive walking example above, `BadFileFormat` errors are simply
consumed and ignored. If the client had wanted to report these errors after
-completing the walk over the archive they could use the ``joinErrors`` utility:
-
-.. code-block:: c++
-
- Error walkArchive(Archive A) {
- Error DeferredErrs = Error::success();
- for (unsigned I = 0; I != A.numMembers(); ++I) {
- auto ChildOrErr = A.getMember(I);
- if (auto Err = ChildOrErr.takeError())
- if (Err.isA<BadFileFormat>())
- DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
- else
- return Err;
- auto &Child = *ChildOrErr;
- // Use Child
- ...
- }
- return DeferredErrs;
+completing the walk over the archive they could use the `joinErrors` utility:
+
+```cpp
+Error walkArchive(Archive A) {
+ Error DeferredErrs = Error::success();
+ for (unsigned I = 0; I != A.numMembers(); ++I) {
+ auto ChildOrErr = A.getMember(I);
+ if (auto Err = ChildOrErr.takeError())
+ if (Err.isA<BadFileFormat>())
+ DeferredErrs = joinErrors(std::move(DeferredErrs), std::move(Err));
+ else
+ return Err;
+ auto &Child = *ChildOrErr;
+ // Use Child
+ ...
}
-
-The ``joinErrors`` routine builds a special error type called ``ErrorList``,
-which holds a list of user-defined errors. The ``handleErrors`` routine
+ return DeferredErrs;
+}
+```
+The `joinErrors` routine builds a special error type called `ErrorList`,
+which holds a list of user-defined errors. The `handleErrors` routine
recognizes this type and will attempt to handle each of the contained errors in
-order. If all contained errors can be handled, ``handleErrors`` will return
-``Error::success()``; otherwise, ``handleErrors`` will concatenate the remaining
-errors and return the resulting ``ErrorList``.
+order. If all contained errors can be handled, `handleErrors` will return
+`Error::success()`; otherwise, `handleErrors` will concatenate the remaining
+errors and return the resulting `ErrorList`.
-Building fallible iterators and iterator ranges
-"""""""""""""""""""""""""""""""""""""""""""""""
+##### Building fallible iterators and iterator ranges
The archive walking examples above retrieve archive members by index; however,
this requires considerable boilerplate for iteration and error checking. We can
clean this up by using the "fallible iterator" pattern, which supports the
following natural iteration idiom for fallible containers like Archive:
-.. code-block:: c++
+```cpp
+Error Err = Error::success();
+for (auto &Child : Ar->children(Err)) {
+ // Use Child - only enter the loop when it's valid
- Error Err = Error::success();
- for (auto &Child : Ar->children(Err)) {
- // Use Child - only enter the loop when it's valid
-
- // Allow early exit from the loop body, since we know that Err is success
- // when we're inside the loop.
- if (BailOutOn(Child))
- return;
-
- ...
- }
- // Check Err after the loop to ensure it didn't break due to an error.
- if (Err)
- return Err;
+ // Allow early exit from the loop body, since we know that Err is success
+ // when we're inside the loop.
+ if (BailOutOn(Child))
+ return;
+ ...
+}
+// Check Err after the loop to ensure it didn't break due to an error.
+if (Err)
+ return Err;
+```
To enable this idiom, iterators over fallible containers are written in a
-natural style, with their ``++`` and ``--`` operators replaced with fallible
-``Error inc()`` and ``Error dec()`` functions. E.g.:
-
-.. code-block:: c++
-
- class FallibleChildIterator {
- public:
- FallibleChildIterator(Archive &A, unsigned ChildIdx);
- Archive::Child &operator*();
- friend bool operator==(const ArchiveIterator &LHS,
- const ArchiveIterator &RHS);
-
- // operator++/operator-- replaced with fallible increment / decrement:
- Error inc() {
- if (!A.childValid(ChildIdx + 1))
- return make_error<BadArchiveMember>(...);
- ++ChildIdx;
- return Error::success();
- }
-
- Error dec() { ... }
- };
+natural style, with their `++` and `--` operators replaced with fallible
+`Error inc()` and `Error dec()` functions. E.g.:
+
+```cpp
+class FallibleChildIterator {
+public:
+ FallibleChildIterator(Archive &A, unsigned ChildIdx);
+ Archive::Child &operator*();
+ friend bool operator==(const ArchiveIterator &LHS,
+ const ArchiveIterator &RHS);
+
+ // operator++/operator-- replaced with fallible increment / decrement:
+ Error inc() {
+ if (!A.childValid(ChildIdx + 1))
+ return make_error<BadArchiveMember>(...);
+ ++ChildIdx;
+ return Error::success();
+ }
+ Error dec() { ... }
+};
+```
Instances of this kind of fallible iterator interface are then wrapped with the
-fallible_iterator utility which provides ``operator++`` and ``operator--``,
+fallible_iterator utility which provides `operator++` and `operator--`,
returning any errors via a reference passed in to the wrapper at construction
time. The fallible_iterator wrapper takes care of (a) jumping to the end of the
range on error, and (b) marking the error as checked whenever an iterator is
-compared to ``end`` and found to be unequal (in particular, this marks the
+compared to `end` and found to be unequal (in particular, this marks the
error as checked throughout the body of a range-based for loop), enabling early
exit from the loop without redundant error checking.
Instances of the fallible iterator interface (e.g., FallibleChildIterator above)
-are wrapped using the ``make_fallible_itr`` and ``make_fallible_end``
+are wrapped using the `make_fallible_itr` and `make_fallible_end`
functions. E.g.:
-.. code-block:: c++
+```cpp
+class Archive {
+public:
+ using child_iterator = fallible_iterator<FallibleChildIterator>;
- class Archive {
- public:
- using child_iterator = fallible_iterator<FallibleChildIterator>;
-
- child_iterator child_begin(Error &Err) {
- return make_fallible_itr(FallibleChildIterator(*this, 0), Err);
- }
-
- child_iterator child_end() {
- return make_fallible_end(FallibleChildIterator(*this, size()));
- }
+ child_iterator child_begin(Error &Err) {
+ return make_fallible_itr(FallibleChildIterator(*this, 0), Err);
+ }
- iterator_range<child_iterator> children(Error &Err) {
- return make_range(child_begin(Err), child_end());
- }
- };
+ child_iterator child_end() {
+ return make_fallible_end(FallibleChildIterator(*this, size()));
+ }
+ iterator_range<child_iterator> children(Error &Err) {
+ return make_range(child_begin(Err), child_end());
+ }
+};
+```
Using the fallible_iterator utility allows for both natural construction of
-fallible iterators (using failing ``inc`` and ``dec`` operations) and
+fallible iterators (using failing `inc` and `dec` operations) and
relatively natural use of C++ iterator/loop idioms.
-.. _function_apis:
+(function_apis)=
More information on Error and its related utilities can be found in the
-``Error.h`` header file.
+`Error.h` header file.
-Passing functions and other callable objects
---------------------------------------------
+### Passing functions and other callable objects
Sometimes you may want a function to be passed a callback object. In order to
support lambda expressions and other function objects, you should not use the
traditional C approach of taking a function pointer and an opaque cookie:
-.. code-block:: c++
-
- void takeCallback(bool (*Callback)(Function *, void *), void *Cookie);
-
+```cpp
+void takeCallback(bool (*Callback)(Function *, void *), void *Cookie);
+```
Instead, use one of the following approaches:
-Function template
-^^^^^^^^^^^^^^^^^
+#### Function template
If you don't mind putting the definition of your function into a header file,
make it a function template that is templated on the callable type.
-.. code-block:: c++
-
- template<typename Callable>
- void takeCallback(Callable Callback) {
- Callback(1, 2, 3);
- }
+```cpp
+template<typename Callable>
+void takeCallback(Callable Callback) {
+ Callback(1, 2, 3);
+}
+```
+#### The `function_ref` class template
-The ``function_ref`` class template
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``function_ref``
-(`doxygen <https://llvm.org/doxygen/classllvm_1_1function__ref_3_01Ret_07Params_8_8_8_08_4.html>`__) class
+The `function_ref`
+([doxygen](https://llvm.org/doxygen/classllvm_1_1function__ref_3_01Ret_07Params_8_8_8_08_4.html)) class
template represents a reference to a callable object, templated over the type
of the callable. This is a good choice for passing a callback to a function,
if you don't need to hold onto the callback after the function returns. In this
-way, ``function_ref`` is to ``std::function`` as ``StringRef`` is to
-``std::string``.
+way, `function_ref` is to `std::function` as `StringRef` is to
+`std::string`.
-``function_ref<Ret(Param1, Param2, ...)>`` can be implicitly constructed from
-any callable object that can be called with arguments of type ``Param1``,
-``Param2``, ..., and returns a value that can be converted to type ``Ret``.
+`function_ref<Ret(Param1, Param2, ...)>` can be implicitly constructed from
+any callable object that can be called with arguments of type `Param1`,
+`Param2`, ..., and returns a value that can be converted to type `Ret`.
For example:
-.. code-block:: c++
-
- void visitBasicBlocks(Function *F, function_ref<bool (BasicBlock*)> Callback) {
- for (BasicBlock &BB : *F)
- if (Callback(&BB))
- return;
- }
-
+```cpp
+void visitBasicBlocks(Function *F, function_ref<bool (BasicBlock*)> Callback) {
+ for (BasicBlock &BB : *F)
+ if (Callback(&BB))
+ return;
+}
+```
can be called using:
-.. code-block:: c++
-
- visitBasicBlocks(F, [&](BasicBlock *BB) {
- if (process(BB))
- return isEmpty(BB);
- return false;
- });
-
-Note that a ``function_ref`` object contains pointers to external memory, so it
+```cpp
+visitBasicBlocks(F, [&](BasicBlock *BB) {
+ if (process(BB))
+ return isEmpty(BB);
+ return false;
+});
+```
+Note that a `function_ref` object contains pointers to external memory, so it
is not generally safe to store an instance of the class (unless you know that
the external storage will not be freed). If you need this ability, consider
-using ``std::function``. ``function_ref`` is small enough that it should always
+using `std::function`. `function_ref` is small enough that it should always
be passed by value.
-.. _DEBUG:
+(DEBUG)=
-The ``LDBG`` and ``LLVM_DEBUG()`` macros and ``-debug`` option
---------------------------------------------------------------
+### The `LDBG` and `LLVM_DEBUG()` macros and `-debug` option
Often, when working on your pass, you will put a bunch of debugging printouts and
other code into your pass. After you get it working, you want to remove it, but
@@ -1170,158 +1080,142 @@ Naturally, because of this, you don't want to delete the debug printouts, but
you don't want them to always be noisy. A standard compromise is to comment
them out, allowing you to enable them if you need them in the future.
-The ``llvm/Support/DebugLog.h`` file provides a macro named ``LDBG`` that is a
+The `llvm/Support/DebugLog.h` file provides a macro named `LDBG` that is a
more convenient way to add debug output to your code. It is a macro that
provides a raw_ostream that is used to write the debug output.
-.. code-block:: c++
-
- LDBG() << "I am here!";
-
+```cpp
+LDBG() << "I am here!";
+```
It'll only print the output if the debug output is enabled.
It also supports a `level` argument to control the verbosity of the output.
-.. code-block:: c++
-
- LDBG(2) << "I am here!";
-
-A ``DEBUG_TYPE`` macro may optionally be defined in the file before using
-``LDBG()``, otherwise the file name is used as the debug type.
+```cpp
+LDBG(2) << "I am here!";
+```
+A `DEBUG_TYPE` macro may optionally be defined in the file before using
+`LDBG()`, otherwise the file name is used as the debug type.
The file name and line number are automatically added to the output, as well as
a terminating newline.
-The debug output can be enabled by passing the ``-debug`` command line argument.
-
-.. code-block:: none
+The debug output can be enabled by passing the `-debug` command line argument.
- $ opt < a.bc > /dev/null -mypass
- <no output>
- $ opt < a.bc > /dev/null -mypass -debug
- [my-pass MyPass.cpp:123 2] I am here!
-
-While ``LDBG()`` is useful to add debug output to your code, there are cases
+```none
+$ opt < a.bc > /dev/null -mypass
+<no output>
+$ opt < a.bc > /dev/null -mypass -debug
+[my-pass MyPass.cpp:123 2] I am here!
+```
+While `LDBG()` is useful to add debug output to your code, there are cases
where you may need to guard a block of code with a debug check. The
-``llvm/Support/Debug.h`` (`doxygen
-<https://llvm.org/doxygen/Debug_8h_source.html>`__) file provides a macro named
-``LLVM_DEBUG()`` that offers a solution to this problem. You can put arbitrary
-code into the argument of the ``LLVM_DEBUG`` macro, and it is only executed if
-'``opt``' (or any other tool) is run with the '``-debug``' command
+`llvm/Support/Debug.h` ([doxygen](https://llvm.org/doxygen/Debug_8h_source.html)) file provides a macro named
+`LLVM_DEBUG()` that offers a solution to this problem. You can put arbitrary
+code into the argument of the `LLVM_DEBUG` macro, and it is only executed if
+'`opt`' (or any other tool) is run with the '`-debug`' command
line argument.
-.. code-block:: c++
-
- LLVM_DEBUG({
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> logBuffer =
- llvm::MemoryBuffer::getFile(logFile->first);
- if (logBuffer && !(*logBuffer)->getBuffer().empty()) {
- LDBG() << "Output:\n" << (*logBuffer)->getBuffer();
- }
- });
-
-
+```cpp
+LLVM_DEBUG({
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> logBuffer =
+ llvm::MemoryBuffer::getFile(logFile->first);
+ if (logBuffer && !(*logBuffer)->getBuffer().empty()) {
+ LDBG() << "Output:\n" << (*logBuffer)->getBuffer();
+ }
+});
+```
Using these macros instead of a home-brewed solution allows you to not have to
create "yet another" command-line option for the debug output for your pass.
-Note that ``LDBG()`` and ``LLVM_DEBUG()`` macros are disabled for non-asserts
+Note that `LDBG()` and `LLVM_DEBUG()` macros are disabled for non-asserts
builds, so they do not cause a performance impact at all (for the same reason,
they should also not contain side-effects!).
-One additional nice thing about the ``LDBG()`` and ``LLVM_DEBUG()`` macros is
+One additional nice thing about the `LDBG()` and `LLVM_DEBUG()` macros is
that you can enable or disable it directly in gdb. Just use
-"``set DebugFlag=0``" or "``set DebugFlag=1``" from the gdb if the program is
+"`set DebugFlag=0`" or "`set DebugFlag=1`" from the gdb if the program is
running. If the program hasn't been started yet, you can always just run it
-with ``-debug``.
+with `-debug`.
-.. _DEBUG_TYPE:
+(DEBUG_TYPE)=
-Fine grained debug info with ``DEBUG_TYPE`` and the ``-debug-only`` option
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Fine grained debug info with `DEBUG_TYPE` and the `-debug-only` option
-Sometimes, you may find yourself in a situation where enabling ``-debug`` just
+Sometimes, you may find yourself in a situation where enabling `-debug` just
turns on **too much** information (such as when working on the code generator).
If you want to enable debug information with more fine-grained control, you
can control the debug type and level with associate with each logging statement
as follows:
-.. code-block:: c++
-
- #define DEBUG_TYPE "foo" // Optional: the file name is used instead if not defined
- LDBG(2) << "Hello,";
- // DEBUG_TYPE can be overridden locally, here with "bar"
- LDBG("bar", 3) << "'bar' debug type";
-
-
+```cpp
+#define DEBUG_TYPE "foo" // Optional: the file name is used instead if not defined
+LDBG(2) << "Hello,";
+// DEBUG_TYPE can be overridden locally, here with "bar"
+LDBG("bar", 3) << "'bar' debug type";
+```
A more fine-grained control of the output can be achieved by passing the
-``-debug-only`` command line argument:
-
-.. code-block:: none
-
- $ opt < a.bc > /dev/null -mypass -debug-only=foo
- [foo MyPass.cpp:123 2] Hello,
- $ opt < a.bc > /dev/null -mypass -debug-only=foo,bar
- [foo MyPass.cpp:123 2] Hello,
- [bar MyPass.cpp:124 3] World!
- $ opt < a.bc > /dev/null -mypass -debug-only=bar
- [bar MyPass.cpp:124 3] World!
-
+`-debug-only` command line argument:
+
+```none
+$ opt < a.bc > /dev/null -mypass -debug-only=foo
+[foo MyPass.cpp:123 2] Hello,
+$ opt < a.bc > /dev/null -mypass -debug-only=foo,bar
+[foo MyPass.cpp:123 2] Hello,
+[bar MyPass.cpp:124 3] World!
+$ opt < a.bc > /dev/null -mypass -debug-only=bar
+[bar MyPass.cpp:124 3] World!
+```
The debug-only argument is a comma separated list of debug types and levels.
The level is an optional integer setting the maximum debug level to enable:
-.. code-block:: none
-
- $ opt < a.bc > /dev/null -mypass -debug-only=foo:2,bar:2
- [foo MyPass.cpp:123 2] Hello,
- $ opt < a.bc > /dev/null -mypass -debug-only=foo:1,bar:3
- [bar MyPass.cpp:124 3] World!
-
-Instead of opting in specific debug types, the ``-debug-only`` option also
+```none
+$ opt < a.bc > /dev/null -mypass -debug-only=foo:2,bar:2
+[foo MyPass.cpp:123 2] Hello,
+$ opt < a.bc > /dev/null -mypass -debug-only=foo:1,bar:3
+[bar MyPass.cpp:124 3] World!
+```
+Instead of opting in specific debug types, the `-debug-only` option also
works to filter out debug output for specific debug types, by omitting the
level (or setting it to 0):
-.. code-block:: none
-
- $ opt < a.bc > /dev/null -mypass -debug-only=foo:
- [bar MyPass.cpp:124 3] World!
- $ opt < a.bc > /dev/null -mypass -debug-only=bar:0,foo:
-
-
-In practice, you should only set ``DEBUG_TYPE`` at the top of a file, to
+```none
+$ opt < a.bc > /dev/null -mypass -debug-only=foo:
+[bar MyPass.cpp:124 3] World!
+$ opt < a.bc > /dev/null -mypass -debug-only=bar:0,foo:
+```
+In practice, you should only set `DEBUG_TYPE` at the top of a file, to
specify the debug type for the entire module. Be careful that you only do
-this after you're done including headers (in particular ``Debug.h``/``DebugLog.h``).
+this after you're done including headers (in particular `Debug.h`/`DebugLog.h`).
Also, you should use names more meaningful than "foo" and "bar", because there
is no system in place to ensure that names do not conflict. If two different
modules use the same string, they will all be turned on when the name is specified.
This allows, for example, all debug information for instruction scheduling to be
-enabled with ``-debug-only=InstrSched``, even if the source lives in multiple
+enabled with `-debug-only=InstrSched`, even if the source lives in multiple
files. The name must not include a comma (,) as that is used to separate the
-arguments of the ``-debug-only`` option.
+arguments of the `-debug-only` option.
For performance reasons, -debug-only is not available in non-asserts build
of LLVM.
-The ``DEBUG_WITH_TYPE`` macro is an alternative to the ``LLVM_DEBUG()`` macro
-for situations where you would like to set ``DEBUG_TYPE``, but only for one
-specific ``LLVM_DEBUG`` statement. It takes an additional first parameter,
+The `DEBUG_WITH_TYPE` macro is an alternative to the `LLVM_DEBUG()` macro
+for situations where you would like to set `DEBUG_TYPE`, but only for one
+specific `LLVM_DEBUG` statement. It takes an additional first parameter,
which is the type to use. The example from the previous section could be
written as:
-.. code-block:: c++
-
- DEBUG_WITH_TYPE("special-type", {
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> logBuffer =
- llvm::MemoryBuffer::getFile(logFile->first);
- if (logBuffer && !(*logBuffer)->getBuffer().empty()) {
- LDBG("special-type") << "Output:\n" << (*logBuffer)->getBuffer();
- }
- });
-
-.. _Statistic:
+```cpp
+DEBUG_WITH_TYPE("special-type", {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> logBuffer =
+ llvm::MemoryBuffer::getFile(logFile->first);
+ if (logBuffer && !(*logBuffer)->getBuffer().empty()) {
+ LDBG("special-type") << "Output:\n" << (*logBuffer)->getBuffer();
+ }
+});
+```
+(Statistic)=
-The ``Statistic`` class & ``-stats`` option
--------------------------------------------
+### The `Statistic` class & `-stats` option
-The ``llvm/ADT/Statistic.h`` (`doxygen
-<https://llvm.org/doxygen/Statistic_8h_source.html>`__) file provides a class
-named ``Statistic`` that is used as a unified way to keep track of what the LLVM
+The `llvm/ADT/Statistic.h` ([doxygen](https://llvm.org/doxygen/Statistic_8h_source.html)) file provides a class
+named `Statistic` that is used as a unified way to keep track of what the LLVM
compiler is doing and how effective various optimizations are. It is useful to
see what optimizations are contributing to making a particular program run
faster.
@@ -1329,81 +1223,76 @@ faster.
Often you may run your pass on some big program, and you're interested to see
how many times it makes a certain transformation. Although you can do this with
hand inspection, or some ad-hoc method, this is a real pain and not very useful
-for big programs. Using the ``Statistic`` class makes it very easy to keep
+for big programs. Using the `Statistic` class makes it very easy to keep
track of this information, and the calculated information is presented in a
uniform manner with the rest of the passes being executed.
-There are many examples of ``Statistic`` uses, but the basics of using it are as
+There are many examples of `Statistic` uses, but the basics of using it are as
follows:
Define your statistic like this:
-.. code-block:: c++
-
- #define DEBUG_TYPE "mypassname" // This goes after any #includes.
- STATISTIC(NumXForms, "The # of times I did stuff");
-
-The ``STATISTIC`` macro defines a static variable, whose name is specified by
-the first argument. The pass name is taken from the ``DEBUG_TYPE`` macro, and
+```cpp
+#define DEBUG_TYPE "mypassname" // This goes after any #includes.
+STATISTIC(NumXForms, "The # of times I did stuff");
+```
+The `STATISTIC` macro defines a static variable, whose name is specified by
+the first argument. The pass name is taken from the `DEBUG_TYPE` macro, and
the description is taken from the second argument. The variable defined
("NumXForms" in this case) acts like an unsigned integer.
Whenever you make a transformation, bump the counter:
-.. code-block:: c++
-
- ++NumXForms; // I did stuff!
-
-That's all you have to do. To get '``opt``' to print out the statistics
-gathered, use the '``-stats``' option:
-
-.. code-block:: none
-
- $ opt -stats -mypassname < program.bc > /dev/null
- ... statistics output ...
-
-Note that in order to use the '``-stats``' option, LLVM must be
+```cpp
+++NumXForms; // I did stuff!
+```
+That's all you have to do. To get '`opt`' to print out the statistics
+gathered, use the '`-stats`' option:
+
+```none
+$ opt -stats -mypassname < program.bc > /dev/null
+... statistics output ...
+```
+Note that in order to use the '`-stats`' option, LLVM must be
compiled with assertions enabled.
-When running ``opt`` on a C file from the SPEC benchmark suite, it gives a
+When running `opt` on a C file from the SPEC benchmark suite, it gives a
report that looks like this:
-.. code-block:: none
-
- 7646 bitcodewriter - Number of normal instructions
- 725 bitcodewriter - Number of oversized instructions
- 129996 bitcodewriter - Number of bitcode bytes written
- 2817 raise - Number of insts DCEd or constprop'd
- 3213 raise - Number of cast-of-self removed
- 5046 raise - Number of expression trees converted
- 75 raise - Number of other getelementptr's formed
- 138 raise - Number of load/store peepholes
- 42 deadtypeelim - Number of unused typenames removed from symtab
- 392 funcresolve - Number of varargs functions resolved
- 27 globaldce - Number of global variables removed
- 2 adce - Number of basic blocks removed
- 134 cee - Number of branches revectored
- 49 cee - Number of setcc instruction eliminated
- 532 gcse - Number of loads removed
- 2919 gcse - Number of instructions removed
- 86 indvars - Number of canonical indvars added
- 87 indvars - Number of aux indvars removed
- 25 instcombine - Number of dead inst eliminate
- 434 instcombine - Number of insts combined
- 248 licm - Number of load insts hoisted
- 1298 licm - Number of insts hoisted to a loop pre-header
- 3 licm - Number of insts hoisted to multiple loop preds (bad, no loop pre-header)
- 75 mem2reg - Number of alloca's promoted
- 1444 cfgsimplify - Number of blocks simplified
-
+```none
+ 7646 bitcodewriter - Number of normal instructions
+ 725 bitcodewriter - Number of oversized instructions
+129996 bitcodewriter - Number of bitcode bytes written
+ 2817 raise - Number of insts DCEd or constprop'd
+ 3213 raise - Number of cast-of-self removed
+ 5046 raise - Number of expression trees converted
+ 75 raise - Number of other getelementptr's formed
+ 138 raise - Number of load/store peepholes
+ 42 deadtypeelim - Number of unused typenames removed from symtab
+ 392 funcresolve - Number of varargs functions resolved
+ 27 globaldce - Number of global variables removed
+ 2 adce - Number of basic blocks removed
+ 134 cee - Number of branches revectored
+ 49 cee - Number of setcc instruction eliminated
+ 532 gcse - Number of loads removed
+ 2919 gcse - Number of instructions removed
+ 86 indvars - Number of canonical indvars added
+ 87 indvars - Number of aux indvars removed
+ 25 instcombine - Number of dead inst eliminate
+ 434 instcombine - Number of insts combined
+ 248 licm - Number of load insts hoisted
+ 1298 licm - Number of insts hoisted to a loop pre-header
+ 3 licm - Number of insts hoisted to multiple loop preds (bad, no loop pre-header)
+ 75 mem2reg - Number of alloca's promoted
+ 1444 cfgsimplify - Number of blocks simplified
+```
Obviously, with so many optimizations, having a unified framework for this stuff
is very nice. Making your pass fit well into the framework makes it more
maintainable and useful.
-.. _DebugCounters:
+(DebugCounters)=
-Adding debug counters to aid in debugging your code
----------------------------------------------------
+### Adding debug counters to aid in debugging your code
Sometimes, when writing new passes or trying to track down bugs, it
is useful to be able to control whether certain things in your pass
@@ -1414,50 +1303,46 @@ automatically, using bisection. This is where debug counters help.
They provide a framework for making parts of your code only execute a
certain number of times.
-The ``llvm/Support/DebugCounter.h`` (`doxygen
-<https://llvm.org/doxygen/DebugCounter_8h_source.html>`__) file
-provides a class named ``DebugCounter`` that can be used to create
+The `llvm/Support/DebugCounter.h` ([doxygen](https://llvm.org/doxygen/DebugCounter_8h_source.html)) file
+provides a class named `DebugCounter` that can be used to create
command-line counter options that control execution of parts of your code.
-Define your ``DebugCounter`` like this:
+Define your `DebugCounter` like this:
-.. code-block:: c++
-
- DEBUG_COUNTER(DeleteAnInstruction, "passname-delete-instruction",
+```cpp
+DEBUG_COUNTER(DeleteAnInstruction, "passname-delete-instruction",
+```
"Controls which instructions get delete");
-The ``DEBUG_COUNTER`` macro defines a static variable, whose name
+The `DEBUG_COUNTER` macro defines a static variable, whose name
is specified by the first argument. The name of the counter
(which is used on the command line) is specified by the second
argument, and the description used in the help is specified by the
third argument.
-Whatever code you want to control, use ``DebugCounter::shouldExecute`` to control it.
-
-.. code-block:: c++
-
- if (DebugCounter::shouldExecute(DeleteAnInstruction))
- I->eraseFromParent();
+Whatever code you want to control, use `DebugCounter::shouldExecute` to control it.
+```cpp
+if (DebugCounter::shouldExecute(DeleteAnInstruction))
+ I->eraseFromParent();
+```
That's all you have to do. Now, using opt, you can control when this code triggers using
-the '``--debug-counter``' Options. To specify when to execute the codepath.
-
-.. code-block:: none
-
- $ opt --debug-counter=passname-delete-instruction=2-3 -passname
+the '`--debug-counter`' Options. To specify when to execute the codepath.
+```none
+$ opt --debug-counter=passname-delete-instruction=2-3 -passname
+```
This will skip the above code the first two times we hit it, then execute it 2 times, then skip the rest of the executions.
So if executed on the following code:
-.. code-block:: llvm
-
- %1 = add i32 %a, %b
- %2 = add i32 %a, %b
- %3 = add i32 %a, %b
- %4 = add i32 %a, %b
-
-It would delete number ``%2`` and ``%3``.
+```llvm
+%1 = add i32 %a, %b
+%2 = add i32 %a, %b
+%3 = add i32 %a, %b
+%4 = add i32 %a, %b
+```
+It would delete number `%2` and `%3`.
A utility is provided in `utils/bisect-skip-count` to binary search
the begin and end of the range argument. It can be used to automatically minimize the
@@ -1470,77 +1355,71 @@ First, Figure out the number of calls to the debug counter you want to minimize.
To do so, run the compilation command causing you want to minimize with `-print-debug-counter` adding a `-mllvm` if needed.
Then find the line with the counter of interest. it should look like:
-.. code-block:: none
-
- my-counter : {5678,empty}
-
+```none
+my-counter : {5678,empty}
+```
The number of calls to `my-counter` is 5678
Then find the minimum set of chunks that is interesting, with `reduce-chunk-list`.
Build a reproducer script like:
-.. code-block:: bash
-
- #! /bin/bash
- opt -debug-counter=my-counter=$1
- # ... Test result of the command. Failure of the script is considered interesting
-
+```bash
+#! /bin/bash
+opt -debug-counter=my-counter=$1
+# ... Test result of the command. Failure of the script is considered interesting
+```
Then run `reduce-chunk-list my-script.sh 0-5678 2>&1 | tee dump_bisect`
This command may take some time.
but when it is done, it will print the result like: `Minimal Chunks = 0:1:5:11-12:33-34`
-.. _ViewGraph:
+(ViewGraph)=
-Viewing graphs while debugging code
------------------------------------
+### Viewing graphs while debugging code
Several of the important data structures in LLVM are graphs: for example CFGs
-made out of LLVM :ref:`BasicBlocks <BasicBlock>`, CFGs made out of LLVM
-:ref:`MachineBasicBlocks <MachineBasicBlock>`, and :ref:`Instruction Selection
-DAGs <SelectionDAG>`. In many cases, while debugging various parts of the
+made out of LLVM {ref}`BasicBlocks <BasicBlock>`, CFGs made out of LLVM
+[MachineBasicBlocks](https://llvm.org/docs/CodeGenerator.html#machinebasicblock), and [Instruction Selection
+DAGs](https://llvm.org/docs/CodeGenerator.html#selectiondag). In many cases, while debugging various parts of the
compiler, it is nice to instantly visualize these graphs.
LLVM provides several callbacks that are available in a debug build to do
-exactly that. If you call the ``Function::viewCFG()`` method, for example, the
+exactly that. If you call the `Function::viewCFG()` method, for example, the
current LLVM tool will pop up a window containing the CFG for the function where
each basic block is a node in the graph, and each node contains the instructions
-in the block. Similarly, there also exists ``Function::viewCFGOnly()`` (does
-not include the instructions), the ``MachineFunction::viewCFG()`` and
-``MachineFunction::viewCFGOnly()``, and the ``SelectionDAG::viewGraph()``
-methods. Within GDB, for example, you can usually use something like ``call
-DAG.viewGraph()`` to pop up a window. Alternatively, you can sprinkle calls to
+in the block. Similarly, there also exists `Function::viewCFGOnly()` (does
+not include the instructions), the `MachineFunction::viewCFG()` and
+`MachineFunction::viewCFGOnly()`, and the `SelectionDAG::viewGraph()`
+methods. Within GDB, for example, you can usually use something like `call
+DAG.viewGraph()` to pop up a window. Alternatively, you can sprinkle calls to
these functions in your code in places you want to debug.
Getting this to work requires a small amount of setup. On Unix systems
-with X11, install the `graphviz <http://www.graphviz.org>`_ toolkit, and make
+with X11, install the [graphviz](http://www.graphviz.org) toolkit, and make
sure 'dot' and 'gv' are in your path. If you are running on macOS, download
-and install the macOS `Graphviz program
-<http://www.pixelglow.com/graphviz/>`_ and add
-``/Applications/Graphviz.app/Contents/MacOS/`` (or wherever you install it) to
+and install the macOS [Graphviz program](http://www.pixelglow.com/graphviz/) and add
+`/Applications/Graphviz.app/Contents/MacOS/` (or wherever you install it) to
your path. The programs need not be present when configuring, building or
running LLVM and can simply be installed when needed during an active debug
session.
-``SelectionDAG`` has been extended to make it easier to locate *interesting*
-nodes in large complex graphs. From gdb, if you ``call DAG.setGraphColor(node,
-"color")``, then the next ``call DAG.viewGraph()`` would highlight the node in
-the specified color (choices of colors can be found at `colors
-<http://www.graphviz.org/doc/info/colors.html>`_.) More complex node attributes
-can be provided with ``call DAG.setGraphAttrs(node, "attributes")`` (choices can
-be found at `Graph attributes <http://www.graphviz.org/doc/info/attrs.html>`_.)
+`SelectionDAG` has been extended to make it easier to locate *interesting*
+nodes in large complex graphs. From gdb, if you `call DAG.setGraphColor(node,
+"color")`, then the next `call DAG.viewGraph()` would highlight the node in
+the specified color (choices of colors can be found at [colors](http://www.graphviz.org/doc/info/colors.html).) More complex node attributes
+can be provided with `call DAG.setGraphAttrs(node, "attributes")` (choices can
+be found at [Graph attributes](http://www.graphviz.org/doc/info/attrs.html).)
If you want to restart and clear all the current graph attributes, then you can
-``call DAG.clearGraphAttrs()``.
+`call DAG.clearGraphAttrs()`.
Note that graph visualization features are compiled out of Release builds to
reduce file size. This means that you need a Debug+Asserts or Release+Asserts
build to use these features.
-.. _datastructure:
+(datastructure)=
-Picking the Right Data Structure for a Task
-===========================================
+## Picking the Right Data Structure for a Task
-LLVM has a plethora of data structures in the ``llvm/ADT/`` directory, and we
+LLVM has a plethora of data structures in the `llvm/ADT/` directory, and we
commonly use STL data structures. This section describes the trade-offs you
should consider when you pick one.
@@ -1550,7 +1429,7 @@ thing when choosing a container is the algorithmic properties of how you plan to
access the container. Based on that, you should use:
-* a :ref:`map-like <ds_map>` container if you need efficient look-up of a
+* a {ref}`map-like <ds_map>` container if you need efficient look-up of a
value based on another value. Map-like containers also support efficient
queries for containment (whether a key is in the map). Map-like containers
generally do not support efficient reverse mapping (values to keys). If you
@@ -1558,20 +1437,20 @@ access the container. Based on that, you should use:
iteration through the keys in sorted order. Map-like containers are the most
expensive sort, only use them if you need one of these capabilities.
-* a :ref:`set-like <ds_set>` container if you need to put a bunch of stuff into
+* a {ref}`set-like <ds_set>` container if you need to put a bunch of stuff into
a container that automatically eliminates duplicates. Some set-like
containers support efficient iteration through the elements in sorted order.
Set-like containers are more expensive than sequential containers.
-* a :ref:`sequential <ds_sequential>` container provides the most efficient way
+* a {ref}`sequential <ds_sequential>` container provides the most efficient way
to add elements and keeps track of the order they are added to the collection.
They permit duplicates and support efficient iteration, but do not support
efficient look-up based on a key.
-* a :ref:`string <ds_string>` container is a specialized sequential container or
+* a {ref}`string <ds_string>` container is a specialized sequential container or
reference structure that is used for character or byte arrays.
-* a :ref:`bit <ds_bit>` container provides an efficient way to store and
+* a {ref}`bit <ds_bit>` container provides an efficient way to store and
perform set operations on sets of numeric id's, while automatically
eliminating duplicates. Bit containers require a maximum of 1 bit for each
identifier you want to store.
@@ -1581,283 +1460,266 @@ memory use, constant factors, and cache behaviors of access by intelligently
picking a member of the category. Note that constant factors and cache behavior
can be a big deal. If you have a vector that usually only contains a few
elements (but could contain many), for example, it's much better to use
-:ref:`SmallVector <dss_smallvector>` than :ref:`vector <dss_vector>`. Doing so
+{ref}`SmallVector <dss_smallvector>` than {ref}`vector <dss_vector>`. Doing so
avoids (relatively) expensive malloc/free calls, which dwarf the cost of adding
the elements to the container.
-.. _ds_sequential:
+(ds_sequential)=
-Sequential Containers (std::vector, std::list, etc)
----------------------------------------------------
+### Sequential Containers (std::vector, std::list, etc)
There are a variety of sequential containers available for you, based on your
needs. Pick the first in this section that will do what you want.
-.. _dss_arrayref:
+(dss_arrayref)=
-llvm/ADT/ArrayRef.h
-^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/ArrayRef.h
-The ``llvm::ArrayRef`` class is the preferred class to use in an interface that
+The `llvm::ArrayRef` class is the preferred class to use in an interface that
accepts a sequential list of elements in memory and just reads from them. By
-taking an ``ArrayRef``, the API can be passed a fixed size array, an
-``std::vector``, an ``llvm::SmallVector`` and anything else that is contiguous
+taking an `ArrayRef`, the API can be passed a fixed size array, an
+`std::vector`, an `llvm::SmallVector` and anything else that is contiguous
in memory.
-.. _dss_fixedarrays:
+(dss_fixedarrays)=
-Fixed Size Arrays
-^^^^^^^^^^^^^^^^^
+#### Fixed Size Arrays
Fixed size arrays are very simple and very fast. They are good if you know
exactly how many elements you have, or you have a (low) upper bound on how many
you have.
-.. _dss_heaparrays:
+(dss_heaparrays)=
-Heap Allocated Arrays
-^^^^^^^^^^^^^^^^^^^^^
+#### Heap Allocated Arrays
-Heap allocated arrays (``new[]`` + ``delete[]``) are also simple. They are good
+Heap allocated arrays (`new[]` + `delete[]`) are also simple. They are good
if the number of elements is variable, if you know how many elements you will
need before the array is allocated, and if the array is usually large (if not,
-consider a :ref:`SmallVector <dss_smallvector>`). The cost of a heap allocated
+consider a {ref}`SmallVector <dss_smallvector>`). The cost of a heap allocated
array is the cost of the new/delete (aka malloc/free). Also note that if you
are allocating an array of a type with a constructor, the constructor and
destructors will be run for every element in the array (re-sizable vectors only
construct those elements actually used).
-.. _dss_tinyptrvector:
+(dss_tinyptrvector)=
-llvm/ADT/TinyPtrVector.h
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/TinyPtrVector.h
-``TinyPtrVector<Type>`` is a highly specialized collection class that is
+`TinyPtrVector<Type>` is a highly specialized collection class that is
optimized to avoid allocation in the case when a vector has zero or one
elements. It has two major restrictions: 1) it can only hold values of pointer
type, and 2) it cannot hold a null pointer.
Since this container is highly specialized, it is rarely used.
-.. _dss_smallvector:
+(dss_smallvector)=
-llvm/ADT/SmallVector.h
-^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SmallVector.h
-``SmallVector<Type, N>`` is a simple class that looks and smells just like
-``vector<Type>``: it supports efficient iteration, lays out elements in memory
+`SmallVector<Type, N>` is a simple class that looks and smells just like
+`vector<Type>`: it supports efficient iteration, lays out elements in memory
order (so you can do pointer arithmetic between elements), supports efficient
-``push_back``/``pop_back`` operations, supports efficient random access to its elements,
+`push_back`/`pop_back` operations, supports efficient random access to its elements,
etc.
-The main advantage of ``SmallVector`` is that it allocates space for some number of
-elements (N) **in the object itself**. Because of this, if the ``SmallVector`` is
+The main advantage of `SmallVector` is that it allocates space for some number of
+elements (N) **in the object itself**. Because of this, if the `SmallVector` is
dynamically smaller than N, no malloc is performed. This can be a big win in
cases where the malloc/free call is far more expensive than the code that
fiddles around with the elements.
This is good for vectors that are "usually small" (e.g., the number of
predecessors/successors of a block is usually less than 8). On the other hand,
-this makes the size of the ``SmallVector`` itself large, so you don't want to
+this makes the size of the `SmallVector` itself large, so you don't want to
allocate lots of them (doing so will waste a lot of space). As such,
SmallVectors are most useful when on the stack.
In the absence of a well-motivated choice for the number of
-inlined elements ``N``, it is recommended to use ``SmallVector<T>`` (that is,
-omitting the ``N``). This will choose a default number of
+inlined elements `N`, it is recommended to use `SmallVector<T>` (that is,
+omitting the `N`). This will choose a default number of
inlined elements reasonable for allocation on the stack (for example, trying
-to keep ``sizeof(SmallVector<T>)`` around 64 bytes).
+to keep `sizeof(SmallVector<T>)` around 64 bytes).
-``SmallVector`` also provides a nice portable and efficient replacement for
-``alloca``.
+`SmallVector` also provides a nice portable and efficient replacement for
+`alloca`.
-``SmallVector`` has grown a few other minor advantages over ``std::vector``, causing
-``SmallVector<Type, 0>`` to be preferred over ``std::vector<Type>``.
+`SmallVector` has grown a few other minor advantages over `std::vector`, causing
+`SmallVector<Type, 0>` to be preferred over `std::vector<Type>`.
-#. ``std::vector`` is exception-safe, and some implementations have pessimizations
- that copy elements when ``SmallVector`` would move them.
+1. `std::vector` is exception-safe, and some implementations have pessimizations
+ that copy elements when `SmallVector` would move them.
-#. ``SmallVector`` understands ``std::is_trivially_copyable<Type>`` and uses realloc aggressively.
+1. `SmallVector` understands `std::is_trivially_copyable<Type>` and uses realloc aggressively.
-#. Many LLVM APIs take a ``SmallVectorImpl`` as an out parameter (see the note
+1. Many LLVM APIs take a `SmallVectorImpl` as an out parameter (see the note
below).
-#. ``SmallVector`` with N equal to 0 is smaller than ``std::vector`` on 64-bit
- platforms, since it uses ``unsigned`` (instead of ``void*``) for its size
+1. `SmallVector` with N equal to 0 is smaller than `std::vector` on 64-bit
+ platforms, since it uses `unsigned` (instead of `void*`) for its size
and capacity.
-.. note::
-
- Prefer to use ``ArrayRef<T>`` or ``SmallVectorImpl<T>`` as a parameter type.
-
- It's rarely appropriate to use ``SmallVector<T, N>`` as a parameter type.
- If an API only reads from the vector, it should use :ref:`ArrayRef
- <dss_arrayref>`. Even if an API updates the vector the "small size" is
- unlikely to be relevant; such an API should use the ``SmallVectorImpl<T>``
- class, which is the "vector header" (and methods) without the elements
- allocated after it. Note that ``SmallVector<T, N>`` inherits from
- ``SmallVectorImpl<T>`` so the conversion is implicit and costs nothing. E.g.
-
- .. code-block:: c++
-
- // DISCOURAGED: Clients cannot pass e.g., raw arrays.
- hardcodedContiguousStorage(const SmallVectorImpl<Foo> &In);
- // ENCOURAGED: Clients can pass any contiguous storage of Foo.
- allowsAnyContiguousStorage(ArrayRef<Foo> In);
-
- void someFunc1() {
- Foo Vec[] = { /* ... */ };
- hardcodedContiguousStorage(Vec); // Error.
- allowsAnyContiguousStorage(Vec); // Works.
- }
-
- // DISCOURAGED: Clients cannot pass e.g., SmallVector<Foo, 8>.
- hardcodedSmallSize(SmallVector<Foo, 2> &Out);
- // ENCOURAGED: Clients can pass any SmallVector<Foo, N>.
- allowsAnySmallSize(SmallVectorImpl<Foo> &Out);
-
- void someFunc2() {
- SmallVector<Foo, 8> Vec;
- hardcodedSmallSize(Vec); // Error.
- allowsAnySmallSize(Vec); // Works.
- }
-
- Even though it has "``Impl``" in the name, SmallVectorImpl is widely used
- and is no longer "private to the implementation". A name like
- ``SmallVectorHeader`` might be more appropriate.
-
-.. _dss_pagedvector:
-
-llvm/ADT/PagedVector.h
-^^^^^^^^^^^^^^^^^^^^^^
-
-``PagedVector<Type, PageSize>`` is a random access container that allocates
-``PageSize`` elements of type ``Type`` when the first element of a page is
-accessed via the ``operator[]``. This is useful for cases where the number of
+````{note}
+Prefer to use `ArrayRef<T>` or `SmallVectorImpl<T>` as a parameter type.
+
+It's rarely appropriate to use `SmallVector<T, N>` as a parameter type.
+If an API only reads from the vector, it should use {ref}`ArrayRef <dss_arrayref>`. Even if an API updates the vector the "small size" is
+unlikely to be relevant; such an API should use the `SmallVectorImpl<T>`
+class, which is the "vector header" (and methods) without the elements
+allocated after it. Note that `SmallVector<T, N>` inherits from
+`SmallVectorImpl<T>` so the conversion is implicit and costs nothing. E.g.
+
+```cpp
+// DISCOURAGED: Clients cannot pass e.g., raw arrays.
+hardcodedContiguousStorage(const SmallVectorImpl<Foo> &In);
+// ENCOURAGED: Clients can pass any contiguous storage of Foo.
+allowsAnyContiguousStorage(ArrayRef<Foo> In);
+
+void someFunc1() {
+ Foo Vec[] = { /* ... */ };
+ hardcodedContiguousStorage(Vec); // Error.
+ allowsAnyContiguousStorage(Vec); // Works.
+}
+
+// DISCOURAGED: Clients cannot pass e.g., SmallVector<Foo, 8>.
+hardcodedSmallSize(SmallVector<Foo, 2> &Out);
+// ENCOURAGED: Clients can pass any SmallVector<Foo, N>.
+allowsAnySmallSize(SmallVectorImpl<Foo> &Out);
+
+void someFunc2() {
+ SmallVector<Foo, 8> Vec;
+ hardcodedSmallSize(Vec); // Error.
+ allowsAnySmallSize(Vec); // Works.
+}
+```
+Even though it has "`Impl`" in the name, SmallVectorImpl is widely used
+and is no longer "private to the implementation". A name like
+`SmallVectorHeader` might be more appropriate.
+````
+(dss_pagedvector)=
+
+#### llvm/ADT/PagedVector.h
+
+`PagedVector<Type, PageSize>` is a random access container that allocates
+`PageSize` elements of type `Type` when the first element of a page is
+accessed via the `operator[]`. This is useful for cases where the number of
elements is known in advance; their actual initialization is expensive; and
they are sparsely used. This utility uses page-granular lazy initialization
when the element is accessed. When the number of used pages is small
significant memory savings can be achieved.
-The main advantage is that a ``PagedVector`` allows to delay the actual
+The main advantage is that a `PagedVector` allows to delay the actual
allocation of the page until it's needed, at the extra cost of one pointer per
page and one extra indirection when accessing elements with their positional
index.
In order to minimise the memory footprint of this container, it's important to
-balance the ``PageSize`` so that it's not too small (otherwise, the overhead of the
+balance the `PageSize` so that it's not too small (otherwise, the overhead of the
pointer per page might become too high) and not too big (otherwise, the memory
is wasted if the page is not fully used).
Moreover, while retaining the order of the elements based on their insertion
-index, like a vector, iterating over the elements via ``begin()`` and ``end()``
+index, like a vector, iterating over the elements via `begin()` and `end()`
is not provided in the API, due to the fact that accessing the elements in order
would allocate all the iterated pages, defeating memory savings and the purpose
-of the ``PagedVector``.
+of the `PagedVector`.
-Finally, ``materialized_begin()`` and ``materialized_end`` iterators are
+Finally, `materialized_begin()` and `materialized_end` iterators are
provided to access the elements associated to the accessed pages, which could
speed up operations that need to iterate over initialized elements in a
non-ordered manner.
-.. _dss_vector:
+(dss_vector)=
-<vector>
-^^^^^^^^
+#### <vector>
-``std::vector<T>`` is well loved and respected. However, ``SmallVector<T, 0>``
-is often a better option due to the advantages listed above. ``std::vector`` is
-still useful when you need to store more than ``UINT32_MAX`` elements or when
+`std::vector<T>` is well loved and respected. However, `SmallVector<T, 0>`
+is often a better option due to the advantages listed above. `std::vector` is
+still useful when you need to store more than `UINT32_MAX` elements or when
interfacing with code that expects vectors :).
-One worthwhile note about ``std::vector``: avoid code like this:
-
-.. code-block:: c++
-
- for ( ... ) {
- std::vector<foo> V;
- // make use of V.
- }
+One worthwhile note about `std::vector`: avoid code like this:
+```cpp
+for ( ... ) {
+ std::vector<foo> V;
+ // make use of V.
+}
+```
Instead, write this as:
-.. code-block:: c++
-
- std::vector<foo> V;
- for ( ... ) {
- // make use of V.
- V.clear();
- }
-
+```cpp
+std::vector<foo> V;
+for ( ... ) {
+ // make use of V.
+ V.clear();
+}
+```
Doing so will save (at least) one heap allocation and free per iteration of the
loop.
-.. _dss_deque:
+(dss_deque)=
-<deque>
-^^^^^^^
+#### <deque>
-``std::deque`` is, in some senses, a generalized version of ``std::vector``.
-Like ``std::vector``, it provides constant-time random access and other similar
+`std::deque` is, in some senses, a generalized version of `std::vector`.
+Like `std::vector`, it provides constant-time random access and other similar
properties, but it also provides efficient access to the front of the list. It
does not guarantee the continuity of elements within memory.
-In exchange for this extra flexibility, ``std::deque`` has significantly higher
-constant factor costs than ``std::vector``. If possible, use ``std::vector`` or
+In exchange for this extra flexibility, `std::deque` has significantly higher
+constant factor costs than `std::vector`. If possible, use `std::vector` or
something cheaper.
-.. _dss_list:
+(dss_list)=
-<list>
-^^^^^^
+#### <list>
-``std::list`` is an extremely inefficient class that is rarely useful. It
+`std::list` is an extremely inefficient class that is rarely useful. It
performs a heap allocation for every element inserted into it, thus having an
extremely high constant factor, particularly for small data types.
-``std::list`` also only supports bidirectional iteration, not random access
+`std::list` also only supports bidirectional iteration, not random access
iteration.
-In exchange for this high cost, ``std::list`` supports efficient access to both ends
-of the list (like ``std::deque``, but unlike ``std::vector`` or
-``SmallVector``). In addition, the iterator invalidation characteristics of
-``std::list`` are stronger than that of a vector class: inserting or removing an
+In exchange for this high cost, `std::list` supports efficient access to both ends
+of the list (like `std::deque`, but unlike `std::vector` or
+`SmallVector`). In addition, the iterator invalidation characteristics of
+`std::list` are stronger than that of a vector class: inserting or removing an
element into the list does not invalidate iterator or pointers to other elements
in the list.
-.. _dss_ilist:
+(dss_ilist)=
-llvm/ADT/ilist.h
-^^^^^^^^^^^^^^^^
+#### llvm/ADT/ilist.h
-``ilist<T>`` implements an 'intrusive' doubly-linked list. It is intrusive,
+`ilist<T>` implements an 'intrusive' doubly-linked list. It is intrusive,
because it requires the element to store and provide access to the prev/next
pointers for the list.
-``ilist`` has the same drawbacks as ``std::list``, and additionally requires an
-``ilist_traits`` implementation for the element type, but it provides some novel
+`ilist` has the same drawbacks as `std::list`, and additionally requires an
+`ilist_traits` implementation for the element type, but it provides some novel
characteristics. In particular, it can efficiently store polymorphic objects,
the traits class is informed when an element is inserted or removed from the
-list, and ``ilist``\ s are guaranteed to support a constant-time splice
+list, and `ilist`s are guaranteed to support a constant-time splice
operation.
-An ``ilist`` and an ``iplist`` are ``using`` aliases to one another and the
+An `ilist` and an `iplist` are `using` aliases to one another and the
latter only currently exists for historical purposes.
-These properties are exactly what we want for things like ``Instruction``\ s and
-basic blocks, which is why these are implemented with ``ilist``\ s.
+These properties are exactly what we want for things like `Instruction`s and
+basic blocks, which is why these are implemented with `ilist`s.
Related classes of interest are explained in the following subsections:
-* :ref:`ilist_traits <dss_ilist_traits>`
+* {ref}`ilist_traits <dss_ilist_traits>`
-* :ref:`llvm/ADT/ilist_node.h <dss_ilist_node>`
+* {ref}`llvm/ADT/ilist_node.h <dss_ilist_node>`
-* :ref:`Sentinels <dss_ilist_sentinel>`
+* {ref}`Sentinels <dss_ilist_sentinel>`
-.. _dss_packedvector:
+(dss_packedvector)=
-llvm/ADT/PackedVector.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/PackedVector.h
Useful for storing a vector of values using only a few bits for each
value. Apart from the standard operations of a vector-like container, it can
@@ -1865,155 +1727,146 @@ also perform an 'or' set operation.
For example:
-.. code-block:: c++
-
- enum State {
- None = 0x0,
- FirstCondition = 0x1,
- SecondCondition = 0x2,
- Both = 0x3
- };
+```cpp
+enum State {
+ None = 0x0,
+ FirstCondition = 0x1,
+ SecondCondition = 0x2,
+ Both = 0x3
+};
- State get() {
- PackedVector<State, 2> Vec1;
- Vec1.push_back(FirstCondition);
+State get() {
+ PackedVector<State, 2> Vec1;
+ Vec1.push_back(FirstCondition);
- PackedVector<State, 2> Vec2;
- Vec2.push_back(SecondCondition);
+ PackedVector<State, 2> Vec2;
+ Vec2.push_back(SecondCondition);
- Vec1 |= Vec2;
- return Vec1[0]; // returns 'Both'.
- }
+ Vec1 |= Vec2;
+ return Vec1[0]; // returns 'Both'.
+}
+```
+(dss_ilist_traits)=
-.. _dss_ilist_traits:
+#### ilist_traits
-ilist_traits
-^^^^^^^^^^^^
-
-``ilist_traits<T>`` is ``ilist<T>``'s customization mechanism. ``ilist<T>``
+`ilist_traits<T>` is `ilist<T>`'s customization mechanism. `ilist<T>`
publicly derives from this traits class.
-.. _dss_ilist_node:
+(dss_ilist_node)=
-llvm/ADT/ilist_node.h
-^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/ilist_node.h
-``ilist_node<T>`` implements the forward and backward links that are expected
-by the ``ilist<T>`` (and analogous containers) in the default manner.
+`ilist_node<T>` implements the forward and backward links that are expected
+by the `ilist<T>` (and analogous containers) in the default manner.
-``ilist_node<T>``\ s are meant to be embedded in the node type ``T``, usually
-``T`` publicly derives from ``ilist_node<T>``.
+`ilist_node<T>`s are meant to be embedded in the node type `T`, usually
+`T` publicly derives from `ilist_node<T>`.
-.. _dss_ilist_sentinel:
+(dss_ilist_sentinel)=
-Sentinels
-^^^^^^^^^
+#### Sentinels
-``ilist``\ s have another specialty that must be considered. To be a good
+`ilist`s have another specialty that must be considered. To be a good
citizen in the C++ ecosystem, it needs to support the standard container
-operations, such as ``begin`` and ``end`` iterators, etc. Also, the
-``operator--`` must work correctly on the ``end`` iterator in the case of
-non-empty ``ilist``\ s.
+operations, such as `begin` and `end` iterators, etc. Also, the
+`operator--` must work correctly on the `end` iterator in the case of
+non-empty `ilist`s.
The only sensible solution to this problem is to allocate a so-called *sentinel*
-along with the intrusive list, which serves as the ``end`` iterator, providing
+along with the intrusive list, which serves as the `end` iterator, providing
the back-link to the last element. However, conforming to the C++ convention it
-is illegal to ``operator++`` beyond the sentinel and it also must not be
+is illegal to `operator++` beyond the sentinel and it also must not be
dereferenced.
-These constraints allow for some implementation freedom to the ``ilist`` how to
+These constraints allow for some implementation freedom to the `ilist` how to
allocate and store the sentinel. The corresponding policy is dictated by
-``ilist_traits<T>``. By default, a ``T`` gets heap-allocated whenever the need
+`ilist_traits<T>`. By default, a `T` gets heap-allocated whenever the need
for a sentinel arises.
While the default policy is sufficient in most cases, it may break down when
-``T`` does not provide a default constructor. Also, in the case of many
-instances of ``ilist``\ s, the memory overhead of the associated sentinels is
+`T` does not provide a default constructor. Also, in the case of many
+instances of `ilist`s, the memory overhead of the associated sentinels is
wasted. To alleviate the situation with numerous and voluminous
-``T``-sentinels, sometimes a trick is employed, leading to *ghostly sentinels*.
+`T`-sentinels, sometimes a trick is employed, leading to *ghostly sentinels*.
-Ghostly sentinels are obtained by specially-crafted ``ilist_traits<T>`` which
-superpose the sentinel with the ``ilist`` instance in memory. Pointer
-arithmetic is used to obtain the sentinel, which is relative to the ``ilist``'s
-``this`` pointer. The ``ilist`` is augmented by an extra pointer, which serves
+Ghostly sentinels are obtained by specially-crafted `ilist_traits<T>` which
+superpose the sentinel with the `ilist` instance in memory. Pointer
+arithmetic is used to obtain the sentinel, which is relative to the `ilist`'s
+`this` pointer. The `ilist` is augmented by an extra pointer, which serves
as the back-link of the sentinel. This is the only field in the ghostly
sentinel which can be legally accessed.
-.. _dss_other:
+(dss_other)=
-Other Sequential Container options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Other Sequential Container options
-Other STL containers are available, such as ``std::string``.
+Other STL containers are available, such as `std::string`.
-There are also various STL adapter classes such as ``std::queue``,
-``std::priority_queue``, ``std::stack``, etc. These provide simplified access
+There are also various STL adapter classes such as `std::queue`,
+`std::priority_queue`, `std::stack`, etc. These provide simplified access
to an underlying container but don't affect the cost of the container itself.
-.. _ds_string:
+(ds_string)=
-String-like containers
-----------------------
+### String-like containers
There are a variety of ways to pass around and use strings in C and C++, and
LLVM adds a few new options to choose from. Pick the first option on this list
that will do what you need; they are ordered according to their relative cost.
-Note that it is generally preferred to *not* pass strings around as ``const
-char*``'s. These have a number of problems, including the fact that they
+Note that it is generally preferred to *not* pass strings around as `const
+char*`'s. These have a number of problems, including the fact that they
cannot represent embedded nul ("\0") characters, and do not have a length
-available efficiently. The general replacement for '``const char*``' is
-``StringRef``.
+available efficiently. The general replacement for '`const char*`' is
+`StringRef`.
For more information on choosing string containers for APIs, please see
-:ref:`Passing Strings <string_apis>`.
+{ref}`Passing Strings <string_apis>`.
-.. _dss_stringref:
+(dss_stringref)=
-llvm/ADT/StringRef.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/StringRef.h
-The ``StringRef`` class is a simple value class that contains a pointer to a
-character and a length, and is quite related to the :ref:`ArrayRef
-<dss_arrayref>` class (but specialized for arrays of characters). Because
-``StringRef`` carries a length with it, it safely handles strings with embedded nul
+The `StringRef` class is a simple value class that contains a pointer to a
+character and a length, and is quite related to the {ref}`ArrayRef <dss_arrayref>` class (but specialized for arrays of characters). Because
+`StringRef` carries a length with it, it safely handles strings with embedded nul
characters in it, getting the length does not require a strlen call, and it even
has very convenient APIs for slicing and dicing the character range that it
represents.
-``StringRef`` is ideal for passing simple strings around that are known to be live,
-either because they are C string literals, ``std::string``, a C array, or a
-``SmallVector``. Each of these cases has an efficient implicit conversion to
-``StringRef``, which doesn't result in a dynamic ``strlen`` being executed.
+`StringRef` is ideal for passing simple strings around that are known to be live,
+either because they are C string literals, `std::string`, a C array, or a
+`SmallVector`. Each of these cases has an efficient implicit conversion to
+`StringRef`, which doesn't result in a dynamic `strlen` being executed.
-``StringRef`` has a few major limitations which make more powerful string containers
+`StringRef` has a few major limitations which make more powerful string containers
useful:
-#. You cannot directly convert a ``StringRef`` to a ``const char*`` because there is
- no way to add a trailing nul (unlike the ``.c_str()`` method on various stronger
+1. You cannot directly convert a `StringRef` to a `const char*` because there is
+ no way to add a trailing nul (unlike the `.c_str()` method on various stronger
classes).
-#. ``StringRef`` doesn't own or keep alive the underlying string bytes.
+1. `StringRef` doesn't own or keep alive the underlying string bytes.
As such, it can easily lead to dangling pointers, and is not suitable for
- embedding in datastructures in most cases (instead, use an ``std::string`` or
+ embedding in datastructures in most cases (instead, use an `std::string` or
something like that).
-#. For the same reason, ``StringRef`` cannot be used as the return value of a
- method if the method "computes" the result string. Instead, use ``std::string``.
+1. For the same reason, `StringRef` cannot be used as the return value of a
+ method if the method "computes" the result string. Instead, use `std::string`.
-#. ``StringRef``'s do not allow you to mutate the pointed-to string bytes and it
+1. `StringRef`'s do not allow you to mutate the pointed-to string bytes and it
doesn't allow you to insert or remove bytes from the range. For editing
- operations like this, it interoperates with the :ref:`Twine <dss_twine>`
+ operations like this, it interoperates with the {ref}`Twine <dss_twine>`
class.
Because of its strengths and limitations, it is very common for a function to
-take a ``StringRef`` and for a method on an object to return a ``StringRef`` that points
+take a `StringRef` and for a method on an object to return a `StringRef` that points
into some string that it owns.
-.. _dss_twine:
+(dss_twine)=
-llvm/ADT/Twine.h
-^^^^^^^^^^^^^^^^
+#### llvm/ADT/Twine.h
The Twine class is used as an intermediary datatype for APIs that want to take a
string that can be constructed inline with a series of concatenations. Twine
@@ -2022,14 +1875,13 @@ object) on the stack as temporary objects, linking them together into a tree
which is then linearized when the Twine is consumed. Twine is only safe to use
as the argument to a function, and should always be a const reference, e.g.:
-.. code-block:: c++
-
- void foo(const Twine &T);
- ...
- StringRef X = ...
- unsigned i = ...
- foo(X + "." + Twine(i));
-
+```cpp
+void foo(const Twine &T);
+...
+StringRef X = ...
+unsigned i = ...
+foo(X + "." + Twine(i));
+```
This example forms a string like "blarg.42" by concatenating the values
together, and does not form intermediate strings containing "blarg" or "blarg.".
@@ -2038,159 +1890,147 @@ these instances are destroyed at the end of the current statement, it is an
inherently dangerous API. For example, this simple variant contains undefined
behavior and will probably crash:
-.. code-block:: c++
-
- void foo(const Twine &T);
- ...
- StringRef X = ...
- unsigned i = ...
- const Twine &Tmp = X + "." + Twine(i);
- foo(Tmp);
-
-... because the temporaries are destroyed before the call. That said, ``Twine``'s
-are much more efficient than intermediate ``std::string`` temporaries, and they work
-really well with ``StringRef``. Just be aware of their limitations.
+```cpp
+void foo(const Twine &T);
+...
+StringRef X = ...
+unsigned i = ...
+const Twine &Tmp = X + "." + Twine(i);
+foo(Tmp);
+```
+... because the temporaries are destroyed before the call. That said, `Twine`'s
+are much more efficient than intermediate `std::string` temporaries, and they work
+really well with `StringRef`. Just be aware of their limitations.
-.. _dss_smallstring:
+(dss_smallstring)=
-llvm/ADT/SmallString.h
-^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SmallString.h
-``SmallString`` is a subclass of :ref:`SmallVector <dss_smallvector>` that adds some
-convenience APIs like += that takes ``StringRef``'s. ``SmallString`` avoids allocating
+`SmallString` is a subclass of {ref}`SmallVector <dss_smallvector>` that adds some
+convenience APIs like += that takes `StringRef`'s. `SmallString` avoids allocating
memory in the case when the preallocated space is enough to hold its data, and
it calls back to general heap allocation when required. Since it owns its data,
it is very safe to use and supports full mutation of the string.
-Like ``SmallVector``'s, the big downside to ``SmallString`` is their sizeof. While they
+Like `SmallVector`'s, the big downside to `SmallString` is their sizeof. While they
are optimized for small strings, they themselves are not particularly small.
This means that they work great for temporary scratch buffers on the stack, but
-should not generally be put into the heap: it is very rare to see a ``SmallString``
+should not generally be put into the heap: it is very rare to see a `SmallString`
as the member of a frequently-allocated heap data structure or returned
by-value.
-.. _dss_stdstring:
+(dss_stdstring)=
-std::string
-^^^^^^^^^^^
+#### std::string
-The standard C++ ``std::string`` class is a very general class that (like
-``SmallString``) owns its underlying data. sizeof(std::string) is very reasonable
+The standard C++ `std::string` class is a very general class that (like
+`SmallString`) owns its underlying data. sizeof(std::string) is very reasonable
so it can be embedded into heap data structures and returned by-value. On the
-other hand, ``std::string`` is highly inefficient for inline editing (e.g.
+other hand, `std::string` is highly inefficient for inline editing (e.g.
concatenating a bunch of stuff together) and because it is provided by the
standard library, its performance characteristics depend a lot of the host
standard library (e.g., libc++ and MSVC provide a highly optimized string class,
GCC contains a really slow implementation).
-The major disadvantage of ``std::string`` is that almost every operation that makes
+The major disadvantage of `std::string` is that almost every operation that makes
them larger can allocate memory, which is slow. As such, it is better to use
-``SmallVector`` or ``Twine`` as a scratch buffer, but then use ``std::string`` to persist
+`SmallVector` or `Twine` as a scratch buffer, but then use `std::string` to persist
the result.
-.. _ds_set:
+(ds_set)=
-Set-Like Containers (std::set, SmallSet, SetVector, etc)
---------------------------------------------------------
+### Set-Like Containers (std::set, SmallSet, SetVector, etc)
Set-like containers are useful when you need to canonicalize multiple values
into a single representation. There are several different choices for how to do
this, providing various trade-offs.
-.. _dss_sortedvectorset:
+(dss_sortedvectorset)=
-A sorted 'vector'
-^^^^^^^^^^^^^^^^^
+#### A sorted 'vector'
If you intend to insert a lot of elements, then do a lot of queries, a great
-approach is to use an ``std::vector`` (or other sequential container) with
-``std::sort``+``std::unique`` to remove duplicates. This approach works really well if
+approach is to use an `std::vector` (or other sequential container) with
+`std::sort`+`std::unique` to remove duplicates. This approach works really well if
your usage pattern has these two distinct phases (insert then query), and can be
-coupled with a good choice of :ref:`sequential container <ds_sequential>`.
+coupled with a good choice of {ref}`sequential container <ds_sequential>`.
This combination provides the several nice properties: the result data is
contiguous in memory (good for cache locality), has few allocations, is easy to
address (iterators in the final vector are just indices or pointers), and can be
efficiently queried with a standard binary search (e.g.
-``std::lower_bound``; if you want the whole range of elements comparing
-equal, use ``std::equal_range``).
+`std::lower_bound`; if you want the whole range of elements comparing
+equal, use `std::equal_range`).
-.. _dss_smallset:
+(dss_smallset)=
-llvm/ADT/SmallSet.h
-^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SmallSet.h
If you have a set-like data structure that is usually small and whose elements
-are reasonably small, a ``SmallSet<Type, N>`` is a good choice. This set has
+are reasonably small, a `SmallSet<Type, N>` is a good choice. This set has
space for N elements in place (thus, if the set is dynamically smaller than N,
no malloc traffic is required) and accesses them with a simple linear search.
When the set grows beyond N elements, it allocates a more expensive
representation that guarantees efficient access (for most types, it falls back
-to :ref:`std::set <dss_set>`, but for pointers it uses something far better,
-:ref:`SmallPtrSet <dss_smallptrset>`.
+to {ref}`std::set <dss_set>`, but for pointers it uses something far better,
+{ref}`SmallPtrSet <dss_smallptrset>`.
The magic of this class is that it handles small sets extremely efficiently, but
gracefully handles extremely large sets without loss of efficiency.
-.. _dss_smallptrset:
+(dss_smallptrset)=
-llvm/ADT/SmallPtrSet.h
-^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SmallPtrSet.h
-``SmallPtrSet`` has all the advantages of ``SmallSet`` (and a ``SmallSet`` of
-pointers is transparently implemented with a ``SmallPtrSet``). If more than N
+`SmallPtrSet` has all the advantages of `SmallSet` (and a `SmallSet` of
+pointers is transparently implemented with a `SmallPtrSet`). If more than N
insertions are performed, a single quadratically probed hash table is allocated
and grows as needed, providing extremely efficient access (constant time
insertion/deleting/queries with low constant factors) and is very stingy with
malloc traffic.
-Note that, unlike :ref:`std::set <dss_set>`, the iterators of ``SmallPtrSet``
-are invalidated whenever an insertion or erasure occurs. The ``remove_if``
+Note that, unlike {ref}`std::set <dss_set>`, the iterators of `SmallPtrSet`
+are invalidated whenever an insertion or erasure occurs. The `remove_if`
method can be used to remove elements while iterating over the set.
Also, the values visited by the iterators are not visited in sorted order.
-.. _dss_stringset:
+(dss_stringset)=
-llvm/ADT/StringSet.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/StringSet.h
-``StringSet`` is a thin wrapper around :ref:`StringMap\<char\> <dss_stringmap>`,
+`StringSet` is a thin wrapper around {ref}`StringMap <dss_stringmap>`\<char\>,
and it allows efficient storage and retrieval of unique strings.
-Functionally analogous to ``SmallSet<StringRef>``, ``StringSet`` also supports
-iteration. (The iterator dereferences to a ``StringMapEntry<char>``, so you
-need to call ``i->getKey()`` to access the item of the StringSet.) On the
-other hand, ``StringSet`` doesn't support range-insertion and
-copy-construction, which :ref:`SmallSet <dss_smallset>` and :ref:`SmallPtrSet
-<dss_smallptrset>` do support.
+Functionally analogous to `SmallSet<StringRef>`, `StringSet` also supports
+iteration. (The iterator dereferences to a `StringMapEntry<char>`, so you
+need to call `i->getKey()` to access the item of the StringSet.) On the
+other hand, `StringSet` doesn't support range-insertion and
+copy-construction, which {ref}`SmallSet <dss_smallset>` and {ref}`SmallPtrSet <dss_smallptrset>` do support.
-.. _dss_denseset:
+(dss_denseset)=
-llvm/ADT/DenseSet.h
-^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/DenseSet.h
-``DenseSet`` is a simple quadratically probed hash table. It excels at supporting
+`DenseSet` is a simple quadratically probed hash table. It excels at supporting
small values: it uses a single allocation to hold all of the pairs that are
-currently inserted in the set. ``DenseSet`` is a great way to unique small values
-that are not simple pointers (use :ref:`SmallPtrSet <dss_smallptrset>` for
-pointers). Note that ``DenseSet`` has the same requirements for the value type that
-:ref:`DenseMap <dss_densemap>` has.
+currently inserted in the set. `DenseSet` is a great way to unique small values
+that are not simple pointers (use {ref}`SmallPtrSet <dss_smallptrset>` for
+pointers). Note that `DenseSet` has the same requirements for the value type that
+{ref}`DenseMap <dss_densemap>` has.
-.. _dss_radixtree:
+(dss_radixtree)=
-llvm/ADT/RadixTree.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/RadixTree.h
-``RadixTree`` is a trie-based data structure that stores range-like keys and
+`RadixTree` is a trie-based data structure that stores range-like keys and
their associated values. It is particularly efficient for storing keys that
share common prefixes, as it can compress these prefixes to save memory. It
supports efficient search of matching prefixes.
-.. _dss_sparseset:
+(dss_sparseset)=
-llvm/ADT/SparseSet.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SparseSet.h
SparseSet holds a small number of objects identified by unsigned keys of
moderate size. It uses a lot of memory, but provides operations that are almost
@@ -2201,31 +2041,29 @@ SparseSet is useful for algorithms that need very fast clear/find/insert/erase
and fast iteration over small sets. It is not intended for building composite
data structures.
-.. _dss_sparsemultiset:
+(dss_sparsemultiset)=
-llvm/ADT/SparseMultiSet.h
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SparseMultiSet.h
-``SparseMultiSet`` adds multiset behavior to ``SparseSet``, while retaining ``SparseSet``'s
-desirable attributes. Like ``SparseSet``, it typically uses a lot of memory, but
+`SparseMultiSet` adds multiset behavior to `SparseSet`, while retaining `SparseSet`'s
+desirable attributes. Like `SparseSet`, it typically uses a lot of memory, but
provides operations that are almost as fast as a vector. Typical keys are
physical registers, virtual registers, or numbered basic blocks.
-``SparseMultiSet`` is useful for algorithms that need very fast
+`SparseMultiSet` is useful for algorithms that need very fast
clear/find/insert/erase of the entire collection, and iteration over sets of
elements sharing a key. It is often a more efficient choice than using composite
data structures (e.g., vector-of-vectors, map-of-vectors). It is not intended for
building composite data structures.
-.. _dss_FoldingSet:
+(dss_FoldingSet)=
-llvm/ADT/FoldingSet.h
-^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/FoldingSet.h
-``FoldingSet`` is an aggregate class that is really good at uniquing
+`FoldingSet` is an aggregate class that is really good at uniquing
expensive-to-create or polymorphic objects. It is a combination of a chained
hash table with intrusive links (uniqued objects are required to inherit from
-``FoldingSetNode``) that uses :ref:`SmallVector <dss_smallvector>` as part of its ID
+`FoldingSetNode`) that uses {ref}`SmallVector <dss_smallvector>` as part of its ID
process.
Consider a case where you want to implement a "getOrCreateFoo" method for a
@@ -2235,25 +2073,24 @@ operands), but we don't want to 'new' a node, then try inserting it into a set
only to find out it already exists, at which point we would have to delete it
and return the node that already exists.
-To support this style of client, ``FoldingSet`` perform a query with a
-``FoldingSetNodeID`` (which wraps ``SmallVector``) that can be used to describe the
+To support this style of client, `FoldingSet` perform a query with a
+`FoldingSetNodeID` (which wraps `SmallVector`) that can be used to describe the
element that we want to query for. The query either returns the element
matching the ID or it returns an opaque ID that indicates where insertion should
take place. Construction of the ID usually does not require heap traffic.
-Because ``FoldingSet`` uses intrusive links, it can support polymorphic objects in
-the set (for example, you can have ``SDNode`` instances mixed with ``LoadSDNodes``).
+Because `FoldingSet` uses intrusive links, it can support polymorphic objects in
+the set (for example, you can have `SDNode` instances mixed with `LoadSDNodes`).
Because the elements are individually allocated, pointers to the elements are
stable: inserting or removing elements does not invalidate any pointers to other
elements.
-.. _dss_set:
+(dss_set)=
-<set>
-^^^^^
+#### <set>
-``std::set`` is a reasonable all-around set class, which is decent at many
-things but great at nothing. ``std::set`` allocates memory for each element
+`std::set` is a reasonable all-around set class, which is decent at many
+things but great at nothing. `std::set` allocates memory for each element
inserted (thus it is very malloc intensive) and typically stores three pointers
per element in the set (thus adding a large amount of per-element space
overhead). It offers guaranteed log(n) performance, which is not particularly
@@ -2261,53 +2098,51 @@ fast from a complexity standpoint (particularly if the elements of the set are
expensive to compare, like strings), and has extremely high constant factors for
lookup, insertion and removal.
-The advantages of ``std::set`` are that its iterators are stable (deleting or
+The advantages of `std::set` are that its iterators are stable (deleting or
inserting an element from the set does not affect iterators or pointers to other
elements) and that iteration over the set is guaranteed to be in sorted order.
If the elements in the set are large, then the relative overhead of the pointers
and malloc traffic is not a big deal, but if the elements of the set are small,
-``std::set`` is almost never a good choice.
+`std::set` is almost never a good choice.
-.. _dss_setvector:
+(dss_setvector)=
-llvm/ADT/SetVector.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/SetVector.h
-LLVM's ``SetVector<Type>`` is an adapter class that combines your choice of a
-set-like container along with a :ref:`Sequential Container <ds_sequential>` The
+LLVM's `SetVector<Type>` is an adapter class that combines your choice of a
+set-like container along with a {ref}`Sequential Container <ds_sequential>` The
important property that this provides is efficient insertion with uniquing
(duplicate elements are ignored) with iteration support. It implements this by
inserting elements into both a set-like container and the sequential container,
using the set-like container for uniquing and the sequential container for
iteration.
-The difference between ``SetVector`` and other sets is that the order of iteration
-is guaranteed to match the order of insertion into the ``SetVector``. This property
+The difference between `SetVector` and other sets is that the order of iteration
+is guaranteed to match the order of insertion into the `SetVector`. This property
is really important for things like sets of pointers. Because pointer values
are non-deterministic (e.g., vary across runs of the program on different
machines), iterating over the pointers in the set will not be in a well-defined
order.
-The drawback of ``SetVector`` is that it requires twice as much space as a normal
+The drawback of `SetVector` is that it requires twice as much space as a normal
set and has the sum of constant factors from the set-like container and the
sequential container that it uses. Use it **only** if you need to iterate over
-the elements in a deterministic order. ``SetVector`` is also expensive to delete
+the elements in a deterministic order. `SetVector` is also expensive to delete
elements out of (linear time), unless you use its "pop_back" method, which is
faster.
-``SetVector`` is an adapter class that defaults to using ``std::vector`` and a
-size 16 ``SmallSet`` for the underlying containers, so it is quite expensive.
-However, ``"llvm/ADT/SetVector.h"`` also provides a ``SmallSetVector`` class,
-which defaults to using a ``SmallVector`` and ``SmallSet`` of a specified size.
-If you use this, and if your sets are dynamically smaller than ``N``, you will
+`SetVector` is an adapter class that defaults to using `std::vector` and a
+size 16 `SmallSet` for the underlying containers, so it is quite expensive.
+However, `"llvm/ADT/SetVector.h"` also provides a `SmallSetVector` class,
+which defaults to using a `SmallVector` and `SmallSet` of a specified size.
+If you use this, and if your sets are dynamically smaller than `N`, you will
save a lot of heap traffic.
-.. _dss_uniquevector:
+(dss_uniquevector)=
-llvm/ADT/UniqueVector.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/UniqueVector.h
-UniqueVector is similar to :ref:`SetVector <dss_setvector>` but it retains a
+UniqueVector is similar to {ref}`SetVector <dss_setvector>` but it retains a
unique ID for each element inserted into the set. It internally contains a map
and a vector, and it assigns a unique ID for each value inserted into the set.
@@ -2315,94 +2150,87 @@ UniqueVector is very expensive: its cost is the sum of the cost of maintaining
both the map and vector, it has high complexity, high constant factors, and
produces a lot of malloc traffic. It should be avoided.
-.. _dss_immutableset:
+(dss_immutableset)=
-llvm/ADT/ImmutableSet.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/ImmutableSet.h
-``ImmutableSet`` is an immutable (functional) set implementation based on an AVL
+`ImmutableSet` is an immutable (functional) set implementation based on an AVL
tree. Adding or removing elements is done through a Factory object and results
-in the creation of a new ``ImmutableSet`` object. If an ``ImmutableSet`` already exists
+in the creation of a new `ImmutableSet` object. If an `ImmutableSet` already exists
with the given contents, then the existing one is returned; equality is compared
-with a ``FoldingSetNodeID``. The time and space complexity of add or remove
+with a `FoldingSetNodeID`. The time and space complexity of add or remove
operations is logarithmic in the size of the original set.
There is no method for returning an element of the set, you can only check for
membership.
-.. _dss_otherset:
+(dss_otherset)=
-Other Set-Like Container Options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Other Set-Like Container Options
-The STL provides several other options, such as ``std::multiset`` and
-``std::unordered_set``. We never use containers like ``unordered_set`` because
+The STL provides several other options, such as `std::multiset` and
+`std::unordered_set`. We never use containers like `unordered_set` because
they are generally very expensive (each insertion requires a malloc).
-``std::multiset`` is useful if you're not interested in elimination of duplicates,
-but has all the drawbacks of :ref:`std::set <dss_set>`. A sorted vector
+`std::multiset` is useful if you're not interested in elimination of duplicates,
+but has all the drawbacks of {ref}`std::set <dss_set>`. A sorted vector
(where you don't delete duplicate entries) or some other approach is almost
always better.
-.. _ds_map:
+(ds_map)=
-Map-Like Containers (std::map, DenseMap, etc)
----------------------------------------------
+### Map-Like Containers (std::map, DenseMap, etc)
Map-like containers are useful when you want to associate data to a key. As
usual, there are a lot of different ways to do this. :)
-.. _dss_sortedvectormap:
+(dss_sortedvectormap)=
-A sorted 'vector'
-^^^^^^^^^^^^^^^^^
+#### A sorted 'vector'
If your usage pattern follows a strict insert-then-query approach, you can
-trivially use the same approach as :ref:`sorted vectors for set-like containers
-<dss_sortedvectorset>`. The only difference is that your query function (which
-uses ``std::lower_bound`` to get efficient log(n) lookup) should only compare the
+trivially use the same approach as {ref}`sorted vectors for set-like containers <dss_sortedvectorset>`. The only difference is that your query function (which
+uses `std::lower_bound` to get efficient log(n) lookup) should only compare the
key, not both the key and value. This yields the same advantages as sorted
vectors for sets.
-.. _dss_stringmap:
+(dss_stringmap)=
-llvm/ADT/StringMap.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/StringMap.h
Strings are commonly used as keys in maps, and they are difficult to support
efficiently: they are variable length, inefficient to hash and compare when
-long, expensive to copy, etc. ``StringMap`` is a specialized container designed to
+long, expensive to copy, etc. `StringMap` is a specialized container designed to
cope with these issues. It supports mapping an arbitrary range of bytes to an
arbitrary other object.
-The ``StringMap`` implementation uses a quadratically-probed hash table, where the
+The `StringMap` implementation uses a quadratically-probed hash table, where the
buckets store a pointer to the heap allocated entries (and some other stuff).
The entries in the map must be heap allocated because the strings are variable
length. The string data (key) and the element object (value) are stored in the
same allocation with the string data immediately after the element object.
-This container guarantees the "``(char*)(&Value+1)``" points to the key string
+This container guarantees the "`(char*)(&Value+1)`" points to the key string
for a value.
-The ``StringMap`` is very fast for several reasons: quadratic probing is very cache
+The `StringMap` is very fast for several reasons: quadratic probing is very cache
efficient for lookups, the hash value of strings in buckets is not recomputed
-when looking up an element, ``StringMap`` rarely has to touch the memory for
+when looking up an element, `StringMap` rarely has to touch the memory for
unrelated objects when looking up a value (even when hash collisions happen),
hash table growth does not recompute the hash values for strings already in the
table, and each pair in the map is store in a single allocation (the string data
is stored in the same allocation as the Value of a pair).
-``StringMap`` also provides query methods that take byte ranges, so it only ever
+`StringMap` also provides query methods that take byte ranges, so it only ever
copies a string if a value is inserted into the table.
-``StringMap`` iteration order, however, is not guaranteed to be deterministic, so
-any uses which require that should instead use a ``std::map``.
+`StringMap` iteration order, however, is not guaranteed to be deterministic, so
+any uses which require that should instead use a `std::map`.
-.. _dss_indexmap:
+(dss_indexmap)=
-llvm/ADT/IndexedMap.h
-^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/IndexedMap.h
-``IndexedMap`` is a specialized container for mapping small dense integers (or
+`IndexedMap` is a specialized container for mapping small dense integers (or
values that can be mapped to small dense integers) to some other type. It is
internally implemented as a vector with a mapping function that maps the keys
to the dense integer range.
@@ -2411,94 +2239,88 @@ This is useful for cases like virtual registers in the LLVM code generator: they
have a dense mapping that is offset by a compile-time constant (the first
virtual register ID).
-.. _dss_densemap:
+(dss_densemap)=
-llvm/ADT/DenseMap.h
-^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/DenseMap.h
-``DenseMap`` is a simple quadratically probed hash table. It excels at supporting
+`DenseMap` is a simple quadratically probed hash table. It excels at supporting
small keys and values: it uses a single allocation to hold all of the pairs
-that are currently inserted in the map. ``DenseMap`` is a great way to map
+that are currently inserted in the map. `DenseMap` is a great way to map
pointers to pointers, or map other small types to each other.
-There are several aspects of ``DenseMap`` that you should be aware of, however.
-The iterators in a ``DenseMap`` are invalidated whenever an insertion or
-erasure occurs, unlike ``map``. Also, because ``DenseMap`` allocates space for
+There are several aspects of `DenseMap` that you should be aware of, however.
+The iterators in a `DenseMap` are invalidated whenever an insertion or
+erasure occurs, unlike `map`. Also, because `DenseMap` allocates space for
a large number of key/value pairs (it starts with 64 by default), it will waste
a lot of space if your keys or values are large. Finally, you must implement a
-partial specialization of ``DenseMapInfo`` for the key that you want, if it
-isn't already supported. This is required to tell ``DenseMap`` about two
+partial specialization of `DenseMapInfo` for the key that you want, if it
+isn't already supported. This is required to tell `DenseMap` about two
special marker values (which can never be inserted into the map) that it needs
internally.
-``DenseMap``'s ``find_as()`` method supports lookup operations using an alternate key
+`DenseMap`'s `find_as()` method supports lookup operations using an alternate key
type. This is useful in cases where the normal key type is expensive to
-construct, but cheap to compare against. The ``DenseMapInfo`` is responsible for
+construct, but cheap to compare against. The `DenseMapInfo` is responsible for
defining the appropriate comparison and hashing methods for each alternate key
type used.
-``DenseMap.h`` also contains a ``SmallDenseMap`` variant, that similar to
-:ref:`SmallVector <dss_smallvector>` performs no heap allocation until the
+`DenseMap.h` also contains a `SmallDenseMap` variant, that similar to
+{ref}`SmallVector <dss_smallvector>` performs no heap allocation until the
number of elements in the template parameter N are exceeded.
-.. _dss_valuemap:
+(dss_valuemap)=
-llvm/IR/ValueMap.h
-^^^^^^^^^^^^^^^^^^^
+#### llvm/IR/ValueMap.h
-ValueMap is a wrapper around a :ref:`DenseMap <dss_densemap>` mapping
-``Value*``\ s (or subclasses) to another type. When a Value is deleted or
-RAUW'ed, ``ValueMap`` will update itself so the new version of the key is mapped to
+ValueMap is a wrapper around a {ref}`DenseMap <dss_densemap>` mapping
+`Value*`s (or subclasses) to another type. When a Value is deleted or
+RAUW'ed, `ValueMap` will update itself so the new version of the key is mapped to
the same value, just as if the key were a WeakVH. You can configure exactly how
-this happens, and what else happens on these two events, by passing a ``Config``
-parameter to the ``ValueMap`` template.
+this happens, and what else happens on these two events, by passing a `Config`
+parameter to the `ValueMap` template.
-.. _dss_intervalmap:
+(dss_intervalmap)=
-llvm/ADT/IntervalMap.h
-^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/IntervalMap.h
-``IntervalMap`` is a compact map for small keys and values. It maps key intervals
+`IntervalMap` is a compact map for small keys and values. It maps key intervals
instead of single keys, and it will automatically coalesce adjacent intervals.
When the map only contains a few intervals, they are stored in the map object
itself to avoid allocations.
-The ``IntervalMap`` iterators are quite big, so they should not be passed around as
+The `IntervalMap` iterators are quite big, so they should not be passed around as
STL iterators. The heavyweight iterators allow a smaller data structure.
-.. _dss_intervaltree:
+(dss_intervaltree)=
-llvm/ADT/IntervalTree.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/IntervalTree.h
-``llvm::IntervalTree`` is a light tree data structure to hold intervals. It
+`llvm::IntervalTree` is a light tree data structure to hold intervals. It
allows finding all intervals that overlap with any given point. At this time,
it does not support any deletion or rebalancing operations.
-The ``IntervalTree`` is designed to be set up once, and then queried without any
+The `IntervalTree` is designed to be set up once, and then queried without any
further additions.
-.. _dss_map:
+(dss_map)=
-<map>
-^^^^^
+#### <map>
-``std::map`` has similar characteristics to :ref:`std::set <dss_set>`: it uses a
+`std::map` has similar characteristics to {ref}`std::set <dss_set>`: it uses a
single allocation per pair inserted into the map, it offers log(n) lookup with
an extremely large constant factor, imposes a space penalty of 3 pointers per
pair in the map, etc.
-``std::map`` is most useful when your keys or values are very large, if you need to
+`std::map` is most useful when your keys or values are very large, if you need to
iterate over the collection in sorted order, or if you need stable iterators
into the map (i.e., they don't get invalidated if an insertion or deletion of
another element takes place).
-.. _dss_mapvector:
+(dss_mapvector)=
-llvm/ADT/MapVector.h
-^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/MapVector.h
-``MapVector<KeyT,ValueT>`` provides a subset of the ``DenseMap`` interface. The
+`MapVector<KeyT,ValueT>` provides a subset of the `DenseMap` interface. The
main difference is that the iteration order is guaranteed to be the insertion
order, making it an easy (but somewhat expensive) solution for non-deterministic
iteration over maps of pointers.
@@ -2507,17 +2329,16 @@ It is implemented by mapping from key to an index in a vector of key,value
pairs. This provides fast lookup and iteration, but has two main drawbacks:
the key is stored twice and removing elements takes linear time. If it is
necessary to remove elements, it's best to remove them in bulk using
-``remove_if()``.
+`remove_if()`.
-.. _dss_inteqclasses:
+(dss_inteqclasses)=
-llvm/ADT/IntEqClasses.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/IntEqClasses.h
-``IntEqClasses`` provides a compact representation of equivalence classes of small
+`IntEqClasses` provides a compact representation of equivalence classes of small
integers. Initially, each integer in the range 0..n-1 has its own equivalence
class. Classes can be joined by passing two class representatives to the
-``join(a, b)`` method. Two integers are in the same class when ``findLeader()`` returns
+`join(a, b)` method. Two integers are in the same class when `findLeader()` returns
the same representative.
Once all equivalence classes are formed, the map can be compressed so each
@@ -2525,61 +2346,56 @@ integer 0..n-1 maps to an equivalence class number in the range 0..m-1, where m
is the total number of equivalence classes. The map must be uncompressed before
it can be edited again.
-.. _dss_immutablemap:
+(dss_immutablemap)=
-llvm/ADT/ImmutableMap.h
-^^^^^^^^^^^^^^^^^^^^^^^
+#### llvm/ADT/ImmutableMap.h
-``ImmutableMap`` is an immutable (functional) map implementation based on an AVL
+`ImmutableMap` is an immutable (functional) map implementation based on an AVL
tree. Adding or removing elements is done through a Factory object and results
-in the creation of a new ``ImmutableMap`` object. If an ``ImmutableMap`` already exists
+in the creation of a new `ImmutableMap` object. If an `ImmutableMap` already exists
with the given key set, then the existing one is returned; equality is compared
-with a ``FoldingSetNodeID``. The time and space complexity of add or remove
+with a `FoldingSetNodeID`. The time and space complexity of add or remove
operations is logarithmic in the size of the original map.
-.. _dss_othermap:
+(dss_othermap)=
-Other Map-Like Container Options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Other Map-Like Container Options
-The STL provides several other options, such as ``std::multimap`` and
-``std::unordered_map``. We never use containers like ``unordered_map`` because
+The STL provides several other options, such as `std::multimap` and
+`std::unordered_map`. We never use containers like `unordered_map` because
they are generally very expensive (each insertion requires a malloc).
-``std::multimap`` is useful if you want to map a key to multiple values, but has all
-the drawbacks of ``std::map``. A sorted vector or some other approach is almost
+`std::multimap` is useful if you want to map a key to multiple values, but has all
+the drawbacks of `std::map`. A sorted vector or some other approach is almost
always better.
-.. _ds_bit:
+(ds_bit)=
-Bit storage containers
-------------------------------------------------------------------------
+### Bit storage containers
There are several bit storage containers, and choosing when to use each is
relatively straightforward.
-One additional option is ``std::vector<bool>``: we discourage its use for two
+One additional option is `std::vector<bool>`: we discourage its use for two
reasons 1) the implementation in many common compilers (e.g., commonly
available versions of GCC) is extremely inefficient and 2) the C++ standards
committee is likely to deprecate this container and/or change it significantly
somehow. In any case, please don't use it.
-.. _dss_bitvector:
+(dss_bitvector)=
-BitVector
-^^^^^^^^^
+#### BitVector
-The ``BitVector`` container provides a dynamic size set of bits for manipulation.
+The `BitVector` container provides a dynamic size set of bits for manipulation.
It supports individual bit setting/testing, as well as set operations. The set
operations take time O(size of bitvector), but operations are performed one word
-at a time, instead of one bit at a time. This makes the ``BitVector`` very fast for
-set operations compared to other containers. Use the ``BitVector`` when you expect
+at a time, instead of one bit at a time. This makes the `BitVector` very fast for
+set operations compared to other containers. Use the `BitVector` when you expect
the number of set bits to be high (i.e., a dense set).
-.. _dss_smallbitvector:
+(dss_smallbitvector)=
-SmallBitVector
-^^^^^^^^^^^^^^
+#### SmallBitVector
The SmallBitVector container provides the same interface as BitVector, but it is
optimized for the case where only a small number of bits, less than 25 or so,
@@ -2590,164 +2406,150 @@ larger counts are rare.
At this time, SmallBitVector does not support set operations (and, or, xor), and
its operator[] does not provide an assignable lvalue.
-.. _dss_sparsebitvector:
+(dss_sparsebitvector)=
-SparseBitVector
-^^^^^^^^^^^^^^^
+#### SparseBitVector
-The ``SparseBitVector`` container is much like ``BitVector``, with one major difference:
-Only the bits that are set, are stored. This makes the ``SparseBitVector`` much
-more space efficient than ``BitVector`` when the set is sparse, as well as making
+The `SparseBitVector` container is much like `BitVector`, with one major difference:
+Only the bits that are set, are stored. This makes the `SparseBitVector` much
+more space efficient than `BitVector` when the set is sparse, as well as making
set operations O(number of set bits) instead of O(size of universe). The
-downside to the ``SparseBitVector`` is that setting and testing of random bits is
-O(N), and on large ``SparseBitVectors``, this can be slower than ``BitVector``. In our
+downside to the `SparseBitVector` is that setting and testing of random bits is
+O(N), and on large `SparseBitVectors`, this can be slower than `BitVector`. In our
implementation, setting or testing bits in sorted order (either forwards or
reverse) is O(1) worst case. Testing and setting bits within 128 bits (depends
on size) of the current bit is also O(1). As a general statement,
-testing/setting bits in a ``SparseBitVector`` is O(distance away from last set bit).
+testing/setting bits in a `SparseBitVector` is O(distance away from last set bit).
-.. _dss_coalescingbitvector:
+(dss_coalescingbitvector)=
-CoalescingBitVector
-^^^^^^^^^^^^^^^^^^^
+#### CoalescingBitVector
-The ``CoalescingBitVector`` container is similar in principle to a ``SparseBitVector``,
+The `CoalescingBitVector` container is similar in principle to a `SparseBitVector`,
but is optimized to represent large contiguous ranges of set bits compactly. It
does this by coalescing contiguous ranges of set bits into intervals. Searching
-for a bit in a ``CoalescingBitVector`` is O(log(gaps between contiguous ranges)).
+for a bit in a `CoalescingBitVector` is O(log(gaps between contiguous ranges)).
-``CoalescingBitVector`` is a better choice than ``BitVector`` when gaps between ranges
-of set bits are large. It's a better choice than ``SparseBitVector`` when find()
+`CoalescingBitVector` is a better choice than `BitVector` when gaps between ranges
+of set bits are large. It's a better choice than `SparseBitVector` when find()
operations must have fast, predictable performance. However, it's not a good
choice for representing sets which have lots of very short ranges. E.g. the set
`{2*x : x \in [0, n)}` would be a pathological input.
-.. _utility_functions:
+(utility_functions)=
-Useful Utility Functions
-========================
+## Useful Utility Functions
LLVM implements a number of general utility functions used across the
-codebase. You can find the most common ones in ``STLExtras.h``
-(`doxygen <https://llvm.org/doxygen/STLExtras_8h.html>`__). Some of these wrap
+codebase. You can find the most common ones in `STLExtras.h`
+([doxygen](https://llvm.org/doxygen/STLExtras_8h.html)). Some of these wrap
well-known C++ standard library functions, while others are unique to LLVM.
-.. _uf_iteration:
+(uf_iteration)=
-Iterating over ranges
----------------------
+### Iterating over ranges
Sometimes you may want to iterate over more than range at a time or know the
index of the index. LLVM provides custom utility functions to make that easier,
without having to manually manage all iterators and/or indices:
-.. _uf_zip:
+(uf_zip)=
-The ``zip``\ * functions
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `zip`\ * functions
-``zip``\ * functions allow for iterating over elements from two or more ranges
+`zip`\ * functions allow for iterating over elements from two or more ranges
at the same time. For example:
-.. code-block:: c++
-
- SmallVector<size_t> Counts = ...;
- char Letters[26] = ...;
- for (auto [Letter, Count] : zip_equal(Letters, Counts))
- errs() << Letter << ": " << Count << "\n";
-
+```cpp
+SmallVector<size_t> Counts = ...;
+char Letters[26] = ...;
+for (auto [Letter, Count] : zip_equal(Letters, Counts))
+ errs() << Letter << ": " << Count << "\n";
+```
Note that the elements are provided through a 'reference wrapper' proxy type
(tuple of references), which combined with the structured bindings declaration
-makes ``Letter`` and ``Count`` references to range elements. Any modification
-to these references will affect the elements of ``Letters`` or ``Counts``.
-
-The ``zip``\ * functions support temporary ranges, for example:
+makes `Letter` and `Count` references to range elements. Any modification
+to these references will affect the elements of `Letters` or `Counts`.
-.. code-block:: c++
+The `zip`\ * functions support temporary ranges, for example:
- for (auto [Letter, Count] : zip(SmallVector<char>{'a', 'b', 'c'}, Counts))
- errs() << Letter << ": " << Count << "\n";
-
-The difference between the functions in the ``zip`` family is how they behave
+```cpp
+for (auto [Letter, Count] : zip(SmallVector<char>{'a', 'b', 'c'}, Counts))
+ errs() << Letter << ": " << Count << "\n";
+```
+The difference between the functions in the `zip` family is how they behave
when the supplied ranges have different lengths:
-* ``zip_equal`` -- requires all input ranges have the same length.
-* ``zip`` -- iteration stops when the end of the shortest range is reached.
-* ``zip_first`` -- requires the first range is the shortest one.
-* ``zip_longest`` -- iteration continues until the end of the longest range is
+* `zip_equal` -- requires all input ranges have the same length.
+* `zip` -- iteration stops when the end of the shortest range is reached.
+* `zip_first` -- requires the first range is the shortest one.
+* `zip_longest` -- iteration continues until the end of the longest range is
reached. The non-existent elements of shorter ranges are replaced with
- ``std::nullopt``.
+ `std::nullopt`.
-The length requirements are checked with ``assert``\ s.
+The length requirements are checked with `assert`s.
-As a rule of thumb, prefer to use ``zip_equal`` when you expect all
-ranges to have the same lengths, and consider alternative ``zip`` functions only
-when this is not the case. This is because ``zip_equal`` clearly communicates
+As a rule of thumb, prefer to use `zip_equal` when you expect all
+ranges to have the same lengths, and consider alternative `zip` functions only
+when this is not the case. This is because `zip_equal` clearly communicates
this same-length assumption and has the best (release-mode) runtime performance.
-.. _uf_enumerate:
+(uf_enumerate)=
-``enumerate``
-^^^^^^^^^^^^^
+#### `enumerate`
-The ``enumerate`` functions allows to iterate over one or more ranges while
+The `enumerate` functions allows to iterate over one or more ranges while
keeping track of the index of the current loop iteration. For example:
-.. code-block:: c++
-
- for (auto [Idx, BB, Value] : enumerate(Phi->blocks(),
- Phi->incoming_values()))
- errs() << "#" << Idx << " " << BB->getName() << ": " << *Value << "\n";
-
+```cpp
+for (auto [Idx, BB, Value] : enumerate(Phi->blocks(),
+ Phi->incoming_values()))
+ errs() << "#" << Idx << " " << BB->getName() << ": " << *Value << "\n";
+```
The current element index is provided as the first structured bindings element.
Alternatively, the index and the element value can be obtained with the
-``index()`` and ``value()`` member functions:
-
-.. code-block:: c++
-
- char Letters[26] = ...;
- for (auto En : enumerate(Letters))
- errs() << "#" << En.index() << " " << En.value() << "\n";
-
-Note that ``enumerate`` has ``zip_equal`` semantics and provides elements
+`index()` and `value()` member functions:
+
+```cpp
+char Letters[26] = ...;
+for (auto En : enumerate(Letters))
+ errs() << "#" << En.index() << " " << En.value() << "\n";
+```
+Note that `enumerate` has `zip_equal` semantics and provides elements
through a 'reference wrapper' proxy, which makes them modifiable when accessed
-through structured bindings or the ``value()`` member function. When two or more
-ranges are passed, ``enumerate`` requires them to have equal lengths (checked
-with an ``assert``).
+through structured bindings or the `value()` member function. When two or more
+ranges are passed, `enumerate` requires them to have equal lengths (checked
+with an `assert`).
-.. _debugging:
+(debugging)=
-Debugging
-=========
+## Debugging
-See :doc:`Debugging LLVM <DebuggingLLVM>`.
+See {doc}`Debugging LLVM <DebuggingLLVM>`.
-.. _common:
+(common)=
-Helpful Hints for Common Operations
-===================================
+## Helpful Hints for Common Operations
This section describes how to perform some very simple transformations of LLVM
code. This is meant to give examples of common idioms used, showing the
practical side of LLVM transformations.
Because this is a "how-to" section, you should also read about the main classes
-that you will be working with. The :ref:`Core LLVM Class Hierarchy Reference
-<coreclasses>` contains details and descriptions of the main classes that you
+that you will be working with. The {ref}`Core LLVM Class Hierarchy Reference <coreclasses>` contains details and descriptions of the main classes that you
should know about.
-.. _inspection:
+(inspection)=
-Basic Inspection and Traversal Routines
----------------------------------------
+### Basic Inspection and Traversal Routines
The LLVM compiler infrastructure have many different data structures that may be
traversed. Following the example of the C++ standard template library, the
techniques used to traverse these various data structures are all basically the
-same. For an enumerable sequence of values, the ``XXXbegin()`` function (or
-method) returns an iterator to the start of the sequence, the ``XXXend()``
+same. For an enumerable sequence of values, the `XXXbegin()` function (or
+method) returns an iterator to the start of the sequence, the `XXXend()`
function returns an iterator pointing to one past the last valid element of the
-sequence, and there is some ``XXXiterator`` data type that is common between the
+sequence, and there is some `XXXiterator` data type that is common between the
two operations.
Because the pattern for iteration is common across many different aspects of the
@@ -2756,265 +2558,239 @@ them, and it is easier to remember how to iterate. First we show a few common
examples of the data structures that need to be traversed. Other data
structures are traversed in very similar ways.
-.. _iterate_function:
-
-Iterating over the ``BasicBlock`` in a ``Function``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It's quite common to have a ``Function`` instance that you'd like to transform
-in some way; in particular, you'd like to manipulate its ``BasicBlock``\ s. To
-facilitate this, you'll need to iterate over all of the ``BasicBlock``\ s that
-constitute the ``Function``. The following is an example that prints the name
-of a ``BasicBlock`` and the number of ``Instruction``\ s it contains:
-
-.. code-block:: c++
-
- Function &Func = ...
- for (BasicBlock &BB : Func)
- // Print out the name of the basic block if it has one, and then the
- // number of instructions that it contains
- errs() << "Basic block (name=" << BB.getName() << ") has "
- << BB.size() << " instructions.\n";
-
-.. _iterate_basicblock:
-
-Iterating over the ``Instruction`` in a ``BasicBlock``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Just like when dealing with ``BasicBlock``\ s in ``Function``\ s, it's easy to
-iterate over the individual instructions that make up ``BasicBlock``\ s. Here's
-a code snippet that prints out each instruction in a ``BasicBlock``:
-
-.. code-block:: c++
-
- BasicBlock& BB = ...
- for (Instruction &I : BB)
- // The next statement works since operator<<(ostream&,...)
- // is overloaded for Instruction&
- errs() << I << "\n";
-
-
+(iterate_function)=
+
+#### Iterating over the `BasicBlock` in a `Function`
+
+It's quite common to have a `Function` instance that you'd like to transform
+in some way; in particular, you'd like to manipulate its `BasicBlock`s. To
+facilitate this, you'll need to iterate over all of the `BasicBlock`s that
+constitute the `Function`. The following is an example that prints the name
+of a `BasicBlock` and the number of `Instruction`s it contains:
+
+```cpp
+Function &Func = ...
+for (BasicBlock &BB : Func)
+ // Print out the name of the basic block if it has one, and then the
+ // number of instructions that it contains
+ errs() << "Basic block (name=" << BB.getName() << ") has "
+ << BB.size() << " instructions.\n";
+```
+(iterate_basicblock)=
+
+#### Iterating over the `Instruction` in a `BasicBlock`
+
+Just like when dealing with `BasicBlock`s in `Function`s, it's easy to
+iterate over the individual instructions that make up `BasicBlock`s. Here's
+a code snippet that prints out each instruction in a `BasicBlock`:
+
+```cpp
+BasicBlock& BB = ...
+for (Instruction &I : BB)
+ // The next statement works since operator<<(ostream&,...)
+ // is overloaded for Instruction&
+ errs() << I << "\n";
+```
However, this isn't really the best way to print out the contents of a
-``BasicBlock``! Since the ostream operators are overloaded for virtually
+`BasicBlock`! Since the ostream operators are overloaded for virtually
anything you'll care about, you could have just invoked the print routine on the
-basic block itself: ``errs() << BB << "\n";``.
+basic block itself: `errs() << BB << "\n";`.
-.. _iterate_insiter:
+(iterate_insiter)=
-Iterating over the ``Instruction`` in a ``Function``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Iterating over the `Instruction` in a `Function`
-If you're finding that you commonly iterate over a ``Function``'s
-``BasicBlock``\ s and then that ``BasicBlock``'s ``Instruction``\ s,
-``InstIterator`` should be used instead. You'll need to include
-``llvm/IR/InstIterator.h`` (`doxygen
-<https://llvm.org/doxygen/InstIterator_8h.html>`__) and then instantiate
-``InstIterator``\ s explicitly in your code. Here's a small example that shows
+If you're finding that you commonly iterate over a `Function`'s
+`BasicBlock`s and then that `BasicBlock`'s `Instruction`s,
+`InstIterator` should be used instead. You'll need to include
+`llvm/IR/InstIterator.h` ([doxygen](https://llvm.org/doxygen/InstIterator_8h.html)) and then instantiate
+`InstIterator`s explicitly in your code. Here's a small example that shows
how to dump all instructions in a function to the standard error stream:
-.. code-block:: c++
-
- #include "llvm/IR/InstIterator.h"
-
- // F is a pointer to a Function instance
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
- errs() << *I << "\n";
+```cpp
+#include "llvm/IR/InstIterator.h"
-Easy, isn't it? You can also use ``InstIterator``\ s to fill a work list with
+// F is a pointer to a Function instance
+for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ errs() << *I << "\n";
+```
+Easy, isn't it? You can also use `InstIterator`s to fill a work list with
its initial contents. For example, if you wanted to initialize a work list to
-contain all instructions in a ``Function`` F, all you would need to do is
+contain all instructions in a `Function` F, all you would need to do is
something like:
-.. code-block:: c++
+```cpp
+std::set<Instruction*> worklist;
+// or better yet, SmallPtrSet<Instruction*, 64> worklist;
- std::set<Instruction*> worklist;
- // or better yet, SmallPtrSet<Instruction*, 64> worklist;
-
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
- worklist.insert(&*I);
-
-The STL set ``worklist`` would now contain all instructions in the ``Function``
+for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ worklist.insert(&*I);
+```
+The STL set `worklist` would now contain all instructions in the `Function`
pointed to by F.
-.. _iterate_convert:
+(iterate_convert)=
-Turning an iterator into a class pointer (and vice-versa)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Turning an iterator into a class pointer (and vice-versa)
Sometimes, it'll be useful to grab a reference (or pointer) to a class instance
when all you've got at hand is an iterator. Well, extracting a reference or a
-pointer from an iterator is very straightforward. Assuming that ``i`` is a
-``BasicBlock::iterator`` and ``j`` is a ``BasicBlock::const_iterator``:
-
-.. code-block:: c++
-
- Instruction& inst = *i; // Grab reference to instruction reference
- Instruction* pinst = &*i; // Grab pointer to instruction reference
- const Instruction& inst = *j;
-
+pointer from an iterator is very straightforward. Assuming that `i` is a
+`BasicBlock::iterator` and `j` is a `BasicBlock::const_iterator`:
+
+```cpp
+Instruction& inst = *i; // Grab reference to instruction reference
+Instruction* pinst = &*i; // Grab pointer to instruction reference
+const Instruction& inst = *j;
+```
It's also possible to turn a class pointer into the corresponding iterator, and
this is a constant time operation (very efficient). The following code snippet
illustrates use of the conversion constructors provided by LLVM iterators. By
using these, you can explicitly grab the iterator of something without actually
obtaining it via iteration over some structure:
-.. code-block:: c++
+```cpp
+void printNextInstruction(Instruction* inst) {
+ BasicBlock::iterator it(inst);
+ ++it; // After this line, it refers to the instruction after *inst
+ if (it != inst->getParent()->end()) errs() << *it << "\n";
+}
+```
+(iterate_complex)=
- void printNextInstruction(Instruction* inst) {
- BasicBlock::iterator it(inst);
- ++it; // After this line, it refers to the instruction after *inst
- if (it != inst->getParent()->end()) errs() << *it << "\n";
- }
-
-.. _iterate_complex:
-
-Finding call sites: a slightly more complex example
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Finding call sites: a slightly more complex example
Say that you're writing a FunctionPass and would like to count all the locations
-in the entire module (that is, across every ``Function``) where a certain
-function (i.e., some ``Function *``) is already in scope. As you'll learn
-later, you may want to use an ``InstVisitor`` to accomplish this in a much more
+in the entire module (that is, across every `Function`) where a certain
+function (i.e., some `Function *`) is already in scope. As you'll learn
+later, you may want to use an `InstVisitor` to accomplish this in a much more
straightforward manner, but this example will allow us to explore how you'd do
-it if you didn't have ``InstVisitor`` around. In pseudo-code, this is what we
+it if you didn't have `InstVisitor` around. In pseudo-code, this is what we
want to do:
-.. code-block:: none
-
- initialize callCounter to zero
- for each Function f in the Module
- for each BasicBlock b in f
- for each Instruction i in b
- if (i a Call and calls the given function)
- increment callCounter
-
-And the actual code is (remember, because we're writing a ``FunctionPass``, our
-``FunctionPass``-derived class simply has to override the ``runOnFunction``
+```none
+initialize callCounter to zero
+for each Function f in the Module
+ for each BasicBlock b in f
+ for each Instruction i in b
+ if (i a Call and calls the given function)
+ increment callCounter
+```
+And the actual code is (remember, because we're writing a `FunctionPass`, our
+`FunctionPass`-derived class simply has to override the `runOnFunction`
method):
-.. code-block:: c++
-
- Function* targetFunc = ...;
+```cpp
+Function* targetFunc = ...;
- class OurFunctionPass : public FunctionPass {
- public:
- OurFunctionPass(): callCounter(0) { }
-
- virtual runOnFunction(Function& F) {
- for (BasicBlock &B : F) {
- for (Instruction &I: B) {
- if (auto *CB = dyn_cast<CallBase>(&I)) {
- // We know we've encountered some kind of call instruction (call,
- // invoke, or callbr), so we need to determine if it's a call to
- // the function pointed to by m_func or not.
- if (CB->getCalledFunction() == targetFunc)
- ++callCounter;
- }
+class OurFunctionPass : public FunctionPass {
+ public:
+ OurFunctionPass(): callCounter(0) { }
+
+ virtual runOnFunction(Function& F) {
+ for (BasicBlock &B : F) {
+ for (Instruction &I: B) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ // We know we've encountered some kind of call instruction (call,
+ // invoke, or callbr), so we need to determine if it's a call to
+ // the function pointed to by m_func or not.
+ if (CB->getCalledFunction() == targetFunc)
+ ++callCounter;
}
}
}
-
- private:
- unsigned callCounter;
- };
-
-.. _iterate_chains:
-
-Iterating over def-use & use-def chains
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Frequently, we might have an instance of the ``Value`` class (`doxygen
-<https://llvm.org/doxygen/classllvm_1_1Value.html>`__) and we want to determine
-which ``User``\ s use the ``Value``. The list of all ``User``\ s of a particular
-``Value`` is called a *def-use* chain. For example, let's say we have a
-``Function*`` named ``F`` to a particular function ``foo``. Finding all of the
-instructions that *use* ``foo`` is as simple as iterating over the *def-use*
-chain of ``F``:
-
-.. code-block:: c++
-
- Function *F = ...;
-
- for (User *U : F->users()) {
- if (Instruction *Inst = dyn_cast<Instruction>(U)) {
- errs() << "F is used in instruction:\n";
- errs() << *Inst << "\n";
}
-Alternatively, it's common to have an instance of the ``User`` Class (`doxygen
-<https://llvm.org/doxygen/classllvm_1_1User.html>`__) and need to know what
-``Value``\ s are used by it. The list of all ``Value``\ s used by a ``User`` is
-known as a *use-def* chain. Instances of class ``Instruction`` are common
-``User`` s, so we might want to iterate over all of the values that a particular
-instruction uses (that is, the operands of the particular ``Instruction``):
-
-.. code-block:: c++
-
- Instruction *pi = ...;
-
- for (Use &U : pi->operands()) {
- Value *v = U.get();
- // ...
+ private:
+ unsigned callCounter;
+};
+```
+(iterate_chains)=
+
+#### Iterating over def-use & use-def chains
+
+Frequently, we might have an instance of the `Value` class ([doxygen](https://llvm.org/doxygen/classllvm_1_1Value.html)) and we want to determine
+which `User`s use the `Value`. The list of all `User`s of a particular
+`Value` is called a *def-use* chain. For example, let's say we have a
+`Function*` named `F` to a particular function `foo`. Finding all of the
+instructions that *use* `foo` is as simple as iterating over the *def-use*
+chain of `F`:
+
+```cpp
+Function *F = ...;
+
+for (User *U : F->users()) {
+ if (Instruction *Inst = dyn_cast<Instruction>(U)) {
+ errs() << "F is used in instruction:\n";
+ errs() << *Inst << "\n";
}
-
-Declaring objects as ``const`` is an important tool of enforcing mutation free
+```
+Alternatively, it's common to have an instance of the `User` Class ([doxygen](https://llvm.org/doxygen/classllvm_1_1User.html)) and need to know what
+`Value`s are used by it. The list of all `Value`s used by a `User` is
+known as a *use-def* chain. Instances of class `Instruction` are common
+`User` s, so we might want to iterate over all of the values that a particular
+instruction uses (that is, the operands of the particular `Instruction`):
+
+```cpp
+Instruction *pi = ...;
+
+for (Use &U : pi->operands()) {
+ Value *v = U.get();
+ // ...
+}
+```
+Declaring objects as `const` is an important tool of enforcing mutation free
algorithms (such as analyses, etc.). For this purpose above iterators come in
-constant flavors as ``Value::const_use_iterator`` and
-``Value::const_op_iterator``. They automatically arise when calling
-``use/op_begin()`` on ``const Value*``\ s or ``const User*``\ s respectively.
-Upon dereferencing, they return ``const Use*``\ s. Otherwise the above patterns
+constant flavors as `Value::const_use_iterator` and
+`Value::const_op_iterator`. They automatically arise when calling
+`use/op_begin()` on `const Value*`s or `const User*`s respectively.
+Upon dereferencing, they return `const Use*`s. Otherwise the above patterns
remain unchanged.
-.. _iterate_preds:
+(iterate_preds)=
-Iterating over predecessors & successors of blocks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Iterating over predecessors & successors of blocks
Iterating over the predecessors and successors of a block is quite easy with the
-routines defined in ``"llvm/IR/CFG.h"``. Just use code like this to
+routines defined in `"llvm/IR/CFG.h"`. Just use code like this to
iterate over all predecessors of BB:
-.. code-block:: c++
+```cpp
+#include "llvm/IR/CFG.h"
+BasicBlock *BB = ...;
- #include "llvm/IR/CFG.h"
- BasicBlock *BB = ...;
+for (BasicBlock *Pred : predecessors(BB)) {
+ // ...
+}
+```
+Similarly, to iterate over successors use `successors`.
- for (BasicBlock *Pred : predecessors(BB)) {
- // ...
- }
-
-Similarly, to iterate over successors use ``successors``.
+(simplechanges)=
-.. _simplechanges:
-
-Making simple changes
----------------------
+### Making simple changes
There are some primitive transformation operations present in the LLVM
infrastructure that are worth knowing about. When performing transformations,
it's fairly common to manipulate the contents of basic blocks. This section
describes some of the common methods for doing so and gives example code.
-.. _schanges_creating:
+(schanges_creating)=
-Creating and inserting new ``Instruction``\ s
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Creating and inserting new `Instruction`s
*Instantiating Instructions*
-Creation of ``Instruction``\ s is straightforward: simply call the constructor
+Creation of `Instruction`s is straightforward: simply call the constructor
for the kind of instruction to instantiate and provide the necessary parameters.
-For example, an ``AllocaInst`` only *requires* a (const-ptr-to) ``Type``. Thus:
-
-.. code-block:: c++
-
- auto *ai = new AllocaInst(Type::Int32Ty);
+For example, an `AllocaInst` only *requires* a (const-ptr-to) `Type`. Thus:
-will create an ``AllocaInst`` instance that represents the allocation of one
-integer in the current stack frame, at run time. Each ``Instruction`` subclass
+```cpp
+auto *ai = new AllocaInst(Type::Int32Ty);
+```
+will create an `AllocaInst` instance that represents the allocation of one
+integer in the current stack frame, at run time. Each `Instruction` subclass
is likely to have varying default parameters which change the semantics of the
-instruction, so refer to the `doxygen documentation for the subclass of
-Instruction <https://llvm.org/doxygen/classllvm_1_1Instruction.html>`_ that
+instruction, so refer to the [doxygen documentation for the subclass of Instruction](https://llvm.org/doxygen/classllvm_1_1Instruction.html) that
you're interested in instantiating.
*Naming values*
@@ -3023,194 +2799,173 @@ It is very useful to name the values of instructions when you're able to, as
this facilitates the debugging of your transformations. If you end up looking
at generated LLVM machine code, you definitely want to have logical names
associated with the results of instructions! By supplying a value for the
-``Name`` (default) parameter of the ``Instruction`` constructor, you associate a
+`Name` (default) parameter of the `Instruction` constructor, you associate a
logical name with the result of the instruction's execution at run time. For
example, say that I'm writing a transformation that dynamically allocates space
for an integer on the stack, and that integer is going to be used as some kind
-of index by some other code. To accomplish this, I place an ``AllocaInst`` at
-the first point in the first ``BasicBlock`` of some ``Function``, and I'm
-intending to use it within the same ``Function``. I might do:
-
-.. code-block:: c++
-
- auto *pa = new AllocaInst(Type::Int32Ty, 0, "indexLoc");
-
-where ``indexLoc`` is now the logical name of the instruction's execution value,
+of index by some other code. To accomplish this, I place an `AllocaInst` at
+the first point in the first `BasicBlock` of some `Function`, and I'm
+intending to use it within the same `Function`. I might do:
+
+```cpp
+auto *pa = new AllocaInst(Type::Int32Ty, 0, "indexLoc");
+```
+where `indexLoc` is now the logical name of the instruction's execution value,
which is a pointer to an integer on the run time stack.
*Inserting instructions*
-There are essentially three ways to insert an ``Instruction`` into an existing
-sequence of instructions that form a ``BasicBlock``:
+There are essentially three ways to insert an `Instruction` into an existing
+sequence of instructions that form a `BasicBlock`:
-* Insertion into the instruction list of the ``BasicBlock``
+* Insertion into the instruction list of the `BasicBlock`
- Given a ``BasicBlock* pb``, an ``Instruction* pi`` within that ``BasicBlock``,
- and a newly-created instruction we wish to insert before ``*pi``, we do the
+ Given a `BasicBlock* pb`, an `Instruction* pi` within that `BasicBlock`,
+ and a newly-created instruction we wish to insert before `*pi`, we do the
following:
- .. code-block:: c++
-
- BasicBlock *pb = ...;
- Instruction *pi = ...;
- auto *newInst = new Instruction(...);
-
- newInst->insertBefore(pi); // Inserts newInst before pi
+ ```cpp
+ BasicBlock *pb = ...;
+ Instruction *pi = ...;
+ auto *newInst = new Instruction(...);
- Appending to the end of a ``BasicBlock`` is so common that the ``Instruction``
- class and ``Instruction``-derived classes provide constructors which take a
- pointer to a ``BasicBlock`` to be appended to. For example code that looked
+ newInst->insertBefore(pi); // Inserts newInst before pi
+ ```
+ Appending to the end of a `BasicBlock` is so common that the `Instruction`
+ class and `Instruction`-derived classes provide constructors which take a
+ pointer to a `BasicBlock` to be appended to. For example code that looked
like:
- .. code-block:: c++
-
- BasicBlock *pb = ...;
- auto *newInst = new Instruction(...);
-
- newInst->insertInto(pb, pb->end()); // Appends newInst to pb
+ ```cpp
+ BasicBlock *pb = ...;
+ auto *newInst = new Instruction(...);
+ newInst->insertInto(pb, pb->end()); // Appends newInst to pb
+ ```
becomes:
- .. code-block:: c++
-
- BasicBlock *pb = ...;
- auto *newInst = new Instruction(..., pb);
-
+ ```cpp
+ BasicBlock *pb = ...;
+ auto *newInst = new Instruction(..., pb);
+ ```
which is much cleaner, especially if you are creating long instruction
streams.
-* Insertion using an instance of ``IRBuilder``
+* Insertion using an instance of `IRBuilder`
- Inserting several ``Instruction``\ s can be quite laborious using the previous
- methods. The ``IRBuilder`` is a convenience class that can be used to add
- several instructions to the end of a ``BasicBlock`` or before a particular
- ``Instruction``. It also supports constant folding and renaming named
- registers (see ``IRBuilder``'s template arguments).
+ Inserting several `Instruction`s can be quite laborious using the previous
+ methods. The `IRBuilder` is a convenience class that can be used to add
+ several instructions to the end of a `BasicBlock` or before a particular
+ `Instruction`. It also supports constant folding and renaming named
+ registers (see `IRBuilder`'s template arguments).
- The example below demonstrates a very simple use of the ``IRBuilder`` where
- three instructions are inserted before the instruction ``pi``. The first two
+ The example below demonstrates a very simple use of the `IRBuilder` where
+ three instructions are inserted before the instruction `pi`. The first two
instructions are Call instructions and third instruction multiplies the return
value of the two calls.
- .. code-block:: c++
-
- Instruction *pi = ...;
- IRBuilder<> Builder(pi);
- CallInst* callOne = Builder.CreateCall(...);
- CallInst* callTwo = Builder.CreateCall(...);
- Value* result = Builder.CreateMul(callOne, callTwo);
-
+ ```cpp
+ Instruction *pi = ...;
+ IRBuilder<> Builder(pi);
+ CallInst* callOne = Builder.CreateCall(...);
+ CallInst* callTwo = Builder.CreateCall(...);
+ Value* result = Builder.CreateMul(callOne, callTwo);
+ ```
The example below is similar to the above example except that the created
- ``IRBuilder`` inserts instructions at the end of the ``BasicBlock`` ``pb``.
-
- .. code-block:: c++
+ `IRBuilder` inserts instructions at the end of the `BasicBlock` `pb`.
- BasicBlock *pb = ...;
- IRBuilder<> Builder(pb);
- CallInst* callOne = Builder.CreateCall(...);
- CallInst* callTwo = Builder.CreateCall(...);
- Value* result = Builder.CreateMul(callOne, callTwo);
+ ```cpp
+ BasicBlock *pb = ...;
+ IRBuilder<> Builder(pb);
+ CallInst* callOne = Builder.CreateCall(...);
+ CallInst* callTwo = Builder.CreateCall(...);
+ Value* result = Builder.CreateMul(callOne, callTwo);
+ ```
+ See {doc}`tutorial/LangImpl03` for a practical use of the `IRBuilder`.
- See :doc:`tutorial/LangImpl03` for a practical use of the ``IRBuilder``.
+(schanges_deleting)=
-.. _schanges_deleting:
-
-Deleting Instructions
-^^^^^^^^^^^^^^^^^^^^^
+#### Deleting Instructions
Deleting an instruction from an existing sequence of instructions that form a
-``BasicBlock`` is very straightforward: just call the instruction's
-``eraseFromParent()`` method. For example:
-
-.. code-block:: c++
-
- Instruction *I = .. ;
- I->eraseFromParent();
+`BasicBlock` is very straightforward: just call the instruction's
+`eraseFromParent()` method. For example:
+```cpp
+Instruction *I = .. ;
+I->eraseFromParent();
+```
This unlinks the instruction from its containing basic block and deletes it. If
you'd just like to unlink the instruction from its containing basic block but
-not delete it, you can use the ``removeFromParent()`` method.
+not delete it, you can use the `removeFromParent()` method.
-.. _schanges_replacing:
+(schanges_replacing)=
-Replacing an Instruction with another Value
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Replacing an Instruction with another Value
-Replacing individual instructions
-"""""""""""""""""""""""""""""""""
+##### Replacing individual instructions
-Including "`llvm/Transforms/Utils/BasicBlockUtils.h
-<https://llvm.org/doxygen/BasicBlockUtils_8h_source.html>`_" permits use of two
-very useful replace functions: ``ReplaceInstWithValue`` and
-``ReplaceInstWithInst``.
+Including "[llvm/Transforms/Utils/BasicBlockUtils.h](https://llvm.org/doxygen/BasicBlockUtils_8h_source.html)" permits use of two
+very useful replace functions: `ReplaceInstWithValue` and
+`ReplaceInstWithInst`.
-.. _schanges_deleting_sub:
+(schanges_deleting_sub)=
-Deleting Instructions
-"""""""""""""""""""""
+##### Deleting Instructions
-* ``ReplaceInstWithValue``
+* `ReplaceInstWithValue`
This function replaces all uses of a given instruction with a value, and then
removes the original instruction. The following example illustrates the
- replacement of the result of a particular ``AllocaInst`` that allocates memory
+ replacement of the result of a particular `AllocaInst` that allocates memory
for a single integer with a null pointer to an integer.
- .. code-block:: c++
-
- AllocaInst* instToReplace = ...;
- BasicBlock::iterator ii(instToReplace);
+ ```cpp
+ AllocaInst* instToReplace = ...;
+ BasicBlock::iterator ii(instToReplace);
- ReplaceInstWithValue(ii, Constant::getNullValue(PointerType::getUnqual(Type::Int32Ty)));
-
-* ``ReplaceInstWithInst``
+ ReplaceInstWithValue(ii, Constant::getNullValue(PointerType::getUnqual(Type::Int32Ty)));
+ ```
+* `ReplaceInstWithInst`
This function replaces a particular instruction with another instruction,
inserting the new instruction into the basic block at the location where the
old instruction was, and replacing any uses of the old instruction with the
new instruction. The following example illustrates the replacement of one
- ``AllocaInst`` with another.
-
- .. code-block:: c++
-
- AllocaInst* instToReplace = ...;
- BasicBlock::iterator ii(instToReplace);
+ `AllocaInst` with another.
- ReplaceInstWithInst(instToReplace->getParent(), ii,
- new AllocaInst(Type::Int32Ty, 0, "ptrToReplacedInt"));
+ ```cpp
+ AllocaInst* instToReplace = ...;
+ BasicBlock::iterator ii(instToReplace);
+ ReplaceInstWithInst(instToReplace->getParent(), ii,
+ new AllocaInst(Type::Int32Ty, 0, "ptrToReplacedInt"));
+ ```
+##### Replacing multiple uses of Users and Values
-Replacing multiple uses of Users and Values
-"""""""""""""""""""""""""""""""""""""""""""
-
-You can use ``Value::replaceAllUsesWith`` and ``User::replaceUsesOfWith`` to
+You can use `Value::replaceAllUsesWith` and `User::replaceUsesOfWith` to
change more than one use at a time. See the doxygen documentation for the
-`Value Class <https://llvm.org/doxygen/classllvm_1_1Value.html>`_ and `User Class
-<https://llvm.org/doxygen/classllvm_1_1User.html>`_, respectively, for more
+[Value Class](https://llvm.org/doxygen/classllvm_1_1Value.html) and [User Class](https://llvm.org/doxygen/classllvm_1_1User.html), respectively, for more
information.
-.. _schanges_deletingGV:
+(schanges_deletingGV)=
-Deleting GlobalVariables
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Deleting GlobalVariables
Deleting a global variable from a module is just as easy as deleting an
Instruction. First, you must have a pointer to the global variable that you
wish to delete. You use this pointer to erase it from its parent, the module.
For example:
-.. code-block:: c++
-
- GlobalVariable *GV = .. ;
-
- GV->eraseFromParent();
+```cpp
+GlobalVariable *GV = .. ;
+GV->eraseFromParent();
+```
+(threading)=
-.. _threading:
-
-Threads and LLVM
-================
+## Threads and LLVM
This section describes the interaction of the LLVM APIs with multithreading,
both on the part of client applications, and in the JIT, in the hosted
@@ -3229,187 +2984,174 @@ compiler, consider compiling LLVM and LLVM-GCC in single-threaded mode, and
using the resultant compiler to build a copy of LLVM with multithreading
support.
-.. _shutdown:
+(shutdown)=
-Ending Execution with ``llvm_shutdown()``
------------------------------------------
+### Ending Execution with `llvm_shutdown()`
-When you are done using the LLVM APIs, you should call ``llvm_shutdown()`` to
+When you are done using the LLVM APIs, you should call `llvm_shutdown()` to
deallocate memory used for internal structures.
-.. _managedstatic:
+(managedstatic)=
-Lazy Initialization with ``ManagedStatic``
-------------------------------------------
+### Lazy Initialization with `ManagedStatic`
-``ManagedStatic`` is a utility class in LLVM used to implement static
+`ManagedStatic` is a utility class in LLVM used to implement static
initialization of static resources, such as the global type tables. In a
single-threaded environment, it implements a simple lazy initialization scheme.
When LLVM is compiled with support for multi-threading, however, it uses
double-checked locking to implement thread-safe lazy initialization.
-.. _llvmcontext:
+(llvmcontext)=
-Achieving Isolation with ``LLVMContext``
-----------------------------------------
+### Achieving Isolation with `LLVMContext`
-``LLVMContext`` is an opaque class in the LLVM API which clients can use to
+`LLVMContext` is an opaque class in the LLVM API which clients can use to
operate multiple, isolated instances of LLVM concurrently within the same
address space. For instance, in a hypothetical compile-server, the compilation
of an individual translation unit is conceptually independent from all the
others, and it would be desirable to be able to compile incoming translation
-units concurrently on independent server threads. Fortunately, ``LLVMContext``
+units concurrently on independent server threads. Fortunately, `LLVMContext`
exists to enable just this kind of scenario!
-Conceptually, ``LLVMContext`` provides isolation. Every LLVM entity
-(``Module``\ s, ``Value``\ s, ``Type``\ s, ``Constant``\ s, etc.) in LLVM's
-in-memory IR belongs to an ``LLVMContext``. Entities in different contexts
-*cannot* interact with each other: ``Module``\ s in different contexts cannot be
-linked together, ``Function``\ s cannot be added to ``Module``\ s in different
+Conceptually, `LLVMContext` provides isolation. Every LLVM entity
+(`Module`s, `Value`s, `Type`s, `Constant`s, etc.) in LLVM's
+in-memory IR belongs to an `LLVMContext`. Entities in different contexts
+*cannot* interact with each other: `Module`s in different contexts cannot be
+linked together, `Function`s cannot be added to `Module`s in different
contexts, etc. What this means is that is safe to compile on multiple
threads simultaneously, as long as no two threads operate on entities within the
same context.
In practice, very few places in the API require the explicit specification of a
-``LLVMContext``, other than the ``Type`` creation/lookup APIs. Because every
-``Type`` carries a reference to its owning context, most other entities can
-determine what context they belong to by looking at their own ``Type``. If you
+`LLVMContext`, other than the `Type` creation/lookup APIs. Because every
+`Type` carries a reference to its owning context, most other entities can
+determine what context they belong to by looking at their own `Type`. If you
are adding new entities to LLVM IR, please try to maintain this interface
design.
-.. _jitthreading:
+(jitthreading)=
-Threads and the JIT
--------------------
+### Threads and the JIT
LLVM's "eager" JIT compiler is safe to use in threaded programs. Multiple
-threads can call ``ExecutionEngine::getPointerToFunction()`` or
-``ExecutionEngine::runFunction()`` concurrently, and multiple threads can run
+threads can call `ExecutionEngine::getPointerToFunction()` or
+`ExecutionEngine::runFunction()` concurrently, and multiple threads can run
code output by the JIT concurrently. The user must still ensure that only one
-thread accesses IR in a given ``LLVMContext`` while another thread might be
+thread accesses IR in a given `LLVMContext` while another thread might be
modifying it. One way to do that is to always hold the JIT lock while accessing
-IR outside the JIT (the JIT *modifies* the IR by adding ``CallbackVH``\ s).
-Another way is to only call ``getPointerToFunction()`` from the
-``LLVMContext``'s thread.
+IR outside the JIT (the JIT *modifies* the IR by adding `CallbackVH`s).
+Another way is to only call `getPointerToFunction()` from the
+`LLVMContext`'s thread.
When the JIT is configured to compile lazily (using
-``ExecutionEngine::DisableLazyCompilation(false)``), there is currently a `race
-condition <https://bugs.llvm.org/show_bug.cgi?id=5184>`_ in updating call sites
+`ExecutionEngine::DisableLazyCompilation(false)`), there is currently a [race condition](https://bugs.llvm.org/show_bug.cgi?id=5184) in updating call sites
after a function is lazily-jitted. It's still possible to use the lazy JIT in a
threaded program if you ensure that only one thread at a time can call any
particular lazy stub and that the JIT lock guards any IR access, but we suggest
using only the eager JIT in threaded programs.
-.. _advanced:
+(advanced)=
-Advanced Topics
-===============
+## Advanced Topics
This section describes some of the advanced or obscure API's that most clients
do not need to be aware of. These API's tend manage the inner workings of the
LLVM system, and only need to be accessed in unusual circumstances.
-.. _SymbolTable:
+(SymbolTable)=
-The ``ValueSymbolTable`` class
-------------------------------
+### The `ValueSymbolTable` class
-The ``ValueSymbolTable`` (`doxygen
-<https://llvm.org/doxygen/classllvm_1_1ValueSymbolTable.html>`__) class provides
-a symbol table that the :ref:`Function <c_Function>` and Module_ classes use for
-naming value definitions. The symbol table can provide a name for any Value_.
+The `ValueSymbolTable` ([doxygen](https://llvm.org/doxygen/classllvm_1_1ValueSymbolTable.html)) class provides
+a symbol table that the {ref}`Function <c_Function>` and {ref}`Module <Module>` classes use for
+naming value definitions. The symbol table can provide a name for any {ref}`Value <Value>`.
-Note that the ``SymbolTable`` class should not be directly accessed by most
+Note that the `SymbolTable` class should not be directly accessed by most
clients. It should only be used when iteration over the symbol table names
themselves are required, which is very special purpose. Note that not all LLVM
-Value_\ s have names, and those without names (i.e., they have an empty name) do
+{ref}`Value <Value>`s have names, and those without names (i.e., they have an empty name) do
not exist in the symbol table.
Symbol tables support iteration over the values in the symbol table with
-``begin/end/iterator`` and supports querying to see if a specific name is in the
-symbol table (with ``lookup``). The ``ValueSymbolTable`` class exposes no
-public mutator methods, instead, simply call ``setName`` on a value, which will
+`begin/end/iterator` and supports querying to see if a specific name is in the
+symbol table (with `lookup`). The `ValueSymbolTable` class exposes no
+public mutator methods, instead, simply call `setName` on a value, which will
autoinsert it into the appropriate symbol table.
-.. _UserLayout:
+(UserLayout)=
-The ``User`` and owned ``Use`` classes' memory layout
------------------------------------------------------
+### The `User` and owned `Use` classes' memory layout
-The ``User`` (`doxygen <https://llvm.org/doxygen/classllvm_1_1User.html>`__)
-class provides a basis for expressing the ownership of ``User`` towards other
-`Value instance <https://llvm.org/doxygen/classllvm_1_1Value.html>`_\ s. The
-``Use`` (`doxygen <https://llvm.org/doxygen/classllvm_1_1Use.html>`__) helper
+The `User` ([doxygen](https://llvm.org/doxygen/classllvm_1_1User.html))
+class provides a basis for expressing the ownership of `User` towards other
+[Value instance](https://llvm.org/doxygen/classllvm_1_1Value.html)s. The
+`Use` ([doxygen](https://llvm.org/doxygen/classllvm_1_1Use.html)) helper
class is employed to do the bookkeeping and to facilitate *O(1)* addition and
removal.
-.. _Use2User:
+(Use2User)=
-Interaction and relationship between ``User`` and ``Use`` objects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Interaction and relationship between `User` and `Use` objects
-A subclass of ``User`` can choose between incorporating its ``Use`` objects or
-refer to them out-of-line by means of a pointer. A mixed variant (some ``Use``
+A subclass of `User` can choose between incorporating its `Use` objects or
+refer to them out-of-line by means of a pointer. A mixed variant (some `Use`
s inline others hung off) is impractical and breaks the invariant that the
-``Use`` objects belonging to the same ``User`` form a contiguous array.
+`Use` objects belonging to the same `User` form a contiguous array.
-We have 2 different layouts in the ``User`` (sub)classes:
+We have 2 different layouts in the `User` (sub)classes:
* Layout a)
- The ``Use`` object(s) are inside (resp. at fixed offset) of the ``User``
+ The `Use` object(s) are inside (resp. at fixed offset) of the `User`
object and there are a fixed number of them.
* Layout b)
- The ``Use`` object(s) are referenced by a pointer to an array from the
- ``User`` object and there may be a variable number of them.
+ The `Use` object(s) are referenced by a pointer to an array from the
+ `User` object and there may be a variable number of them.
As of v2.4 each layout still possesses a direct pointer to the start of the
-array of ``Use``\ s. Though not mandatory for layout a), we stick to this
-redundancy for the sake of simplicity. The ``User`` object also stores the
-number of ``Use`` objects it has. (Theoretically this information can also be
+array of `Use`s. Though not mandatory for layout a), we stick to this
+redundancy for the sake of simplicity. The `User` object also stores the
+number of `Use` objects it has. (Theoretically this information can also be
calculated given the scheme presented below.)
-Special forms of allocation operators (``operator new``) enforce the following
+Special forms of allocation operators (`operator new`) enforce the following
memory layouts:
-* Layout a) is modelled by prepending the ``User`` object by the ``Use[]``
+* Layout a) is modelled by prepending the `User` object by the `Use[]`
array.
- .. code-block:: none
-
- ...---.---.---.---.-------...
- | P | P | P | P | User
- '''---'---'---'---'-------'''
-
-* Layout b) is modelled by pointing at the ``Use[]`` array.
-
- .. code-block:: none
-
- .-------...
- | User
- '-------'''
- |
- v
- .---.---.---.---...
- | P | P | P | P |
- '---'---'---'---'''
-
-*(In the above figures* '``P``' *stands for the* ``Use**`` *that is stored in
-each* ``Use`` *object in the member* ``Use::Prev`` *)*
-
-.. _polymorphism:
-
-Designing Type Hierarchies and Polymorphic Interfaces
------------------------------------------------------
+ ```none
+ ...---.---.---.---.-------...
+ | P | P | P | P | User
+ '''---'---'---'---'-------'''
+ ```
+* Layout b) is modelled by pointing at the `Use[]` array.
+
+ ```none
+ .-------...
+ | User
+ '-------'''
+ |
+ v
+ .---.---.---.---...
+ | P | P | P | P |
+ '---'---'---'---'''
+ ```
+*(In the above figures* '`P`' *stands for the* `Use**` *that is stored in
+each* `Use` *object in the member* `Use::Prev` *)*
+
+(polymorphism)=
+
+### Designing Type Hierarchies and Polymorphic Interfaces
There are two different design patterns that tend to result in the use of
virtual dispatch for methods in a type hierarchy in C++ programs. The first is
a genuine type hierarchy where different types in the hierarchy model
a specific subset of the functionality and semantics, and these types nest
-strictly within each other. Good examples of this can be seen in the ``Value``
-or ``Type`` type hierarchies.
+strictly within each other. Good examples of this can be seen in the `Value`
+or `Type` type hierarchies.
A second is the desire to dispatch dynamically across a collection of
polymorphic interface implementations. This latter use case can be modeled with
@@ -3423,28 +3165,25 @@ implementations.
The preferred implementation strategy for the second use case is that of
generic programming (sometimes called "compile-time duck typing" or "static
-polymorphism"). For example, a template over some type parameter ``T`` can be
+polymorphism"). For example, a template over some type parameter `T` can be
instantiated across any particular implementation that conforms to the
interface or *concept*. A good example here is the highly generic properties of
any type which models a node in a directed graph. LLVM models these primarily
through templates and generic programming. Such templates include the
-``LoopInfoBase`` and ``DominatorTreeBase``. When this type of polymorphism
+`LoopInfoBase` and `DominatorTreeBase`. When this type of polymorphism
truly needs **dynamic** dispatch you can generalize it using a technique
called *concept-based polymorphism*. This pattern emulates the interfaces and
behaviors of templates using a very limited form of virtual dispatch for type
erasure inside its implementation. You can find examples of this technique in
-the ``PassManager.h`` system, and there is a more detailed introduction to it
+the `PassManager.h` system, and there is a more detailed introduction to it
by Sean Parent in several of his talks and papers:
-#. `Inheritance Is The Base Class of Evil
- <https://learn.microsoft.com/en-us/shows/goingnative-2013/inheritance-base-class-of-evil>`_
+1. [Inheritance Is The Base Class of Evil](https://learn.microsoft.com/en-us/shows/goingnative-2013/inheritance-base-class-of-evil)
- The GoingNative 2013 talk describing this technique, and probably the best
place to start.
-#. `Value Semantics and Concepts-based Polymorphism
- <http://www.youtube.com/watch?v=_BpMYeUFXv8>`_ - The C++Now! 2012 talk
+1. [Value Semantics and Concepts-based Polymorphism](http://www.youtube.com/watch?v=_BpMYeUFXv8) - The C++Now! 2012 talk
describing this technique in more detail.
-#. `Sean Parent's Papers and Presentations
- <https://sean-parent.stlab.cc/papers-and-presentations>`_
+1. [Sean Parent's Papers and Presentations](https://sean-parent.stlab.cc/papers-and-presentations)
- Links to slides, videos, and sometimes code.
When deciding between creating a type hierarchy (with either tagged or virtual
@@ -3465,14 +3204,12 @@ generate significantly more efficient code. We have also found that a large
amount of our usage of type hierarchies fits better with tag-based pattern
matching rather than dynamic dispatch across a common interface. Within LLVM we
have built custom helpers to facilitate this design. See this document's
-section on :ref:`isa and dyn_cast <isa>` and our :doc:`detailed document
-<HowToSetUpLLVMStyleRTTI>` which describes how you can implement this
+section on {ref}`isa and dyn_cast <isa>` and our {doc}`detailed document <HowToSetUpLLVMStyleRTTI>` which describes how you can implement this
pattern for use with the LLVM helpers.
-.. _abi_breaking_checks:
+(abi_breaking_checks)=
-ABI Breaking Checks
--------------------
+### ABI Breaking Checks
Checks and asserts that alter the LLVM C++ ABI are predicated on the
preprocessor symbol `LLVM_ENABLE_ABI_BREAKING_CHECKS` -- LLVM
@@ -3485,242 +3222,232 @@ between +Asserts and -Asserts builds should use the CMake build system
to set `LLVM_ENABLE_ABI_BREAKING_CHECKS` independently
of `LLVM_ENABLE_ASSERTIONS`.
-.. _coreclasses:
+(coreclasses)=
-The Core LLVM Class Hierarchy Reference
-=======================================
+## The Core LLVM Class Hierarchy Reference
-``#include "llvm/IR/Type.h"``
+`#include "llvm/IR/Type.h"`
-header source: `Type.h <https://llvm.org/doxygen/Type_8h_source.html>`_
+header source: [Type.h](https://llvm.org/doxygen/Type_8h_source.html)
-doxygen info: `Type Classes <https://llvm.org/doxygen/classllvm_1_1Type.html>`_
+doxygen info: [Type Classes](https://llvm.org/doxygen/classllvm_1_1Type.html)
The Core LLVM classes are the primary means of representing the program being
inspected or transformed. The core LLVM classes are defined in header files in
-the ``include/llvm/IR`` directory, and implemented in the ``lib/IR``
+the `include/llvm/IR` directory, and implemented in the `lib/IR`
directory. It's worth noting that, for historical reasons, this library is
-called ``libLLVMCore.so``, not ``libLLVMIR.so`` as you might expect.
+called `libLLVMCore.so`, not `libLLVMIR.so` as you might expect.
-.. _Type:
+(Type)=
-The Type class and Derived Types
---------------------------------
+### The Type class and Derived Types
-``Type`` is a superclass of all type classes. Every ``Value`` has a ``Type``.
-``Type`` cannot be instantiated directly but only through its subclasses.
-Certain primitive types (``VoidType``, ``LabelType``, ``FloatType`` and
-``DoubleType``) have hidden subclasses. They are hidden because they offer no
-useful functionality beyond what the ``Type`` class offers except to distinguish
-themselves from other subclasses of ``Type``.
+`Type` is a superclass of all type classes. Every `Value` has a `Type`.
+`Type` cannot be instantiated directly but only through its subclasses.
+Certain primitive types (`VoidType`, `LabelType`, `FloatType` and
+`DoubleType`) have hidden subclasses. They are hidden because they offer no
+useful functionality beyond what the `Type` class offers except to distinguish
+themselves from other subclasses of `Type`.
-All other types are subclasses of ``DerivedType``. Types can be named, but this
+All other types are subclasses of `DerivedType`. Types can be named, but this
is not a requirement. There exists exactly one instance of a given shape at any
one time. This allows type equality to be performed with address equality of
-the Type Instance. That is, given two ``Type*`` values, the types are identical
+the Type Instance. That is, given two `Type*` values, the types are identical
if the pointers are identical.
-.. _m_Type:
+(m_Type)=
-Important Public Methods
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Methods
-* ``bool isIntegerTy() const``: Returns true for any integer type.
+* `bool isIntegerTy() const`: Returns true for any integer type.
-* ``bool isFloatingPointTy()``: Return true if this is one of the five
+* `bool isFloatingPointTy()`: Return true if this is one of the five
floating point types.
-* ``bool isSized()``: Return true if the type has known size. Things
+* `bool isSized()`: Return true if the type has known size. Things
that don't have a size are abstract types, labels and void.
-.. _derivedtypes:
+(derivedtypes)=
-Important Derived Types
-^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Derived Types
-``IntegerType``
+`IntegerType`
Subclass of DerivedType that represents integer types of any bit width. Any
- bit width between ``IntegerType::MIN_INT_BITS`` (1) and
- ``IntegerType::MAX_INT_BITS`` (~8 million) can be represented.
+ bit width between `IntegerType::MIN_INT_BITS` (1) and
+ `IntegerType::MAX_INT_BITS` (~8 million) can be represented.
- * ``static const IntegerType* get(unsigned NumBits)``: get an integer
+ * `static const IntegerType* get(unsigned NumBits)`: get an integer
type of a specific bit width.
- * ``unsigned getBitWidth() const``: Get the bit width of an integer type.
+ * `unsigned getBitWidth() const`: Get the bit width of an integer type.
-``SequentialType``
+`SequentialType`
This is subclassed by ArrayType and VectorType.
- * ``const Type * getElementType() const``: Returns the type of each
+ * `const Type * getElementType() const`: Returns the type of each
of the elements in the sequential type.
- * ``uint64_t getNumElements() const``: Returns the number of elements
+ * `uint64_t getNumElements() const`: Returns the number of elements
in the sequential type.
-``ArrayType``
+`ArrayType`
This is a subclass of SequentialType and defines the interface for array
types.
-``PointerType``
+`PointerType`
Subclass of Type for pointer types.
-``VectorType``
+`VectorType`
Subclass of SequentialType for vector types. A vector type is similar to an
ArrayType but is distinguished because it is a first class type whereas
ArrayType is not. Vector types are used for vector operations and are usually
small vectors of an integer or floating point type.
-``StructType``
+`StructType`
Subclass of DerivedTypes for struct types.
-.. _FunctionType:
+(FunctionType)=
-``FunctionType``
+`FunctionType`
Subclass of DerivedTypes for function types.
- * ``bool isVarArg() const``: Returns true if it's a vararg function.
+ * `bool isVarArg() const`: Returns true if it's a vararg function.
- * ``const Type * getReturnType() const``: Returns the return type of the
+ * `const Type * getReturnType() const`: Returns the return type of the
function.
- * ``const Type * getParamType (unsigned i)``: Returns the type of the ith
+ * `const Type * getParamType (unsigned i)`: Returns the type of the ith
parameter.
- * ``const unsigned getNumParams() const``: Returns the number of formal
+ * `const unsigned getNumParams() const`: Returns the number of formal
parameters.
-.. _Module:
+(Module)=
-The ``Module`` class
---------------------
+### The `Module` class
-``#include "llvm/IR/Module.h"``
+`#include "llvm/IR/Module.h"`
-header source: `Module.h <https://llvm.org/doxygen/Module_8h_source.html>`_
+header source: [Module.h](https://llvm.org/doxygen/Module_8h_source.html)
-doxygen info: `Module Class <https://llvm.org/doxygen/classllvm_1_1Module.html>`_
+doxygen info: [Module Class](https://llvm.org/doxygen/classllvm_1_1Module.html)
-The ``Module`` class represents the top level structure present in LLVM
+The `Module` class represents the top level structure present in LLVM
programs. An LLVM module is effectively either a translation unit of the
original program or a combination of several translation units merged by the
-linker. The ``Module`` class keeps track of a list of :ref:`Function
-<c_Function>`\ s, a list of GlobalVariable_\ s, and a SymbolTable_.
+linker. The `Module` class keeps track of a list of {ref}`Function <c_Function>`s, a list of {ref}`GlobalVariable <GlobalVariable>`s, and a {ref}`SymbolTable <SymbolTable>`.
Additionally, it contains a few helpful member functions that try to make common
operations easy.
-.. _m_Module:
+(m_Module)=
-Important Public Members of the ``Module`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `Module` class
-* ``Module::Module(std::string name = "")``
+* `Module::Module(std::string name = "")`
- Constructing a Module_ is easy. You can optionally provide a name for it
+ Constructing a {ref}`Module <Module>` is easy. You can optionally provide a name for it
(probably based on the name of the translation unit).
-* | ``Module::iterator`` - Typedef for function list iterator
- | ``Module::const_iterator`` - Typedef for const_iterator.
- | ``begin()``, ``end()``, ``size()``, ``empty()``
+* `Module::iterator` - Typedef for function list iterator\
+ `Module::const_iterator` - Typedef for const_iterator.\
+ `begin()`, `end()`, `size()`, `empty()`
These are forwarding methods that make it easy to access the contents of a
- ``Module`` object's :ref:`Function <c_Function>` list.
+ `Module` object's {ref}`Function <c_Function>` list.
-* ``Module::FunctionListType &getFunctionList()``
+* `Module::FunctionListType &getFunctionList()`
- Returns the list of :ref:`Function <c_Function>`\ s. This is necessary to use
+ Returns the list of {ref}`Function <c_Function>`s. This is necessary to use
when you need to update the list or perform a complex action that doesn't have
a forwarding method.
----------------
-* | ``Module::global_iterator`` - Typedef for global variable list iterator
- | ``Module::const_global_iterator`` - Typedef for const_iterator.
- | ``Module::insertGlobalVariable()`` - Inserts a global variable to the list.
- | ``Module::removeGlobalVariable()`` - Removes a global variable from the list.
- | ``Module::eraseGlobalVariable()`` - Removes a global variable from the list and deletes it.
- | ``global_begin()``, ``global_end()``, ``global_size()``, ``global_empty()``
+* `Module::global_iterator` - Typedef for global variable list iterator\
+ `Module::const_global_iterator` - Typedef for const_iterator.\
+ `Module::insertGlobalVariable()` - Inserts a global variable to the list.\
+ `Module::removeGlobalVariable()` - Removes a global variable from the list.\
+ `Module::eraseGlobalVariable()` - Removes a global variable from the list and deletes it.\
+ `global_begin()`, `global_end()`, `global_size()`, `global_empty()`
These are forwarding methods that make it easy to access the contents of a
- ``Module`` object's GlobalVariable_ list.
+ `Module` object's {ref}`GlobalVariable <GlobalVariable>` list.
----------------
-* ``SymbolTable *getSymbolTable()``
+* `SymbolTable *getSymbolTable()`
- Return a reference to the SymbolTable_ for this ``Module``.
+ Return a reference to the {ref}`SymbolTable <SymbolTable>` for this `Module`.
----------------
-* ``Function *getFunction(StringRef Name) const``
+* `Function *getFunction(StringRef Name) const`
- Look up the specified function in the ``Module`` SymbolTable_. If it does not
- exist, return ``null``.
+ Look up the specified function in the `Module` {ref}`SymbolTable <SymbolTable>`. If it does not
+ exist, return `null`.
-* ``FunctionCallee getOrInsertFunction(const std::string &Name,
- const FunctionType *T)``
+* `FunctionCallee getOrInsertFunction(const std::string &Name,
+ const FunctionType *T)`
- Look up the specified function in the ``Module`` SymbolTable_. If
+ Look up the specified function in the `Module` {ref}`SymbolTable <SymbolTable>`. If
it does not exist, add an external declaration for the function and
return it. Note that the function signature already present may not
match the requested signature. Thus, in order to enable the common
usage of passing the result directly to EmitCall, the return type is
- a struct of ``{FunctionType *T, Constant *FunctionPtr}``, rather
- than simply the ``Function*`` with potentially an unexpected
+ a struct of `{FunctionType *T, Constant *FunctionPtr}`, rather
+ than simply the `Function*` with potentially an unexpected
signature.
-* ``std::string getTypeName(const Type *Ty)``
+* `std::string getTypeName(const Type *Ty)`
- If there is at least one entry in the SymbolTable_ for the specified Type_,
+ If there is at least one entry in the {ref}`SymbolTable <SymbolTable>` for the specified {ref}`Type <Type>`,
return it. Otherwise return the empty string.
-* ``bool addTypeName(const std::string &Name, const Type *Ty)``
+* `bool addTypeName(const std::string &Name, const Type *Ty)`
- Insert an entry in the SymbolTable_ mapping ``Name`` to ``Ty``. If there is
- already an entry for this name, true is returned and the SymbolTable_ is not
+ Insert an entry in the {ref}`SymbolTable <SymbolTable>` mapping `Name` to `Ty`. If there is
+ already an entry for this name, true is returned and the {ref}`SymbolTable <SymbolTable>` is not
modified.
-.. _Value:
+(Value)=
-The ``Value`` class
--------------------
+### The `Value` class
-``#include "llvm/IR/Value.h"``
+`#include "llvm/IR/Value.h"`
-header source: `Value.h <https://llvm.org/doxygen/Value_8h_source.html>`_
+header source: [Value.h](https://llvm.org/doxygen/Value_8h_source.html)
-doxygen info: `Value Class <https://llvm.org/doxygen/classllvm_1_1Value.html>`_
+doxygen info: [Value Class](https://llvm.org/doxygen/classllvm_1_1Value.html)
-The ``Value`` class is the most important class in the LLVM Source base. It
+The `Value` class is the most important class in the LLVM Source base. It
represents a typed value that may be used (among other things) as an operand to
-an instruction. There are many different types of ``Value``\ s, such as
-Constant_\ s, Argument_\ s. Even Instruction_\ s and :ref:`Function
-<c_Function>`\ s are ``Value``\ s.
+an instruction. There are many different types of `Value`s, such as
+{ref}`Constant <Constant>`s, {ref}`Argument <Argument>`s. Even {ref}`Instruction <Instruction>`s and {ref}`Function <c_Function>`s are `Value`s.
-A particular ``Value`` may be used many times in the LLVM representation for a
+A particular `Value` may be used many times in the LLVM representation for a
program. For example, an incoming argument to a function (represented with an
-instance of the Argument_ class) is "used" by every instruction in the function
-that references the argument. To keep track of this relationship, the ``Value``
-class keeps a list of all of the ``User``\ s that is using it (the User_ class
-is a base class for all nodes in the LLVM graph that can refer to ``Value``\ s).
+instance of the {ref}`Argument <Argument>` class) is "used" by every instruction in the function
+that references the argument. To keep track of this relationship, the `Value`
+class keeps a list of all of the `User`s that is using it (the {ref}`User <User>` class
+is a base class for all nodes in the LLVM graph that can refer to `Value`s).
This use list is how LLVM represents def-use information in the program, and is
-accessible through the ``use_*`` methods, shown below.
+accessible through the `use_*` methods, shown below.
-Because LLVM is a typed representation, every LLVM ``Value`` is typed, and this
-Type_ is available through the ``getType()`` method. In addition, all LLVM
-values can be named. The "name" of the ``Value`` is a symbolic string printed
+Because LLVM is a typed representation, every LLVM `Value` is typed, and this
+{ref}`Type <Type>` is available through the `getType()` method. In addition, all LLVM
+values can be named. The "name" of the `Value` is a symbolic string printed
in the LLVM code:
-.. code-block:: llvm
-
- %foo = add i32 1, 2
-
-.. _nameWarning:
+```llvm
+%foo = add i32 1, 2
+```
+(nameWarning)=
The name of this instruction is "foo". **NOTE** that the name of any value may
be missing (an empty string), so names should **ONLY** be used for debugging
(making the source code easier to read, debugging printouts), they should not be
used to keep track of values or map between them. For this purpose, use a
-``std::map`` of pointers to the ``Value`` itself instead.
+`std::map` of pointers to the `Value` itself instead.
One important aspect of LLVM is that there is no distinction between an SSA
variable and the operation that produces it. Because of this, any reference to
@@ -3729,429 +3456,405 @@ argument, for example) is represented as a direct pointer to the instance of the
class that represents this value. Although this may take some getting used to,
it simplifies the representation and makes it easier to manipulate.
-.. _m_Value:
+(m_Value)=
-Important Public Members of the ``Value`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `Value` class
-* | ``Value::use_iterator`` - Typedef for iterator over the use-list
- | ``Value::const_use_iterator`` - Typedef for const_iterator over the
- use-list
- | ``unsigned use_size()`` - Returns the number of users of the value.
- | ``bool use_empty()`` - Returns true if there are no users.
- | ``use_iterator use_begin()`` - Get an iterator to the start of the
- use-list.
- | ``use_iterator use_end()`` - Get an iterator to the end of the use-list.
- | ``User *use_back()`` - Returns the last element in the list.
+* `Value::use_iterator` - Typedef for iterator over the use-list\
+ `Value::const_use_iterator` - Typedef for const_iterator over the
+ use-list\
+ `unsigned use_size()` - Returns the number of users of the value.\
+ `bool use_empty()` - Returns true if there are no users.\
+ `use_iterator use_begin()` - Get an iterator to the start of the
+ use-list.\
+ `use_iterator use_end()` - Get an iterator to the end of the use-list.\
+ `User *use_back()` - Returns the last element in the list.
These methods are the interface to access the def-use information in LLVM.
As with all other iterators in LLVM, the naming conventions follow the
- conventions defined by the STL_.
+ conventions defined by the {ref}`STL <stl>`.
-* ``Type *getType() const``
+* `Type *getType() const`
This method returns the Type of the Value.
-* | ``bool hasName() const``
- | ``std::string getName() const``
- | ``void setName(const std::string &Name)``
+* `bool hasName() const`\
+ `std::string getName() const`\
+ `void setName(const std::string &Name)`
- This family of methods is used to access and assign a name to a ``Value``, be
- aware of the :ref:`precaution above <nameWarning>`.
+ This family of methods is used to access and assign a name to a `Value`, be
+ aware of the {ref}`precaution above <nameWarning>`.
-* ``void replaceAllUsesWith(Value *V)``
+* `void replaceAllUsesWith(Value *V)`
- This method traverses the use list of a ``Value`` changing all User_\ s of the
- current value to refer to "``V``" instead. For example, if you detect that an
+ This method traverses the use list of a `Value` changing all {ref}`User <User>`s of the
+ current value to refer to "`V`" instead. For example, if you detect that an
instruction always produces a constant value (for example through constant
folding), you can replace all uses of the instruction with the constant like
this:
- .. code-block:: c++
-
- Inst->replaceAllUsesWith(ConstVal);
-
-.. _User:
+ ```cpp
+ Inst->replaceAllUsesWith(ConstVal);
+ ```
+(User)=
-The ``User`` class
-------------------
+### The `User` class
-``#include "llvm/IR/User.h"``
+`#include "llvm/IR/User.h"`
-header source: `User.h <https://llvm.org/doxygen/User_8h_source.html>`_
+header source: [User.h](https://llvm.org/doxygen/User_8h_source.html)
-doxygen info: `User Class <https://llvm.org/doxygen/classllvm_1_1User.html>`_
+doxygen info: [User Class](https://llvm.org/doxygen/classllvm_1_1User.html)
-Superclass: Value_
+Superclass: {ref}`Value <Value>`
-The ``User`` class is the common base class of all LLVM nodes that may refer to
-``Value``\ s. It exposes a list of "Operands" that are all of the ``Value``\ s
-that the User is referring to. The ``User`` class itself is a subclass of
-``Value``.
+The `User` class is the common base class of all LLVM nodes that may refer to
+`Value`s. It exposes a list of "Operands" that are all of the `Value`s
+that the User is referring to. The `User` class itself is a subclass of
+`Value`.
-The operands of a ``User`` point directly to the LLVM ``Value`` that it refers
+The operands of a `User` point directly to the LLVM `Value` that it refers
to. Because LLVM uses Static Single Assignment (SSA) form, there can only be
one definition referred to, allowing this direct connection. This connection
provides the use-def information in LLVM.
-.. _m_User:
+(m_User)=
-Important Public Members of the ``User`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `User` class
-The ``User`` class exposes the operand list in two ways: through an index access
+The `User` class exposes the operand list in two ways: through an index access
interface and through an iterator based interface.
-* | ``Value *getOperand(unsigned i)``
- | ``unsigned getNumOperands()``
+* `Value *getOperand(unsigned i)`\
+ `unsigned getNumOperands()`
- These two methods expose the operands of the ``User`` in a convenient form for
+ These two methods expose the operands of the `User` in a convenient form for
direct access.
-* | ``User::op_iterator`` - Typedef for iterator over the operand list
- | ``op_iterator op_begin()`` - Get an iterator to the start of the operand
- list.
- | ``op_iterator op_end()`` - Get an iterator to the end of the operand list.
+* `User::op_iterator` - Typedef for iterator over the operand list\
+ `op_iterator op_begin()` - Get an iterator to the start of the operand
+ list.\
+ `op_iterator op_end()` - Get an iterator to the end of the operand list.
Together, these methods make up the iterator based interface to the operands
- of a ``User``.
+ of a `User`.
-.. _Instruction:
+(Instruction)=
-The ``Instruction`` class
--------------------------
+### The `Instruction` class
-``#include "llvm/IR/Instruction.h"``
+`#include "llvm/IR/Instruction.h"`
-header source: `Instruction.h
-<https://llvm.org/doxygen/Instruction_8h_source.html>`_
+header source: [Instruction.h](https://llvm.org/doxygen/Instruction_8h_source.html)
-doxygen info: `Instruction Class
-<https://llvm.org/doxygen/classllvm_1_1Instruction.html>`_
+doxygen info: [Instruction Class](https://llvm.org/doxygen/classllvm_1_1Instruction.html)
-Superclasses: User_, Value_
+Superclasses: {ref}`User <User>`, {ref}`Value <Value>`
-The ``Instruction`` class is the common base class for all LLVM instructions.
+The `Instruction` class is the common base class for all LLVM instructions.
It provides only a few methods, but is a very commonly used class. The primary
-data tracked by the ``Instruction`` class itself is the opcode (instruction
-type) and the parent BasicBlock_ the ``Instruction`` is embedded into. To
+data tracked by the `Instruction` class itself is the opcode (instruction
+type) and the parent {ref}`BasicBlock <BasicBlock>` the `Instruction` is embedded into. To
represent a specific type of instruction, one of many subclasses of
-``Instruction`` are used.
+`Instruction` are used.
-Because the ``Instruction`` class subclasses the User_ class, its operands can
-be accessed in the same way as for other ``User``\ s (with the
-``getOperand()``/``getNumOperands()`` and ``op_begin()``/``op_end()`` methods).
-An important file for the ``Instruction`` class is the ``llvm/Instruction.def``
+Because the `Instruction` class subclasses the {ref}`User <User>` class, its operands can
+be accessed in the same way as for other `User`s (with the
+`getOperand()`/`getNumOperands()` and `op_begin()`/`op_end()` methods).
+An important file for the `Instruction` class is the `llvm/Instruction.def`
file. This file contains some meta-data about the various different types of
instructions in LLVM. It describes the enum values that are used as opcodes
-(for example ``Instruction::Add`` and ``Instruction::ICmp``), as well as the
-concrete sub-classes of ``Instruction`` that implement the instruction (for
-example BinaryOperator_ and CmpInst_). Unfortunately, the use of macros in this
+(for example `Instruction::Add` and `Instruction::ICmp`), as well as the
+concrete sub-classes of `Instruction` that implement the instruction (for
+example {ref}`BinaryOperator <BinaryOperator>` and {ref}`CmpInst <CmpInst>`). Unfortunately, the use of macros in this
file confuses doxygen, so these enum values don't show up correctly in the
-`doxygen output <https://llvm.org/doxygen/classllvm_1_1Instruction.html>`_.
+[doxygen output](https://llvm.org/doxygen/classllvm_1_1Instruction.html).
-.. _s_Instruction:
+(s_Instruction)=
-Important Subclasses of the ``Instruction`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Subclasses of the `Instruction` class
-.. _BinaryOperator:
+(BinaryOperator)=
-* ``BinaryOperator``
+* `BinaryOperator`
This subclass represents all two operand instructions whose operands must be
the same type, except for the comparison instructions.
-.. _CastInst:
+(CastInst)=
-* ``CastInst``
+* `CastInst`
This subclass is the parent of the 12 casting instructions. It provides
common operations on cast instructions.
-.. _CmpInst:
+(CmpInst)=
-* ``CmpInst``
+* `CmpInst`
This subclass represents the two comparison instructions,
- `ICmpInst <LangRef.html#i_icmp>`_ (integer operands), and
- `FCmpInst <LangRef.html#i_fcmp>`_ (floating point operands).
+ {ref}`ICmpInst <i_icmp>` (integer operands), and
+ {ref}`FCmpInst <i_fcmp>` (floating point operands).
-.. _m_Instruction:
+(m_Instruction)=
-Important Public Members of the ``Instruction`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `Instruction` class
-* ``BasicBlock *getParent()``
+* `BasicBlock *getParent()`
- Returns the BasicBlock_ that this
- ``Instruction`` is embedded into.
+ Returns the {ref}`BasicBlock <BasicBlock>` that this
+ `Instruction` is embedded into.
-* ``bool mayWriteToMemory()``
+* `bool mayWriteToMemory()`
- Returns true if the instruction writes to memory, i.e., it is a ``call``,
- ``free``, ``invoke``, or ``store``.
+ Returns true if the instruction writes to memory, i.e., it is a `call`,
+ `free`, `invoke`, or `store`.
-* ``unsigned getOpcode()``
+* `unsigned getOpcode()`
- Returns the opcode for the ``Instruction``.
+ Returns the opcode for the `Instruction`.
-* ``Instruction *clone() const``
+* `Instruction *clone() const`
Returns another instance of the specified instruction, identical in all ways
to the original except that the instruction has no parent (i.e., it's not
- embedded into a BasicBlock_), and it has no name.
+ embedded into a {ref}`BasicBlock <BasicBlock>`), and it has no name.
-.. _Constant:
+(Constant)=
-The ``Constant`` class and subclasses
--------------------------------------
+### The `Constant` class and subclasses
Constant represents a base class for different types of constants. It is
subclassed by ConstantInt, ConstantArray, etc. for representing the various
-types of Constants. GlobalValue_ is also a subclass, which represents the
+types of Constants. {ref}`GlobalValue <GlobalValue>` is also a subclass, which represents the
address of a global variable or function.
-.. _s_Constant:
+(s_Constant)=
-Important Subclasses of Constant
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Subclasses of Constant
* ConstantInt : This subclass of Constant represents an integer constant of
any width.
- * ``const APInt& getValue() const``: Returns the underlying
- value of this constant, an ``APInt`` value.
+ * `const APInt& getValue() const`: Returns the underlying
+ value of this constant, an `APInt` value.
- * ``int64_t getSExtValue() const``: Converts the underlying APInt value to an
- ``int64_t`` via sign extension. If the value (not the bit width) of the APInt
- is too large to fit in an ``int64_t``, an assertion will result. For this
+ * `int64_t getSExtValue() const`: Converts the underlying APInt value to an
+ `int64_t` via sign extension. If the value (not the bit width) of the APInt
+ is too large to fit in an `int64_t`, an assertion will result. For this
reason, use of this method is discouraged.
- * ``uint64_t getZExtValue() const``: Converts the underlying ``APInt`` value
- to a ``uint64_t`` via zero extension. If the value (not the bit width) of the
- APInt is too large to fit in a ``uint64_t``, an assertion will result. For this
+ * `uint64_t getZExtValue() const`: Converts the underlying `APInt` value
+ to a `uint64_t` via zero extension. If the value (not the bit width) of the
+ APInt is too large to fit in a `uint64_t`, an assertion will result. For this
reason, use of this method is discouraged.
- * ``static ConstantInt* get(const APInt& Val)``: Returns the ConstantInt
- object that represents the value provided by ``Val``. The type is implied
- as the IntegerType that corresponds to the bit width of ``Val``.
+ * `static ConstantInt* get(const APInt& Val)`: Returns the ConstantInt
+ object that represents the value provided by `Val`. The type is implied
+ as the IntegerType that corresponds to the bit width of `Val`.
- * ``static ConstantInt* get(const Type *Ty, uint64_t Val)``: Returns the
- ConstantInt object that represents the value provided by ``Val`` for integer
- type ``Ty``.
+ * `static ConstantInt* get(const Type *Ty, uint64_t Val)`: Returns the
+ ConstantInt object that represents the value provided by `Val` for integer
+ type `Ty`.
* ConstantFP : This class represents a floating point constant.
- * ``double getValue() const``: Returns the underlying value of this constant.
+ * `double getValue() const`: Returns the underlying value of this constant.
* ConstantArray : This represents a constant array.
- * ``const std::vector<Use> &getValues() const``: Returns a vector of
+ * `const std::vector<Use> &getValues() const`: Returns a vector of
component constants that makeup this array.
* ConstantStruct : This represents a constant struct.
- * ``const std::vector<Use> &getValues() const``: Returns a vector of
+ * `const std::vector<Use> &getValues() const`: Returns a vector of
component constants that makeup this array.
* GlobalValue : This represents either a global variable or a function. In
either case, the value is a constant fixed address (after linking).
-.. _GlobalValue:
+(GlobalValue)=
-The ``GlobalValue`` class
--------------------------
+### The `GlobalValue` class
-``#include "llvm/IR/GlobalValue.h"``
+`#include "llvm/IR/GlobalValue.h"`
-header source: `GlobalValue.h
-<https://llvm.org/doxygen/GlobalValue_8h_source.html>`_
+header source: [GlobalValue.h](https://llvm.org/doxygen/GlobalValue_8h_source.html)
-doxygen info: `GlobalValue Class
-<https://llvm.org/doxygen/classllvm_1_1GlobalValue.html>`_
+doxygen info: [GlobalValue Class](https://llvm.org/doxygen/classllvm_1_1GlobalValue.html)
-Superclasses: Constant_, User_, Value_
+Superclasses: {ref}`Constant <Constant>`, {ref}`User <User>`, {ref}`Value <Value>`
-Global values ( GlobalVariable_\ s or :ref:`Function <c_Function>`\ s) are the
-only LLVM values that are visible in the bodies of all :ref:`Function
-<c_Function>`\ s. Because they are visible at global scope, they are also
+Global values ( {ref}`GlobalVariable <GlobalVariable>`s or {ref}`Function <c_Function>`s) are the
+only LLVM values that are visible in the bodies of all {ref}`Function <c_Function>`s. Because they are visible at global scope, they are also
subject to linking with other globals defined in different translation units.
-To control the linking process, ``GlobalValue``\ s know their linkage rules.
-Specifically, ``GlobalValue``\ s know whether they have internal or external
-linkage, as defined by the ``LinkageTypes`` enumeration.
+To control the linking process, `GlobalValue`s know their linkage rules.
+Specifically, `GlobalValue`s know whether they have internal or external
+linkage, as defined by the `LinkageTypes` enumeration.
-If a ``GlobalValue`` has internal linkage (equivalent to being ``static`` in C),
+If a `GlobalValue` has internal linkage (equivalent to being `static` in C),
it is not visible to code outside the current translation unit, and does not
participate in linking. If it has external linkage, it is visible to external
code, and does participate in linking. In addition to linkage information,
-``GlobalValue``\ s keep track of which Module_ they are currently part of.
+`GlobalValue`s keep track of which {ref}`Module <Module>` they are currently part of.
-Because ``GlobalValue``\ s are memory objects, they are always referred to by
-their **address**. As such, the Type_ of a global is always a pointer to its
-contents. It is important to remember this when using the ``GetElementPtrInst``
+Because `GlobalValue`s are memory objects, they are always referred to by
+their **address**. As such, the {ref}`Type <Type>` of a global is always a pointer to its
+contents. It is important to remember this when using the `GetElementPtrInst`
instruction because this pointer must be dereferenced first. For example, if
-you have a ``GlobalVariable`` (a subclass of ``GlobalValue)`` that is an array
-of 24 ints, type ``[24 x i32]``, then the ``GlobalVariable`` is a pointer to
+you have a `GlobalVariable` (a subclass of `GlobalValue)` that is an array
+of 24 ints, type `[24 x i32]`, then the `GlobalVariable` is a pointer to
that array. Although the address of the first element of this array and the
-value of the ``GlobalVariable`` are the same, they have different types. The
-``GlobalVariable``'s type is ``[24 x i32]``. The first element's type is
-``i32.`` Because of this, accessing a global value requires you to dereference
-the pointer with ``GetElementPtrInst`` first, then its elements can be accessed.
-This is explained in the `LLVM Language Reference Manual
-<LangRef.html#globalvars>`_.
+value of the `GlobalVariable` are the same, they have different types. The
+`GlobalVariable`'s type is `[24 x i32]`. The first element's type is
+`i32.` Because of this, accessing a global value requires you to dereference
+the pointer with `GetElementPtrInst` first, then its elements can be accessed.
+This is explained in the {ref}`LLVM Language Reference Manual <globalvars>`.
-.. _m_GlobalValue:
+(m_GlobalValue)=
-Important Public Members of the ``GlobalValue`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `GlobalValue` class
-* | ``bool hasInternalLinkage() const``
- | ``bool hasExternalLinkage() const``
- | ``void setInternalLinkage(bool HasInternalLinkage)``
+* `bool hasInternalLinkage() const`\
+ `bool hasExternalLinkage() const`\
+ `void setInternalLinkage(bool HasInternalLinkage)`
- These methods manipulate the linkage characteristics of the ``GlobalValue``.
+ These methods manipulate the linkage characteristics of the `GlobalValue`.
-* ``Module *getParent()``
+* `Module *getParent()`
- This returns the Module_ that the
+ This returns the {ref}`Module <Module>` that the
GlobalValue is currently embedded into.
-.. _c_Function:
+(c_Function)=
-The ``Function`` class
-----------------------
+### The `Function` class
-``#include "llvm/IR/Function.h"``
+`#include "llvm/IR/Function.h"`
-header source: `Function.h <https://llvm.org/doxygen/Function_8h_source.html>`_
+header source: [Function.h](https://llvm.org/doxygen/Function_8h_source.html)
-doxygen info: `Function Class
-<https://llvm.org/doxygen/classllvm_1_1Function.html>`_
+doxygen info: [Function Class](https://llvm.org/doxygen/classllvm_1_1Function.html)
-Superclasses: GlobalValue_, Constant_, User_, Value_
+Superclasses: {ref}`GlobalValue <GlobalValue>`, {ref}`Constant <Constant>`, {ref}`User <User>`, {ref}`Value <Value>`
-The ``Function`` class represents a single procedure in LLVM. It is actually
+The `Function` class represents a single procedure in LLVM. It is actually
one of the more complex classes in the LLVM hierarchy because it must keep track
-of a large amount of data. The ``Function`` class keeps track of a list of
-BasicBlock_\ s, a list of formal Argument_\ s, and a SymbolTable_.
+of a large amount of data. The `Function` class keeps track of a list of
+{ref}`BasicBlock <BasicBlock>`s, a list of formal {ref}`Argument <Argument>`s, and a {ref}`SymbolTable <SymbolTable>`.
-The list of BasicBlock_\ s is the most commonly used part of ``Function``
+The list of {ref}`BasicBlock <BasicBlock>`s is the most commonly used part of `Function`
objects. The list imposes an implicit ordering of the blocks in the function,
which indicate how the code will be laid out by the backend. Additionally, the
-first BasicBlock_ is the implicit entry node for the ``Function``. It is not
+first {ref}`BasicBlock <BasicBlock>` is the implicit entry node for the `Function`. It is not
legal in LLVM to explicitly branch to this initial block. There are no implicit
exit nodes, and in fact there may be multiple exit nodes from a single
-``Function``. If the BasicBlock_ list is empty, this indicates that the
-``Function`` is actually a function declaration: the actual body of the function
+`Function`. If the {ref}`BasicBlock <BasicBlock>` list is empty, this indicates that the
+`Function` is actually a function declaration: the actual body of the function
hasn't been linked in yet.
-In addition to a list of BasicBlock_\ s, the ``Function`` class also keeps track
-of the list of formal Argument_\ s that the function receives. This container
-manages the lifetime of the Argument_ nodes, just like the BasicBlock_ list does
-for the BasicBlock_\ s.
+In addition to a list of {ref}`BasicBlock <BasicBlock>`s, the `Function` class also keeps track
+of the list of formal {ref}`Argument <Argument>`s that the function receives. This container
+manages the lifetime of the {ref}`Argument <Argument>` nodes, just like the {ref}`BasicBlock <BasicBlock>` list does
+for the {ref}`BasicBlock <BasicBlock>`s.
-The SymbolTable_ is a very rarely used LLVM feature that is only used when you
-have to look up a value by name. Aside from that, the SymbolTable_ is used
+The {ref}`SymbolTable <SymbolTable>` is a very rarely used LLVM feature that is only used when you
+have to look up a value by name. Aside from that, the {ref}`SymbolTable <SymbolTable>` is used
internally to make sure that there are not conflicts between the names of
-Instruction_\ s, BasicBlock_\ s, or Argument_\ s in the function body.
+{ref}`Instruction <Instruction>`s, {ref}`BasicBlock <BasicBlock>`s, or {ref}`Argument <Argument>`s in the function body.
-Note that ``Function`` is a GlobalValue_ and therefore also a Constant_. The
+Note that `Function` is a {ref}`GlobalValue <GlobalValue>` and therefore also a {ref}`Constant <Constant>`. The
value of the function is its address (after linking) which is guaranteed to be
constant.
-.. _m_Function:
+(m_Function)=
-Important Public Members of the ``Function``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `Function`
-* ``Function(const FunctionType *Ty, LinkageTypes Linkage,
- const std::string &N = "", Module* Parent = 0)``
+* `Function(const FunctionType *Ty, LinkageTypes Linkage,
+ const std::string &N = "", Module* Parent = 0)`
- Constructor used when you need to create new ``Function``\ s to add the
+ Constructor used when you need to create new `Function`s to add the
program. The constructor must specify the type of the function to create and
- what type of linkage the function should have. The FunctionType_ argument
+ what type of linkage the function should have. The {ref}`FunctionType <FunctionType>` argument
specifies the formal arguments and return value for the function. The same
- FunctionType_ value can be used to create multiple functions. The ``Parent``
+ {ref}`FunctionType <FunctionType>` value can be used to create multiple functions. The `Parent`
argument specifies the Module in which the function is defined. If this
argument is provided, the function will automatically be inserted into that
module's list of functions.
-* ``bool isDeclaration()``
+* `bool isDeclaration()`
- Return whether or not the ``Function`` has a body defined. If the function is
+ Return whether or not the `Function` has a body defined. If the function is
"external", it does not have a body, and thus must be resolved by linking with
a function defined in a different translation unit.
-* | ``Function::iterator`` - Typedef for basic block list iterator
- | ``Function::const_iterator`` - Typedef for const_iterator.
- | ``begin()``, ``end()``, ``size()``, ``empty()``, ``insert()``,
- ``splice()``, ``erase()``
+* `Function::iterator` - Typedef for basic block list iterator\
+ `Function::const_iterator` - Typedef for const_iterator.\
+ `begin()`, `end()`, `size()`, `empty()`, `insert()`,
+ `splice()`, `erase()`
These are forwarding methods that make it easy to access the contents of a
- ``Function`` object's BasicBlock_ list.
+ `Function` object's {ref}`BasicBlock <BasicBlock>` list.
-* | ``Function::arg_iterator`` - Typedef for the argument list iterator
- | ``Function::const_arg_iterator`` - Typedef for const_iterator.
- | ``arg_begin()``, ``arg_end()``, ``arg_size()``, ``arg_empty()``
+* `Function::arg_iterator` - Typedef for the argument list iterator\
+ `Function::const_arg_iterator` - Typedef for const_iterator.\
+ `arg_begin()`, `arg_end()`, `arg_size()`, `arg_empty()`
These are forwarding methods that make it easy to access the contents of a
- ``Function`` object's Argument_ list.
+ `Function` object's {ref}`Argument <Argument>` list.
-* ``Function::ArgumentListType &getArgumentList()``
+* `Function::ArgumentListType &getArgumentList()`
- Returns the list of Argument_. This is necessary to use when you need to
+ Returns the list of {ref}`Argument <Argument>`. This is necessary to use when you need to
update the list or perform a complex action that doesn't have a forwarding
method.
-* ``BasicBlock &getEntryBlock()``
+* `BasicBlock &getEntryBlock()`
- Returns the entry ``BasicBlock`` for the function. Because the entry block
+ Returns the entry `BasicBlock` for the function. Because the entry block
for the function is always the first block, this returns the first block of
- the ``Function``.
+ the `Function`.
-* | ``Type *getReturnType()``
- | ``FunctionType *getFunctionType()``
+* `Type *getReturnType()`\
+ `FunctionType *getFunctionType()`
- This traverses the Type_ of the ``Function`` and returns the return type of
- the function, or the FunctionType_ of the actual function.
+ This traverses the {ref}`Type <Type>` of the `Function` and returns the return type of
+ the function, or the {ref}`FunctionType <FunctionType>` of the actual function.
-* ``SymbolTable *getSymbolTable()``
+* `SymbolTable *getSymbolTable()`
- Return a pointer to the SymbolTable_ for this ``Function``.
+ Return a pointer to the {ref}`SymbolTable <SymbolTable>` for this `Function`.
-.. _GlobalVariable:
+(GlobalVariable)=
-The ``GlobalVariable`` class
-----------------------------
+### The `GlobalVariable` class
-``#include "llvm/IR/GlobalVariable.h"``
+`#include "llvm/IR/GlobalVariable.h"`
-header source: `GlobalVariable.h
-<https://llvm.org/doxygen/GlobalVariable_8h_source.html>`_
+header source: [GlobalVariable.h](https://llvm.org/doxygen/GlobalVariable_8h_source.html)
-doxygen info: `GlobalVariable Class
-<https://llvm.org/doxygen/classllvm_1_1GlobalVariable.html>`_
+doxygen info: [GlobalVariable Class](https://llvm.org/doxygen/classllvm_1_1GlobalVariable.html)
-Superclasses: GlobalValue_, Constant_, User_, Value_
+Superclasses: {ref}`GlobalValue <GlobalValue>`, {ref}`Constant <Constant>`, {ref}`User <User>`, {ref}`Value <Value>`
-Global variables are represented with the (surprise surprise) ``GlobalVariable``
-class. Like functions, ``GlobalVariable``\ s are also subclasses of
-GlobalValue_, and as such are always referenced by their address (global values
+Global variables are represented with the (surprise surprise) `GlobalVariable`
+class. Like functions, `GlobalVariable`s are also subclasses of
+{ref}`GlobalValue <GlobalValue>`, and as such are always referenced by their address (global values
must live in memory, so their "name" refers to their constant address). See
-GlobalValue_ for more on this. Global variables may have an initial value
-(which must be a Constant_), and if they have an initializer, they may be marked
+{ref}`GlobalValue <GlobalValue>` for more on this. Global variables may have an initial value
+(which must be a {ref}`Constant <Constant>`), and if they have an initializer, they may be marked
as "constant" themselves (indicating that their contents never change at
runtime).
-.. _m_GlobalVariable:
+(m_GlobalVariable)=
-Important Public Members of the ``GlobalVariable`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `GlobalVariable` class
-* ``GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes &Linkage,
- Constant *Initializer = 0, const std::string &Name = "", Module* Parent = 0)``
+* `GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes &Linkage,
+ Constant *Initializer = 0, const std::string &Name = "", Module* Parent = 0)`
- Create a new global variable of the specified type. If ``isConstant`` is true
+ Create a new global variable of the specified type. If `isConstant` is true
then the global variable will be marked as unchanging for the program. The
Linkage parameter specifies the type of linkage (internal, external, weak,
linkonce, appending) for the variable. If the linkage is InternalLinkage,
@@ -4159,72 +3862,67 @@ Important Public Members of the ``GlobalVariable`` class
the resultant global variable will have internal linkage. AppendingLinkage
concatenates together all instances (in different translation units) of the
variable into a single variable but is only applicable to arrays. See the
- `LLVM Language Reference <LangRef.html#modulestructure>`_ for further details
+ [LLVM Language Reference](https://llvm.org/docs/LangRef.html#modulestructure) for further details
on linkage types. Optionally an initializer, a name, and the module to put
the variable into may be specified for the global variable as well.
-* ``bool isConstant() const``
+* `bool isConstant() const`
Returns true if this is a global variable that is known not to be modified at
runtime.
-* ``bool hasInitializer()``
+* `bool hasInitializer()`
- Returns true if this ``GlobalVariable`` has an initializer.
+ Returns true if this `GlobalVariable` has an initializer.
-* ``Constant *getInitializer()``
+* `Constant *getInitializer()`
- Returns the initial value for a ``GlobalVariable``. It is not legal to call
+ Returns the initial value for a `GlobalVariable`. It is not legal to call
this method if there is no initializer.
-.. _BasicBlock:
+(BasicBlock)=
-The ``BasicBlock`` class
-------------------------
+### The `BasicBlock` class
-``#include "llvm/IR/BasicBlock.h"``
+`#include "llvm/IR/BasicBlock.h"`
-header source: `BasicBlock.h
-<https://llvm.org/doxygen/BasicBlock_8h_source.html>`_
+header source: [BasicBlock.h](https://llvm.org/doxygen/BasicBlock_8h_source.html)
-doxygen info: `BasicBlock Class
-<https://llvm.org/doxygen/classllvm_1_1BasicBlock.html>`_
+doxygen info: [BasicBlock Class](https://llvm.org/doxygen/classllvm_1_1BasicBlock.html)
-Superclass: Value_
+Superclass: {ref}`Value <Value>`
This class represents a single entry single exit section of the code, commonly
-known as a basic block by the compiler community. The ``BasicBlock`` class
-maintains a list of Instruction_\ s, which form the body of the block. Matching
+known as a basic block by the compiler community. The `BasicBlock` class
+maintains a list of {ref}`Instruction <Instruction>`s, which form the body of the block. Matching
the language definition, the last element of this list of instructions is always
a terminator instruction.
In addition to tracking the list of instructions that make up the block, the
-``BasicBlock`` class also keeps track of the :ref:`Function <c_Function>` that
+`BasicBlock` class also keeps track of the {ref}`Function <c_Function>` that
it is embedded into.
-Note that ``BasicBlock``\ s themselves are Value_\ s, because they are
+Note that `BasicBlock`s themselves are {ref}`Value <Value>`s, because they are
referenced by instructions like branches and can go in the switch tables.
-``BasicBlock``\ s have type ``label``.
+`BasicBlock`s have type `label`.
-.. _m_BasicBlock:
+(m_BasicBlock)=
-Important Public Members of the ``BasicBlock`` class
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Important Public Members of the `BasicBlock` class
-* ``BasicBlock(const std::string &Name = "", Function *Parent = 0)``
+* `BasicBlock(const std::string &Name = "", Function *Parent = 0)`
- The ``BasicBlock`` constructor is used to create new basic blocks for
+ The `BasicBlock` constructor is used to create new basic blocks for
insertion into a function. The constructor optionally takes a name for the
- new block, and a :ref:`Function <c_Function>` to insert it into. If the
- ``Parent`` parameter is specified, the new ``BasicBlock`` is automatically
- inserted at the end of the specified :ref:`Function <c_Function>`, if not
- specified, the ``BasicBlock`` must be manually inserted into the :ref:`Function
- <c_Function>`.
-
-* | ``BasicBlock::iterator`` - Typedef for instruction list iterator
- | ``BasicBlock::const_iterator`` - Typedef for const_iterator.
- | ``begin()``, ``end()``, ``front()``, ``back()``,
- ``size()``, ``empty()``, ``splice()``
+ new block, and a {ref}`Function <c_Function>` to insert it into. If the
+ `Parent` parameter is specified, the new `BasicBlock` is automatically
+ inserted at the end of the specified {ref}`Function <c_Function>`, if not
+ specified, the `BasicBlock` must be manually inserted into the {ref}`Function <c_Function>`.
+
+* `BasicBlock::iterator` - Typedef for instruction list iterator\
+ `BasicBlock::const_iterator` - Typedef for const_iterator.\
+ `begin()`, `end()`, `front()`, `back()`,
+ `size()`, `empty()`, `splice()`
STL-style functions for accessing the instruction list.
These methods and typedefs are forwarding functions that have the same
@@ -4232,21 +3930,20 @@ Important Public Members of the ``BasicBlock`` class
expose the underlying instruction list of a basic block in a way that is easy
to manipulate.
-* ``Function *getParent()``
+* `Function *getParent()`
- Returns a pointer to :ref:`Function <c_Function>` the block is embedded into,
+ Returns a pointer to {ref}`Function <c_Function>` the block is embedded into,
or a null pointer if it is homeless.
-* ``Instruction *getTerminator()``
+* `Instruction *getTerminator()`
Returns a pointer to the terminator instruction that appears at the end of the
- ``BasicBlock``. If there is no terminator instruction, or if the last
+ `BasicBlock`. If there is no terminator instruction, or if the last
instruction in the block is not a terminator, then a null pointer is returned.
-.. _Argument:
+(Argument)=
-The ``Argument`` class
-----------------------
+### The `Argument` class
This subclass of Value defines the interface for incoming formal arguments to a
function. A Function maintains a list of its formal arguments. An argument has
diff --git a/llvm/docs/RFCProcess.md b/llvm/docs/RFCProcess.md
index 2c339eb0cd557..e45c2782301dc 100644
--- a/llvm/docs/RFCProcess.md
+++ b/llvm/docs/RFCProcess.md
@@ -1,22 +1,20 @@
-=================================
-Request For Comment (RFC) process
-=================================
+# Request For Comment (RFC) process
-.. contents::
- :local:
- :depth: 1
+```{contents}
+:local:
+:depth: 1
+```
+
+## Introduction
-Introduction
-============
Substantive changes to LLVM projects need to be acceptable to the wider
community, which requires gaining community consensus to adopt the changes.
This is done by posting an RFC and obtaining feedback about the proposal.
-Process
-=======
+## Process
+
+### Writing an RFC
-Writing an RFC
---------------
The process begins with writing a proposal for the changes you'd like to see
made. The proposal should include:
@@ -26,10 +24,10 @@ made. The proposal should include:
* any open questions the community should address.
The proposal should be posted to the appropriate forum on
-`Discourse <https://discourse.llvm.org/>`_.
+[Discourse](https://discourse.llvm.org/).
+
+### Feedback Period
-Feedback Period
----------------
Once the RFC is posted, the community will provide feedback on the proposal.
The feedback period is a collaborative effort between the community and the
proposal authors. Authors should take the community's feedback into
@@ -45,14 +43,13 @@ discussion is actively continuing on the proposal.
After posting a major proposal, it is common to receive lots of conflicting
feedback from different parties, or no feedback at all, leaving authors without
-clear next steps. As a community, we are aiming for `"rough consensus"
-<https://en.wikipedia.org/wiki/Rough_consensus>`_, similar in spirit to what is
-described in `IETF RFC7282 <https://datatracker.ietf.org/doc/html/rfc7282>`_.
+clear next steps. As a community, we are aiming for ["rough consensus"][rc],
+similar in spirit to what is
+described in [IETF RFC7282][rfc7282].
This requires considering and addressing all of the objections to the RFC, and
confirming that we can all live with the tradeoffs embodied in the proposal.
-The LLVM Area Teams (defined in `LP0004
-<https://github.com/llvm/llvm-www/blob/main/proposals/LP0004-project-governance.md>`_)
+The LLVM Area Teams (defined in [LP0004][lp0004])
are responsible for facilitating project decision making. In cases where there
isn't obvious agreement, area teams should step in to restate their perceived
consensus. In cases of deeper disagreement, area teams should try to identify
@@ -60,20 +57,23 @@ the next steps for the proposal, such as gathering more data, changing the
proposal, or rejecting it in the absence of major changes in the design or
context. They can also act as moderators by scheduling calls for participants
to speak directly to resolve disagreements, subject to normal
-:ref:`Code of Conduct <LLVM Community Code of Conduct>` guidelines.
+{ref}`Code of Conduct <LLVM Community Code of Conduct>` guidelines.
Once the design of the new feature is finalized, the work itself should be done
-as a series of :ref:`incremental changes <incremental-changes>`, not as a long-term development branch.
+as a series of {ref}`incremental changes <incremental-changes>`, not as a long-term development branch.
+[rc]: https://en.wikipedia.org/wiki/Rough_consensus
+[rfc7282]: https://datatracker.ietf.org/doc/html/rfc7282
+[lp0004]: https://github.com/llvm/llvm-www/blob/main/proposals/LP0004-project-governance.md
+
+### Trivial Acceptance or Rejection
-Trivial Acceptance or Rejection
--------------------------------
Some proposals have obvious consensus (for or against) after discussion in the
community. It is acceptable to presume a post which appears to have obvious
consensus has been accepted.
-Non-trivial Acceptance or Rejection
------------------------------------
+### Non-trivial Acceptance or Rejection
+
If the proposal does not have obvious consensus after community discussion,
a maintainer for each of the impacted parts of the project should explicitly
accept or reject the RFC by leaving a comment stating their decision and
@@ -81,16 +81,16 @@ possibly detailing any provisions for their acceptance. Overall consensus is
determined once a maintainer from each impacted part of the project has
accepted the proposal.
-Low Engagement Level
-~~~~~~~~~~~~~~~~~~~~
+#### Low Engagement Level
+
If the proposal gets little or no engagement by the community, it is a sign that
the proposal does not have consensus and is rejected. Engagement means comments
on the proposal. If there are few or no comments but the are a lot of people
pressing the like/heart button on the post, the appropriate area team can make
a value judgement on whether to accept or reject.
-After Acceptance
-----------------
+### After Acceptance
+
Once an RFC has been accepted, the authors may begin merging pull requests
related to the proposal. While the RFC process typically makes reviewing the
pull requests go more smoothly, the review process may identify additional
@@ -98,16 +98,16 @@ necessary changes to the proposal. Minor changes to the proposal do not require
an additional RFC. However, if the proposal changes significantly in a material
way, the authors may be asked to run another RFC.
-After Rejection
----------------
+### After Rejection
+
Any rejected RFC can be brought back to the community as a new RFC in the
future. The new RFC should either clearly identify new information that may
change the community's perception of the proposal and/or explicitly address the
concerns previously raised by the community. It is helpful to explicitly call
out such information in the subsequent RFC.
-Suggestions on Getting a Change Accepted
-----------------------------------------
+### Suggestions on Getting a Change Accepted
+
These are some suggestions for how to get a major change accepted:
* Make it targeted, and avoid touching components irrelevant to the task.
@@ -122,4 +122,4 @@ These are some suggestions for how to get a major change accepted:
* Compilers are foundational infrastructure, so there is a high quality bar,
and the burden of proof is on the proposer. If reviewers repeatedly ask for
an unreasonable amount of evidence or data, proposal authors can escalate to
- the area team to resolve disagreements.
\ No newline at end of file
+ the area team to resolve disagreements.
diff --git a/llvm/docs/Reference.md b/llvm/docs/Reference.md
index 56e367388b1a8..3333cb06095ed 100644
--- a/llvm/docs/Reference.md
+++ b/llvm/docs/Reference.md
@@ -1,258 +1,249 @@
-Reference
-=========
+---
+myst:
+ enable_extensions:
+ - deflist
+---
+
+# Reference
LLVM and API reference documentation.
-.. contents::
- :local:
-
-.. toctree::
- :hidden:
-
- HowToUseAttributes
- CommandGuide/index
- CommandGuide/llvm-reduce
- OptBisect
- SymbolizerMarkupFormat
- PDB/index
- GarbageCollection
- Statepoints
- LibFuzzer
- FuzzingLLVM
- LangRef
- UndefinedBehavior
- InAlloca
- BitCodeFormat
- MIRLangRef
- GlobalISel/index
- ConvergentOperations
- TestingGuide
- TestSuiteGuide
- GwpAsan
- XRay
- XRayExample
- FaultMaps
- Atomics
- ExceptionHandling
- Extensions
- HowToSetUpLLVMStyleRTTI
- BlockFrequencyTerminology
- BranchWeightMetadata
- GetElementPtr
- ScudoHardenedAllocator
- MemoryModelRelaxationAnnotations
- MemTagSanitizer
- DependenceGraphs/index
- SpeculativeLoadHardening
- SegmentedStacks
- MarkedUpDisassembly
- StackMaps
- Coroutines
- PointerAuth
- YamlIO
- ConvergenceAndUniformity
- MLGO
- ContentAddressableStorage
- CIBestPractices
- AIToolPolicy
- CalleeTypeMetadata
- CallGraphSection
- InterfaceExportAnnotations
- PCSectionsMetadata
- QualGroup
- Security
- SecurityTransparencyReports
- SystemLibrary
- TransformMetadata
- TypeMetadata
- XRayFDRFormat
-
-API Reference
--------------
-
-`Doxygen generated documentation <https://llvm.org/doxygen/>`_
- (`classes <https://llvm.org/doxygen/inherits.html>`_)
-
-:doc:`HowToUseAttributes`
- Answers some questions about the new Attributes infrastructure.
-
-LLVM Reference
---------------
-
-======================
-Command Line Utilities
-======================
-
-:doc:`LLVM Command Guide <CommandGuide/index>`
- A reference manual for the LLVM command line utilities ("man" pages for LLVM
- tools).
-
-:doc:`llvm-reduce <CommandGuide/llvm-reduce>`
- Automatic bug finder and test-case reducer description and usage
- information.
-
-:doc:`OptBisect`
- A command line option for debugging optimization-induced failures.
-
-:doc:`SymbolizerMarkupFormat`
- A reference for the log symbolizer markup accepted by ``llvm-symbolizer``.
-
-:doc:`The Microsoft PDB File Format <PDB/index>`
- A detailed description of the Microsoft PDB (Program Database) file format.
-
-==================
-Garbage Collection
-==================
-
-:doc:`GarbageCollection`
- The interfaces source-language compilers should use for compiling GC'd
- programs.
-
-:doc:`Statepoints`
- This describes a set of experimental extensions for garbage
- collection support.
-
-=========
+```{contents}
+:local:
+```
+
+```{toctree}
+:hidden:
+
+HowToUseAttributes
+CommandGuide/index
+CommandGuide/llvm-reduce
+OptBisect
+SymbolizerMarkupFormat
+PDB/index
+GarbageCollection
+Statepoints
LibFuzzer
-=========
+FuzzingLLVM
+LangRef
+UndefinedBehavior
+InAlloca
+BitCodeFormat
+MIRLangRef
+GlobalISel/index
+ConvergentOperations
+TestingGuide
+TestSuiteGuide
+GwpAsan
+XRay
+XRayExample
+FaultMaps
+Atomics
+ExceptionHandling
+Extensions
+HowToSetUpLLVMStyleRTTI
+BlockFrequencyTerminology
+BranchWeightMetadata
+GetElementPtr
+ScudoHardenedAllocator
+MemoryModelRelaxationAnnotations
+MemTagSanitizer
+DependenceGraphs/index
+SpeculativeLoadHardening
+SegmentedStacks
+MarkedUpDisassembly
+StackMaps
+Coroutines
+PointerAuth
+YamlIO
+ConvergenceAndUniformity
+MLGO
+ContentAddressableStorage
+CIBestPractices
+AIToolPolicy
+CalleeTypeMetadata
+CallGraphSection
+InterfaceExportAnnotations
+PCSectionsMetadata
+QualGroup
+Security
+SecurityTransparencyReports
+SystemLibrary
+TransformMetadata
+TypeMetadata
+XRayFDRFormat
+```
-:doc:`LibFuzzer`
- A library for writing in-process guided fuzzers.
+## API Reference
-:doc:`FuzzingLLVM`
- Information on writing and using Fuzzers to find bugs in LLVM.
+[Doxygen generated documentation](https://llvm.org/doxygen/)
+: ([classes](https://llvm.org/doxygen/inherits.html))
-========
-LLVM IR
-========
+{doc}`HowToUseAttributes`
+: Answers some questions about the new Attributes infrastructure.
-:doc:`LLVM Language Reference Manual <LangRef>`
- Defines the LLVM intermediate representation and the assembly form of the
- different nodes.
+## LLVM Reference
-:doc:`Undefined Behavior (UB) <UndefinedBehavior>`
- A guide on what UB/undef/poison are and when to use each one.
+### Command Line Utilities
-:doc:`InAlloca`
- Description of the ``inalloca`` argument attribute.
+{doc}`LLVM Command Guide <CommandGuide/index>`
+: A reference manual for the LLVM command line utilities ("man" pages for LLVM
+ tools).
-:doc:`BitCodeFormat`
- This describes the file format and encoding used for LLVM "bc" files.
+{doc}`llvm-reduce <CommandGuide/llvm-reduce>`
+: Automatic bug finder and test-case reducer description and usage
+ information.
-:doc:`Machine IR (MIR) Format Reference Manual <MIRLangRef>`
- A reference manual for the MIR serialization format, which is used to test
- LLVM's code generation passes.
+{doc}`OptBisect`
+: A command line option for debugging optimization-induced failures.
-:doc:`GlobalISel/index`
- This describes the prototype instruction selection replacement, GlobalISel.
+{doc}`SymbolizerMarkupFormat`
+: A reference for the log symbolizer markup accepted by `llvm-symbolizer`.
-:doc:`ConvergentOperations`
- Description of ``convergent`` operation semantics and related intrinsics.
+{doc}`The Microsoft PDB File Format <PDB/index>`
+: A detailed description of the Microsoft PDB (Program Database) file format.
-=====================
-Testing and Debugging
-=====================
+### Garbage Collection
-:doc:`LLVM Testing Infrastructure Guide <TestingGuide>`
- A reference manual for using the LLVM testing infrastructure.
+{doc}`GarbageCollection`
+: The interfaces source-language compilers should use for compiling GC'd
+ programs.
-:doc:`TestSuiteGuide`
- Describes how to compile and run the test-suite benchmarks.
+{doc}`Statepoints`
+: This describes a set of experimental extensions for garbage
+ collection support.
+### LibFuzzer
-:doc:`GwpAsan`
- A sampled heap memory error detection toolkit designed for production use.
+{doc}`LibFuzzer`
+: A library for writing in-process guided fuzzers.
-====
-XRay
-====
+{doc}`FuzzingLLVM`
+: Information on writing and using Fuzzers to find bugs in LLVM.
+
+### LLVM IR
+
+{doc}`LLVM Language Reference Manual <LangRef>`
+: Defines the LLVM intermediate representation and the assembly form of the
+ different nodes.
+
+{doc}`Undefined Behavior (UB) <UndefinedBehavior>`
+: A guide on what UB/undef/poison are and when to use each one.
+
+{doc}`InAlloca`
+: Description of the `inalloca` argument attribute.
+
+{doc}`BitCodeFormat`
+: This describes the file format and encoding used for LLVM "bc" files.
+
+{doc}`Machine IR (MIR) Format Reference Manual <MIRLangRef>`
+: A reference manual for the MIR serialization format, which is used to test
+ LLVM's code generation passes.
+
+{doc}`GlobalISel/index`
+: This describes the prototype instruction selection replacement, GlobalISel.
+
+{doc}`ConvergentOperations`
+: Description of `convergent` operation semantics and related intrinsics.
+
+### Testing and Debugging
+
+{doc}`LLVM Testing Infrastructure Guide <TestingGuide>`
+: A reference manual for using the LLVM testing infrastructure.
+
+{doc}`TestSuiteGuide`
+: Describes how to compile and run the test-suite benchmarks.
+
+
+{doc}`GwpAsan`
+: A sampled heap memory error detection toolkit designed for production use.
+
+### XRay
-:doc:`XRay`
- High-level documentation of how to use XRay in LLVM.
+{doc}`XRay`
+: High-level documentation of how to use XRay in LLVM.
-:doc:`XRayExample`
- An example of how to debug an application with XRay.
+{doc}`XRayExample`
+: An example of how to debug an application with XRay.
-=================
-Additional Topics
-=================
+### Additional Topics
-:doc:`FaultMaps`
- LLVM support for folding control flow into faulting machine instructions.
+{doc}`FaultMaps`
+: LLVM support for folding control flow into faulting machine instructions.
-:doc:`Atomics`
- Information about LLVM's concurrency model.
+{doc}`Atomics`
+: Information about LLVM's concurrency model.
-:doc:`ExceptionHandling`
- This document describes the design and implementation of exception handling
- in LLVM.
+{doc}`ExceptionHandling`
+: This document describes the design and implementation of exception handling
+ in LLVM.
-:doc:`Extensions`
- LLVM-specific extensions to tools and formats LLVM seeks compatibility with.
+{doc}`Extensions`
+: LLVM-specific extensions to tools and formats LLVM seeks compatibility with.
-:doc:`HowToSetUpLLVMStyleRTTI`
- How to make ``isa<>``, ``dyn_cast<>``, etc. available for clients of your
- class hierarchy.
+{doc}`HowToSetUpLLVMStyleRTTI`
+: How to make `isa<>`, `dyn_cast<>`, etc. available for clients of your
+ class hierarchy.
-:doc:`BlockFrequencyTerminology`
- Provides information about terminology used in the ``BlockFrequencyInfo``
- analysis pass.
+{doc}`BlockFrequencyTerminology`
+: Provides information about terminology used in the `BlockFrequencyInfo`
+ analysis pass.
-:doc:`BranchWeightMetadata`
- Provides information about Branch Prediction Information.
+{doc}`BranchWeightMetadata`
+: Provides information about Branch Prediction Information.
-:doc:`GetElementPtr`
- Answers to some very frequent questions about LLVM's most frequently
- misunderstood instruction.
+{doc}`GetElementPtr`
+: Answers to some very frequent questions about LLVM's most frequently
+ misunderstood instruction.
-:doc:`ScudoHardenedAllocator`
- A library that implements a security-hardened `malloc()`.
+{doc}`ScudoHardenedAllocator`
+: A library that implements a security-hardened `malloc()`.
-:doc:`MemoryModelRelaxationAnnotations`
- Target-defined relaxation to LLVM's concurrency model.
+{doc}`MemoryModelRelaxationAnnotations`
+: Target-defined relaxation to LLVM's concurrency model.
-:doc:`MemTagSanitizer`
- Security hardening for production code aiming to mitigate memory
- related vulnerabilities. Based on the Armv8.5-A Memory Tagging Extension.
+{doc}`MemTagSanitizer`
+: Security hardening for production code aiming to mitigate memory
+ related vulnerabilities. Based on the Armv8.5-A Memory Tagging Extension.
-:doc:`Dependence Graphs <DependenceGraphs/index>`
- A description of the design of the various dependence graphs such as
- the DDG (Data Dependence Graph).
+{doc}`Dependence Graphs <DependenceGraphs/index>`
+: A description of the design of the various dependence graphs such as
+ the DDG (Data Dependence Graph).
-:doc:`SpeculativeLoadHardening`
- A description of the Speculative Load Hardening mitigation for Spectre v1.
+{doc}`SpeculativeLoadHardening`
+: A description of the Speculative Load Hardening mitigation for Spectre v1.
-:doc:`SegmentedStacks`
- This document describes segmented stacks and how they are used in LLVM.
+{doc}`SegmentedStacks`
+: This document describes segmented stacks and how they are used in LLVM.
-:doc:`MarkedUpDisassembly`
- This document describes the optional rich disassembly output syntax.
+{doc}`MarkedUpDisassembly`
+: This document describes the optional rich disassembly output syntax.
-:doc:`StackMaps`
- LLVM support for mapping instruction addresses to the location of
- values and allowing code to be patched.
+{doc}`StackMaps`
+: LLVM support for mapping instruction addresses to the location of
+ values and allowing code to be patched.
-:doc:`Coroutines`
- LLVM support for coroutines.
+{doc}`Coroutines`
+: LLVM support for coroutines.
-:doc:`PointerAuth`
- A description of pointer authentication, its LLVM IR representation, and its
- support in the backend.
+{doc}`PointerAuth`
+: A description of pointer authentication, its LLVM IR representation, and its
+ support in the backend.
-:doc:`YamlIO`
- A reference guide for using LLVM's YAML I/O library.
+{doc}`YamlIO`
+: A reference guide for using LLVM's YAML I/O library.
-:doc:`ConvergenceAndUniformity`
- A description of uniformity analysis in the presence of irreducible
- control flow, and its implementation.
+{doc}`ConvergenceAndUniformity`
+: A description of uniformity analysis in the presence of irreducible
+ control flow, and its implementation.
-:doc:`MLGO`
- Facilities for ML-Guided Optimization, such as collecting IR corpora from a
- build, interfacing with ML models, an exposing features for training.
+{doc}`MLGO`
+: Facilities for ML-Guided Optimization, such as collecting IR corpora from a
+ build, interfacing with ML models, an exposing features for training.
-:doc:`ContentAddressableStorage`
- A reference guide for using LLVM's CAS library.
+{doc}`ContentAddressableStorage`
+: A reference guide for using LLVM's CAS library.
-:doc:`CIBestPractices`
- A list of guidelines and best practices to use when working on LLVM's
- CI systems.
+{doc}`CIBestPractices`
+: A list of guidelines and best practices to use when working on LLVM's
+ CI systems.
diff --git a/llvm/docs/SourceLevelDebugging.md b/llvm/docs/SourceLevelDebugging.md
index 815fccec7aa40..74bb8840a56e4 100644
--- a/llvm/docs/SourceLevelDebugging.md
+++ b/llvm/docs/SourceLevelDebugging.md
@@ -1,21 +1,18 @@
-================================
-Source Level Debugging with LLVM
-================================
+# Source Level Debugging with LLVM
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction
-============
+## Introduction
This document is the central repository for all information pertaining to debug
-information in LLVM. It describes the :ref:`actual format that the LLVM debug
+information in LLVM. It describes the {ref}`actual format that the LLVM debug
information takes <format>`, which is useful for those interested in creating
front-ends or dealing directly with the information. Further, this document
provides specific examples of what debug information for C/C++ looks like.
-Philosophy behind LLVM debugging information
---------------------------------------------
+### Philosophy behind LLVM debugging information
The idea of the LLVM debugging information is to capture how the important
pieces of the source-language's Abstract Syntax Tree map onto LLVM code.
@@ -26,7 +23,7 @@ important ones are:
compiler. No transformations, analyses, or code generators should need to
be modified because of debugging information.
-* LLVM optimizations should interact in :ref:`well-defined and easily described
+* LLVM optimizations should interact in {ref}`well-defined and easily described
ways <intro_debugopt>` with the debugging information.
* Because LLVM is designed to support arbitrary programming languages,
@@ -43,22 +40,20 @@ important ones are:
debuggers, like GDB or DBX.
The approach used by the LLVM implementation is to use a small set of
-:ref:`debug records <debug_records>` to define a mapping
+{ref}`debug records <debug_records>` to define a mapping
between LLVM program objects and the source-level objects. The description of
the source-level program is maintained in LLVM metadata in an
-:ref:`implementation-defined format <ccxx_frontend>` (the C/C++ front-end
-currently uses working draft 7 of the `DWARF 3 standard
-<http://www.eagercon.com/dwarf/dwarf3std.htm>`_).
+{ref}`implementation-defined format <ccxx_frontend>` (the C/C++ front-end
+currently uses working draft 7 of the [DWARF 3 standard](http://www.eagercon.com/dwarf/dwarf3std.htm)).
When a program is being debugged, a debugger interacts with the user and turns
the stored debug information into source-language specific information. As
such, a debugger must be aware of the source-language, and is thus tied to a
specific language or family of languages.
-.. _intro_consumers:
+(intro_consumers)=
-Debug information consumers
----------------------------
+### Debug information consumers
The role of debug information is to provide meta information normally stripped
away during the compilation process. This meta information provides an LLVM
@@ -67,20 +62,20 @@ code.
Currently, there are two backend consumers of debug info: DwarfDebug and
CodeViewDebug. DwarfDebug produces DWARF suitable for use with GDB, LLDB, and
-other DWARF-based debuggers. :ref:`CodeViewDebug <codeview>` produces CodeView,
+other DWARF-based debuggers. {ref}`CodeViewDebug <codeview>` produces CodeView,
the Microsoft debug info format, which is usable with Microsoft debuggers such
as Visual Studio and WinDBG. LLVM's debug information format is mostly derived
from and inspired by DWARF, but it is feasible to translate into other target
debug info formats such as STABS.
-SamplePGO (also known as `AutoFDO <https://gcc.gnu.org/wiki/AutoFDO>`_)
+SamplePGO (also known as [AutoFDO](https://gcc.gnu.org/wiki/AutoFDO))
is a variant of profile-guided optimizations which uses hardware sampling based
profilers to collect branch frequency data with low overhead in production
environments. It relies on debug information to associate profile information
with LLVM IR which is then used to guide optimization heuristics. Maintaining
deterministic and distinct source locations is necessary to maximize the
accuracy of mapping hardware sample counts to LLVM IR. For example, DWARF
-`discriminators <https://wiki.dwarfstd.org/Path_Discriminators.md>`_ allow
+[discriminators](https://wiki.dwarfstd.org/Path_Discriminators.md) allow
SamplePGO to distinguish between multiple paths of execution which map to the
same source line.
@@ -88,10 +83,9 @@ It would also be reasonable to use debug information to feed profiling tools
for analysis of generated code, or, tools for reconstructing the original
source from generated code.
-.. _intro_debugopt:
+(intro_debugopt)=
-Debug information and optimizations
------------------------------------
+### Debug information and optimizations
An extremely high priority of LLVM debugging information is to make it interact
well with optimizations and analysis. In particular, the LLVM debug
@@ -99,7 +93,7 @@ information provides the following guarantees:
* LLVM debug information **always provides information to accurately read
the source-level state of the program**, regardless of which LLVM
- optimizations have been run. :doc:`HowToUpdateDebugInfo` specifies how debug
+ optimizations have been run. {doc}`HowToUpdateDebugInfo` specifies how debug
info should be updated in various kinds of code transformations to avoid
breaking this guarantee, and how to preserve as much useful debug info as
possible. Note that some optimizations may impact the ability to modify the
@@ -121,18 +115,17 @@ information provides the following guarantees:
is automatically removed.
Basically, the debug information allows you to compile a program with
-"``-O0 -g``" and get full debug information, allowing you to arbitrarily modify
+"`-O0 -g`" and get full debug information, allowing you to arbitrarily modify
the program as it executes from a debugger. Compiling a program with
-"``-O3 -g``" gives you full debug information that is always available and
+"`-O3 -g`" gives you full debug information that is always available and
accurate for reading (e.g., you get accurate stack traces despite tail call
elimination and inlining), but you might lose the ability to modify the program
and call functions which were optimized out of the program, or inlined away
completely.
-.. _variables_and_variable_fragments:
+(variables_and_variable_fragments)=
-Variables and Variable Fragments
-================================
+## Variables and Variable Fragments
In this document "variable" refers generally to any source language object
which can have a value, including at least:
@@ -141,34 +134,31 @@ which can have a value, including at least:
- Constants
- Formal parameters
-.. note::
-
- There is no special provision for "true" constants in LLVM today, and
- they are instead treated as local or global variables.
-
-A variable is represented by a :ref:`local variable <dilocalvariable>` or
-:ref:`global variable <diglobalvariable>` metadata node.
+```{note}
+There is no special provision for "true" constants in LLVM today, and
+they are instead treated as local or global variables.
+```
+A variable is represented by a {ref}`local variable <dilocalvariable>` or
+{ref}`global variable <diglobalvariable>` metadata node.
A "variable fragment" (or just "fragment") is a contiguous span of bits of a
variable.
-A :ref:`debug record <debug_records>` which refers to a :ref:`diexpression`
-ending with a ``DW_OP_LLVM_fragment`` operation describes a fragment of the
+A {ref}`debug record <debug_records>` which refers to a {ref}`diexpression`
+ending with a `DW_OP_LLVM_fragment` operation describes a fragment of the
variable it refers to.
-The operands of the ``DW_OP_LLVM_fragment`` operation encode the bit offset of
+The operands of the `DW_OP_LLVM_fragment` operation encode the bit offset of
the fragment relative to the start of the variable, and the size of the
fragment in bits, respectively.
-.. note::
-
- The ``DW_OP_LLVM_fragment`` operation acts only to encode the fragment
- information, and does not have an effect on the semantics of the expression.
+```{note}
+The `DW_OP_LLVM_fragment` operation acts only to encode the fragment
+information, and does not have an effect on the semantics of the expression.
+```
+(format)=
-.. _format:
-
-Debugging information format
-============================
+## Debugging information format
LLVM debugging information has been carefully designed to make it possible for
the optimizer to optimize the program and debugging information without
@@ -191,31 +181,30 @@ debugger to interpret the information.
To provide basic functionality, the LLVM debugger does have to make some
assumptions about the source-level language being debugged, though it keeps
these to a minimum. The only common features that the LLVM debugger assumes
-exist are :ref:`source files <difile>`, and :ref:`program objects
+exist are {ref}`source files <difile>`, and {ref}`program objects
<diglobalvariable>`. These abstract objects are used by a debugger to form
stack traces, show information about local variables, etc.
This section of the documentation first describes the representation aspects
-common to any source-language. :ref:`ccxx_frontend` describes the data layout
+common to any source-language. {ref}`ccxx_frontend` describes the data layout
conventions used by the C and C++ front-ends.
-Debug information descriptors are :ref:`specialized metadata nodes
-<specialized-metadata>`, first-class subclasses of ``Metadata``.
+Debug information descriptors are {ref}`specialized metadata nodes
+<specialized-metadata>`, first-class subclasses of `Metadata`.
There are two models for defining the values of source variables at different
states of the program and tracking these values through optimization and code
-generation: :ref:`debug records <debug_records>`, the current default, and
-:ref:`intrinsic function calls <format_common_intrinsics>`, which are
+generation: {ref}`debug records <debug_records>`, the current default, and
+{ref}`intrinsic function calls <format_common_intrinsics>`, which are
non-default but currently supported for backwards compatibility - though these
two models must never be mixed within an IR module. For an explanation of why
we changed to the new model, how it works, and guidance on how to update old
-code or IR to use debug records, see the `RemoveDIs <RemoveDIsDebugInfo.html>`_
+code or IR to use debug records, see the {doc}`RemoveDIs <RemoveDIsDebugInfo>`
document.
-.. _debug_records:
+(debug_records)=
-Debug Records
--------------
+### Debug Records
Debug records define the value that a source variable has during execution of
the program; they appear interleaved with instructions, although they are not
@@ -225,207 +214,185 @@ compiler.
LLVM uses several types of debug records to define source variables. The
common syntax for these records is:
-.. code-block:: llvm
-
- #dbg_<kind>([<arg>, ]* <DILocation>)
- ; Using the intrinsic model, the above is equivalent to:
- call void llvm.dbg.<kind>([metadata <arg>, ]*), !dbg <DILocation>
-
+```llvm
+ #dbg_<kind>([<arg>, ]* <DILocation>)
+; Using the intrinsic model, the above is equivalent to:
+call void llvm.dbg.<kind>([metadata <arg>, ]*), !dbg <DILocation>
+```
Debug records are always printed with an extra level of indentation compared
to instructions, and always have the prefix `#dbg_` and a list of
comma-separated arguments in parentheses, as with a `call`.
-``#dbg_declare``
-^^^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- #dbg_declare([Value|MDNode], DILocalVariable, DIExpression, DILocation)
+#### `#dbg_declare`
+```llvm
+#dbg_declare([Value|MDNode], DILocalVariable, DIExpression, DILocation)
+```
This record provides information about a local element (e.g., variable). The
-first argument is an SSA ``ptr`` value corresponding to a variable address, and
-is typically a static ``alloca`` in the function entry block. The second
-argument is a :ref:`local variable <dilocalvariable>` containing a description
-of the variable. The third argument is a :ref:`complex expression
-<diexpression>`. The fourth argument is a :ref:`source location <dilocation>`.
-A ``#dbg_declare`` record describes the *address* of a source variable.
-
-.. code-block:: llvm
-
- %i.addr = alloca i32, align 4
- #dbg_declare(ptr %i.addr, !1, !DIExpression(), !2)
- ; ...
- !1 = !DILocalVariable(name: "i", ...) ; int i
- !2 = !DILocation(...)
- ; ...
- %buffer = alloca [256 x i8], align 8
- ; The address of i is buffer+64.
- #dbg_declare(ptr %buffer, !3, !DIExpression(DW_OP_plus, 64), !4)
- ; ...
- !3 = !DILocalVariable(name: "i", ...) ; int i
- !4 = !DILocation(...)
-
-A frontend should generate exactly one ``#dbg_declare`` record at the point
+first argument is an SSA `ptr` value corresponding to a variable address, and
+is typically a static `alloca` in the function entry block. The second
+argument is a {ref}`local variable <dilocalvariable>` containing a description
+of the variable. The third argument is a {ref}`complex expression
+<diexpression>`. The fourth argument is a {ref}`source location <dilocation>`.
+A `#dbg_declare` record describes the *address* of a source variable.
+
+```llvm
+%i.addr = alloca i32, align 4
+ #dbg_declare(ptr %i.addr, !1, !DIExpression(), !2)
+; ...
+!1 = !DILocalVariable(name: "i", ...) ; int i
+!2 = !DILocation(...)
+; ...
+%buffer = alloca [256 x i8], align 8
+; The address of i is buffer+64.
+ #dbg_declare(ptr %buffer, !3, !DIExpression(DW_OP_plus, 64), !4)
+; ...
+!3 = !DILocalVariable(name: "i", ...) ; int i
+!4 = !DILocation(...)
+```
+A frontend should generate exactly one `#dbg_declare` record at the point
of declaration of a source variable. Optimization passes that fully promote the
variable from memory to SSA values will replace this record with possibly
-multiple ``#dbg_value``` records. Passes that delete stores are effectively
-partial promotion, and they will insert a mix of ``#dbg_value`` records to
+multiple `#dbg_value` records. Passes that delete stores are effectively
+partial promotion, and they will insert a mix of `#dbg_value` records to
track the source variable value when it is available. After optimization, there
-may be multiple ``#dbg_declare`` records describing the program points where
+may be multiple `#dbg_declare` records describing the program points where
the variables lives in memory. All calls for the same concrete source variable
must agree on the memory location.
-``#dbg_value``
-^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- #dbg_value([Value|DIArgList|MDNode], DILocalVariable, DIExpression, DILocation)
+#### `#dbg_value`
+```llvm
+#dbg_value([Value|DIArgList|MDNode], DILocalVariable, DIExpression, DILocation)
+```
This record provides information when a user source variable is set to a new
value. The first argument is the new value. The second argument is a
-:ref:`local variable <dilocalvariable>` containing a description of the
-variable. The third argument is a :ref:`complex expression <diexpression>`.
-The fourth argument is a :ref:`source location <dilocation>`.
+{ref}`local variable <dilocalvariable>` containing a description of the
+variable. The third argument is a {ref}`complex expression <diexpression>`.
+The fourth argument is a {ref}`source location <dilocation>`.
-A ``#dbg_value`` record describes the *value* of a source variable
+A `#dbg_value` record describes the *value* of a source variable
directly, not its address. Note that the value operand of this intrinsic may
be indirect (i.e, a pointer to the source variable), provided that interpreting
the complex expression derives the direct value.
-``#dbg_declare_value``
-^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- #dbg_declare_value([Value|MDNode], DILocalVariable, DIExpression, DILocation)
+#### `#dbg_declare_value`
+```llvm
+#dbg_declare_value([Value|MDNode], DILocalVariable, DIExpression, DILocation)
+```
This record provides information about a local element (e.g., variable). The
-first argument is used to compute the value of the variable throughout the
-entire function. The second argument is a
-:ref:`local variable <dilocalvariable>` containing a description of the
-variable. The third argument is a :ref:`complex expression <diexpression>`. The
-foruth argument is a :ref:`source location <dilocation>`. A
-``#dbg_declare_value`` record describes describes the *value* of a source
-variable directly, not its address. The difference between a ``#dbg_value`` and
-a ``#dbg_declare_value`` is that, just like a ``#dbg_declare``, a frontend
-should generate exactly one ``#dbg_declare_value`` record. The idea is to have
-``#dbg_declare`` guarantees but be able to describe a value rather than the
+first argument is used to compute the value of the variable throughout the
+entire function. The second argument is a
+{ref}`local variable <dilocalvariable>` containing a description of the
+variable. The third argument is a {ref}`complex expression <diexpression>`. The
+foruth argument is a {ref}`source location <dilocation>`. A
+`#dbg_declare_value` record describes describes the *value* of a source
+variable directly, not its address. The difference between a `#dbg_value` and
+a `#dbg_declare_value` is that, just like a `#dbg_declare`, a frontend
+should generate exactly one `#dbg_declare_value` record. The idea is to have
+`#dbg_declare` guarantees but be able to describe a value rather than the
address of a value.
-``#dbg_assign``
-^^^^^^^^^^^^^^^
-.. toctree::
- :hidden:
-
- AssignmentTracking
-
-.. code-block:: llvm
+#### `#dbg_assign`
- #dbg_assign( [Value|DIArgList|MDNode] Value,
- DILocalVariable Variable,
- DIExpression ValueExpression,
- DIAssignID ID,
- [Value|MDNode] Address,
- DIExpression AddressExpression,
- DILocation SourceLocation )
+```{toctree}
+:hidden:
+AssignmentTracking
+```
+```llvm
+#dbg_assign( [Value|DIArgList|MDNode] Value,
+ DILocalVariable Variable,
+ DIExpression ValueExpression,
+ DIAssignID ID,
+ [Value|MDNode] Address,
+ DIExpression AddressExpression,
+ DILocation SourceLocation )
+```
This record marks the position in IR where a source assignment occurred. It
encodes the value of the variable. It references the store, if any, that
performs the assignment, and the destination address.
-The first three arguments are the same as for a ``#dbg_value``. The fourth
-argument is a ``DIAssignID`` used to reference a store. The fifth is the
-destination of the store, the sixth is a :ref:`complex expression
-<diexpression>` that modifies it, and the seventh is a :ref:`source location
+The first three arguments are the same as for a `#dbg_value`. The fourth
+argument is a `DIAssignID` used to reference a store. The fifth is the
+destination of the store, the sixth is a {ref}`complex expression
+<diexpression>` that modifies it, and the seventh is a {ref}`source location
<dilocation>`.
-See :doc:`AssignmentTracking` for more info.
+See {doc}`AssignmentTracking` for more info.
-Debugger intrinsic functions
-----------------------------
+### Debugger intrinsic functions
-.. warning::
+```{warning}
+These intrinsics are deprecated, please use {ref}`debug records
+<debug_records>` instead. For more details see {doc}`RemoveDIs <RemoveDIsDebugInfo>`.
+```
+(format_common_intrinsics)=
- These intrinsics are deprecated, please use :ref:`debug records
- <debug_records>` instead. For more details see `RemoveDIs
- <RemoveDIsDebugInfo.html>`_.
-
-.. _format_common_intrinsics:
-
-In intrinsic-mode, LLVM uses several intrinsic functions (name prefixed with "``llvm.dbg``") to
+In intrinsic-mode, LLVM uses several intrinsic functions (name prefixed with "`llvm.dbg`") to
track source local variables through optimization and code generation. These
intrinsic functions each correspond to one of the debug records above, with a
few syntactic differences: each argument to a debugger intrinsic must be wrapped
-as metadata, meaning it must be prefixed with ``metadata``, and the
-``DILocation`` argument in each record must be a metadata attachment to the
+as metadata, meaning it must be prefixed with `metadata`, and the
+`DILocation` argument in each record must be a metadata attachment to the
call instruction, meaning it appears after the argument list with the prefix
-``!dbg``.
-
-``llvm.dbg.declare``
-^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- void @llvm.dbg.declare(metadata, metadata, metadata)
-
-This intrinsic is equivalent to ``#dbg_declare``:
-
-.. code-block:: llvm
-
- #dbg_declare(i32* %i.addr, !1, !DIExpression(), !2)
- call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1,
- metadata !DIExpression()), !dbg !2
-
-``llvm.dbg.value``
-^^^^^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- void @llvm.dbg.value(metadata, metadata, metadata)
-
-This intrinsic is equivalent to ``#dbg_value``:
-
-.. code-block:: llvm
-
- #dbg_value(i32 %i, !1, !DIExpression(), !2)
- call void @llvm.dbg.value(metadata i32 %i, metadata !1,
- metadata !DIExpression()), !dbg !2
-
-``llvm.dbg.assign``
-^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: llvm
-
- void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
-
-This intrinsic is equivalent to ``#dbg_assign``:
-
-.. code-block:: llvm
-
- #dbg_assign(i32 %i, !1, !DIExpression(), !2,
- ptr %i.addr, !DIExpression(), !3)
- call void @llvm.dbg.assign(
- metadata i32 %i, metadata !1, metadata !DIExpression(), metadata !2,
- metadata ptr %i.addr, metadata !DIExpression(), metadata !3), !dbg !3
-
-.. _diexpression:
-
-DIExpression
-------------
-
-Debug expressions are represented as :ref:`specialized-metadata`.
+`!dbg`.
+
+#### `llvm.dbg.declare`
+
+```llvm
+void @llvm.dbg.declare(metadata, metadata, metadata)
+```
+This intrinsic is equivalent to `#dbg_declare`:
+
+```llvm
+ #dbg_declare(i32* %i.addr, !1, !DIExpression(), !2)
+call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1,
+ metadata !DIExpression()), !dbg !2
+```
+#### `llvm.dbg.value`
+
+```llvm
+void @llvm.dbg.value(metadata, metadata, metadata)
+```
+This intrinsic is equivalent to `#dbg_value`:
+
+```llvm
+ #dbg_value(i32 %i, !1, !DIExpression(), !2)
+call void @llvm.dbg.value(metadata i32 %i, metadata !1,
+ metadata !DIExpression()), !dbg !2
+```
+#### `llvm.dbg.assign`
+
+```llvm
+void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+```
+This intrinsic is equivalent to `#dbg_assign`:
+
+```llvm
+ #dbg_assign(i32 %i, !1, !DIExpression(), !2,
+ ptr %i.addr, !DIExpression(), !3)
+call void @llvm.dbg.assign(
+ metadata i32 %i, metadata !1, metadata !DIExpression(), metadata !2,
+ metadata ptr %i.addr, metadata !DIExpression(), metadata !3), !dbg !3
+```
+(diexpression)=
+
+### DIExpression
+
+Debug expressions are represented as {ref}`specialized-metadata`.
Debug expressions are interpreted left-to-right: start by pushing the
value/address operand of the record onto a stack, then repeatedly push and
-evaluate opcodes from the ``DIExpression`` until the final variable description
+evaluate opcodes from the `DIExpression` until the final variable description
is produced.
The opcodes available in these expressions are described in
-:ref:`dwarf-opcodes` and :ref:`internal-opcodes`.
+{ref}`dwarf-opcodes` and {ref}`internal-opcodes`.
DWARF specifies three kinds of simple location descriptions: register, memory,
and implicit location descriptions. Note that a location description is
@@ -434,206 +401,200 @@ change over the course of the program. Register and memory location
descriptions describe the *concrete location* of a source variable (in the
sense that a debugger might modify its value), whereas *implicit locations*
describe merely the actual *value* of a source variable which might not exist
-in registers or in memory (see ``DW_OP_stack_value``).
+in registers or in memory (see `DW_OP_stack_value`).
-A ``#dbg_declare`` record describes an indirect value (the address) of a source
+A `#dbg_declare` record describes an indirect value (the address) of a source
variable. The first operand of the record must be an address of some kind. A
-``DIExpression`` operand to the record refines this address to produce a
+`DIExpression` operand to the record refines this address to produce a
concrete location for the source variable.
-A ``#dbg_value`` record describes the direct value of a source variable. The
+A `#dbg_value` record describes the direct value of a source variable. The
first operand of the record may be a direct or indirect value. A
-``DIExpression`` operand to the record refines the first operand to produce a
+`DIExpression` operand to the record refines the first operand to produce a
direct value. For example, if the first operand is an indirect value, it may be
-necessary to insert ``DW_OP_deref`` into the ``DIExpression`` in order to
+necessary to insert `DW_OP_deref` into the `DIExpression` in order to
produce a valid debug record.
-.. note::
-
- A ``DIExpression`` is interpreted in the same way regardless of which kind
- of debug record it's attached to.
-
- ``DIExpression``\s are always printed and parsed inline; they can never be
- referenced by an ID (e.g. ``!1``).
+```{note}
+A `DIExpression` is interpreted in the same way regardless of which kind
+of debug record it's attached to.
-.. _dwarf-opcodes:
+`DIExpression`s are always printed and parsed inline; they can never be
+referenced by an ID (e.g. `!1`).
+```
+(dwarf-opcodes)=
-DWARF Opcodes
-^^^^^^^^^^^^^
+#### DWARF Opcodes
When possible LLVM reuses DWARF opcodes and gives them identical semantics in
LLVM expressions as in DWARF expressions. The current supported opcode
vocabulary is limited, but includes at least:
-- ``DW_OP_deref`` dereferences the top of the expression stack.
-- ``DW_OP_plus`` pops the last two entries from the expression stack, adds
+- `DW_OP_deref` dereferences the top of the expression stack.
+- `DW_OP_plus` pops the last two entries from the expression stack, adds
them together and pushes the result to the expression stack.
-- ``DW_OP_minus`` pops the last two entries from the expression stack, subtracts
+- `DW_OP_minus` pops the last two entries from the expression stack, subtracts
the last entry from the second last entry and appends the result to the
expression stack.
-- ``DW_OP_plus_uconst, 93`` adds ``93`` to the value on top of the stack.
-- ``DW_OP_swap`` swaps top two stack entries.
-- ``DW_OP_xderef`` provides extended dereference mechanism. The entry at the top
+- `DW_OP_plus_uconst, 93` adds `93` to the value on top of the stack.
+- `DW_OP_swap` swaps top two stack entries.
+- `DW_OP_xderef` provides extended dereference mechanism. The entry at the top
of the stack is treated as an address. The second stack entry is treated as an
address space identifier. The two entries are popped and then an
implementation defined value is pushed on the stack.
-- ``DW_OP_stack_value`` may appear at most once in an expression, and must be
- the last opcode if ``DW_OP_LLVM_fragment`` is not present, or the second last
- opcode if ``DW_OP_LLVM_fragment`` is present. It pops the top value of the
+- `DW_OP_stack_value` may appear at most once in an expression, and must be
+ the last opcode if `DW_OP_LLVM_fragment` is not present, or the second last
+ opcode if `DW_OP_LLVM_fragment` is present. It pops the top value of the
expression stack and makes an implicit value location with that value.
-- ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided
+- `DW_OP_breg` (or `DW_OP_bregx`) represents a content on the provided
signed offset of the specified register. The opcode is only generated by the
- ``AsmPrinter`` pass to describe call site parameter value which requires an
+ `AsmPrinter` pass to describe call site parameter value which requires an
expression over two registers.
-- ``DW_OP_push_object_address`` pushes the address of the object which can then
+- `DW_OP_push_object_address` pushes the address of the object which can then
serve as a descriptor in subsequent calculation. This opcode can be used to
calculate bounds of a Fortran allocatable array which has array descriptors.
-- ``DW_OP_over`` duplicates the entry currently second in the stack at the top
+- `DW_OP_over` duplicates the entry currently second in the stack at the top
of the stack. This opcode can be used to calculate bounds of a Fortran
assumed rank array which has rank known at run time and current dimension
number is implicitly first element of the stack.
-.. _internal-opcodes:
+(internal-opcodes)=
-Internal Opcodes
-^^^^^^^^^^^^^^^^
+#### Internal Opcodes
Where the DWARF equivalent is not suitable, or no DWARF equivalent exists, LLVM
defines internal-only opcodes which have no direct analog in DWARF.
-.. note::
-
- Some opcodes do not influence the final DWARF expression directly, instead
- encoding information logically belonging to the debug records which use
- them.
-
-- ``DW_OP_LLVM_fragment, <offset>, <size>`` may appear at most once in an
+```{note}
+Some opcodes do not influence the final DWARF expression directly, instead
+encoding information logically belonging to the debug records which use
+them.
+```
+- `DW_OP_LLVM_fragment, <offset>, <size>` may appear at most once in an
expression, and must be the last opcode. It specifies the bit offset and bit
size of the variable fragment being described by the record or intrinsic
- using the expression. Note that contrary to ``DW_OP_bit_piece``, the offset
+ using the expression. Note that contrary to `DW_OP_bit_piece`, the offset
is describing the location within the described source variable. At DWARF
generation time all fragments for the same variable are collected together
- and DWARF ``DW_OP_piece`` and ``DW_OP_bit_piece`` opcodes are used to
+ and DWARF `DW_OP_piece` and `DW_OP_bit_piece` opcodes are used to
describe a composite with pieces corresponding to the fragments. (This does
not affect the semantics of the expression containing it.)
-- ``DW_OP_LLVM_convert, 16, DW_ATE_signed`` specifies a bit size and encoding
- (``16`` and ``DW_ATE_signed`` here, respectively) to which the top of the
- expression stack is to be converted. Maps into a ``DW_OP_convert`` operation
+- `DW_OP_LLVM_convert, 16, DW_ATE_signed` specifies a bit size and encoding
+ (`16` and `DW_ATE_signed` here, respectively) to which the top of the
+ expression stack is to be converted. Maps into a `DW_OP_convert` operation
that references a base type constructed from the supplied values.
-- ``DW_OP_LLVM_tag_offset, tag_offset`` specifies that a memory tag should be
+- `DW_OP_LLVM_tag_offset, tag_offset` specifies that a memory tag should be
optionally applied to the pointer. The memory tag is derived from the given
tag offset in an implementation-defined manner. (This does not affect the
semantics of the expression containing it.)
-- ``DW_OP_LLVM_entry_value, N`` evaluates a sub-expression as-if it were
+- `DW_OP_LLVM_entry_value, N` evaluates a sub-expression as-if it were
evaluated upon entry to the current call frame.
The sub-expression replaces the operations which comprise it, i.e. all such
operations are evaluated only in the frame entry context.
The sub-expression begins with the operation which immediately precedes
- ``DW_OP_LLVM_entry_value, N`` in the ``DIExpression``. If no such operation
- exists (i.e. the expression begins with ``DW_OP_LLVM_entry_value, N``), the
+ `DW_OP_LLVM_entry_value, N` in the `DIExpression`. If no such operation
+ exists (i.e. the expression begins with `DW_OP_LLVM_entry_value, N`), the
implicit operation which pushes the first debug argument of the containing
- marker/pseudo is used instead. The value ``N`` must always be at least ``1``,
- as this first operation cannot be omitted and is counted in ``N``.
+ marker/pseudo is used instead. The value `N` must always be at least `1`,
+ as this first operation cannot be omitted and is counted in `N`.
- The rest of the sub-expression comprises the ``(N - 1)`` operations following
- ``DW_OP_LLVM_entry_value, N`` in the ``DIExpression``.
+ The rest of the sub-expression comprises the `(N - 1)` operations following
+ `DW_OP_LLVM_entry_value, N` in the `DIExpression`.
Due to framework limitations:
- - ``N`` must not be greater than ``1``. In other words, ``N`` must equal
- ``1``, and the sub-expression comprises only the operation immediately
- preceding ``DW_OP_LLVM_entry_value, N``.
- - ``DW_OP_LLVM_entry_value, N`` must be either the first operation of a
- ``DIExpression`` or the second operation if the expression begins with
- ``DW_OP_LLVM_arg, 0``.
+ - `N` must not be greater than `1`. In other words, `N` must equal
+ `1`, and the sub-expression comprises only the operation immediately
+ preceding `DW_OP_LLVM_entry_value, N`.
+ - `DW_OP_LLVM_entry_value, N` must be either the first operation of a
+ `DIExpression` or the second operation if the expression begins with
+ `DW_OP_LLVM_arg, 0`.
- The first operation must refer to a register value.
- Taken together, these limitations mean that ``DW_OP_LLVM_entry_value`` can
+ Taken together, these limitations mean that `DW_OP_LLVM_entry_value` can
only currently be used to push the value a single register had on entry to
the current stack frame.
- For example, ``!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_entry_value, 1,
- DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)`` specifies an expression
- where the entry value of the first argument to the ``DIExpression`` is added
+ For example, `!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_entry_value, 1,
+ DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)` specifies an expression
+ where the entry value of the first argument to the `DIExpression` is added
to the non-entry value of the second argument, and the result is used as the
value for an implicit value location.
- When targeting DWARF, a ``DBG_VALUE(reg, ...,
- DIExpression(DW_OP_LLVM_entry_value, 1, ...)`` is lowered to
- ``DW_OP_entry_value [reg], ...``, which pushes the value ``reg`` had upon
+ When targeting DWARF, a `DBG_VALUE(reg, ...,
+ DIExpression(DW_OP_LLVM_entry_value, 1, ...)` is lowered to
+ `DW_OP_entry_value [reg], ...`, which pushes the value `reg` had upon
frame entry onto the DWARF expression stack.
- Because ``DW_OP_LLVM_entry_value`` is currently limited to registers, it is
+ Because `DW_OP_LLVM_entry_value` is currently limited to registers, it is
usually used in MIR, but it is also allowed in LLVM IR when targeting a
- :ref:`swiftasync <swiftasync>` argument. The operation is introduced by:
+ {ref}`swiftasync <swiftasync>` argument. The operation is introduced by:
- - ``LiveDebugValues`` pass, which applies it to function parameters that
+ - `LiveDebugValues` pass, which applies it to function parameters that
are unmodified throughout the function. Support is limited to simple
register location descriptions, or as indirect locations (e.g.,
parameters passed-by-value to a callee via a pointer to a temporary copy
made in the caller).
- - ``AsmPrinter`` pass when a call site parameter value
- (``DW_AT_call_site_parameter_value``) is represented as entry value of
+ - `AsmPrinter` pass when a call site parameter value
+ (`DW_AT_call_site_parameter_value`) is represented as entry value of
the parameter.
- - ``CoroSplit`` pass, which may move variables from ``alloca``\s into a
+ - `CoroSplit` pass, which may move variables from `alloca`s into a
coroutine frame. If the coroutine frame is a
- :ref:`swiftasync <swiftasync>` argument, the variable is described with
- an ``DW_OP_LLVM_entry_value`` operation.
+ {ref}`swiftasync <swiftasync>` argument, the variable is described with
+ an `DW_OP_LLVM_entry_value` operation.
-- ``DW_OP_LLVM_implicit_pointer`` It specifies the dereferenced value. It can
+- `DW_OP_LLVM_implicit_pointer` It specifies the dereferenced value. It can
be used to represent pointer variables which are optimized out but the value
it points to is known. This operator is required as it is different than
- DWARF operator ``DW_OP_implicit_pointer`` in representation and specification
+ DWARF operator `DW_OP_implicit_pointer` in representation and specification
(number and types of operands) and later can not be used as multiple level.
- Examples using ``DW_OP_LLVM_implicit_pointer``:
-
- .. code-block:: text
-
- IR for "*ptr = 4;"
- --------------
- #dbg_value(i32 4, !17, !DIExpression(DW_OP_LLVM_implicit_pointer), !20)
- !17 = !DILocalVariable(name: "ptr", scope: !12, file: !3, line: 5,
- type: !18)
- !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
- !19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !20 = !DILocation(line: 10, scope: !12)
-
- IR for "**ptr = 4;"
- --------------
- #dbg_value(i32 4, !17,
- !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer),
- !21)
- !17 = !DILocalVariable(name: "ptr", scope: !12, file: !3, line: 5,
- type: !18)
- !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
- !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
- !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !21 = !DILocation(line: 10, scope: !12)
-
-- ``DW_OP_LLVM_arg, N`` is used in debug intrinsics that refer to more than one
+ Examples using `DW_OP_LLVM_implicit_pointer`:
+
+ ```text
+ IR for "*ptr = 4;"
+ --------------
+ #dbg_value(i32 4, !17, !DIExpression(DW_OP_LLVM_implicit_pointer), !20)
+ !17 = !DILocalVariable(name: "ptr", scope: !12, file: !3, line: 5,
+ type: !18)
+ !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+ !19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !20 = !DILocation(line: 10, scope: !12)
+
+ IR for "**ptr = 4;"
+ --------------
+ #dbg_value(i32 4, !17,
+ !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_implicit_pointer),
+ !21)
+ !17 = !DILocalVariable(name: "ptr", scope: !12, file: !3, line: 5,
+ type: !18)
+ !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+ !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64)
+ !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !21 = !DILocation(line: 10, scope: !12)
+ ```
+- `DW_OP_LLVM_arg, N` is used in debug intrinsics that refer to more than one
value, such as one that calculates the sum of two registers. This is always
used in combination with an ordered list of values, such that
- ``DW_OP_LLVM_arg, N`` refers to the ``N``\ :sup:`th` element in that list.
- For example, ``!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1,
- DW_OP_minus, DW_OP_stack_value)`` used with the list ``(%reg1, %reg2)`` would
+ `DW_OP_LLVM_arg, N` refers to the `N` {sup}`th` element in that list.
+ For example, `!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1,
+ DW_OP_minus, DW_OP_stack_value)` used with the list `(%reg1, %reg2)` would
evaluate to an implicit value location that has the value of
- ``%reg1 - reg2``. This list of values should be provided by the containing
+ `%reg1 - reg2`. This list of values should be provided by the containing
intrinsic/instruction.
-- ``DW_OP_LLVM_extract_bits_sext, 16, 8,`` specifies the offset and size
- (``16`` and ``8`` here, respectively) of bits that are to be extracted and
+- `DW_OP_LLVM_extract_bits_sext, 16, 8,` specifies the offset and size
+ (`16` and `8` here, respectively) of bits that are to be extracted and
sign-extended from the value at the top of the expression stack. If the top of
the expression stack is a memory location then these bits are extracted from
- the value pointed to by that memory location. Maps into a ``DW_OP_shl``
- followed by ``DW_OP_shra``.
-- ``DW_OP_LLVM_extract_bits_zext`` behaves similarly to
- ``DW_OP_LLVM_extract_bits_sext``, but zero-extends instead of sign-extending.
- Maps into a ``DW_OP_shl`` followed by ``DW_OP_shr``.
+ the value pointed to by that memory location. Maps into a `DW_OP_shl`
+ followed by `DW_OP_shra`.
+- `DW_OP_LLVM_extract_bits_zext` behaves similarly to
+ `DW_OP_LLVM_extract_bits_sext`, but zero-extends instead of sign-extending.
+ Maps into a `DW_OP_shl` followed by `DW_OP_shr`.
-Object lifetimes and scoping
-============================
+## Object lifetimes and scoping
In many languages, the local variables in functions can have their lifetimes or
scopes limited to a subset of a function. In the C family of languages, for
@@ -647,157 +608,149 @@ In order to handle this, the LLVM debug format uses the metadata attached to
LLVM instructions to encode line number and scoping information. Consider the
following C fragment, for example:
-.. code-block:: c
-
- 1. void foo() {
- 2. int X = 21;
- 3. int Y = 22;
- 4. {
- 5. int Z = 23;
- 6. Z = X;
- 7. }
- 8. X = Y;
- 9. }
-
+```c
+1. void foo() {
+2. int X = 21;
+3. int Y = 22;
+4. {
+5. int Z = 23;
+6. Z = X;
+7. }
+8. X = Y;
+9. }
+```
Compiled to LLVM, this function would be represented like this:
-.. code-block:: text
-
- ; Function Attrs: nounwind ssp uwtable
- define void @foo() #0 !dbg !4 {
- entry:
- %X = alloca i32, align 4
- %Y = alloca i32, align 4
- %Z = alloca i32, align 4
- #dbg_declare(ptr %X, !11, !DIExpression(), !13)
- store i32 21, i32* %X, align 4, !dbg !13
- #dbg_declare(ptr %Y, !14, !DIExpression(), !15)
- store i32 22, i32* %Y, align 4, !dbg !15
- #dbg_declare(ptr %Z, !16, !DIExpression(), !18)
- store i32 23, i32* %Z, align 4, !dbg !18
- %0 = load i32, i32* %X, align 4, !dbg !20
- store i32 %0, i32* %Z, align 4, !dbg !21
- %1 = load i32, i32* %Y, align 4, !dbg !22
- store i32 %1, i32* %X, align 4, !dbg !23
- ret void, !dbg !24
- }
-
- attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "use-soft-float"="false" }
- attributes #1 = { nounwind readnone }
-
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!7, !8, !9}
- !llvm.ident = !{!10}
-
- !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
- !1 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
- !2 = !{}
- !3 = !{!4}
- !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, retainedNodes: !2)
- !5 = !DISubroutineType(types: !6)
- !6 = !{null}
- !7 = !{i32 2, !"Dwarf Version", i32 2}
- !8 = !{i32 2, !"Debug Info Version", i32 3}
- !9 = !{i32 1, !"PIC Level", i32 2}
- !10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
- !11 = !DILocalVariable(name: "X", scope: !4, file: !1, line: 2, type: !12)
- !12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
- !13 = !DILocation(line: 2, column: 9, scope: !4)
- !14 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12)
- !15 = !DILocation(line: 3, column: 9, scope: !4)
- !16 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12)
- !17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
- !18 = !DILocation(line: 5, column: 11, scope: !17)
- !29 = !DILocation(line: 6, column: 11, scope: !17)
- !20 = !DILocation(line: 6, column: 9, scope: !17)
- !21 = !DILocation(line: 8, column: 9, scope: !4)
- !22 = !DILocation(line: 8, column: 7, scope: !4)
- !23 = !DILocation(line: 9, column: 3, scope: !4)
-
-
+```text
+; Function Attrs: nounwind ssp uwtable
+define void @foo() #0 !dbg !4 {
+entry:
+ %X = alloca i32, align 4
+ %Y = alloca i32, align 4
+ %Z = alloca i32, align 4
+ #dbg_declare(ptr %X, !11, !DIExpression(), !13)
+ store i32 21, i32* %X, align 4, !dbg !13
+ #dbg_declare(ptr %Y, !14, !DIExpression(), !15)
+ store i32 22, i32* %Y, align 4, !dbg !15
+ #dbg_declare(ptr %Z, !16, !DIExpression(), !18)
+ store i32 23, i32* %Z, align 4, !dbg !18
+ %0 = load i32, i32* %X, align 4, !dbg !20
+ store i32 %0, i32* %Z, align 4, !dbg !21
+ %1 = load i32, i32* %Y, align 4, !dbg !22
+ store i32 %1, i32* %X, align 4, !dbg !23
+ ret void, !dbg !24
+}
+
+attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!1 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, retainedNodes: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = !{i32 2, !"Dwarf Version", i32 2}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"PIC Level", i32 2}
+!10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
+!11 = !DILocalVariable(name: "X", scope: !4, file: !1, line: 2, type: !12)
+!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!13 = !DILocation(line: 2, column: 9, scope: !4)
+!14 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12)
+!15 = !DILocation(line: 3, column: 9, scope: !4)
+!16 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12)
+!17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
+!18 = !DILocation(line: 5, column: 11, scope: !17)
+!29 = !DILocation(line: 6, column: 11, scope: !17)
+!20 = !DILocation(line: 6, column: 9, scope: !17)
+!21 = !DILocation(line: 8, column: 9, scope: !4)
+!22 = !DILocation(line: 8, column: 7, scope: !4)
+!23 = !DILocation(line: 9, column: 3, scope: !4)
+
+```
This example illustrates a few important details about LLVM debugging
-information. In particular, it shows how the ``#dbg_declare`` record and
+information. In particular, it shows how the `#dbg_declare` record and
location information, which are attached to an instruction, are applied
together to allow a debugger to analyze the relationship between statements,
variable definitions, and the code used to implement the function.
-.. code-block:: llvm
-
- #dbg_declare(ptr %X, !11, !DIExpression(), !13)
- ; [debug line = 2:9] [debug variable = X]
-
-The first record ``#dbg_declare`` encodes debugging information for the
-variable ``X``. The location ``!13`` at the end of the record provides
-scope information for the variable ``X``.
-
-.. code-block:: text
-
- !13 = !DILocation(line: 2, column: 9, scope: !4)
- !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
- isLocal: false, isDefinition: true, scopeLine: 1,
- isOptimized: false, retainedNodes: !2)
-
-Here ``!13`` is metadata providing :ref:`location information <dilocation>`.
-In this example, scope is encoded by ``!4``, a :ref:`subprogram descriptor
+```llvm
+#dbg_declare(ptr %X, !11, !DIExpression(), !13)
+; [debug line = 2:9] [debug variable = X]
+```
+The first record `#dbg_declare` encodes debugging information for the
+variable `X`. The location `!13` at the end of the record provides
+scope information for the variable `X`.
+
+```text
+!13 = !DILocation(line: 2, column: 9, scope: !4)
+!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
+ isLocal: false, isDefinition: true, scopeLine: 1,
+ isOptimized: false, retainedNodes: !2)
+```
+Here `!13` is metadata providing {ref}`location information <dilocation>`.
+In this example, scope is encoded by `!4`, a {ref}`subprogram descriptor
<disubprogram>`. This way the location information parameter to the records
-indicates that the variable ``X`` is declared at line number 2 at a function
-level scope in function ``foo``.
+indicates that the variable `X` is declared at line number 2 at a function
+level scope in function `foo`.
Now, let's take another example.
-.. code-block:: llvm
-
- #dbg_declare(ptr %Z, !16, !DIExpression(), !18)
- ; [debug line = 5:11] [debug variable = Z]
-
-The third record ``#dbg_declare`` encodes debugging information for
-variable ``Z``. The metadata ``!18`` at the end of the record provides
-scope information for the variable ``Z``.
-
-.. code-block:: text
-
- !17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
- !18 = !DILocation(line: 5, column: 11, scope: !17)
-
-Here ``!18`` indicates that ``Z`` is declared at line number 5 and column
-number 11 inside of lexical scope ``!17``. The lexical scope itself resides
-inside of subprogram ``!4`` described above.
+```llvm
+#dbg_declare(ptr %Z, !16, !DIExpression(), !18)
+; [debug line = 5:11] [debug variable = Z]
+```
+The third record `#dbg_declare` encodes debugging information for
+variable `Z`. The metadata `!18` at the end of the record provides
+scope information for the variable `Z`.
+
+```text
+!17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
+!18 = !DILocation(line: 5, column: 11, scope: !17)
+```
+Here `!18` indicates that `Z` is declared at line number 5 and column
+number 11 inside of lexical scope `!17`. The lexical scope itself resides
+inside of subprogram `!4` described above.
The scope information attached to each instruction provides a straightforward
way to find instructions covered by a scope.
-Object lifetime in optimized code
-=================================
+## Object lifetime in optimized code
In the example above, every variable assignment uniquely corresponds to a
memory store to the variable's position on the stack. However, in heavily
optimized code LLVM promotes most variables into SSA values, which can
eventually be placed in physical registers or memory locations. To track SSA
values through compilation, when objects are promoted to SSA values a
-``#dbg_value`` record is created for each assignment, recording the
-variable's new location. Compared with the ``#dbg_declare`` record:
+`#dbg_value` record is created for each assignment, recording the
+variable's new location. Compared with the `#dbg_declare` record:
-* A ``#dbg_value`` terminates the effects that any preceding records have on
+* A `#dbg_value` terminates the effects that any preceding records have on
any common bits of a common variable.
- .. note::
-
- The current implementation generally terminates the effect of every
- record in its entirety if any of its effects would be terminated, rather
- than carrying forward the effect of previous records for non-overlapping
- bits as it would be permitted to do by this definition. This is allowed
- just as dropping any debug information at any point in the compilation is
- allowed.
-
- One exception to this is :doc:`AssignmentTracking` where certain
- memory-based locations are carried forward partially in some situations.
-
-* The ``#dbg_value``'s position in the IR defines where in the instruction
+ ```{note}
+ The current implementation generally terminates the effect of every
+ record in its entirety if any of its effects would be terminated, rather
+ than carrying forward the effect of previous records for non-overlapping
+ bits as it would be permitted to do by this definition. This is allowed
+ just as dropping any debug information at any point in the compilation is
+ allowed.
+
+ One exception to this is {doc}`AssignmentTracking` where certain
+ memory-based locations are carried forward partially in some situations.
+ ```
+* The `#dbg_value`'s position in the IR defines where in the instruction
stream the variable's value changes.
* Operands can be constants, indicating the variable is assigned a
constant value.
-Care must be taken to update ``#dbg_value`` records when optimization
+Care must be taken to update `#dbg_value` records when optimization
passes alter or move instructions and blocks -- the developer could observe such
changes reflected in the value of variables when debugging the program. For any
execution of the optimized program, the set of variable values presented to the
@@ -808,128 +761,123 @@ damaging their understanding of the optimized program and undermining their
trust in the debugger.
Sometimes perfectly preserving variable locations is not possible, often when a
-redundant calculation is optimized out. In such cases, a ``#dbg_value``
-with operand ``poison`` should be used, to terminate earlier variable locations
-and let the debugger present ``optimized out`` to the developer. Withholding
+redundant calculation is optimized out. In such cases, a `#dbg_value`
+with operand `poison` should be used, to terminate earlier variable locations
+and let the debugger present `optimized out` to the developer. Withholding
these potentially stale variable values from the developer diminishes the
amount of available debug information, but increases the reliability of the
remaining information.
To illustrate some potential issues, consider the following example:
-.. code-block:: llvm
-
- define i32 @foo(i32 %bar, i1 %cond) {
- entry:
- #dbg_value(i32 0, !1, !DIExpression(), !4)
- br i1 %cond, label %truebr, label %falsebr
- truebr:
- %tval = add i32 %bar, 1
- #dbg_value(i32 %tval, !1, !DIExpression(), !4)
- %g1 = call i32 @gazonk()
- br label %exit
- falsebr:
- %fval = add i32 %bar, 2
- #dbg_value(i32 %fval, !1, !DIExpression(), !4)
- %g2 = call i32 @gazonk()
- br label %exit
- exit:
- %merge = phi [ %tval, %truebr ], [ %fval, %falsebr ]
- %g = phi [ %g1, %truebr ], [ %g2, %falsebr ]
- #dbg_value(i32 %merge, !1, !DIExpression(), !4)
- #dbg_value(i32 %g, !3, !DIExpression(), !4)
- %plusten = add i32 %merge, 10
- %toret = add i32 %plusten, %g
- #dbg_value(i32 %toret, !1, !DIExpression(), !4)
- ret i32 %toret
- }
-
-Containing two source-level variables in ``!1`` and ``!3``. The function could,
+```llvm
+define i32 @foo(i32 %bar, i1 %cond) {
+entry:
+ #dbg_value(i32 0, !1, !DIExpression(), !4)
+ br i1 %cond, label %truebr, label %falsebr
+truebr:
+ %tval = add i32 %bar, 1
+ #dbg_value(i32 %tval, !1, !DIExpression(), !4)
+ %g1 = call i32 @gazonk()
+ br label %exit
+falsebr:
+ %fval = add i32 %bar, 2
+ #dbg_value(i32 %fval, !1, !DIExpression(), !4)
+ %g2 = call i32 @gazonk()
+ br label %exit
+exit:
+ %merge = phi [ %tval, %truebr ], [ %fval, %falsebr ]
+ %g = phi [ %g1, %truebr ], [ %g2, %falsebr ]
+ #dbg_value(i32 %merge, !1, !DIExpression(), !4)
+ #dbg_value(i32 %g, !3, !DIExpression(), !4)
+ %plusten = add i32 %merge, 10
+ %toret = add i32 %plusten, %g
+ #dbg_value(i32 %toret, !1, !DIExpression(), !4)
+ ret i32 %toret
+}
+```
+Containing two source-level variables in `!1` and `!3`. The function could,
perhaps, be optimized into the following code:
-.. code-block:: llvm
-
- define i32 @foo(i32 %bar, i1 %cond) {
- entry:
- %g = call i32 @gazonk()
- %addoper = select i1 %cond, i32 11, i32 12
- %plusten = add i32 %bar, %addoper
- %toret = add i32 %plusten, %g
- ret i32 %toret
- }
-
-What ``#dbg_value`` records should be placed to represent the original variable
+```llvm
+define i32 @foo(i32 %bar, i1 %cond) {
+entry:
+ %g = call i32 @gazonk()
+ %addoper = select i1 %cond, i32 11, i32 12
+ %plusten = add i32 %bar, %addoper
+ %toret = add i32 %plusten, %g
+ ret i32 %toret
+}
+```
+What `#dbg_value` records should be placed to represent the original variable
locations in this code? Unfortunately the second, third, and fourth
-``#dbg_value``\s for ``!1`` in the source function have had their operands
-(``%tval``, ``%fval``, ``%merge``) optimized out. Assuming we cannot recover
-them, we might consider this placement of ``#dbg_value``\s:
-
-.. code-block:: llvm
-
- define i32 @foo(i32 %bar, i1 %cond) {
- entry:
- #dbg_value(i32 0, !1, !DIExpression(), !4)
- %g = call i32 @gazonk()
- #dbg_value(i32 %g, !3, !DIExpression(), !4)
- %addoper = select i1 %cond, i32 11, i32 12
- %plusten = add i32 %bar, %addoper
- %toret = add i32 %plusten, %g
- #dbg_value(i32 %toret, !1, !DIExpression(), !4)
- ret i32 %toret
- }
-
-However, this will cause ``!3`` to have the return value of ``@gazonk()`` at
-the same time as ``!1`` has the constant value zero -- a pair of assignments
+`#dbg_value`s for `!1` in the source function have had their operands
+(`%tval`, `%fval`, `%merge`) optimized out. Assuming we cannot recover
+them, we might consider this placement of `#dbg_value`s:
+
+```llvm
+define i32 @foo(i32 %bar, i1 %cond) {
+entry:
+ #dbg_value(i32 0, !1, !DIExpression(), !4)
+ %g = call i32 @gazonk()
+ #dbg_value(i32 %g, !3, !DIExpression(), !4)
+ %addoper = select i1 %cond, i32 11, i32 12
+ %plusten = add i32 %bar, %addoper
+ %toret = add i32 %plusten, %g
+ #dbg_value(i32 %toret, !1, !DIExpression(), !4)
+ ret i32 %toret
+}
+```
+However, this will cause `!3` to have the return value of `@gazonk()` at
+the same time as `!1` has the constant value zero -- a pair of assignments
that never occurred in the unoptimized program. To avoid this, we must terminate
-the range that ``!1`` has the constant value assignment by inserting an poison
-``#dbg_value`` before the ``#dbg_value`` for ``!3``:
-
-.. code-block:: llvm
-
- define i32 @foo(i32 %bar, i1 %cond) {
- entry:
- #dbg_value(i32 0, !1, !DIExpression(), !2)
- %g = call i32 @gazonk()
- #dbg_value(i32 poison, !1, !DIExpression(), !2)
- #dbg_value(i32 %g, !3, !DIExpression(), !2)
- %addoper = select i1 %cond, i32 11, i32 12
- %plusten = add i32 %bar, %addoper
- %toret = add i32 %plusten, %g
- #dbg_value(i32 %toret, !1, !DIExpression(), !2)
- ret i32 %toret
- }
-
-There are a few other ``#dbg_value`` configurations that mean it terminates
+the range that `!1` has the constant value assignment by inserting an poison
+`#dbg_value` before the `#dbg_value` for `!3`:
+
+```llvm
+define i32 @foo(i32 %bar, i1 %cond) {
+entry:
+ #dbg_value(i32 0, !1, !DIExpression(), !2)
+ %g = call i32 @gazonk()
+ #dbg_value(i32 poison, !1, !DIExpression(), !2)
+ #dbg_value(i32 %g, !3, !DIExpression(), !2)
+ %addoper = select i1 %cond, i32 11, i32 12
+ %plusten = add i32 %bar, %addoper
+ %toret = add i32 %plusten, %g
+ #dbg_value(i32 %toret, !1, !DIExpression(), !2)
+ ret i32 %toret
+}
+```
+There are a few other `#dbg_value` configurations that mean it terminates
dominating location definitions without adding a new location. The complete
list is:
-* Any location operand is ``poison`` (or ``undef``).
-* Any location operand is an empty metadata tuple (``!{}``) (which cannot
- occur in a ``!DIArgList``).
-* There are no location operands (empty ``DIArgList``) and the ``DIExpression``
+* Any location operand is `poison` (or `undef`).
+* Any location operand is an empty metadata tuple (`!{}`) (which cannot
+ occur in a `!DIArgList`).
+* There are no location operands (empty `DIArgList`) and the `DIExpression`
is empty.
-This class of ``#dbg_value`` that kills variable locations is called a "kill
-``#dbg_value``" or "kill location", and for legacy reasons the term "``undef
-#dbg_value``" may be used in existing code. The ``DbgVariableIntrinsic``
-methods ``isKillLocation`` and ``setKillLocation`` should be used where
+This class of `#dbg_value` that kills variable locations is called a "kill
+`#dbg_value`" or "kill location", and for legacy reasons the term "`undef
+#dbg_value`" may be used in existing code. The `DbgVariableIntrinsic`
+methods `isKillLocation` and `setKillLocation` should be used where
possible rather than inspecting location operands directly to check or set
-whether a ``#dbg_value`` is a kill location.
+whether a `#dbg_value` is a kill location.
-In general, if any ``#dbg_value`` has its operand optimized out and cannot be
-recovered, then a kill ``#dbg_value`` is necessary to terminate earlier
-variable locations. Additional kill ``#dbg_values`` may be necessary when the
+In general, if any `#dbg_value` has its operand optimized out and cannot be
+recovered, then a kill `#dbg_value` is necessary to terminate earlier
+variable locations. Additional kill `#dbg_values` may be necessary when the
debugger can observe re-ordering of assignments.
-How variable location metadata is transformed during CodeGen
-============================================================
+## How variable location metadata is transformed during CodeGen
LLVM preserves debug information throughout mid-level and backend passes,
ultimately producing a mapping between source-level information and
instruction ranges. This
is relatively straightforward for line number information, as mapping
instructions to line numbers is a simple association. For variable locations
-however the story is more complex. As each ``#dbg_value`` record
+however the story is more complex. As each `#dbg_value` record
represents a source-level assignment of a value to a source variable, the
debug records effectively embed a small imperative program
within the LLVM IR. By the end of CodeGen, this becomes a mapping from each
@@ -946,19 +894,18 @@ significantly change the ordering of the program, and occurs in a number of
different passes.
Some variable locations are not transformed during CodeGen. Stack locations
-specified by ``#dbg_declare`` are valid and unchanging for the entire duration
-of the function, and are recorded in a simple ``MachineFunction`` table.
+specified by `#dbg_declare` are valid and unchanging for the entire duration
+of the function, and are recorded in a simple `MachineFunction` table.
Location changes in the prologue and epilogue of a function are also ignored:
frame setup and destruction may take several instructions, require a
disproportionate amount of debugging information in the output binary to
describe, and should be stepped over by debuggers anyway.
-Variable locations in Instruction Selection and MIR
----------------------------------------------------
+### Variable locations in Instruction Selection and MIR
Instruction selection creates a MIR function from an IR function, and just as
-it transforms ``intermediate`` instructions into machine instructions, so must
-``intermediate`` variable locations become machine variable locations. Within
+it transforms `intermediate` instructions into machine instructions, so must
+`intermediate` variable locations become machine variable locations. Within
IR, variable locations are always identified by a Value, but in MIR there can
be different types of variable locations. In addition, some IR locations become
unavailable, for example if the operation of multiple IR instructions are
@@ -966,58 +913,56 @@ combined into one machine instruction (such as multiply-and-accumulate) then
intermediate Values are lost. To track variable locations through instruction
selection, they are first separated into locations that do not depend on code
generation (constants, stack locations, allocated virtual registers) and those
-that do. For those that do, debug metadata is attached to ``SDNode``\s in
-``SelectionDAG``\s. After instruction selection has occurred and a MIR function
-is created, if the ``SDNode`` associated with debug metadata is allocated a
+that do. For those that do, debug metadata is attached to `SDNode`s in
+`SelectionDAG`s. After instruction selection has occurred and a MIR function
+is created, if the `SDNode` associated with debug metadata is allocated a
virtual register, that virtual register is used as the variable location. If
-the ``SDNode`` is folded into a machine instruction or otherwise transformed
+the `SDNode` is folded into a machine instruction or otherwise transformed
into a non-register, the variable location becomes unavailable.
Locations that are unavailable are treated as if they have been optimized out:
-in IR the location would be assigned ``undef`` by a debug record, and in MIR
+in IR the location would be assigned `undef` by a debug record, and in MIR
the equivalent location is used.
After MIR locations are assigned to each variable, machine pseudo-instructions
-corresponding to each ``#dbg_value`` record are inserted. There are two
+corresponding to each `#dbg_value` record are inserted. There are two
forms of this type of instruction.
-The first form, ``DBG_VALUE``, appears thus:
-
-.. code-block:: text
-
- DBG_VALUE %1, $noreg, !123, !DIExpression()
+The first form, `DBG_VALUE`, appears thus:
+```text
+DBG_VALUE %1, $noreg, !123, !DIExpression()
+```
And has the following operands:
* The first operand can record the variable location as a register,
a frame index, an immediate, or the base address register if the original
- debug record referred to memory. ``$noreg`` indicates the variable
- location is undefined, equivalent to an ``undef #dbg_value`` operand.
+ debug record referred to memory. `$noreg` indicates the variable
+ location is undefined, equivalent to an `undef #dbg_value` operand.
* The type of the second operand indicates whether the variable location is
- directly referred to by the ``DBG_VALUE``, or whether it is indirect. The
- ``$noreg`` register signifies the former, an immediate operand (0) the
+ directly referred to by the `DBG_VALUE`, or whether it is indirect. The
+ `$noreg` register signifies the former, an immediate operand (0) the
latter.
* Operand 3 is the Variable field of the original debug record.
* Operand 4 is the Expression field of the original debug record.
-The second form, ``DBG_VALUE_LIST``, appears thus:
-
-.. code-block:: text
-
- DBG_VALUE_LIST !123, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %1, %2
+The second form, `DBG_VALUE_LIST`, appears thus:
+```text
+DBG_VALUE_LIST !123, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %1, %2
+```
And has the following operands:
* The first operand is the Variable field of the original debug record.
* The second operand is the Expression field of the original debug record.
* Any number of operands, from the 3rd onwards, record a sequence of variable
location operands, which may take any of the same values as the first
- operand of the ``DBG_VALUE`` instruction above. These variable location
+ operand of the `DBG_VALUE` instruction above. These variable location
operands are inserted into the final DWARF Expression in positions indicated
- by the ``DW_OP_LLVM_arg`` operator in the :ref:`diexpression`.
+ by the `DW_OP_LLVM_arg` operator in the {ref}`diexpression`.
-The position at which the ``DBG_VALUE``\s are inserted should correspond to the
-positions of their matching ``#dbg_value`` records in the IR block. As with
+The position at which the `DBG_VALUE`s are inserted should correspond to the
+positions of their matching `#dbg_value` records in the IR block. As with
optimization, LLVM aims to preserve the order in which variable assignments
-occurred in the source program. However, ``SelectionDAG`` performs some
+occurred in the source program. However, `SelectionDAG` performs some
instruction scheduling, which can reorder assignments (discussed below).
Function parameter locations are moved to the beginning of the function if
they're not already, to ensure they're immediately available on function entry.
@@ -1025,82 +970,79 @@ they're not already, to ensure they're immediately available on function entry.
To demonstrate variable locations during instruction selection, consider
the following example:
-.. code-block:: llvm
-
- define i32 @foo(i32* %addr) {
- entry:
- #dbg_value(i32 0, !3, !DIExpression(), !5)
- br label %bb1, !dbg !5
-
- bb1: ; preds = %bb1, %entry
- %bar.0 = phi i32 [ 0, %entry ], [ %add, %bb1 ]
- #dbg_value(i32 %bar.0, !3, !DIExpression(), !5)
- %addr1 = getelementptr i32, i32 *%addr, i32 1, !dbg !5
- #dbg_value(i32 *%addr1, !3, !DIExpression(), !5)
- %loaded1 = load i32, i32* %addr1, !dbg !5
- %addr2 = getelementptr i32, i32 *%addr, i32 %bar.0, !dbg !5
- #dbg_value(i32 *%addr2, !3, !DIExpression(), !5)
- %loaded2 = load i32, i32* %addr2, !dbg !5
- %add = add i32 %bar.0, 1, !dbg !5
- #dbg_value(i32 %add, !3, !DIExpression(), !5)
- %added = add i32 %loaded1, %loaded2
- %cond = icmp ult i32 %added, %bar.0, !dbg !5
- br i1 %cond, label %bb1, label %bb2, !dbg !5
-
- bb2: ; preds = %bb1
- ret i32 0, !dbg !5
- }
-
-If one compiles this IR with ``llc -o - -start-after=codegen-prepare -stop-after=expand-isel-pseudos -mtriple=x86_64--``, the following MIR is produced:
-
-.. code-block:: text
-
- bb.0.entry:
- successors: %bb.1(0x80000000)
- liveins: $rdi
-
- %2:gr64 = COPY $rdi
- %3:gr32 = MOV32r0 implicit-def dead $eflags
- DBG_VALUE 0, $noreg, !3, !DIExpression(), debug-location !5
-
- bb.1.bb1:
- successors: %bb.1(0x7c000000), %bb.2(0x04000000)
-
- %0:gr32 = PHI %3, %bb.0, %1, %bb.1
- DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
- DBG_VALUE %2, $noreg, !3, !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value), debug-location !5
- %4:gr32 = MOV32rm %2, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
- %5:gr64_nosp = MOVSX64rr32 %0, debug-location !5
- DBG_VALUE $noreg, $noreg, !3, !DIExpression(), debug-location !5
- %1:gr32 = INC32r %0, implicit-def dead $eflags, debug-location !5
- DBG_VALUE %1, $noreg, !3, !DIExpression(), debug-location !5
- %6:gr32 = ADD32rm %4, %2, 4, killed %5, 0, $noreg, implicit-def dead $eflags :: (load 4 from %ir.addr2)
- %7:gr32 = SUB32rr %6, %0, implicit-def $eflags, debug-location !5
- JB_1 %bb.1, implicit $eflags, debug-location !5
- JMP_1 %bb.2, debug-location !5
-
- bb.2.bb2:
- %8:gr32 = MOV32r0 implicit-def dead $eflags
- $eax = COPY %8, debug-location !5
- RET 0, $eax, debug-location !5
-
-Observe first that there is a ``DBG_VALUE`` instruction for every ``#dbg_value``
+```llvm
+define i32 @foo(i32* %addr) {
+entry:
+ #dbg_value(i32 0, !3, !DIExpression(), !5)
+ br label %bb1, !dbg !5
+
+bb1: ; preds = %bb1, %entry
+ %bar.0 = phi i32 [ 0, %entry ], [ %add, %bb1 ]
+ #dbg_value(i32 %bar.0, !3, !DIExpression(), !5)
+ %addr1 = getelementptr i32, i32 *%addr, i32 1, !dbg !5
+ #dbg_value(i32 *%addr1, !3, !DIExpression(), !5)
+ %loaded1 = load i32, i32* %addr1, !dbg !5
+ %addr2 = getelementptr i32, i32 *%addr, i32 %bar.0, !dbg !5
+ #dbg_value(i32 *%addr2, !3, !DIExpression(), !5)
+ %loaded2 = load i32, i32* %addr2, !dbg !5
+ %add = add i32 %bar.0, 1, !dbg !5
+ #dbg_value(i32 %add, !3, !DIExpression(), !5)
+ %added = add i32 %loaded1, %loaded2
+ %cond = icmp ult i32 %added, %bar.0, !dbg !5
+ br i1 %cond, label %bb1, label %bb2, !dbg !5
+
+bb2: ; preds = %bb1
+ ret i32 0, !dbg !5
+}
+```
+If one compiles this IR with `llc -o - -start-after=codegen-prepare -stop-after=expand-isel-pseudos -mtriple=x86_64--`, the following MIR is produced:
+
+```text
+bb.0.entry:
+ successors: %bb.1(0x80000000)
+ liveins: $rdi
+
+ %2:gr64 = COPY $rdi
+ %3:gr32 = MOV32r0 implicit-def dead $eflags
+ DBG_VALUE 0, $noreg, !3, !DIExpression(), debug-location !5
+
+bb.1.bb1:
+ successors: %bb.1(0x7c000000), %bb.2(0x04000000)
+
+ %0:gr32 = PHI %3, %bb.0, %1, %bb.1
+ DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
+ DBG_VALUE %2, $noreg, !3, !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value), debug-location !5
+ %4:gr32 = MOV32rm %2, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
+ %5:gr64_nosp = MOVSX64rr32 %0, debug-location !5
+ DBG_VALUE $noreg, $noreg, !3, !DIExpression(), debug-location !5
+ %1:gr32 = INC32r %0, implicit-def dead $eflags, debug-location !5
+ DBG_VALUE %1, $noreg, !3, !DIExpression(), debug-location !5
+ %6:gr32 = ADD32rm %4, %2, 4, killed %5, 0, $noreg, implicit-def dead $eflags :: (load 4 from %ir.addr2)
+ %7:gr32 = SUB32rr %6, %0, implicit-def $eflags, debug-location !5
+ JB_1 %bb.1, implicit $eflags, debug-location !5
+ JMP_1 %bb.2, debug-location !5
+
+bb.2.bb2:
+ %8:gr32 = MOV32r0 implicit-def dead $eflags
+ $eax = COPY %8, debug-location !5
+ RET 0, $eax, debug-location !5
+```
+Observe first that there is a `DBG_VALUE` instruction for every `#dbg_value`
record in the source IR, ensuring no source level assignments go missing.
Then consider the different ways in which variable locations have been recorded:
-* For the first ``#dbg_value`` an immediate operand is used to record a zero value.
-* The ``#dbg_value`` of the PHI instruction leads to a ``DBG_VALUE`` of virtual register
- ``%0``.
+* For the first `#dbg_value` an immediate operand is used to record a zero value.
+* The `#dbg_value` of the PHI instruction leads to a `DBG_VALUE` of virtual register
+ `%0`.
* The first GEP has its effect folded into the first load instruction
(as a 4-byte offset), but the variable location is salvaged by folding
- the GEPs effect into the ``DIExpression``.
+ the GEPs effect into the `DIExpression`.
* The second GEP is also folded into the corresponding load. However, it is
- insufficiently simple to be salvaged, and is emitted as a ``$noreg``
- ``DBG_VALUE``, indicating that the variable takes on an undefined location.
-* The final ``#dbg_value`` has its Value placed in virtual register ``%1``.
+ insufficiently simple to be salvaged, and is emitted as a `$noreg`
+ `DBG_VALUE`, indicating that the variable takes on an undefined location.
+* The final `#dbg_value` has its Value placed in virtual register `%1`.
-Instruction Scheduling
-----------------------
+### Instruction Scheduling
A number of passes can reschedule instructions, notably instruction selection
and the pre-and-post RA machine schedulers. Instruction scheduling can
@@ -1109,83 +1051,78 @@ case the instruction sequence could be completely reversed. In such
circumstances LLVM follows the principle applied to optimizations, that it is
better for the debugger not to display any state than a misleading state.
Thus, whenever instructions are advanced in order of execution, any
-corresponding ``DBG_VALUE`` is kept in its original position, and if an instruction
+corresponding `DBG_VALUE` is kept in its original position, and if an instruction
is delayed then the variable is given an undefined location for the duration
of the delay. To illustrate, consider this pseudo-MIR:
-.. code-block:: text
-
- %1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
- DBG_VALUE %1, $noreg, !1, !2
- %4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
- DBG_VALUE %4, $noreg, !3, !4
- %7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
- DBG_VALUE %7, $noreg, !5, !6
-
-Imagine that the ``SUB32rr`` were moved forward to give us the following MIR:
-
-.. code-block:: text
-
- %7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
- %1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
- DBG_VALUE %1, $noreg, !1, !2
- %4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
- DBG_VALUE %4, $noreg, !3, !4
- DBG_VALUE %7, $noreg, !5, !6
-
+```text
+%1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
+DBG_VALUE %1, $noreg, !1, !2
+%4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
+DBG_VALUE %4, $noreg, !3, !4
+%7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
+DBG_VALUE %7, $noreg, !5, !6
+```
+Imagine that the `SUB32rr` were moved forward to give us the following MIR:
+
+```text
+%7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
+%1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
+DBG_VALUE %1, $noreg, !1, !2
+%4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
+DBG_VALUE %4, $noreg, !3, !4
+DBG_VALUE %7, $noreg, !5, !6
+```
In this circumstance LLVM would leave the MIR as shown above. Were we to move
-the ``DBG_VALUE`` of virtual register %7 upwards with the ``SUB32rr``, we would re-order
+the `DBG_VALUE` of virtual register %7 upwards with the `SUB32rr`, we would re-order
assignments and introduce a new state of the program. Whereas with the solution
above, the debugger will see one fewer combination of variable values, because
-``!3`` and ``!5`` will change value at the same time. This is preferred over
+`!3` and `!5` will change value at the same time. This is preferred over
misrepresenting the original program.
-In comparison, if one sunk the ``MOV32rm``, LLVM would produce the following:
-
-.. code-block:: text
-
- DBG_VALUE $noreg, $noreg, !1, !2
- %4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
- DBG_VALUE %4, $noreg, !3, !4
- %7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
- DBG_VALUE %7, $noreg, !5, !6
- %1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
- DBG_VALUE %1, $noreg, !1, !2
-
-Here, to avoid presenting a state in which the first assignment to ``!1``
-disappears, the ``DBG_VALUE`` at the top of the block assigns the variable the
+In comparison, if one sunk the `MOV32rm`, LLVM would produce the following:
+
+```text
+DBG_VALUE $noreg, $noreg, !1, !2
+%4:gr32 = ADD32rr %3, %2, implicit-def dead $eflags
+DBG_VALUE %4, $noreg, !3, !4
+%7:gr32 = SUB32rr %6, %5, implicit-def dead $eflags
+DBG_VALUE %7, $noreg, !5, !6
+%1:gr32 = MOV32rm %0, 1, $noreg, 4, $noreg, debug-location !5 :: (load 4 from %ir.addr1)
+DBG_VALUE %1, $noreg, !1, !2
+```
+Here, to avoid presenting a state in which the first assignment to `!1`
+disappears, the `DBG_VALUE` at the top of the block assigns the variable the
undefined location, until its value is available at the end of the block where
-an additional ``DBG_VALUE`` is added. Were any other ``DBG_VALUE`` for ``!1`` to occur
-in the instructions that the ``MOV32rm`` was sunk past, the ``DBG_VALUE`` for ``%1``
+an additional `DBG_VALUE` is added. Were any other `DBG_VALUE` for `!1` to occur
+in the instructions that the `MOV32rm` was sunk past, the `DBG_VALUE` for `%1`
would be dropped and the debugger would never observe it in the variable. This
accurately reflects that the value is not available during the corresponding
portion of the original program.
-Variable locations during Register Allocation
----------------------------------------------
+### Variable locations during Register Allocation
To avoid debug instructions interfering with the register allocator, the
-``LiveDebugVariables`` pass extracts variable locations from a MIR function and
-deletes the corresponding ``DBG_VALUE`` instructions. Some localized copy
+`LiveDebugVariables` pass extracts variable locations from a MIR function and
+deletes the corresponding `DBG_VALUE` instructions. Some localized copy
propagation is performed within blocks. After register allocation, the
-``VirtRegRewriter`` pass re-inserts ``DBG_VALUE`` instructions in their
+`VirtRegRewriter` pass re-inserts `DBG_VALUE` instructions in their
original positions, translating virtual register references into their physical
machine locations. To avoid encoding incorrect variable locations, in this pass
-any ``DBG_VALUE`` of a virtual register that is not live, is replaced by the
-undefined location. The ``LiveDebugVariables`` may insert redundant
-``DBG_VALUE``\s because of virtual register rewriting. These will be
-subsequently removed by the ``RemoveRedundantDebugValues`` pass.
+any `DBG_VALUE` of a virtual register that is not live, is replaced by the
+undefined location. The `LiveDebugVariables` may insert redundant
+`DBG_VALUE`s because of virtual register rewriting. These will be
+subsequently removed by the `RemoveRedundantDebugValues` pass.
-``LiveDebugValues`` expansion of variable locations
----------------------------------------------------
+### `LiveDebugValues` expansion of variable locations
After all optimizations have run and shortly before emission, the
-``LiveDebugValue``\s pass runs to achieve two aims:
+`LiveDebugValue`s pass runs to achieve two aims:
* To propagate the location of variables through copies and register spills,
* For every block, to record every valid variable location in that block.
-After this pass the ``DBG_VALUE`` instruction changes meaning: rather than
+After this pass the `DBG_VALUE` instruction changes meaning: rather than
corresponding to a source-level assignment where the variable may change value,
it asserts the location of a variable in a block, and loses effect outside the
block. Propagating variable locations through copies and spills is
@@ -1193,78 +1130,76 @@ straightforward: determining the variable location in every basic block
requires the consideration of control flow. Consider the following IR, which
presents several difficulties:
-.. code-block:: text
-
- define dso_local i32 @foo(i1 %cond, i32 %input) !dbg !12 {
- entry:
- br i1 %cond, label %truebr, label %falsebr
-
- bb1:
- %value = phi i32 [ %value1, %truebr ], [ %value2, %falsebr ]
- br label %exit, !dbg !26
-
- truebr:
- #dbg_value(i32 %input, !30, !DIExpression(), !24)
- #dbg_value(i32 1, !23, !DIExpression(), !24)
- %value1 = add i32 %input, 1
- br label %bb1
-
- falsebr:
- #dbg_value(i32 %input, !30, !DIExpression(), !24)
- #dbg_value(i32 2, !23, !DIExpression(), !24)
- %value2 = add i32 %input, 2
- br label %bb1
-
- exit:
- ret i32 %value, !dbg !30
- }
-
+```text
+define dso_local i32 @foo(i1 %cond, i32 %input) !dbg !12 {
+entry:
+ br i1 %cond, label %truebr, label %falsebr
+
+bb1:
+ %value = phi i32 [ %value1, %truebr ], [ %value2, %falsebr ]
+ br label %exit, !dbg !26
+
+truebr:
+ #dbg_value(i32 %input, !30, !DIExpression(), !24)
+ #dbg_value(i32 1, !23, !DIExpression(), !24)
+ %value1 = add i32 %input, 1
+ br label %bb1
+
+falsebr:
+ #dbg_value(i32 %input, !30, !DIExpression(), !24)
+ #dbg_value(i32 2, !23, !DIExpression(), !24)
+ %value2 = add i32 %input, 2
+ br label %bb1
+
+exit:
+ ret i32 %value, !dbg !30
+}
+```
Here the difficulties are:
* The control flow is roughly the opposite of basic block order
-* The value of the ``!23`` variable merges into ``%bb1``, but there is no PHI
+* The value of the `!23` variable merges into `%bb1`, but there is no PHI
node
-As mentioned above, the ``#dbg_value`` records essentially form an
+As mentioned above, the `#dbg_value` records essentially form an
imperative program embedded in the IR, with each record defining a variable
-location. This *could* be converted to an SSA form by ``mem2reg``, in the same way
+location. This *could* be converted to an SSA form by `mem2reg`, in the same way
that it uses use-def chains to identify control flow merges and insert phi
nodes for IR Values. However, because debug variable locations are defined for
every machine instruction, in effect every IR instruction uses every variable
location, which would lead to a large number of debugging records being
generated.
-Examining the example above, variable ``!30`` is assigned ``%input`` on both
-conditional paths through the function, while ``!23`` is assigned differing
-constant values on either path. Where control flow merges in ``%bb1`` we would
-want ``!30`` to keep its location (``%input``), but ``!23`` to become undefined
-as we cannot determine at runtime what value it should have in ``%bb1`` without
-inserting a PHI node. ``mem2reg`` does not insert the PHI node to avoid changing
-CodeGen when debugging is enabled, and does not insert the other ``#dbg_values``
+Examining the example above, variable `!30` is assigned `%input` on both
+conditional paths through the function, while `!23` is assigned differing
+constant values on either path. Where control flow merges in `%bb1` we would
+want `!30` to keep its location (`%input`), but `!23` to become undefined
+as we cannot determine at runtime what value it should have in `%bb1` without
+inserting a PHI node. `mem2reg` does not insert the PHI node to avoid changing
+CodeGen when debugging is enabled, and does not insert the other `#dbg_values`
to avoid adding very large numbers of records.
-Instead, ``LiveDebugValue``\s determines variable locations when control
+Instead, `LiveDebugValue`s determines variable locations when control
flow merges. A dataflow analysis is used to propagate locations between blocks:
when control flow merges, if a variable has the same location in all
predecessors then that location is propagated into the successor. If the
predecessor locations disagree, the location becomes undefined.
-Once ``LiveDebugValue``\s has run, every block should have all valid variable
-locations described by ``DBG_VALUE`` instructions within the block. Very little
+Once `LiveDebugValue`s has run, every block should have all valid variable
+locations described by `DBG_VALUE` instructions within the block. Very little
effort is then required by supporting classes (such as
-``DbgEntityHistoryCalculator``) to build a map of each instruction to every
+`DbgEntityHistoryCalculator`) to build a map of each instruction to every
valid variable location, without the need to consider control flow. From
the example above, it is otherwise difficult to determine that the location
-of variable ``!30`` should flow "up" into block ``%bb1``, but that the location
-of variable ``!23`` should not flow "down" into the ``%exit`` block.
+of variable `!30` should flow "up" into block `%bb1`, but that the location
+of variable `!23` should not flow "down" into the `%exit` block.
-.. _ccxx_frontend:
+(ccxx_frontend)=
-C/C++ front-end specific debug information
-==========================================
+## C/C++ front-end specific debug information
The C and C++ front-ends represent information about the program in a
-format that is effectively identical to `DWARF <http://www.dwarfstd.org/>`_
+format that is effectively identical to [DWARF](http://www.dwarfstd.org/)
in terms of information content. This allows code generators to
trivially support native debuggers by generating standard dwarf
information, and contains enough information for non-dwarf targets to
@@ -1279,261 +1214,238 @@ source-language front-ends, the information used should be documented here.
The following sections provide examples of a few C/C++ constructs and
the debug information that would best describe those constructs. The
-canonical references are the ``DINode`` classes defined in
-``include/llvm/IR/DebugInfoMetadata.h`` and the implementations of the
-helper functions in ``lib/IR/DIBuilder.cpp``.
+canonical references are the `DINode` classes defined in
+`include/llvm/IR/DebugInfoMetadata.h` and the implementations of the
+helper functions in `lib/IR/DIBuilder.cpp`.
-C/C++ source file information
------------------------------
+### C/C++ source file information
-``llvm::Instruction`` provides easy access to metadata attached to an
+`llvm::Instruction` provides easy access to metadata attached to an
instruction. One can extract line number information encoded in LLVM IR using
-``Instruction::getDebugLoc()`` and ``DILocation::getLine()``.
-
-.. code-block:: c++
-
- if (DILocation *Loc = I->getDebugLoc()) { // Here I is an LLVM instruction
- unsigned Line = Loc->getLine();
- StringRef File = Loc->getFilename();
- StringRef Dir = Loc->getDirectory();
- bool ImplicitCode = Loc->isImplicitCode();
- }
-
-When the flag ``ImplicitCode`` is true then it means that the Instruction has been
+`Instruction::getDebugLoc()` and `DILocation::getLine()`.
+
+```c++
+if (DILocation *Loc = I->getDebugLoc()) { // Here I is an LLVM instruction
+ unsigned Line = Loc->getLine();
+ StringRef File = Loc->getFilename();
+ StringRef Dir = Loc->getDirectory();
+ bool ImplicitCode = Loc->isImplicitCode();
+}
+```
+When the flag `ImplicitCode` is true then it means that the Instruction has been
added by the front-end but doesn't correspond to source code written by the user. For example
-.. code-block:: c++
-
- if (MyBoolean) {
- MyObject MO;
- ...
- }
-
-At the end of the scope the ``MyObject``'s destructor is called but it isn't written
+```c++
+if (MyBoolean) {
+ MyObject MO;
+ ...
+}
+```
+At the end of the scope the `MyObject`'s destructor is called but it isn't written
explicitly. This information is useful to avoid having counters on brackets when
making code coverage.
-C/C++ global variable information
----------------------------------
+### C/C++ global variable information
Given an integer global variable declared as follows:
-.. code-block:: c
-
- _Alignas(8) int MyGlobal = 100;
-
+```c
+_Alignas(8) int MyGlobal = 100;
+```
a C/C++ front-end would generate the following descriptors:
-.. code-block:: text
-
- ;;
- ;; Define the global itself.
- ;;
- @MyGlobal = global i32 100, align 8, !dbg !0
+```text
+;;
+;; Define the global itself.
+;;
+ at MyGlobal = global i32 100, align 8, !dbg !0
- ;;
- ;; List of debug info of globals
- ;;
- !llvm.dbg.cu = !{!1}
+;;
+;; List of debug info of globals
+;;
+!llvm.dbg.cu = !{!1}
- ;; Some unrelated metadata.
- !llvm.module.flags = !{!6, !7}
- !llvm.ident = !{!8}
+;; Some unrelated metadata.
+!llvm.module.flags = !{!6, !7}
+!llvm.ident = !{!8}
- ;; Define the global variable itself
- !0 = distinct !DIGlobalVariable(name: "MyGlobal", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true, align: 64)
+;; Define the global variable itself
+!0 = distinct !DIGlobalVariable(name: "MyGlobal", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true, align: 64)
- ;; Define the compile unit.
- !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2,
- producer: "clang version 4.0.0",
- isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug,
- enums: !3, globals: !4)
+;; Define the compile unit.
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2,
+ producer: "clang version 4.0.0",
+ isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug,
+ enums: !3, globals: !4)
- ;;
- ;; Define the file
- ;;
- !2 = !DIFile(filename: "/dev/stdin",
- directory: "/Users/dexonsmith/data/llvm/debug-info")
+;;
+;; Define the file
+;;
+!2 = !DIFile(filename: "/dev/stdin",
+ directory: "/Users/dexonsmith/data/llvm/debug-info")
- ;; An empty array.
- !3 = !{}
+;; An empty array.
+!3 = !{}
- ;; The Array of Global Variables
- !4 = !{!0}
+;; The Array of Global Variables
+!4 = !{!0}
- ;;
- ;; Define the type
- ;;
- !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+;;
+;; Define the type
+;;
+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- ;; Dwarf version to output.
- !6 = !{i32 2, !"Dwarf Version", i32 4}
+;; Dwarf version to output.
+!6 = !{i32 2, !"Dwarf Version", i32 4}
- ;; Debug info schema version.
- !7 = !{i32 2, !"Debug Info Version", i32 3}
+;; Debug info schema version.
+!7 = !{i32 2, !"Debug Info Version", i32 3}
- ;; Compiler identification
- !8 = !{!"clang version 4.0.0"}
+;; Compiler identification
+!8 = !{!"clang version 4.0.0"}
-
-The align value in ``DIGlobalVariable`` description specifies variable alignment in
-case it was forced by C11 ``_Alignas()``, C++11 ``alignas()`` keywords or compiler
-attribute ``__attribute__((aligned ()))``. In other case (when this field is missing)
+```
+The align value in `DIGlobalVariable` description specifies variable alignment in
+case it was forced by C11 `_Alignas()`, C++11 `alignas()` keywords or compiler
+attribute `__attribute__((aligned ()))`. In other case (when this field is missing)
alignment is considered default. This is used when producing DWARF output
-for ``DW_AT_alignment`` value.
+for `DW_AT_alignment` value.
-C/C++ function information
---------------------------
+### C/C++ function information
Given a function declared as follows:
-.. code-block:: c
-
- int main(int argc, char *argv[]) {
- return 0;
- }
-
+```c
+int main(int argc, char *argv[]) {
+ return 0;
+}
+```
a C/C++ front-end would generate the following descriptors:
-.. code-block:: text
+```text
+;;
+;; Define the anchor for subprograms.
+;;
+!4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
+ isLocal: false, isDefinition: true, scopeLine: 1,
+ flags: DIFlagPrototyped, isOptimized: false,
+ retainedNodes: !2)
- ;;
- ;; Define the anchor for subprograms.
- ;;
- !4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
- isLocal: false, isDefinition: true, scopeLine: 1,
- flags: DIFlagPrototyped, isOptimized: false,
- retainedNodes: !2)
+;;
+;; Define the subprogram itself.
+;;
+define i32 @main(i32 %argc, i8** %argv) !dbg !4 {
+...
+}
+```
+## C++ specific debug information
- ;;
- ;; Define the subprogram itself.
- ;;
- define i32 @main(i32 %argc, i8** %argv) !dbg !4 {
- ...
- }
-
-C++ specific debug information
-==============================
-
-C++ special member functions information
-----------------------------------------
+### C++ special member functions information
-DWARF v5 introduces attributes defined to enhance debugging information of C++ programs. LLVM can generate (or omit) these appropriate DWARF attributes. In C++ a special member function Ctors, Dtors, Copy/Move Ctors, assignment operators can be declared with C++11 keyword deleted. This is represented in LLVM using ``spFlags`` value ``DISPFlagDeleted``.
+DWARF v5 introduces attributes defined to enhance debugging information of C++ programs. LLVM can generate (or omit) these appropriate DWARF attributes. In C++ a special member function Ctors, Dtors, Copy/Move Ctors, assignment operators can be declared with C++11 keyword deleted. This is represented in LLVM using `spFlags` value `DISPFlagDeleted`.
Given a class declaration with copy constructor declared as deleted:
-.. code-block:: c
-
- class foo {
- public:
- foo(const foo&) = deleted;
- };
-
+```c
+class foo {
+ public:
+ foo(const foo&) = deleted;
+};
+```
A C++ frontend would generate the following:
-.. code-block:: text
-
- !17 = !DISubprogram(name: "foo", scope: !11, file: !1, line: 5, type: !18, scopeLine: 5, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted)
-
+```text
+!17 = !DISubprogram(name: "foo", scope: !11, file: !1, line: 5, type: !18, scopeLine: 5, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted)
+```
and this will produce an additional DWARF attribute as:
-.. code-block:: text
-
- DW_TAG_subprogram [7] *
- DW_AT_name [DW_FORM_strx1] (indexed (00000006) string = "foo")
- DW_AT_decl_line [DW_FORM_data1] (5)
- ...
- DW_AT_deleted [DW_FORM_flag_present] (true)
-
-Fortran specific debug information
-==================================
-
-Fortran function information
-----------------------------
-
-There are a few DWARF attributes defined to support client debugging of Fortran programs. LLVM can generate (or omit) the appropriate DWARF attributes for the prefix-specs of ELEMENTAL, PURE, IMPURE, RECURSIVE, and NON_RECURSIVE. This is done by using the ``spFlags`` values: ``DISPFlagElemental``, ``DISPFlagPure``, and ``DISPFlagRecursive``.
+```text
+DW_TAG_subprogram [7] *
+ DW_AT_name [DW_FORM_strx1] (indexed (00000006) string = "foo")
+ DW_AT_decl_line [DW_FORM_data1] (5)
+ ...
+ DW_AT_deleted [DW_FORM_flag_present] (true)
+```
+## Fortran specific debug information
-.. code-block:: fortran
+### Fortran function information
- elemental function elem_func(a)
+There are a few DWARF attributes defined to support client debugging of Fortran programs. LLVM can generate (or omit) the appropriate DWARF attributes for the prefix-specs of ELEMENTAL, PURE, IMPURE, RECURSIVE, and NON_RECURSIVE. This is done by using the `spFlags` values: `DISPFlagElemental`, `DISPFlagPure`, and `DISPFlagRecursive`.
+```fortran
+elemental function elem_func(a)
+```
a Fortran front-end would generate the following descriptors:
-.. code-block:: text
-
- !11 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !1,
- line: 5, type: !8, scopeLine: 6,
- spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !0,
- retainedNodes: !2)
-
+```text
+!11 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !1,
+ line: 5, type: !8, scopeLine: 6,
+ spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !0,
+ retainedNodes: !2)
+```
and this will materialize an additional DWARF attribute as:
-.. code-block:: text
-
- DW_TAG_subprogram [3]
- DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010 ".text")
- DW_AT_high_pc [DW_FORM_data4] (0x00000001)
- ...
- DW_AT_elemental [DW_FORM_flag_present] (true)
-
-There are a few DWARF tags defined to represent Fortran specific constructs i.e ``DW_TAG_string_type`` for representing Fortran character(n). In LLVM, this is represented as ``DIStringType``.
-
-.. code-block:: fortran
-
- character(len=*), intent(in) :: string
-
+```text
+DW_TAG_subprogram [3]
+ DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010 ".text")
+ DW_AT_high_pc [DW_FORM_data4] (0x00000001)
+ ...
+ DW_AT_elemental [DW_FORM_flag_present] (true)
+```
+There are a few DWARF tags defined to represent Fortran specific constructs i.e `DW_TAG_string_type` for representing Fortran character(n). In LLVM, this is represented as `DIStringType`.
+
+```fortran
+character(len=*), intent(in) :: string
+```
a Fortran front-end would generate the following descriptors:
-.. code-block:: text
+```text
+!DILocalVariable(name: "string", arg: 1, scope: !10, file: !3, line: 4, type: !15)
+!DIStringType(name: "character(*)!2", stringLength: !16, stringLengthExpression: !DIExpression(), size: 32)
+```
+A fortran deferred-length character can also contain the information of raw storage of the characters in addition to the length of the string. This information is encoded in the stringLocationExpression field. Based on this information, `DW_AT_data_location` attribute is emitted in a `DW_TAG_string_type` debug info.
- !DILocalVariable(name: "string", arg: 1, scope: !10, file: !3, line: 4, type: !15)
- !DIStringType(name: "character(*)!2", stringLength: !16, stringLengthExpression: !DIExpression(), size: 32)
-
-A fortran deferred-length character can also contain the information of raw storage of the characters in addition to the length of the string. This information is encoded in the stringLocationExpression field. Based on this information, ``DW_AT_data_location`` attribute is emitted in a ``DW_TAG_string_type`` debug info.
-
- !DIStringType(name: "character(*)!2", stringLengthExpression: !DIExpression(), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), size: 32)
+```llvm
+!DIStringType(name: "character(*)!2", stringLengthExpression: !DIExpression(),
+ stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref),
+ size: 32)
+```
and this will materialize in DWARF tags as:
-.. code-block:: text
-
- DW_TAG_string_type
- DW_AT_name ("character(*)!2")
- DW_AT_string_length (0x00000064)
- 0x00000064: DW_TAG_variable
- DW_AT_location (DW_OP_fbreg +16)
- DW_AT_type (0x00000083 "integer*8")
- DW_AT_data_location (DW_OP_push_object_address, DW_OP_deref)
- ...
- DW_AT_artificial (true)
-
+```text
+DW_TAG_string_type
+ DW_AT_name ("character(*)!2")
+ DW_AT_string_length (0x00000064)
+0x00000064: DW_TAG_variable
+ DW_AT_location (DW_OP_fbreg +16)
+ DW_AT_type (0x00000083 "integer*8")
+ DW_AT_data_location (DW_OP_push_object_address, DW_OP_deref)
+ ...
+ DW_AT_artificial (true)
+```
A Fortran front-end may need to generate a *trampoline* function to call a
function defined in a different compilation unit. In this case, the front-end
can emit the following descriptor for the trampoline function:
-.. code-block:: text
-
- !DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p", scope: !4, file: !4, type: !5, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !7, retainedNodes: !24, targetFuncName: "sub1_")
-
+```text
+!DISubprogram(name: "sub1_.t0p", linkageName: "sub1_.t0p", scope: !4, file: !4, type: !5, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !7, retainedNodes: !24, targetFuncName: "sub1_")
+```
The targetFuncName field is the name of the function that the trampoline
calls. This descriptor results in the following DWARF tag:
-.. code-block:: text
-
- DW_TAG_subprogram
- ...
- DW_AT_linkage_name ("sub1_.t0p")
- DW_AT_name ("sub1_.t0p")
- DW_AT_trampoline ("sub1_")
-
-Debugging information format
-============================
+```text
+DW_TAG_subprogram
+ ...
+ DW_AT_linkage_name ("sub1_.t0p")
+ DW_AT_name ("sub1_.t0p")
+ DW_AT_trampoline ("sub1_")
+```
+## Debugging information format
-Debugging Information Extension for Objective-C Properties
-----------------------------------------------------------
+### Debugging Information Extension for Objective-C Properties
-Introduction
-^^^^^^^^^^^^
+#### Introduction
Objective-C provides a simpler way to declare and define accessor methods using
declared properties. The language provides features to declare a property and
@@ -1547,8 +1459,7 @@ encoding of Objective-C properties. This proposal describes DWARF extensions to
encode Objective-C properties, which the debugger can use to let developers
inspect Objective-C properties.
-Proposal
-^^^^^^^^
+#### Proposal
Objective-C properties exist separately from class members. A property can be
defined only by "setter" and "getter" selectors, and be calculated anew on each
@@ -1556,69 +1467,67 @@ access. Or a property can just be a direct access to some declared ivar.
Finally it can have an ivar "automatically synthesized" for it by the compiler,
in which case the property can be referred to in user code directly using the
standard C dereference syntax as well as through the property "dot" syntax, but
-there is no entry in the ``@interface`` declaration corresponding to this ivar.
+there is no entry in the `@interface` declaration corresponding to this ivar.
To facilitate debugging, these properties we will add a new DWARF TAG into the
-``DW_TAG_structure_type`` definition for the class to hold the description of a
+`DW_TAG_structure_type` definition for the class to hold the description of a
given property, and a set of DWARF attributes that provide said description.
The property tag will also contain the name and declared type of the property.
If there is a related ivar, there will also be a DWARF property attribute placed
-in the ``DW_TAG_member`` DIE for that ivar referring back to the property TAG
+in the `DW_TAG_member` DIE for that ivar referring back to the property TAG
for that property. And in the case where the compiler synthesizes the ivar
-directly, the compiler is expected to generate a ``DW_TAG_member`` for that
-ivar (with the ``DW_AT_artificial`` set to 1), whose name will be the name used
+directly, the compiler is expected to generate a `DW_TAG_member` for that
+ivar (with the `DW_AT_artificial` set to 1), whose name will be the name used
to access this ivar directly in code, and with the property attribute pointing
back to the property it is backing.
The following examples will serve as illustration for our discussion:
-.. code-block:: objc
-
- @interface I1 {
- int n2;
- }
-
- @property int p1;
- @property int p2;
- @end
+```objc
+ at interface I1 {
+ int n2;
+}
- @implementation I1
- @synthesize p1;
- @synthesize p2 = n2;
- @end
+ at property int p1;
+ at property int p2;
+ at end
+ at implementation I1
+ at synthesize p1;
+ at synthesize p2 = n2;
+ at end
+```
This produces the following DWARF (this is a "pseudo dwarfdump" output):
-.. code-block:: none
-
- 0x00000100: TAG_structure_type [7] *
- AT_APPLE_runtime_class( 0x10 )
- AT_name( "I1" )
- AT_decl_file( "Objc_Property.m" )
- AT_decl_line( 3 )
-
- 0x00000110 TAG_APPLE_property
- AT_name ( "p1" )
- AT_type ( {0x00000150} ( int ) )
-
- 0x00000120: TAG_APPLE_property
- AT_name ( "p2" )
- AT_type ( {0x00000150} ( int ) )
-
- 0x00000130: TAG_member [8]
- AT_name( "_p1" )
- AT_APPLE_property ( {0x00000110} "p1" )
- AT_type( {0x00000150} ( int ) )
- AT_artificial ( 0x1 )
-
- 0x00000140: TAG_member [8]
- AT_name( "n2" )
- AT_APPLE_property ( {0x00000120} "p2" )
- AT_type( {0x00000150} ( int ) )
-
- 0x00000150: AT_type( ( int ) )
-
+```text
+0x00000100: TAG_structure_type [7] *
+ AT_APPLE_runtime_class( 0x10 )
+ AT_name( "I1" )
+ AT_decl_file( "Objc_Property.m" )
+ AT_decl_line( 3 )
+
+0x00000110 TAG_APPLE_property
+ AT_name ( "p1" )
+ AT_type ( {0x00000150} ( int ) )
+
+0x00000120: TAG_APPLE_property
+ AT_name ( "p2" )
+ AT_type ( {0x00000150} ( int ) )
+
+0x00000130: TAG_member [8]
+ AT_name( "_p1" )
+ AT_APPLE_property ( {0x00000110} "p1" )
+ AT_type( {0x00000150} ( int ) )
+ AT_artificial ( 0x1 )
+
+0x00000140: TAG_member [8]
+ AT_name( "n2" )
+ AT_APPLE_property ( {0x00000120} "p2" )
+ AT_type( {0x00000150} ( int ) )
+
+0x00000150: AT_type( ( int ) )
+```
Note, the current convention is that the name of the ivar for an
auto-synthesized property is the name of the property from which it derives
with an underscore prepended, as is shown in the example. But we actually
@@ -1626,151 +1535,119 @@ don't need to know this convention, since we are given the name of the ivar
directly.
Also, it is common practice in ObjC to have different property declarations in
-the ``@interface`` and ``@implementation`` - e.g. to provide a read-only property in
+the `@interface` and `@implementation` - e.g. to provide a read-only property in
the interface, and a read-write interface in the implementation. In that case,
the compiler should emit whichever property declaration will be in force in the
current translation unit.
Developers can decorate a property with attributes which are encoded using
-``DW_AT_APPLE_property_attribute``.
-
-.. code-block:: objc
-
- @property (readonly, nonatomic) int pr;
-
-.. code-block:: none
-
- TAG_APPLE_property [8]
- AT_name( "pr" )
- AT_type ( {0x00000147} (int) )
- AT_APPLE_property_attribute (DW_APPLE_PROPERTY_readonly, DW_APPLE_PROPERTY_nonatomic)
-
+`DW_AT_APPLE_property_attribute`.
+
+```objc
+ at property (readonly, nonatomic) int pr;
+```
+```text
+TAG_APPLE_property [8]
+ AT_name( "pr" )
+ AT_type ( {0x00000147} (int) )
+ AT_APPLE_property_attribute (DW_APPLE_PROPERTY_readonly, DW_APPLE_PROPERTY_nonatomic)
+```
The setter and getter method names are attached to the property using
-``DW_AT_APPLE_property_setter`` and ``DW_AT_APPLE_property_getter`` attributes.
-
-.. code-block:: objc
-
- @interface I1
- @property (setter=myOwnP3Setter:) int p3;
- -(void)myOwnP3Setter:(int)a;
- @end
-
- @implementation I1
- @synthesize p3;
- -(void)myOwnP3Setter:(int)a{ }
- @end
-
+`DW_AT_APPLE_property_setter` and `DW_AT_APPLE_property_getter` attributes.
+
+```objc
+ at interface I1
+ at property (setter=myOwnP3Setter:) int p3;
+-(void)myOwnP3Setter:(int)a;
+ at end
+
+ at implementation I1
+ at synthesize p3;
+-(void)myOwnP3Setter:(int)a{ }
+ at end
+```
The DWARF for this would be:
-.. code-block:: none
-
- 0x000003bd: TAG_structure_type [7] *
- AT_APPLE_runtime_class( 0x10 )
- AT_name( "I1" )
- AT_decl_file( "Objc_Property.m" )
- AT_decl_line( 3 )
-
- 0x000003cd TAG_APPLE_property
- AT_name ( "p3" )
- AT_APPLE_property_setter ( "myOwnP3Setter:" )
- AT_type( {0x00000147} ( int ) )
-
- 0x000003f3: TAG_member [8]
- AT_name( "_p3" )
- AT_type ( {0x00000147} ( int ) )
- AT_APPLE_property ( {0x000003cd} )
- AT_artificial ( 0x1 )
-
-New DWARF Tags
-^^^^^^^^^^^^^^
+```text
+0x000003bd: TAG_structure_type [7] *
+ AT_APPLE_runtime_class( 0x10 )
+ AT_name( "I1" )
+ AT_decl_file( "Objc_Property.m" )
+ AT_decl_line( 3 )
+
+0x000003cd TAG_APPLE_property
+ AT_name ( "p3" )
+ AT_APPLE_property_setter ( "myOwnP3Setter:" )
+ AT_type( {0x00000147} ( int ) )
+
+0x000003f3: TAG_member [8]
+ AT_name( "_p3" )
+ AT_type ( {0x00000147} ( int ) )
+ AT_APPLE_property ( {0x000003cd} )
+ AT_artificial ( 0x1 )
+```
+#### New DWARF Tags
-+-----------------------+--------+
| TAG | Value |
-+=======================+========+
+|-----------------------|--------|
| DW_TAG_APPLE_property | 0x4200 |
-+-----------------------+--------+
-New DWARF Attributes
-^^^^^^^^^^^^^^^^^^^^
+#### New DWARF Attributes
-+--------------------------------+--------+-----------+
| Attribute | Value | Classes |
-+================================+========+===========+
+|--------------------------------|--------|-----------|
| DW_AT_APPLE_property | 0x3fed | Reference |
-+--------------------------------+--------+-----------+
| DW_AT_APPLE_property_getter | 0x3fe9 | String |
-+--------------------------------+--------+-----------+
| DW_AT_APPLE_property_setter | 0x3fea | String |
-+--------------------------------+--------+-----------+
| DW_AT_APPLE_property_attribute | 0x3feb | Constant |
-+--------------------------------+--------+-----------+
-New DWARF Constants
-^^^^^^^^^^^^^^^^^^^
+#### New DWARF Constants
-+--------------------------------------+-------+
| Name | Value |
-+======================================+=======+
+|--------------------------------------|-------|
| DW_APPLE_PROPERTY_readonly | 0x01 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_getter | 0x02 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_assign | 0x04 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_readwrite | 0x08 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_retain | 0x10 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_copy | 0x20 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_nonatomic | 0x40 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_setter | 0x80 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_atomic | 0x100 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_weak | 0x200 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_strong | 0x400 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_unsafe_unretained | 0x800 |
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_nullability | 0x1000|
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_null_resettable | 0x2000|
-+--------------------------------------+-------+
| DW_APPLE_PROPERTY_class | 0x4000|
-+--------------------------------------+-------+
-Name Accelerator Tables
------------------------
+### Name Accelerator Tables
-Introduction
-^^^^^^^^^^^^
+#### Introduction
-The "``.debug_pubnames``" and "``.debug_pubtypes``" formats are not what a
-debugger needs. The "``pub``" in the section name indicates that the entries
+The "`.debug_pubnames`" and "`.debug_pubtypes`" formats are not what a
+debugger needs. The "`pub`" in the section name indicates that the entries
in the table are publicly visible names only. This means no static or hidden
-functions show up in the "``.debug_pubnames``". No static variables or private
-class variables are in the "``.debug_pubtypes``". Many compilers add different
+functions show up in the "`.debug_pubnames`". No static variables or private
+class variables are in the "`.debug_pubtypes`". Many compilers add different
things to these tables, so we can't rely upon the contents between gcc, icc, or
clang.
The typical query given by users tends not to match up with the contents of
these tables. For example, the DWARF spec states that "In the case of the name
of a function member or static data member of a C++ structure, class or union,
-the name presented in the "``.debug_pubnames``" section is not the simple name
-given by the ``DW_AT_name attribute`` of the referenced debugging information
+the name presented in the "`.debug_pubnames`" section is not the simple name
+given by the `DW_AT_name attribute` of the referenced debugging information
entry, but rather the fully qualified name of the data or function member."
So the only names in these tables for complex C++ entries is a fully
qualified name. Debugger users tend not to enter their search strings as
-"``a::b::c(int,const Foo&) const``", but rather as "``c``", "``b::c``" , or
-"``a::b::c``". So the name entered in the name table must be demangled in
+"`a::b::c(int,const Foo&) const`", but rather as "`c`", "`b::c`" , or
+"`a::b::c`". So the name entered in the name table must be demangled in
order to chop it up appropriately and additional names must be manually entered
into the table to make it effective as a name lookup table for debuggers to
use.
-All debuggers currently ignore the "``.debug_pubnames``" table as a result of
+All debuggers currently ignore the "`.debug_pubnames`" table as a result of
its inconsistent and useless public-only name content making it a waste of
space in the object file. These tables, when they are written to disk, are not
sorted in any way, leaving every debugger to do its own parsing and sorting.
@@ -1786,8 +1663,8 @@ need.
These tables are also insufficient for what a debugger like LLDB needs. LLDB
uses clang for its expression parsing where LLDB acts as a PCH. LLDB is then
-often asked to look for type "``foo``" or namespace "``bar``", or list items in
-namespace "``baz``". Namespaces are not included in the pubnames or pubtypes
+often asked to look for type "`foo`" or namespace "`bar`", or list items in
+namespace "`baz`". Namespaces are not included in the pubnames or pubtypes
tables. Since clang asks a lot of questions when it is parsing an expression,
we need to be very fast when looking up names, as it happens a lot. Having new
accelerator tables that are optimized for very quick lookups will benefit this
@@ -1819,298 +1696,283 @@ case of debuggers we optimized for lookups that fail most of the time.
Each table that is defined should have strict rules on exactly what is in the
accelerator tables and documented so clients can rely on the content.
-Hash Tables
-^^^^^^^^^^^
+#### Hash Tables
-Standard Hash Tables
-""""""""""""""""""""
+##### Standard Hash Tables
Typical hash tables have a header, buckets, and each bucket points to the
bucket contents:
-.. code-block:: none
-
- .------------.
- | HEADER |
- |------------|
- | BUCKETS |
- |------------|
- | DATA |
- `------------'
-
+```text
+.------------.
+| HEADER |
+|------------|
+| BUCKETS |
+|------------|
+| DATA |
+`------------'
+```
The BUCKETS are an array of offsets to DATA for each hash:
-.. code-block:: none
-
- .------------.
- | 0x00001000 | BUCKETS[0]
- | 0x00002000 | BUCKETS[1]
- | 0x00002200 | BUCKETS[2]
- | 0x000034f0 | BUCKETS[3]
- | | ...
- | 0xXXXXXXXX | BUCKETS[n_buckets]
- '------------'
-
-So for ``bucket[3]`` in the example above, we have an offset into the table
+```text
+.------------.
+| 0x00001000 | BUCKETS[0]
+| 0x00002000 | BUCKETS[1]
+| 0x00002200 | BUCKETS[2]
+| 0x000034f0 | BUCKETS[3]
+| | ...
+| 0xXXXXXXXX | BUCKETS[n_buckets]
+'------------'
+```
+So for `bucket[3]` in the example above, we have an offset into the table
0x000034f0 which points to a chain of entries for the bucket. Each bucket must
contain a next pointer, full 32-bit hash value, the string itself, and the data
for the current string value.
-.. code-block:: none
-
- .------------.
- 0x000034f0: | 0x00003500 | next pointer
- | 0x12345678 | 32-bit hash
- | "erase" | string value
- | data[n] | HashData for this bucket
- |------------|
- 0x00003500: | 0x00003550 | next pointer
- | 0x29273623 | 32-bit hash
- | "dump" | string value
- | data[n] | HashData for this bucket
- |------------|
- 0x00003550: | 0x00000000 | next pointer
- | 0x82638293 | 32-bit hash
- | "main" | string value
- | data[n] | HashData for this bucket
- `------------'
-
+```text
+ .------------.
+0x000034f0: | 0x00003500 | next pointer
+ | 0x12345678 | 32-bit hash
+ | "erase" | string value
+ | data[n] | HashData for this bucket
+ |------------|
+0x00003500: | 0x00003550 | next pointer
+ | 0x29273623 | 32-bit hash
+ | "dump" | string value
+ | data[n] | HashData for this bucket
+ |------------|
+0x00003550: | 0x00000000 | next pointer
+ | 0x82638293 | 32-bit hash
+ | "main" | string value
+ | data[n] | HashData for this bucket
+ `------------'
+```
The problem with this layout for debuggers is that we need to optimize for the
negative lookup case where the symbol we're searching for is not present. So
-if we were to lookup "``printf``" in the table above, we would make a 32-bit
-hash for "``printf``", it might match ``bucket[3]``. We would need to go to
+if we were to lookup "`printf`" in the table above, we would make a 32-bit
+hash for "`printf`", it might match `bucket[3]`. We would need to go to
the offset 0x000034f0 and start looking to see if our 32-bit hash matches. To
do so, we need to read the next pointer, then read the hash, compare it, and
skip to the next bucket. Each time we are skipping many bytes in memory and
touching new pages just to do the compare on the full 32-bit hash. All of
these accesses then tell us that we didn't have a match.
-Name Hash Tables
-""""""""""""""""
+##### Name Hash Tables
To solve the issues mentioned above, we have structured the hash tables a bit
differently: a header, buckets, an array of all unique 32-bit hash values,
followed by an array of hash value data offsets, one for each hash value, then
the data for all hash values:
-.. code-block:: none
-
- .-------------.
- | HEADER |
- |-------------|
- | BUCKETS |
- |-------------|
- | HASHES |
- |-------------|
- | OFFSETS |
- |-------------|
- | DATA |
- `-------------'
-
-The ``BUCKETS`` in the name tables are an index into the ``HASHES`` array. By
+```text
+.-------------.
+| HEADER |
+|-------------|
+| BUCKETS |
+|-------------|
+| HASHES |
+|-------------|
+| OFFSETS |
+|-------------|
+| DATA |
+`-------------'
+```
+The `BUCKETS` in the name tables are an index into the `HASHES` array. By
making all of the full 32-bit hash values contiguous in memory, we allow
ourselves to efficiently check for a match while touching as little memory as
possible. Most often checking the 32-bit hash values is as far as the lookup
goes. If it does match, it usually is a match with no collisions. So for a
-table with "``n_buckets``" buckets, and "``n_hashes``" unique 32-bit hash
-values, we can clarify the contents of the ``BUCKETS``, ``HASHES`` and
-``OFFSETS`` as:
-
-.. code-block:: none
-
- .-------------------------.
- | HEADER.magic | uint32_t
- | HEADER.version | uint16_t
- | HEADER.hash_function | uint16_t
- | HEADER.bucket_count | uint32_t
- | HEADER.hashes_count | uint32_t
- | HEADER.header_data_len | uint32_t
- | HEADER_DATA | HeaderData
- |-------------------------|
- | BUCKETS | uint32_t[n_buckets] // 32-bit hash indexes
- |-------------------------|
- | HASHES | uint32_t[n_hashes] // 32-bit hash values
- |-------------------------|
- | OFFSETS | uint32_t[n_hashes] // 32-bit offsets to hash value data
- |-------------------------|
- | ALL HASH DATA |
- `-------------------------'
-
+table with "`n_buckets`" buckets, and "`n_hashes`" unique 32-bit hash
+values, we can clarify the contents of the `BUCKETS`, `HASHES` and
+`OFFSETS` as:
+
+```text
+.-------------------------.
+| HEADER.magic | uint32_t
+| HEADER.version | uint16_t
+| HEADER.hash_function | uint16_t
+| HEADER.bucket_count | uint32_t
+| HEADER.hashes_count | uint32_t
+| HEADER.header_data_len | uint32_t
+| HEADER_DATA | HeaderData
+|-------------------------|
+| BUCKETS | uint32_t[n_buckets] // 32-bit hash indexes
+|-------------------------|
+| HASHES | uint32_t[n_hashes] // 32-bit hash values
+|-------------------------|
+| OFFSETS | uint32_t[n_hashes] // 32-bit offsets to hash value data
+|-------------------------|
+| ALL HASH DATA |
+`-------------------------'
+```
So taking the exact same data from the standard hash example above, we end up
with:
-.. code-block:: none
-
- .------------.
- | HEADER |
- |------------|
- | 0 | BUCKETS[0]
- | 2 | BUCKETS[1]
- | 5 | BUCKETS[2]
- | 6 | BUCKETS[3]
- | | ...
- | ... | BUCKETS[n_buckets]
- |------------|
- | 0x........ | HASHES[0]
- | 0x........ | HASHES[1]
- | 0x........ | HASHES[2]
- | 0x........ | HASHES[3]
- | 0x........ | HASHES[4]
- | 0x........ | HASHES[5]
- | 0x12345678 | HASHES[6] hash for BUCKETS[3]
- | 0x29273623 | HASHES[7] hash for BUCKETS[3]
- | 0x82638293 | HASHES[8] hash for BUCKETS[3]
- | 0x........ | HASHES[9]
- | 0x........ | HASHES[10]
- | 0x........ | HASHES[11]
- | 0x........ | HASHES[12]
- | 0x........ | HASHES[13]
- | 0x........ | HASHES[n_hashes]
- |------------|
- | 0x........ | OFFSETS[0]
- | 0x........ | OFFSETS[1]
- | 0x........ | OFFSETS[2]
- | 0x........ | OFFSETS[3]
- | 0x........ | OFFSETS[4]
- | 0x........ | OFFSETS[5]
- | 0x000034f0 | OFFSETS[6] offset for BUCKETS[3]
- | 0x00003500 | OFFSETS[7] offset for BUCKETS[3]
- | 0x00003550 | OFFSETS[8] offset for BUCKETS[3]
- | 0x........ | OFFSETS[9]
- | 0x........ | OFFSETS[10]
- | 0x........ | OFFSETS[11]
- | 0x........ | OFFSETS[12]
- | 0x........ | OFFSETS[13]
- | 0x........ | OFFSETS[n_hashes]
- |------------|
- | |
- | |
- | |
- | |
- | |
- |------------|
- 0x000034f0: | 0x00001203 | .debug_str ("erase")
- | 0x00000004 | A 32-bit array count - number of HashData with name "erase"
- | 0x........ | HashData[0]
- | 0x........ | HashData[1]
- | 0x........ | HashData[2]
- | 0x........ | HashData[3]
- | 0x00000000 | String offset into .debug_str (terminate data for hash)
- |------------|
- 0x00003500: | 0x00001203 | String offset into .debug_str ("collision")
- | 0x00000002 | A 32-bit array count - number of HashData with name "collision"
- | 0x........ | HashData[0]
- | 0x........ | HashData[1]
- | 0x00001203 | String offset into .debug_str ("dump")
- | 0x00000003 | A 32-bit array count - number of HashData with name "dump"
- | 0x........ | HashData[0]
- | 0x........ | HashData[1]
- | 0x........ | HashData[2]
- | 0x00000000 | String offset into .debug_str (terminate data for hash)
- |------------|
- 0x00003550: | 0x00001203 | String offset into .debug_str ("main")
- | 0x00000009 | A 32-bit array count - number of HashData with name "main"
- | 0x........ | HashData[0]
- | 0x........ | HashData[1]
- | 0x........ | HashData[2]
- | 0x........ | HashData[3]
- | 0x........ | HashData[4]
- | 0x........ | HashData[5]
- | 0x........ | HashData[6]
- | 0x........ | HashData[7]
- | 0x........ | HashData[8]
- | 0x00000000 | String offset into .debug_str (terminate data for hash)
- `------------'
-
+```text
+ .------------.
+ | HEADER |
+ |------------|
+ | 0 | BUCKETS[0]
+ | 2 | BUCKETS[1]
+ | 5 | BUCKETS[2]
+ | 6 | BUCKETS[3]
+ | | ...
+ | ... | BUCKETS[n_buckets]
+ |------------|
+ | 0x........ | HASHES[0]
+ | 0x........ | HASHES[1]
+ | 0x........ | HASHES[2]
+ | 0x........ | HASHES[3]
+ | 0x........ | HASHES[4]
+ | 0x........ | HASHES[5]
+ | 0x12345678 | HASHES[6] hash for BUCKETS[3]
+ | 0x29273623 | HASHES[7] hash for BUCKETS[3]
+ | 0x82638293 | HASHES[8] hash for BUCKETS[3]
+ | 0x........ | HASHES[9]
+ | 0x........ | HASHES[10]
+ | 0x........ | HASHES[11]
+ | 0x........ | HASHES[12]
+ | 0x........ | HASHES[13]
+ | 0x........ | HASHES[n_hashes]
+ |------------|
+ | 0x........ | OFFSETS[0]
+ | 0x........ | OFFSETS[1]
+ | 0x........ | OFFSETS[2]
+ | 0x........ | OFFSETS[3]
+ | 0x........ | OFFSETS[4]
+ | 0x........ | OFFSETS[5]
+ | 0x000034f0 | OFFSETS[6] offset for BUCKETS[3]
+ | 0x00003500 | OFFSETS[7] offset for BUCKETS[3]
+ | 0x00003550 | OFFSETS[8] offset for BUCKETS[3]
+ | 0x........ | OFFSETS[9]
+ | 0x........ | OFFSETS[10]
+ | 0x........ | OFFSETS[11]
+ | 0x........ | OFFSETS[12]
+ | 0x........ | OFFSETS[13]
+ | 0x........ | OFFSETS[n_hashes]
+ |------------|
+ | |
+ | |
+ | |
+ | |
+ | |
+ |------------|
+0x000034f0: | 0x00001203 | .debug_str ("erase")
+ | 0x00000004 | A 32-bit array count - number of HashData with name "erase"
+ | 0x........ | HashData[0]
+ | 0x........ | HashData[1]
+ | 0x........ | HashData[2]
+ | 0x........ | HashData[3]
+ | 0x00000000 | String offset into .debug_str (terminate data for hash)
+ |------------|
+0x00003500: | 0x00001203 | String offset into .debug_str ("collision")
+ | 0x00000002 | A 32-bit array count - number of HashData with name "collision"
+ | 0x........ | HashData[0]
+ | 0x........ | HashData[1]
+ | 0x00001203 | String offset into .debug_str ("dump")
+ | 0x00000003 | A 32-bit array count - number of HashData with name "dump"
+ | 0x........ | HashData[0]
+ | 0x........ | HashData[1]
+ | 0x........ | HashData[2]
+ | 0x00000000 | String offset into .debug_str (terminate data for hash)
+ |------------|
+0x00003550: | 0x00001203 | String offset into .debug_str ("main")
+ | 0x00000009 | A 32-bit array count - number of HashData with name "main"
+ | 0x........ | HashData[0]
+ | 0x........ | HashData[1]
+ | 0x........ | HashData[2]
+ | 0x........ | HashData[3]
+ | 0x........ | HashData[4]
+ | 0x........ | HashData[5]
+ | 0x........ | HashData[6]
+ | 0x........ | HashData[7]
+ | 0x........ | HashData[8]
+ | 0x00000000 | String offset into .debug_str (terminate data for hash)
+ `------------'
+```
So we still have all of the same data, we just organize it more efficiently for
-debugger lookup. If we repeat the same "``printf``" lookup from above, we
-would hash "``printf``" and find it matches ``BUCKETS[3]`` by taking the 32-bit
-hash value and modulo it by ``n_buckets``. ``BUCKETS[3]`` contains "6" which
-is the index into the ``HASHES`` table. We would then compare any consecutive
-32-bit hash values in the ``HASHES`` array as long as the hashes would be in
-``BUCKETS[3]``. We do this by verifying that each subsequent hash value modulo
-``n_buckets`` is still 3. In the case of a failed lookup we would access the
-memory for ``BUCKETS[3]``, and then compare a few consecutive 32-bit hashes
+debugger lookup. If we repeat the same "`printf`" lookup from above, we
+would hash "`printf`" and find it matches `BUCKETS[3]` by taking the 32-bit
+hash value and modulo it by `n_buckets`. `BUCKETS[3]` contains "6" which
+is the index into the `HASHES` table. We would then compare any consecutive
+32-bit hash values in the `HASHES` array as long as the hashes would be in
+`BUCKETS[3]`. We do this by verifying that each subsequent hash value modulo
+`n_buckets` is still 3. In the case of a failed lookup we would access the
+memory for `BUCKETS[3]`, and then compare a few consecutive 32-bit hashes
before we know that we have no match. We don't end up marching through
multiple words of memory and we really keep the number of processor data cache
lines being accessed as small as possible.
The string hash that is used for these lookup tables is the Daniel J.
-Bernstein hash which is also used in the ELF ``GNU_HASH`` sections. It is a
+Bernstein hash which is also used in the ELF `GNU_HASH` sections. It is a
very good hash for all kinds of names in programs with very few hash
collisions.
-Empty buckets are designated by using an invalid hash index of ``UINT32_MAX``.
+Empty buckets are designated by using an invalid hash index of `UINT32_MAX`.
-Details
-^^^^^^^
+#### Details
These name hash tables are designed to be generic where specializations of the
-table get to define additional data that goes into the header ("``HeaderData``"),
-how the string value is stored ("``KeyType``") and the content of the data for each
+table get to define additional data that goes into the header ("`HeaderData`"),
+how the string value is stored ("`KeyType`") and the content of the data for each
hash value.
-Header Layout
-"""""""""""""
+##### Header Layout
The header has a fixed part, and the specialized part. The exact format of the
header is:
-.. code-block:: c
-
- struct Header
- {
- uint32_t magic; // 'HASH' magic value to allow endian detection
- uint16_t version; // Version number
- uint16_t hash_function; // The hash function enumeration that was used
- uint32_t bucket_count; // The number of buckets in this hash table
- uint32_t hashes_count; // The total number of unique hash values and hash data offsets in this table
- uint32_t header_data_len; // The bytes to skip to get to the hash indexes (buckets) for correct alignment
- // Specifically the length of the following HeaderData field - this does not
- // include the size of the preceding fields
- HeaderData header_data; // Implementation specific header data
- };
-
-The header starts with a 32-bit "``magic``" value which must be ``'HASH'``
+```c
+struct Header
+{
+ uint32_t magic; // 'HASH' magic value to allow endian detection
+ uint16_t version; // Version number
+ uint16_t hash_function; // The hash function enumeration that was used
+ uint32_t bucket_count; // The number of buckets in this hash table
+ uint32_t hashes_count; // The total number of unique hash values and hash data offsets in this table
+ uint32_t header_data_len; // The bytes to skip to get to the hash indexes (buckets) for correct alignment
+ // Specifically the length of the following HeaderData field - this does not
+ // include the size of the preceding fields
+ HeaderData header_data; // Implementation specific header data
+};
+```
+The header starts with a 32-bit "`magic`" value which must be `'HASH'`
encoded as an ASCII integer. This allows the detection of the start of the
hash table and also allows the table's byte order to be determined so the table
-can be correctly extracted. The "``magic``" value is followed by a 16-bit
-``version`` number which allows the table to be revised and modified in the
-future. The current version number is 1. ``hash_function`` is a ``uint16_t``
+can be correctly extracted. The "`magic`" value is followed by a 16-bit
+`version` number which allows the table to be revised and modified in the
+future. The current version number is 1. `hash_function` is a `uint16_t`
enumeration that specifies which hash function was used to produce this table.
The current values for the hash function enumerations include:
-.. code-block:: c
-
- enum HashFunctionType
- {
- eHashFunctionDJB = 0u, // Daniel J Bernstein hash function
- };
-
-``bucket_count`` is a 32-bit unsigned integer that represents how many buckets
-are in the ``BUCKETS`` array. ``hashes_count`` is the number of unique 32-bit
-hash values that are in the ``HASHES`` array, and is the same number of offsets
-are contained in the ``OFFSETS`` array. ``header_data_len`` specifies the size
-in bytes of the ``HeaderData`` that is filled in by specialized versions of
+```c
+enum HashFunctionType
+{
+ eHashFunctionDJB = 0u, // Daniel J Bernstein hash function
+};
+```
+`bucket_count` is a 32-bit unsigned integer that represents how many buckets
+are in the `BUCKETS` array. `hashes_count` is the number of unique 32-bit
+hash values that are in the `HASHES` array, and is the same number of offsets
+are contained in the `OFFSETS` array. `header_data_len` specifies the size
+in bytes of the `HeaderData` that is filled in by specialized versions of
this table.
-Fixed Lookup
-""""""""""""
+##### Fixed Lookup
The header is followed by the buckets, hashes, offsets, and hash value data.
-.. code-block:: c
-
- struct FixedTable
- {
- uint32_t buckets[Header.bucket_count]; // An array of hash indexes into the "hashes[]" array below
- uint32_t hashes [Header.hashes_count]; // Every unique 32-bit hash for the entire table is in this table
- uint32_t offsets[Header.hashes_count]; // An offset that corresponds to each item in the "hashes[]" array above
- };
-
-``buckets`` is an array of 32-bit indexes into the ``hashes`` array. The
-``hashes`` array contains all of the 32-bit hash values for all names in the
-hash table. Each hash in the ``hashes`` table has an offset in the ``offsets``
+```c
+struct FixedTable
+{
+ uint32_t buckets[Header.bucket_count]; // An array of hash indexes into the "hashes[]" array below
+ uint32_t hashes [Header.hashes_count]; // Every unique 32-bit hash for the entire table is in this table
+ uint32_t offsets[Header.hashes_count]; // An offset that corresponds to each item in the "hashes[]" array above
+};
+```
+`buckets` is an array of 32-bit indexes into the `hashes` array. The
+`hashes` array contains all of the 32-bit hash values for all names in the
+hash table. Each hash in the `hashes` table has an offset in the `offsets`
array that points to the data for the hash value.
This table setup makes it very easy to repurpose these tables to contain
@@ -2124,79 +1986,74 @@ able to store the data efficiently so we have used some of the DWARF features
that enable efficient data storage to define exactly what kind of data we store
for each name.
-The ``HeaderData`` contains a definition of the contents of each HashData chunk.
+The `HeaderData` contains a definition of the contents of each HashData chunk.
We might want to store an offset to all of the debug information entries (DIEs)
for each name. To keep things extensible, we create a list of items, or
Atoms, that are contained in the data for each name. First comes the type of
the data in each atom:
-.. code-block:: c
-
- enum AtomType
- {
- eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags
- };
-
+```c
+enum AtomType
+{
+ eAtomTypeNULL = 0u,
+ eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
+ eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
+ eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
+ eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
+ eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags
+};
+```
The enumeration values and their meanings are:
-.. code-block:: none
-
- eAtomTypeNULL - a termination atom that specifies the end of the atom list
- eAtomTypeDIEOffset - an offset into the .debug_info section for the DWARF DIE for this name
- eAtomTypeCUOffset - an offset into the .debug_info section for the CU that contains the DIE
- eAtomTypeDIETag - The DW_TAG_XXX enumeration value so you don't have to parse the DWARF to see what it is
- eAtomTypeNameFlags - Flags for functions and global variables (isFunction, isInlined, isExternal...)
- eAtomTypeTypeFlags - Flags for types (isCXXClass, isObjCClass, ...)
-
+```text
+eAtomTypeNULL - a termination atom that specifies the end of the atom list
+eAtomTypeDIEOffset - an offset into the .debug_info section for the DWARF DIE for this name
+eAtomTypeCUOffset - an offset into the .debug_info section for the CU that contains the DIE
+eAtomTypeDIETag - The DW_TAG_XXX enumeration value so you don't have to parse the DWARF to see what it is
+eAtomTypeNameFlags - Flags for functions and global variables (isFunction, isInlined, isExternal...)
+eAtomTypeTypeFlags - Flags for types (isCXXClass, isObjCClass, ...)
+```
Then we allow each atom type to define the atom type and how the data for each
atom type data is encoded:
-.. code-block:: c
-
- struct Atom
- {
- uint16_t type; // AtomType enum value
- uint16_t form; // DWARF DW_FORM_XXX defines
- };
-
-The ``form`` type above is from the DWARF specification and defines the exact
+```c
+struct Atom
+{
+ uint16_t type; // AtomType enum value
+ uint16_t form; // DWARF DW_FORM_XXX defines
+};
+```
+The `form` type above is from the DWARF specification and defines the exact
encoding of the data for the Atom type. See the DWARF specification for the
-``DW_FORM_`` definitions.
-
-.. code-block:: c
-
- struct HeaderData
- {
- uint32_t die_offset_base;
- uint32_t atom_count;
- Atoms atoms[atom_count0];
- };
-
-``HeaderData`` defines the base DIE offset that should be added to any atoms
-that are encoded using the ``DW_FORM_ref1``, ``DW_FORM_ref2``,
-``DW_FORM_ref4``, ``DW_FORM_ref8`` or ``DW_FORM_ref_udata``. It also defines
-what is contained in each ``HashData`` object -- ``Atom.form`` tells us how large
-each field will be in the ``HashData`` and the ``Atom.type`` tells us how this data
+`DW_FORM_` definitions.
+
+```c
+struct HeaderData
+{
+ uint32_t die_offset_base;
+ uint32_t atom_count;
+ Atoms atoms[atom_count0];
+};
+```
+`HeaderData` defines the base DIE offset that should be added to any atoms
+that are encoded using the `DW_FORM_ref1`, `DW_FORM_ref2`,
+`DW_FORM_ref4`, `DW_FORM_ref8` or `DW_FORM_ref_udata`. It also defines
+what is contained in each `HashData` object -- `Atom.form` tells us how large
+each field will be in the `HashData` and the `Atom.type` tells us how this data
should be interpreted.
-For the current implementations of the "``.apple_names``" (all functions +
-globals), the "``.apple_types``" (names of all types that are defined), and
-the "``.apple_namespaces``" (all namespaces), we currently set the ``Atom``
+For the current implementations of the "`.apple_names`" (all functions +
+globals), the "`.apple_types`" (names of all types that are defined), and
+the "`.apple_namespaces`" (all namespaces), we currently set the `Atom`
array to be:
-.. code-block:: c
-
- HeaderData.atom_count = 1;
- HeaderData.atoms[0].type = eAtomTypeDIEOffset;
- HeaderData.atoms[0].form = DW_FORM_data4;
-
-This defines the contents to be the DIE offset (``eAtomTypeDIEOffset``) that is
-encoded as a 32-bit value (``DW_FORM_data4``). This allows a single name to have
+```c
+HeaderData.atom_count = 1;
+HeaderData.atoms[0].type = eAtomTypeDIEOffset;
+HeaderData.atoms[0].form = DW_FORM_data4;
+```
+This defines the contents to be the DIE offset (`eAtomTypeDIEOffset`) that is
+encoded as a 32-bit value (`DW_FORM_data4`). This allows a single name to have
multiple matching DIEs in a single file, which could come up with an inlined
function for instance. Future tables could include more information about the
DIE such as flags indicating if the DIE is a function, method, block,
@@ -2207,89 +2064,84 @@ The KeyType for the DWARF table is a 32-bit string table offset into the
may already contain copies of all of the strings. This helps make sure, with
help from the compiler, that we reuse the strings between all of the DWARF
sections and keeps the hash table size down. Another benefit to having the
-compiler generate all strings as ``DW_FORM_strp`` in the debug info, is that
+compiler generate all strings as `DW_FORM_strp` in the debug info, is that
DWARF parsing can be made much faster.
After a lookup is made, we get an offset into the hash data. The hash data
needs to be able to deal with 32-bit hash collisions, so the chunk of data
at the offset in the hash data consists of a triple:
-.. code-block:: c
-
- uint32_t str_offset
- uint32_t hash_data_count
- HashData[hash_data_count]
-
+```c
+uint32_t str_offset
+uint32_t hash_data_count
+HashData[hash_data_count]
+```
If "str_offset" is zero, then the bucket contents are done. 99.9% of the
hash data chunks contain a single item (no 32-bit hash collision):
-.. code-block:: none
-
- .------------.
- | 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main")
- | 0x00000004 | uint32_t HashData count
- | 0x........ | uint32_t HashData[0] DIE offset
- | 0x........ | uint32_t HashData[1] DIE offset
- | 0x........ | uint32_t HashData[2] DIE offset
- | 0x........ | uint32_t HashData[3] DIE offset
- | 0x00000000 | uint32_t KeyType (end of hash chain)
- `------------'
-
+```text
+.------------.
+| 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main")
+| 0x00000004 | uint32_t HashData count
+| 0x........ | uint32_t HashData[0] DIE offset
+| 0x........ | uint32_t HashData[1] DIE offset
+| 0x........ | uint32_t HashData[2] DIE offset
+| 0x........ | uint32_t HashData[3] DIE offset
+| 0x00000000 | uint32_t KeyType (end of hash chain)
+`------------'
+```
If there are collisions, you will have multiple valid string offsets:
-.. code-block:: none
-
- .------------.
- | 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main")
- | 0x00000004 | uint32_t HashData count
- | 0x........ | uint32_t HashData[0] DIE offset
- | 0x........ | uint32_t HashData[1] DIE offset
- | 0x........ | uint32_t HashData[2] DIE offset
- | 0x........ | uint32_t HashData[3] DIE offset
- | 0x00002023 | uint32_t KeyType (.debug_str[0x0002023] => "print")
- | 0x00000002 | uint32_t HashData count
- | 0x........ | uint32_t HashData[0] DIE offset
- | 0x........ | uint32_t HashData[1] DIE offset
- | 0x00000000 | uint32_t KeyType (end of hash chain)
- `------------'
-
+```text
+.------------.
+| 0x00001023 | uint32_t KeyType (.debug_str[0x0001023] => "main")
+| 0x00000004 | uint32_t HashData count
+| 0x........ | uint32_t HashData[0] DIE offset
+| 0x........ | uint32_t HashData[1] DIE offset
+| 0x........ | uint32_t HashData[2] DIE offset
+| 0x........ | uint32_t HashData[3] DIE offset
+| 0x00002023 | uint32_t KeyType (.debug_str[0x0002023] => "print")
+| 0x00000002 | uint32_t HashData count
+| 0x........ | uint32_t HashData[0] DIE offset
+| 0x........ | uint32_t HashData[1] DIE offset
+| 0x00000000 | uint32_t KeyType (end of hash chain)
+`------------'
+```
Current testing with real world C++ binaries has shown that there is around 1
32-bit hash collision per 100,000 name entries.
-Contents
-^^^^^^^^
+#### Contents
As we said, we want to strictly define exactly what is included in the
-different tables. For DWARF, we have 3 tables: "``.apple_names``",
-"``.apple_types``", and "``.apple_namespaces``".
-
-"``.apple_names``" sections should contain an entry for each DWARF DIE whose
-``DW_TAG`` is a ``DW_TAG_label``, ``DW_TAG_inlined_subroutine``, or
-``DW_TAG_subprogram`` that has address attributes: ``DW_AT_low_pc``,
-``DW_AT_high_pc``, ``DW_AT_ranges`` or ``DW_AT_entry_pc``. It also contains
-``DW_TAG_variable`` DIEs that have a ``DW_OP_addr`` in the location (global and
+different tables. For DWARF, we have 3 tables: "`.apple_names`",
+"`.apple_types`", and "`.apple_namespaces`".
+
+"`.apple_names`" sections should contain an entry for each DWARF DIE whose
+`DW_TAG` is a `DW_TAG_label`, `DW_TAG_inlined_subroutine`, or
+`DW_TAG_subprogram` that has address attributes: `DW_AT_low_pc`,
+`DW_AT_high_pc`, `DW_AT_ranges` or `DW_AT_entry_pc`. It also contains
+`DW_TAG_variable` DIEs that have a `DW_OP_addr` in the location (global and
static variables). All global and static variables should be included,
including those scoped within functions and classes. For example using the
following code:
-.. code-block:: c
+```c
+static int var = 0;
+void f ()
+{
static int var = 0;
-
- void f ()
- {
- static int var = 0;
- }
-
-Both of the static ``var`` variables would be included in the table. All
+}
+```
+Both of the static `var` variables would be included in the table. All
functions should emit both their full names and their basenames. For C or C++,
the full name is the mangled name (if available) which is usually in the
-``DW_AT_MIPS_linkage_name`` attribute, and the ``DW_AT_name`` contains the
+`DW_AT_MIPS_linkage_name` attribute, and the `DW_AT_name` contains the
function basename. If global or static variables have a mangled name in a
-``DW_AT_MIPS_linkage_name`` attribute, this should be emitted along with the
-simple name found in the ``DW_AT_name`` attribute.
+`DW_AT_MIPS_linkage_name` attribute, this should be emitted along with the
+simple name found in the `DW_AT_name` attribute.
-"``.apple_types``" sections should contain an entry for each DWARF DIE whose
+"`.apple_types`" sections should contain an entry for each DWARF DIE whose
tag is one of:
* DW_TAG_array_type
@@ -2318,75 +2170,70 @@ tag is one of:
* DW_TAG_unspecified_type
* DW_TAG_shared_type
-Only entries with a ``DW_AT_name`` attribute are included, and the entry must
-not be a forward declaration (``DW_AT_declaration`` attribute with a non-zero
+Only entries with a `DW_AT_name` attribute are included, and the entry must
+not be a forward declaration (`DW_AT_declaration` attribute with a non-zero
value). For example, using the following code:
-.. code-block:: c
-
- int main ()
- {
- int *b = 0;
- return *b;
- }
-
+```c
+int main ()
+{
+ int *b = 0;
+ return *b;
+}
+```
We get a few type DIEs:
-.. code-block:: none
-
- 0x00000067: TAG_base_type [5]
- AT_encoding( DW_ATE_signed )
- AT_name( "int" )
- AT_byte_size( 0x04 )
-
- 0x0000006e: TAG_pointer_type [6]
- AT_type( {0x00000067} ( int ) )
- AT_byte_size( 0x08 )
+```text
+0x00000067: TAG_base_type [5]
+ AT_encoding( DW_ATE_signed )
+ AT_name( "int" )
+ AT_byte_size( 0x04 )
-The ``DW_TAG_pointer_type`` is not included because it does not have a ``DW_AT_name``.
+0x0000006e: TAG_pointer_type [6]
+ AT_type( {0x00000067} ( int ) )
+ AT_byte_size( 0x08 )
+```
+The `DW_TAG_pointer_type` is not included because it does not have a `DW_AT_name`.
-"``.apple_namespaces``" section should contain all ``DW_TAG_namespace`` DIEs.
+"`.apple_namespaces`" section should contain all `DW_TAG_namespace` DIEs.
If we run into a namespace that has no name this is an anonymous namespace, and
-the name should be output as "``(anonymous namespace)``" (without the quotes).
-Why? This matches the output of the ``abi::cxa_demangle()`` that is in the
+the name should be output as "`(anonymous namespace)`" (without the quotes).
+Why? This matches the output of the `abi::cxa_demangle()` that is in the
standard C++ library that demangles mangled names.
-Language Extensions and File Format Changes
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Language Extensions and File Format Changes
-.. _llvm_language_dialect:
+(llvm_language_dialect)=
-LLVM Language Dialect
-"""""""""""""""""""""
+##### LLVM Language Dialect
-LLVM emits an optional ``DW_AT_LLVM_language_dialect`` attribute on
-``DW_TAG_compile_unit`` to identify an execution-model dialect of the
-source-level language declared by ``DW_AT_language`` /
-``DW_AT_LLVM_source_language_name``.
+LLVM emits an optional `DW_AT_LLVM_language_dialect` attribute on
+`DW_TAG_compile_unit` to identify an execution-model dialect of the
+source-level language declared by `DW_AT_language` /
+`DW_AT_LLVM_source_language_name`.
The attribute value is encoded as an unsigned integer from the
-``DW_LLVM_LANG_DIALECT_*`` enumeration:
+`DW_LLVM_LANG_DIALECT_*` enumeration:
-* ``DW_LLVM_LANG_DIALECT_simt`` (``0x01``) -- single-instruction,
+* `DW_LLVM_LANG_DIALECT_simt` (`0x01`) -- single-instruction,
multiple-thread execution model.
-* ``DW_LLVM_LANG_DIALECT_tile`` (``0x02``) -- tile-based execution model.
+* `DW_LLVM_LANG_DIALECT_tile` (`0x02`) -- tile-based execution model.
-To express "no dialect specified", the ``dialect:`` field on
-:ref:`DICompileUnit <DICompileUnit>` is simply omitted; no
-``DW_AT_LLVM_language_dialect`` attribute is emitted in that case.
+To express "no dialect specified", the `dialect:` field on
+{ref}`DICompileUnit <DICompileUnit>` is simply omitted; no
+`DW_AT_LLVM_language_dialect` attribute is emitted in that case.
-Objective-C Extensions
-""""""""""""""""""""""
+##### Objective-C Extensions
-"``.apple_objc``" section should contain all ``DW_TAG_subprogram`` DIEs for an
+"`.apple_objc`" section should contain all `DW_TAG_subprogram` DIEs for an
Objective-C class. The name used in the hash table is the name of the
Objective-C class itself. If the Objective-C class has a category, then an
entry is made for both the class name without the category, and for the class
name with the category. So if we have a DIE at offset 0x1234 with a name of
-method "``-[NSString(my_additions) stringWithSpecialString:]``", we would add
-an entry for "``NSString``" that points to DIE 0x1234, and an entry for
-"``NSString(my_additions)``" that points to 0x1234. This allows us to quickly
+method "`-[NSString(my_additions) stringWithSpecialString:]`", we would add
+an entry for "`NSString`" that points to DIE 0x1234, and an entry for
+"`NSString(my_additions)`" that points to 0x1234. This allows us to quickly
track down all Objective-C methods for an Objective-C class when doing
expressions. It is needed because of the dynamic nature of Objective-C where
anyone can add methods to a class. The DWARF for Objective-C methods is also
@@ -2398,35 +2245,32 @@ given the Objective-C class name, or quickly find all methods and class
functions for a class + category name. This table does not contain any
selector names, it just maps Objective-C class names (or class names +
category) to all of the methods and class functions. The selectors are added
-as function basenames in the "``.debug_names``" section.
+as function basenames in the "`.debug_names`" section.
-In the "``.apple_names``" section for Objective-C functions, the full name is
-the entire function name with the brackets ("``-[NSString
-stringWithCString:]``") and the basename is the selector only
-("``stringWithCString:``").
+In the "`.apple_names`" section for Objective-C functions, the full name is
+the entire function name with the brackets ("`-[NSString
+stringWithCString:]`") and the basename is the selector only
+("`stringWithCString:`").
-Mach-O Changes
-""""""""""""""
+##### Mach-O Changes
The sections names for the apple hash tables are for non-mach-o files. For
-mach-o files, the sections should be contained in the ``__DWARF`` segment with
+mach-o files, the sections should be contained in the `__DWARF` segment with
names as follows:
-* "``.apple_names``" -> "``__apple_names``"
-* "``.apple_types``" -> "``__apple_types``"
-* "``.apple_namespaces``" -> "``__apple_namespac``" (16 character limit)
-* "``.apple_objc``" -> "``__apple_objc``"
+* "`.apple_names`" -> "`__apple_names`"
+* "`.apple_types`" -> "`__apple_types`"
+* "`.apple_namespaces`" -> "`__apple_namespac`" (16 character limit)
+* "`.apple_objc`" -> "`__apple_objc`"
-.. _codeview:
+(codeview)=
-CodeView Debug Info Format
-==========================
+## CodeView Debug Info Format
LLVM supports emitting CodeView, the Microsoft debug info format, and this
section describes the design and implementation of that support.
-Format Background
------------------
+### Format Background
CodeView as a format is clearly oriented around C++ debugging, and in C++, the
majority of debug information tends to be type information. Therefore, the
@@ -2436,19 +2280,19 @@ merged across translation units. Both type information and symbol information is
generally stored as a sequence of records, where each record begins with a
16-bit record size and a 16-bit record kind.
-Type information is usually stored in the ``.debug$T`` section of the object
+Type information is usually stored in the `.debug$T` section of the object
file. All other debug info, such as line info, string table, symbol info, and
-inlinee info, is stored in one or more ``.debug$S`` sections. There may only be
-one ``.debug$T`` section per object file, since all other debug info refers to
-it. If a PDB (enabled by the ``/Zi`` MSVC option) was used during compilation,
-the ``.debug$T`` section will contain only an ``LF_TYPESERVER2`` record pointing
+inlinee info, is stored in one or more `.debug$S` sections. There may only be
+one `.debug$T` section per object file, since all other debug info refers to
+it. If a PDB (enabled by the `/Zi` MSVC option) was used during compilation,
+the `.debug$T` section will contain only an `LF_TYPESERVER2` record pointing
to the PDB. When using PDBs, symbol information appears to remain in the object
-file ``.debug$S`` sections.
+file `.debug$S` sections.
Type records are referred to by their index, which is the number of records in
-the stream before a given record plus ``0x1000``. Many common basic types, such
+the stream before a given record plus `0x1000`. Many common basic types, such
as the basic integral types and unqualified pointers to them, are represented
-using type indices less than ``0x1000``. Such basic types are built in to
+using type indices less than `0x1000`. Such basic types are built in to
CodeView consumers and do not require type records.
Each type record may only contain type indices that are less than its own type
@@ -2456,31 +2300,36 @@ index. This ensures that the graph of type stream references is acyclic. While
the source-level type graph may contain cycles through pointer types (consider a
linked list struct), these cycles are removed from the type stream by always
referring to the forward declaration record of user-defined record types. Only
-"symbol" records in the ``.debug$S`` streams may refer to complete,
+"symbol" records in the `.debug$S` streams may refer to complete,
non-forward-declaration type records.
-Working with CodeView
----------------------
+### Working with CodeView
These are instructions for some common tasks for developers working to improve
LLVM's CodeView support. Most of them revolve around using the CodeView dumper
-embedded in ``llvm-readobj``.
+embedded in `llvm-readobj`.
-* Testing MSVC's output::
+* Testing MSVC's output:
- $ cl -c -Z7 foo.cpp # Use /Z7 to keep types in the object file
- $ llvm-readobj --codeview foo.obj
+ ```console
+ $ cl -c -Z7 foo.cpp # Use /Z7 to keep types in the object file
+ $ llvm-readobj --codeview foo.obj
+ ```
-* Getting LLVM IR debug info out of Clang::
+* Getting LLVM IR debug info out of Clang:
- $ clang -g -gcodeview --target=x86_64-windows-msvc foo.cpp -S -emit-llvm
+ ```console
+ $ clang -g -gcodeview --target=x86_64-windows-msvc foo.cpp -S -emit-llvm
+ ```
Use this to generate LLVM IR for LLVM test cases.
-* Generate and dump CodeView from LLVM IR metadata::
+* Generate and dump CodeView from LLVM IR metadata:
- $ llc foo.ll -filetype=obj -o foo.obj
- $ llvm-readobj --codeview foo.obj > foo.txt
+ ```console
+ $ llc foo.ll -filetype=obj -o foo.obj
+ $ llvm-readobj --codeview foo.obj > foo.txt
+ ```
Use this pattern in lit test cases and FileCheck the output of llvm-readobj
diff --git a/llvm/docs/TableGen/index.md b/llvm/docs/TableGen/index.md
index 0f1190c54627a..a85fdf3f39766 100644
--- a/llvm/docs/TableGen/index.md
+++ b/llvm/docs/TableGen/index.md
@@ -1,19 +1,18 @@
-=================
-TableGen Overview
-=================
+# TableGen Overview
-.. contents::
- :local:
+```{contents}
+:local:
+```
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- BackEnds
- BackGuide
- ProgRef
+BackEnds
+BackGuide
+ProgRef
+```
-Introduction
-============
+## Introduction
TableGen's purpose is to help a human develop and maintain records of
domain-specific information. Because there may be a large number of these
@@ -23,141 +22,140 @@ amount of duplication in the description, reduces the chance of error, and makes
it easier to structure domain-specific information.
The TableGen front end parses a file, instantiates the declarations, and
-hands the result off to a domain-specific `backend`_ for processing. See
-the :doc:`TableGen Programmer's Reference <./ProgRef>` for an in-depth
-description of TableGen. See :doc:`tblgen - Description to C++ Code
-<../CommandGuide/tblgen>` for details on the ``*-tblgen`` commands
-that run the various flavors of TableGen.
+hands the result off to a domain-specific {ref}`backend <backend>` for processing. See
+the {doc}`TableGen Programmer's Reference <./ProgRef>` for an in-depth
+description of TableGen. See
+{doc}`tblgen - Description to C++ Code <../CommandGuide/tblgen>` for details on the
+`*-tblgen` commands that run the various flavors of TableGen.
-The current major users of TableGen are :doc:`The LLVM Target-Independent
-Code Generator <../CodeGenerator>` and the `Clang diagnostics and attributes
-<https://clang.llvm.org/docs/UsersManual.html#controlling-errors-and-warnings>`_.
+The current major users of TableGen are
+{doc}`The LLVM Target-Independent Code Generator <../CodeGenerator>` and the
+[Clang diagnostics and attributes][clang-diagnostics-and-attributes].
+
+[clang-diagnostics-and-attributes]: https://clang.llvm.org/docs/UsersManual.html#controlling-errors-and-warnings
Note that if you work with TableGen frequently and use emacs or vim,
you can find an emacs "TableGen mode" and a vim language file in the
-``llvm/utils/emacs`` and ``llvm/utils/vim`` directories of your LLVM
+`llvm/utils/emacs` and `llvm/utils/vim` directories of your LLVM
distribution, respectively.
-.. _intro:
+(intro)=
-The TableGen program
-====================
+## The TableGen program
-TableGen files are interpreted by the TableGen program: ``llvm-tblgen`` available
-in your build directory under ``bin``. It is not installed in the system (or where
+TableGen files are interpreted by the TableGen program: `llvm-tblgen` available
+in your build directory under `bin`. It is not installed in the system (or where
your sysroot is set to), since it has no use beyond LLVM's build process.
-Running TableGen
-----------------
+### Running TableGen
TableGen runs just like any other LLVM tool. The first (optional) argument
-specifies the file to read. If a filename is not specified, ``llvm-tblgen``
+specifies the file to read. If a filename is not specified, `llvm-tblgen`
reads from standard input.
-The ``-o`` option specifies the output file or ``-`` to output to
+The `-o` option specifies the output file or `-` to output to
stdout. Where TableGen produces multiple output files, the option
specifies the name of the main output file, which also works as the
name prefix for other output files.
-To be useful, one of the `backends`_ must be used. These backends are
-selectable on the command line (type '``llvm-tblgen -help``' for a list). For
+To be useful, one of the {ref}`backends <backends>` must be used. These backends are
+selectable on the command line (type '`llvm-tblgen -help`' for a list). For
example, to get a list of all of the definitions that subclass a particular type
(which can be useful for building up an enum list of these records), use the
-``-print-enums`` option:
-
-.. code-block:: bash
-
- $ llvm-tblgen X86.td -print-enums -class=Register
- AH, AL, AX, BH, BL, BP, BPL, BX, CH, CL, CX, DH, DI, DIL, DL, DX, EAX, EBP, EBX,
- ECX, EDI, EDX, EFLAGS, EIP, ESI, ESP, FP0, FP1, FP2, FP3, FP4, FP5, FP6, IP,
- MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, R10, R10B, R10D, R10W, R11, R11B, R11D,
- R11W, R12, R12B, R12D, R12W, R13, R13B, R13D, R13W, R14, R14B, R14D, R14W, R15,
- R15B, R15D, R15W, R8, R8B, R8D, R8W, R9, R9B, R9D, R9W, RAX, RBP, RBX, RCX, RDI,
- RDX, RIP, RSI, RSP, SI, SIL, SP, SPL, ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
- XMM0, XMM1, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5,
- XMM6, XMM7, XMM8, XMM9,
-
- $ llvm-tblgen X86.td -print-enums -class=Instruction
- ABS_F, ABS_Fp32, ABS_Fp64, ABS_Fp80, ADC32mi, ADC32mi8, ADC32mr, ADC32ri,
- ADC32ri8, ADC32rm, ADC32rr, ADC64mi32, ADC64mi8, ADC64mr, ADC64ri32, ADC64ri8,
- ADC64rm, ADC64rr, ADD16mi, ADD16mi8, ADD16mr, ADD16ri, ADD16ri8, ADD16rm,
- ADD16rr, ADD32mi, ADD32mi8, ADD32mr, ADD32ri, ADD32ri8, ADD32rm, ADD32rr,
- ADD64mi32, ADD64mi8, ADD64mr, ADD64ri32, ...
+`-print-enums` option:
+
+```console
+$ llvm-tblgen X86.td -print-enums -class=Register
+AH, AL, AX, BH, BL, BP, BPL, BX, CH, CL, CX, DH, DI, DIL, DL, DX, EAX, EBP, EBX,
+ECX, EDI, EDX, EFLAGS, EIP, ESI, ESP, FP0, FP1, FP2, FP3, FP4, FP5, FP6, IP,
+MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, R10, R10B, R10D, R10W, R11, R11B, R11D,
+R11W, R12, R12B, R12D, R12W, R13, R13B, R13D, R13W, R14, R14B, R14D, R14W, R15,
+R15B, R15D, R15W, R8, R8B, R8D, R8W, R9, R9B, R9D, R9W, RAX, RBP, RBX, RCX, RDI,
+RDX, RIP, RSI, RSP, SI, SIL, SP, SPL, ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
+XMM0, XMM1, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5,
+XMM6, XMM7, XMM8, XMM9,
+
+$ llvm-tblgen X86.td -print-enums -class=Instruction
+ABS_F, ABS_Fp32, ABS_Fp64, ABS_Fp80, ADC32mi, ADC32mi8, ADC32mr, ADC32ri,
+ADC32ri8, ADC32rm, ADC32rr, ADC64mi32, ADC64mi8, ADC64mr, ADC64ri32, ADC64ri8,
+ADC64rm, ADC64rr, ADD16mi, ADD16mi8, ADD16mr, ADD16ri, ADD16ri8, ADD16rm,
+ADD16rr, ADD32mi, ADD32mi8, ADD32mr, ADD32ri, ADD32ri8, ADD32rm, ADD32rr,
+ADD64mi32, ADD64mi8, ADD64mr, ADD64ri32, ...
+```
The default backend prints out all of the records. There is also a general
backend which outputs all the records as a JSON data structure, enabled using
the `-dump-json` option.
-If you plan to use TableGen, you will most likely have to write a `backend`_
+If you plan to use TableGen, you will most likely have to write a {ref}`backend <backend>`
that extracts the information specific to what you need and formats it in the
appropriate way. You can do this by extending TableGen itself in C++ or by
writing a script in any language that can consume the JSON output.
-Example
--------
+### Example
With no other arguments, `llvm-tblgen` parses the specified file and prints out all
of the classes, then all of the definitions. This is a good way to see what the
-various definitions expand to fully. Running this on the ``X86.td`` file prints
+various definitions expand to fully. Running this on the `X86.td` file prints
this (at the time of this writing):
-.. code-block:: text
-
- ...
- def ADD32rr { // Instruction X86Inst I
- string Namespace = "X86";
- dag OutOperandList = (outs GR32:$dst);
- dag InOperandList = (ins GR32:$src1, GR32:$src2);
- string AsmString = "add{l}\t{$src2, $dst|$dst, $src2}";
- list<dag> Pattern = [(set GR32:$dst, (add GR32:$src1, GR32:$src2))];
- list<Register> Uses = [];
- list<Register> Defs = [EFLAGS];
- list<Predicate> Predicates = [];
- int CodeSize = 3;
- int AddedComplexity = 0;
- bit isReturn = 0;
- bit isBranch = 0;
- bit isIndirectBranch = 0;
- bit isBarrier = 0;
- bit isCall = 0;
- bit canFoldAsLoad = 0;
- bit mayLoad = 0;
- bit mayStore = 0;
- bit isImplicitDef = 0;
- bit isConvertibleToThreeAddress = 1;
- bit isCommutable = 1;
- bit isTerminator = 0;
- bit isReMaterializable = 0;
- bit isPredicable = 0;
- bit hasDelaySlot = 0;
- bit usesCustomInserter = 0;
- bit hasCtrlDep = 0;
- bit isNotDuplicable = 0;
- bit hasSideEffects = 0;
- InstrItinClass Itinerary = NoItinerary;
- string Constraints = "";
- string DisableEncoding = "";
- bits<8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 1 };
- Format Form = MRMDestReg;
- bits<6> FormBits = { 0, 0, 0, 0, 1, 1 };
- ImmType ImmT = NoImm;
- bits<3> ImmTypeBits = { 0, 0, 0 };
- bit hasOpSizePrefix = 0;
- bit hasAdSizePrefix = 0;
- bits<4> Prefix = { 0, 0, 0, 0 };
- bit hasREX_WPrefix = 0;
- FPFormat FPForm = ?;
- bits<3> FPFormBits = { 0, 0, 0 };
- }
- ...
-
-This definition corresponds to the 32-bit register-register ``add`` instruction
-of the x86 architecture. ``def ADD32rr`` defines a record named
-``ADD32rr``, and the comment at the end of the line indicates the superclasses
+```text
+...
+def ADD32rr { // Instruction X86Inst I
+ string Namespace = "X86";
+ dag OutOperandList = (outs GR32:$dst);
+ dag InOperandList = (ins GR32:$src1, GR32:$src2);
+ string AsmString = "add{l}\t{$src2, $dst|$dst, $src2}";
+ list<dag> Pattern = [(set GR32:$dst, (add GR32:$src1, GR32:$src2))];
+ list<Register> Uses = [];
+ list<Register> Defs = [EFLAGS];
+ list<Predicate> Predicates = [];
+ int CodeSize = 3;
+ int AddedComplexity = 0;
+ bit isReturn = 0;
+ bit isBranch = 0;
+ bit isIndirectBranch = 0;
+ bit isBarrier = 0;
+ bit isCall = 0;
+ bit canFoldAsLoad = 0;
+ bit mayLoad = 0;
+ bit mayStore = 0;
+ bit isImplicitDef = 0;
+ bit isConvertibleToThreeAddress = 1;
+ bit isCommutable = 1;
+ bit isTerminator = 0;
+ bit isReMaterializable = 0;
+ bit isPredicable = 0;
+ bit hasDelaySlot = 0;
+ bit usesCustomInserter = 0;
+ bit hasCtrlDep = 0;
+ bit isNotDuplicable = 0;
+ bit hasSideEffects = 0;
+ InstrItinClass Itinerary = NoItinerary;
+ string Constraints = "";
+ string DisableEncoding = "";
+ bits<8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 1 };
+ Format Form = MRMDestReg;
+ bits<6> FormBits = { 0, 0, 0, 0, 1, 1 };
+ ImmType ImmT = NoImm;
+ bits<3> ImmTypeBits = { 0, 0, 0 };
+ bit hasOpSizePrefix = 0;
+ bit hasAdSizePrefix = 0;
+ bits<4> Prefix = { 0, 0, 0, 0 };
+ bit hasREX_WPrefix = 0;
+ FPFormat FPForm = ?;
+ bits<3> FPFormBits = { 0, 0, 0 };
+}
+...
+```
+
+This definition corresponds to the 32-bit register-register `add` instruction
+of the x86 architecture. `def ADD32rr` defines a record named
+`ADD32rr`, and the comment at the end of the line indicates the superclasses
of the definition. The body of the record contains all of the data that
TableGen assembled for the record, indicating that the instruction is part of
-the ``X86`` namespace, the pattern indicating how the instruction is selected by
+the `X86` namespace, the pattern indicating how the instruction is selected by
the code generator, that it is a two-address instruction, has a particular
encoding, etc. The contents and semantics of the information in the record are
specific to the needs of the X86 backend, and are only shown as an example.
@@ -167,31 +165,29 @@ by the code generator, and specifying it all manually would be unmaintainable,
prone to bugs, and tiring to do in the first place. Because we are using
TableGen, all of the information was derived from the following definition:
-.. code-block:: text
-
- let Defs = [EFLAGS],
- isCommutable = 1, // X = ADD Y,Z --> X = ADD Z,Y
- isConvertibleToThreeAddress = 1 in // Can transform into LEA.
- def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst),
- (ins GR32:$src1, GR32:$src2),
- "add{l}\t{$src2, $dst|$dst, $src2}",
- [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
-
-This definition makes use of the custom class ``I`` (extended from the custom
-class ``X86Inst``), which is defined in the X86-specific TableGen file, to
+```text
+let Defs = [EFLAGS],
+ isCommutable = 1, // X = ADD Y,Z --> X = ADD Z,Y
+ isConvertibleToThreeAddress = 1 in // Can transform into LEA.
+def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst),
+ (ins GR32:$src1, GR32:$src2),
+ "add{l}\t{$src2, $dst|$dst, $src2}",
+ [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
+```
+
+This definition makes use of the custom class `I` (extended from the custom
+class `X86Inst`), which is defined in the X86-specific TableGen file, to
factor out the common features that instructions of its class share. A key
feature of TableGen is that it allows the end user to define the abstractions
they prefer to use when describing their information.
-Syntax
-======
+## Syntax
TableGen has a syntax loosely based on C++ templates, with built-in
types and specification. In addition, TableGen's syntax introduces some
automation concepts like multiclass, foreach, let, etc.
-Basic concepts
---------------
+### Basic concepts
TableGen files consist of two key parts: 'classes' and 'definitions', both of
which are considered 'records'.
@@ -199,40 +195,40 @@ which are considered 'records'.
**TableGen records** have a unique name, a list of values, and a list of
superclasses. The list of values is the main data that TableGen builds for each
record; it is this that holds the domain-specific information for the
-application. The interpretation of this data is left to a specific `backend`_,
+application. The interpretation of this data is left to a specific {ref}`backend <backend>`,
but the structure and format rules are taken care of and fixed by
TableGen.
**TableGen definitions** are the concrete form of 'records'. These generally do
-not have any undefined values and are marked with the '``def``' keyword.
+not have any undefined values and are marked with the '`def`' keyword.
-.. code-block:: text
+```text
+def FeatureFPARMv8 : SubtargetFeature<"fp-armv8", "HasFPARMv8", "true",
+ "Enable ARMv8 FP">;
+```
- def FeatureFPARMv8 : SubtargetFeature<"fp-armv8", "HasFPARMv8", "true",
- "Enable ARMv8 FP">;
-
-In this example, ``FeatureFPARMv8`` is ``SubtargetFeature`` record initialised
+In this example, `FeatureFPARMv8` is `SubtargetFeature` record initialised
with some values. The names of the classes are defined via the
keyword `class` either in the same file or some other included. Most target
-TableGen files include the generic ones in ``include/llvm/Target``.
+TableGen files include the generic ones in `include/llvm/Target`.
**TableGen classes** are abstract records that are used to build and describe
other records. These classes allow the end-user to build abstractions for
-either the domain they are targeting (such as ``Register``, ``RegisterClass``, and
-``Instruction`` in the LLVM code generator) or for the implementor to help factor
-out common properties of records (such as ``FPInst``, which is used to represent
+either the domain they are targeting (such as `Register`, `RegisterClass`, and
+`Instruction` in the LLVM code generator) or for the implementor to help factor
+out common properties of records (such as `FPInst`, which is used to represent
floating point instructions in the X86 backend). TableGen keeps track of all of
the classes that are used to build up a definition, so the backend can find all
-definitions of a particular class, such as ``Instruction``.
-
-.. code-block:: text
+definitions of a particular class, such as `Instruction`.
- class ProcNoItin<string Name, list<SubtargetFeature> Features>
- : Processor<Name, NoItineraries, Features>;
+```text
+class ProcNoItin<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+```
-Here, the class ``ProcNoItin``, receiving parameters ``Name`` of type ``string`` and
-a list of target features is specializing the class ``Processor`` by passing the
-arguments down as well as hard-coding ``NoItineraries``.
+Here, the class `ProcNoItin`, receiving parameters `Name` of type `string` and
+a list of target features is specializing the class `Processor` by passing the
+arguments down as well as hard-coding `NoItineraries`.
**TableGen multiclasses** are groups of abstract records that are instantiated
all at once. Each instantiation can result in multiple TableGen definitions.
@@ -240,36 +236,35 @@ If a multiclass inherits from another multiclass, the definitions in the
sub-multiclass become part of the current multiclass, as if they were declared
in the current multiclass.
-.. code-block:: text
-
- multiclass ro_signed_pats<string T, string Rm, dag Base, dag Offset, dag Extend,
- dag address, ValueType sty> {
- def : Pat<(i32 (!cast<SDNode>("sextload" # sty) address)),
- (!cast<Instruction>("LDRS" # T # "w_" # Rm # "_RegOffset")
- Base, Offset, Extend)>;
-
- def : Pat<(i64 (!cast<SDNode>("sextload" # sty) address)),
- (!cast<Instruction>("LDRS" # T # "x_" # Rm # "_RegOffset")
- Base, Offset, Extend)>;
- }
-
- defm : ro_signed_pats<"B", Rm, Base, Offset, Extend,
- !foreach(decls.pattern, address,
- !subst(SHIFT, imm_eq0, decls.pattern)),
- i8>;
-
-See the :doc:`TableGen Programmer's Reference <./ProgRef>` for an in-depth
+```text
+multiclass ro_signed_pats<string T, string Rm, dag Base, dag Offset, dag Extend,
+ dag address, ValueType sty> {
+def : Pat<(i32 (!cast<SDNode>("sextload" # sty) address)),
+ (!cast<Instruction>("LDRS" # T # "w_" # Rm # "_RegOffset")
+ Base, Offset, Extend)>;
+
+def : Pat<(i64 (!cast<SDNode>("sextload" # sty) address)),
+ (!cast<Instruction>("LDRS" # T # "x_" # Rm # "_RegOffset")
+ Base, Offset, Extend)>;
+}
+
+defm : ro_signed_pats<"B", Rm, Base, Offset, Extend,
+ !foreach(decls.pattern, address,
+ !subst(SHIFT, imm_eq0, decls.pattern)),
+ i8>;
+```
+
+See the {doc}`TableGen Programmer's Reference <./ProgRef>` for an in-depth
description of TableGen.
-.. _backend:
-.. _backends:
+(backend)=
+(backends)=
-TableGen backends
-=================
+## TableGen backends
TableGen files have no real meaning without a backend. The default operation
-when running ``*-tblgen`` is to print the information in a textual format, but
+when running `*-tblgen` is to print the information in a textual format, but
that's only useful for debugging the TableGen files themselves. The power
in TableGen is, however, to interpret the source files into an internal
representation that can be generated into anything you want.
@@ -284,19 +279,17 @@ Pre-processed output should be used if the same information needs to be used
in different contexts (like Instruction names), so your backend should print
a meta-information list that can be shaped into different compile-time formats.
-See :doc:`TableGen BackEnds <./BackEnds>` for a list of available
-backends, and see the :doc:`TableGen Backend Developer's Guide <./BackGuide>`
+See {doc}`TableGen BackEnds <./BackEnds>` for a list of available
+backends, and see the {doc}`TableGen Backend Developer's Guide <./BackGuide>`
for information on how to write and debug a new backend.
-Tools and Resources
-===================
+## Tools and Resources
In addition to this documentation, a list of tools and resources for TableGen
can be found in TableGen's
-`README <https://github.com/llvm/llvm-project/blob/main/llvm/utils/TableGen/README.md>`_.
+[README](https://github.com/llvm/llvm-project/blob/main/llvm/utils/TableGen/README.md).
-TableGen Deficiencies
-=====================
+## TableGen Deficiencies
Despite being very generic, TableGen has some deficiencies that have been
pointed out numerous times. The common theme is that, while TableGen allows
diff --git a/llvm/docs/TestingGuide.md b/llvm/docs/TestingGuide.md
index 9a53838f7172c..4be8ce289ef8f 100644
--- a/llvm/docs/TestingGuide.md
+++ b/llvm/docs/TestingGuide.md
@@ -1,83 +1,82 @@
-=================================
-LLVM Testing Infrastructure Guide
-=================================
+---
+myst:
+ enable_extensions:
+ - deflist
+---
-.. contents::
- :local:
+# LLVM Testing Infrastructure Guide
-.. toctree::
- :hidden:
+```{contents}
+:local:
+```
- TestSuiteGuide
+```{toctree}
+:hidden:
-Overview
-========
+TestSuiteGuide
+```
+
+## Overview
This document is the reference manual for the LLVM testing
infrastructure. It documents the structure of the LLVM testing
infrastructure, the tools needed to use it, and how to add and run
tests.
-Requirements
-============
+## Requirements
In order to use the LLVM testing infrastructure, you will need all of the
-software required to build LLVM, as well as `Python <http://python.org>`_ 3.8 or
+software required to build LLVM, as well as [Python](http://python.org) 3.8 or
later.
-LLVM Testing Infrastructure Organization
-========================================
+## LLVM Testing Infrastructure Organization
The LLVM testing infrastructure contains three major categories of tests:
unit tests, regression tests, and whole programs. The unit tests and regression
-tests are contained inside the LLVM repository itself under ``llvm/unittests``
-and ``llvm/test`` respectively and are expected to always pass. They should be
+tests are contained inside the LLVM repository itself under `llvm/unittests`
+and `llvm/test` respectively and are expected to always pass. They should be
run before every commit.
The whole-program tests are referred to as the "LLVM test suite" (or
-"test-suite") and are in the ``test-suite``
-`repository on GitHub <https://github.com/llvm/llvm-test-suite.git>`_.
+"test-suite") and are in the `test-suite`
+[repository on GitHub](https://github.com/llvm/llvm-test-suite.git).
For historical reasons, these tests are also referred to as the "nightly
tests" in places, which is less ambiguous than "test-suite" and remains
in use although we run them much more often than nightly.
-Unit tests
-----------
+### Unit tests
-Unit tests are written using `Google Test <https://github.com/google/googletest/blob/master/docs/primer.md>`_
-and `Google Mock <https://github.com/google/googletest/blob/master/docs/gmock_for_dummies.md>`_
-and are located in the ``llvm/unittests`` directory.
+Unit tests are written using [Google Test](https://github.com/google/googletest/blob/master/docs/primer.md)
+and [Google Mock](https://github.com/google/googletest/blob/master/docs/gmock_for_dummies.md)
+and are located in the `llvm/unittests` directory.
In general, unit tests are reserved for targeting the support library and other
generic data structure. We prefer relying on regression tests for testing
transformations and analysis on the IR.
-Regression tests
-----------------
+### Regression tests
The regression tests are small pieces of code that test a specific
feature of LLVM or trigger a specific bug in LLVM. The language they are
written in depends on the part of LLVM being tested. These tests are driven by
-the :doc:`Lit <CommandGuide/lit>` testing tool (which is part of LLVM), and
-are located in the ``llvm/test`` directory.
+the {doc}`Lit <CommandGuide/lit>` testing tool (which is part of LLVM), and
+are located in the `llvm/test` directory.
Typically, when a bug is found in LLVM, a regression test containing just
enough code to reproduce the problem should be written and placed
somewhere underneath this directory. For example, it can be a small
piece of LLVM IR distilled from an actual application or benchmark.
-Testing Analysis
-----------------
+### Testing Analysis
An analysis is a pass to infer properties on some part of the IR without
transforming it. They are tested in general using the same infrastructure as the
regression tests, by creating a separate "Printer" pass to consume the analysis
result and print it on the standard output in a textual format suitable for
FileCheck.
-See `llvm/test/Analysis/BranchProbabilityInfo/loop.ll <https://github.com/llvm/llvm-project/blob/main/llvm/test/Analysis/BranchProbabilityInfo/loop.ll>`_
+See [llvm/test/Analysis/BranchProbabilityInfo/loop.ll](https://github.com/llvm/llvm-project/blob/main/llvm/test/Analysis/BranchProbabilityInfo/loop.ll)
for an example of such test.
-``test-suite``
---------------
+### `test-suite`
The test suite contains whole programs, which are pieces of code which
can be compiled and linked into a stand-alone program that can be
@@ -94,244 +93,237 @@ serve as a way of benchmarking LLVM performance, both in terms of the
efficiency of the programs generated as well as the speed with which
LLVM compiles, optimizes, and generates code.
-The test-suite is located in the ``test-suite``
-`repository on GitHub <https://github.com/llvm/llvm-test-suite.git>`_.
+The test-suite is located in the `test-suite`
+[repository on GitHub](https://github.com/llvm/llvm-test-suite.git).
-See the :doc:`TestSuiteGuide` for details.
+See the {doc}`TestSuiteGuide` for details.
-Debugging Information tests
----------------------------
+### Debugging Information tests
The test suite contains tests to check the quality of debugging information.
The tests are written in C-based languages or in LLVM assembly language.
These tests are compiled and run under a debugger. The debugger output
-is checked to validate the debugging information. See ``README.txt`` in the
+is checked to validate the debugging information. See `README.txt` in the
test suite for more information. This test suite is located in the
-``cross-project-tests/debuginfo-tests`` directory.
+`cross-project-tests/debuginfo-tests` directory.
-Quick start
-===========
+## Quick start
The tests are located in two separate repositories. The unit and
regression tests are in the main "llvm"/ directory under the directories
-``llvm/unittests`` and ``llvm/test`` (so you get these tests for free with the
-main LLVM tree). Use ``make check-all`` to run the unit and regression tests
+`llvm/unittests` and `llvm/test` (so you get these tests for free with the
+main LLVM tree). Use `make check-all` to run the unit and regression tests
after building LLVM.
-The ``test-suite`` module contains more comprehensive tests including whole C
-and C++ programs. See the :doc:`TestSuiteGuide` for details.
-
-Unit and Regression tests
--------------------------
+The `test-suite` module contains more comprehensive tests including whole C
+and C++ programs. See the {doc}`TestSuiteGuide` for details.
-To run all of the LLVM unit tests, use the ``check-llvm-unit`` target:
+### Unit and Regression tests
-.. code-block:: bash
+To run all of the LLVM unit tests, use the `check-llvm-unit` target:
- % make check-llvm-unit
+```bash
+% make check-llvm-unit
+```
-To run all of the LLVM regression tests, use the ``check-llvm`` target:
+To run all of the LLVM regression tests, use the `check-llvm` target:
-.. code-block:: bash
-
- % make check-llvm
+```bash
+% make check-llvm
+```
In order to get reasonable testing performance, build LLVM and subprojects
in release mode, i.e.,
-.. code-block:: bash
-
- % cmake -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_ASSERTIONS=On
+```bash
+% cmake -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_ASSERTIONS=On
+```
-If you have `Clang <https://clang.llvm.org/>`_ checked out and built, you
+If you have [Clang](https://clang.llvm.org/) checked out and built, you
can run the LLVM and Clang tests simultaneously using:
-.. code-block:: bash
+```bash
+% make check-all
+```
- % make check-all
-
-To run the tests with Valgrind (Memcheck by default), use the ``LIT_OPTS`` make
+To run the tests with Valgrind (Memcheck by default), use the `LIT_OPTS` make
variable to pass the required options to lit. For example, you can use:
-.. code-block:: bash
-
- % make check LIT_OPTS="-v --vg --vg-leak"
+```bash
+% make check LIT_OPTS="-v --vg --vg-leak"
+```
to enable testing with Valgrind and with leak checking enabled.
-To run individual tests or subsets of tests, you can use the ``llvm-lit``
+To run individual tests or subsets of tests, you can use the `llvm-lit`
script which is built as part of LLVM. For example, to run the
-``Integer/BitPacked.ll`` test by itself, you can run:
+`Integer/BitPacked.ll` test by itself, you can run:
-.. code-block:: bash
+```bash
+% llvm-lit <path to llvm-project>/llvm/test/Integer/BitPacked.ll
+```
- % llvm-lit <path to llvm-project>/llvm/test/Integer/BitPacked.ll
-
-.. note::
- The test files are in the ``llvm-project`` directory, not the directory you
- are building LLVM in.
+```{note}
+The test files are in the `llvm-project` directory, not the directory you
+are building LLVM in.
+```
Or you can run a whole folder of tests. To run all of the ARM CodeGen tests:
-.. code-block:: bash
-
- % llvm-lit <path to llvm-project>/llvm/test/CodeGen/ARM
+```bash
+% llvm-lit <path to llvm-project>/llvm/test/CodeGen/ARM
+```
The regression tests will use the Python psutil module only if installed in a
**non-user** location. Under Linux, install with sudo or within a virtual
environment. Under Windows, install Python for all users and then run
-``pip install psutil`` in an elevated command prompt.
+`pip install psutil` in an elevated command prompt.
-For more information on using the :program:`lit` tool, see ``llvm-lit --help``
-or the :doc:`lit man page <CommandGuide/lit>`.
+For more information on using the {program}`lit` tool, see `llvm-lit --help`
+or the {doc}`lit man page <CommandGuide/lit>`.
-Debugging Information tests
----------------------------
+### Debugging Information tests
-To run debugging information tests simply add the ``cross-project-tests``
-project to your ``LLVM_ENABLE_PROJECTS`` define on the cmake
+To run debugging information tests simply add the `cross-project-tests`
+project to your `LLVM_ENABLE_PROJECTS` define on the cmake
command-line.
-Regression test structure
-=========================
+## Regression test structure
-The LLVM regression tests are driven by :program:`lit` and are located in the
-``llvm/test`` directory.
+The LLVM regression tests are driven by {program}`lit` and are located in the
+`llvm/test` directory.
This directory contains a large array of small tests that exercise
various features of LLVM and to ensure that regressions do not occur.
The directory is broken into several subdirectories, each focused on a
particular area of LLVM.
-Writing new regression tests
-----------------------------
+### Writing new regression tests
The regression test structure is very simple but does require some
-information to be set. This information is gathered via ``cmake``
-and is written to a file, ``test/lit.site.cfg.py`` in the build directory.
-The ``llvm/test`` Makefile does this work for you.
+information to be set. This information is gathered via `cmake`
+and is written to a file, `test/lit.site.cfg.py` in the build directory.
+The `llvm/test` Makefile does this work for you.
In order for the regression tests to work, each directory of tests must
-have a ``lit.local.cfg`` file. :program:`lit` looks for this file to determine
+have a `lit.local.cfg` file. {program}`lit` looks for this file to determine
how to run the tests. This file is just Python code and thus is very
flexible, but we've standardized it for the LLVM regression tests. If
-you're adding a directory of tests, just copy ``lit.local.cfg`` from
-another directory to get running. The standard ``lit.local.cfg`` simply
+you're adding a directory of tests, just copy `lit.local.cfg` from
+another directory to get running. The standard `lit.local.cfg` simply
specifies which files to look in for tests. Any directory that contains
-only directories does not need the ``lit.local.cfg`` file. Read the :doc:`Lit
-documentation <CommandGuide/lit>` for more information.
+only directories does not need the `lit.local.cfg` file. Read the
+{doc}`Lit documentation <CommandGuide/lit>` for more information.
-Each test file must contain lines starting with "RUN:" that tell :program:`lit`
-how to run it. If there are no ``RUN`` lines, :program:`lit` will issue an error
+Each test file must contain lines starting with "RUN:" that tell {program}`lit`
+how to run it. If there are no `RUN` lines, {program}`lit` will issue an error
while running a test.
-``RUN`` lines are specified in the comments of the test program using the
-keyword ``RUN`` followed by a colon, and lastly the command (pipeline)
-to execute. Together, these lines form the "script" that :program:`lit`
-executes to run the test case. The syntax of the ``RUN`` lines is similar to a
+`RUN` lines are specified in the comments of the test program using the
+keyword `RUN` followed by a colon, and lastly the command (pipeline)
+to execute. Together, these lines form the "script" that {program}`lit`
+executes to run the test case. The syntax of the `RUN` lines is similar to a
shell's syntax for pipelines including I/O redirection and variable
substitution. However, even though these lines may *look* like a shell
-script, they are not. ``RUN`` lines are interpreted by :program:`lit`.
+script, they are not. `RUN` lines are interpreted by {program}`lit`.
Consequently, the syntax differs from shell in a few ways. You can specify
-as many ``RUN`` lines as needed.
+as many `RUN` lines as needed.
-:program:`lit` performs substitution on each ``RUN`` line to replace LLVM tool names
+{program}`lit` performs substitution on each `RUN` line to replace LLVM tool names
with the full paths to the executable built for each tool (in
-``$(LLVM_OBJ_ROOT)/bin``). This ensures that :program:`lit` does
+`$(LLVM_OBJ_ROOT)/bin`). This ensures that {program}`lit` does
not invoke any stray LLVM tools in the user's path during testing.
-Each ``RUN`` line is executed on its own, distinct from other lines unless
-its last character is ``\``. This continuation character causes the ``RUN``
+Each `RUN` line is executed on its own, distinct from other lines unless
+its last character is `\`. This continuation character causes the `RUN`
line to be concatenated with the next one. In this way, you can build up
long pipelines of commands without making huge line lengths. The lines
-ending in ``\`` are concatenated until a ``RUN`` line that doesn't end in
-``\`` is found. This concatenated set of ``RUN`` lines then constitutes one
-execution. :program:`lit` will substitute variables and arrange for the pipeline
+ending in `\` are concatenated until a `RUN` line that doesn't end in
+`\` is found. This concatenated set of `RUN` lines then constitutes one
+execution. {program}`lit` will substitute variables and arrange for the pipeline
to be executed. If any process in the pipeline fails, the entire line (and
test case) fails too.
-Below is an example of legal ``RUN`` lines in a ``.ll`` file:
+Below is an example of legal `RUN` lines in a `.ll` file:
-.. code-block:: llvm
+```llvm
+; RUN: llvm-as < %s | llvm-dis > %t1
+; RUN: llvm-dis < %s.bc-13 > %t2
+; RUN: diff %t1 %t2
+```
- ; RUN: llvm-as < %s | llvm-dis > %t1
- ; RUN: llvm-dis < %s.bc-13 > %t2
- ; RUN: diff %t1 %t2
-
-As with a Unix shell, the ``RUN`` lines permit pipelines and I/O
+As with a Unix shell, the `RUN` lines permit pipelines and I/O
redirection to be used.
There are some quoting rules that you must pay attention to when writing
-your ``RUN`` lines. In general, nothing needs to be quoted. :program:`lit` won't
+your `RUN` lines. In general, nothing needs to be quoted. {program}`lit` won't
strip off any quote characters, so they will get passed to the invoked program.
-To avoid this use curly braces to tell :program:`lit` that it should treat
+To avoid this use curly braces to tell {program}`lit` that it should treat
everything enclosed as one value.
-In general, you should strive to keep your ``RUN`` lines as simple as possible,
+In general, you should strive to keep your `RUN` lines as simple as possible,
using them only to run tools that generate textual output you can then examine.
The recommended way to examine output to figure out if the test passes is using
-the :doc:`FileCheck tool <CommandGuide/FileCheck>`. *[The usage of grep in ``RUN``
+the {doc}`FileCheck tool <CommandGuide/FileCheck>`. *[The usage of grep in `RUN`
lines is deprecated - please do not send or commit patches that use it.]*
Put related tests into a single file rather than having a separate file per
test. Check if there are files already covering your feature and consider
adding your code there instead of creating a new file.
-Generating assertions in regression tests
------------------------------------------
+### Generating assertions in regression tests
Some regression test cases are very large and complex to write/update by hand.
In that case, to reduce the manual work, we can use the scripts available in
-``llvm/utils/`` to generate the assertions.
-
-For example, to generate assertions in an :program:`llc`-based test, after
-adding one or more ``RUN`` lines, use:
+`llvm/utils/` to generate the assertions.
- .. code-block:: bash
+For example, to generate assertions in an {program}`llc`-based test, after
+adding one or more `RUN` lines, use:
- % llvm/utils/update_llc_test_checks.py --llc-binary build/bin/llc test.ll
+```bash
+% llvm/utils/update_llc_test_checks.py --llc-binary build/bin/llc test.ll
+```
-This will generate FileCheck assertions, and insert a ``NOTE:`` line at the
+This will generate FileCheck assertions, and insert a `NOTE:` line at the
top to indicate that assertions were automatically generated.
If you want to update assertions in an existing test case, pass the `-u` option
-which first checks the ``NOTE:`` line exists and matches the script name.
+which first checks the `NOTE:` line exists and matches the script name.
Sometimes, a test absolutely depends on hand-written assertions and should not
-have assertions automatically generated. In that case, add the text ``NOTE: Do
-not autogenerate`` to the first line, and the scripts will skip that test. It
+have assertions automatically generated. In that case, add the text `NOTE: Do
+not autogenerate` to the first line, and the scripts will skip that test. It
is a good idea to explain why generated assertions will not work for the test
so future developers will understand what is going on.
These are the most common scripts and their purposes/applications in generating
assertions:
-.. code-block:: none
+```
+update_analyze_test_checks.py
+opt -passes='print<cost-model>'
- update_analyze_test_checks.py
- opt -passes='print<cost-model>'
+update_cc_test_checks.py
+C/C++, or clang/clang++ (IR checks)
- update_cc_test_checks.py
- C/C++, or clang/clang++ (IR checks)
+update_llc_test_checks.py
+llc (assembly checks)
- update_llc_test_checks.py
- llc (assembly checks)
+update_mca_test_checks.py
+llvm-mca
- update_mca_test_checks.py
- llvm-mca
+update_mir_test_checks.py
+llc (MIR checks)
- update_mir_test_checks.py
- llc (MIR checks)
+update_test_checks.py
+opt
- update_test_checks.py
- opt
+update_llubi_test_checks.py
+llubi
+```
- update_llubi_test_checks.py
- llubi
-
-Precommit workflow for tests
-----------------------------
+### Precommit workflow for tests
If the test does not crash, assert, or infinite loop, commit the test with
baseline check-lines first. That is, the test will show a miscompile or
@@ -345,8 +337,7 @@ Remove TODO/FIXME comments added in the previous step if a problem is solved.
Baseline tests (no-functional-change or NFC patch) may be pushed to main
without pre-commit review if you have commit access.
-Best practices for regression tests
------------------------------------
+### Best practices for regression tests
- Use auto-generated check lines (produced by the scripts mentioned above)
whenever feasible.
@@ -354,19 +345,19 @@ Best practices for regression tests
are relevant issues in the bug tracker, add references to those bug reports
(for example, "See PR999 for more details").
- Avoid undefined behavior and poison/undef values unless necessary. For
- example, do not use patterns like ``br i1 undef``, which are likely to break
+ example, do not use patterns like `br i1 undef`, which are likely to break
as a result of future optimizations.
- Minimize tests by removing unnecessary instructions, metadata, attributes,
- etc. Tools like ``llvm-reduce`` can partially automate this, but usually
+ etc. Tools like `llvm-reduce` can partially automate this, but usually
some manual cleanup is still required.
- Outside PhaseOrdering tests, only run a minimal set of passes. For example,
- prefer ``opt -S -passes=instcombine`` over ``opt -S -O3``.
-- Avoid unnamed instructions/blocks (such as ``%0`` or ``1:``), because they may
+ prefer `opt -S -passes=instcombine` over `opt -S -O3`.
+- Avoid unnamed instructions/blocks (such as `%0` or `1:`), because they may
require renumbering on future test modifications. These can be removed by
- running the test through ``opt -S -passes=instnamer``.
+ running the test through `opt -S -passes=instnamer`.
- Try to give values (including variables, blocks and functions) meaningful
names, and avoid retaining complex names generated by the optimization
- pipeline (such as ``%foo.0.0.0.0.0.0``).
+ pipeline (such as `%foo.0.0.0.0.0.0`).
- Omit target triples and datalayouts when possible. If the test case only
exercises the code path of interest with a specific target triple
and/or datalayout, then they should be in the test, but otherwise they
@@ -376,203 +367,201 @@ Best practices for regression tests
an existing file rather than creating a new one. If your test requires
a specific target, prefer putting it in a target-specific test
subdirectory rather than requiring a specific backend to be built with a
- ``REQUIRES:`` line.
-- Use a minimal number of non-default (``CHECK-<prefix>``) check prefixes.
- Avoid setting a check prefix if all ``FileCheck`` invocations in the test
+ `REQUIRES:` line.
+- Use a minimal number of non-default (`CHECK-<prefix>`) check prefixes.
+ Avoid setting a check prefix if all `FileCheck` invocations in the test
expect the same output.
-Extra files
------------
+### Extra files
-If your test requires extra files besides the file containing the ``RUN:`` lines,
+If your test requires extra files besides the file containing the `RUN:` lines,
and the extra files are small, consider specifying them in the same file and
-using ``split-file`` to extract them. For example,
-
-.. code-block:: llvm
+using `split-file` to extract them. For example,
- ; RUN: split-file %s %t
- ; RUN: llvm-link -S %t/a.ll %t/b.ll | FileCheck %s
+```llvm
+; RUN: split-file %s %t
+; RUN: llvm-link -S %t/a.ll %t/b.ll | FileCheck %s
- ; CHECK: ...
+; CHECK: ...
- ;--- a.ll
- ...
- ;--- b.ll
- ...
+;--- a.ll
+...
+;--- b.ll
+...
+```
-The parts are separated by the regex ``^(.|//)--- <part>``.
+The parts are separated by the regex `^(.|//)--- <part>`.
-If you want to test relative line numbers like ``[[#@LINE+1]]``, specify
-``--leading-lines`` to add leading empty lines to preserve line numbers.
+If you want to test relative line numbers like `[[#@LINE+1]]`, specify
+`--leading-lines` to add leading empty lines to preserve line numbers.
-If the extra files are large, the idiomatic place to put them is in a subdirectory ``Inputs``.
-You can then refer to the extra files as ``%S/Inputs/foo.bar``.
+If the extra files are large, the idiomatic place to put them is in a subdirectory `Inputs`.
+You can then refer to the extra files as `%S/Inputs/foo.bar`.
-For example, consider ``test/Linker/ident.ll``. The directory structure is
-as follows::
+For example, consider `test/Linker/ident.ll`. The directory structure is
+as follows:
- test/
- Linker/
- ident.ll
- Inputs/
- ident.a.ll
- ident.b.ll
+```
+test/
+ Linker/
+ ident.ll
+ Inputs/
+ ident.a.ll
+ ident.b.ll
+```
For convenience, these are the contents:
-.. code-block:: llvm
+```llvm
+;;;;; ident.ll:
- ;;;;; ident.ll:
+; RUN: llvm-link %S/Inputs/ident.a.ll %S/Inputs/ident.b.ll -S | FileCheck %s
- ; RUN: llvm-link %S/Inputs/ident.a.ll %S/Inputs/ident.b.ll -S | FileCheck %s
+; Verify that multiple input llvm.ident metadata are linked together.
- ; Verify that multiple input llvm.ident metadata are linked together.
+; CHECK-DAG: !llvm.ident = !{!0, !1, !2}
+; CHECK-DAG: "Compiler V1"
+; CHECK-DAG: "Compiler V2"
+; CHECK-DAG: "Compiler V3"
- ; CHECK-DAG: !llvm.ident = !{!0, !1, !2}
- ; CHECK-DAG: "Compiler V1"
- ; CHECK-DAG: "Compiler V2"
- ; CHECK-DAG: "Compiler V3"
+;;;;; Inputs/ident.a.ll:
- ;;;;; Inputs/ident.a.ll:
+!llvm.ident = !{!0, !1}
+!0 = metadata !{metadata !"Compiler V1"}
+!1 = metadata !{metadata !"Compiler V2"}
- !llvm.ident = !{!0, !1}
- !0 = metadata !{metadata !"Compiler V1"}
- !1 = metadata !{metadata !"Compiler V2"}
+;;;;; Inputs/ident.b.ll:
- ;;;;; Inputs/ident.b.ll:
+!llvm.ident = !{!0}
+!0 = metadata !{metadata !"Compiler V3"}
+```
- !llvm.ident = !{!0}
- !0 = metadata !{metadata !"Compiler V3"}
+For symmetry, `ident.ll` is just a dummy file that doesn't
+actually participate in the test besides holding the `RUN:` lines.
-For symmetry, ``ident.ll`` is just a dummy file that doesn't
-actually participate in the test besides holding the ``RUN:`` lines.
+```{note}
+Some existing tests use `RUN: true` in extra files instead of just
+putting the extra files in an `Inputs/` directory. This pattern is
+deprecated.
+```
-.. note::
-
- Some existing tests use ``RUN: true`` in extra files instead of just
- putting the extra files in an ``Inputs/`` directory. This pattern is
- deprecated.
-
-Elaborated tests
-----------------
+### Elaborated tests
Generally, IR and assembly test files benefit from being cleaned to remove
unnecessary details. However, for tests requiring elaborate IR or assembly
files where cleanup is less practical (e.g., a large amount of debug information
output from Clang), you can include generation instructions within
-``split-file`` part called ``gen``. Then, run
-``llvm/utils/update_test_body.py`` on the test file to generate the needed
+`split-file` part called `gen`. Then, run
+`llvm/utils/update_test_body.py` on the test file to generate the needed
content.
-.. code-block:: none
-
- ; RUN: rm -rf %t && split-file %s %t && cd %t
- ; RUN: opt -S a.ll ... | FileCheck %s
-
- ; CHECK: hello
+```
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: opt -S a.ll ... | FileCheck %s
- ;--- a.cc
- int va;
- ;--- gen
- clang --target=x86_64-linux -S -emit-llvm -g a.cc -o -
+; CHECK: hello
- ;--- a.ll
- # content generated by the script 'gen'
+;--- a.cc
+int va;
+;--- gen
+clang --target=x86_64-linux -S -emit-llvm -g a.cc -o -
-.. code-block:: bash
+;--- a.ll
+# content generated by the script 'gen'
+```
- PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.ll
+```bash
+PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.ll
+```
-The script will prepare extra files with ``split-file``, invoke ``gen``, and
-then rewrite the part after ``gen`` with its stdout.
+The script will prepare extra files with `split-file`, invoke `gen`, and
+then rewrite the part after `gen` with its stdout.
For convenience, if the test needs a single assembly file, you can also wrap
-``gen`` and its required files with ``.ifdef`` and ``.endif``. Then you can
-skip ``split-file`` in ``RUN`` lines.
-
-.. code-block:: none
-
- # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o a.o
- # RUN: ... | FileCheck %s
-
- # CHECK: hello
-
- .ifdef GEN
- #--- a.cc
- int va;
- #--- gen
- clang --target=x86_64-linux -S -g a.cc -o -
- .endif
- # content generated by the script 'gen'
-
-.. note::
-
- Consider specifying an explicit target triple to avoid differences when
- regeneration is needed on another machine.
-
- ``gen`` is invoked with ``PWD`` set to ``/proc/self/cwd``. Clang commands
- don't need ``-fdebug-compilation-dir=`` since its default value is ``PWD``.
-
- Check prefixes should be placed before ``.endif`` since the part after
- ``.endif`` is replaced.
-
-If the test body contains multiple files, you can print ``---`` separators and
-utilize ``split-file`` in ``RUN`` lines.
-
-.. code-block:: none
-
- # RUN: rm -rf %t && split-file %s %t && cd %t
- ...
-
- #--- a.cc
- int va;
- #--- b.cc
- int vb;
- #--- gen
- clang --target=x86_64-linux -S -O1 -g a.cc -o -
- echo '#--- b.s'
- clang --target=x86_64-linux -S -O1 -g b.cc -o -
- #--- a.s
-
-Fragile tests
--------------
+`gen` and its required files with `.ifdef` and `.endif`. Then you can
+skip `split-file` in `RUN` lines.
+
+```
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o a.o
+# RUN: ... | FileCheck %s
+
+# CHECK: hello
+
+.ifdef GEN
+#--- a.cc
+int va;
+#--- gen
+clang --target=x86_64-linux -S -g a.cc -o -
+.endif
+# content generated by the script 'gen'
+```
+
+```{note}
+Consider specifying an explicit target triple to avoid differences when
+regeneration is needed on another machine.
+
+`gen` is invoked with `PWD` set to `/proc/self/cwd`. Clang commands
+don't need `-fdebug-compilation-dir=` since its default value is `PWD`.
+
+Check prefixes should be placed before `.endif` since the part after
+`.endif` is replaced.
+```
+
+If the test body contains multiple files, you can print `---` separators and
+utilize `split-file` in `RUN` lines.
+
+```
+# RUN: rm -rf %t && split-file %s %t && cd %t
+...
+
+#--- a.cc
+int va;
+#--- b.cc
+int vb;
+#--- gen
+clang --target=x86_64-linux -S -O1 -g a.cc -o -
+echo '#--- b.s'
+clang --target=x86_64-linux -S -O1 -g b.cc -o -
+#--- a.s
+```
+
+### Fragile tests
It is easy to write a fragile test that could fail spuriously if the tool being
-tested outputs a full path to the input file. For example, :program:`opt` by
-default outputs a ``ModuleID``:
-
-.. code-block:: console
+tested outputs a full path to the input file. For example, {program}`opt` by
+default outputs a `ModuleID`:
- $ cat example.ll
- define i32 @main() nounwind {
- ret i32 0
- }
+```console
+$ cat example.ll
+define i32 @main() nounwind {
+ ret i32 0
+}
- $ opt -S /path/to/example.ll
- ; ModuleID = '/path/to/example.ll'
+$ opt -S /path/to/example.ll
+; ModuleID = '/path/to/example.ll'
- define i32 @main() nounwind {
- ret i32 0
- }
+define i32 @main() nounwind {
+ ret i32 0
+}
+```
-``ModuleID`` can unexpectedly match against ``CHECK`` lines. For example:
+`ModuleID` can unexpectedly match against `CHECK` lines. For example:
-.. code-block:: llvm
+```llvm
+; RUN: opt -S %s | FileCheck
- ; RUN: opt -S %s | FileCheck
+define i32 @main() nounwind {
+ ; CHECK-NOT: load
+ ret i32 0
+}
+```
- define i32 @main() nounwind {
- ; CHECK-NOT: load
- ret i32 0
- }
+This test will fail if placed into a `download` directory.
-This test will fail if placed into a ``download`` directory.
+To make your tests robust, always use `opt ... < %s` in the `RUN` line.
+{program}`opt` does not output a `ModuleID` when input comes from stdin.
-To make your tests robust, always use ``opt ... < %s`` in the ``RUN`` line.
-:program:`opt` does not output a ``ModuleID`` when input comes from stdin.
-
-Platform-Specific Tests
------------------------
+### Platform-Specific Tests
Whenever adding tests that require the knowledge of a specific platform,
either related to code generated, specific output or back-end features,
@@ -584,45 +573,45 @@ The first problem is to check for target-specific output, for example sizes
of structures, paths and architecture names, for example:
* Tests containing Windows paths will fail on Linux and vice versa.
-* Tests that check for ``x86_64`` somewhere in the text will fail anywhere else.
+* Tests that check for `x86_64` somewhere in the text will fail anywhere else.
* Tests where the debug information calculates the size of types and structures.
Also, if the test relies on any behaviour that is coded in any back-end, it must
go in its own directory. So, for instance, code generator tests for ARM go
-into ``test/CodeGen/ARM`` and so on. Those directories contain a special
-``lit`` configuration file that ensures all tests in that directory will
+into `test/CodeGen/ARM` and so on. Those directories contain a special
+`lit` configuration file that ensures all tests in that directory will
only run if a specific back-end is compiled and available.
-For instance, on ``test/CodeGen/ARM``, the ``lit.local.cfg`` is:
-
-.. code-block:: python
+For instance, on `test/CodeGen/ARM`, the `lit.local.cfg` is:
- config.suffixes = ['.ll', '.c', '.cpp', '.test']
- if not 'ARM' in config.root.targets:
- config.unsupported = True
+```python
+config.suffixes = ['.ll', '.c', '.cpp', '.test']
+if not 'ARM' in config.root.targets:
+ config.unsupported = True
+```
Other platform-specific tests are those that depend on a specific feature
-of a specific sub-architecture, for example only to Intel chips that support ``AVX2``.
+of a specific sub-architecture, for example only to Intel chips that support `AVX2`.
-For instance, ``test/CodeGen/X86/psubus.ll`` tests three sub-architecture
+For instance, `test/CodeGen/X86/psubus.ll` tests three sub-architecture
variants:
-.. code-block:: llvm
-
- ; RUN: llc -mcpu=core2 < %s | FileCheck %s -check-prefix=SSE2
- ; RUN: llc -mcpu=corei7-avx < %s | FileCheck %s -check-prefix=AVX1
- ; RUN: llc -mcpu=core-avx2 < %s | FileCheck %s -check-prefix=AVX2
+```llvm
+; RUN: llc -mcpu=core2 < %s | FileCheck %s -check-prefix=SSE2
+; RUN: llc -mcpu=corei7-avx < %s | FileCheck %s -check-prefix=AVX1
+; RUN: llc -mcpu=core-avx2 < %s | FileCheck %s -check-prefix=AVX2
+```
And the checks are different:
-.. code-block:: llvm
-
- ; SSE2: @test1
- ; SSE2: psubusw LCPI0_0(%rip), %xmm0
- ; AVX1: @test1
- ; AVX1: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0
- ; AVX2: @test1
- ; AVX2: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0
+```llvm
+; SSE2: @test1
+; SSE2: psubusw LCPI0_0(%rip), %xmm0
+; AVX1: @test1
+; AVX1: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0
+; AVX2: @test1
+; AVX2: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0
+```
So, if you're testing for a behaviour that you know is platform-specific or
depends on special features of sub-architectures, you must add the specific
@@ -630,479 +619,495 @@ triple, test with the specific FileCheck and put it into the specific
directory that will filter out all other architectures.
-Constraining test execution
----------------------------
+### Constraining test execution
Some tests can be run only in specific configurations, such as
-with debug builds or on particular platforms. Use ``REQUIRES``
-and ``UNSUPPORTED`` to control when the test is enabled.
+with debug builds or on particular platforms. Use `REQUIRES`
+and `UNSUPPORTED` to control when the test is enabled.
Some tests are expected to fail. For example, there may be a known bug
-that the test detects. Use ``XFAIL`` to mark a test as an expected failure.
-An ``XFAIL`` test will be successful if its execution fails, and
+that the test detects. Use `XFAIL` to mark a test as an expected failure.
+An `XFAIL` test will be successful if its execution fails, and
will be a failure if its execution succeeds.
-.. code-block:: llvm
+```llvm
+; This test will be only enabled in the build with asserts.
+; REQUIRES: asserts
+; This test is disabled when running on Linux.
+; UNSUPPORTED: system-linux
+; This test is expected to fail when targeting PowerPC.
+; XFAIL: target=powerpc{{.*}}
+```
- ; This test will be only enabled in the build with asserts.
- ; REQUIRES: asserts
- ; This test is disabled when running on Linux.
- ; UNSUPPORTED: system-linux
- ; This test is expected to fail when targeting PowerPC.
- ; XFAIL: target=powerpc{{.*}}
-
-``REQUIRES`` and ``UNSUPPORTED`` and ``XFAIL`` all accept a comma-separated
+`REQUIRES` and `UNSUPPORTED` and `XFAIL` all accept a comma-separated
list of boolean expressions. The values in each expression may be:
-- Features added to ``config.available_features`` by configuration files such as ``lit.cfg``.
+- Features added to `config.available_features` by configuration files such as `lit.cfg`.
String comparison of features is case-sensitive. Furthermore, a boolean expression can
- contain any Python regular expression enclosed in ``{{ }}``, in which case the boolean
+ contain any Python regular expression enclosed in `{{ }}`, in which case the boolean
expression is satisfied if any feature matches the regular expression. Regular
- expressions can appear inside an identifier, so for example ``he{{l+}}o`` would match
- ``helo``, ``hello``, ``helllo``, and so on.
-- The default target triple, preceded by the string ``target=`` (for example,
- ``target=x86_64-pc-windows-msvc``). Typically, regular expressions are used
- to match parts of the triple (for example, ``target={{.*}}-windows{{.*}}``
+ expressions can appear inside an identifier, so for example `he{{l+}}o` would match
+ `helo`, `hello`, `helllo`, and so on.
+- The default target triple, preceded by the string `target=` (for example,
+ `target=x86_64-pc-windows-msvc`). Typically, regular expressions are used
+ to match parts of the triple (for example, `target={{.*}}-windows{{.*}}`
to match any Windows target triple).
-| ``REQUIRES`` enables the test if all expressions are true.
-| ``UNSUPPORTED`` disables the test if any expression is true.
-| ``XFAIL`` expects the test to fail if any expression is true.
-
-Use, ``XFAIL: *`` if the test is expected to fail everywhere. Similarly, use
-``UNSUPPORTED: target={{.*}}`` to disable the test everywhere.
+- `REQUIRES` enables the test if all expressions are true.
+- `UNSUPPORTED` disables the test if any expression is true.
+- `XFAIL` expects the test to fail if any expression is true.
-.. code-block:: llvm
+Use, `XFAIL: *` if the test is expected to fail everywhere. Similarly, use
+`UNSUPPORTED: target={{.*}}` to disable the test everywhere.
- ; This test is disabled when running on Windows,
- ; and is disabled when targeting Linux, except for Android Linux.
- ; UNSUPPORTED: system-windows, target={{.*linux.*}} && !target={{.*android.*}}
- ; This test is expected to fail when targeting PowerPC or running on Darwin.
- ; XFAIL: target=powerpc{{.*}}, system-darwin
+```llvm
+; This test is disabled when running on Windows,
+; and is disabled when targeting Linux, except for Android Linux.
+; UNSUPPORTED: system-windows, target={{.*linux.*}} && !target={{.*android.*}}
+; This test is expected to fail when targeting PowerPC or running on Darwin.
+; XFAIL: target=powerpc{{.*}}, system-darwin
+```
+### Tips for writing constraints
-Tips for writing constraints
-----------------------------
+**`REQUIRES` and `UNSUPPORTED`**
-**``REQUIRES`` and ``UNSUPPORTED``**
-
-These are logical inverses. In principle, ``UNSUPPORTED`` isn't absolutely
-necessary (the logical negation could be used with ``REQUIRES`` to get
+These are logical inverses. In principle, `UNSUPPORTED` isn't absolutely
+necessary (the logical negation could be used with `REQUIRES` to get
exactly the same effect), but it can make these clauses easier to read and
-understand. Generally, people use ``REQUIRES`` to state things that the test
-depends on to operate correctly, and ``UNSUPPORTED`` to exclude cases where
+understand. Generally, people use `REQUIRES` to state things that the test
+depends on to operate correctly, and `UNSUPPORTED` to exclude cases where
the test is expected never to work.
-**``UNSUPPORTED`` and ``XFAIL``**
+**`UNSUPPORTED` and `XFAIL`**
Both of these indicate that the test isn't expected to work; however, they
-have different effects. ``UNSUPPORTED`` causes the test to be skipped;
+have different effects. `UNSUPPORTED` causes the test to be skipped;
this saves execution time, but then you'll never know whether the test
-actually would start working. Conversely, ``XFAIL`` actually runs the test
+actually would start working. Conversely, `XFAIL` actually runs the test
but expects a failure output, taking extra execution time but alerting you
-if/when the test begins to behave correctly (an ``XPASS`` test result). You
+if/when the test begins to behave correctly (an `XPASS` test result). You
need to decide which is more appropriate in each case.
-**Using ``target=...``**
+**Using `target=...`**
Checking the target triple can be tricky; it's easy to mis-specify. For
-example, ``target=mips{{.*}}`` will match not only mips, but also mipsel,
-mips64, and mips64el. ``target={{.*}}-linux-gnu`` will match
+example, `target=mips{{.*}}` will match not only mips, but also mipsel,
+mips64, and mips64el. `target={{.*}}-linux-gnu` will match
x86_64-unknown-linux-gnu, but not armv8l-unknown-linux-gnueabihf.
-Prefer to use hyphens to delimit triple components (``target=mips-{{.*}}``)
+Prefer to use hyphens to delimit triple components (`target=mips-{{.*}}`)
and it's generally a good idea to use a trailing wildcard to allow for
unexpected suffixes.
Also, it's generally better to write regular expressions that use entire
triple components than to do something clever to shorten them. For
example, to match both freebsd and netbsd in an expression, you could write
-``target={{.*(free|net)bsd.*}}`` and that would work. However, it would
-prevent a ``grep freebsd`` from finding this test. Better to use:
-``target={{.+-freebsd.*}} || target={{.+-netbsd.*}}``
+`target={{.*(free|net)bsd.*}}` and that would work. However, it would
+prevent a `grep freebsd` from finding this test. Better to use:
+`target={{.+-freebsd.*}} || target={{.+-netbsd.*}}`
-Substitutions
--------------
+### Substitutions
Besides replacing LLVM tool names, the following substitutions are performed in
-``RUN`` lines:
+`RUN` lines:
+
+`%%`
+
+: Replaced by a single `%`. This allows escaping other substitutions.
+
+`%s`
-``%%``
- Replaced by a single ``%``. This allows escaping other substitutions.
+: File path to the test case's source. This is suitable for passing on the
+ command line as the input to an LLVM tool.
-``%s``
- File path to the test case's source. This is suitable for passing on the
- command line as the input to an LLVM tool.
+ Example: `/home/user/llvm/test/MC/ELF/foo_test.s`
- Example: ``/home/user/llvm/test/MC/ELF/foo_test.s``
+`%S`
-``%S``
- Directory path to the test case's source.
+: Directory path to the test case's source.
- Example: ``/home/user/llvm/test/MC/ELF``
+ Example: `/home/user/llvm/test/MC/ELF`
-``%t``
- File path to a temporary file name that can be used for this test case.
- The file name won't conflict with other test cases. You can append to it
- if you need multiple temporaries. This is useful as the destination of
- some redirected output.
+`%t`
- Example: ``/home/user/llvm.build/test/MC/ELF/Output/foo_test.s.tmp``
+: File path to a temporary file name that can be used for this test case.
+ The file name won't conflict with other test cases. You can append to it
+ if you need multiple temporaries. This is useful as the destination of
+ some redirected output.
-``%T``
- Directory of ``%t``. Deprecated. Shouldn't be used, because it can be easily
- misused and cause race conditions between tests.
+ Example: `/home/user/llvm.build/test/MC/ELF/Output/foo_test.s.tmp`
- Use ``rm -rf %t && mkdir %t`` instead if a temporary directory is necessary.
+`%T`
- Example: ``/home/user/llvm.build/test/MC/ELF/Output``
+: Directory of `%t`. Deprecated. Shouldn't be used, because it can be easily
+ misused and cause race conditions between tests.
-``%{pathsep}``
+ Use `rm -rf %t && mkdir %t` instead if a temporary directory is necessary.
- Expands to the path separator, i.e. ``:`` (or ``;`` on Windows).
+ Example: `/home/user/llvm.build/test/MC/ELF/Output`
-``%{fs-src-root}``
- Expands to the root component of file system paths for the source directory,
- i.e. ``/`` on Unix systems or ``C:\`` (or another drive) on Windows.
+`%{pathsep}`
-``%{fs-tmp-root}``
- Expands to the root component of file system paths for the test's temporary
- directory, i.e. ``/`` on Unix systems or ``C:\`` (or another drive) on
- Windows.
+: Expands to the path separator, i.e. `:` (or `;` on Windows).
-``%{fs-sep}``
- Expands to the file system separator, i.e. ``/`` or ``\`` on Windows.
+`%{fs-src-root}`
-``%/s, %/S, %/t, %/T``
+: Expands to the root component of file system paths for the source directory,
+ i.e. `/` on Unix systems or `C:\` (or another drive) on Windows.
- Act like the corresponding substitution above but replace any ``\``
- character with a ``/``. This is useful to normalize path separators.
+`%{fs-tmp-root}`
- Example: ``%s: C:\Desktop Files/foo_test.s.tmp``
+: Expands to the root component of file system paths for the test's temporary
+ directory, i.e. `/` on Unix systems or `C:\` (or another drive) on
+ Windows.
- Example: ``%/s: C:/Desktop Files/foo_test.s.tmp``
+`%{fs-sep}`
-``%{s:real}, %{S:real}, %{t:real}, %{T:real}``
-``%{/s:real}, %{/S:real}, %{/t:real}, %{/T:real}``
+: Expands to the file system separator, i.e. `/` or `\` on Windows.
- Act like the corresponding substitution, including with ``/``, but use
- the real path by expanding all symbolic links and substitute drives.
+`%/s, %/S, %/t, %/T`
- Example: ``%s: S:\foo_test.s.tmp``
+: Act like the corresponding substitution above but replace any `\`
+ character with a `/`. This is useful to normalize path separators.
- Example: ``%{/s:real}: C:/SDrive/foo_test.s.tmp``
+ Example: `%s: C:\Desktop Files/foo_test.s.tmp`
-``%:s, %:S, %:t, %:T``
+ Example: `%/s: C:/Desktop Files/foo_test.s.tmp`
- Act like the corresponding substitution above but remove colons at
- the beginning of Windows paths. This is useful to allow concatenation
- of absolute paths on Windows to produce a legal path.
+`%{s:real}, %{S:real}, %{t:real}, %{T:real}` \
+`%{/s:real}, %{/S:real}, %{/t:real}, %{/T:real}`
- Example: ``%s: C:\Desktop Files\foo_test.s.tmp``
+: Act like the corresponding substitution, including with `/`, but use
+ the real path by expanding all symbolic links and substitute drives.
- Example: ``%:s: C\Desktop Files\foo_test.s.tmp``
+ Example: `%s: S:\foo_test.s.tmp`
-``%errc_<ERRCODE>``
+ Example: `%{/s:real}: C:/SDrive/foo_test.s.tmp`
- Some error messages may be substituted to allow different spellings
- based on the host platform.
+`%:s, %:S, %:t, %:T`
- The following error codes are currently supported:
- ENOENT, EISDIR, EINVAL, EACCES.
+: Act like the corresponding substitution above but remove colons at
+ the beginning of Windows paths. This is useful to allow concatenation
+ of absolute paths on Windows to produce a legal path.
- Example: ``Linux %errc_ENOENT: No such file or directory``
+ Example: `%s: C:\Desktop Files\foo_test.s.tmp`
- Example: ``Windows %errc_ENOENT: no such file or directory``
+ Example: `%:s: C\Desktop Files\foo_test.s.tmp`
-``%if feature %{<if branch>%} %else %{<else branch>%}``
+`%errc_<ERRCODE>`
- Conditional substitution: if ``feature`` is available it expands to
- ``<if branch>``, otherwise it expands to ``<else branch>``.
- ``%else %{<else branch>%}`` is optional and treated like ``%else %{%}``
- if not present.
+: Some error messages may be substituted to allow different spellings
+ based on the host platform.
-``%(line)``, ``%(line+<number>)``, ``%(line-<number>)``
+ The following error codes are currently supported:
+ ENOENT, EISDIR, EINVAL, EACCES.
- The number of the line where this substitution is used, with an
- optional integer offset. These expand only if they appear
- immediately in ``RUN:``, ``DEFINE:``, and ``REDEFINE:`` directives.
- Occurrences in substitutions defined elsewhere are never expanded.
- For example, this can be used in tests with multiple ``RUN`` lines,
- which reference the test file's line numbers.
+ Example: `Linux %errc_ENOENT: No such file or directory`
+
+ Example: `Windows %errc_ENOENT: no such file or directory`
+
+`%if feature %{<if branch>%} %else %{<else branch>%}`
+
+: Conditional substitution: if `feature` is available it expands to
+ `<if branch>`, otherwise it expands to `<else branch>`.
+ `%else %{<else branch>%}` is optional and treated like `%else %{%}`
+ if not present.
+
+`%(line)`, `%(line+<number>)`, `%(line-<number>)`
+
+: The number of the line where this substitution is used, with an
+ optional integer offset. These expand only if they appear
+ immediately in `RUN:`, `DEFINE:`, and `REDEFINE:` directives.
+ Occurrences in substitutions defined elsewhere are never expanded.
+ For example, this can be used in tests with multiple `RUN` lines,
+ which reference the test file's line numbers.
**LLVM-specific substitutions:**
-``%shlibext``
- The suffix for the host platforms shared library files. This includes the
- period as the first character.
+`%shlibext`
+
+: The suffix for the host platforms shared library files. This includes the
+ period as the first character.
- Example: ``.so`` (Linux), ``.dylib`` (macOS), ``.dll`` (Windows)
+ Example: `.so` (Linux), `.dylib` (macOS), `.dll` (Windows)
-``%exeext``
- The suffix for the host platforms executable files. This includes the
- period as the first character.
+`%exeext`
- Example: ``.exe`` (Windows), empty on Linux.
+: The suffix for the host platforms executable files. This includes the
+ period as the first character.
+
+ Example: `.exe` (Windows), empty on Linux.
**Clang-specific substitutions:**
-``%clang``
- Invokes the Clang driver.
+`%clang`
+
+: Invokes the Clang driver.
-``%clang_cpp``
- Invokes the Clang driver as the preprocessor.
+`%clang_cpp`
-``%clang_cl``
- Invokes the CL-compatible Clang driver.
+: Invokes the Clang driver as the preprocessor.
-``%clangxx``
- Invokes the G++-compatible Clang driver.
+`%clang_cl`
-``%clang_cc1``
- Invokes the Clang frontend.
+: Invokes the CL-compatible Clang driver.
-``%itanium_abi_triple``, ``%ms_abi_triple``
- These substitutions can be used to get the current target triple adjusted to
- the desired ABI. For example, if the test suite is running with the
- ``i686-pc-win32`` target, ``%itanium_abi_triple`` will expand to
- ``i686-pc-mingw32``. This allows a test to run with a specific ABI without
- constraining it to a specific triple.
+`%clangxx`
+
+: Invokes the G++-compatible Clang driver.
+
+`%clang_cc1`
+
+: Invokes the Clang frontend.
+
+`%itanium_abi_triple`, `%ms_abi_triple`
+
+: These substitutions can be used to get the current target triple adjusted to
+ the desired ABI. For example, if the test suite is running with the
+ `i686-pc-win32` target, `%itanium_abi_triple` will expand to
+ `i686-pc-mingw32`. This allows a test to run with a specific ABI without
+ constraining it to a specific triple.
**FileCheck-specific substitutions:**
-``%ProtectFileCheckOutput``
- This should precede a ``FileCheck`` call if and only if the call's textual
- output affects test results. It's usually easy to tell: just look for
- redirection or piping of the ``FileCheck`` call's stdout or stderr.
+`%ProtectFileCheckOutput`
+
+: This should precede a `FileCheck` call if and only if the call's textual
+ output affects test results. It's usually easy to tell: just look for
+ redirection or piping of the `FileCheck` call's stdout or stderr.
-.. _Test-specific substitutions:
+(Test-specific substitutions)=
**Test-specific substitutions:**
Additional substitutions can be defined as follows:
-- Lit configuration files (e.g., ``lit.cfg`` or ``lit.local.cfg``) can define
+- Lit configuration files (e.g., `lit.cfg` or `lit.local.cfg`) can define
substitutions for all tests in a test directory. They do so by extending the
- substitution list, ``config.substitutions``. Each item in the list is a tuple
+ substitution list, `config.substitutions`. Each item in the list is a tuple
consisting of a pattern and its replacement, which lit applies as plain text
- (even if it contains sequences that Python's ``re.sub`` considers to be
+ (even if it contains sequences that Python's `re.sub` considers to be
escape sequences).
- To define substitutions within a single test file, lit supports the
- ``DEFINE:`` and ``REDEFINE:`` directives, described in detail below. So that
+ `DEFINE:` and `REDEFINE:` directives, described in detail below. So that
they have no effect on other test files, these directives modify a copy of the
substitution list that is produced by lit configuration files.
For example, the following directives can be inserted into a test file to define
-``%{cflags}`` and ``%{fcflags}`` substitutions with empty initial values, which
-serve as the parameters of another newly defined ``%{check}`` substitution:
+`%{cflags}` and `%{fcflags}` substitutions with empty initial values, which
+serve as the parameters of another newly defined `%{check}` substitution:
-.. code-block:: llvm
+```llvm
+; DEFINE: %{cflags} =
+; DEFINE: %{fcflags} =
- ; DEFINE: %{cflags} =
- ; DEFINE: %{fcflags} =
-
- ; DEFINE: %{check} = \
- ; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{cflags} \
- ; DEFINE: -emit-llvm -o - %s | \
- ; DEFINE: FileCheck %{fcflags} %s
+; DEFINE: %{check} = \
+; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{cflags} \
+; DEFINE: -emit-llvm -o - %s | \
+; DEFINE: FileCheck %{fcflags} %s
+```
Alternatively, the above substitutions can be defined in a lit configuration
file to be shared with other test files. Either way, the test file can then
specify directives like the following to redefine the parameter substitutions as
-desired before each use of ``%{check}`` in a ``RUN:`` line:
-
-.. code-block:: llvm
+desired before each use of `%{check}` in a `RUN:` line:
- ; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0 -fopenmp-simd
- ; REDEFINE: %{fcflags} = -check-prefix=SIMD
- ; RUN: %{check}
+```llvm
+; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0 -fopenmp-simd
+; REDEFINE: %{fcflags} = -check-prefix=SIMD
+; RUN: %{check}
- ; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu -fopenmp-simd
- ; REDEFINE: %{fcflags} = -check-prefix=SIMD
- ; RUN: %{check}
+; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu -fopenmp-simd
+; REDEFINE: %{fcflags} = -check-prefix=SIMD
+; RUN: %{check}
- ; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0
- ; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD
- ; RUN: %{check}
+; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0
+; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD
+; RUN: %{check}
- ; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu
- ; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD
- ; RUN: %{check}
+; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu
+; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD
+; RUN: %{check}
+```
-Besides providing initial values, the initial ``DEFINE:`` directives for the
+Besides providing initial values, the initial `DEFINE:` directives for the
parameter substitutions in the above example serve a second purpose: they
-establish the substitution order so that both ``%{check}`` and its parameters
+establish the substitution order so that both `%{check}` and its parameters
expand as desired. There's a simple way to remember the required definition
order in a test file: define a substitution before any substitution that might
refer to it.
In general, substitution expansion behaves as follows:
-- Upon arriving at each ``RUN:`` line, lit expands all substitutions in that
- ``RUN:`` line using their current values from the substitution list. No
- substitution expansion is performed immediately at ``DEFINE:`` and
- ``REDEFINE:`` directives except ``%(line)``, ``%(line+<number>)``, and
- ``%(line-<number>)``.
-- When expanding substitutions in a ``RUN:`` line, lit makes only one pass
+- Upon arriving at each `RUN:` line, lit expands all substitutions in that
+ `RUN:` line using their current values from the substitution list. No
+ substitution expansion is performed immediately at `DEFINE:` and
+ `REDEFINE:` directives except `%(line)`, `%(line+<number>)`, and
+ `%(line-<number>)`.
+- When expanding substitutions in a `RUN:` line, lit makes only one pass
through the substitution list by default. In this case, a substitution must
have been inserted earlier in the substitution list than any substitution
appearing in its value in order for the latter to expand. (For greater
flexibility, you can enable multiple passes through the substitution list by
- setting `recursiveExpansionLimit`_ in a lit configuration file.)
+ setting {ref}`recursiveExpansionLimit <recursiveexpansionlimit>` in a lit
+ configuration file.)
- While lit configuration files can insert anywhere in the substitution list,
- the insertion behavior of the ``DEFINE:`` and ``REDEFINE:`` directives is
+ the insertion behavior of the `DEFINE:` and `REDEFINE:` directives is
specified below and is designed specifically for the use case presented in the
example above.
- Defining a substitution in terms of itself, whether directly or via other
substitutions, should be avoided. It usually produces an infinitely recursive
definition that cannot be fully expanded. It does *not* define the
- substitution in terms of its previous value, even when using ``REDEFINE:``.
+ substitution in terms of its previous value, even when using `REDEFINE:`.
-The relationship between the ``DEFINE:`` and ``REDEFINE:`` directive is
+The relationship between the `DEFINE:` and `REDEFINE:` directive is
analogous to the relationship between a variable declaration and variable
assignment in many programming languages:
-- ``DEFINE: %{name} = value``
+- `DEFINE: %{name} = value`
This directive assigns the specified value to a new substitution whose
- pattern is ``%{name}``, or it reports an error if there is already a
- substitution whose pattern contains ``%{name}`` because that could produce
+ pattern is `%{name}`, or it reports an error if there is already a
+ substitution whose pattern contains `%{name}` because that could produce
confusing expansions (e.g., a lit configuration file might define a
- substitution with the pattern ``%{name}\[0\]``). The new substitution is
+ substitution with the pattern `%{name}\[0\]`). The new substitution is
inserted at the start of the substitution list so that it will expand first.
Thus, its value can contain any substitution previously defined, whether in
the same test file or in a lit configuration file, and both will expand.
-- ``REDEFINE: %{name} = value``
+- `REDEFINE: %{name} = value`
This directive assigns the specified value to an existing substitution whose
- pattern is ``%{name}``, or it reports an error if there are no substitutions
+ pattern is `%{name}`, or it reports an error if there are no substitutions
with that pattern or if there are multiple substitutions whose patterns
- contain ``%{name}``. The substitution's current position in the substitution
+ contain `%{name}`. The substitution's current position in the substitution
list does not change so that expansion order relative to other existing
substitutions is preserved.
-The following properties apply to both the ``DEFINE:`` and ``REDEFINE:``
+The following properties apply to both the `DEFINE:` and `REDEFINE:`
directives:
- **Substitution name**: In the directive, whitespace immediately before or
- after ``%{name}`` is optional and discarded. ``%{name}`` must start with
- ``%{``, it must end with ``}``, and the rest must start with a letter or
+ after `%{name}` is optional and discarded. `%{name}` must start with
+ `%{`, it must end with `}`, and the rest must start with a letter or
underscore and contain only alphanumeric characters, hyphens, underscores, and
colons. This syntax has a few advantages:
- - It is impossible for ``%{name}`` to contain sequences that are special in
- Python's ``re.sub`` patterns. Otherwise, attempting to specify
- ``%{name}`` as a substitution pattern in a lit configuration file could
+ - It is impossible for `%{name}` to contain sequences that are special in
+ Python's `re.sub` patterns. Otherwise, attempting to specify
+ `%{name}` as a substitution pattern in a lit configuration file could
produce confusing expansions.
- The braces help avoid the possibility that another substitution's pattern
- will match part of ``%{name}`` or vice-versa, producing confusing
+ will match part of `%{name}` or vice-versa, producing confusing
expansions. However, the patterns of substitutions defined by lit
configuration files and by lit itself are not restricted to this form, so
overlaps are still theoretically possible.
- **Substitution value**: The value includes all text from the first
- non-whitespace character after ``=`` to the last non-whitespace character. If
- there is no non-whitespace character after ``=``, the value is the empty
- string. Escape sequences that can appear in Python ``re.sub`` replacement
+ non-whitespace character after `=` to the last non-whitespace character. If
+ there is no non-whitespace character after `=`, the value is the empty
+ string. Escape sequences that can appear in Python `re.sub` replacement
strings are treated as plain text in the value.
- **Line continuations**: If the last non-whitespace character on the line after
- ``:`` is ``\``, then the next directive must use the same directive keyword
- (e.g., ``DEFINE:``) , and it is an error if there is no additional directive.
+ `:` is `\`, then the next directive must use the same directive keyword
+ (e.g., `DEFINE:`) , and it is an error if there is no additional directive.
That directive serves as a continuation. That is, before following the rules
- above to parse the text after ``:`` in either directive, lit joins that text
- together to form a single directive, replaces the ``\`` with a single space,
+ above to parse the text after `:` in either directive, lit joins that text
+ together to form a single directive, replaces the `\` with a single space,
and removes any other whitespace that is now adjacent to that space. A
continuation can be continued in the same manner. A continuation containing
- only whitespace after its ``:`` is an error.
+ only whitespace after its `:` is an error.
-.. _recursiveExpansionLimit:
+(recursiveExpansionLimit)=
**recursiveExpansionLimit:**
-As described in the previous section, when expanding substitutions in a ``RUN:``
+As described in the previous section, when expanding substitutions in a `RUN:`
line, lit makes only one pass through the substitution list by default. Thus,
if substitutions are not defined in the proper order, some will remain in the
-``RUN:`` line unexpanded. For example, the following directives refer to
-``%{inner}`` within ``%{outer}`` but do not define ``%{inner}`` until after
-``%{outer}``:
+`RUN:` line unexpanded. For example, the following directives refer to
+`%{inner}` within `%{outer}` but do not define `%{inner}` until after
+`%{outer}`:
-.. code-block:: llvm
+```llvm
+; By default, this definition order does not enable full expansion.
- ; By default, this definition order does not enable full expansion.
+; DEFINE: %{outer} = %{inner}
+; DEFINE: %{inner} = expanded
- ; DEFINE: %{outer} = %{inner}
- ; DEFINE: %{inner} = expanded
+; RUN: echo '%{outer}'
+```
- ; RUN: echo '%{outer}'
+`DEFINE:` inserts substitutions at the start of the substitution list, so
+`%{inner}` expands first but has no effect because the original `RUN:` line
+does not contain `%{inner}`. Next, `%{outer}` expands, and the output of
+the `echo` command becomes:
-``DEFINE:`` inserts substitutions at the start of the substitution list, so
-``%{inner}`` expands first but has no effect because the original ``RUN:`` line
-does not contain ``%{inner}``. Next, ``%{outer}`` expands, and the output of
-the ``echo`` command becomes:
-
-.. code-block:: shell
-
- %{inner}
+```shell
+%{inner}
+```
Of course, one way to fix this simple case is to reverse the definitions of
-``%{outer}`` and ``%{inner}``. However, if a test has a complex set of
+`%{outer}` and `%{inner}`. However, if a test has a complex set of
substitutions that can all reference each other, there might not exist a
sufficient substitution order.
To address such use cases, lit configuration files support
-``config.recursiveExpansionLimit``, which can be set to a non-negative integer
+`config.recursiveExpansionLimit`, which can be set to a non-negative integer
to specify the maximum number of passes through the substitution list. Thus, in
the above example, setting the limit to 2 would cause lit to make a second pass
-that expands ``%{inner}`` in the ``RUN:`` line, and the output from the ``echo``
+that expands `%{inner}` in the `RUN:` line, and the output from the `echo`
command would then be:
-.. code-block:: shell
+```shell
+expanded
+```
- expanded
-
-To improve performance, lit will stop making passes when it notices the ``RUN:``
+To improve performance, lit will stop making passes when it notices the `RUN:`
line has stopped changing. In the above example, setting the limit higher than
2 is thus harmless.
To facilitate debugging, after reaching the limit, lit will make one extra pass
-and report an error if the ``RUN:`` line changes again. In the above example,
+and report an error if the `RUN:` line changes again. In the above example,
setting the limit to 1 will thus cause lit to report an error instead of
producing incorrect output.
-Options
--------
+### Options
The llvm lit configuration allows some things to be customized with user options:
-``llc``, ``opt``, ...
- Substitute the respective llvm tool name with a custom command line. This
+`llc`, `opt`, ...
+
+: Substitute the respective llvm tool name with a custom command line. This
allows to specify custom paths and default arguments for these tools.
Example:
% llvm-lit "-Dllc=llc -verify-machineinstrs"
-``run_long_tests``
- Enable the execution of long running tests.
+`run_long_tests`
-``llvm_site_config``
- Load the specified lit configuration instead of the default one.
+: Enable the execution of long running tests.
+`llvm_site_config`
-Other Features
---------------
+: Load the specified lit configuration instead of the default one.
-To make ``RUN`` line writing easier, several helper programs are available. These
-helpers are in the ``PATH`` when running tests, so you can just call them using
+
+### Other Features
+
+To make `RUN` line writing easier, several helper programs are available. These
+helpers are in the `PATH` when running tests, so you can just call them using
their name. For example:
-``not``
- This program runs its arguments and then inverts the result code from it.
- Zero result codes become 1. Non-zero result codes become 0.
+`not`
+
+: This program runs its arguments and then inverts the result code from it.
+ Zero result codes become 1. Non-zero result codes become 0.
-To make the output more useful, :program:`lit` will scan
+To make the output more useful, {program}`lit` will scan
the lines of the test case for ones that contain a pattern that matches
-``PR[0-9]+``. This is the syntax for specifying a PR (Problem Report) number
+`PR[0-9]+`. This is the syntax for specifying a PR (Problem Report) number
that is related to the test case. The number after "PR" specifies the
LLVM Bugzilla number. When a PR number is specified, it will be used in
the pass/fail reporting. This is useful to quickly get some context when
@@ -1110,7 +1115,7 @@ a test fails.
Finally, any line that contains "END." will cause the special
interpretation of lines to terminate. This is generally done right after
-the last ``RUN:`` line. This has two side effects:
+the last `RUN:` line. This has two side effects:
(a) it prevents special interpretation of lines that are part of the test
program, not the instructions to the test case, and
diff --git a/llvm/docs/UserGuides.md b/llvm/docs/UserGuides.md
index 1a5ff1e0e06dd..72ebd3b9cedce 100644
--- a/llvm/docs/UserGuides.md
+++ b/llvm/docs/UserGuides.md
@@ -1,343 +1,398 @@
-User Guides
-===========
+# User Guides
NOTE: If you are a user who is only interested in using an LLVM-based compiler,
-you should look into `Clang <https://clang.llvm.org>`_ instead. The
+you should look into [Clang](https://clang.llvm.org) instead. The
documentation here is intended for users who have a need to work with the
intermediate LLVM representation.
-.. contents::
- :local:
-
-.. toctree::
- :hidden:
-
- HowToBuildOnARM
- HowToBuildWithPGO
- HowToCrossCompileLLVM
- CoverageMappingFormat
- CFIVerify
- BuildingADistribution
- CMake
- Docker
- SupportLibrary
- AdvancedBuilds
- WritingAnLLVMNewPMPass
- WritingAnLLVMPass
- Passes
- StackSafetyAnalysis
- MergeFunctions
- AliasAnalysis
- MemorySSA
- MemProf
- LoopTerminology
- CycleTerminology
- Vectorizers
- LinkTimeOptimization
- DTLTO
- GoldPlugin
- Remarks
- SourceLevelDebugging
- HowToUpdateDebugInfo
- Instrumentor
- InstrRefDebugInfo
- RemoveDIsDebugInfo
- KeyInstructionsDebugInfo
- InstrProfileFormat
- InstCombineContributorGuide
- WritingAnLLVMBackend
- CodeGenerator
- TableGen/index
- GlobalISel/MIRPatterns
- MCJITDesignAndImplementation
- ORCv2
- JITLink
- DebuggingJITedCode
- CommandLine
- ExtendingLLVM
- AddingConstrainedIntrinsics
- HowToBuildWindowsItaniumPrograms
- HowToCrossCompileBuiltinsOnArm
- BigEndianNEON
- AArch64SME
- CompileCudaWithLLVM
- NVPTXUsage
- AMDGPUUsage
- AMDGPUAsyncOperations
- AMDGPUDwarfExtensionsForHeterogeneousDebugging
- AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack
- AMDGPUExecutionSynchronization
- AMDGPUMemoryModel
- SPIRVUsage
- DirectXUsage
- RISCVUsage
- RISCV/RISCVVectorExtension
- RISCV/RISCVVCIX
- SandboxIR
- Telemetry
- LFI
- AdminTasks
- Benchmarking
- CMakePrimer
- CodeOfConduct
- FatLTO
- GitHub
- MarkdownQuickstartTemplate
- MisExpect
- OpaquePointers
- NewPassManager
- ReportingGuide
- ResponseGuide
- TableGenFundamentals
- yaml2obj
-
-Clang
------
-
-:doc:`HowToBuildOnARM`
- Notes on building and testing LLVM/Clang on ARM.
-
-:doc:`HowToBuildWithPGO`
- Notes on building LLVM/Clang with PGO.
-
-:doc:`HowToCrossCompileLLVM`
- Notes on cross-building and testing LLVM/Clang.
-
-`How to build the C, C++, ObjC, and ObjC++ front end`__
- Instructions for building the clang front-end from source.
-
- .. __: https://clang.llvm.org/get_started.html
-
-:doc:`CoverageMappingFormat`
+```{contents}
+:local:
+```
+
+```{toctree}
+:hidden:
+
+HowToBuildOnARM
+HowToBuildWithPGO
+HowToCrossCompileLLVM
+CoverageMappingFormat
+CFIVerify
+BuildingADistribution
+CMake
+Docker
+SupportLibrary
+AdvancedBuilds
+WritingAnLLVMNewPMPass
+WritingAnLLVMPass
+Passes
+StackSafetyAnalysis
+MergeFunctions
+AliasAnalysis
+MemorySSA
+MemProf
+LoopTerminology
+CycleTerminology
+Vectorizers
+LinkTimeOptimization
+DTLTO
+GoldPlugin
+Remarks
+SourceLevelDebugging
+HowToUpdateDebugInfo
+Instrumentor
+InstrRefDebugInfo
+RemoveDIsDebugInfo
+KeyInstructionsDebugInfo
+InstrProfileFormat
+InstCombineContributorGuide
+WritingAnLLVMBackend
+CodeGenerator
+TableGen/index
+GlobalISel/MIRPatterns
+MCJITDesignAndImplementation
+ORCv2
+JITLink
+DebuggingJITedCode
+CommandLine
+ExtendingLLVM
+AddingConstrainedIntrinsics
+HowToBuildWindowsItaniumPrograms
+HowToCrossCompileBuiltinsOnArm
+BigEndianNEON
+AArch64SME
+CompileCudaWithLLVM
+NVPTXUsage
+AMDGPUUsage
+AMDGPUAsyncOperations
+AMDGPUDwarfExtensionsForHeterogeneousDebugging
+AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack
+AMDGPUExecutionSynchronization
+AMDGPUMemoryModel
+SPIRVUsage
+DirectXUsage
+RISCVUsage
+RISCV/RISCVVectorExtension
+RISCV/RISCVVCIX
+SandboxIR
+Telemetry
+LFI
+AdminTasks
+Benchmarking
+CMakePrimer
+CodeOfConduct
+FatLTO
+GitHub
+MarkdownQuickstartTemplate
+MisExpect
+OpaquePointers
+NewPassManager
+ReportingGuide
+ResponseGuide
+TableGenFundamentals
+yaml2obj
+```
+
+## Clang
+
+- {doc}`HowToBuildOnARM`
+
+ Notes on building and testing LLVM/Clang on ARM.
+
+- {doc}`HowToBuildWithPGO`
+
+ Notes on building LLVM/Clang with PGO.
+
+- {doc}`HowToCrossCompileLLVM`
+
+ Notes on cross-building and testing LLVM/Clang.
+
+- [How to build the C, C++, ObjC, and ObjC++ front end](https://clang.llvm.org/get_started.html)
+
+ Instructions for building the clang front-end from source.
+
+- {doc}`CoverageMappingFormat`
+
This describes the format and encoding used for LLVM’s code coverage mapping.
-:doc:`CFIVerify`
+- {doc}`CFIVerify`
+
A description of the verification tool for Control Flow Integrity.
-LLVM Builds and Distributions
------------------------------
+## LLVM Builds and Distributions
+
+- {doc}`BuildingADistribution`
-:doc:`BuildingADistribution`
A best-practices guide for using LLVM's CMake build system to package and
distribute LLVM-based tools.
-:doc:`CMake`
- An addendum to the main Getting Started guide for those using the `CMake
- build system <http://www.cmake.org>`_.
+- {doc}`CMake`
+
+ An addendum to the main Getting Started guide for those using the [CMake
+ build system](http://www.cmake.org).
+
+- {doc}`Docker`
+
+ A reference for using Dockerfiles provided with LLVM.
+
+- {doc}`Support Library <SupportLibrary>`
+
+ This document describes the LLVM Support Library (`lib/Support`) and
+ how to keep LLVM source code portable.
-:doc:`Docker`
- A reference for using Dockerfiles provided with LLVM.
+- {doc}`AdvancedBuilds`
-:doc:`Support Library <SupportLibrary>`
- This document describes the LLVM Support Library (``lib/Support``) and
- how to keep LLVM source code portable.
+ This document describes more advanced build configurations.
-:doc:`AdvancedBuilds`
- This document describes more advanced build configurations.
+## Optimizations
-Optimizations
--------------
+- {doc}`WritingAnLLVMNewPMPass`
-:doc:`WritingAnLLVMNewPMPass`
- Information on how to write LLVM transformations under the new pass
- manager.
+ Information on how to write LLVM transformations under the new pass
+ manager.
-:doc:`WritingAnLLVMPass`
- Information on how to write LLVM transformations and analyses under the
- legacy pass manager.
+- {doc}`WritingAnLLVMPass`
-:doc:`Passes`
- A list of optimizations and analyses implemented in LLVM.
+ Information on how to write LLVM transformations and analyses under the
+ legacy pass manager.
+
+- {doc}`Passes`
+
+ A list of optimizations and analyses implemented in LLVM.
+
+- {doc}`StackSafetyAnalysis`
-:doc:`StackSafetyAnalysis`
This document describes the design of the stack safety analysis of local
variables.
-:doc:`MergeFunctions`
+- {doc}`MergeFunctions`
+
Describes functions merging optimization.
-:doc:`AliasAnalysis`
- Information on how to write a new alias analysis implementation or how to
- use existing analyses.
+- {doc}`AliasAnalysis`
+
+ Information on how to write a new alias analysis implementation or how to
+ use existing analyses.
+
+- {doc}`MemorySSA`
+
+ Information about the MemorySSA utility in LLVM, as well as how to use it.
-:doc:`MemorySSA`
- Information about the MemorySSA utility in LLVM, as well as how to use it.
+- {doc}`MemProf`
-:doc:`MemProf`
- User guide and internals of MemProf, profile guided optimizations for memory.
+ User guide and internals of MemProf, profile guided optimizations for memory.
+
+- {doc}`LoopTerminology`
-:doc:`LoopTerminology`
A document describing Loops and associated terms as used in LLVM.
-:doc:`CycleTerminology`
+- {doc}`CycleTerminology`
+
A document describing cycles as a generalization of loops.
-:doc:`Vectorizers`
- This document describes the current status of vectorization in LLVM.
+- {doc}`Vectorizers`
+
+ This document describes the current status of vectorization in LLVM.
+
+- {doc}`LinkTimeOptimization`
+
+ This document describes the interface between LLVM intermodular optimizer
+ and the linker and its design
+
+- {doc}`DTLTO`
+
+ This document describes the DTLTO implementation, which allows for
+ distributing ThinLTO backend compilations without requiring support from
+ the build system.
+
+- {doc}`GoldPlugin`
+
+ How to build your programs with link-time optimization on Linux.
+
+- {doc}`Remarks`
+
+ A reference on the implementation of remarks in LLVM.
+
+- {doc}`Source Level Debugging with LLVM <SourceLevelDebugging>`
+
+ This document describes the design and philosophy behind the LLVM
+ source-level debugger.
+
+- {doc}`How to Update Debug Info <HowToUpdateDebugInfo>`
+
+ This document specifies how to correctly update debug info in various kinds
+ of code transformations.
-:doc:`LinkTimeOptimization`
- This document describes the interface between LLVM intermodular optimizer
- and the linker and its design
+- {doc}`InstrRefDebugInfo`
-:doc:`DTLTO`
- This document describes the DTLTO implementation, which allows for
- distributing ThinLTO backend compilations without requiring support from
- the build system.
+ This document explains how LLVM uses value tracking, or instruction
+ referencing, to determine variable locations for debug info in the final
+ stages of compilation.
-:doc:`GoldPlugin`
- How to build your programs with link-time optimization on Linux.
+- {doc}`RemoveDIsDebugInfo`
-:doc:`Remarks`
- A reference on the implementation of remarks in LLVM.
+ This is a migration guide describing how to move from debug info using
+ intrinsics such as dbg.value to using the non-instruction DbgRecord object.
-:doc:`Source Level Debugging with LLVM <SourceLevelDebugging>`
- This document describes the design and philosophy behind the LLVM
- source-level debugger.
+- {doc}`KeyInstructionsDebugInfo`
-:doc:`How to Update Debug Info <HowToUpdateDebugInfo>`
- This document specifies how to correctly update debug info in various kinds
- of code transformations.
+ This document explains how the debug info feature Key Instructions is
+ implemented in LLVM.
-:doc:`InstrRefDebugInfo`
- This document explains how LLVM uses value tracking, or instruction
- referencing, to determine variable locations for debug info in the final
- stages of compilation.
+- {doc}`InstrProfileFormat`
-:doc:`RemoveDIsDebugInfo`
- This is a migration guide describing how to move from debug info using
- intrinsics such as dbg.value to using the non-instruction DbgRecord object.
+ This document explains two binary formats of instrumentation-based profiles.
-:doc:`KeyInstructionsDebugInfo`
- This document explains how the debug info feature Key Instructions is
- implemented in LLVM.
+- {doc}`InstCombineContributorGuide`
-:doc:`InstrProfileFormat`
- This document explains two binary formats of instrumentation-based profiles.
+ This document specifies guidelines for contributions for InstCombine and
+ related passes.
-:doc:`InstCombineContributorGuide`
- This document specifies guidelines for contributions for InstCombine and
- related passes.
+- {doc}`Instrumentor`
-:doc:`Instrumentor`
- A comprehensive guide to the highly configurable Instrumentor pass for custom
- program instrumentation, including the interactive configuration wizard.
+ A comprehensive guide to the highly configurable Instrumentor pass for custom
+ program instrumentation, including the interactive configuration wizard.
+## Code Generation
-Code Generation
----------------
+- {doc}`WritingAnLLVMBackend`
-:doc:`WritingAnLLVMBackend`
- Information on how to write LLVM backends for machine targets.
+ Information on how to write LLVM backends for machine targets.
-:doc:`CodeGenerator`
- The design and implementation of the LLVM code generator. Useful if you are
- working on retargetting LLVM to a new architecture, designing a new codegen
- pass, or enhancing existing components.
+- {doc}`CodeGenerator`
-:doc:`TableGen <TableGen/index>`
- Describes the TableGen tool, which is used heavily by the LLVM code
- generator.
+ The design and implementation of the LLVM code generator. Useful if you are
+ working on retargetting LLVM to a new architecture, designing a new codegen
+ pass, or enhancing existing components.
-==========
-GlobalISel
-==========
+- {doc}`TableGen <TableGen/index>`
-:doc:`MIRPatterns <GlobalISel/MIRPatterns>`
- Describes the design of MIR Patterns and how to use them.
+ Describes the TableGen tool, which is used heavily by the LLVM code
+ generator.
-===
-JIT
-===
+### GlobalISel
-:doc:`MCJITDesignAndImplementation`
- Describes the inner workings of MCJIT execution engine.
+- {doc}`MIRPatterns <GlobalISel/MIRPatterns>`
-:doc:`ORCv2`
- Describes the design and implementation of the ORC APIs, including some
- usage examples, and a guide for users transitioning from ORCv1 to ORCv2.
+ Describes the design of MIR Patterns and how to use them.
-:doc:`JITLink`
- Describes the design and APIs for the JITLink library, ORC's new JIT
- linker.
+### JIT
-:doc:`DebuggingJITedCode`
- How to debug JITed code with GDB.
+- {doc}`MCJITDesignAndImplementation`
-Additional Topics
------------------
+ Describes the inner workings of MCJIT execution engine.
+
+- {doc}`ORCv2`
+
+ Describes the design and implementation of the ORC APIs, including some
+ usage examples, and a guide for users transitioning from ORCv1 to ORCv2.
+
+- {doc}`JITLink`
+
+ Describes the design and APIs for the JITLink library, ORC's new JIT
+ linker.
+
+- {doc}`DebuggingJITedCode`
+
+ How to debug JITed code with GDB.
+
+## Additional Topics
+
+- {doc}`CommandLine`
-:doc:`CommandLine`
Provides information on using the command line parsing library.
-:doc:`ExtendingLLVM`
+- {doc}`ExtendingLLVM`
+
Look here to see how to add instructions and intrinsics to LLVM.
-:doc:`AddingConstrainedIntrinsics`
- Gives the steps necessary when adding a new constrained math intrinsic
- to LLVM.
+- {doc}`AddingConstrainedIntrinsics`
+
+ Gives the steps necessary when adding a new constrained math intrinsic
+ to LLVM.
+
+- {doc}`HowToBuildWindowsItaniumPrograms`
+
+ Notes on assembling a Windows Itanium environment.
-:doc:`HowToBuildWindowsItaniumPrograms`
- Notes on assembling a Windows Itanium environment.
+- {doc}`HowToCrossCompileBuiltinsOnArm`
-:doc:`HowToCrossCompileBuiltinsOnArm`
- Notes on cross-building and testing the compiler-rt builtins for Arm.
+ Notes on cross-building and testing the compiler-rt builtins for Arm.
+
+- {doc}`BigEndianNEON`
-:doc:`BigEndianNEON`
LLVM's support for generating NEON instructions on big endian ARM targets is
somewhat nonintuitive. This document explains the implementation and rationale.
-:doc:`AArch64SME`
+- {doc}`AArch64SME`
+
LLVM's support for AArch64 SME ACLE and ABI.
-:doc:`CompileCudaWithLLVM`
+- {doc}`CompileCudaWithLLVM`
+
LLVM support for CUDA.
-:doc:`NVPTXUsage`
- This document describes using the NVPTX backend to compile GPU kernels.
+- {doc}`NVPTXUsage`
+
+ This document describes using the NVPTX backend to compile GPU kernels.
+
+- {doc}`AMDGPUUsage`
+
+ This document describes using the AMDGPU backend to compile GPU kernels.
+
+- {doc}`AMDGPUAsyncOperations`
+
+ Builtins for invoking asynchronous data transfer operations in AMD GPUs.
+
+- {doc}`AMDGPUMemoryModel`
+
+ This document describes *AMDGPU Memory Model* which overrides the
+ {ref}`LLVM memory model <memmodel>` when a program is compiled for the
+ AMDGPU target.
+
+- {doc}`AMDGPUDwarfExtensionsForHeterogeneousDebugging`
+
+ This document describes DWARF extensions to support heterogeneous debugging
+ for targets such as the AMDGPU backend.
+
+- {doc}`AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack`
+
+ This document describes a DWARF extension to allow location descriptions on
+ the DWARF expression stack. It is part of
+ {doc}`AMDGPUDwarfExtensionsForHeterogeneousDebugging`.
+
+- {doc}`AMDGPUExecutionSynchronization`
+
+ This document describes how execution of threads can be synchronized on AMD GPUs.
+
+- {doc}`SPIRVUsage`
+
+ This document describes using the SPIR-V target to compile GPU kernels.
-:doc:`AMDGPUUsage`
- This document describes using the AMDGPU backend to compile GPU kernels.
+- {doc}`DirectXUsage`
-:doc:`AMDGPUAsyncOperations`
- Builtins for invoking asynchronous data transfer operations in AMD GPUs.
+ This document describes using the DirectX target to compile GPU code for the
+ DirectX runtime.
-:doc:`AMDGPUMemoryModel`
- This document describes *AMDGPU Memory Model* which overrides the :ref:`LLVM
- memory model<memmodel>` when a program is compiled for the AMDGPU target.
+- {doc}`RISCVUsage`
-:doc:`AMDGPUDwarfExtensionsForHeterogeneousDebugging`
- This document describes DWARF extensions to support heterogeneous debugging
- for targets such as the AMDGPU backend.
+ This document describes using the RISC-V target.
-:doc:`AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack`
- This document describes a DWARF extension to allow location descriptions on
- the DWARF expression stack. It is part of
- :doc:`AMDGPUDwarfExtensionsForHeterogeneousDebugging`.
+- {doc}`RISCV/RISCVVectorExtension`
-:doc:`AMDGPUExecutionSynchronization`
- This document describes how execution of threads can be synchronized on AMD GPUs.
+ This document describes how the RISC-V Vector extension can be expressed in LLVM IR and how code is generated for it in the backend.
-:doc:`SPIRVUsage`
- This document describes using the SPIR-V target to compile GPU kernels.
+- {doc}`RISCV/RISCVVCIX`
-:doc:`DirectXUsage`
- This document describes using the DirectX target to compile GPU code for the
- DirectX runtime.
+ This document shows how the scheduling information for RISC-V's `XSfvcp` extension -- SiFive Vector Coprocessor Interface (VCIX) -- works and how to customize them.
-:doc:`RISCVUsage`
- This document describes using the RISC-V target.
+- {doc}`Sandbox IR <SandboxIR>`
-:doc:`RISCV/RISCVVectorExtension`
- This document describes how the RISC-V Vector extension can be expressed in LLVM IR and how code is generated for it in the backend.
+ This document describes the design and usage of Sandbox IR, a transactional layer over LLVM IR.
-:doc:`RISCV/RISCVVCIX`
- This document shows how the scheduling information for RISC-V's ``XSfvcp`` extension -- SiFive Vector Coprocessor Interface (VCIX) -- works and how to customize them.
+- {doc}`Telemetry`
-:doc:`Sandbox IR <SandboxIR>`
- This document describes the design and usage of Sandbox IR, a transactional layer over LLVM IR.
+ This document describes the Telemetry framework in LLVM.
-:doc:`Telemetry`
- This document describes the Telemetry framework in LLVM.
+- {doc}`LFI <LFI>`
-:doc:`LFI <LFI>`
- This document describes the Lightweight Fault Isolation (LFI) target in LLVM.
+ This document describes the Lightweight Fault Isolation (LFI) target in LLVM.
diff --git a/llvm/docs/WritingAnLLVMBackend.md b/llvm/docs/WritingAnLLVMBackend.md
index cab647125742e..1a9def75e1cb1 100644
--- a/llvm/docs/WritingAnLLVMBackend.md
+++ b/llvm/docs/WritingAnLLVMBackend.md
@@ -1,17 +1,16 @@
-=======================
-Writing an LLVM Backend
-=======================
+# Writing an LLVM Backend
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- HowToUseInstrMappings
+HowToUseInstrMappings
+```
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction
-============
+## Introduction
This document describes techniques for writing compiler backends that convert
the LLVM Intermediate Representation (IR) to code for a specified machine or
@@ -24,216 +23,214 @@ ARM, and SPARC. The backend may also be used to generate code targeted at SPUs
of the Cell processor or GPUs to support the execution of compute kernels.
The document focuses on existing examples found in subdirectories of
-``llvm/lib/Target`` in a downloaded LLVM release. In particular, this document
+`llvm/lib/Target` in a downloaded LLVM release. In particular, this document
focuses on the example of creating a static compiler (one that emits text
assembly) for a SPARC target, because SPARC has fairly standard
characteristics, such as a RISC instruction set and straightforward calling
conventions.
-Audience
---------
+### Audience
The audience for this document is anyone who needs to write an LLVM backend to
generate code for a specific hardware or software target.
-Prerequisite Reading
---------------------
+### Prerequisite Reading
These essential documents must be read before reading this document:
-* `LLVM Language Reference Manual <LangRef.html>`_ --- a reference manual for
+* {doc}`LLVM Language Reference Manual <LangRef>` --- a reference manual for
the LLVM assembly language.
-* :doc:`CodeGenerator` --- a guide to the components (classes and code
+* {doc}`CodeGenerator` --- a guide to the components (classes and code
generation algorithms) for translating the LLVM internal representation into
machine code for a specified target. Pay particular attention to the
descriptions of code generation stages: Instruction Selection, Scheduling and
Formation, SSA-based Optimization, Register Allocation, Prolog/Epilog Code
Insertion, Late Machine Code Optimizations, and Code Emission.
-* :doc:`TableGen/index` --- a document that describes the TableGen
- (``tblgen``) application that manages domain-specific information to support
+* {doc}`TableGen/index` --- a document that describes the TableGen
+ (`tblgen`) application that manages domain-specific information to support
LLVM code generation. TableGen processes input from a target description
- file (``.td`` suffix) and generates C++ code that can be used for code
+ file (`.td` suffix) and generates C++ code that can be used for code
generation.
-* :doc:`WritingAnLLVMPass` --- The assembly printer is a ``FunctionPass``, as
- are several ``SelectionDAG`` processing steps.
+* {doc}`WritingAnLLVMPass` --- The assembly printer is a `FunctionPass`, as
+ are several `SelectionDAG` processing steps.
-To follow the SPARC examples in this document, have a copy of `The SPARC
-Architecture Manual, Version 8 <http://www.sparc.org/standards/V8.pdf>`_ for
-reference. For details about the ARM instruction set, refer to the `ARM
-Architecture Reference Manual <http://infocenter.arm.com/>`_. For more about
-the GNU Assembler format (``GAS``), see `Using As
-<http://sourceware.org/binutils/docs/as/index.html>`_, especially for the
+To follow the SPARC examples in this document, have a copy of [The SPARC
+Architecture Manual, Version 8] for
+reference. For details about the ARM instruction set, refer to the [ARM
+Architecture Reference Manual]. For more about
+the GNU Assembler format (`GAS`), see [Using As], especially for the
assembly printer. "Using As" contains a list of target machine dependent
features.
-Basic Steps
------------
+[The SPARC Architecture Manual, Version 8]: http://www.sparc.org/standards/V8.pdf
+[ARM Architecture Reference Manual]: http://infocenter.arm.com/
+[Using As]: http://sourceware.org/binutils/docs/as/index.html
+
+### Basic Steps
To write a compiler backend for LLVM that converts the LLVM IR to code for a
specified target (machine or other language), follow these steps:
-* Create a subclass of the ``TargetMachine`` class that describes
+* Create a subclass of the `TargetMachine` class that describes
characteristics of your target machine. Copy existing examples of specific
- ``TargetMachine`` class and header files; for example, start with
- ``SparcTargetMachine.cpp`` and ``SparcTargetMachine.h``, but change the file
- names for your target. Similarly, change code that references "``Sparc``" to
+ `TargetMachine` class and header files; for example, start with
+ `SparcTargetMachine.cpp` and `SparcTargetMachine.h`, but change the file
+ names for your target. Similarly, change code that references "`Sparc`" to
reference your target.
* Describe the register set of the target. Use TableGen to generate code for
register definition, register aliases, and register classes from a
- target-specific ``RegisterInfo.td`` input file. You should also write
- additional code for a subclass of the ``TargetRegisterInfo`` class that
+ target-specific `RegisterInfo.td` input file. You should also write
+ additional code for a subclass of the `TargetRegisterInfo` class that
represents the class register file data used for register allocation and also
describes the interactions between registers.
* Describe the instruction set of the target. Use TableGen to generate code
for target-specific instructions from target-specific versions of
- ``TargetInstrFormats.td`` and ``TargetInstrInfo.td``. You should write
- additional code for a subclass of the ``TargetInstrInfo`` class to represent
+ `TargetInstrFormats.td` and `TargetInstrInfo.td`. You should write
+ additional code for a subclass of the `TargetInstrInfo` class to represent
machine instructions supported by the target machine.
* Describe the selection and conversion of the LLVM IR from a Directed Acyclic
Graph (DAG) representation of instructions to native target-specific
instructions. Use TableGen to generate code that matches patterns and
selects instructions based on additional information in a target-specific
- version of ``TargetInstrInfo.td``. Write code for ``XXXISelDAGToDAG.cpp``,
- where ``XXX`` identifies the specific target, to perform pattern matching and
- DAG-to-DAG instruction selection. Also write code in ``XXXISelLowering.cpp``
+ version of `TargetInstrInfo.td`. Write code for `XXXISelDAGToDAG.cpp`,
+ where `XXX` identifies the specific target, to perform pattern matching and
+ DAG-to-DAG instruction selection. Also write code in `XXXISelLowering.cpp`
to replace or remove operations and data types that are not supported
natively in a SelectionDAG.
* Write code for an assembly printer that converts LLVM IR to a GAS format for
your target machine. You should add assembly strings to the instructions
- defined in your target-specific version of ``TargetInstrInfo.td``. You
- should also write code for a subclass of ``AsmPrinter`` that performs the
- LLVM-to-assembly conversion and a trivial subclass of ``TargetAsmInfo``.
+ defined in your target-specific version of `TargetInstrInfo.td`. You
+ should also write code for a subclass of `AsmPrinter` that performs the
+ LLVM-to-assembly conversion and a trivial subclass of `TargetAsmInfo`.
* Optionally, add support for subtargets (i.e., variants with different
capabilities). You should also write code for a subclass of the
- ``TargetSubtarget`` class, which allows you to use the ``-mcpu=`` and
- ``-mattr=`` command-line options.
+ `TargetSubtarget` class, which allows you to use the `-mcpu=` and
+ `-mattr=` command-line options.
* Optionally, add JIT support and create a machine code emitter (subclass of
- ``TargetJITInfo``) that is used to emit binary code directly into memory.
+ `TargetJITInfo`) that is used to emit binary code directly into memory.
-In the ``.cpp`` and ``.h``. files, initially stub up these methods and then
+In the `.cpp` and `.h`. files, initially stub up these methods and then
implement them later. Initially, you may not know which private members that
the class will need and which components will need to be subclassed.
-Preliminaries
--------------
+### Preliminaries
To actually create your compiler backend, you need to create and modify a few
files. The absolute minimum is discussed here. But to actually use the LLVM
target-independent code generator, you must perform the steps described in the
-:doc:`LLVM Target-Independent Code Generator <CodeGenerator>` document.
+{doc}`LLVM Target-Independent Code Generator <CodeGenerator>` document.
-First, you should create a subdirectory under ``lib/Target`` to hold all the
+First, you should create a subdirectory under `lib/Target` to hold all the
files related to your target. If your target is called "Dummy", create the
-directory ``lib/Target/Dummy``.
+directory `lib/Target/Dummy`.
-In this new directory, create a ``CMakeLists.txt``. It is easiest to copy a
-``CMakeLists.txt`` of another target and modify it. It should at least contain
-the ``LLVM_TARGET_DEFINITIONS`` variable. The library can be named ``LLVMDummy``
+In this new directory, create a `CMakeLists.txt`. It is easiest to copy a
+`CMakeLists.txt` of another target and modify it. It should at least contain
+the `LLVM_TARGET_DEFINITIONS` variable. The library can be named `LLVMDummy`
(for example, see the MIPS target). Alternatively, you can split the library
-into ``LLVMDummyCodeGen`` and ``LLVMDummyAsmPrinter``, the latter of which
-should be implemented in a subdirectory below ``lib/Target/Dummy`` (for example,
+into `LLVMDummyCodeGen` and `LLVMDummyAsmPrinter`, the latter of which
+should be implemented in a subdirectory below `lib/Target/Dummy` (for example,
see the PowerPC target).
-Note that these two naming schemes are hardcoded into ``llvm-config``. Using
-any other naming scheme will confuse ``llvm-config`` and produce a lot of
-(seemingly unrelated) linker errors when linking ``llc``.
+Note that these two naming schemes are hardcoded into `llvm-config`. Using
+any other naming scheme will confuse `llvm-config` and produce a lot of
+(seemingly unrelated) linker errors when linking `llc`.
To make your target actually do something, you need to implement a subclass of
-``TargetMachine``. This implementation should typically be in the file
-``lib/Target/DummyTargetMachine.cpp``, but any file in the ``lib/Target``
+`TargetMachine`. This implementation should typically be in the file
+`lib/Target/DummyTargetMachine.cpp`, but any file in the `lib/Target`
directory will be built and should work. To use LLVM's target-independent code
generator, you should do what all current machine backends do: create a
-subclass of ``CodeGenTargetMachineImpl``. (To create a target from scratch, create a
-subclass of ``TargetMachine``.)
+subclass of `CodeGenTargetMachineImpl`. (To create a target from scratch, create a
+subclass of `TargetMachine`.)
-To get LLVM to actually build and link your target, you need to run ``cmake``
-with ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Dummy``. This will build your
+To get LLVM to actually build and link your target, you need to run `cmake`
+with `-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=Dummy`. This will build your
target without needing to add it to the list of all the targets.
-Once your target is stable, you can add it to the ``LLVM_ALL_TARGETS`` variable
-located in the main ``CMakeLists.txt``.
+Once your target is stable, you can add it to the `LLVM_ALL_TARGETS` variable
+located in the main `CMakeLists.txt`.
-Target Machine
-==============
+## Target Machine
-``CodeGenTargetMachineImpl`` is designed as a base class for targets implemented with
-the LLVM target-independent code generator. The ``CodeGenTargetMachineImpl`` class
+`CodeGenTargetMachineImpl` is designed as a base class for targets implemented with
+the LLVM target-independent code generator. The `CodeGenTargetMachineImpl` class
should be specialized by a concrete target class that implements the various
-virtual methods. ``CodeGenTargetMachineImpl`` is defined as a subclass of
-``TargetMachine`` in ``include/llvm/CodeGen/CodeGenTargetMachineImpl.h``. The
-``TargetMachine`` class implementation (``include/llvm/Target/TargetMachine.cpp``)
+virtual methods. `CodeGenTargetMachineImpl` is defined as a subclass of
+`TargetMachine` in `include/llvm/CodeGen/CodeGenTargetMachineImpl.h`. The
+`TargetMachine` class implementation (`include/llvm/Target/TargetMachine.cpp`)
also processes numerous command-line options.
-To create a concrete target-specific subclass of ``CodeGenTargetMachineImpl``, start
-by copying an existing ``TargetMachine`` class and header. You should name the
+To create a concrete target-specific subclass of `CodeGenTargetMachineImpl`, start
+by copying an existing `TargetMachine` class and header. You should name the
files that you create to reflect your specific target. For instance, for the
-SPARC target, name the files ``SparcTargetMachine.h`` and
-``SparcTargetMachine.cpp``.
+SPARC target, name the files `SparcTargetMachine.h` and
+`SparcTargetMachine.cpp`.
-For a target machine ``XXX``, the implementation of ``XXXTargetMachine`` must
+For a target machine `XXX`, the implementation of `XXXTargetMachine` must
have access methods to obtain objects that represent target components. These
-methods are named ``get*Info``, and are intended to obtain the instruction set
-(``getInstrInfo``), register set (``getRegisterInfo``), stack frame layout
-(``getFrameInfo``), and similar information. ``XXXTargetMachine`` must also
-implement the ``getDataLayout`` method to access an object with target-specific
+methods are named `get*Info`, and are intended to obtain the instruction set
+(`getInstrInfo`), register set (`getRegisterInfo`), stack frame layout
+(`getFrameInfo`), and similar information. `XXXTargetMachine` must also
+implement the `getDataLayout` method to access an object with target-specific
data characteristics, such as data type size and alignment requirements.
-For instance, for the SPARC target, the header file ``SparcTargetMachine.h``
-declares prototypes for several ``get*Info`` and ``getDataLayout`` methods that
+For instance, for the SPARC target, the header file `SparcTargetMachine.h`
+declares prototypes for several `get*Info` and `getDataLayout` methods that
simply return a class member.
-.. code-block:: c++
-
- namespace llvm {
+```c++
+namespace llvm {
- class Module;
+class Module;
- class SparcTargetMachine : public CodeGenTargetMachineImpl {
- const DataLayout DataLayout; // Calculates type size & alignment
- SparcSubtarget Subtarget;
- SparcInstrInfo InstrInfo;
- TargetFrameInfo FrameInfo;
+class SparcTargetMachine : public CodeGenTargetMachineImpl {
+ const DataLayout DataLayout; // Calculates type size & alignment
+ SparcSubtarget Subtarget;
+ SparcInstrInfo InstrInfo;
+ TargetFrameInfo FrameInfo;
- protected:
- virtual const TargetAsmInfo *createTargetAsmInfo() const;
+protected:
+ virtual const TargetAsmInfo *createTargetAsmInfo() const;
- public:
- SparcTargetMachine(const Module &M, const std::string &FS);
+public:
+ SparcTargetMachine(const Module &M, const std::string &FS);
- virtual const SparcInstrInfo *getInstrInfo() const {return &InstrInfo; }
- virtual const TargetFrameInfo *getFrameInfo() const {return &FrameInfo; }
- virtual const TargetSubtarget *getSubtargetImpl() const{return &Subtarget; }
- virtual const TargetRegisterInfo *getRegisterInfo() const {
- return &InstrInfo.getRegisterInfo();
- }
- virtual const DataLayout *getDataLayout() const { return &DataLayout; }
+ virtual const SparcInstrInfo *getInstrInfo() const {return &InstrInfo; }
+ virtual const TargetFrameInfo *getFrameInfo() const {return &FrameInfo; }
+ virtual const TargetSubtarget *getSubtargetImpl() const{return &Subtarget; }
+ virtual const TargetRegisterInfo *getRegisterInfo() const {
+ return &InstrInfo.getRegisterInfo();
+ }
+ virtual const DataLayout *getDataLayout() const { return &DataLayout; }
- // Pass Pipeline Configuration
- virtual bool addInstSelector(PassManagerBase &PM, bool Fast);
- virtual bool addPreEmitPass(PassManagerBase &PM, bool Fast);
- };
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(PassManagerBase &PM, bool Fast);
+ virtual bool addPreEmitPass(PassManagerBase &PM, bool Fast);
+};
- } // end namespace llvm
+} // end namespace llvm
+```
-* ``getInstrInfo()``
-* ``getRegisterInfo()``
-* ``getFrameInfo()``
-* ``getDataLayout()``
-* ``getSubtargetImpl()``
+* `getInstrInfo()`
+* `getRegisterInfo()`
+* `getFrameInfo()`
+* `getDataLayout()`
+* `getSubtargetImpl()`
For some targets, you also need to support the following methods:
-* ``getTargetLowering()``
-* ``getJITInfo()``
+* `getTargetLowering()`
+* `getJITInfo()`
Some architectures, such as GPUs, do not support jumping to an arbitrary
program location and implement branching using masked execution and loop using
@@ -241,81 +238,80 @@ special instructions around the loop body. In order to avoid CFG modifications
that introduce irreducible control flow not handled by such hardware, a target
must call `setRequiresStructuredCFG(true)` when being initialized.
-In addition, the ``XXXTargetMachine`` constructor should specify a
-``TargetDescription`` string that determines the data layout for the target
+In addition, the `XXXTargetMachine` constructor should specify a
+`TargetDescription` string that determines the data layout for the target
machine, including characteristics such as pointer size, alignment, and
-endianness. For example, the constructor for ``SparcTargetMachine`` contains
+endianness. For example, the constructor for `SparcTargetMachine` contains
the following:
-.. code-block:: c++
+```c++
+SparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS)
+ : DataLayout("E-p:32:32-f128:128:128"),
+ Subtarget(M, FS), InstrInfo(Subtarget),
+ FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
+}
+```
- SparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS)
- : DataLayout("E-p:32:32-f128:128:128"),
- Subtarget(M, FS), InstrInfo(Subtarget),
- FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
- }
-
-Hyphens separate portions of the ``TargetDescription`` string.
+Hyphens separate portions of the `TargetDescription` string.
-* An upper-case "``E``" in the string indicates a big-endian target data model.
- A lower-case "``e``" indicates little-endian.
+* An upper-case "`E`" in the string indicates a big-endian target data model.
+ A lower-case "`e`" indicates little-endian.
-* "``p:``" is followed by pointer information: size, ABI alignment, and
- preferred alignment. If only two figures follow "``p:``", then the first
+* "`p:`" is followed by pointer information: size, ABI alignment, and
+ preferred alignment. If only two figures follow "`p:`", then the first
value is pointer size, and the second value is both ABI and preferred
alignment.
-* Then a letter for numeric type alignment: "``i``", "``f``", "``v``", or
- "``a``" (corresponding to integer, floating point, vector, or aggregate).
- "``i``", "``v``", or "``a``" are followed by ABI alignment and preferred
- alignment. "``f``" is followed by three values: the first indicates the size
+* Then a letter for numeric type alignment: "`i`", "`f`", "`v`", or
+ "`a`" (corresponding to integer, floating point, vector, or aggregate).
+ "`i`", "`v`", or "`a`" are followed by ABI alignment and preferred
+ alignment. "`f`" is followed by three values: the first indicates the size
of a long double, then ABI alignment, and then ABI preferred alignment.
-Target Registration
-===================
+## Target Registration
-You must also register your target with the ``TargetRegistry``, which is what
+You must also register your target with the `TargetRegistry`, which is what
other LLVM tools use to be able to lookup and use your target at runtime. The
-``TargetRegistry`` can be used directly, but for most targets there are helper
+`TargetRegistry` can be used directly, but for most targets there are helper
templates which should take care of the work for you.
-All targets should declare a global ``Target`` object which is used to
-represent the target during registration. Then, in the target's ``TargetInfo``
-library, the target should define that object and use the ``RegisterTarget``
+All targets should declare a global `Target` object which is used to
+represent the target during registration. Then, in the target's `TargetInfo`
+library, the target should define that object and use the `RegisterTarget`
template to register the target. For example, the Sparc registration code
looks like this:
-.. code-block:: c++
+```c++
+Target llvm::getTheSparcTarget();
- Target llvm::getTheSparcTarget();
+extern "C" void LLVMInitializeSparcTargetInfo() {
+ RegisterTarget<Triple::sparc, /*HasJIT=*/false>
+ X(getTheSparcTarget(), "sparc", "Sparc");
+}
+```
- extern "C" void LLVMInitializeSparcTargetInfo() {
- RegisterTarget<Triple::sparc, /*HasJIT=*/false>
- X(getTheSparcTarget(), "sparc", "Sparc");
- }
-
-This allows the ``TargetRegistry`` to look up the target by name or by target
+This allows the `TargetRegistry` to look up the target by name or by target
triple. In addition, most targets will also register additional features which
are available in separate libraries. These registration steps are separate,
because some clients may wish to only link in some parts of the target --- the
JIT code generator does not require the use of the assembler printer, for
example. Here is an example of registering the Sparc assembly printer:
-.. code-block:: c++
+```c++
+extern "C" void LLVMInitializeSparcAsmPrinter() {
+ RegisterAsmPrinter<SparcAsmPrinter> X(getTheSparcTarget());
+}
+```
- extern "C" void LLVMInitializeSparcAsmPrinter() {
- RegisterAsmPrinter<SparcAsmPrinter> X(getTheSparcTarget());
- }
+For more information, see "[`llvm/Target/TargetRegistry.h`][TargetRegistry]".
-For more information, see "`llvm/Target/TargetRegistry.h
-</doxygen/TargetRegistry_8h-source.html>`_".
+[TargetRegistry]: doxygen:TargetRegistry_8h-source.html
-Register Set and Register Classes
-=================================
+## Register Set and Register Classes
You should describe a concrete target-specific class that represents the
-register file of a target machine. This class is called ``XXXRegisterInfo``
-(where ``XXX`` identifies the target) and represents the class register file
+register file of a target machine. This class is called `XXXRegisterInfo`
+(where `XXX` identifies the target) and represents the class register file
data that is used for register allocation. It also describes the interactions
between registers.
@@ -331,366 +327,362 @@ registers.
Much of the code for registers, including register definition, register
aliases, and register classes, is generated by TableGen from
-``XXXRegisterInfo.td`` input files and placed in ``XXXGenRegisterInfo.h.inc``
-and ``XXXGenRegisterInfo.inc`` output files. Some of the code in the
-implementation of ``XXXRegisterInfo`` requires hand-coding.
+`XXXRegisterInfo.td` input files and placed in `XXXGenRegisterInfo.h.inc`
+and `XXXGenRegisterInfo.inc` output files. Some of the code in the
+implementation of `XXXRegisterInfo` requires hand-coding.
-Defining a Register
--------------------
+### Defining a Register
-The ``XXXRegisterInfo.td`` file typically starts with register definitions for
-a target machine. The ``Register`` class (specified in ``Target.td``) is used
-to define an object for each register. The specified string ``n`` becomes the
-``Name`` of the register. The basic ``Register`` object does not have any
+The `XXXRegisterInfo.td` file typically starts with register definitions for
+a target machine. The `Register` class (specified in `Target.td`) is used
+to define an object for each register. The specified string `n` becomes the
+`Name` of the register. The basic `Register` object does not have any
subregisters and does not specify any aliases.
-.. code-block:: text
-
- class Register<string n> {
- string Namespace = "";
- string AsmName = n;
- string Name = n;
- int SpillSize = 0;
- int SpillAlignment = 0;
- list<Register> Aliases = [];
- list<Register> SubRegs = [];
- list<int> DwarfNumbers = [];
- }
-
-For example, in the ``X86RegisterInfo.td`` file, there are register definitions
-that utilize the ``Register`` class, such as:
-
-.. code-block:: text
-
- def AL : Register<"AL">, DwarfRegNum<[0, 0, 0]>;
-
-This defines the register ``AL`` and assigns it values (with ``DwarfRegNum``)
-that are used by ``gcc``, ``gdb``, or a debug information writer to identify a
-register. For register ``AL``, ``DwarfRegNum`` takes an array of 3 values
+```text
+class Register<string n> {
+ string Namespace = "";
+ string AsmName = n;
+ string Name = n;
+ int SpillSize = 0;
+ int SpillAlignment = 0;
+ list<Register> Aliases = [];
+ list<Register> SubRegs = [];
+ list<int> DwarfNumbers = [];
+}
+```
+
+For example, in the `X86RegisterInfo.td` file, there are register definitions
+that utilize the `Register` class, such as:
+
+```text
+def AL : Register<"AL">, DwarfRegNum<[0, 0, 0]>;
+```
+
+This defines the register `AL` and assigns it values (with `DwarfRegNum`)
+that are used by `gcc`, `gdb`, or a debug information writer to identify a
+register. For register `AL`, `DwarfRegNum` takes an array of 3 values
representing 3 different modes: the first element is for X86-64, the second for
exception handling (EH) on X86-32, and the third is generic. -1 is a special
Dwarf number that indicates the gcc number is undefined, and -2 indicates the
register number is invalid for this mode.
-From the previously described line in the ``X86RegisterInfo.td`` file, TableGen
-generates this code in the ``X86GenRegisterInfo.inc`` file:
-
-.. code-block:: c++
-
- static const unsigned GR8[] = { X86::AL, ... };
-
- const unsigned AL_AliasSet[] = { X86::AX, X86::EAX, X86::RAX, 0 };
-
- const TargetRegisterDesc RegisterDescriptors[] = {
- ...
- { "AL", "AL", AL_AliasSet, Empty_SubRegsSet, Empty_SubRegsSet, AL_SuperRegsSet }, ...
+From the previously described line in the `X86RegisterInfo.td` file, TableGen
+generates this code in the `X86GenRegisterInfo.inc` file:
-From the register info file, TableGen generates a ``TargetRegisterDesc`` object
-for each register. ``TargetRegisterDesc`` is defined in
-``include/llvm/Target/TargetRegisterInfo.h`` with the following fields:
+```c++
+static const unsigned GR8[] = { X86::AL, ... };
-.. code-block:: c++
+const unsigned AL_AliasSet[] = { X86::AX, X86::EAX, X86::RAX, 0 };
- struct TargetRegisterDesc {
- const char *AsmName; // Assembly language name for the register
- const char *Name; // Printable name for the reg (for debugging)
- const unsigned *AliasSet; // Register Alias Set
- const unsigned *SubRegs; // Sub-register set
- const unsigned *ImmSubRegs; // Immediate sub-register set
- const unsigned *SuperRegs; // Super-register set
- };
-
-TableGen uses the entire target description file (``.td``) to determine text
-names for the register (in the ``AsmName`` and ``Name`` fields of
-``TargetRegisterDesc``) and the relationships of other registers to the defined
-register (in the other ``TargetRegisterDesc`` fields). In this example, other
-definitions establish the registers "``AX``", "``EAX``", and "``RAX``" as
-aliases for one another, so TableGen generates a null-terminated array
-(``AL_AliasSet``) for this register alias set.
-
-The ``Register`` class is commonly used as a base class for more complex
-classes. In ``Target.td``, the ``Register`` class is the base for the
-``RegisterWithSubRegs`` class that is used to define registers that need to
-specify subregisters in the ``SubRegs`` list, as shown here:
-
-.. code-block:: text
-
- class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
- let SubRegs = subregs;
- }
-
-In ``SparcRegisterInfo.td``, additional register classes are defined for SPARC:
-a ``Register`` subclass, ``SparcReg``, and further subclasses: ``Ri``, ``Rf``,
-and ``Rd``. SPARC registers are identified by 5-bit ID numbers, which is a
-feature common to these subclasses. Note the use of "``let``" expressions to
-override values that are initially defined in a superclass (such as ``SubRegs``
-field in the ``Rd`` class).
-
-.. code-block:: text
-
- class SparcReg<string n> : Register<n> {
- field bits<5> Num;
- let Namespace = "SP";
- }
- // Ri - 32-bit integer registers
- class Ri<bits<5> num, string n> :
- SparcReg<n> {
- let Num = num;
- }
- // Rf - 32-bit floating-point registers
- class Rf<bits<5> num, string n> :
- SparcReg<n> {
- let Num = num;
- }
- // Rd - Slots in the FP register file for 64-bit floating-point values.
- class Rd<bits<5> num, string n, list<Register> subregs> : SparcReg<n> {
- let Num = num;
- let SubRegs = subregs;
- }
-
-In the ``SparcRegisterInfo.td`` file, there are register definitions that
-utilize these subclasses of ``Register``, such as:
-
-.. code-block:: text
-
- def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>;
- def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>;
+const TargetRegisterDesc RegisterDescriptors[] = {
...
- def F0 : Rf< 0, "F0">, DwarfRegNum<[32]>;
- def F1 : Rf< 1, "F1">, DwarfRegNum<[33]>;
- ...
- def D0 : Rd< 0, "F0", [F0, F1]>, DwarfRegNum<[32]>;
- def D1 : Rd< 2, "F2", [F2, F3]>, DwarfRegNum<[34]>;
-
-The last two registers shown above (``D0`` and ``D1``) are double-precision
+{ "AL", "AL", AL_AliasSet, Empty_SubRegsSet, Empty_SubRegsSet, AL_SuperRegsSet }, ...
+```
+
+From the register info file, TableGen generates a `TargetRegisterDesc` object
+for each register. `TargetRegisterDesc` is defined in
+`include/llvm/Target/TargetRegisterInfo.h` with the following fields:
+
+```c++
+struct TargetRegisterDesc {
+ const char *AsmName; // Assembly language name for the register
+ const char *Name; // Printable name for the reg (for debugging)
+ const unsigned *AliasSet; // Register Alias Set
+ const unsigned *SubRegs; // Sub-register set
+ const unsigned *ImmSubRegs; // Immediate sub-register set
+ const unsigned *SuperRegs; // Super-register set
+};
+```
+
+TableGen uses the entire target description file (`.td`) to determine text
+names for the register (in the `AsmName` and `Name` fields of
+`TargetRegisterDesc`) and the relationships of other registers to the defined
+register (in the other `TargetRegisterDesc` fields). In this example, other
+definitions establish the registers "`AX`", "`EAX`", and "`RAX`" as
+aliases for one another, so TableGen generates a null-terminated array
+(`AL_AliasSet`) for this register alias set.
+
+The `Register` class is commonly used as a base class for more complex
+classes. In `Target.td`, the `Register` class is the base for the
+`RegisterWithSubRegs` class that is used to define registers that need to
+specify subregisters in the `SubRegs` list, as shown here:
+
+```text
+class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
+ let SubRegs = subregs;
+}
+```
+
+In `SparcRegisterInfo.td`, additional register classes are defined for SPARC:
+a `Register` subclass, `SparcReg`, and further subclasses: `Ri`, `Rf`,
+and `Rd`. SPARC registers are identified by 5-bit ID numbers, which is a
+feature common to these subclasses. Note the use of "`let`" expressions to
+override values that are initially defined in a superclass (such as `SubRegs`
+field in the `Rd` class).
+
+```text
+class SparcReg<string n> : Register<n> {
+ field bits<5> Num;
+ let Namespace = "SP";
+}
+// Ri - 32-bit integer registers
+class Ri<bits<5> num, string n> :
+SparcReg<n> {
+ let Num = num;
+}
+// Rf - 32-bit floating-point registers
+class Rf<bits<5> num, string n> :
+SparcReg<n> {
+ let Num = num;
+}
+// Rd - Slots in the FP register file for 64-bit floating-point values.
+class Rd<bits<5> num, string n, list<Register> subregs> : SparcReg<n> {
+ let Num = num;
+ let SubRegs = subregs;
+}
+```
+
+In the `SparcRegisterInfo.td` file, there are register definitions that
+utilize these subclasses of `Register`, such as:
+
+```text
+def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>;
+def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>;
+...
+def F0 : Rf< 0, "F0">, DwarfRegNum<[32]>;
+def F1 : Rf< 1, "F1">, DwarfRegNum<[33]>;
+...
+def D0 : Rd< 0, "F0", [F0, F1]>, DwarfRegNum<[32]>;
+def D1 : Rd< 2, "F2", [F2, F3]>, DwarfRegNum<[34]>;
+```
+
+The last two registers shown above (`D0` and `D1`) are double-precision
floating-point registers that are aliases for pairs of single-precision
floating-point sub-registers. In addition to aliases, the sub-register and
super-register relationships of the defined register are in fields of a
-register's ``TargetRegisterDesc``.
+register's `TargetRegisterDesc`.
-Defining a Register Class
--------------------------
+### Defining a Register Class
-The ``RegisterClass`` class (specified in ``Target.td``) is used to define an
+The `RegisterClass` class (specified in `Target.td`) is used to define an
object that represents a group of related registers and also defines the
default allocation order of the registers. A target description file
-``XXXRegisterInfo.td`` that uses ``Target.td`` can construct register classes
+`XXXRegisterInfo.td` that uses `Target.td` can construct register classes
using the following class:
-.. code-block:: text
-
- class RegisterClass<string namespace,
- list<ValueType> regTypes, int alignment, dag regList> {
- string Namespace = namespace;
- list<ValueType> RegTypes = regTypes;
- int Size = 0; // spill size, in bits; zero lets tblgen pick the size
- int Alignment = alignment;
+```text
+class RegisterClass<string namespace,
+list<ValueType> regTypes, int alignment, dag regList> {
+ string Namespace = namespace;
+ list<ValueType> RegTypes = regTypes;
+ int Size = 0; // spill size, in bits; zero lets tblgen pick the size
+ int Alignment = alignment;
- // CopyCost is the cost of copying a value between two registers
- // default value 1 means a single instruction
- // A negative value means copying is extremely expensive or impossible
- int CopyCost = 1;
- dag MemberList = regList;
+ // CopyCost is the cost of copying a value between two registers
+ // default value 1 means a single instruction
+ // A negative value means copying is extremely expensive or impossible
+ int CopyCost = 1;
+ dag MemberList = regList;
- // for register classes that are subregisters of this class
- list<RegisterClass> SubRegClassList = [];
+ // for register classes that are subregisters of this class
+ list<RegisterClass> SubRegClassList = [];
- code MethodProtos = [{}]; // to insert arbitrary code
- code MethodBodies = [{}];
- }
+ code MethodProtos = [{}]; // to insert arbitrary code
+ code MethodBodies = [{}];
+}
+```
-To define a ``RegisterClass``, use the following 4 arguments:
+To define a `RegisterClass`, use the following 4 arguments:
* The first argument of the definition is the name of the namespace.
-* The second argument is a list of ``ValueType`` register type values that are
- defined in ``include/llvm/CodeGen/ValueTypes.td``. Defined values include
- integer types (such as ``i16``, ``i32``, and ``i1`` for Boolean),
- floating-point types (``f32``, ``f64``), and vector types (for example,
- ``v8i16`` for an ``8 x i16`` vector). All registers in a ``RegisterClass``
- must have the same ``ValueType``, but some registers may store vector data in
+* The second argument is a list of `ValueType` register type values that are
+ defined in `include/llvm/CodeGen/ValueTypes.td`. Defined values include
+ integer types (such as `i16`, `i32`, and `i1` for Boolean),
+ floating-point types (`f32`, `f64`), and vector types (for example,
+ `v8i16` for an `8 x i16` vector). All registers in a `RegisterClass`
+ must have the same `ValueType`, but some registers may store vector data in
different configurations. For example a register that can process a 128-bit
vector may be able to handle 16 8-bit integer elements, 8 16-bit integers, 4
32-bit integers, and so on.
-* The third argument of the ``RegisterClass`` definition specifies the
+* The third argument of the `RegisterClass` definition specifies the
alignment required of the registers when they are stored or loaded to
memory.
-* The final argument, ``regList``, specifies which registers are in this class.
- If an alternative allocation order method is not specified, then ``regList``
+* The final argument, `regList`, specifies which registers are in this class.
+ If an alternative allocation order method is not specified, then `regList`
also defines the order of allocation used by the register allocator. Besides
- simply listing registers with ``(add R0, R1, ...)``, more advanced set
- operators are available. See ``include/llvm/Target/Target.td`` for more
+ simply listing registers with `(add R0, R1, ...)`, more advanced set
+ operators are available. See `include/llvm/Target/Target.td` for more
information.
-In ``SparcRegisterInfo.td``, three ``RegisterClass`` objects are defined:
-``FPRegs``, ``DFPRegs``, and ``IntRegs``. For all three register classes, the
-first argument defines the namespace with the string "``SP``". ``FPRegs``
-defines a group of 32 single-precision floating-point registers (``F0`` to
-``F31``); ``DFPRegs`` defines a group of 16 double-precision registers
-(``D0-D15``).
-
-.. code-block:: text
-
- // F0, F1, F2, ..., F31
- def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
-
- def DFPRegs : RegisterClass<"SP", [f64], 64,
- (add D0, D1, D2, D3, D4, D5, D6, D7, D8,
- D9, D10, D11, D12, D13, D14, D15)>;
-
- def IntRegs : RegisterClass<"SP", [i32], 32,
- (add L0, L1, L2, L3, L4, L5, L6, L7,
- I0, I1, I2, I3, I4, I5,
- O0, O1, O2, O3, O4, O5, O7,
- G1,
- // Non-allocatable regs:
- G2, G3, G4,
- O6, // stack ptr
- I6, // frame ptr
- I7, // return address
- G0, // constant zero
- G5, G6, G7 // reserved for kernel
- )>;
-
-Using ``SparcRegisterInfo.td`` with TableGen generates several output files
+In `SparcRegisterInfo.td`, three `RegisterClass` objects are defined:
+`FPRegs`, `DFPRegs`, and `IntRegs`. For all three register classes, the
+first argument defines the namespace with the string "`SP`". `FPRegs`
+defines a group of 32 single-precision floating-point registers (`F0` to
+`F31`); `DFPRegs` defines a group of 16 double-precision registers
+(`D0-D15`).
+
+```text
+// F0, F1, F2, ..., F31
+def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
+
+def DFPRegs : RegisterClass<"SP", [f64], 64,
+ (add D0, D1, D2, D3, D4, D5, D6, D7, D8,
+ D9, D10, D11, D12, D13, D14, D15)>;
+
+def IntRegs : RegisterClass<"SP", [i32], 32,
+ (add L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5,
+ O0, O1, O2, O3, O4, O5, O7,
+ G1,
+ // Non-allocatable regs:
+ G2, G3, G4,
+ O6, // stack ptr
+ I6, // frame ptr
+ I7, // return address
+ G0, // constant zero
+ G5, G6, G7 // reserved for kernel
+ )>;
+```
+
+Using `SparcRegisterInfo.td` with TableGen generates several output files
that are intended for inclusion in other source code that you write.
-``SparcRegisterInfo.td`` generates ``SparcGenRegisterInfo.h.inc``, which should
+`SparcRegisterInfo.td` generates `SparcGenRegisterInfo.h.inc`, which should
be included in the header file for the implementation of the SPARC register
-implementation that you write (``SparcRegisterInfo.h``). In
-``SparcGenRegisterInfo.h.inc`` a new structure is defined called
-``SparcGenRegisterInfo`` that uses ``TargetRegisterInfo`` as its base. It also
-specifies types, based upon the defined register classes: ``DFPRegsClass``,
-``FPRegsClass``, and ``IntRegsClass``.
-
-``SparcRegisterInfo.td`` also generates ``SparcGenRegisterInfo.inc``, which is
-included at the bottom of ``SparcRegisterInfo.cpp``, the SPARC register
+implementation that you write (`SparcRegisterInfo.h`). In
+`SparcGenRegisterInfo.h.inc` a new structure is defined called
+`SparcGenRegisterInfo` that uses `TargetRegisterInfo` as its base. It also
+specifies types, based upon the defined register classes: `DFPRegsClass`,
+`FPRegsClass`, and `IntRegsClass`.
+
+`SparcRegisterInfo.td` also generates `SparcGenRegisterInfo.inc`, which is
+included at the bottom of `SparcRegisterInfo.cpp`, the SPARC register
implementation. The code below shows only the generated integer registers and
-associated register classes. The order of registers in ``IntRegs`` reflects
-the order in the definition of ``IntRegs`` in the target description file.
-
-.. code-block:: c++
-
- // IntRegs Register Class...
- static const unsigned IntRegs[] = {
- SP::L0, SP::L1, SP::L2, SP::L3, SP::L4, SP::L5,
- SP::L6, SP::L7, SP::I0, SP::I1, SP::I2, SP::I3,
- SP::I4, SP::I5, SP::O0, SP::O1, SP::O2, SP::O3,
- SP::O4, SP::O5, SP::O7, SP::G1, SP::G2, SP::G3,
- SP::G4, SP::O6, SP::I6, SP::I7, SP::G0, SP::G5,
- SP::G6, SP::G7,
+associated register classes. The order of registers in `IntRegs` reflects
+the order in the definition of `IntRegs` in the target description file.
+
+```c++
+// IntRegs Register Class...
+static const unsigned IntRegs[] = {
+ SP::L0, SP::L1, SP::L2, SP::L3, SP::L4, SP::L5,
+ SP::L6, SP::L7, SP::I0, SP::I1, SP::I2, SP::I3,
+ SP::I4, SP::I5, SP::O0, SP::O1, SP::O2, SP::O3,
+ SP::O4, SP::O5, SP::O7, SP::G1, SP::G2, SP::G3,
+ SP::G4, SP::O6, SP::I6, SP::I7, SP::G0, SP::G5,
+ SP::G6, SP::G7,
+};
+
+// IntRegsVTs Register Class Value Types...
+static const MVT::ValueType IntRegsVTs[] = {
+ MVT::i32, MVT::Other
+};
+
+namespace SP { // Register class instances
+ DFPRegsClass DFPRegsRegClass;
+ FPRegsClass FPRegsRegClass;
+ IntRegsClass IntRegsRegClass;
+...
+ // IntRegs Sub-register Classes...
+ static const TargetRegisterClass* const IntRegsSubRegClasses [] = {
+ NULL
};
-
- // IntRegsVTs Register Class Value Types...
- static const MVT::ValueType IntRegsVTs[] = {
- MVT::i32, MVT::Other
+...
+ // IntRegs Super-register Classes..
+ static const TargetRegisterClass* const IntRegsSuperRegClasses [] = {
+ NULL
+ };
+...
+ // IntRegs Register Class sub-classes...
+ static const TargetRegisterClass* const IntRegsSubclasses [] = {
+ NULL
+ };
+...
+ // IntRegs Register Class super-classes...
+ static const TargetRegisterClass* const IntRegsSuperclasses [] = {
+ NULL
};
- namespace SP { // Register class instances
- DFPRegsClass DFPRegsRegClass;
- FPRegsClass FPRegsRegClass;
- IntRegsClass IntRegsRegClass;
- ...
- // IntRegs Sub-register Classes...
- static const TargetRegisterClass* const IntRegsSubRegClasses [] = {
- NULL
- };
- ...
- // IntRegs Super-register Classes..
- static const TargetRegisterClass* const IntRegsSuperRegClasses [] = {
- NULL
- };
- ...
- // IntRegs Register Class sub-classes...
- static const TargetRegisterClass* const IntRegsSubclasses [] = {
- NULL
- };
- ...
- // IntRegs Register Class super-classes...
- static const TargetRegisterClass* const IntRegsSuperclasses [] = {
- NULL
- };
-
- IntRegsClass::IntRegsClass() : TargetRegisterClass(IntRegsRegClassID,
- IntRegsVTs, IntRegsSubclasses, IntRegsSuperclasses, IntRegsSubRegClasses,
- IntRegsSuperRegClasses, 4, 4, 1, IntRegs, IntRegs + 32) {}
- }
+ IntRegsClass::IntRegsClass() : TargetRegisterClass(IntRegsRegClassID,
+ IntRegsVTs, IntRegsSubclasses, IntRegsSuperclasses, IntRegsSubRegClasses,
+ IntRegsSuperRegClasses, 4, 4, 1, IntRegs, IntRegs + 32) {}
+}
+```
The register allocators will avoid using reserved registers, and callee saved
registers are not used until all the volatile registers have been used. That
is usually good enough, but in some cases it may be necessary to provide custom
allocation orders.
-Implement a subclass of ``TargetRegisterInfo``
-----------------------------------------------
+### Implement a subclass of `TargetRegisterInfo`
-The final step is to hand code portions of ``XXXRegisterInfo``, which
-implements the interface described in ``TargetRegisterInfo.h`` (see
-:ref:`TargetRegisterInfo`). These functions return ``0``, ``NULL``, or
-``false``, unless overridden. Here is a list of functions that are overridden
-for the SPARC implementation in ``SparcRegisterInfo.cpp``:
+The final step is to hand code portions of `XXXRegisterInfo`, which
+implements the interface described in `TargetRegisterInfo.h` (see
+{ref}`TargetRegisterInfo`). These functions return `0`, `NULL`, or
+`false`, unless overridden. Here is a list of functions that are overridden
+for the SPARC implementation in `SparcRegisterInfo.cpp`:
-* ``getCalleeSavedRegs`` --- Returns a list of callee-saved registers in the
+* `getCalleeSavedRegs` --- Returns a list of callee-saved registers in the
order of the desired callee-save stack frame offset.
-* ``getReservedRegs`` --- Returns a bitset indexed by physical register
+* `getReservedRegs` --- Returns a bitset indexed by physical register
numbers, indicating if a particular register is unavailable.
-* ``hasFP`` --- Return a Boolean indicating if a function should have a
+* `hasFP` --- Return a Boolean indicating if a function should have a
dedicated frame pointer register.
-* ``eliminateCallFramePseudoInstr`` --- If call frame setup or destroy pseudo
+* `eliminateCallFramePseudoInstr` --- If call frame setup or destroy pseudo
instructions are used, this can be called to eliminate them.
-* ``eliminateFrameIndex`` --- Eliminate abstract frame indices from
+* `eliminateFrameIndex` --- Eliminate abstract frame indices from
instructions that may use them.
-* ``emitPrologue`` --- Insert prologue code into the function.
+* `emitPrologue` --- Insert prologue code into the function.
-* ``emitEpilogue`` --- Insert epilogue code into the function.
+* `emitEpilogue` --- Insert epilogue code into the function.
-.. _instruction-set:
+(instruction-set)=
-Instruction Set
-===============
+## Instruction Set
During the early stages of code generation, the LLVM IR code is converted to a
-``SelectionDAG`` with nodes that are instances of the ``SDNode`` class
-containing target instructions. An ``SDNode`` has an opcode, operands, type
+`SelectionDAG` with nodes that are instances of the `SDNode` class
+containing target instructions. An `SDNode` has an opcode, operands, type
requirements, and operation properties. For example, is an operation
commutative, does an operation load from memory. The various operation node
-types are described in the ``include/llvm/CodeGen/SelectionDAGNodes.h`` file
-(values of the ``NodeType`` enum in the ``ISD`` namespace).
+types are described in the `include/llvm/CodeGen/SelectionDAGNodes.h` file
+(values of the `NodeType` enum in the `ISD` namespace).
-TableGen uses the following target description (``.td``) input files to
+TableGen uses the following target description (`.td`) input files to
generate much of the code for instruction definition:
-* ``Target.td`` --- Where the ``Instruction``, ``Operand``, ``InstrInfo``, and
+* `Target.td` --- Where the `Instruction`, `Operand`, `InstrInfo`, and
other fundamental classes are defined.
-* ``TargetSelectionDAG.td`` --- Used by ``SelectionDAG`` instruction selection
- generators, contains ``SDTC*`` classes (selection DAG type constraint),
- definitions of ``SelectionDAG`` nodes (such as ``imm``, ``cond``, ``bb``,
- ``add``, ``fadd``, ``sub``), and pattern support (``Pattern``, ``Pat``,
- ``PatFrag``, ``PatLeaf``, ``ComplexPattern``.
+* `TargetSelectionDAG.td` --- Used by `SelectionDAG` instruction selection
+ generators, contains `SDTC*` classes (selection DAG type constraint),
+ definitions of `SelectionDAG` nodes (such as `imm`, `cond`, `bb`,
+ `add`, `fadd`, `sub`), and pattern support (`Pattern`, `Pat`,
+ `PatFrag`, `PatLeaf`, `ComplexPattern`.
-* ``XXXInstrFormats.td`` --- Patterns for definitions of target-specific
+* `XXXInstrFormats.td` --- Patterns for definitions of target-specific
instructions.
-* ``XXXInstrInfo.td`` --- Target-specific definitions of instruction templates,
+* `XXXInstrInfo.td` --- Target-specific definitions of instruction templates,
condition codes, and instructions of an instruction set. For architecture
modifications, a different file name may be used. For example, for Pentium
- with SSE instruction, this file is ``X86InstrSSE.td``, and for Pentium with
- MMX, this file is ``X86InstrMMX.td``.
+ with SSE instruction, this file is `X86InstrSSE.td`, and for Pentium with
+ MMX, this file is `X86InstrMMX.td`.
-There is also a target-specific ``XXX.td`` file, where ``XXX`` is the name of
-the target. The ``XXX.td`` file includes the other ``.td`` input files, but
+There is also a target-specific `XXX.td` file, where `XXX` is the name of
+the target. The `XXX.td` file includes the other `.td` input files, but
its contents are only directly important for subtargets.
-You should describe a concrete target-specific class ``XXXInstrInfo`` that
+You should describe a concrete target-specific class `XXXInstrInfo` that
represents machine instructions supported by a target machine.
-``XXXInstrInfo`` contains an array of ``XXXInstrDescriptor`` objects, each of
+`XXXInstrInfo` contains an array of `XXXInstrDescriptor` objects, each of
which describes one instruction. An instruction descriptor defines:
* Opcode mnemonic
@@ -699,25 +691,25 @@ which describes one instruction. An instruction descriptor defines:
* Target-independent properties (such as memory access, is commutable)
* Target-specific flags
-The Instruction class (defined in ``Target.td``) is mostly used as a base for
+The Instruction class (defined in `Target.td`) is mostly used as a base for
more complex instruction classes.
-.. code-block:: text
-
- class Instruction {
- string Namespace = "";
- dag OutOperandList; // A dag containing the MI def operand list.
- dag InOperandList; // A dag containing the MI use operand list.
- string AsmString = ""; // The .s format to print the instruction with.
- list<dag> Pattern; // Set to the DAG pattern for this instruction.
- list<Register> Uses = [];
- list<Register> Defs = [];
- list<Predicate> Predicates = []; // predicates turned into isel match code
- ... remainder not shown for space ...
- }
-
-A ``SelectionDAG`` node (``SDNode``) should contain an object representing a
-target-specific instruction that is defined in ``XXXInstrInfo.td``. The
+```text
+class Instruction {
+ string Namespace = "";
+ dag OutOperandList; // A dag containing the MI def operand list.
+ dag InOperandList; // A dag containing the MI use operand list.
+ string AsmString = ""; // The .s format to print the instruction with.
+ list<dag> Pattern; // Set to the DAG pattern for this instruction.
+ list<Register> Uses = [];
+ list<Register> Defs = [];
+ list<Predicate> Predicates = []; // predicates turned into isel match code
+ ... remainder not shown for space ...
+}
+```
+
+A `SelectionDAG` node (`SDNode`) should contain an object representing a
+target-specific instruction that is defined in `XXXInstrInfo.td`. The
instruction objects should represent instructions from the architecture manual
of the target machine (such as the SPARC Architecture Manual for the SPARC
target).
@@ -725,8 +717,8 @@ target).
A single instruction from the architecture manual is often modeled as multiple
target instructions, depending upon its operands. For example, a manual might
describe an add instruction that takes a register or an immediate operand. An
-LLVM target could model this with two instructions named ``ADDri`` and
-``ADDrr``.
+LLVM target could model this with two instructions named `ADDri` and
+`ADDrr`.
You should define a class for each instruction category and define each opcode
as a subclass of the category with appropriate parameters such as the fixed
@@ -736,50 +728,50 @@ Also you should specify how the instruction should be printed when the
automatic assembly printer is used.
As is described in the SPARC Architecture Manual, Version 8, there are three
-major 32-bit formats for instructions. Format 1 is only for the ``CALL``
-instruction. Format 2 is for branch on condition codes and ``SETHI`` (set high
+major 32-bit formats for instructions. Format 1 is only for the `CALL`
+instruction. Format 2 is for branch on condition codes and `SETHI` (set high
bits of a register) instructions. Format 3 is for other instructions.
-Each of these formats has corresponding classes in ``SparcInstrFormat.td``.
-``InstSP`` is a base class for other instruction classes. Additional base
+Each of these formats has corresponding classes in `SparcInstrFormat.td`.
+`InstSP` is a base class for other instruction classes. Additional base
classes are specified for more precise formats: for example in
-``SparcInstrFormat.td``, ``F2_1`` is for ``SETHI``, and ``F2_2`` is for
-branches. There are three other base classes: ``F3_1`` for register/register
-operations, ``F3_2`` for register/immediate operations, and ``F3_3`` for
-floating-point operations. ``SparcInstrInfo.td`` also adds the base class
-``Pseudo`` for synthetic SPARC instructions.
-
-``SparcInstrInfo.td`` largely consists of operand and instruction definitions
-for the SPARC target. In ``SparcInstrInfo.td``, the following target
-description file entry, ``LDrr``, defines the Load Integer instruction for a
-Word (the ``LD`` SPARC opcode) from a memory address to a register. The first
-parameter, the value 3 (``11``\ :sub:`2`), is the operation value for this
-category of operation. The second parameter (``000000``\ :sub:`2`) is the
-specific operation value for ``LD``/Load Word. The third parameter is the
-output destination, which is a register operand and defined in the ``Register``
-target description file (``IntRegs``).
-
-.. code-block:: text
-
- def LDrr : F3_1 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
- "ld [$addr], $dst",
- [(set i32:$dst, (load ADDRrr:$addr))]>;
+`SparcInstrFormat.td`, `F2_1` is for `SETHI`, and `F2_2` is for
+branches. There are three other base classes: `F3_1` for register/register
+operations, `F3_2` for register/immediate operations, and `F3_3` for
+floating-point operations. `SparcInstrInfo.td` also adds the base class
+`Pseudo` for synthetic SPARC instructions.
+
+`SparcInstrInfo.td` largely consists of operand and instruction definitions
+for the SPARC target. In `SparcInstrInfo.td`, the following target
+description file entry, `LDrr`, defines the Load Integer instruction for a
+Word (the `LD` SPARC opcode) from a memory address to a register. The first
+parameter, the value 3 (`11`{sub}`2`), is the operation value for this
+category of operation. The second parameter (`000000`{sub}`2`) is the
+specific operation value for `LD`/Load Word. The third parameter is the
+output destination, which is a register operand and defined in the `Register`
+target description file (`IntRegs`).
+
+```text
+def LDrr : F3_1 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
+ "ld [$addr], $dst",
+ [(set i32:$dst, (load ADDRrr:$addr))]>;
+```
The fourth parameter is the input source, which uses the address operand
-``MEMrr`` that is defined earlier in ``SparcInstrInfo.td``:
+`MEMrr` that is defined earlier in `SparcInstrInfo.td`:
-.. code-block:: text
-
- def MEMrr : Operand<i32> {
- let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops IntRegs, IntRegs);
- }
+```text
+def MEMrr : Operand<i32> {
+ let PrintMethod = "printMemOperand";
+ let MIOperandInfo = (ops IntRegs, IntRegs);
+}
+```
The fifth parameter is a string that is used by the assembly printer and can be
left as an empty string until the assembly printer interface is implemented.
The sixth and final parameter is the pattern used to match the instruction
-during the SelectionDAG Select Phase described in :doc:`CodeGenerator`.
-This parameter is detailed in the next section, :ref:`instruction-selector`.
+during the SelectionDAG Select Phase described in {doc}`CodeGenerator`.
+This parameter is detailed in the next section, {ref}`instruction-selector`.
Instruction class definitions are not overloaded for different operand types,
so separate versions of instructions are needed for register, memory, or
@@ -787,169 +779,167 @@ immediate value operands. For example, to perform a Load Integer instruction
for a Word from an immediate operand to a register, the following instruction
class is defined:
-.. code-block:: text
-
- def LDri : F3_2 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13):$addr),
- "ld [$addr], $dst",
- [(set i32:$rd, (load ADDRri:$addr))]>;
+```text
+def LDri : F3_2 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMri $rs1, $simm13):$addr),
+ "ld [$addr], $dst",
+ [(set i32:$rd, (load ADDRri:$addr))]>;
+```
Writing these definitions for so many similar instructions can involve a lot of
-cut and paste. In ``.td`` files, the ``multiclass`` directive enables the
+cut and paste. In `.td` files, the `multiclass` directive enables the
creation of templates to define several instruction classes at once (using the
-``defm`` directive). For example in ``SparcInstrInfo.td``, the ``multiclass``
-pattern ``F3_12`` is defined to create 2 instruction classes each time
-``F3_12`` is invoked:
-
-.. code-block:: text
-
- multiclass F3_12 <string OpcStr, bits<6> Op3Val, SDNode OpNode> {
- def rr : F3_1 <2, Op3Val,
- (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs1),
- !strconcat(OpcStr, " $rs1, $rs2, $rd"),
- [(set i32:$rd, (OpNode i32:$rs1, i32:$rs2))]>;
- def ri : F3_2 <2, Op3Val,
- (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
- !strconcat(OpcStr, " $rs1, $simm13, $rd"),
- [(set i32:$rd, (OpNode i32:$rs1, simm13:$simm13))]>;
- }
-
-So when the ``defm`` directive is used for the ``XOR`` and ``ADD``
-instructions, as seen below, it creates four instruction objects: ``XORrr``,
-``XORri``, ``ADDrr``, and ``ADDri``.
-
-.. code-block:: text
-
- defm XOR : F3_12<"xor", 0b000011, xor>;
- defm ADD : F3_12<"add", 0b000000, add>;
-
-``SparcInstrInfo.td`` also includes definitions for condition codes that are
+`defm` directive). For example in `SparcInstrInfo.td`, the `multiclass`
+pattern `F3_12` is defined to create 2 instruction classes each time
+`F3_12` is invoked:
+
+```text
+multiclass F3_12 <string OpcStr, bits<6> Op3Val, SDNode OpNode> {
+ def rr : F3_1 <2, Op3Val,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs1),
+ !strconcat(OpcStr, " $rs1, $rs2, $rd"),
+ [(set i32:$rd, (OpNode i32:$rs1, i32:$rs2))]>;
+ def ri : F3_2 <2, Op3Val,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
+ !strconcat(OpcStr, " $rs1, $simm13, $rd"),
+ [(set i32:$rd, (OpNode i32:$rs1, simm13:$simm13))]>;
+}
+```
+
+So when the `defm` directive is used for the `XOR` and `ADD`
+instructions, as seen below, it creates four instruction objects: `XORrr`,
+`XORri`, `ADDrr`, and `ADDri`.
+
+```text
+defm XOR : F3_12<"xor", 0b000011, xor>;
+defm ADD : F3_12<"add", 0b000000, add>;
+```
+
+`SparcInstrInfo.td` also includes definitions for condition codes that are
referenced by branch instructions. The following definitions in
-``SparcInstrInfo.td`` indicate the bit location of the SPARC condition code.
-For example, the 10\ :sup:`th` bit represents the "greater than" condition for
-integers, and the 22\ :sup:`nd` bit represents the "greater than" condition for
+`SparcInstrInfo.td` indicate the bit location of the SPARC condition code.
+For example, the 10{sup}`th` bit represents the "greater than" condition for
+integers, and the 22{sup}`nd` bit represents the "greater than" condition for
floats.
-.. code-block:: text
-
- def ICC_NE : ICC_VAL< 9>; // Not Equal
- def ICC_E : ICC_VAL< 1>; // Equal
- def ICC_G : ICC_VAL<10>; // Greater
- ...
- def FCC_U : FCC_VAL<23>; // Unordered
- def FCC_G : FCC_VAL<22>; // Greater
- def FCC_UG : FCC_VAL<21>; // Unordered or Greater
- ...
+```text
+def ICC_NE : ICC_VAL< 9>; // Not Equal
+def ICC_E : ICC_VAL< 1>; // Equal
+def ICC_G : ICC_VAL<10>; // Greater
+...
+def FCC_U : FCC_VAL<23>; // Unordered
+def FCC_G : FCC_VAL<22>; // Greater
+def FCC_UG : FCC_VAL<21>; // Unordered or Greater
+...
+```
-(Note that ``Sparc.h`` also defines enums that correspond to the same SPARC
-condition codes. Care must be taken to ensure the values in ``Sparc.h``
-correspond to the values in ``SparcInstrInfo.td``. I.e., ``SPCC::ICC_NE = 9``,
-``SPCC::FCC_U = 23`` and so on.)
+(Note that `Sparc.h` also defines enums that correspond to the same SPARC
+condition codes. Care must be taken to ensure the values in `Sparc.h`
+correspond to the values in `SparcInstrInfo.td`. I.e., `SPCC::ICC_NE = 9`,
+`SPCC::FCC_U = 23` and so on.)
-Instruction Operand Mapping
----------------------------
+### Instruction Operand Mapping
The code generator backend maps instruction operands to fields in the
-instruction. Whenever a bit in the instruction encoding ``Inst`` is assigned
-to field without a concrete value, an operand from the ``outs`` or ``ins`` list
+instruction. Whenever a bit in the instruction encoding `Inst` is assigned
+to field without a concrete value, an operand from the `outs` or `ins` list
is expected to have a matching name. This operand then populates that undefined
-field. For example, the Sparc target defines the ``XNORrr`` instruction as a
-``F3_1`` format instruction having three operands: the output ``$rd``, and the
-inputs ``$rs1``, and ``$rs2``.
-
-.. code-block:: text
-
- def XNORrr : F3_1<2, 0b000111,
- (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
- "xnor $rs1, $rs2, $rd",
- [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>;
-
-The instruction templates in ``SparcInstrFormats.td`` show the base class for
-``F3_1`` is ``InstSP``.
-
-.. code-block:: text
-
- class InstSP<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction {
- field bits<32> Inst;
- let Namespace = "SP";
- bits<2> op;
- let Inst{31-30} = op;
- dag OutOperandList = outs;
- dag InOperandList = ins;
- let AsmString = asmstr;
- let Pattern = pattern;
- }
-
-``InstSP`` defines the ``op`` field, and uses it to define bits 30 and 31 of the
+field. For example, the Sparc target defines the `XNORrr` instruction as a
+`F3_1` format instruction having three operands: the output `$rd`, and the
+inputs `$rs1`, and `$rs2`.
+
+```text
+def XNORrr : F3_1<2, 0b000111,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
+ "xnor $rs1, $rs2, $rd",
+ [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>;
+```
+
+The instruction templates in `SparcInstrFormats.td` show the base class for
+`F3_1` is `InstSP`.
+
+```text
+class InstSP<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction {
+ field bits<32> Inst;
+ let Namespace = "SP";
+ bits<2> op;
+ let Inst{31-30} = op;
+ dag OutOperandList = outs;
+ dag InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
+}
+```
+
+`InstSP` defines the `op` field, and uses it to define bits 30 and 31 of the
instruction, but does not assign a value to it.
-.. code-block:: text
-
- class F3<dag outs, dag ins, string asmstr, list<dag> pattern>
- : InstSP<outs, ins, asmstr, pattern> {
- bits<5> rd;
- bits<6> op3;
- bits<5> rs1;
- let op{1} = 1; // Op = 2 or 3
- let Inst{29-25} = rd;
- let Inst{24-19} = op3;
- let Inst{18-14} = rs1;
- }
-
-``F3`` defines the ``rd``, ``op3``, and ``rs1`` fields, and uses them in the
+```text
+class F3<dag outs, dag ins, string asmstr, list<dag> pattern>
+ : InstSP<outs, ins, asmstr, pattern> {
+ bits<5> rd;
+ bits<6> op3;
+ bits<5> rs1;
+ let op{1} = 1; // Op = 2 or 3
+ let Inst{29-25} = rd;
+ let Inst{24-19} = op3;
+ let Inst{18-14} = rs1;
+}
+```
+
+`F3` defines the `rd`, `op3`, and `rs1` fields, and uses them in the
instruction, and again does not assign values.
-.. code-block:: text
-
- class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
- string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
- bits<8> asi = 0; // asi not currently used
- bits<5> rs2;
- let op = opVal;
- let op3 = op3val;
- let Inst{13} = 0; // i field = 0
- let Inst{12-5} = asi; // address space identifier
- let Inst{4-0} = rs2;
- }
-
-``F3_1`` assigns a value to ``op`` and ``op3`` fields, and defines the ``rs2``
-field. Therefore, a ``F3_1`` format instruction will require a definition for
-``rd``, ``rs1``, and ``rs2`` in order to fully specify the instruction encoding.
-
-The ``XNORrr`` instruction then provides those three operands in its
+```text
+class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
+ string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
+ bits<8> asi = 0; // asi not currently used
+ bits<5> rs2;
+ let op = opVal;
+ let op3 = op3val;
+ let Inst{13} = 0; // i field = 0
+ let Inst{12-5} = asi; // address space identifier
+ let Inst{4-0} = rs2;
+}
+```
+
+`F3_1` assigns a value to `op` and `op3` fields, and defines the `rs2`
+field. Therefore, a `F3_1` format instruction will require a definition for
+`rd`, `rs1`, and `rs2` in order to fully specify the instruction encoding.
+
+The `XNORrr` instruction then provides those three operands in its
OutOperandList and InOperandList, which bind to the corresponding fields, and
thus complete the instruction encoding.
For some instructions, a single operand may contain sub-operands. As shown
-earlier, the instruction ``LDrr`` uses an input operand of type ``MEMrr``. This
+earlier, the instruction `LDrr` uses an input operand of type `MEMrr`. This
operand type contains two register sub-operands, defined by the
-``MIOperandInfo`` value to be ``(ops IntRegs, IntRegs)``.
+`MIOperandInfo` value to be `(ops IntRegs, IntRegs)`.
-.. code-block:: text
+```text
+def LDrr : F3_1 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
+ "ld [$addr], $dst",
+ [(set i32:$dst, (load ADDRrr:$addr))]>;
+```
- def LDrr : F3_1 <3, 0b000000, (outs IntRegs:$rd), (ins (MEMrr $rs1, $rs2):$addr),
- "ld [$addr], $dst",
- [(set i32:$dst, (load ADDRrr:$addr))]>;
-
-As this instruction is also the ``F3_1`` format, it will expect operands named
-``rd``, ``rs1``, and ``rs2`` as well. In order to allow this, a complex operand
+As this instruction is also the `F3_1` format, it will expect operands named
+`rd`, `rs1`, and `rs2` as well. In order to allow this, a complex operand
can optionally give names to each of its sub-operands. In this example
-``MEMrr``'s first sub-operand is named ``$rs1``, the second ``$rs2``, and the
-operand as a whole is also given the name ``$addr``.
+`MEMrr`'s first sub-operand is named `$rs1`, the second `$rs2`, and the
+operand as a whole is also given the name `$addr`.
When a particular instruction doesn't use all the operands that the instruction
format defines, a constant value may instead be bound to one or all. For
-example, the ``RDASR`` instruction only takes a single register operand, so we
-assign a constant zero to ``rs2``:
-
-.. code-block:: text
+example, the `RDASR` instruction only takes a single register operand, so we
+assign a constant zero to `rs2`:
- let rs2 = 0 in
- def RDASR : F3_1<2, 0b101000,
- (outs IntRegs:$rd), (ins ASRRegs:$rs1),
- "rd $rs1, $rd", []>;
+```text
+let rs2 = 0 in
+ def RDASR : F3_1<2, 0b101000,
+ (outs IntRegs:$rd), (ins ASRRegs:$rs1),
+ "rd $rs1, $rd", []>;
+```
-Instruction Operand Name Mapping
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Instruction Operand Name Mapping
TableGen will also generate a function called getNamedOperandIdx() which
can be used to look up an operand's index in a MachineInstr based on its
@@ -958,14 +948,14 @@ TableGen definition will add all of its operands to an enumeration
llvm::XXX:OpName and also add an entry for it into the OperandMap
table, which can be queried using getNamedOperandIdx()
-.. code-block:: text
+```text
+int DstIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::dst); // => 0
+int BIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::b); // => 1
+int CIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::c); // => 2
+int DIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::d); // => -1
- int DstIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::dst); // => 0
- int BIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::b); // => 1
- int CIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::c); // => 2
- int DIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::d); // => -1
-
- ...
+...
+```
The entries in the OpName enum are taken verbatim from the TableGen definitions,
so operands with lowercase names will have lower case entries in the enum.
@@ -976,67 +966,65 @@ For example:
XXXInstrInfo.cpp:
-.. code-block:: c++
-
- // For getNamedOperandIdx() function definition.
- #define GET_INSTRINFO_NAMED_OPS
- #include "XXXGenInstrInfo.inc"
+```c++
+// For getNamedOperandIdx() function definition.
+#define GET_INSTRINFO_NAMED_OPS
+#include "XXXGenInstrInfo.inc"
+```
XXXInstrInfo.h:
-.. code-block:: c++
-
- // For OpName enum and getNamedOperandIdx declaration.
- #define GET_INSTRINFO_OPERAND_ENUM
- #include "XXXGenInstrInfo.inc"
+```c++
+// For OpName enum and getNamedOperandIdx declaration.
+#define GET_INSTRINFO_OPERAND_ENUM
+#include "XXXGenInstrInfo.inc"
+```
-Instruction Operand Types
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Instruction Operand Types
TableGen will also generate an enumeration consisting of all named Operand
types defined in the backend, in the llvm::XXX::OpTypes namespace.
Some common immediate Operand types (for instance i8, i32, i64, f32, f64)
-are defined for all targets in ``include/llvm/Target/Target.td``, and are
+are defined for all targets in `include/llvm/Target/Target.td`, and are
available in each Target's OpTypes enum. Also, only named Operand types appear
in the enumeration: anonymous types are ignored.
-For example, the X86 backend defines ``brtarget`` and ``brtarget8``, both
-instances of the TableGen ``Operand`` class, which represent branch target
+For example, the X86 backend defines `brtarget` and `brtarget8`, both
+instances of the TableGen `Operand` class, which represent branch target
operands:
-.. code-block:: text
-
- def brtarget : Operand<OtherVT>;
- def brtarget8 : Operand<OtherVT>;
+```text
+def brtarget : Operand<OtherVT>;
+def brtarget8 : Operand<OtherVT>;
+```
This results in:
-.. code-block:: c++
-
- namespace X86 {
- namespace OpTypes {
- enum OperandType {
- ...
- brtarget,
- brtarget8,
- ...
- i32imm,
- i64imm,
- ...
- OPERAND_TYPE_LIST_END
- } // End namespace OpTypes
- } // End namespace X86
+```c++
+namespace X86 {
+namespace OpTypes {
+enum OperandType {
+ ...
+ brtarget,
+ brtarget8,
+ ...
+ i32imm,
+ i64imm,
+ ...
+ OPERAND_TYPE_LIST_END
+} // End namespace OpTypes
+} // End namespace X86
+```
In typical TableGen fashion, to use the enum, you will need to define a
preprocessor macro:
-.. code-block:: c++
-
- #define GET_INSTRINFO_OPERAND_TYPES_ENUM // For OpTypes enum
- #include "XXXGenInstrInfo.inc"
+```c++
+#define GET_INSTRINFO_OPERAND_TYPES_ENUM // For OpTypes enum
+#include "XXXGenInstrInfo.inc"
+```
-Instruction Scheduling
-----------------------
+### Instruction Scheduling
Instruction itineraries can be queried using MCDesc::getSchedClass(). The
value can be named by an enumeration in llvm::XXX::Sched namespace generated
@@ -1044,406 +1032,398 @@ by TableGen in XXXGenInstrInfo.inc. The name of the schedule classes are
the same as provided in XXXSchedule.td plus a default NoItinerary class.
The schedule models are generated by TableGen by the SubtargetEmitter,
-using the ``CodeGenSchedModels`` class. This is distinct from the itinerary
-method of specifying machine resource use. The tool ``utils/schedcover.py``
+using the `CodeGenSchedModels` class. This is distinct from the itinerary
+method of specifying machine resource use. The tool `utils/schedcover.py`
can be used to determine which instructions have been covered by the
schedule model description and which haven't. The first step is to use the
-instructions below to create an output file. Then run ``schedcover.py`` on the
+instructions below to create an output file. Then run `schedcover.py` on the
output file:
-.. code-block:: shell
-
- $ <src>/utils/schedcover.py <build>/lib/Target/AArch64/tblGenSubtarget.with
- instruction, default, CortexA53Model, CortexA57Model, CycloneModel, ExynosM3Model, FalkorModel, KryoModel, ThunderX2T99Model, ThunderXT8XModel
- ABSv16i8, WriteV, , , CyWriteV3, M3WriteNMISC1, FalkorWr_2VXVY_2cyc, KryoWrite_2cyc_XY_XY_150ln, ,
- ABSv1i64, WriteV, , , CyWriteV3, M3WriteNMISC1, FalkorWr_1VXVY_2cyc, KryoWrite_2cyc_XY_noRSV_67ln, ,
- ...
+```console
+$ <src>/utils/schedcover.py <build>/lib/Target/AArch64/tblGenSubtarget.with
+instruction, default, CortexA53Model, CortexA57Model, CycloneModel, ExynosM3Model, FalkorModel, KryoModel, ThunderX2T99Model, ThunderXT8XModel
+ABSv16i8, WriteV, , , CyWriteV3, M3WriteNMISC1, FalkorWr_2VXVY_2cyc, KryoWrite_2cyc_XY_XY_150ln, ,
+ABSv1i64, WriteV, , , CyWriteV3, M3WriteNMISC1, FalkorWr_1VXVY_2cyc, KryoWrite_2cyc_XY_noRSV_67ln, ,
+...
+```
To capture the debug output from generating a schedule model, change to the
appropriate target directory and use the following command:
-command with the ``subtarget-emitter`` debug option:
-
-.. code-block:: shell
-
- $ <build>/bin/llvm-tblgen -debug-only=subtarget-emitter -gen-subtarget \
- -I <src>/lib/Target/<target> -I <src>/include \
- -I <src>/lib/Target <src>/lib/Target/<target>/<target>.td \
- -o <build>/lib/Target/<target>/<target>GenSubtargetInfo.inc.tmp \
- > tblGenSubtarget.dbg 2>&1
-
-Where ``<build>`` is the build directory, ``src`` is the source directory,
-and ``<target>`` is the name of the target.
+command with the `subtarget-emitter` debug option:
+
+```console
+$ <build>/bin/llvm-tblgen -debug-only=subtarget-emitter -gen-subtarget \
+ -I <src>/lib/Target/<target> -I <src>/include \
+ -I <src>/lib/Target <src>/lib/Target/<target>/<target>.td \
+ -o <build>/lib/Target/<target>/<target>GenSubtargetInfo.inc.tmp \
+ > tblGenSubtarget.dbg 2>&1
+```
+
+Where `<build>` is the build directory, `src` is the source directory,
+and `<target>` is the name of the target.
To double check that the above command is what is needed, one can capture the
exact TableGen command from a build by using:
-.. code-block:: shell
+```console
+$ VERBOSE=1 make ...
+```
- $ VERBOSE=1 make ...
+and search for `llvm-tblgen` commands in the output.
-and search for ``llvm-tblgen`` commands in the output.
-
-Instruction Relation Mapping
-----------------------------
+### Instruction Relation Mapping
This TableGen feature is used to relate instructions with each other. It is
particularly useful when you have multiple instruction formats and need to
switch between them after instruction selection. This entire feature is driven
-by relation models which can be defined in ``XXXInstrInfo.td`` files
+by relation models which can be defined in `XXXInstrInfo.td` files
according to the target-specific instruction set. Relation models are defined
-using ``InstrMapping`` class as a base. TableGen parses all the models
+using `InstrMapping` class as a base. TableGen parses all the models
and generates instruction relation maps using the specified information.
-Relation maps are emitted as tables in the ``XXXGenInstrInfo.inc`` file
+Relation maps are emitted as tables in the `XXXGenInstrInfo.inc` file
along with the functions to query them. For the detailed information on how to
-use this feature, please refer to :doc:`HowToUseInstrMappings`.
+use this feature, please refer to {doc}`HowToUseInstrMappings`.
-Implement a subclass of ``TargetInstrInfo``
--------------------------------------------
+### Implement a subclass of `TargetInstrInfo`
-The final step is to hand code portions of ``XXXInstrInfo``, which implements
-the interface described in ``TargetInstrInfo.h`` (see :ref:`TargetInstrInfo`).
-These functions return ``0`` or a Boolean or they assert, unless overridden.
+The final step is to hand code portions of `XXXInstrInfo`, which implements
+the interface described in `TargetInstrInfo.h` (see {ref}`TargetInstrInfo`).
+These functions return `0` or a Boolean or they assert, unless overridden.
Here's a list of functions that are overridden for the SPARC implementation in
-``SparcInstrInfo.cpp``:
+`SparcInstrInfo.cpp`:
-* ``isLoadFromStackSlot`` --- If the specified machine instruction is a direct
+* `isLoadFromStackSlot` --- If the specified machine instruction is a direct
load from a stack slot, return the register number of the destination and the
- ``FrameIndex`` of the stack slot.
+ `FrameIndex` of the stack slot.
-* ``isStoreToStackSlot`` --- If the specified machine instruction is a direct
+* `isStoreToStackSlot` --- If the specified machine instruction is a direct
store to a stack slot, return the register number of the destination and the
- ``FrameIndex`` of the stack slot.
+ `FrameIndex` of the stack slot.
-* ``copyPhysReg`` --- Copy values between a pair of physical registers.
+* `copyPhysReg` --- Copy values between a pair of physical registers.
-* ``storeRegToStackSlot`` --- Store a register value to a stack slot.
+* `storeRegToStackSlot` --- Store a register value to a stack slot.
-* ``loadRegFromStackSlot`` --- Load a register value from a stack slot.
+* `loadRegFromStackSlot` --- Load a register value from a stack slot.
-* ``storeRegToAddr`` --- Store a register value to memory.
+* `storeRegToAddr` --- Store a register value to memory.
-* ``loadRegFromAddr`` --- Load a register value from memory.
+* `loadRegFromAddr` --- Load a register value from memory.
-* ``foldMemoryOperand`` --- Attempt to combine instructions of any load or
+* `foldMemoryOperand` --- Attempt to combine instructions of any load or
store instruction for the specified operand(s).
-Branch Folding and If Conversion
---------------------------------
+### Branch Folding and If Conversion
Performance can be improved by combining instructions or by eliminating
-instructions that are never reached. The ``analyzeBranch`` method in
-``XXXInstrInfo`` may be implemented to examine conditional instructions and
-remove unnecessary instructions. ``analyzeBranch`` looks at the end of a
+instructions that are never reached. The `analyzeBranch` method in
+`XXXInstrInfo` may be implemented to examine conditional instructions and
+remove unnecessary instructions. `analyzeBranch` looks at the end of a
machine basic block (MBB) for opportunities for improvement, such as branch
-folding and if conversion. The ``BranchFolder`` and ``IfConverter`` machine
-function passes (see the source files ``BranchFolding.cpp`` and
-``IfConversion.cpp`` in the ``lib/CodeGen`` directory) call ``analyzeBranch``
+folding and if conversion. The `BranchFolder` and `IfConverter` machine
+function passes (see the source files `BranchFolding.cpp` and
+`IfConversion.cpp` in the `lib/CodeGen` directory) call `analyzeBranch`
to improve the control flow graph that represents the instructions.
-Several implementations of ``analyzeBranch`` (for ARM, Alpha, and X86) can be
-examined as models for your own ``analyzeBranch`` implementation. Since SPARC
-does not implement a useful ``analyzeBranch``, the ARM target implementation is
+Several implementations of `analyzeBranch` (for ARM, Alpha, and X86) can be
+examined as models for your own `analyzeBranch` implementation. Since SPARC
+does not implement a useful `analyzeBranch`, the ARM target implementation is
shown below.
-``analyzeBranch`` returns a Boolean value and takes four parameters:
+`analyzeBranch` returns a Boolean value and takes four parameters:
-* ``MachineBasicBlock &MBB`` --- The incoming block to be examined.
+* `MachineBasicBlock &MBB` --- The incoming block to be examined.
-* ``MachineBasicBlock *&TBB`` --- A destination block that is returned. For a
- conditional branch that evaluates to true, ``TBB`` is the destination.
+* `MachineBasicBlock *&TBB` --- A destination block that is returned. For a
+ conditional branch that evaluates to true, `TBB` is the destination.
-* ``MachineBasicBlock *&FBB`` --- For a conditional branch that evaluates to
- false, ``FBB`` is returned as the destination.
+* `MachineBasicBlock *&FBB` --- For a conditional branch that evaluates to
+ false, `FBB` is returned as the destination.
-* ``std::vector<MachineOperand> &Cond`` --- List of operands to evaluate a
+* `std::vector<MachineOperand> &Cond` --- List of operands to evaluate a
condition for a conditional branch.
In the simplest case, if a block ends without a branch, then it falls through
-to the successor block. No destination blocks are specified for either ``TBB``
-or ``FBB``, so both parameters return ``NULL``. The start of the
-``analyzeBranch`` (see code below for the ARM target) shows the function
+to the successor block. No destination blocks are specified for either `TBB`
+or `FBB`, so both parameters return `NULL`. The start of the
+`analyzeBranch` (see code below for the ARM target) shows the function
parameters and the code for the simplest case.
-.. code-block:: c++
-
- bool ARMInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
- MachineBasicBlock *&TBB,
- MachineBasicBlock *&FBB,
- std::vector<MachineOperand> &Cond) const
- {
- MachineBasicBlock::iterator I = MBB.end();
- if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
- return false;
+```c++
+bool ARMInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ std::vector<MachineOperand> &Cond) const
+{
+ MachineBasicBlock::iterator I = MBB.end();
+ if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
+ return false;
+```
If a block ends with a single unconditional branch instruction, then
-``analyzeBranch`` (shown below) should return the destination of that branch in
-the ``TBB`` parameter.
-
-.. code-block:: c++
+`analyzeBranch` (shown below) should return the destination of that branch in
+the `TBB` parameter.
- if (LastOpc == ARM::B || LastOpc == ARM::tB) {
- TBB = LastInst->getOperand(0).getMBB();
- return false;
- }
+```c++
+ if (LastOpc == ARM::B || LastOpc == ARM::tB) {
+ TBB = LastInst->getOperand(0).getMBB();
+ return false;
+ }
+```
If a block ends with two unconditional branches, then the second branch is
never reached. In that situation, as shown below, remove the last branch
-instruction and return the penultimate branch in the ``TBB`` parameter.
-
-.. code-block:: c++
-
- if ((SecondLastOpc == ARM::B || SecondLastOpc == ARM::tB) &&
- (LastOpc == ARM::B || LastOpc == ARM::tB)) {
- TBB = SecondLastInst->getOperand(0).getMBB();
- I = LastInst;
- I->eraseFromParent();
- return false;
- }
+instruction and return the penultimate branch in the `TBB` parameter.
+
+```c++
+ if ((SecondLastOpc == ARM::B || SecondLastOpc == ARM::tB) &&
+ (LastOpc == ARM::B || LastOpc == ARM::tB)) {
+ TBB = SecondLastInst->getOperand(0).getMBB();
+ I = LastInst;
+ I->eraseFromParent();
+ return false;
+ }
+```
A block may end with a single conditional branch instruction that falls through
to successor block if the condition evaluates to false. In that case,
-``analyzeBranch`` (shown below) should return the destination of that
-conditional branch in the ``TBB`` parameter and a list of operands in the
-``Cond`` parameter to evaluate the condition.
-
-.. code-block:: c++
-
- if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) {
- // Block ends with fall-through condbranch.
- TBB = LastInst->getOperand(0).getMBB();
- Cond.push_back(LastInst->getOperand(1));
- Cond.push_back(LastInst->getOperand(2));
- return false;
- }
+`analyzeBranch` (shown below) should return the destination of that
+conditional branch in the `TBB` parameter and a list of operands in the
+`Cond` parameter to evaluate the condition.
+
+```c++
+ if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) {
+ // Block ends with fall-through condbranch.
+ TBB = LastInst->getOperand(0).getMBB();
+ Cond.push_back(LastInst->getOperand(1));
+ Cond.push_back(LastInst->getOperand(2));
+ return false;
+ }
+```
If a block ends with both a conditional branch and an ensuing unconditional
-branch, then ``analyzeBranch`` (shown below) should return the conditional
+branch, then `analyzeBranch` (shown below) should return the conditional
branch destination (assuming it corresponds to a conditional evaluation of
-"``true``") in the ``TBB`` parameter and the unconditional branch destination
-in the ``FBB`` (corresponding to a conditional evaluation of "``false``"). A
-list of operands to evaluate the condition should be returned in the ``Cond``
+"`true`") in the `TBB` parameter and the unconditional branch destination
+in the `FBB` (corresponding to a conditional evaluation of "`false`"). A
+list of operands to evaluate the condition should be returned in the `Cond`
parameter.
-.. code-block:: c++
-
- unsigned SecondLastOpc = SecondLastInst->getOpcode();
+```c++
+ unsigned SecondLastOpc = SecondLastInst->getOpcode();
- if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
- (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
- TBB = SecondLastInst->getOperand(0).getMBB();
- Cond.push_back(SecondLastInst->getOperand(1));
- Cond.push_back(SecondLastInst->getOperand(2));
- FBB = LastInst->getOperand(0).getMBB();
- return false;
- }
+ if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
+ (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
+ TBB = SecondLastInst->getOperand(0).getMBB();
+ Cond.push_back(SecondLastInst->getOperand(1));
+ Cond.push_back(SecondLastInst->getOperand(2));
+ FBB = LastInst->getOperand(0).getMBB();
+ return false;
+ }
+```
For the last two cases (ending with a single conditional branch or ending with
one conditional and one unconditional branch), the operands returned in the
-``Cond`` parameter can be passed to methods of other instructions to create new
-branches or perform other operations. An implementation of ``analyzeBranch``
-requires the helper methods ``removeBranch`` and ``insertBranch`` to manage
+`Cond` parameter can be passed to methods of other instructions to create new
+branches or perform other operations. An implementation of `analyzeBranch`
+requires the helper methods `removeBranch` and `insertBranch` to manage
subsequent operations.
-``analyzeBranch`` should return false indicating success in most circumstances.
-``analyzeBranch`` should only return true when the method is stumped about what
+`analyzeBranch` should return false indicating success in most circumstances.
+`analyzeBranch` should only return true when the method is stumped about what
to do, for example, if a block has three terminating branches.
-``analyzeBranch`` may return true if it encounters a terminator it cannot
+`analyzeBranch` may return true if it encounters a terminator it cannot
handle, such as an indirect branch.
-.. _instruction-selector:
+(instruction-selector)=
-Instruction Selector
-====================
+## Instruction Selector
-LLVM uses a ``SelectionDAG`` to represent LLVM IR instructions, and nodes of
-the ``SelectionDAG`` ideally represent native target instructions. During code
+LLVM uses a `SelectionDAG` to represent LLVM IR instructions, and nodes of
+the `SelectionDAG` ideally represent native target instructions. During code
generation, instruction selection passes are performed to convert non-native
DAG instructions into native target-specific instructions. The pass described
-in ``XXXISelDAGToDAG.cpp`` is used to match patterns and perform DAG-to-DAG
+in `XXXISelDAGToDAG.cpp` is used to match patterns and perform DAG-to-DAG
instruction selection. Optionally, a pass may be defined (in
-``XXXBranchSelector.cpp``) to perform similar DAG-to-DAG operations for branch
-instructions. Later, the code in ``XXXISelLowering.cpp`` replaces or removes
+`XXXBranchSelector.cpp`) to perform similar DAG-to-DAG operations for branch
+instructions. Later, the code in `XXXISelLowering.cpp` replaces or removes
operations and data types not supported natively (legalizes) in a
-``SelectionDAG``.
+`SelectionDAG`.
TableGen generates code for instruction selection using the following target
description input files:
-* ``XXXInstrInfo.td`` --- Contains definitions of instructions in a
- target-specific instruction set, generates ``XXXGenDAGISel.inc``, which is
- included in ``XXXISelDAGToDAG.cpp``.
+* `XXXInstrInfo.td` --- Contains definitions of instructions in a
+ target-specific instruction set, generates `XXXGenDAGISel.inc`, which is
+ included in `XXXISelDAGToDAG.cpp`.
-* ``XXXCallingConv.td`` --- Contains the calling and return value conventions
- for the target architecture, and it generates ``XXXGenCallingConv.inc``,
- which is included in ``XXXISelLowering.cpp``.
+* `XXXCallingConv.td` --- Contains the calling and return value conventions
+ for the target architecture, and it generates `XXXGenCallingConv.inc`,
+ which is included in `XXXISelLowering.cpp`.
The implementation of an instruction selection pass must include a header that
-declares the ``FunctionPass`` class or a subclass of ``FunctionPass``. In
-``XXXTargetMachine.cpp``, a Pass Manager (PM) should add each instruction
+declares the `FunctionPass` class or a subclass of `FunctionPass`. In
+`XXXTargetMachine.cpp`, a Pass Manager (PM) should add each instruction
selection pass into the queue of passes to run.
-The LLVM static compiler (``llc``) is an excellent tool for visualizing the
-contents of DAGs. To display the ``SelectionDAG`` before or after specific
-processing phases, use the command line options for ``llc``, described at
-:ref:`SelectionDAG-Process`.
+The LLVM static compiler (`llc`) is an excellent tool for visualizing the
+contents of DAGs. To display the `SelectionDAG` before or after specific
+processing phases, use the command line options for `llc`, described at
+{ref}`SelectionDAG-Process`.
To describe instruction selector behavior, you should add patterns for lowering
-LLVM code into a ``SelectionDAG`` as the last parameter of the instruction
-definitions in ``XXXInstrInfo.td``. For example, in ``SparcInstrInfo.td``,
+LLVM code into a `SelectionDAG` as the last parameter of the instruction
+definitions in `XXXInstrInfo.td`. For example, in `SparcInstrInfo.td`,
this entry defines a register store operation, and the last parameter describes
a pattern with the store DAG operator.
-.. code-block:: text
+```text
+def STrr : F3_1< 3, 0b000100, (outs), (ins MEMrr:$addr, IntRegs:$src),
+ "st $src, [$addr]", [(store i32:$src, ADDRrr:$addr)]>;
+```
- def STrr : F3_1< 3, 0b000100, (outs), (ins MEMrr:$addr, IntRegs:$src),
- "st $src, [$addr]", [(store i32:$src, ADDRrr:$addr)]>;
+`ADDRrr` is a memory mode that is also defined in `SparcInstrInfo.td`:
-``ADDRrr`` is a memory mode that is also defined in ``SparcInstrInfo.td``:
+```text
+def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
+```
-.. code-block:: text
-
- def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
-
-The definition of ``ADDRrr`` refers to ``SelectADDRrr``, which is a function
+The definition of `ADDRrr` refers to `SelectADDRrr`, which is a function
defined in an implementation of the Instructor Selector (such as
-``SparcISelDAGToDAG.cpp``).
+`SparcISelDAGToDAG.cpp`).
-In ``lib/Target/TargetSelectionDAG.td``, the DAG operator for store is defined
+In `lib/Target/TargetSelectionDAG.td`, the DAG operator for store is defined
below:
-.. code-block:: text
-
- def store : PatFrag<(ops node:$val, node:$ptr),
- (unindexedstore node:$val, node:$ptr)> {
- let IsStore = true;
- let IsTruncStore = false;
- }
-
-``XXXInstrInfo.td`` also generates (in ``XXXGenDAGISel.inc``) the
-``SelectCode`` method that is used to call the appropriate processing method
-for an instruction. In this example, ``SelectCode`` calls ``Select_ISD_STORE``
-for the ``ISD::STORE`` opcode.
-
-.. code-block:: c++
-
- SDNode *SelectCode(SDValue N) {
- ...
- MVT::ValueType NVT = N.getNode()->getValueType(0);
- switch (N.getOpcode()) {
- case ISD::STORE: {
- switch (NVT) {
- default:
- return Select_ISD_STORE(N);
- break;
- }
+```text
+def store : PatFrag<(ops node:$val, node:$ptr),
+ (unindexedstore node:$val, node:$ptr)> {
+ let IsStore = true;
+ let IsTruncStore = false;
+}
+```
+
+`XXXInstrInfo.td` also generates (in `XXXGenDAGISel.inc`) the
+`SelectCode` method that is used to call the appropriate processing method
+for an instruction. In this example, `SelectCode` calls `Select_ISD_STORE`
+for the `ISD::STORE` opcode.
+
+```c++
+SDNode *SelectCode(SDValue N) {
+ ...
+ MVT::ValueType NVT = N.getNode()->getValueType(0);
+ switch (N.getOpcode()) {
+ case ISD::STORE: {
+ switch (NVT) {
+ default:
+ return Select_ISD_STORE(N);
break;
}
- ...
+ break;
+ }
+ ...
+```
-The pattern for ``STrr`` is matched, so elsewhere in ``XXXGenDAGISel.inc``,
-code for ``STrr`` is created for ``Select_ISD_STORE``. The ``Emit_22`` method
-is also generated in ``XXXGenDAGISel.inc`` to complete the processing of this
+The pattern for `STrr` is matched, so elsewhere in `XXXGenDAGISel.inc`,
+code for `STrr` is created for `Select_ISD_STORE`. The `Emit_22` method
+is also generated in `XXXGenDAGISel.inc` to complete the processing of this
instruction.
-.. code-block:: c++
-
- SDNode *Select_ISD_STORE(const SDValue &N) {
- SDValue Chain = N.getOperand(0);
- if (Predicate_store(N.getNode())) {
- SDValue N1 = N.getOperand(1);
- SDValue N2 = N.getOperand(2);
- SDValue CPTmp0;
- SDValue CPTmp1;
-
- // Pattern: (st:void i32:i32:$src,
- // ADDRrr:i32:$addr)<<P:Predicate_store>>
- // Emits: (STrr:void ADDRrr:i32:$addr, IntRegs:i32:$src)
- // Pattern complexity = 13 cost = 1 size = 0
- if (SelectADDRrr(N, N2, CPTmp0, CPTmp1) &&
- N1.getNode()->getValueType(0) == MVT::i32 &&
- N2.getNode()->getValueType(0) == MVT::i32) {
- return Emit_22(N, SP::STrr, CPTmp0, CPTmp1);
- }
- ...
+```c++
+SDNode *Select_ISD_STORE(const SDValue &N) {
+ SDValue Chain = N.getOperand(0);
+ if (Predicate_store(N.getNode())) {
+ SDValue N1 = N.getOperand(1);
+ SDValue N2 = N.getOperand(2);
+ SDValue CPTmp0;
+ SDValue CPTmp1;
+
+ // Pattern: (st:void i32:i32:$src,
+ // ADDRrr:i32:$addr)<<P:Predicate_store>>
+ // Emits: (STrr:void ADDRrr:i32:$addr, IntRegs:i32:$src)
+ // Pattern complexity = 13 cost = 1 size = 0
+ if (SelectADDRrr(N, N2, CPTmp0, CPTmp1) &&
+ N1.getNode()->getValueType(0) == MVT::i32 &&
+ N2.getNode()->getValueType(0) == MVT::i32) {
+ return Emit_22(N, SP::STrr, CPTmp0, CPTmp1);
+ }
+...
+```
-The SelectionDAG Legalize Phase
--------------------------------
+### The SelectionDAG Legalize Phase
The Legalize phase converts a DAG to use types and operations that are natively
supported by the target. For natively unsupported types and operations, you
-need to add code to the target-specific ``XXXTargetLowering`` implementation to
+need to add code to the target-specific `XXXTargetLowering` implementation to
convert unsupported types and operations to supported ones.
-In the constructor for the ``XXXTargetLowering`` class, first use the
-``addRegisterClass`` method to specify which types are supported and which
+In the constructor for the `XXXTargetLowering` class, first use the
+`addRegisterClass` method to specify which types are supported and which
register classes are associated with them. The code for the register classes
-are generated by TableGen from ``XXXRegisterInfo.td`` and placed in
-``XXXGenRegisterInfo.h.inc``. For example, the implementation of the
-constructor for the SparcTargetLowering class (in ``SparcISelLowering.cpp``)
+are generated by TableGen from `XXXRegisterInfo.td` and placed in
+`XXXGenRegisterInfo.h.inc`. For example, the implementation of the
+constructor for the SparcTargetLowering class (in `SparcISelLowering.cpp`)
starts with the following code:
-.. code-block:: c++
-
- addRegisterClass(MVT::i32, SP::IntRegsRegisterClass);
- addRegisterClass(MVT::f32, SP::FPRegsRegisterClass);
- addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass);
+```c++
+addRegisterClass(MVT::i32, SP::IntRegsRegisterClass);
+addRegisterClass(MVT::f32, SP::FPRegsRegisterClass);
+addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass);
+```
-You should examine the node types in the ``ISD`` namespace
-(``include/llvm/CodeGen/SelectionDAGNodes.h``) and determine which operations
+You should examine the node types in the `ISD` namespace
+(`include/llvm/CodeGen/SelectionDAGNodes.h`) and determine which operations
the target natively supports. For operations that do **not** have native
-support, add a callback to the constructor for the ``XXXTargetLowering`` class,
-so the instruction selection process knows what to do. The ``TargetLowering``
-class callback methods (declared in ``llvm/Target/TargetLowering.h``) are:
-
-* ``setOperationAction`` --- General operation.
-* ``setLoadExtAction`` --- Load with extension.
-* ``setTruncStoreAction`` --- Truncating store.
-* ``setIndexedLoadAction`` --- Indexed load.
-* ``setIndexedStoreAction`` --- Indexed store.
-* ``setConvertAction`` --- Type conversion.
-* ``setCondCodeAction`` --- Support for a given condition code.
-
-Note: on older releases, ``setLoadXAction`` is used instead of
-``setLoadExtAction``. Also, on older releases, ``setCondCodeAction`` may not
+support, add a callback to the constructor for the `XXXTargetLowering` class,
+so the instruction selection process knows what to do. The `TargetLowering`
+class callback methods (declared in `llvm/Target/TargetLowering.h`) are:
+
+* `setOperationAction` --- General operation.
+* `setLoadExtAction` --- Load with extension.
+* `setTruncStoreAction` --- Truncating store.
+* `setIndexedLoadAction` --- Indexed load.
+* `setIndexedStoreAction` --- Indexed store.
+* `setConvertAction` --- Type conversion.
+* `setCondCodeAction` --- Support for a given condition code.
+
+Note: on older releases, `setLoadXAction` is used instead of
+`setLoadExtAction`. Also, on older releases, `setCondCodeAction` may not
be supported. Examine your release to see what methods are specifically
supported.
These callbacks are used to determine that an operation does or does not work
with a specified type (or types). And in all cases, the third parameter is a
-``LegalAction`` type enum value: ``Promote``, ``Expand``, ``Custom``, or
-``Legal``. ``SparcISelLowering.cpp`` contains examples of all four
-``LegalAction`` values.
+`LegalAction` type enum value: `Promote`, `Expand`, `Custom`, or
+`Legal`. `SparcISelLowering.cpp` contains examples of all four
+`LegalAction` values.
-Promote
-^^^^^^^
+#### Promote
For an operation without native support for a given type, the specified type
may be promoted to a larger type that is supported. For example, SPARC does
-not support a sign-extending load for Boolean values (``i1`` type), so in
-``SparcISelLowering.cpp`` the third parameter below, ``Promote``, changes
-``i1`` type values to a large type before loading.
+not support a sign-extending load for Boolean values (`i1` type), so in
+`SparcISelLowering.cpp` the third parameter below, `Promote`, changes
+`i1` type values to a large type before loading.
-.. code-block:: c++
+```c++
+setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
+```
- setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
-
-Expand
-^^^^^^
+#### Expand
For a type without native support, a value may need to be broken down further,
rather than promoted. For an operation without native support, a combination
of other operations may be used to similar effect. In SPARC, the
floating-point sine and cosine trig operations are supported by expansion to
-other operations, as indicated by the third parameter, ``Expand``, to
-``setOperationAction``:
-
-.. code-block:: c++
+other operations, as indicated by the third parameter, `Expand`, to
+`setOperationAction`:
- setOperationAction(ISD::FSIN, MVT::f32, Expand);
- setOperationAction(ISD::FCOS, MVT::f32, Expand);
+```c++
+setOperationAction(ISD::FSIN, MVT::f32, Expand);
+setOperationAction(ISD::FCOS, MVT::f32, Expand);
+```
-Custom
-^^^^^^
+#### Custom
For some operations, simple type promotion or operation expansion may be
insufficient. In some cases, a special intrinsic function must be implemented.
@@ -1452,67 +1432,65 @@ For example, a constant value may require special treatment, or an operation
may require spilling and restoring registers in the stack and working with
register allocators.
-As seen in ``SparcISelLowering.cpp`` code below, to perform a type conversion
+As seen in `SparcISelLowering.cpp` code below, to perform a type conversion
from a floating point value to a signed integer, first the
-``setOperationAction`` should be called with ``Custom`` as the third parameter:
+`setOperationAction` should be called with `Custom` as the third parameter:
-.. code-block:: c++
+```c++
+setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+```
- setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
-
-In the ``LowerOperation`` method, for each ``Custom`` operation, a case
+In the `LowerOperation` method, for each `Custom` operation, a case
statement should be added to indicate what function to call. In the following
-code, an ``FP_TO_SINT`` opcode will call the ``LowerFP_TO_SINT`` method:
-
-.. code-block:: c++
+code, an `FP_TO_SINT` opcode will call the `LowerFP_TO_SINT` method:
- SDValue SparcTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
- switch (Op.getOpcode()) {
- case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
- ...
- }
+```c++
+SDValue SparcTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
+ switch (Op.getOpcode()) {
+ case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
+ ...
}
+}
+```
-Finally, the ``LowerFP_TO_SINT`` method is implemented, using an FP register to
+Finally, the `LowerFP_TO_SINT` method is implemented, using an FP register to
convert the floating-point value to an integer.
-.. code-block:: c++
-
- static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
- assert(Op.getValueType() == MVT::i32);
- Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0));
- return DAG.getNode(ISD::BITCAST, MVT::i32, Op);
- }
+```c++
+static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
+ assert(Op.getValueType() == MVT::i32);
+ Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0));
+ return DAG.getNode(ISD::BITCAST, MVT::i32, Op);
+}
+```
-Legal
-^^^^^
+#### Legal
-The ``Legal`` ``LegalizeAction`` enum value simply indicates that an operation
-**is** natively supported. ``Legal`` represents the default condition, so it
-is rarely used. In ``SparcISelLowering.cpp``, the action for ``CTPOP`` (an
+The `Legal` `LegalizeAction` enum value simply indicates that an operation
+**is** natively supported. `Legal` represents the default condition, so it
+is rarely used. In `SparcISelLowering.cpp`, the action for `CTPOP` (an
operation to count the bits set in an integer) is natively supported only for
-SPARC v9. The following code enables the ``Expand`` conversion technique for
+SPARC v9. The following code enables the `Expand` conversion technique for
non-v9 SPARC implementations.
-.. code-block:: c++
-
- setOperationAction(ISD::CTPOP, MVT::i32, Expand);
- ...
- if (TM.getSubtarget<SparcSubtarget>().isV9())
- setOperationAction(ISD::CTPOP, MVT::i32, Legal);
+```c++
+setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+...
+if (TM.getSubtarget<SparcSubtarget>().isV9())
+ setOperationAction(ISD::CTPOP, MVT::i32, Legal);
+```
-.. _backend-calling-convs:
+(backend-calling-convs)=
-Calling Conventions
--------------------
+### Calling Conventions
-To support target-specific calling conventions, ``XXXGenCallingConv.td`` uses
-interfaces (such as ``CCIfType`` and ``CCAssignToReg``) that are defined in
-``lib/Target/TargetCallingConv.td``. TableGen can take the target descriptor
-file ``XXXGenCallingConv.td`` and generate the header file
-``XXXGenCallingConv.inc``, which is typically included in
-``XXXISelLowering.cpp``. You can use the interfaces in
-``TargetCallingConv.td`` to specify:
+To support target-specific calling conventions, `XXXGenCallingConv.td` uses
+interfaces (such as `CCIfType` and `CCAssignToReg`) that are defined in
+`lib/Target/TargetCallingConv.td`. TableGen can take the target descriptor
+file `XXXGenCallingConv.td` and generate the header file
+`XXXGenCallingConv.inc`, which is typically included in
+`XXXISelLowering.cpp`. You can use the interfaces in
+`TargetCallingConv.td` to specify:
* The order of parameter allocation.
@@ -1523,115 +1501,114 @@ file ``XXXGenCallingConv.td`` and generate the header file
* Whether the caller or callee unwinds the stack.
-The following example demonstrates the use of the ``CCIfType`` and
-``CCAssignToReg`` interfaces. If the ``CCIfType`` predicate is true (that is,
-if the current argument is of type ``f32`` or ``f64``), then the action is
-performed. In this case, the ``CCAssignToReg`` action assigns the argument
-value to the first available register: either ``R0`` or ``R1``.
+The following example demonstrates the use of the `CCIfType` and
+`CCAssignToReg` interfaces. If the `CCIfType` predicate is true (that is,
+if the current argument is of type `f32` or `f64`), then the action is
+performed. In this case, the `CCAssignToReg` action assigns the argument
+value to the first available register: either `R0` or `R1`.
-.. code-block:: text
+```text
+CCIfType<[f32,f64], CCAssignToReg<[R0, R1]>>
+```
- CCIfType<[f32,f64], CCAssignToReg<[R0, R1]>>
-
-``SparcCallingConv.td`` contains definitions for a target-specific return-value
-calling convention (``RetCC_Sparc32``) and a basic 32-bit C calling convention
-(``CC_Sparc32``). The definition of ``RetCC_Sparc32`` (shown below) indicates
+`SparcCallingConv.td` contains definitions for a target-specific return-value
+calling convention (`RetCC_Sparc32`) and a basic 32-bit C calling convention
+(`CC_Sparc32`). The definition of `RetCC_Sparc32` (shown below) indicates
which registers are used for specified scalar return types. A single-precision
-float is returned to register ``F0``, and a double-precision float goes to
-register ``D0``. A 32-bit integer is returned in register ``I0`` or ``I1``.
-
-.. code-block:: text
-
- def RetCC_Sparc32 : CallingConv<[
- CCIfType<[i32], CCAssignToReg<[I0, I1]>>,
- CCIfType<[f32], CCAssignToReg<[F0]>>,
- CCIfType<[f64], CCAssignToReg<[D0]>>
- ]>;
-
-The definition of ``CC_Sparc32`` in ``SparcCallingConv.td`` introduces
-``CCAssignToStack``, which assigns the value to a stack slot with the specified
+float is returned to register `F0`, and a double-precision float goes to
+register `D0`. A 32-bit integer is returned in register `I0` or `I1`.
+
+```text
+def RetCC_Sparc32 : CallingConv<[
+ CCIfType<[i32], CCAssignToReg<[I0, I1]>>,
+ CCIfType<[f32], CCAssignToReg<[F0]>>,
+ CCIfType<[f64], CCAssignToReg<[D0]>>
+]>;
+```
+
+The definition of `CC_Sparc32` in `SparcCallingConv.td` introduces
+`CCAssignToStack`, which assigns the value to a stack slot with the specified
size and alignment. In the example below, the first parameter, 4, indicates
the size of the slot, and the second parameter, also 4, indicates the stack
alignment along 4-byte units. (Special cases: if size is zero, then the ABI
size is used; if alignment is zero, then the ABI alignment is used.)
-.. code-block:: text
-
- def CC_Sparc32 : CallingConv<[
- // All arguments get passed in integer registers if there is space.
- CCIfType<[i32, f32, f64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
- CCAssignToStack<4, 4>
- ]>;
+```text
+def CC_Sparc32 : CallingConv<[
+ // All arguments get passed in integer registers if there is space.
+ CCIfType<[i32, f32, f64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
+ CCAssignToStack<4, 4>
+]>;
+```
-``CCDelegateTo`` is another commonly used interface, which tries to find a
+`CCDelegateTo` is another commonly used interface, which tries to find a
specified sub-calling convention, and, if a match is found, it is invoked. In
-the following example (in ``X86CallingConv.td``), the definition of
-``RetCC_X86_32_C`` ends with ``CCDelegateTo``. After the current value is
-assigned to the register ``ST0`` or ``ST1``, the ``RetCC_X86Common`` is
+the following example (in `X86CallingConv.td`), the definition of
+`RetCC_X86_32_C` ends with `CCDelegateTo`. After the current value is
+assigned to the register `ST0` or `ST1`, the `RetCC_X86Common` is
invoked.
-.. code-block:: text
+```text
+def RetCC_X86_32_C : CallingConv<[
+ CCIfType<[f32], CCAssignToReg<[ST0, ST1]>>,
+ CCIfType<[f64], CCAssignToReg<[ST0, ST1]>>,
+ CCDelegateTo<RetCC_X86Common>
+]>;
+```
- def RetCC_X86_32_C : CallingConv<[
- CCIfType<[f32], CCAssignToReg<[ST0, ST1]>>,
- CCIfType<[f64], CCAssignToReg<[ST0, ST1]>>,
- CCDelegateTo<RetCC_X86Common>
- ]>;
-
-``CCIfCC`` is an interface that attempts to match the given name to the current
+`CCIfCC` is an interface that attempts to match the given name to the current
calling convention. If the name identifies the current calling convention,
then a specified action is invoked. In the following example (in
-``X86CallingConv.td``), if the ``Fast`` calling convention is in use, then
-``RetCC_X86_32_Fast`` is invoked. If the ``SSECall`` calling convention is in
-use, then ``RetCC_X86_32_SSE`` is invoked.
-
-.. code-block:: text
-
- def RetCC_X86_32 : CallingConv<[
- CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_X86_32_Fast>>,
- CCIfCC<"CallingConv::X86_SSECall", CCDelegateTo<RetCC_X86_32_SSE>>,
- CCDelegateTo<RetCC_X86_32_C>
- ]>;
-
-``CCAssignToRegAndStack`` is the same as ``CCAssignToReg``, but also allocates
+`X86CallingConv.td`), if the `Fast` calling convention is in use, then
+`RetCC_X86_32_Fast` is invoked. If the `SSECall` calling convention is in
+use, then `RetCC_X86_32_SSE` is invoked.
+
+```text
+def RetCC_X86_32 : CallingConv<[
+ CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_X86_32_Fast>>,
+ CCIfCC<"CallingConv::X86_SSECall", CCDelegateTo<RetCC_X86_32_SSE>>,
+ CCDelegateTo<RetCC_X86_32_C>
+]>;
+```
+
+`CCAssignToRegAndStack` is the same as `CCAssignToReg`, but also allocates
a stack slot, when some register is used. Basically, it works like:
-``CCIf<CCAssignToReg<regList>, CCAssignToStack<size, align>>``.
+`CCIf<CCAssignToReg<regList>, CCAssignToStack<size, align>>`.
-.. code-block:: text
-
- class CCAssignToRegAndStack<list<Register> regList, int size, int align>
- : CCAssignToReg<regList> {
- int Size = size;
- int Align = align;
- }
+```text
+class CCAssignToRegAndStack<list<Register> regList, int size, int align>
+ : CCAssignToReg<regList> {
+ int Size = size;
+ int Align = align;
+}
+```
Other calling convention interfaces include:
-* ``CCIf <predicate, action>`` --- If the predicate matches, apply the action.
+* `CCIf <predicate, action>` --- If the predicate matches, apply the action.
-* ``CCIfInReg <action>`` --- If the argument is marked with the "``inreg``"
+* `CCIfInReg <action>` --- If the argument is marked with the "`inreg`"
attribute, then apply the action.
-* ``CCIfNest <action>`` --- If the argument is marked with the "``nest``"
+* `CCIfNest <action>` --- If the argument is marked with the "`nest`"
attribute, then apply the action.
-* ``CCIfNotVarArg <action>`` --- If the current function does not take a
+* `CCIfNotVarArg <action>` --- If the current function does not take a
variable number of arguments, apply the action.
-* ``CCAssignToRegWithShadow <registerList, shadowList>`` --- similar to
- ``CCAssignToReg``, but with a shadow list of registers.
+* `CCAssignToRegWithShadow <registerList, shadowList>` --- similar to
+ `CCAssignToReg`, but with a shadow list of registers.
-* ``CCPassByVal <size, align>`` --- Assign value to a stack slot with the
+* `CCPassByVal <size, align>` --- Assign value to a stack slot with the
minimum specified size and alignment.
-* ``CCPromoteToType <type>`` --- Promote the current value to the specified
+* `CCPromoteToType <type>` --- Promote the current value to the specified
type.
-* ``CallingConv <[actions]>`` --- Define each calling convention that is
+* `CallingConv <[actions]>` --- Define each calling convention that is
supported.
-Assembly Printer
-================
+## Assembly Printer
During the code emission stage, the code generator may utilize an LLVM pass to
produce assembly output. To do this, you want to implement the code for a
@@ -1639,107 +1616,106 @@ printer that converts LLVM IR to a GAS-format assembly language for your target
machine, using the following steps:
* Define all the assembly strings for your target, adding them to the
- instructions defined in the ``XXXInstrInfo.td`` file. (See
- :ref:`instruction-set`.) TableGen will produce an output file
- (``XXXGenAsmWriter.inc``) with an implementation of the ``printInstruction``
- method for the ``XXXAsmPrinter`` class.
+ instructions defined in the `XXXInstrInfo.td` file. (See
+ {ref}`instruction-set`.) TableGen will produce an output file
+ (`XXXGenAsmWriter.inc`) with an implementation of the `printInstruction`
+ method for the `XXXAsmPrinter` class.
-* Write ``XXXTargetAsmInfo.h``, which contains the bare-bones declaration of
- the ``XXXTargetAsmInfo`` class (a subclass of ``TargetAsmInfo``).
+* Write `XXXTargetAsmInfo.h`, which contains the bare-bones declaration of
+ the `XXXTargetAsmInfo` class (a subclass of `TargetAsmInfo`).
-* Write ``XXXTargetAsmInfo.cpp``, which contains target-specific values for
- ``TargetAsmInfo`` properties and sometimes new implementations for methods.
+* Write `XXXTargetAsmInfo.cpp`, which contains target-specific values for
+ `TargetAsmInfo` properties and sometimes new implementations for methods.
-* Write ``XXXAsmPrinter.cpp``, which implements the ``AsmPrinter`` class that
+* Write `XXXAsmPrinter.cpp`, which implements the `AsmPrinter` class that
performs the LLVM-to-assembly conversion.
-The code in ``XXXTargetAsmInfo.h`` is usually a trivial declaration of the
-``XXXTargetAsmInfo`` class for use in ``XXXTargetAsmInfo.cpp``. Similarly,
-``XXXTargetAsmInfo.cpp`` usually has a few declarations of ``XXXTargetAsmInfo``
-replacement values that override the default values in ``TargetAsmInfo.cpp``.
-For example in ``SparcTargetAsmInfo.cpp``:
-
-.. code-block:: c++
-
- SparcTargetAsmInfo::SparcTargetAsmInfo(const SparcTargetMachine &TM) {
- Data16bitsDirective = "\t.half\t";
- Data32bitsDirective = "\t.word\t";
- Data64bitsDirective = 0; // .xword is only supported by V9.
- ZeroDirective = "\t.skip\t";
- CommentString = "!";
- ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
- }
-
-The X86 assembly printer implementation (``X86TargetAsmInfo``) is an example
-where the target-specific ``TargetAsmInfo`` class uses an overridden methods:
-``ExpandInlineAsm``.
-
-A target-specific implementation of ``AsmPrinter`` is written in
-``XXXAsmPrinter.cpp``, which implements the ``AsmPrinter`` class that converts
+The code in `XXXTargetAsmInfo.h` is usually a trivial declaration of the
+`XXXTargetAsmInfo` class for use in `XXXTargetAsmInfo.cpp`. Similarly,
+`XXXTargetAsmInfo.cpp` usually has a few declarations of `XXXTargetAsmInfo`
+replacement values that override the default values in `TargetAsmInfo.cpp`.
+For example in `SparcTargetAsmInfo.cpp`:
+
+```c++
+SparcTargetAsmInfo::SparcTargetAsmInfo(const SparcTargetMachine &TM) {
+ Data16bitsDirective = "\t.half\t";
+ Data32bitsDirective = "\t.word\t";
+ Data64bitsDirective = 0; // .xword is only supported by V9.
+ ZeroDirective = "\t.skip\t";
+ CommentString = "!";
+ ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
+}
+```
+
+The X86 assembly printer implementation (`X86TargetAsmInfo`) is an example
+where the target-specific `TargetAsmInfo` class uses an overridden methods:
+`ExpandInlineAsm`.
+
+A target-specific implementation of `AsmPrinter` is written in
+`XXXAsmPrinter.cpp`, which implements the `AsmPrinter` class that converts
the LLVM to printable assembly. The implementation must include the following
-headers that have declarations for the ``AsmPrinter`` and
-``MachineFunctionPass`` classes. The ``MachineFunctionPass`` is a subclass of
-``FunctionPass``.
+headers that have declarations for the `AsmPrinter` and
+`MachineFunctionPass` classes. The `MachineFunctionPass` is a subclass of
+`FunctionPass`.
-.. code-block:: c++
+```c++
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+```
- #include "llvm/CodeGen/AsmPrinter.h"
- #include "llvm/CodeGen/MachineFunctionPass.h"
-
-As a ``FunctionPass``, ``AsmPrinter`` first calls ``doInitialization`` to set
-up the ``AsmPrinter``. In ``SparcAsmPrinter``, a ``Mangler`` object is
+As a `FunctionPass`, `AsmPrinter` first calls `doInitialization` to set
+up the `AsmPrinter`. In `SparcAsmPrinter`, a `Mangler` object is
instantiated to process variable names.
-In ``XXXAsmPrinter.cpp``, the ``runOnMachineFunction`` method (declared in
-``MachineFunctionPass``) must be implemented for ``XXXAsmPrinter``. In
-``MachineFunctionPass``, the ``runOnFunction`` method invokes
-``runOnMachineFunction``. Target-specific implementations of
-``runOnMachineFunction`` differ, but generally do the following to process each
+In `XXXAsmPrinter.cpp`, the `runOnMachineFunction` method (declared in
+`MachineFunctionPass`) must be implemented for `XXXAsmPrinter`. In
+`MachineFunctionPass`, the `runOnFunction` method invokes
+`runOnMachineFunction`. Target-specific implementations of
+`runOnMachineFunction` differ, but generally do the following to process each
machine function:
-* Call ``SetupMachineFunction`` to perform initialization.
+* Call `SetupMachineFunction` to perform initialization.
-* Call ``EmitConstantPool`` to print out (to the output stream) constants which
+* Call `EmitConstantPool` to print out (to the output stream) constants which
have been spilled to memory.
-* Call ``EmitJumpTableInfo`` to print out jump tables used by the current
+* Call `EmitJumpTableInfo` to print out jump tables used by the current
function.
* Print out the label for the current function.
* Print out the code for the function, including basic block labels and the
- assembly for the instruction (using ``printInstruction``)
+ assembly for the instruction (using `printInstruction`)
-The ``XXXAsmPrinter`` implementation must also include the code generated by
-TableGen that is output in the ``XXXGenAsmWriter.inc`` file. The code in
-``XXXGenAsmWriter.inc`` contains an implementation of the ``printInstruction``
+The `XXXAsmPrinter` implementation must also include the code generated by
+TableGen that is output in the `XXXGenAsmWriter.inc` file. The code in
+`XXXGenAsmWriter.inc` contains an implementation of the `printInstruction`
method that may call these methods:
-* ``printOperand``
-* ``printMemOperand``
-* ``printCCOperand`` (for conditional statements)
-* ``printDataDirective``
-* ``printDeclare``
-* ``printImplicitDef``
-* ``printInlineAsm``
+* `printOperand`
+* `printMemOperand`
+* `printCCOperand` (for conditional statements)
+* `printDataDirective`
+* `printDeclare`
+* `printImplicitDef`
+* `printInlineAsm`
-The implementations of ``printDeclare``, ``printImplicitDef``,
-``printInlineAsm``, and ``printLabel`` in ``AsmPrinter.cpp`` are generally
+The implementations of `printDeclare`, `printImplicitDef`,
+`printInlineAsm`, and `printLabel` in `AsmPrinter.cpp` are generally
adequate for printing assembly and do not need to be overridden.
-The ``printOperand`` method is implemented with a long ``switch``/``case``
+The `printOperand` method is implemented with a long `switch`/`case`
statement for the type of operand: register, immediate, basic block, external
symbol, global address, constant pool index, or jump table index. For an
-instruction with a memory address operand, the ``printMemOperand`` method
+instruction with a memory address operand, the `printMemOperand` method
should be implemented to generate the proper output. Similarly,
-``printCCOperand`` should be used to print a conditional operand.
+`printCCOperand` should be used to print a conditional operand.
-``doFinalization`` should be overridden in ``XXXAsmPrinter``, and it should be
-called to shut down the assembly printer. During ``doFinalization``, global
+`doFinalization` should be overridden in `XXXAsmPrinter`, and it should be
+called to shut down the assembly printer. During `doFinalization`, global
variables and constants are printed to output.
-Subtarget Support
-=================
+## Subtarget Support
Subtarget support is used to inform the code generation process of instruction
set variations for a given chip set. For example, the LLVM SPARC
@@ -1754,13 +1730,13 @@ The UltraSPARC architecture combines V9 with UltraSPARC Visual Instruction Set
extensions.
If subtarget support is needed, you should implement a target-specific
-``XXXSubtarget`` class for your architecture. This class should process the
-command-line options ``-mcpu=`` and ``-mattr=``.
+`XXXSubtarget` class for your architecture. This class should process the
+command-line options `-mcpu=` and `-mattr=`.
-TableGen uses definitions in the ``Target.td`` and ``Sparc.td`` files to
-generate code in ``SparcGenSubtarget.inc``. In ``Target.td``, shown below, the
-``SubtargetFeature`` interface is defined. The first 4 string parameters of
-the ``SubtargetFeature`` interface are a feature name, a XXXSubtarget field set
+TableGen uses definitions in the `Target.td` and `Sparc.td` files to
+generate code in `SparcGenSubtarget.inc`. In `Target.td`, shown below, the
+`SubtargetFeature` interface is defined. The first 4 string parameters of
+the `SubtargetFeature` interface are a feature name, a XXXSubtarget field set
by the feature, the value of the XXXSubtarget field, and a description of the
feature. (The fifth parameter is a list of features whose presence is implied,
and its default value is an empty array.)
@@ -1772,253 +1748,250 @@ of an enum constant. If multiple features use the same integer field, the
field will be set to the maximum value of all enabled features that share
the field.
-.. code-block:: text
-
- class SubtargetFeature<string n, string f, string v, string d,
- list<SubtargetFeature> i = []> {
- string Name = n;
- string FieldName = f;
- string Value = v;
- string Desc = d;
- list<SubtargetFeature> Implies = i;
- }
-
-In the ``Sparc.td`` file, the ``SubtargetFeature`` is used to define the
+```text
+class SubtargetFeature<string n, string f, string v, string d,
+ list<SubtargetFeature> i = []> {
+ string Name = n;
+ string FieldName = f;
+ string Value = v;
+ string Desc = d;
+ list<SubtargetFeature> Implies = i;
+}
+```
+
+In the `Sparc.td` file, the `SubtargetFeature` is used to define the
following features.
-.. code-block:: text
-
- def FeatureV9 : SubtargetFeature<"v9", "IsV9", "true",
- "Enable SPARC-V9 instructions">;
- def FeatureV8Deprecated : SubtargetFeature<"deprecated-v8",
- "UseV8DeprecatedInsts", "true",
- "Enable deprecated V8 instructions in V9 mode">;
- def FeatureVIS : SubtargetFeature<"vis", "IsVIS", "true",
- "Enable UltraSPARC Visual Instruction Set extensions">;
-
-Elsewhere in ``Sparc.td``, the ``Proc`` class is defined and then is used to
+```text
+def FeatureV9 : SubtargetFeature<"v9", "IsV9", "true",
+ "Enable SPARC-V9 instructions">;
+def FeatureV8Deprecated : SubtargetFeature<"deprecated-v8",
+ "UseV8DeprecatedInsts", "true",
+ "Enable deprecated V8 instructions in V9 mode">;
+def FeatureVIS : SubtargetFeature<"vis", "IsVIS", "true",
+ "Enable UltraSPARC Visual Instruction Set extensions">;
+```
+
+Elsewhere in `Sparc.td`, the `Proc` class is defined and then is used to
define particular SPARC processor subtypes that may have the previously
described features.
-.. code-block:: text
-
- class Proc<string Name, list<SubtargetFeature> Features>
- : Processor<Name, NoItineraries, Features>;
-
- def : Proc<"generic", []>;
- def : Proc<"v8", []>;
- def : Proc<"supersparc", []>;
- def : Proc<"sparclite", []>;
- def : Proc<"f934", []>;
- def : Proc<"hypersparc", []>;
- def : Proc<"sparclite86x", []>;
- def : Proc<"sparclet", []>;
- def : Proc<"tsc701", []>;
- def : Proc<"v9", [FeatureV9]>;
- def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>;
- def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
- def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
-
-From ``Target.td`` and ``Sparc.td`` files, the resulting
-``SparcGenSubtarget.inc`` specifies enum values to identify the features,
+```text
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+def : Proc<"generic", []>;
+def : Proc<"v8", []>;
+def : Proc<"supersparc", []>;
+def : Proc<"sparclite", []>;
+def : Proc<"f934", []>;
+def : Proc<"hypersparc", []>;
+def : Proc<"sparclite86x", []>;
+def : Proc<"sparclet", []>;
+def : Proc<"tsc701", []>;
+def : Proc<"v9", [FeatureV9]>;
+def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>;
+def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>;
+def : Proc<"ultrasparc3-vis", [FeatureV9, FeatureV8Deprecated, FeatureVIS]>;
+```
+
+From `Target.td` and `Sparc.td` files, the resulting
+`SparcGenSubtarget.inc` specifies enum values to identify the features,
arrays of constants to represent the CPU features and CPU subtypes, and the
-``ParseSubtargetFeatures`` method that parses the features string that sets
-specified subtarget options. The generated ``SparcGenSubtarget.inc`` file
-should be included in the ``SparcSubtarget.cpp``. The target-specific
-implementation of the ``XXXSubtarget`` method should follow this pseudocode:
-
-.. code-block:: c++
-
- XXXSubtarget::XXXSubtarget(const Module &M, const std::string &FS) {
- // Set the default features
- // Determine default and user specified characteristics of the CPU
- // Call ParseSubtargetFeatures(FS, CPU) to parse the features string
- // Perform any additional operations
- }
-
-JIT Support
-===========
+`ParseSubtargetFeatures` method that parses the features string that sets
+specified subtarget options. The generated `SparcGenSubtarget.inc` file
+should be included in the `SparcSubtarget.cpp`. The target-specific
+implementation of the `XXXSubtarget` method should follow this pseudocode:
+
+```c++
+XXXSubtarget::XXXSubtarget(const Module &M, const std::string &FS) {
+ // Set the default features
+ // Determine default and user specified characteristics of the CPU
+ // Call ParseSubtargetFeatures(FS, CPU) to parse the features string
+ // Perform any additional operations
+}
+```
+
+## JIT Support
The implementation of a target machine optionally includes a Just-In-Time (JIT)
code generator that emits machine code and auxiliary structures as binary
output that can be written directly to memory. To do this, implement JIT code
generation by performing the following steps:
-* Write an ``XXXCodeEmitter.cpp`` file that contains a machine function pass
+* Write an `XXXCodeEmitter.cpp` file that contains a machine function pass
that transforms target-machine instructions into relocatable machine
code.
-* Write an ``XXXJITInfo.cpp`` file that implements the JIT interfaces for
+* Write an `XXXJITInfo.cpp` file that implements the JIT interfaces for
target-specific code-generation activities, such as emitting machine code and
stubs.
-* Modify ``XXXTargetMachine`` so that it provides a ``TargetJITInfo`` object
- through its ``getJITInfo`` method.
+* Modify `XXXTargetMachine` so that it provides a `TargetJITInfo` object
+ through its `getJITInfo` method.
There are several different approaches to writing the JIT support code. For
instance, TableGen and target descriptor files may be used for creating a JIT
code generator, but are not mandatory. For the Alpha and PowerPC target
-machines, TableGen is used to generate ``XXXGenCodeEmitter.inc``, which
+machines, TableGen is used to generate `XXXGenCodeEmitter.inc`, which
contains the binary coding of machine instructions and the
-``getBinaryCodeForInstr`` method to access those codes. Other JIT
+`getBinaryCodeForInstr` method to access those codes. Other JIT
implementations do not.
-Both ``XXXJITInfo.cpp`` and ``XXXCodeEmitter.cpp`` must include the
-``llvm/CodeGen/MachineCodeEmitter.h`` header file that defines the
-``MachineCodeEmitter`` class containing code for several callback functions
+Both `XXXJITInfo.cpp` and `XXXCodeEmitter.cpp` must include the
+`llvm/CodeGen/MachineCodeEmitter.h` header file that defines the
+`MachineCodeEmitter` class containing code for several callback functions
that write data (in bytes, words, strings, etc.) to the output stream.
-Machine Code Emitter
---------------------
-
-In ``XXXCodeEmitter.cpp``, a target-specific of the ``Emitter`` class is
-implemented as a function pass (subclass of ``MachineFunctionPass``). The
-target-specific implementation of ``runOnMachineFunction`` (invoked by
-``runOnFunction`` in ``MachineFunctionPass``) iterates through the
-``MachineBasicBlock`` calls ``emitInstruction`` to process each instruction and
-emit binary code. ``emitInstruction`` is largely implemented with case
-statements on the instruction types defined in ``XXXInstrInfo.h``. For
-example, in ``X86CodeEmitter.cpp``, the ``emitInstruction`` method is built
-around the following ``switch``/``case`` statements:
-
-.. code-block:: c++
-
- switch (Desc->TSFlags & X86::FormMask) {
- case X86II::Pseudo: // for not yet implemented instructions
- ... // or pseudo-instructions
- break;
- case X86II::RawFrm: // for instructions with a fixed opcode value
- ...
- break;
- case X86II::AddRegFrm: // for instructions that have one register operand
- ... // added to their opcode
- break;
- case X86II::MRMDestReg:// for instructions that use the Mod/RM byte
- ... // to specify a destination (register)
- break;
- case X86II::MRMDestMem:// for instructions that use the Mod/RM byte
- ... // to specify a destination (memory)
- break;
- case X86II::MRMSrcReg: // for instructions that use the Mod/RM byte
- ... // to specify a source (register)
- break;
- case X86II::MRMSrcMem: // for instructions that use the Mod/RM byte
- ... // to specify a source (memory)
- break;
- case X86II::MRM0r: case X86II::MRM1r: // for instructions that operate on
- case X86II::MRM2r: case X86II::MRM3r: // a REGISTER r/m operand and
- case X86II::MRM4r: case X86II::MRM5r: // use the Mod/RM byte and a field
- case X86II::MRM6r: case X86II::MRM7r: // to hold extended opcode data
- ...
- break;
- case X86II::MRM0m: case X86II::MRM1m: // for instructions that operate on
- case X86II::MRM2m: case X86II::MRM3m: // a MEMORY r/m operand and
- case X86II::MRM4m: case X86II::MRM5m: // use the Mod/RM byte and a field
- case X86II::MRM6m: case X86II::MRM7m: // to hold extended opcode data
- ...
- break;
- case X86II::MRMInitReg: // for instructions whose source and
- ... // destination are the same register
- break;
- }
+### Machine Code Emitter
+
+In `XXXCodeEmitter.cpp`, a target-specific of the `Emitter` class is
+implemented as a function pass (subclass of `MachineFunctionPass`). The
+target-specific implementation of `runOnMachineFunction` (invoked by
+`runOnFunction` in `MachineFunctionPass`) iterates through the
+`MachineBasicBlock` calls `emitInstruction` to process each instruction and
+emit binary code. `emitInstruction` is largely implemented with case
+statements on the instruction types defined in `XXXInstrInfo.h`. For
+example, in `X86CodeEmitter.cpp`, the `emitInstruction` method is built
+around the following `switch`/`case` statements:
+
+```c++
+switch (Desc->TSFlags & X86::FormMask) {
+case X86II::Pseudo: // for not yet implemented instructions
+ ... // or pseudo-instructions
+ break;
+case X86II::RawFrm: // for instructions with a fixed opcode value
+ ...
+ break;
+case X86II::AddRegFrm: // for instructions that have one register operand
+ ... // added to their opcode
+ break;
+case X86II::MRMDestReg:// for instructions that use the Mod/RM byte
+ ... // to specify a destination (register)
+ break;
+case X86II::MRMDestMem:// for instructions that use the Mod/RM byte
+ ... // to specify a destination (memory)
+ break;
+case X86II::MRMSrcReg: // for instructions that use the Mod/RM byte
+ ... // to specify a source (register)
+ break;
+case X86II::MRMSrcMem: // for instructions that use the Mod/RM byte
+ ... // to specify a source (memory)
+ break;
+case X86II::MRM0r: case X86II::MRM1r: // for instructions that operate on
+case X86II::MRM2r: case X86II::MRM3r: // a REGISTER r/m operand and
+case X86II::MRM4r: case X86II::MRM5r: // use the Mod/RM byte and a field
+case X86II::MRM6r: case X86II::MRM7r: // to hold extended opcode data
+ ...
+ break;
+case X86II::MRM0m: case X86II::MRM1m: // for instructions that operate on
+case X86II::MRM2m: case X86II::MRM3m: // a MEMORY r/m operand and
+case X86II::MRM4m: case X86II::MRM5m: // use the Mod/RM byte and a field
+case X86II::MRM6m: case X86II::MRM7m: // to hold extended opcode data
+ ...
+ break;
+case X86II::MRMInitReg: // for instructions whose source and
+ ... // destination are the same register
+ break;
+}
+```
The implementations of these case statements often first emit the opcode and
then get the operand(s). Then depending upon the operand, helper methods may
-be called to process the operand(s). For example, in ``X86CodeEmitter.cpp``,
-for the ``X86II::AddRegFrm`` case, the first data emitted (by ``emitByte``) is
+be called to process the operand(s). For example, in `X86CodeEmitter.cpp`,
+for the `X86II::AddRegFrm` case, the first data emitted (by `emitByte`) is
the opcode added to the register operand. Then an object representing the
-machine operand, ``MO1``, is extracted. The helper methods such as
-``isImmediate``, ``isGlobalAddress``, ``isExternalSymbol``,
-``isConstantPoolIndex``, and ``isJumpTableIndex`` determine the operand type.
-(``X86CodeEmitter.cpp`` also has private methods such as ``emitConstant``,
-``emitGlobalAddress``, ``emitExternalSymbolAddress``, ``emitConstPoolAddress``,
-and ``emitJumpTableAddress`` that emit the data into the output stream.)
-
-.. code-block:: c++
-
- case X86II::AddRegFrm:
- MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++).getReg()));
-
- if (CurOp != NumOps) {
- const MachineOperand &MO1 = MI.getOperand(CurOp++);
- unsigned Size = X86InstrInfo::sizeOfImm(Desc);
- if (MO1.isImmediate())
- emitConstant(MO1.getImm(), Size);
- else {
- unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
- : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
- if (Opcode == X86::MOV64ri)
- rt = X86::reloc_absolute_dword; // FIXME: add X86II flag?
- if (MO1.isGlobalAddress()) {
- bool NeedStub = isa<Function>(MO1.getGlobal());
- bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
- emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
- NeedStub, isLazy);
- } else if (MO1.isExternalSymbol())
- emitExternalSymbolAddress(MO1.getSymbolName(), rt);
- else if (MO1.isConstantPoolIndex())
- emitConstPoolAddress(MO1.getIndex(), rt);
- else if (MO1.isJumpTableIndex())
- emitJumpTableAddress(MO1.getIndex(), rt);
- }
+machine operand, `MO1`, is extracted. The helper methods such as
+`isImmediate`, `isGlobalAddress`, `isExternalSymbol`,
+`isConstantPoolIndex`, and `isJumpTableIndex` determine the operand type.
+(`X86CodeEmitter.cpp` also has private methods such as `emitConstant`,
+`emitGlobalAddress`, `emitExternalSymbolAddress`, `emitConstPoolAddress`,
+and `emitJumpTableAddress` that emit the data into the output stream.)
+
+```c++
+case X86II::AddRegFrm:
+ MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(CurOp++).getReg()));
+
+ if (CurOp != NumOps) {
+ const MachineOperand &MO1 = MI.getOperand(CurOp++);
+ unsigned Size = X86InstrInfo::sizeOfImm(Desc);
+ if (MO1.isImmediate())
+ emitConstant(MO1.getImm(), Size);
+ else {
+ unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+ : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
+ if (Opcode == X86::MOV64ri)
+ rt = X86::reloc_absolute_dword; // FIXME: add X86II flag?
+ if (MO1.isGlobalAddress()) {
+ bool NeedStub = isa<Function>(MO1.getGlobal());
+ bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
+ emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
+ NeedStub, isLazy);
+ } else if (MO1.isExternalSymbol())
+ emitExternalSymbolAddress(MO1.getSymbolName(), rt);
+ else if (MO1.isConstantPoolIndex())
+ emitConstPoolAddress(MO1.getIndex(), rt);
+ else if (MO1.isJumpTableIndex())
+ emitJumpTableAddress(MO1.getIndex(), rt);
}
- break;
+ }
+ break;
+```
-In the previous example, ``XXXCodeEmitter.cpp`` uses the variable ``rt``, which
-is a ``RelocationType`` enum that may be used to relocate addresses (for
-example, a global address with a PIC base offset). The ``RelocationType`` enum
-for that target is defined in the short target-specific ``XXXRelocations.h``
-file. The ``RelocationType`` is used by the ``relocate`` method defined in
-``XXXJITInfo.cpp`` to rewrite addresses for referenced global symbols.
+In the previous example, `XXXCodeEmitter.cpp` uses the variable `rt`, which
+is a `RelocationType` enum that may be used to relocate addresses (for
+example, a global address with a PIC base offset). The `RelocationType` enum
+for that target is defined in the short target-specific `XXXRelocations.h`
+file. The `RelocationType` is used by the `relocate` method defined in
+`XXXJITInfo.cpp` to rewrite addresses for referenced global symbols.
-For example, ``X86Relocations.h`` specifies the following relocation types for
+For example, `X86Relocations.h` specifies the following relocation types for
the X86 addresses. In all four cases, the relocated value is added to the
-value already in memory. For ``reloc_pcrel_word`` and ``reloc_picrel_word``,
+value already in memory. For `reloc_pcrel_word` and `reloc_picrel_word`,
there is an additional initial adjustment.
-.. code-block:: c++
+```c++
+enum RelocationType {
+ reloc_pcrel_word = 0, // add reloc value after adjusting for the PC loc
+ reloc_picrel_word = 1, // add reloc value after adjusting for the PIC base
+ reloc_absolute_word = 2, // absolute relocation; no additional adjustment
+ reloc_absolute_dword = 3 // absolute relocation; no additional adjustment
+};
+```
- enum RelocationType {
- reloc_pcrel_word = 0, // add reloc value after adjusting for the PC loc
- reloc_picrel_word = 1, // add reloc value after adjusting for the PIC base
- reloc_absolute_word = 2, // absolute relocation; no additional adjustment
- reloc_absolute_dword = 3 // absolute relocation; no additional adjustment
- };
-
-Target JIT Info
----------------
+### Target JIT Info
-``XXXJITInfo.cpp`` implements the JIT interfaces for target-specific
+`XXXJITInfo.cpp` implements the JIT interfaces for target-specific
code-generation activities, such as emitting machine code and stubs. At
-minimum, a target-specific version of ``XXXJITInfo`` implements the following:
+minimum, a target-specific version of `XXXJITInfo` implements the following:
-* ``getLazyResolverFunction`` --- Initializes the JIT, gives the target a
+* `getLazyResolverFunction` --- Initializes the JIT, gives the target a
function that is used for compilation.
-* ``emitFunctionStub`` --- Returns a native function with a specified address
+* `emitFunctionStub` --- Returns a native function with a specified address
for a callback function.
-* ``relocate`` --- Changes the addresses of referenced globals, based on
+* `relocate` --- Changes the addresses of referenced globals, based on
relocation types.
* Callback function that are wrappers to a function stub that is used when the
real target is not initially known.
-``getLazyResolverFunction`` is generally trivial to implement. It makes the
-incoming parameter as the global ``JITCompilerFunction`` and returns the
+`getLazyResolverFunction` is generally trivial to implement. It makes the
+incoming parameter as the global `JITCompilerFunction` and returns the
callback function that will be used a function wrapper. For the Alpha target
-(in ``AlphaJITInfo.cpp``), the ``getLazyResolverFunction`` implementation is
+(in `AlphaJITInfo.cpp`), the `getLazyResolverFunction` implementation is
simply:
-.. code-block:: c++
-
- TargetJITInfo::LazyResolverFn AlphaJITInfo::getLazyResolverFunction(
- JITCompilerFn F) {
- JITCompilerFunction = F;
- return AlphaCompilationCallback;
- }
+```c++
+TargetJITInfo::LazyResolverFn AlphaJITInfo::getLazyResolverFunction(
+ JITCompilerFn F) {
+ JITCompilerFunction = F;
+ return AlphaCompilationCallback;
+}
+```
-For the X86 target, the ``getLazyResolverFunction`` implementation is a little
+For the X86 target, the `getLazyResolverFunction` implementation is a little
more complicated, because it returns a different callback function for
processors with SSE instructions and XMM registers.
diff --git a/llvm/docs/WritingAnLLVMNewPMPass.md b/llvm/docs/WritingAnLLVMNewPMPass.md
index dd094e393d7a3..d430c06b38563 100644
--- a/llvm/docs/WritingAnLLVMNewPMPass.md
+++ b/llvm/docs/WritingAnLLVMNewPMPass.md
@@ -1,19 +1,19 @@
-====================
-Writing an LLVM Pass
-====================
+# Writing an LLVM Pass
-.. program:: opt
+```{program} opt
+```
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction --- What is a pass?
-================================
+## Introduction --- What is a pass?
-.. warning::
- This document deals with the new pass manager. LLVM uses the legacy pass
- manager for the codegen pipeline. For more details, see
- :doc:`WritingAnLLVMPass` and :doc:`NewPassManager`.
+```{warning}
+This document deals with the new pass manager. LLVM uses the legacy pass
+manager for the codegen pipeline. For more details, see
+{doc}`WritingAnLLVMPass` and {doc}`NewPassManager`.
+```
The LLVM pass framework is an important part of the LLVM system, because LLVM
passes are where most of the interesting parts of the compiler exist. Passes
@@ -24,19 +24,18 @@ are, above all, a structuring technique for compiler code.
Unlike passes under the legacy pass manager where the pass interface is
defined via inheritance, passes under the new pass manager rely on
concept-based polymorphism, meaning there is no explicit interface (see
-comments in ``PassManager.h`` for more details). All LLVM passes inherit from
-the CRTP mix-in ``OptionalPassInfoMixin<PassT>`` or
-``RequiredPassInfoMixin<PassT>``. The pass should have a ``run()``
-method which returns a ``PreservedAnalyses`` and takes in some unit of IR
+comments in `PassManager.h` for more details). All LLVM passes inherit from
+the CRTP mix-in `OptionalPassInfoMixin<PassT>` or
+`RequiredPassInfoMixin<PassT>`. The pass should have a `run()`
+method which returns a `PreservedAnalyses` and takes in some unit of IR
along with an analysis manager. For example, a function pass would have a
-``PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);`` method.
+`PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);` method.
We start by showing you how to construct a pass, from setting up the build,
creating the pass, to executing and testing it. Looking at existing passes is
always a great way to learn details.
-Quick Start --- Writing hello world
-===================================
+## Quick Start --- Writing hello world
Here we describe how to write the "hello world" of passes. The "HelloWorld"
pass is designed to simply print out the name of non-external functions that
@@ -46,247 +45,240 @@ it just inspects it.
The code below already exists; feel free to create a pass with a different
name alongside the HelloWorld source files.
-.. _writing-an-llvm-npm-pass-build:
+(writing-an-llvm-npm-pass-build)=
-Setting up the build
---------------------
+### Setting up the build
-First, configure and build LLVM as described in :doc:`GettingStarted`.
+First, configure and build LLVM as described in {doc}`GettingStarted`.
Next, we will reuse an existing directory (creating a new directory involves
messing around with more CMake files than we want). For this example, we'll use
-``llvm/lib/Transforms/Utils/HelloWorld.cpp``, which has already been created.
+`llvm/lib/Transforms/Utils/HelloWorld.cpp`, which has already been created.
If you'd like to create your own pass, add a new source file into
-``llvm/lib/Transforms/Utils/CMakeLists.txt`` (assuming you want your pass in
-the ``Transforms/Utils`` directory.
+`llvm/lib/Transforms/Utils/CMakeLists.txt` (assuming you want your pass in
+the `Transforms/Utils` directory.
Now that we have the build set up for a new pass, we need to write the code
for the pass itself.
-.. _writing-an-llvm-npm-pass-basiccode:
+(writing-an-llvm-npm-pass-basiccode)=
-Basic code required
--------------------
+### Basic code required
Now that the build is setup for a new pass, we just have to write it.
First we need to define the pass in a header file. We'll create
-``llvm/include/llvm/Transforms/Utils/HelloWorld.h``. The file should
+`llvm/include/llvm/Transforms/Utils/HelloWorld.h`. The file should
contain the following boilerplate:
-.. code-block:: c++
+```c++
+#ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+#define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
- #ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
- #define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+#include "llvm/IR/PassManager.h"
- #include "llvm/IR/PassManager.h"
+namespace llvm {
- namespace llvm {
+class HelloWorldPass : public OptionalPassInfoMixin<HelloWorldPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
- class HelloWorldPass : public OptionalPassInfoMixin<HelloWorldPass> {
- public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- };
+} // namespace llvm
- } // namespace llvm
+#endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
+```
- #endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
-
-This creates the class for the pass with a declaration of the ``run()``
+This creates the class for the pass with a declaration of the `run()`
method which actually runs the pass. Inheriting from
-``OptionalPassInfoMixin<PassT>`` or ``RequiredPassInfoMixin<PassT>`` sets up
+`OptionalPassInfoMixin<PassT>` or `RequiredPassInfoMixin<PassT>` sets up
some more boilerplate so that we don't have to write it ourselves.
-``RequiredPassInfoMixin`` should be used for passes that cannot be skipped
-(e.g. ``AlwaysInlinerPass``), while ``OptionalPassInfoMixin`` should be used
+`RequiredPassInfoMixin` should be used for passes that cannot be skipped
+(e.g. `AlwaysInlinerPass`), while `OptionalPassInfoMixin` should be used
for passes that can be skipped (e.g. optimization passes).
-Our class is in the ``llvm`` namespace so that we don't pollute the global
+Our class is in the `llvm` namespace so that we don't pollute the global
namespace.
-Next we'll create ``llvm/lib/Transforms/Utils/HelloWorld.cpp``, starting
+Next we'll create `llvm/lib/Transforms/Utils/HelloWorld.cpp`, starting
with
-.. code-block:: c++
-
- #include "llvm/Transforms/Utils/HelloWorld.h"
+```c++
+#include "llvm/Transforms/Utils/HelloWorld.h"
+```
... to include the header file we just created.
-.. code-block:: c++
-
- using namespace llvm;
+```c++
+using namespace llvm;
+```
... is required because the functions from the include files live in the llvm
namespace. This should only be done in non-header files.
-Next we have the pass's ``run()`` definition:
+Next we have the pass's `run()` definition:
-.. code-block:: c++
-
- PreservedAnalyses HelloWorldPass::run(Function &F,
- FunctionAnalysisManager &AM) {
- errs() << F.getName() << "\n";
- return PreservedAnalyses::all();
- }
+```c++
+PreservedAnalyses HelloWorldPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ errs() << F.getName() << "\n";
+ return PreservedAnalyses::all();
+}
+```
... which simply prints out the name of the function to stderr. The pass
manager will ensure that the pass will be run on every function in a module.
-The ``PreservedAnalyses`` return value says that all analyses (e.g. dominator
+The `PreservedAnalyses` return value says that all analyses (e.g. dominator
tree) are still valid after this pass since we didn't modify any functions.
That's it for the pass itself. Now in order to "register" the pass, we need
to add it to a couple places. Add the following to
-``llvm/lib/Passes/PassRegistry.def`` in the ``FUNCTION_PASS`` section
-
-.. code-block:: c++
+`llvm/lib/Passes/PassRegistry.def` in the `FUNCTION_PASS` section
- FUNCTION_PASS("helloworld", HelloWorldPass())
+```c++
+FUNCTION_PASS("helloworld", HelloWorldPass())
+```
... which adds the pass under the name "helloworld".
-``llvm/lib/Passes/PassRegistry.def`` is #include'd into
-``llvm/lib/Passes/PassBuilder.cpp`` multiple times for various reasons. Since
+`llvm/lib/Passes/PassRegistry.def` is #include'd into
+`llvm/lib/Passes/PassBuilder.cpp` multiple times for various reasons. Since
it constructs our pass, we need to also add the proper #include in
-``llvm/lib/Passes/PassBuilder.cpp``:
-
-.. code-block:: c++
+`llvm/lib/Passes/PassBuilder.cpp`:
- #include "llvm/Transforms/Utils/HelloWorld.h"
+```c++
+#include "llvm/Transforms/Utils/HelloWorld.h"
+```
This should be all the code necessary for our pass, now it's time to compile
and run it.
-Running a pass with ``opt``
----------------------------
+### Running a pass with `opt`
-Now that you have a brand new shiny pass, we can build :program:`opt` and use
+Now that you have a brand new shiny pass, we can build {program}`opt` and use
it to run some LLVM IR through the pass.
-.. code-block:: console
+```console
+$ ninja -C build/ opt
+# or whatever build system/build directory you are using
- $ ninja -C build/ opt
- # or whatever build system/build directory you are using
+$ cat /tmp/a.ll
+define i32 @foo() {
+ %a = add i32 2, 3
+ ret i32 %a
+}
- $ cat /tmp/a.ll
- define i32 @foo() {
- %a = add i32 2, 3
- ret i32 %a
- }
+define void @bar() {
+ ret void
+}
- define void @bar() {
- ret void
- }
-
- $ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld
- foo
- bar
+$ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld
+foo
+bar
+```
Our pass ran and printed the names of functions as expected!
-Testing a pass
---------------
+### Testing a pass
Testing our pass is important to prevent future regressions. We'll add a lit
-test at ``llvm/test/Transforms/Utils/helloworld.ll``. See
-:doc:`TestingGuide` for more information on testing.
-
-.. code-block:: llvm
-
- $ cat llvm/test/Transforms/Utils/helloworld.ll
- ; RUN: opt -disable-output -passes=helloworld %s 2>&1 | FileCheck %s
+test at `llvm/test/Transforms/Utils/helloworld.ll`. See
+{doc}`TestingGuide` for more information on testing.
- ; CHECK: {{^}}foo{{$}}
- define i32 @foo() {
- %a = add i32 2, 3
- ret i32 %a
- }
+```llvm
+$ cat llvm/test/Transforms/Utils/helloworld.ll
+; RUN: opt -disable-output -passes=helloworld %s 2>&1 | FileCheck %s
- ; CHECK-NEXT: {{^}}bar{{$}}
- define void @bar() {
- ret void
- }
+; CHECK: {{^}}foo{{$}}
+define i32 @foo() {
+ %a = add i32 2, 3
+ ret i32 %a
+}
- $ ninja -C build check-llvm
- # runs our new test alongside all other llvm lit tests
+; CHECK-NEXT: {{^}}bar{{$}}
+define void @bar() {
+ ret void
+}
-FAQs
-====
+$ ninja -C build check-llvm
+# runs our new test alongside all other llvm lit tests
+```
-Required passes
----------------
+## FAQs
-A pass that inherits from ``RequiredPassInfoMixin<PassT>`` is a required pass. For example:
+### Required passes
-.. code-block:: c++
+A pass that inherits from `RequiredPassInfoMixin<PassT>` is a required pass. For example:
- class HelloWorldPass : public RequiredPassInfoMixin<HelloWorldPass> {
- public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- };
+```c++
+class HelloWorldPass : public RequiredPassInfoMixin<HelloWorldPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+```
A required pass is a pass that may not be skipped. An example of a required
-pass is ``AlwaysInlinerPass``, which must always be run to preserve
-``alwaysinline`` semantics. Pass managers are required since they may contain
+pass is `AlwaysInlinerPass`, which must always be run to preserve
+`alwaysinline` semantics. Pass managers are required since they may contain
other required passes.
-An example of how a pass can be skipped is the ``optnone`` function
+An example of how a pass can be skipped is the `optnone` function
attribute, which specifies that optimizations should not be run on the
-function. Required passes will still be run on ``optnone`` functions.
+function. Required passes will still be run on `optnone` functions.
For more implementation details, see
-``PassInstrumentation::runBeforePass()``.
+`PassInstrumentation::runBeforePass()`.
-Registering passes as plugins
------------------------------
+### Registering passes as plugins
LLVM provides a mechanism to register pass plugins within various tools like
-``clang`` or ``opt``. A pass plugin can add passes to default optimization
-pipelines or to be manually run via tools like ``opt``. For more information,
-see :doc:`NewPassManager`.
+`clang` or `opt`. A pass plugin can add passes to default optimization
+pipelines or to be manually run via tools like `opt`. For more information,
+see {doc}`NewPassManager`.
Create a CMake project at the root of the repo alongside
other projects. This project must contain the following minimal
-``CMakeLists.txt``:
+`CMakeLists.txt`:
-.. code-block:: cmake
+```cmake
+add_llvm_pass_plugin(MyPassName source.cpp)
+```
- add_llvm_pass_plugin(MyPassName source.cpp)
-
-See the definition of ``add_llvm_pass_plugin`` for more CMake details.
+See the definition of `add_llvm_pass_plugin` for more CMake details.
The pass must provide at least one of two entry points for the new pass manager,
one for static registration and one for dynamically loaded plugins:
-- ``llvm::PassPluginLibraryInfo get##Name##PluginInfo();``
-- ``extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() LLVM_ATTRIBUTE_WEAK;``
+- `llvm::PassPluginLibraryInfo get##Name##PluginInfo();`
+- `extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() LLVM_ATTRIBUTE_WEAK;`
Pass plugins are compiled and linked dynamically by default. Setting
-``LLVM_${NAME}_LINK_INTO_TOOLS`` to ``ON`` turns the project into a statically
+`LLVM_${NAME}_LINK_INTO_TOOLS` to `ON` turns the project into a statically
linked extension.
-For an in-tree example, see ``llvm/examples/Bye/``.
-
-To make ``PassBuilder`` aware of statically linked pass plugins:
-
-.. code-block:: c++
+For an in-tree example, see `llvm/examples/Bye/`.
- // Declare plugin extension function declarations.
- #define HANDLE_EXTENSION(Ext) llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
- #include "llvm/Support/Extension.def"
+To make `PassBuilder` aware of statically linked pass plugins:
- ...
+```c++
+// Declare plugin extension function declarations.
+#define HANDLE_EXTENSION(Ext) llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
+#include "llvm/Support/Extension.def"
- // Register plugin extensions in PassBuilder.
- #define HANDLE_EXTENSION(Ext) get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
- #include "llvm/Support/Extension.def"
+...
-To make ``PassBuilder`` aware of dynamically linked pass plugins:
+// Register plugin extensions in PassBuilder.
+#define HANDLE_EXTENSION(Ext) get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
+#include "llvm/Support/Extension.def"
+```
-.. code-block:: c++
+To make `PassBuilder` aware of dynamically linked pass plugins:
- // Load plugin dynamically.
- auto Plugin = PassPlugin::Load(PathToPlugin);
- if (!Plugin)
- report_error();
- // Register plugin extensions in PassBuilder.
- Plugin.registerPassBuilderCallbacks(PB);
+```c++
+// Load plugin dynamically.
+auto Plugin = PassPlugin::Load(PathToPlugin);
+if (!Plugin)
+ report_error();
+// Register plugin extensions in PassBuilder.
+Plugin.registerPassBuilderCallbacks(PB);
+```
diff --git a/llvm/docs/WritingAnLLVMPass.md b/llvm/docs/WritingAnLLVMPass.md
index 216e693087d96..91f81a3e0c048 100644
--- a/llvm/docs/WritingAnLLVMPass.md
+++ b/llvm/docs/WritingAnLLVMPass.md
@@ -1,21 +1,21 @@
-========================================
-Writing an LLVM Pass (legacy PM version)
-========================================
+# Writing an LLVM Pass (legacy PM version)
-.. program:: opt
+```{program} opt
+```
-.. contents::
- :local:
+```{contents}
+:local:
+```
-Introduction --- What is a pass?
-================================
+## Introduction --- What is a pass?
-.. warning::
- This document deals with the legacy pass manager. LLVM uses the new pass
- manager for the optimization pipeline (the codegen pipeline
- still uses the legacy pass manager), which has its own way of defining
- passes. For more details, see :doc:`WritingAnLLVMNewPMPass` and
- :doc:`NewPassManager`.
+```{warning}
+This document deals with the legacy pass manager. LLVM uses the new pass
+manager for the optimization pipeline (the codegen pipeline
+still uses the legacy pass manager), which has its own way of defining
+passes. For more details, see {doc}`WritingAnLLVMNewPMPass` and
+{doc}`NewPassManager`.
+```
The LLVM Pass Framework is an important part of the LLVM system, because LLVM
passes are where most of the interesting parts of the compiler exist. Passes
@@ -23,40 +23,35 @@ perform the transformations and optimizations that make up the compiler, they
build the analysis results that are used by these transformations, and they
are, above all, a structuring technique for compiler code.
-All LLVM passes are subclasses of the `Pass
-<https://llvm.org/doxygen/classllvm_1_1Pass.html>`_ class, which implement
-functionality by overriding virtual methods inherited from ``Pass``. Depending
-on how your pass works, you should inherit from the :ref:`ModulePass
-<writing-an-llvm-pass-ModulePass>` , :ref:`CallGraphSCCPass
-<writing-an-llvm-pass-CallGraphSCCPass>`, :ref:`FunctionPass
-<writing-an-llvm-pass-FunctionPass>` , or :ref:`LoopPass
-<writing-an-llvm-pass-LoopPass>`, or :ref:`RegionPass
-<writing-an-llvm-pass-RegionPass>` classes, which gives the system more
+All LLVM passes are subclasses of the [Pass](doxygen:classllvm_1_1Pass.html) class, which implement
+functionality by overriding virtual methods inherited from `Pass`. Depending
+on how your pass works, you should inherit from the
+{ref}`ModulePass <writing-an-llvm-pass-ModulePass>` , {ref}`CallGraphSCCPass <writing-an-llvm-pass-CallGraphSCCPass>`,
+{ref}`FunctionPass <writing-an-llvm-pass-FunctionPass>` , or {ref}`LoopPass <writing-an-llvm-pass-LoopPass>`, or
+{ref}`RegionPass <writing-an-llvm-pass-RegionPass>` classes, which gives the system more
information about what your pass does, and how it can be combined with other
passes. One of the main features of the LLVM Pass Framework is that it
schedules passes to run in an efficient way based on the constraints that your
pass meets (which are indicated by which class they derive from).
-.. _writing-an-llvm-pass-pass-classes:
+(writing-an-llvm-pass-pass-classes)=
-Pass classes and requirements
-=============================
+## Pass classes and requirements
One of the first things that you should do when designing a new pass is to
decide what class you should subclass for your pass. Here we talk about the
classes available, from the most general to the most specific.
-When choosing a superclass for your ``Pass``, you should choose the **most
+When choosing a superclass for your `Pass`, you should choose the **most
specific** class possible, while still being able to meet the requirements
listed. This gives the LLVM Pass Infrastructure information necessary to
optimize how passes are run, so that the resultant compiler isn't unnecessarily
slow.
-The ``ImmutablePass`` class
----------------------------
+### The `ImmutablePass` class
-The most plain and boring type of pass is the "`ImmutablePass
-<https://llvm.org/doxygen/classllvm_1_1ImmutablePass.html>`_" class. This pass
+The most plain and boring type of pass is the
+"[ImmutablePass](doxygen:classllvm_1_1ImmutablePass.html)" class. This pass
type is used for passes that do not have to be run, do not change state, and
never need to be updated. This is not a normal type of transformation or
analysis, but can provide information about the current compiler configuration.
@@ -65,413 +60,388 @@ Although this pass class is very infrequently used, it is important for
providing information about the current target machine being compiled for, and
other static information that can affect the various transformations.
-``ImmutablePass``\ es never invalidate other transformations, are never
+`ImmutablePass`es never invalidate other transformations, are never
invalidated, and are never "run".
-.. _writing-an-llvm-pass-ModulePass:
+(writing-an-llvm-pass-ModulePass)=
-The ``ModulePass`` class
-------------------------
+### The `ModulePass` class
-The `ModulePass <https://llvm.org/doxygen/classllvm_1_1ModulePass.html>`_ class
+The [ModulePass](doxygen:classllvm_1_1ModulePass.html) class
is the most general of all superclasses that you can use. Deriving from
-``ModulePass`` indicates that your pass uses the entire program as a unit,
+`ModulePass` indicates that your pass uses the entire program as a unit,
referring to function bodies in no predictable order, or adding and removing
-functions. Because nothing is known about the behavior of ``ModulePass``
+functions. Because nothing is known about the behavior of `ModulePass`
subclasses, no optimization can be done for their execution.
A module pass can use function level passes (e.g. dominators) using the
-``getAnalysis`` interface ``getAnalysis<DominatorTree>(llvm::Function *)`` to
+`getAnalysis` interface `getAnalysis<DominatorTree>(llvm::Function *)` to
provide the function to retrieve analysis result for, if the function pass does
not require any module or immutable passes. Note that this can only be done
for functions for which the analysis ran, e.g. in the case of dominators you
-should only ask for the ``DominatorTree`` for function definitions, not
+should only ask for the `DominatorTree` for function definitions, not
declarations.
-To write a correct ``ModulePass`` subclass, derive from ``ModulePass`` and
-override the ``runOnModule`` method with the following signature:
+To write a correct `ModulePass` subclass, derive from `ModulePass` and
+override the `runOnModule` method with the following signature:
-The ``runOnModule`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `runOnModule` method
-.. code-block:: c++
+```cpp
+virtual bool runOnModule(Module &M) = 0;
+```
- virtual bool runOnModule(Module &M) = 0;
+The `runOnModule` method performs the interesting work of the pass. It
+should return `true` if the module was modified by the transformation and
+`false` otherwise.
-The ``runOnModule`` method performs the interesting work of the pass. It
-should return ``true`` if the module was modified by the transformation and
-``false`` otherwise.
+(writing-an-llvm-pass-CallGraphSCCPass)=
-.. _writing-an-llvm-pass-CallGraphSCCPass:
+### The `CallGraphSCCPass` class
-The ``CallGraphSCCPass`` class
-------------------------------
-
-The `CallGraphSCCPass
-<https://llvm.org/doxygen/classllvm_1_1CallGraphSCCPass.html>`_ is used by
+The [CallGraphSCCPass](doxygen:classllvm_1_1CallGraphSCCPass.html) is used by
passes that need to traverse the program bottom-up on the call graph (callees
-before callers). Deriving from ``CallGraphSCCPass`` provides some mechanics
-for building and traversing the ``CallGraph``, but also allows the system to
-optimize execution of ``CallGraphSCCPass``\ es. If your pass meets the
+before callers). Deriving from `CallGraphSCCPass` provides some mechanics
+for building and traversing the `CallGraph`, but also allows the system to
+optimize execution of `CallGraphSCCPass`es. If your pass meets the
requirements outlined below, and doesn't meet the requirements of a
-:ref:`FunctionPass <writing-an-llvm-pass-FunctionPass>`, you should derive from
-``CallGraphSCCPass``.
+{ref}`FunctionPass <writing-an-llvm-pass-FunctionPass>`, you should derive from
+`CallGraphSCCPass`.
-``TODO``: explain briefly what SCC, Tarjan's algo, and B-U mean.
+`TODO`: explain briefly what SCC, Tarjan's algo, and B-U mean.
To be explicit, CallGraphSCCPass subclasses are:
-#. ... *not allowed* to inspect or modify any ``Function``\ s other than those
+1. ... *not allowed* to inspect or modify any `Function`s other than those
in the current SCC and the direct callers and direct callees of the SCC.
-#. ... *required* to preserve the current ``CallGraph`` object, updating it to
+1. ... *required* to preserve the current `CallGraph` object, updating it to
reflect any changes made to the program.
-#. ... *not allowed* to add or remove SCC's from the current Module, though
+1. ... *not allowed* to add or remove SCC's from the current Module, though
they may change the contents of an SCC.
-#. ... *allowed* to add or remove global variables from the current Module.
-#. ... *allowed* to maintain state across invocations of :ref:`runOnSCC
- <writing-an-llvm-pass-runOnSCC>` (including global data).
+1. ... *allowed* to add or remove global variables from the current Module.
+1. ... *allowed* to maintain state across invocations of
+ {ref}`runOnSCC <writing-an-llvm-pass-runOnSCC>` (including global data).
-Implementing a ``CallGraphSCCPass`` is slightly tricky in some cases because it
+Implementing a `CallGraphSCCPass` is slightly tricky in some cases because it
has to handle SCCs with more than one node in it. All of the virtual methods
-described below should return ``true`` if they modified the program, or
-``false`` if they didn't.
-
-The ``doInitialization(CallGraph &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+described below should return `true` if they modified the program, or
+`false` if they didn't.
-.. code-block:: c++
+#### The `doInitialization(CallGraph &)` method
- virtual bool doInitialization(CallGraph &CG);
+```cpp
+virtual bool doInitialization(CallGraph &CG);
+```
-The ``doInitialization`` method is allowed to do most of the things that
-``CallGraphSCCPass``\ es are not allowed to do. They can add and remove
-functions, get pointers to functions, etc. The ``doInitialization`` method is
+The `doInitialization` method is allowed to do most of the things that
+`CallGraphSCCPass`es are not allowed to do. They can add and remove
+functions, get pointers to functions, etc. The `doInitialization` method is
designed to do simple initialization type of stuff that does not depend on the
-SCCs being processed. The ``doInitialization`` method call is not scheduled to
+SCCs being processed. The `doInitialization` method call is not scheduled to
overlap with any other pass executions (thus it should be very fast).
-.. _writing-an-llvm-pass-runOnSCC:
-
-The ``runOnSCC`` method
-^^^^^^^^^^^^^^^^^^^^^^^
+(writing-an-llvm-pass-runOnSCC)=
-.. code-block:: c++
+#### The `runOnSCC` method
- virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
+```cpp
+virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
+```
-The ``runOnSCC`` method performs the interesting work of the pass, and should
-return ``true`` if the module was modified by the transformation, ``false``
+The `runOnSCC` method performs the interesting work of the pass, and should
+return `true` if the module was modified by the transformation, `false`
otherwise.
-The ``doFinalization(CallGraph &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `doFinalization(CallGraph &)` method
-.. code-block:: c++
+```cpp
+virtual bool doFinalization(CallGraph &CG);
+```
- virtual bool doFinalization(CallGraph &CG);
+The `doFinalization` method is an infrequently used method that is called
+when the pass framework has finished calling
+{ref}`runOnSCC <writing-an-llvm-pass-runOnSCC>` for every SCC in the program being compiled.
-The ``doFinalization`` method is an infrequently used method that is called
-when the pass framework has finished calling :ref:`runOnSCC
-<writing-an-llvm-pass-runOnSCC>` for every SCC in the program being compiled.
+(writing-an-llvm-pass-FunctionPass)=
-.. _writing-an-llvm-pass-FunctionPass:
+### The `FunctionPass` class
-The ``FunctionPass`` class
---------------------------
-
-In contrast to ``ModulePass`` subclasses, `FunctionPass
-<https://llvm.org/doxygen/classllvm_1_1Pass.html>`_ subclasses do have a
+In contrast to `ModulePass` subclasses,
+[FunctionPass](doxygen:classllvm_1_1Pass.html) subclasses do have a
predictable, local behavior that can be expected by the system. All
-``FunctionPass`` execute on each function in the program independent of all of
-the other functions in the program. ``FunctionPass``\ es do not require that
-they are executed in a particular order, and ``FunctionPass``\ es do not modify
+`FunctionPass` execute on each function in the program independent of all of
+the other functions in the program. `FunctionPass`es do not require that
+they are executed in a particular order, and `FunctionPass`es do not modify
external functions.
-To be explicit, ``FunctionPass`` subclasses are not allowed to:
+To be explicit, `FunctionPass` subclasses are not allowed to:
-#. Inspect or modify a ``Function`` other than the one currently being processed.
-#. Add or remove ``Function``\ s from the current ``Module``.
-#. Add or remove global variables from the current ``Module``.
-#. Maintain state across invocations of :ref:`runOnFunction
- <writing-an-llvm-pass-runOnFunction>` (including global data).
+1. Inspect or modify a `Function` other than the one currently being processed.
+1. Add or remove `Function`s from the current `Module`.
+1. Add or remove global variables from the current `Module`.
+1. Maintain state across invocations of
+ {ref}`runOnFunction <writing-an-llvm-pass-runOnFunction>` (including global data).
-Implementing a ``FunctionPass`` is usually straightforward. ``FunctionPass``\
-es may override three virtual methods to do their work. All of these methods
-should return ``true`` if they modified the program, or ``false`` if they
+Implementing a `FunctionPass` is usually straightforward. `FunctionPass`es may
+override three virtual methods to do their work. All of these methods
+should return `true` if they modified the program, or `false` if they
didn't.
-.. _writing-an-llvm-pass-doInitialization-mod:
-
-The ``doInitialization(Module &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+(writing-an-llvm-pass-doInitialization-mod)=
-.. code-block:: c++
+#### The `doInitialization(Module &)` method
- virtual bool doInitialization(Module &M);
+```cpp
+virtual bool doInitialization(Module &M);
+```
-The ``doInitialization`` method is allowed to do most of the things that
-``FunctionPass``\ es are not allowed to do. They can add and remove functions,
-get pointers to functions, etc. The ``doInitialization`` method is designed to
+The `doInitialization` method is allowed to do most of the things that
+`FunctionPass`es are not allowed to do. They can add and remove functions,
+get pointers to functions, etc. The `doInitialization` method is designed to
do simple initialization type of stuff that does not depend on the functions
-being processed. The ``doInitialization`` method call is not scheduled to
+being processed. The `doInitialization` method call is not scheduled to
overlap with any other pass executions (thus it should be very fast).
-A good example of how this method should be used is the `LowerAllocations
-<https://llvm.org/doxygen/LowerAllocations_8cpp-source.html>`_ pass. This pass
-converts ``malloc`` and ``free`` instructions into platform dependent
-``malloc()`` and ``free()`` function calls. It uses the ``doInitialization``
-method to get a reference to the ``malloc`` and ``free`` functions that it
+A good example of how this method should be used is the
+[LowerAllocations](doxygen:LowerAllocations_8cpp-source.html) pass. This pass
+converts `malloc` and `free` instructions into platform dependent
+`malloc()` and `free()` function calls. It uses the `doInitialization`
+method to get a reference to the `malloc` and `free` functions that it
needs, adding prototypes to the module if necessary.
-.. _writing-an-llvm-pass-runOnFunction:
+(writing-an-llvm-pass-runOnFunction)=
-The ``runOnFunction`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `runOnFunction` method
-.. code-block:: c++
+```cpp
+virtual bool runOnFunction(Function &F) = 0;
+```
- virtual bool runOnFunction(Function &F) = 0;
-
-The ``runOnFunction`` method must be implemented by your subclass to do the
-transformation or analysis work of your pass. As usual, a ``true`` value
+The `runOnFunction` method must be implemented by your subclass to do the
+transformation or analysis work of your pass. As usual, a `true` value
should be returned if the function is modified.
-.. _writing-an-llvm-pass-doFinalization-mod:
-
-The ``doFinalization(Module &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+(writing-an-llvm-pass-doFinalization-mod)=
-.. code-block:: c++
+#### The `doFinalization(Module &)` method
- virtual bool doFinalization(Module &M);
+```cpp
+virtual bool doFinalization(Module &M);
+```
-The ``doFinalization`` method is an infrequently used method that is called
-when the pass framework has finished calling :ref:`runOnFunction
-<writing-an-llvm-pass-runOnFunction>` for every function in the program being
+The `doFinalization` method is an infrequently used method that is called
+when the pass framework has finished calling
+{ref}`runOnFunction <writing-an-llvm-pass-runOnFunction>` for every function in the program being
compiled.
-.. _writing-an-llvm-pass-LoopPass:
+(writing-an-llvm-pass-LoopPass)=
-The ``LoopPass`` class
-----------------------
+### The `LoopPass` class
-All ``LoopPass`` execute on each :ref:`loop <loop-terminology>` in the function
-independent of all of the other loops in the function. ``LoopPass`` processes
+All `LoopPass` execute on each {ref}`loop <loop-terminology>` in the function
+independent of all of the other loops in the function. `LoopPass` processes
loops in loop nest order such that outer most loop is processed last.
-``LoopPass`` subclasses are allowed to update loop nest using ``LPPassManager``
+`LoopPass` subclasses are allowed to update loop nest using `LPPassManager`
interface. Implementing a loop pass is usually straightforward.
-``LoopPass``\ es may override three virtual methods to do their work. All
-these methods should return ``true`` if they modified the program, or ``false``
+`LoopPass`es may override three virtual methods to do their work. All
+these methods should return `true` if they modified the program, or `false`
if they didn't.
-A ``LoopPass`` subclass which is intended to run as part of the main loop pass
+A `LoopPass` subclass which is intended to run as part of the main loop pass
pipeline needs to preserve all of the same *function* analyses that the other
loop passes in its pipeline require. To make that easier,
-a ``getLoopAnalysisUsage`` function is provided by ``LoopUtils.h``. It can be
-called within the subclass's ``getAnalysisUsage`` override to get consistent
-and correct behavior. Analogously, ``INITIALIZE_PASS_DEPENDENCY(LoopPass)``
+a `getLoopAnalysisUsage` function is provided by `LoopUtils.h`. It can be
+called within the subclass's `getAnalysisUsage` override to get consistent
+and correct behavior. Analogously, `INITIALIZE_PASS_DEPENDENCY(LoopPass)`
will initialize this set of function analyses.
-The ``doInitialization(Loop *, LPPassManager &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: c++
+#### The `doInitialization(Loop *, LPPassManager &)` method
- virtual bool doInitialization(Loop *, LPPassManager &LPM);
+```cpp
+virtual bool doInitialization(Loop *, LPPassManager &LPM);
+```
-The ``doInitialization`` method is designed to do simple initialization type of
+The `doInitialization` method is designed to do simple initialization type of
stuff that does not depend on the functions being processed. The
-``doInitialization`` method call is not scheduled to overlap with any other
-pass executions (thus it should be very fast). ``LPPassManager`` interface
-should be used to access ``Function`` or ``Module`` level analysis information.
+`doInitialization` method call is not scheduled to overlap with any other
+pass executions (thus it should be very fast). `LPPassManager` interface
+should be used to access `Function` or `Module` level analysis information.
-.. _writing-an-llvm-pass-runOnLoop:
+(writing-an-llvm-pass-runOnLoop)=
-The ``runOnLoop`` method
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `runOnLoop` method
-.. code-block:: c++
+```cpp
+virtual bool runOnLoop(Loop *, LPPassManager &LPM) = 0;
+```
- virtual bool runOnLoop(Loop *, LPPassManager &LPM) = 0;
-
-The ``runOnLoop`` method must be implemented by your subclass to do the
-transformation or analysis work of your pass. As usual, a ``true`` value
-should be returned if the function is modified. ``LPPassManager`` interface
+The `runOnLoop` method must be implemented by your subclass to do the
+transformation or analysis work of your pass. As usual, a `true` value
+should be returned if the function is modified. `LPPassManager` interface
should be used to update loop nest.
-The ``doFinalization()`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: c++
+#### The `doFinalization()` method
- virtual bool doFinalization();
+```cpp
+virtual bool doFinalization();
+```
-The ``doFinalization`` method is an infrequently used method that is called
-when the pass framework has finished calling :ref:`runOnLoop
-<writing-an-llvm-pass-runOnLoop>` for every loop in the program being compiled.
+The `doFinalization` method is an infrequently used method that is called
+when the pass framework has finished calling
+{ref}`runOnLoop <writing-an-llvm-pass-runOnLoop>` for every loop in the program being compiled.
-.. _writing-an-llvm-pass-RegionPass:
+(writing-an-llvm-pass-RegionPass)=
-The ``RegionPass`` class
-------------------------
+### The `RegionPass` class
-``RegionPass`` is similar to :ref:`LoopPass <writing-an-llvm-pass-LoopPass>`,
+`RegionPass` is similar to {ref}`LoopPass <writing-an-llvm-pass-LoopPass>`,
but executes on each single entry single exit region in the function.
-``RegionPass`` processes regions in nested order such that the outer most
+`RegionPass` processes regions in nested order such that the outer most
region is processed last.
-``RegionPass`` subclasses are allowed to update the region tree by using the
-``RGPassManager`` interface. You may override three virtual methods of
-``RegionPass`` to implement your own region pass. All these methods should
-return ``true`` if they modified the program, or ``false`` if they did not.
+`RegionPass` subclasses are allowed to update the region tree by using the
+`RGPassManager` interface. You may override three virtual methods of
+`RegionPass` to implement your own region pass. All these methods should
+return `true` if they modified the program, or `false` if they did not.
-The ``doInitialization(Region *, RGPassManager &)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `doInitialization(Region *, RGPassManager &)` method
-.. code-block:: c++
+```cpp
+virtual bool doInitialization(Region *, RGPassManager &RGM);
+```
- virtual bool doInitialization(Region *, RGPassManager &RGM);
-
-The ``doInitialization`` method is designed to do simple initialization type of
+The `doInitialization` method is designed to do simple initialization type of
stuff that does not depend on the functions being processed. The
-``doInitialization`` method call is not scheduled to overlap with any other
-pass executions (thus it should be very fast). ``RPPassManager`` interface
-should be used to access ``Function`` or ``Module`` level analysis information.
-
-.. _writing-an-llvm-pass-runOnRegion:
+`doInitialization` method call is not scheduled to overlap with any other
+pass executions (thus it should be very fast). `RPPassManager` interface
+should be used to access `Function` or `Module` level analysis information.
-The ``runOnRegion`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+(writing-an-llvm-pass-runOnRegion)=
-.. code-block:: c++
+#### The `runOnRegion` method
- virtual bool runOnRegion(Region *, RGPassManager &RGM) = 0;
+```cpp
+virtual bool runOnRegion(Region *, RGPassManager &RGM) = 0;
+```
-The ``runOnRegion`` method must be implemented by your subclass to do the
+The `runOnRegion` method must be implemented by your subclass to do the
transformation or analysis work of your pass. As usual, a true value should be
-returned if the region is modified. ``RGPassManager`` interface should be used to
+returned if the region is modified. `RGPassManager` interface should be used to
update region tree.
-The ``doFinalization()`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: c++
+#### The `doFinalization()` method
- virtual bool doFinalization();
+```cpp
+virtual bool doFinalization();
+```
-The ``doFinalization`` method is an infrequently used method that is called
-when the pass framework has finished calling :ref:`runOnRegion
-<writing-an-llvm-pass-runOnRegion>` for every region in the program being
+The `doFinalization` method is an infrequently used method that is called
+when the pass framework has finished calling
+{ref}`runOnRegion <writing-an-llvm-pass-runOnRegion>` for every region in the program being
compiled.
-The ``MachineFunctionPass`` class
----------------------------------
+### The `MachineFunctionPass` class
-A ``MachineFunctionPass`` is a part of the LLVM code generator that executes on
+A `MachineFunctionPass` is a part of the LLVM code generator that executes on
the machine-dependent representation of each LLVM function in the program.
Code generator passes are registered and initialized specially by
-``TargetMachine::addPassesToEmitFile`` and similar routines, so they cannot
-generally be run from the :program:`opt` or :program:`bugpoint` commands.
+`TargetMachine::addPassesToEmitFile` and similar routines, so they cannot
+generally be run from the {program}`opt` or {program}`bugpoint` commands.
-A ``MachineFunctionPass`` is also a ``FunctionPass``, so all the restrictions
-that apply to a ``FunctionPass`` also apply to it. ``MachineFunctionPass``\ es
-also have additional restrictions. In particular, ``MachineFunctionPass``\ es
+A `MachineFunctionPass` is also a `FunctionPass`, so all the restrictions
+that apply to a `FunctionPass` also apply to it. `MachineFunctionPass`es
+also have additional restrictions. In particular, `MachineFunctionPass`es
are not allowed to do any of the following:
-#. Modify or create any LLVM IR ``Instruction``\ s, ``BasicBlock``\ s,
- ``Argument``\ s, ``Function``\ s, ``GlobalVariable``\ s,
- ``GlobalAlias``\ es, or ``Module``\ s.
-#. Modify a ``MachineFunction`` other than the one currently being processed.
-#. Maintain state across invocations of :ref:`runOnMachineFunction
- <writing-an-llvm-pass-runOnMachineFunction>` (including global data).
+1. Modify or create any LLVM IR `Instruction`s, `BasicBlock`s,
+ `Argument`s, `Function`s, `GlobalVariable`s,
+ `GlobalAlias`es, or `Module`s.
+1. Modify a `MachineFunction` other than the one currently being processed.
+1. Maintain state across invocations of
+ {ref}`runOnMachineFunction <writing-an-llvm-pass-runOnMachineFunction>` (including global data).
-.. _writing-an-llvm-pass-runOnMachineFunction:
+(writing-an-llvm-pass-runOnMachineFunction)=
-The ``runOnMachineFunction(MachineFunction &MF)`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `runOnMachineFunction(MachineFunction &MF)` method
-.. code-block:: c++
+```cpp
+virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+```
- virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+`runOnMachineFunction` can be considered the main entry point of a
+`MachineFunctionPass`; that is, you should override this method to do the
+work of your `MachineFunctionPass`.
-``runOnMachineFunction`` can be considered the main entry point of a
-``MachineFunctionPass``; that is, you should override this method to do the
-work of your ``MachineFunctionPass``.
-
-The ``runOnMachineFunction`` method is called on every ``MachineFunction`` in a
-``Module``, so that the ``MachineFunctionPass`` may perform optimizations on
+The `runOnMachineFunction` method is called on every `MachineFunction` in a
+`Module`, so that the `MachineFunctionPass` may perform optimizations on
the machine-dependent representation of the function. If you want to get at
-the LLVM ``Function`` for the ``MachineFunction`` you're working on, use
-``MachineFunction``'s ``getFunction()`` accessor method --- but remember, you
-may not modify the LLVM ``Function`` or its contents from a
-``MachineFunctionPass``.
+the LLVM `Function` for the `MachineFunction` you're working on, use
+`MachineFunction`'s `getFunction()` accessor method --- but remember, you
+may not modify the LLVM `Function` or its contents from a
+`MachineFunctionPass`.
-.. _writing-an-llvm-pass-registration:
+(writing-an-llvm-pass-registration)=
-Pass registration
------------------
+### Pass registration
-Passes are registered with the ``RegisterPass`` template. The template
+Passes are registered with the `RegisterPass` template. The template
parameter is the name of the pass that is to be used on the command line to
specify that the pass should be added to a program. The first argument is the
-name of the pass, which is to be used for the :option:`-help` output of
+name of the pass, which is to be used for the {option}`-help` output of
programs, as well as for debug output generated by the `--debug-pass` option.
If you want your pass to be easily dumpable, you should implement the virtual
print method:
-The ``print`` method
-^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: c++
+#### The `print` method
- virtual void print(llvm::raw_ostream &O, const Module *M) const;
+```cpp
+virtual void print(llvm::raw_ostream &O, const Module *M) const;
+```
-The ``print`` method must be implemented by "analyses" in order to print a
+The `print` method must be implemented by "analyses" in order to print a
human-readable version of the analysis results. This is useful for debugging
an analysis itself, as well as for other people to figure out how an analysis
-works. Use the opt ``-analyze`` argument to invoke this method.
+works. Use the opt `-analyze` argument to invoke this method.
-The ``llvm::raw_ostream`` parameter specifies the stream to write the results
-on, and the ``Module`` parameter gives a pointer to the top level module of the
-program that has been analyzed. Note however that this pointer may be ``NULL``
-in certain circumstances (such as calling the ``Pass::dump()`` from a
+The `llvm::raw_ostream` parameter specifies the stream to write the results
+on, and the `Module` parameter gives a pointer to the top level module of the
+program that has been analyzed. Note however that this pointer may be `NULL`
+in certain circumstances (such as calling the `Pass::dump()` from a
debugger), so it should only be used to enhance debug output, it should not be
depended on.
-Scheduling a MachineFunctionPass
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Scheduling a MachineFunctionPass
-Backends create a ``TargetPassConfig`` and use ``addPass`` to schedule
-``MachineFunctionPass``\ es. External plugins can register a callback to modify
+Backends create a `TargetPassConfig` and use `addPass` to schedule
+`MachineFunctionPass`es. External plugins can register a callback to modify
and insert additional passes:
-.. code-block:: c++
-
- RegisterTargetPassConfigCallback X{[](auto &TM, auto &PM, auto *TPC) {
- TPC->insertPass(/* ... */);
- TPC->substitutePass(/* ... */);
- }};
+```cpp
+RegisterTargetPassConfigCallback X{[](auto &TM, auto &PM, auto *TPC) {
+ TPC->insertPass(/* ... */);
+ TPC->substitutePass(/* ... */);
+}};
+```
Note that passes still have to be registered:
-.. code-block:: c++
-
- __attribute__((constructor)) static void initCodeGenPlugin() {
- initializeExamplePass(*PassRegistry::getPassRegistry());
- }
+```cpp
+__attribute__((constructor)) static void initCodeGenPlugin() {
+ initializeExamplePass(*PassRegistry::getPassRegistry());
+}
+```
-.. _writing-an-llvm-pass-interaction:
+(writing-an-llvm-pass-interaction)=
-Specifying interactions between passes
---------------------------------------
+### Specifying interactions between passes
-One of the main responsibilities of the ``PassManager`` is to make sure that
-passes interact with each other correctly. Because ``PassManager`` tries to
-:ref:`optimize the execution of passes <writing-an-llvm-pass-passmanager>` it
+One of the main responsibilities of the `PassManager` is to make sure that
+passes interact with each other correctly. Because `PassManager` tries to
+{ref}`optimize the execution of passes <writing-an-llvm-pass-passmanager>` it
must know how the passes interact with each other and what dependencies exist
between the various passes. To track this, each pass can declare the set of
passes that are required to be executed before the current pass, and the passes
@@ -480,47 +450,43 @@ which are invalidated by the current pass.
Typically this functionality is used to require that analysis results are
computed before your pass is run. Running arbitrary transformation passes can
invalidate the computed analysis results, which is what the invalidation set
-specifies. If a pass does not implement the :ref:`getAnalysisUsage
-<writing-an-llvm-pass-getAnalysisUsage>` method, it defaults to not having any
+specifies. If a pass does not implement the
+{ref}`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>` method, it defaults to not having any
prerequisite passes, and invalidating **all** other passes.
-.. _writing-an-llvm-pass-getAnalysisUsage:
+(writing-an-llvm-pass-getAnalysisUsage)=
-The ``getAnalysisUsage`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `getAnalysisUsage` method
-.. code-block:: c++
+```cpp
+virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+```
- virtual void getAnalysisUsage(AnalysisUsage &Info) const;
-
-By implementing the ``getAnalysisUsage`` method, the required and invalidated
+By implementing the `getAnalysisUsage` method, the required and invalidated
sets may be specified for your transformation. The implementation should fill
-in the `AnalysisUsage
-<https://llvm.org/doxygen/classllvm_1_1AnalysisUsage.html>`_ object with
+in the [AnalysisUsage](doxygen:classllvm_1_1AnalysisUsage.html) object with
information about which passes are required and not invalidated. To do this, a
-pass may call any of the following methods on the ``AnalysisUsage`` object:
+pass may call any of the following methods on the `AnalysisUsage` object:
-The ``AnalysisUsage::addRequired<>`` and ``AnalysisUsage::addRequiredTransitive<>`` methods
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `AnalysisUsage::addRequired<>` and `AnalysisUsage::addRequiredTransitive<>` methods
If your pass requires a previous pass to be executed (an analysis for example),
it can use one of these methods to arrange for it to be run before your pass.
LLVM has many different types of analyses and passes that can be required,
-spanning the range from ``DominatorSet`` to ``BreakCriticalEdges``. Requiring
-``BreakCriticalEdges``, for example, guarantees that there will be no critical
+spanning the range from `DominatorSet` to `BreakCriticalEdges`. Requiring
+`BreakCriticalEdges`, for example, guarantees that there will be no critical
edges in the CFG when your pass has been run.
Some analyses chain to other analyses to do their job. For example, an
-`AliasAnalysis <AliasAnalysis.html>`_ implementation is required to :ref:`chain
-<aliasanalysis-chaining>` to other alias analysis passes. In cases where
-analyses chain, the ``addRequiredTransitive`` method should be used instead of
-the ``addRequired`` method. This informs the ``PassManager`` that the
+{doc}`AliasAnalysis <AliasAnalysis>` implementation is required to
+{ref}`chain <aliasanalysis-chaining>` to other alias analysis passes. In cases where
+analyses chain, the `addRequiredTransitive` method should be used instead of
+the `addRequired` method. This informs the `PassManager` that the
transitively required pass should be alive as long as the requiring pass is.
-The ``AnalysisUsage::addPreserved<>`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `AnalysisUsage::addPreserved<>` method
-One of the jobs of the ``PassManager`` is to optimize how and when analyses are
+One of the jobs of the `PassManager` is to optimize how and when analyses are
run. In particular, it attempts to avoid recomputing data unless it needs to.
For this reason, passes are allowed to declare that they preserve (i.e., they
don't invalidate) an existing analysis if it's available. For example, a
@@ -528,187 +494,180 @@ simple constant folding pass would not modify the CFG, so it can't possibly
affect the results of dominator analysis. By default, all passes are assumed
to invalidate all others.
-The ``AnalysisUsage`` class provides several methods which are useful in
-certain circumstances that are related to ``addPreserved``. In particular, the
-``setPreservesAll`` method can be called to indicate that the pass does not
+The `AnalysisUsage` class provides several methods which are useful in
+certain circumstances that are related to `addPreserved`. In particular, the
+`setPreservesAll` method can be called to indicate that the pass does not
modify the LLVM program at all (which is true for analyses), and the
-``setPreservesCFG`` method can be used by transformations that change
+`setPreservesCFG` method can be used by transformations that change
instructions in the program but do not modify the CFG or terminator
instructions.
-``addPreserved`` is particularly useful for transformations like
-``BreakCriticalEdges``. This pass knows how to update a small set of loop and
+`addPreserved` is particularly useful for transformations like
+`BreakCriticalEdges`. This pass knows how to update a small set of loop and
dominator related analyses if they exist, so it can preserve them, despite the
fact that it hacks on the CFG.
-Example implementations of ``getAnalysisUsage``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: c++
+#### Example implementations of `getAnalysisUsage`
- // This example modifies the program, but does not modify the CFG
- void LICM::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
- AU.addRequired<LoopInfoWrapperPass>();
- }
+```cpp
+// This example modifies the program, but does not modify the CFG
+void LICM::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ AU.addRequired<LoopInfoWrapperPass>();
+}
+```
-.. _writing-an-llvm-pass-getAnalysis:
+(writing-an-llvm-pass-getAnalysis)=
-The ``getAnalysis<>`` and ``getAnalysisIfAvailable<>`` methods
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `getAnalysis<>` and `getAnalysisIfAvailable<>` methods
-The ``Pass::getAnalysis<>`` method is automatically inherited by your class,
+The `Pass::getAnalysis<>` method is automatically inherited by your class,
providing you with access to the passes that you declared that you required
-with the :ref:`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>`
+with the {ref}`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>`
method. It takes a single template argument that specifies which pass class
you want, and returns a reference to that pass. For example:
-.. code-block:: c++
-
- bool LICM::runOnFunction(Function &F) {
- LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- //...
- }
+```cpp
+bool LICM::runOnFunction(Function &F) {
+ LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ //...
+}
+```
This method call returns a reference to the pass desired. You may get a
runtime assertion failure if you attempt to get an analysis that you did not
-declare as required in your :ref:`getAnalysisUsage
-<writing-an-llvm-pass-getAnalysisUsage>` implementation. This method can be
-called by your ``run*`` method implementation, or by any other local method
-invoked by your ``run*`` method.
+declare as required in your
+{ref}`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>` implementation. This method can be
+called by your `run*` method implementation, or by any other local method
+invoked by your `run*` method.
A module level pass can use function level analysis info using this interface.
For example:
-.. code-block:: c++
-
- bool ModuleLevelPass::runOnModule(Module &M) {
- //...
- DominatorTree &DT = getAnalysis<DominatorTree>(Func);
- //...
- }
+```cpp
+bool ModuleLevelPass::runOnModule(Module &M) {
+ //...
+ DominatorTree &DT = getAnalysis<DominatorTree>(Func);
+ //...
+}
+```
-In above example, ``runOnFunction`` for ``DominatorTree`` is called by pass
+In above example, `runOnFunction` for `DominatorTree` is called by pass
manager before returning a reference to the desired pass.
If your pass is capable of updating analyses if they exist (e.g.,
-``BreakCriticalEdges``, as described above), you can use the
-``getAnalysisIfAvailable`` method, which returns a pointer to the analysis if
+`BreakCriticalEdges`, as described above), you can use the
+`getAnalysisIfAvailable` method, which returns a pointer to the analysis if
it is active. For example:
-.. code-block:: c++
-
- if (DominatorSet *DS = getAnalysisIfAvailable<DominatorSet>()) {
- // A DominatorSet is active. This code will update it.
- }
+```cpp
+if (DominatorSet *DS = getAnalysisIfAvailable<DominatorSet>()) {
+ // A DominatorSet is active. This code will update it.
+}
+```
-Pass Statistics
-===============
+## Pass Statistics
-The `Statistic <https://llvm.org/doxygen/Statistic_8h_source.html>`_ class is
+The [Statistic](doxygen:Statistic_8h_source.html) class is
designed to be an easy way to expose various success metrics from passes.
-These statistics are printed at the end of a run, when the :option:`-stats`
-command line option is enabled on the command line. See the :ref:`Statistics
-section <Statistic>` in the Programmer's Manual for details.
+These statistics are printed at the end of a run, when the {option}`-stats`
+command line option is enabled on the command line. See the
+{ref}`Statistics section <Statistic>` in the Programmer's Manual for details.
-.. _writing-an-llvm-pass-passmanager:
+(writing-an-llvm-pass-passmanager)=
-What PassManager does
----------------------
+### What PassManager does
-The `PassManager <https://llvm.org/doxygen/PassManager_8h_source.html>`_ `class
-<https://llvm.org/doxygen/classllvm_1_1PassManager.html>`_ takes a list of
-passes, ensures their :ref:`prerequisites <writing-an-llvm-pass-interaction>`
+The [PassManager](doxygen:PassManager_8h_source.html)
+[class](doxygen:classllvm_1_1PassManager.html) takes a list of
+passes, ensures their {ref}`prerequisites <writing-an-llvm-pass-interaction>`
are set up correctly, and then schedules passes to run efficiently. All of the
LLVM tools that run passes use the PassManager for execution of these passes.
The PassManager does two main things to try to reduce the execution time of a
series of passes:
-#. **Share analysis results.** The ``PassManager`` attempts to avoid
+1. **Share analysis results.** The `PassManager` attempts to avoid
recomputing analysis results as much as possible. This means keeping track
of which analyses are available already, which analyses get invalidated, and
which analyses are needed to be run for a pass. An important part of work
- is that the ``PassManager`` tracks the exact lifetime of all analysis
- results, allowing it to :ref:`free memory
- <writing-an-llvm-pass-releaseMemory>` allocated to holding analysis results
+ is that the `PassManager` tracks the exact lifetime of all analysis
+ results, allowing it to {ref}`free memory <writing-an-llvm-pass-releaseMemory>` allocated to holding analysis results
as soon as they are no longer needed.
-#. **Pipeline the execution of passes on the program.** The ``PassManager``
+1. **Pipeline the execution of passes on the program.** The `PassManager`
attempts to get better cache and memory usage behavior out of a series of
passes by pipelining the passes together. This means that, given a series
- of consecutive :ref:`FunctionPass <writing-an-llvm-pass-FunctionPass>`, it
- will execute all of the :ref:`FunctionPass
- <writing-an-llvm-pass-FunctionPass>` on the first function, then all of the
- :ref:`FunctionPasses <writing-an-llvm-pass-FunctionPass>` on the second
+ of consecutive {ref}`FunctionPass <writing-an-llvm-pass-FunctionPass>`, it
+ will execute all of the
+ {ref}`FunctionPass <writing-an-llvm-pass-FunctionPass>` on the first function, then all of the
+ {ref}`FunctionPasses <writing-an-llvm-pass-FunctionPass>` on the second
function, etc... until the entire program has been run through the passes.
This improves the cache behavior of the compiler, because it is only
touching the LLVM program representation for a single function at a time,
instead of traversing the entire program. It reduces the memory consumption
- of compiler, because, for example, only one `DominatorSet
- <https://llvm.org/doxygen/classllvm_1_1DominatorSet.html>`_ needs to be
+ of compiler, because, for example, only one
+ [DominatorSet](doxygen:classllvm_1_1DominatorSet.html) needs to be
calculated at a time.
-The effectiveness of the ``PassManager`` is influenced directly by how much
+The effectiveness of the `PassManager` is influenced directly by how much
information it has about the behaviors of the passes it is scheduling. For
example, the "preserved" set is intentionally conservative in the face of an
-unimplemented :ref:`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>`
+unimplemented {ref}`getAnalysisUsage <writing-an-llvm-pass-getAnalysisUsage>`
method. Not implementing when it should be implemented will have the effect of
not allowing any analysis results to live across the execution of your pass.
-The ``PassManager`` class exposes a ``--debug-pass`` command line options that
+The `PassManager` class exposes a `--debug-pass` command line options that
is useful for debugging pass execution, seeing how things work, and diagnosing
when you should be preserving more analyses than you currently are. (To get
-information about all of the variants of the ``--debug-pass`` option, just type
-"``llc -help-hidden``").
+information about all of the variants of the `--debug-pass` option, just type
+"`llc -help-hidden`").
By using the --debug-pass=Structure option, for example, we can see inspect the
default optimization pipelines, e.g. (the output has been trimmed):
-.. code-block:: console
-
- $ llc -mtriple=arm64-- -O3 -debug-pass=Structure file.ll > /dev/null
- (...)
- ModulePass Manager
- Pre-ISel Intrinsic Lowering
- FunctionPass Manager
- Expand IR instructions
- Expand Atomic instructions
- SVE intrinsics optimizations
- FunctionPass Manager
- Dominator Tree Construction
+```console
+$ llc -mtriple=arm64-- -O3 -debug-pass=Structure file.ll > /dev/null
+(...)
+ModulePass Manager
+Pre-ISel Intrinsic Lowering
+FunctionPass Manager
+ Expand IR instructions
+ Expand Atomic instructions
+SVE intrinsics optimizations
FunctionPass Manager
- Simplify the CFG
Dominator Tree Construction
- Natural Loop Information
- Canonicalize natural loops
- (...)
+FunctionPass Manager
+ Simplify the CFG
+ Dominator Tree Construction
+ Natural Loop Information
+ Canonicalize natural loops
+(...)
+```
-.. _writing-an-llvm-pass-releaseMemory:
+(writing-an-llvm-pass-releaseMemory)=
-The ``releaseMemory`` method
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### The `releaseMemory` method
-.. code-block:: c++
+```cpp
+virtual void releaseMemory();
+```
- virtual void releaseMemory();
-
-The ``PassManager`` automatically determines when to compute analysis results,
+The `PassManager` automatically determines when to compute analysis results,
and how long to keep them around for. Because the lifetime of the pass object
itself is effectively the entire duration of the compilation process, we need
some way to free analysis results when they are no longer useful. The
-``releaseMemory`` virtual method is the way to do this.
+`releaseMemory` virtual method is the way to do this.
If you are writing an analysis or any other pass that retains a significant
amount of state (for use by another pass which "requires" your pass and uses
-the :ref:`getAnalysis <writing-an-llvm-pass-getAnalysis>` method) you should
-implement ``releaseMemory`` to, well, release the memory allocated to maintain
-this internal state. This method is called after the ``run*`` method for the
-class, before the next call of ``run*`` in your pass.
+the {ref}`getAnalysis <writing-an-llvm-pass-getAnalysis>` method) you should
+implement `releaseMemory` to, well, release the memory allocated to maintain
+this internal state. This method is called after the `run*` method for the
+class, before the next call of `run*` in your pass.
-Registering dynamically loaded passes
-=====================================
+## Registering dynamically loaded passes
*Size matters* when constructing production quality tools using LLVM, both for
the purposes of distribution, and for regulating the resident code size when
@@ -718,109 +677,106 @@ configurations later on. You want to be able to do all this, and, provide
feedback to the user. This is where pass registration comes into play.
The fundamental mechanisms for pass registration are the
-``MachinePassRegistry`` class and subclasses of ``MachinePassRegistryNode``.
+`MachinePassRegistry` class and subclasses of `MachinePassRegistryNode`.
-An instance of ``MachinePassRegistry`` is used to maintain a list of
-``MachinePassRegistryNode`` objects. This instance maintains the list and
+An instance of `MachinePassRegistry` is used to maintain a list of
+`MachinePassRegistryNode` objects. This instance maintains the list and
communicates additions and deletions to the command line interface.
-An instance of ``MachinePassRegistryNode`` subclass is used to maintain
+An instance of `MachinePassRegistryNode` subclass is used to maintain
information provided about a particular pass. This information includes the
command line name, the command help string and the address of the function used
to create an instance of the pass. A global static constructor of one of these
-instances *registers* with a corresponding ``MachinePassRegistry``, the static
+instances *registers* with a corresponding `MachinePassRegistry`, the static
destructor *unregisters*. Thus a pass that is statically linked in the tool
will be registered at start up. A dynamically loaded pass will register on
load and unregister at unload.
-Using existing registries
--------------------------
+### Using existing registries
There are predefined registries to track instruction scheduling
-(``RegisterScheduler``) and register allocation (``RegisterRegAlloc``) machine
+(`RegisterScheduler`) and register allocation (`RegisterRegAlloc`) machine
passes. Here we will describe how to *register* a register allocator machine
pass.
Implement your register allocator machine pass. In your register allocator
-``.cpp`` file add the following include:
-
-.. code-block:: c++
+`.cpp` file add the following include:
- #include "llvm/CodeGen/RegAllocRegistry.h"
+```cpp
+#include "llvm/CodeGen/RegAllocRegistry.h"
+```
-Also in your register allocator ``.cpp`` file, define a creator function in the
+Also in your register allocator `.cpp` file, define a creator function in the
form:
-.. code-block:: c++
-
- FunctionPass *createMyRegisterAllocator() {
- return new MyRegisterAllocator();
- }
+```cpp
+FunctionPass *createMyRegisterAllocator() {
+ return new MyRegisterAllocator();
+}
+```
Note that the signature of this function should match the type of
-``RegisterRegAlloc::FunctionPassCtor``. In the same file add the "installing"
+`RegisterRegAlloc::FunctionPassCtor`. In the same file add the "installing"
declaration, in the form:
-.. code-block:: c++
-
- static RegisterRegAlloc myRegAlloc("myregalloc",
- "my register allocator help string",
- createMyRegisterAllocator);
+```cpp
+static RegisterRegAlloc myRegAlloc("myregalloc",
+ "my register allocator help string",
+ createMyRegisterAllocator);
+```
Note the two spaces prior to the help string produces a tidy result on the
-:option:`-help` query.
-
-.. code-block:: console
-
- $ llc -help
- ...
- -regalloc - Register allocator to use (default=linearscan)
- =linearscan - linear scan register allocator
- =local - local register allocator
- =simple - simple register allocator
- =myregalloc - my register allocator help string
- ...
-
-And that's it. The user is now free to use ``-regalloc=myregalloc`` as an
+{option}`-help` query.
+
+```console
+$ llc -help
+ ...
+ -regalloc - Register allocator to use (default=linearscan)
+ =linearscan - linear scan register allocator
+ =local - local register allocator
+ =simple - simple register allocator
+ =myregalloc - my register allocator help string
+ ...
+```
+
+And that's it. The user is now free to use `-regalloc=myregalloc` as an
option. Registering instruction schedulers is similar except use the
-``RegisterScheduler`` class. Note that the
-``RegisterScheduler::FunctionPassCtor`` is significantly different from
-``RegisterRegAlloc::FunctionPassCtor``.
+`RegisterScheduler` class. Note that the
+`RegisterScheduler::FunctionPassCtor` is significantly different from
+`RegisterRegAlloc::FunctionPassCtor`.
To force the load/linking of your register allocator into the
-:program:`llc`/:program:`lli` tools, add your creator function's global
-declaration to ``Passes.h`` and add a "pseudo" call line to
-``llvm/Codegen/LinkAllCodegenComponents.h``.
+{program}`llc`/{program}`lli` tools, add your creator function's global
+declaration to `Passes.h` and add a "pseudo" call line to
+`llvm/Codegen/LinkAllCodegenComponents.h`.
-Creating new registries
------------------------
+### Creating new registries
The easiest way to get started is to clone one of the existing registries; we
-recommend ``llvm/CodeGen/RegAllocRegistry.h``. The key things to modify are
-the class name and the ``FunctionPassCtor`` type.
+recommend `llvm/CodeGen/RegAllocRegistry.h`. The key things to modify are
+the class name and the `FunctionPassCtor` type.
Then you need to declare the registry. Example: if your pass registry is
-``RegisterMyPasses`` then define:
-
-.. code-block:: c++
+`RegisterMyPasses` then define:
- MachinePassRegistry<RegisterMyPasses::FunctionPassCtor> RegisterMyPasses::Registry;
+```cpp
+MachinePassRegistry<RegisterMyPasses::FunctionPassCtor> RegisterMyPasses::Registry;
+```
And finally, declare the command line option for your passes. Example:
-.. code-block:: c++
+```cpp
+cl::opt<RegisterMyPasses::FunctionPassCtor, false,
+ RegisterPassParser<RegisterMyPasses> >
+MyPassOpt("mypass",
+ cl::init(&createDefaultMyPass),
+ cl::desc("my pass option help"));
+```
- cl::opt<RegisterMyPasses::FunctionPassCtor, false,
- RegisterPassParser<RegisterMyPasses> >
- MyPassOpt("mypass",
- cl::init(&createDefaultMyPass),
- cl::desc("my pass option help"));
-
-Here the command option is "``mypass``", with ``createDefaultMyPass`` as the
+Here the command option is "`mypass`", with `createDefaultMyPass` as the
default creator.
-Using GDB with dynamically loaded passes
-----------------------------------------
+### Using GDB with dynamically loaded passes
Unfortunately, using GDB with dynamically loaded passes is not as easy as it
should be. First of all, you can't set a breakpoint in a shared object that
@@ -829,49 +785,47 @@ functions in shared objects. Here are some suggestions to debugging your pass
with GDB.
For sake of discussion, I'm going to assume that you are debugging a
-transformation invoked by :program:`opt`, although nothing described here
+transformation invoked by {program}`opt`, although nothing described here
depends on that.
-Setting a breakpoint in your pass
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Setting a breakpoint in your pass
First thing you do is start gdb on the opt process:
-.. code-block:: console
-
- $ gdb opt
- GNU gdb 5.0
- Copyright 2000 Free Software Foundation, Inc.
- GDB is free software, covered by the GNU General Public License, and you are
- welcome to change it and/or distribute copies of it under certain conditions.
- Type "show copying" to see the conditions.
- There is absolutely no warranty for GDB. Type "show warranty" for details.
- This GDB was configured as "sparc-sun-solaris2.6"...
- (gdb)
-
-Note that :program:`opt` has a lot of debugging information in it, so it takes
+```console
+$ gdb opt
+GNU gdb 5.0
+Copyright 2000 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty" for details.
+This GDB was configured as "sparc-sun-solaris2.6"...
+(gdb)
+```
+
+Note that {program}`opt` has a lot of debugging information in it, so it takes
time to load. Be patient. Since we cannot set a breakpoint in our pass yet
(the shared object isn't loaded until runtime), we must execute the process,
and have it stop before it invokes our pass, but after it has loaded the shared
object. The most foolproof way of doing this is to set a breakpoint in
-``PassManager::run`` and then run the process with the arguments you want:
-
-.. code-block:: console
-
- $ (gdb) break llvm::PassManager::run
- Breakpoint 1 at 0x2413bc: file Pass.cpp, line 70.
- (gdb) run test.bc -load $(LLVMTOP)/llvm/Debug+Asserts/lib/[libname].so -[passoption]
- Starting program: opt test.bc -load $(LLVMTOP)/llvm/Debug+Asserts/lib/[libname].so -[passoption]
- Breakpoint 1, PassManager::run (this=0xffbef174, M=@0x70b298) at Pass.cpp:70
- 70 bool PassManager::run(Module &M) { return PM->run(M); }
- (gdb)
-
-Once the :program:`opt` stops in the ``PassManager::run`` method you are now
+`PassManager::run` and then run the process with the arguments you want:
+
+```console
+$ (gdb) break llvm::PassManager::run
+Breakpoint 1 at 0x2413bc: file Pass.cpp, line 70.
+(gdb) run test.bc -load $(LLVMTOP)/llvm/Debug+Asserts/lib/[libname].so -[passoption]
+Starting program: opt test.bc -load $(LLVMTOP)/llvm/Debug+Asserts/lib/[libname].so -[passoption]
+Breakpoint 1, PassManager::run (this=0xffbef174, M=@0x70b298) at Pass.cpp:70
+70 bool PassManager::run(Module &M) { return PM->run(M); }
+(gdb)
+```
+
+Once the {program}`opt` stops in the `PassManager::run` method you are now
free to set breakpoints in your pass so that you can trace through execution or
do other standard debugging stuff.
-Miscellaneous Problems
-^^^^^^^^^^^^^^^^^^^^^^
+#### Miscellaneous Problems
Once you have the basics down, there are a couple of problems that GDB has,
some with solutions, some without.
@@ -880,16 +834,15 @@ some with solutions, some without.
good job getting stack traces and stepping through inline functions. When a
pass is dynamically loaded however, it somehow completely loses this
capability. The only solution I know of is to de-inline a function (move it
- from the body of a class to a ``.cpp`` file).
+ from the body of a class to a `.cpp` file).
* Restarting the program breaks breakpoints. After following the information
above, you have succeeded in getting some breakpoints planted in your pass.
- Next thing you know, you restart the program (i.e., you type "``run``" again),
+ Next thing you know, you restart the program (i.e., you type "`run`" again),
and you start getting errors about breakpoints being unsettable. The only
way I have found to "fix" this problem is to delete the breakpoints that are
already set in your pass, run the program, and re-set the breakpoints once
- execution stops in ``PassManager::run``.
+ execution stops in `PassManager::run`.
Hopefully these tips will help with common case debugging situations. If you'd
-like to contribute some tips of your own, just contact `Chris
-<mailto:sabre at nondot.org>`_.
+like to contribute some tips of your own, just contact [Chris](mailto:sabre at nondot.org).
diff --git a/llvm/docs/conf.py b/llvm/docs/conf.py
index ca750dded019f..98b52aedccf1f 100644
--- a/llvm/docs/conf.py
+++ b/llvm/docs/conf.py
@@ -40,6 +40,13 @@
raise
else:
myst_enable_extensions = ["substitution"]
+ myst_url_schemes = {
+ "http": None,
+ "https": None,
+ "mailto": None,
+ "ftp": None,
+ "doxygen": {"url": "/doxygen/{{path}}"},
+ }
# Automatic anchors for markdown titles
myst_heading_anchors = 6
diff --git a/llvm/docs/index.md b/llvm/docs/index.md
index 3f6364fb899c3..bb1c3a21e764f 100644
--- a/llvm/docs/index.md
+++ b/llvm/docs/index.md
@@ -1,10 +1,17 @@
-About
-========
+---
+myst:
+ enable_extensions:
+ - deflist
+---
-.. warning::
+# About
- If you are using a released version of LLVM, see `the download page
- <https://llvm.org/releases/>`_ to find your documentation.
+```{warning}
+If you are using a released version of LLVM, see [the download page]
+to find your documentation.
+```
+
+[the download page]: https://llvm.org/releases/
The LLVM compiler infrastructure supports a wide range of projects, from
industrial strength compilers to specialized JIT applications to small
@@ -13,94 +20,89 @@ research projects.
Similarly, documentation is broken down into several high-level groupings
targeted at different audiences:
-LLVM Design & Overview
-======================
+# LLVM Design & Overview
Several introductory papers and presentations.
-.. toctree::
- :hidden:
-
- FAQ
- Lexicon
+```{toctree}
+:hidden:
-:doc:`FAQ`
- Frequently asked questions.
+FAQ
+Lexicon
+```
-:doc:`Lexicon`
- Glossary.
+{doc}`FAQ`
+: Frequently asked questions.
-`Introduction to the LLVM Compiler`__
- Presentation providing a users introduction to LLVM.
+{doc}`Lexicon`
+: Glossary.
- .. __: https://llvm.org/pubs/2008-10-04-ACAT-LLVM-Intro.html
+[Introduction to the LLVM Compiler]
+: Presentation providing a users introduction to LLVM.
-`Intro to LLVM`__
- A chapter from the book "The Architecture of Open Source Applications" that
+[Intro to LLVM]
+: A chapter from the book "The Architecture of Open Source Applications" that
describes high-level design decisions that shaped LLVM.
- .. __: http://www.aosabook.org/en/llvm.html
-
-
-`LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation`__
- Design overview.
-
- .. __: https://llvm.org/pubs/2004-01-30-CGO-LLVM.html
+[LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation][llvm-lifelong]
+: Design overview.
-`LLVM: An Infrastructure for Multi-Stage Optimization`__
- More details (quite old now).
+[LLVM: An Infrastructure for Multi-Stage Optimization][llvm-multi-stage]
+: More details (quite old now).
- .. __: https://llvm.org/pubs/2002-12-LattnerMSThesis.html
+[Introduction to the LLVM Compiler]: https://llvm.org/pubs/2008-10-04-ACAT-LLVM-Intro.html
+[Intro to LLVM]: http://www.aosabook.org/en/llvm.html
+[llvm-lifelong]: https://llvm.org/pubs/2004-01-30-CGO-LLVM.html
+[llvm-multi-stage]: https://llvm.org/pubs/2002-12-LattnerMSThesis.html
-Documentation
-=============
+# Documentation
Getting Started, How-tos, Developer Guides, and Tutorials.
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- GettingStartedTutorials
- Reference
- UserGuides
- DiscourseMigrationGuide
+GettingStartedTutorials
+Reference
+UserGuides
+DiscourseMigrationGuide
+```
-:doc:`GettingStartedTutorials`
- For those new to the LLVM system.
+{doc}`GettingStartedTutorials`
+: For those new to the LLVM system.
-:doc:`UserGuides`
- User guides and How-tos.
+{doc}`UserGuides`
+: User guides and How-tos.
-:doc:`Reference`
- LLVM and API reference documentation.
+{doc}`Reference`
+: LLVM and API reference documentation.
-:doc:`DiscourseMigrationGuide`
- Guide for users to migrate to Discourse
+{doc}`DiscourseMigrationGuide`
+: Guide for users to migrate to Discourse
-Community
-=========
+# Community
LLVM welcomes contributions of all kinds. To learn more, see the following articles:
-.. toctree::
- :hidden:
+```{toctree}
+:hidden:
- GettingInvolved
- RFCProcess
+GettingInvolved
+RFCProcess
+```
-* :doc:`GettingInvolved`
-* :ref:`development-process`
-* :doc:`RFCProcess`
-* :ref:`lists-forums`
-* :ref:`meetups-social-events`
-* :ref:`community-proposals`
+* {doc}`GettingInvolved`
+* {ref}`development-process`
+* {doc}`RFCProcess`
+* {ref}`lists-forums`
+* {ref}`meetups-social-events`
+* {ref}`community-proposals`
Reporting a security issue
-* :ref:`report-security-issue`
+* {ref}`report-security-issue`
-Indices and tables
-==================
+# Indices and tables
-* :ref:`genindex`
-* :ref:`search`
+* {ref}`genindex`
+* {ref}`search`
>From ab19e8058587ebca70d940aaeb2067bd5b98677f Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Wed, 3 Jun 2026 19:45:44 +0000
Subject: [PATCH 2/3] Remove many pandoc-isms from DeveloperPolicy and CMake
---
llvm/docs/CMake.md | 158 +++----
llvm/docs/DeveloperPolicy.md | 793 +++++++++++++++++------------------
2 files changed, 473 insertions(+), 478 deletions(-)
diff --git a/llvm/docs/CMake.md b/llvm/docs/CMake.md
index 2d79d65f5abba..9eef605217c62 100644
--- a/llvm/docs/CMake.md
+++ b/llvm/docs/CMake.md
@@ -32,71 +32,71 @@ see the {doc}`CMakePrimer` page. It has a basic overview of the CMake language.
We use here the command-line, non-interactive CMake interface.
1. [Download](http://www.cmake.org/cmake/resources/software.html) and install
- CMake. Version 3.20.0 is the minimum required.
+ CMake. Version 3.20.0 is the minimum required.
2. Open a shell. Your development tools must be reachable from this shell
- through the `PATH` environment variable.
+ through the `PATH` environment variable.
3. Create a build directory. Building LLVM in the source
- directory is not supported. `cd` to this directory:
+ directory is not supported. `cd` to this directory:
- ``` console
- $ mkdir mybuilddir
- $ cd mybuilddir
- ```
+ ``` console
+ $ mkdir mybuilddir
+ $ cd mybuilddir
+ ```
4. Execute this command in the shell replacing `path/to/llvm/source/root` with
- the path to the root of your LLVM source tree:
-
- ``` console
- $ cmake path/to/llvm/source/root
- ```
-
- CMake will detect your development environment, perform a series of tests,
- and generate the files required for building LLVM. CMake will use default
- values for all build parameters. See the [Options and
- variables](#options-and-variables) section for a list of build parameters
- that you can modify.
-
- This can fail if CMake can't detect your toolset, or if it thinks that the
- environment is not sane enough. In this case, make sure that the toolset
- that you intend to use is the only one reachable from the shell, and that
- the shell itself is the correct one for your development environment. CMake
- will refuse to build MinGW makefiles if you have a POSIX shell reachable
- through the PATH environment variable, for instance. You can force CMake to
- use a given build tool; for instructions, see the [Usage](#Usage) section,
- below. You may also wish to control which targets LLVM enables, or which
- LLVM components are built; see the [Frequently Used LLVM-related
- variables](#frequently-used-llvm-related-variables) below.
+ the path to the root of your LLVM source tree:
+
+ ``` console
+ $ cmake path/to/llvm/source/root
+ ```
+
+ CMake will detect your development environment, perform a series of tests,
+ and generate the files required for building LLVM. CMake will use default
+ values for all build parameters. See the [Options and
+ variables](#options-and-variables) section for a list of build parameters
+ that you can modify.
+
+ This can fail if CMake can't detect your toolset, or if it thinks that the
+ environment is not sane enough. In this case, make sure that the toolset
+ that you intend to use is the only one reachable from the shell, and that
+ the shell itself is the correct one for your development environment. CMake
+ will refuse to build MinGW makefiles if you have a POSIX shell reachable
+ through the PATH environment variable, for instance. You can force CMake to
+ use a given build tool; for instructions, see the [Usage](#Usage) section,
+ below. You may also wish to control which targets LLVM enables, or which
+ LLVM components are built; see the [Frequently Used LLVM-related
+ variables](#frequently-used-llvm-related-variables) below.
5. After CMake has finished running, use IDE project files, or start
- the build from the build directory:
+ the build from the build directory:
- ``` console
- $ cmake --build .
- ```
+ ``` console
+ $ cmake --build .
+ ```
- The `--build` option tells `cmake` to invoke the underlying build
- tool (`make`, `ninja`, `xcodebuild`, `msbuild`, etc.)
+ The `--build` option tells `cmake` to invoke the underlying build
+ tool (`make`, `ninja`, `xcodebuild`, `msbuild`, etc.)
- The underlying build tool can be invoked directly, of course, but
- the `--build` option is portable.
+ The underlying build tool can be invoked directly, of course, but
+ the `--build` option is portable.
6. After LLVM has finished building, install it from the build directory:
- ``` console
- $ cmake --build . --target install
- ```
+ ``` console
+ $ cmake --build . --target install
+ ```
- The `--target` option with `install` parameter in addition to
- the `--build` option tells `cmake` to build the `install` target.
+ The `--target` option with `install` parameter in addition to
+ the `--build` option tells `cmake` to build the `install` target.
- It is possible to set a different install prefix at installation time by
- invoking the `cmake_install.cmake` script generated in the build directory:
+ It is possible to set a different install prefix at installation time by
+ invoking the `cmake_install.cmake` script generated in the build directory:
- ``` console
- $ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
- ```
+ ``` console
+ $ cmake -DCMAKE_INSTALL_PREFIX=/tmp/llvm -P cmake_install.cmake
+ ```
(Basic CMake usage)=
(Usage)=
@@ -132,7 +132,7 @@ $ cmake -G "Visual Studio 12" path/to/llvm/source/root
```
A given development platform can have more than one adequate
-generator. If you use Visual Studio, \"NMake Makefiles\" is a generator you can use
+generator. If you use Visual Studio, "NMake Makefiles" is a generator you can use
for building with NMake. By default, CMake chooses the most specific generator
supported by your development environment. If you want an alternative generator,
you must specify this to CMake with the `-G` option.
@@ -196,15 +196,15 @@ commonly used variables that control features of LLVM and enabled subprojects.
| **MinSizeRel** | For Size | No | No | When disk space matters |
- Optimizations make LLVM/Clang run faster but can be an impediment for
- step-by-step debugging.
+ step-by-step debugging.
- Builds with debug information can use a lot of RAM and disk space and are
- usually slower to run. You can improve RAM usage by using `lld`, see
- the {ref}`LLVM_USE_LINKER <llvm_use_linker>` option.
+ usually slower to run. You can improve RAM usage by using `lld`, see
+ the {ref}`LLVM_USE_LINKER <llvm_use_linker>` option.
- Assertions are internal checks to help you find bugs. They typically
- slow down LLVM and Clang when enabled but can be useful during
- development. You can manually set {ref}`LLVM_ENABLE_ASSERTIONS
- <llvm_enable_assertions>` to override the default from
- `CMAKE_BUILD_TYPE`.
+ slow down LLVM and Clang when enabled but can be useful during
+ development. You can manually set {ref}`LLVM_ENABLE_ASSERTIONS
+ <llvm_enable_assertions>` to override the default from
+ `CMAKE_BUILD_TYPE`.
If you are using an IDE such as Visual Studio or Xcode, use the IDE
settings to set the build type.
@@ -216,7 +216,7 @@ commonly used variables that control features of LLVM and enabled subprojects.
**CMAKE_INSTALL_PREFIX**:PATH
-: Path where LLVM will be installed when the \"install\" target is built.
+: Path where LLVM will be installed when the "install" target is built.
**CMAKE\_{C,CXX}\_FLAGS**:STRING
@@ -285,22 +285,22 @@ manual, or execute `cmake --help-variable VARIABLE_NAME`.
**CMAKE_INSTALL_BINDIR**:PATH
: The path to install executables, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to \"bin\".
+ Defaults to "bin".
**CMAKE_INSTALL_DOCDIR**:PATH
: The path to install documentation, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to \"share/doc\".
+ Defaults to "share/doc".
**CMAKE_INSTALL_INCLUDEDIR**:PATH
: The path to install header files, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to \"include\".
+ Defaults to "include".
**CMAKE_INSTALL_MANDIR**:PATH
: The path to install manpage files, relative to the *CMAKE_INSTALL_PREFIX*.
- Defaults to \"share/man\".
+ Defaults to "share/man".
(LLVM-related variables)=
### LLVM-related variables
@@ -451,7 +451,7 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
**LLVM_DEFAULT_TARGET_TRIPLE**:STRING
: LLVM target to use for code generation when no target is explicitly
- specified. It defaults to \"host\", meaning that it shall pick the
+ specified. It defaults to "host", meaning that it shall pick the
architecture of the machine where LLVM is being built. If you are building
a cross-compiler, set it to the target triple of your desired architecture.
@@ -485,7 +485,7 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
: Namespace under which the intermediate Qt Help Project file lives. See [Qt
Help
Project](http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters)
- for more information. Defaults to \"org.llvm\". This option is only useful
+ for more information. Defaults to "org.llvm". This option is only useful
in combination with `-DLLVM_ENABLE_DOXYGEN_QT_HELP=ON`; otherwise it has no
effect.
@@ -959,7 +959,7 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
**LLVM_TARGET_ARCH**:STRING
: LLVM target to use for native code generation. This is required for JIT
- generation. It defaults to \"host\", meaning that it shall pick the
+ generation. It defaults to "host", meaning that it shall pick the
architecture of the machine where LLVM is being built. If you are
cross-compiling, set it to the target architecture name.
@@ -991,8 +991,8 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
: This flag controls the behavior of `llvm_unreachable()` in a release build
(when assertions are disabled in general). When ON (default) then
- `llvm_unreachable()` is considered \"undefined behavior\" and optimized as
- such. When OFF it is instead replaced with a guaranteed \"trap\".
+ `llvm_unreachable()` is considered "undefined behavior" and optimized as
+ such. When OFF it is instead replaced with a guaranteed "trap".
**LLVM_USE_INTEL_JITEVENTS**:BOOL
@@ -1074,7 +1074,7 @@ things to go wrong. They are also unstable across LLVM versions.
: The path for examples of using LLVM, relative to the
*CMAKE_INSTALL_PREFIX*. Only matters if *LLVM_BUILD_EXAMPLES* is enabled.
- Defaults to \"examples\".
+ Defaults to "examples".
**LLVM_TOOLS_INSTALL_DIR**:STRING
@@ -1108,12 +1108,12 @@ A few notes about CMake Caches:
- Order of command line arguments is important
- `-D` arguments specified before `-C` are set before the cache is processed and
- can be read inside the cache file
+ can be read inside the cache file
- `-D` arguments specified after `-C` are set after the cache is processed and
- are unset inside the cache file
+ are unset inside the cache file
- All `-D` arguments will override cache file settings
- CMAKE_TOOLCHAIN_FILE is evaluated after both the cache file and the command
- line arguments
+ line arguments
- It is recommended that all `-D` options be specified *before* `-C`
For more information about some of the advanced build configurations supported
@@ -1128,7 +1128,7 @@ using Makefiles, execute this command in the root of your build directory:
$ make check-all
```
-On Visual Studio, you may run tests by building the project \"check-all\".
+On Visual Studio, you may run tests by building the project "check-all".
For more information about testing, see the {doc}`TestingGuide`.
## Cross compiling
@@ -1192,13 +1192,13 @@ the `cmake` command or by setting it directly in `ccmake` or `cmake-gui`).
This file is available in two different locations.
- `<LLVM_INSTALL_PACKAGE_DIR>/LLVMConfig.cmake` where
- `<LLVM_INSTALL_PACKAGE_DIR>` is the location where LLVM CMake modules are
- installed as part of an installed version of LLVM. This is typically
- `cmake/llvm/` within the lib directory. On Linux, this is typically
- `/usr/lib/cmake/llvm/LLVMConfig.cmake`.
+ `<LLVM_INSTALL_PACKAGE_DIR>` is the location where LLVM CMake modules are
+ installed as part of an installed version of LLVM. This is typically
+ `cmake/llvm/` within the lib directory. On Linux, this is typically
+ `/usr/lib/cmake/llvm/LLVMConfig.cmake`.
- `<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake` where
- `<LLVM_BUILD_ROOT>` is the root of the LLVM build tree. **Note: this is
- only available when building LLVM with CMake.**
+ `<LLVM_BUILD_ROOT>` is the root of the LLVM build tree. **Note: this is
+ only available when building LLVM with CMake.**
If LLVM is installed in your operating system's normal installation prefix (e.g.
on Linux this is usually `/usr/`) `find_package(LLVM ...)` will
@@ -1340,9 +1340,9 @@ Notes for specific compilers and/or platforms.
**CMAKE_OSX_SYSROOT**:STRING
: When compiling for OSX, in order for the test suite to find libSystem to
- link dylib tests you'll need to run CMake with `` `xcrun --show-sdk-path
- ``\` as the string to pass in so that the testsuite can find your os
+ link dylib tests you'll need to run CMake with `xcrun --show-sdk-path`
+ as the string to pass in so that the testsuite can find your os
libraries.
- This will show up as `` `ld: library not found for -lSystem ``\` when
+ This will show up as `ld: library not found for -lSystem` when
running tests.
diff --git a/llvm/docs/DeveloperPolicy.md b/llvm/docs/DeveloperPolicy.md
index 8e0faecc22be4..1f68983e932a3 100644
--- a/llvm/docs/DeveloperPolicy.md
+++ b/llvm/docs/DeveloperPolicy.md
@@ -21,7 +21,7 @@ The developer policy supports the following LLVM project objectives:
2. Help people contribute to LLVM by documenting our development practices.
3. Maintain the stability, performance, and quality of the `main` branch.
4. Establish the project's {ref}`copyright, license, and patent
- policies <copyright-license-patents>` policies.
+ policies <copyright-license-patents>` policies.
## Developer Policies
@@ -74,18 +74,17 @@ pull request.
Here are some tips to enable a successful code review:
-- {ref}`Include a test <include a testcase>`. This tends to be one of the
-first things a reviewer will ask for and look at to understand what a new patch
-does.
+- {ref}`Include a test <include a testcase>`. This tends to be one of the first
+ things a reviewer will ask for and look at to understand what a new patch
+ does.
- Identify 2-3 individuals to review the patch. Look through the relevant
- {ref}`Maintainers` file or browse git blame for likely stakeholders for the
- code you want to modify, and add `@username` to a PR comment to notify them
- of your PR if you are unable to add reviewers yourself due to GitHub
- permissions.
+ {ref}`Maintainers` file or browse git blame for likely stakeholders for the
+ code you want to modify, and add `@username` to a PR comment to notify them
+ of your PR if you are unable to add reviewers yourself due to GitHub permissions.
- To avoid precommit CI failures due to merge conflicts, base your patches on
- a recent commit from `main`. If you want to make changes to a release
- branch, land a change in `main` first and then follow the {ref}`backporting
- instructions <backporting>`.
+ a recent commit from `main`. If you want to make changes to a release
+ branch, land a change in `main` first and then follow the {ref}`backporting
+ instructions <backporting>`.
See {doc}`CodeReview` for more info on what to expect.
@@ -102,8 +101,8 @@ infrastructure uses emails to contact contributors about build and test
failures.
Therefore, the LLVM community requires contributors to have a public email
-address associated with their GitHub commits, so please ensure that \"Keep my
-email addresses private\" is disabled in your [account
+address associated with their GitHub commits, so please ensure that "Keep my
+email addresses private" is disabled in your [account
settings](https://github.com/settings/emails). There are many free email
forwarding services available if you wish to keep your identity private.
@@ -131,15 +130,15 @@ Maintainers are volunteering to take on the following shared responsibilities
within an area of a project:
- ensure that commits receive high-quality review, either by the maintainer
- or by someone else,
+ or by someone else,
- help to confirm and comment on issues,
- mediate code review disagreements through collaboration with other
- maintainers (and other reviewers) to come to a consensus on how best to
- proceed with disputed changes,
+ maintainers (and other reviewers) to come to a consensus on how best to
+ proceed with disputed changes,
- actively engage with relevant RFCs,
- aid release managers with backporting and other release-related activities,
- be a point of contact for contributors who need help (answering questions
- on Discord/Discourse or holding office hours).
+ on Discord/Discourse or holding office hours).
Each top-level project in the monorepo will specify one or more
lead maintainers who are responsible for ensuring community needs are
@@ -157,7 +156,7 @@ maintainer. However, we are looking for people who can commit to:
- engaging in their responsibilities the majority of the days in a month,
- ensuring that they, and the community members they interact with, abide by
- the {ref}`LLVM Community Code of Conduct`, and
+ the {ref}`LLVM Community Code of Conduct`, and
- performing these duties for at least three months.
We recognize that priorities shift, job changes happen, burnout is real,
@@ -173,26 +172,27 @@ proposed area(s). The PR will be accepted so long as at least one maintainer in
the same project vouches for their ability to perform the responsibilities and
there are no explicit objections raised by the community.
-*To step down as a maintainer*, you can move your name to the \"inactive
-maintainers\" section of the `Maintainers.md` file for the project, or remove
-your name entirely; no PR review is necessary. Additionally, any maintainer who
-has not been actively performing their responsibilities over an extended period
-of time can be moved to the \"inactive maintainers\" section by another active
-maintainer within that project with agreement from one other active maintainer
-within that project. If there is only one active maintainer for a project,
-please post on Discourse to solicit wider community feedback about the removal
-and future direction for the project. However, please discuss the situation
-with the inactive maintainer before such removal to avoid accidental
-miscommunications. If the inactive maintainer is unreachable, no discussion
-with them is required. Stepping down or being removed as a maintainer is normal
-and does not prevent someone from resuming their activities as a maintainer in
-the future.
+*To step down as a maintainer*, you can move your name to the "inactive
+maintainers" section of the `Maintainers.md` file for
+the project, or remove your name entirely; no PR review is necessary.
+Additionally, any maintainer who has not been actively performing their
+responsibilities over an extended period of time can be moved to the "inactive
+maintainers" section by another active maintainer within that project with
+agreement from one other active maintainer within that project. If there is
+only one active maintainer for a project, please post on Discourse to solicit
+wider community feedback about the removal and future direction for the project.
+However, please discuss the situation with the inactive maintainer before such
+removal to avoid accidental miscommunications. If the inactive maintainer is
+unreachable, no discussion with them is required. Stepping down or being removed
+as a maintainer is normal and does not prevent someone from resuming their
+activities as a maintainer in the future.
*To resume activities as a maintainer*, you can post a PR moving your name from
-the \"inactive maintainers\" section of the `Maintainers.md` file to the
-active maintainers list. Because the volunteer was already previously accepted,
-they will be re-accepted so long as at least one maintainer in the same project
-approves the PR and there are no explicit objections raised by the community.
+the "inactive maintainers" section of the `Maintainers.md`
+file to the active maintainers list. Because the volunteer
+was already previously accepted, they will be re-accepted so long as at least
+one maintainer in the same project approves the PR and there are no explicit
+objections raised by the community.
(include a testcase)=
### Test Cases
@@ -201,33 +201,33 @@ Developers are required to create test cases for any bugs fixed and any new
features added. Some tips for getting your testcase approved:
- All feature and regression test cases are added to the `test` subdirectory
- of each LLVM subproject, i.e. `llvm-project/llvm/test` for LLVM itself. The
- appropriate sub-directory should be selected (see the {doc}`Testing Guide
- <TestingGuide>` for details).
+ of each LLVM subproject, i.e. `llvm-project/llvm/test` for LLVM itself. The
+ appropriate sub-directory should be selected (see the {doc}`Testing Guide
+ <TestingGuide>` for details).
- We prefer that functional changes are tested using `FileCheck` and the tool
- that fits most closely with the code being modified. For example, `opt` is
- used to test IR transformations, `llc` for backend changes, and `clang`
- for frontend changes. Some components have scripts for generating and
- updating golden tests in the `utils/` subproject directory, i.e.
- [mlir/utils/generate-test-checks.py](https://github.com/llvm/llvm-project/blob/main/mlir/utils/generate-test-checks.py)
- and
- [llvm/utils/update_llc_test_checks.py](https://github.com/llvm/llvm-project/blob/main/llvm/utils/update_llc_test_checks.py)
+ that fits most closely with the code being modified. For example, `opt` is
+ used to test IR transformations, `llc` for backend changes, and `clang`
+ for frontend changes. Some components have scripts for generating and
+ updating golden tests in the `utils/` subproject directory, i.e.
+ [mlir/utils/generate-test-checks.py](https://github.com/llvm/llvm-project/blob/main/mlir/utils/generate-test-checks.py)
+ and
+ [llvm/utils/update_llc_test_checks.py](https://github.com/llvm/llvm-project/blob/main/llvm/utils/update_llc_test_checks.py)
- Some subprojects such as `clang` and `clangd` have project specific testing
- tools, like the `clang -verify` flag
- ([docs](https://clang.llvm.org/docs/InternalsManual.html#verifying-diagnostics))
- and the `clangd -lit-test` flag, which are preferred over `FileCheck`.
+ tools, like the `clang -verify` flag
+ ([docs](https://clang.llvm.org/docs/InternalsManual.html#verifying-diagnostics))
+ and the `clangd -lit-test` flag, which are preferred over `FileCheck`.
- Changes to libraries, such as Support, which are not directly observable
- through tool invocations, are often best tested with unit tests. Unit tests
- are located under the `unittests` subdirectory of each subproject.
+ through tool invocations, are often best tested with unit tests. Unit tests
+ are located under the `unittests` subdirectory of each subproject.
- Test cases should be targeted. Large inputs exhibiting bugs should be
- reduced with tools like `llvm-reduce` before committing them to the suite.
- It is not acceptable to place an entire failing program into `llvm/test` as
- this creates a *time-to-test* burden on all developers. Please keep them
- short.
+ reduced with tools like `llvm-reduce` before committing them to the suite.
+ It is not acceptable to place an entire failing program into `llvm/test` as
+ this creates a *time-to-test* burden on all developers. Please keep them
+ short.
- Avoid adding links to resources that are not available to the entire
- community, such as links to private bug trackers, internal corporate
- documentation, etc. Instead, add sufficient comments to the test to provide
- the context behind such links.
+ community, such as links to private bug trackers, internal corporate
+ documentation, etc. Instead, add sufficient comments to the test to provide
+ the context behind such links.
As a project, we prefer to separate tests into small in-tree tests, and large
out-of-tree integration tests. More extensive integration test cases (e.g.,
@@ -251,18 +251,18 @@ exhaustive):
- Adding, removing, or modifying command-line options.
- Adding, removing, or regrouping a diagnostic.
- Fixing a bug that potentially has significant user-facing impact (please link
- to the issue fixed in the bug database).
+ to the issue fixed in the bug database).
- Adding or removing optimizations that have widespread impact or enables new
- programming paradigms.
+ programming paradigms.
- Modifying a C stable API.
- Notifying users about a potentially disruptive change expected to be made
- in a future release, such as removal of a deprecated feature. In this case,
- the release note should be added to a `Potentially Breaking Changes`
- section of the notes with sufficient information and examples to
- demonstrate the potential disruption. Additionally, any new entries to this
- section should be announced in the
- [Announcements](https://discourse.llvm.org/c/announce/) channel on
- Discourse. See {ref}`breaking` for more details.
+ in a future release, such as removal of a deprecated feature. In this case,
+ the release note should be added to a `Potentially Breaking Changes`
+ section of the notes with sufficient information and examples to
+ demonstrate the potential disruption. Additionally, any new entries to this
+ section should be announced in the
+ [Announcements](https://discourse.llvm.org/c/announce/) channel on
+ Discourse. See {ref}`breaking` for more details.
Code reviewers are encouraged to request a release note if they think one is
warranted when performing a code review.
@@ -274,42 +274,42 @@ committed to the main development branch are:
1. Code must adhere to the {doc}`LLVM Coding Standards <CodingStandards>`.
2. Code must compile cleanly (no errors, no warnings) on at least one
- platform.
+ platform.
3. Bug fixes and new features should {ref}`include a testcase <include a
- testcase>` so we know if the fix/feature ever regresses in the future.
+ testcase>` so we know if the fix/feature ever regresses in the future.
4. Pull requests should build and pass premerge checks. For first-time
- contributors, this will require an initial cursory review to run the
- checks.
+ contributors, this will require an initial cursory review to run the
+ checks.
5. Ensure that links in source code and test files point to publicly available
- resources and are used primarily to add additional information rather than to
- supply critical context. The surrounding comments should be sufficient to
- provide the context behind such links.
+ resources and are used primarily to add additional information rather than to
+ supply critical context. The surrounding comments should be sufficient to
+ provide the context behind such links.
Additionally, the committer is responsible for addressing any problems found in
the future that the change is responsible for. For example:
- The code needs to compile cleanly and pass tests on all stable [LLVM
- buildbots](https://lab.llvm.org/buildbot/).
+ buildbots](https://lab.llvm.org/buildbot/).
- The changes should not cause any correctness regressions in the
- [llvm-test-suite](https://github.com/llvm/llvm-test-suite) and must not
- cause any major performance regressions.
+ [llvm-test-suite](https://github.com/llvm/llvm-test-suite) and must not
+ cause any major performance regressions.
- The change set should not cause performance or correctness regressions for
- the LLVM tools. See
- [llvm-compile-time-tracker.com](https://llvm-compile-time-tracker.com)
+ the LLVM tools. See
+ [llvm-compile-time-tracker.com](https://llvm-compile-time-tracker.com)
- The changes should not cause performance or correctness regressions in code
- compiled by LLVM on all applicable targets.
+ compiled by LLVM on all applicable targets.
- You are expected to address any [GitHub
- Issues](https://github.com/llvm/llvm-project/issues) that result from your
- change.
+ Issues](https://github.com/llvm/llvm-project/issues) that result from your
+ change.
Our build bots and [nightly testing
-infrastructure](https://llvm.org/docs/lnt/intro.html) find many of these
-issues. Build bots will directly email you if a group of commits that included
-yours caused a failure. You are expected to check the build bot messages to see
-if they are your fault and, if so, fix the breakage. However, keep in mind that
-if you receive such an email, it is highly likely that your change is not at
-fault. Changes are batched together precisely because these tests are generally
-too expensive to run continuously for every change.
+infrastructure](https://llvm.org/docs/lnt/intro.html) find many of these issues. Build bots
+will directly email you if a group of commits that included yours caused a
+failure. You are expected to check the build bot messages to see if they are
+your fault and, if so, fix the breakage. However, keep in mind that if you
+receive such an email, it is highly likely that your change is not at fault.
+Changes are batched together precisely because these tests are generally too
+expensive to run continuously for every change.
Commits that violate these quality standards may be reverted (see below). This
is necessary when the change blocks other developers from making progress. The
@@ -326,54 +326,54 @@ projects.
Commit messages should communicate briefly what the change does, but they
should really emphasize why a change is being made and provide useful context.
Commit messages should be thoughtfully written and specific, rather than vague.
-For example, \"bits were not set right\" will leave the reviewer wondering about
-which bits, and why they weren't right, while \"Correctly set overflow bits in
-TargetInfo\" conveys almost all there is to the change.
+For example, "bits were not set right" will leave the reviewer wondering about
+which bits, and why they weren't right, while "Correctly set overflow bits in
+TargetInfo" conveys almost all there is to the change.
Below are some guidelines about the format of the message itself:
- Separate the commit message into title and body separated by a blank line.
- In the situation where there are multiple authors, or in the rare situation
- you are submitting a change for someone else (e.g., after putting an old
- patch from someone else through review yourself), please use the [git tag
- 'Co-authored-by:' to list the additional
- authors](https://github.blog/2018-01-29-commit-together-with-co-authors/).
- See [Attribution of Changes](#attribution-of-changes) for more information
- including the method we used for attribution before the project migrated to
- git.
+ you are submitting a change for someone else (e.g., after putting an old
+ patch from someone else through review yourself), please use the [git tag
+ 'Co-authored-by:' to list the additional
+ authors](https://github.blog/2018-01-29-commit-together-with-co-authors/).
+ See [Attribution of Changes](#attribution-of-changes) for more information
+ including the method we used for attribution before the project migrated to
+ git.
- The title should be concise. Because all commits are emailed to the list with
- the first line as the subject, long titles are frowned upon. Short titles
- also look better in `git log`.
+ the first line as the subject, long titles are frowned upon. Short titles
+ also look better in `git log`.
- When the changes are restricted to a specific part of the code (e.g. a
- back-end or optimization pass), it is customary to add a tag to the
- beginning of the line in square brackets. For example, \"\[SCEV\] \...\" or
- \"\[OpenMP\] \...\". This helps email filters and searches for post-commit
- reviews.
+ back-end or optimization pass), it is customary to add a tag to the
+ beginning of the line in square brackets. For example, "\[SCEV\] \..." or
+ "\[OpenMP\] \...". This helps email filters and searches for post-commit
+ reviews.
- The body should be concise, but explanatory, including a complete
- rationale. Unless it is required to understand the change, examples, code
- snippets and gory details should be left to bug comments, web review or the
- mailing list.
+ rationale. Unless it is required to understand the change, examples, code
+ snippets and gory details should be left to bug comments, web review or the
+ mailing list.
- Text formatting and spelling should follow the same rules as documentation
- and in-code comments, ex. capitalization, full stop, etc.
+ and in-code comments, ex. capitalization, full stop, etc.
- If the commit is a bug fix on top of another recently committed patch, or a
- revert or reapply of a patch, include the git commit hash of the prior
- related commit. This could be as simple as \"Revert commit NNNN because it
- caused issue #\".
+ revert or reapply of a patch, include the git commit hash of the prior
+ related commit. This could be as simple as "Revert commit NNNN because it
+ caused issue #".
- If the patch has been reviewed, add a link to its review page, as shown
- [here](https://www.llvm.org/docs/Phabricator.html#committing-a-change). If
- the patch fixes a bug in GitHub Issues, we encourage adding a reference to
- the issue being closed, as described
- [here](https://llvm.org/docs/BugLifeCycle.html#resolving-closing-bugs).
+ [here](https://www.llvm.org/docs/Phabricator.html#committing-a-change). If
+ the patch fixes a bug in GitHub Issues, we encourage adding a reference to
+ the issue being closed, as described
+ [here](https://llvm.org/docs/BugLifeCycle.html#resolving-closing-bugs).
- It is also acceptable to add other metadata to the commit message to automate
- processes, including for downstream consumers. This metadata can include
- links to resources that are not available to the entire community. However,
- such links and/or metadata should not be used in place of making the commit
- message self-explanatory. Note that such non-public links should not be
- included in the submitted code.
+ processes, including for downstream consumers. This metadata can include
+ links to resources that are not available to the entire community. However,
+ such links and/or metadata should not be used in place of making the commit
+ message self-explanatory. Note that such non-public links should not be
+ included in the submitted code.
- Avoid 'tagging' someone's username in your commits and PR descriptions
- (e.g., `@<someUser>`), doing so results in that account receiving a
- notification every time the commit is cherry-picked and/or pushed to a
- fork.
+ (e.g., `@<someUser>`), doing so results in that account receiving a
+ notification every time the commit is cherry-picked and/or pushed to a
+ fork.
LLVM uses a squash workflow for pull requests, so as the pull request evolves
during review, it's important to update the pull request description over the
@@ -389,105 +389,102 @@ reminding the contributor of this policy over reverting.
### Patch reversion policy
As a community, we strongly value having the tip of tree in a good state while
-allowing rapid iterative development. As such, we tend to make much heavier
+allowing rapid iterative development. As such, we tend to make much heavier
use of reverts to keep the tree healthy than some other open source projects,
and our norms are a bit different.
How should you respond if someone reverted your change?
- Remember, it is normal and healthy to have patches reverted. Having a patch
- reverted does not necessarily mean you did anything wrong.
+ reverted does not necessarily mean you did anything wrong.
- We encourage explicitly thanking the person who reverted the patch for doing
- the task on your behalf.
+ the task on your behalf.
- If you need more information to address the problem, please follow up in the
- original commit thread with the reverting patch author.
+ original commit thread with the reverting patch author.
When should you revert your own change?
- Any time you learn of a serious problem with a change, you should revert
- it. We strongly encourage \"revert to green\" as opposed to \"fixing
- forward\". We encourage reverting first, investigating offline, and then
- reapplying the fixed patch - possibly after another round of review if
- warranted.
+ it. We strongly encourage "revert to green" as opposed to "fixing
+ forward". We encourage reverting first, investigating offline, and then
+ reapplying the fixed patch - possibly after another round of review if
+ warranted.
- If you break a buildbot in a way which can't be quickly fixed, please
- revert.
+ revert.
- If a test case that demonstrates a problem is reported in the commit thread,
- please revert and investigate offline.
+ please revert and investigate offline.
- If you receive substantial {ref}`post-commit review <post_commit_review>`
- feedback, please revert and address said feedback before recommitting.
- (Possibly after another round of review.)
+ feedback, please revert and address said feedback before recommitting.
+ (Possibly after another round of review.)
- If you are asked to revert by another contributor, please revert and
- discuss the merits of the request offline (unless doing so would further
- destabilize tip of tree).
+ discuss the merits of the request offline (unless doing so would further
+ destabilize tip of tree).
When should you revert someone else's change?
- In general, if the author themselves would revert the change per these
- guidelines, we encourage other contributors to do so as a courtesy to the
- author. This is one of the major cases where our norms differ from others;
- we generally consider reverting a normal part of development. We don't
- expect contributors to be always available, and the assurance that a
- problematic patch will be reverted and we can return to it at our next
- opportunity enables this.
+ guidelines, we encourage other contributors to do so as a courtesy to the
+ author. This is one of the major cases where our norms differ from others;
+ we generally consider reverting a normal part of development. We don't
+ expect contributors to be always available, and the assurance that a
+ problematic patch will be reverted and we can return to it at our next
+ opportunity enables this.
What are the expectations around a revert?
- Use your best judgment. If you're uncertain, please start an email on
- the commit thread asking for assistance. We aren't trying to enumerate
- every case, but rather give a set of guidelines.
+ the commit thread asking for assistance. We aren't trying to enumerate
+ every case, but rather give a set of guidelines.
- You should be sure that reverting the change improves the stability of tip
- of tree. Sometimes, reverting one change in a series can worsen things
- instead of improving them. We expect reasonable judgment to ensure that
- the proper patch or set of patches is being reverted.
+ of tree. Sometimes, reverting one change in a series can worsen things
+ instead of improving them. We expect reasonable judgment to ensure that
+ the proper patch or set of patches is being reverted.
- The commit message for the reverting commit should explain why patch is
- being reverted.
+ being reverted.
- It is customary to respond to the original commit email mentioning the
- revert. This serves as both a notice to the original author that their
- patch was reverted, and helps others following llvm-commits track context.
+ revert. This serves as both a notice to the original author that their
+ patch was reverted, and helps others following llvm-commits track context.
- Ideally, you should have a publicly reproducible test case ready to share.
- Where possible, we encourage sharing of test cases in commit threads, or in
- PRs. We encourage the reverter to minimize the test case and to prune
- dependencies where practical. This even applies when reverting your own
- patch; documenting the reasons for others who might be following along is
- critical.
+ Where possible, we encourage sharing of test cases in commit threads, or
+ in PRs. We encourage the reverter to minimize the test case and to prune
+ dependencies where practical. This even applies when reverting your own
+ patch; documenting the reasons for others who might be following along is
+ critical.
- It is not considered reasonable to revert without at least the promise to
- provide a means for the patch author to debug the root issue. If a
- situation arises where a public reproducer can not be shared for some
- reason (e.g. requires hardware patch author doesn't have access to, sharp
- regression in compile time of internal workload, etc.), the reverter is
- expected to be proactive about working with the patch author to debug and
- test candidate patches.
+ provide a means for the patch author to debug the root issue. If a situation
+ arises where a public reproducer can not be shared for some reason (e.g.
+ requires hardware patch author doesn't have access to, sharp regression in
+ compile time of internal workload, etc.), the reverter is expected to be
+ proactive about working with the patch author to debug and test candidate
+ patches.
- Reverts should be reasonably timely. A change submitted two hours ago
- can be reverted without prior discussion. A change submitted two years ago
- should not be. Where exactly the transition point is is hard to say, but
- it's probably in the handful of days in tree territory. If you are unsure,
- we encourage you to reply to the commit thread, give the author a bit to
- respond, and then proceed with the revert if the author doesn't seem to be
- actively responding.
+ can be reverted without prior discussion. A change submitted two years ago
+ should not be. Where exactly the transition point is is hard to say, but
+ it's probably in the handful of days in tree territory. If you are unsure,
+ we encourage you to reply to the commit thread, give the author a bit to
+ respond, and then proceed with the revert if the author doesn't seem to be
+ actively responding.
- When re-applying a reverted patch, the commit message should be updated to
- indicate the problem that was addressed and how it was addressed.
+ indicate the problem that was addressed and how it was addressed.
(obtaining_commit_access)=
### Obtaining Commit Access
Once you have 3 or more merged pull requests, you may use [this
link](https://github.com/llvm/llvm-project/issues/new?title=Request%20Commit%20Access%20For%20%3Cuser%3E&body=%23%23%23%20Why%20Are%20you%20requesting%20commit%20access%20?)
-to file an issue and request commit access. Replace the \<user\> string in the
-title with your github username, and explain why you are requesting commit
-access in the issue description. Once the issue is created, you will need to
-get two current contributors to support your request before commit access will
-be granted.
-
-Reviewers of your committed patches will automatically be CCed upon creating
-the issue. Most commonly these reviewers will provide the necessary approval,
-but approvals from other LLVM committers are also acceptable. Those reviewing
-the application are confirming that you have indeed had three patches
-committed, and that based on interactions on those reviews and elsewhere in the
-LLVM community they have no concern about you adhering to our Developer Policy
-and Code of Conduct. Reviewers should clearly state their reasoning for
-accepting or rejecting the request, and finish with a clear statement such as
-\"I approve of this request\", \"LGTM\", or \"I do not approve of this
-request\".
+to file an issue and request commit access. Replace the \<user\> string in the title
+with your github username, and explain why you are requesting commit access in
+the issue description. Once the issue is created, you will need to get two
+current contributors to support your request before commit access will be granted.
+
+Reviewers of your committed patches will automatically be CCed upon creating the issue.
+Most commonly these reviewers will provide the necessary approval, but approvals
+from other LLVM committers are also acceptable. Those reviewing the application are
+confirming that you have indeed had three patches committed, and that based on interactions
+on those reviews and elsewhere in the LLVM community they have no concern about you
+adhering to our Developer Policy and Code of Conduct. Reviewers should clearly state their
+reasoning for accepting or rejecting the request, and finish with a clear statement such
+as "I approve of this request", "LGTM", or "I do not approve of this request".
If approved, a GitHub invitation will be sent to your
GitHub account. In case you don't get notification from GitHub, go to
@@ -509,26 +506,26 @@ archives.
If you have recently been granted commit access, these policies apply:
1. You are granted *commit-after-approval* to all parts of LLVM. For
- information on how to get approval for a patch, please see
- {doc}`CodeReview`. When approved, you may commit it yourself.
+ information on how to get approval for a patch, please see
+ {doc}`CodeReview`. When approved, you may commit it yourself.
2. You are allowed to commit patches without approval which you think are
- obvious. This is clearly a subjective decision \-\-- we simply expect you to
- use good judgement. Examples include: fixing build breakage, reverting
- obviously broken patches, documentation/comment changes, any other minor
- changes. Avoid committing formatting- or whitespace-only changes outside of
- code you plan to make subsequent changes to. Also, try to separate
- formatting or whitespace changes from functional changes, either by
- correcting the format first (ideally) or afterward. Such changes should be
- highly localized and the commit message should clearly state that the commit
- is not intended to change functionality, usually by stating it is
- {ref}`NFC <nfc>`.
+ obvious. This is clearly a subjective decision \-\-- we simply expect you to
+ use good judgement. Examples include: fixing build breakage, reverting
+ obviously broken patches, documentation/comment changes, any other minor
+ changes. Avoid committing formatting- or whitespace-only changes outside of
+ code you plan to make subsequent changes to. Also, try to separate
+ formatting or whitespace changes from functional changes, either by
+ correcting the format first (ideally) or afterward. Such changes should be
+ highly localized and the commit message should clearly state that the commit
+ is not intended to change functionality, usually by stating it is
+ {ref}`NFC <nfc>`.
3. You are allowed to commit patches without approval to those portions of LLVM
- that you have contributed or maintain (i.e., have been assigned
- responsibility for), with the proviso that such commits must not break the
- build. This is a \"trust but verify\" policy, and commits of this nature are
- reviewed after they are committed.
+ that you have contributed or maintain (i.e., have been assigned
+ responsibility for), with the proviso that such commits must not break the
+ build. This is a "trust but verify" policy, and commits of this nature are
+ reviewed after they are committed.
4. Multiple violations of these policies or a single egregious violation may
- cause commit access to be revoked.
+ cause commit access to be revoked.
In any case, your changes are still subject to {ref}`code review <code review>`
(either before or after they are committed, depending on the nature of the
@@ -552,9 +549,9 @@ The design of LLVM is carefully controlled to ensure that all the pieces fit
together well and are as consistent as possible. If you plan to make a major
change to the way LLVM works or want to add a major new extension, it is a good
idea to get consensus with the development community before you invest
-significant effort in an implementation. Prototype implementations, however,
-can often be helpful in making design discussions more concrete by
-demonstrating what is possible.
+significant effort in an implementation. Prototype implementations, however, can
+often be helpful in making design discussions more concrete by demonstrating
+what is possible.
LLVM is a large community with many stakeholders, and before landing any major
change, it is important to discuss the design of a change publicly with the
@@ -572,40 +569,40 @@ is discouraged, although we have accepted features developed this way in the
past. Long-term development branches have a number of drawbacks:
1. Branches must have mainline merged into them periodically. If the branch
- development and mainline development occur in the same pieces of code,
- resolving merge conflicts can take a lot of time.
+ development and mainline development occur in the same pieces of code,
+ resolving merge conflicts can take a lot of time.
2. Other people in the community tend to ignore work on branches.
3. Huge changes (produced when a branch is merged back onto mainline) are
- extremely difficult to {ref}`code review <code review>`.
+ extremely difficult to {ref}`code review <code review>`.
4. Branches are not routinely tested by our nightly tester infrastructure.
5. Changes developed as monolithic large changes often don't work until the
- entire set of changes is done. Breaking it down into a set of smaller
- changes increases the odds that any of the work will be committed to the
- main repository.
+ entire set of changes is done. Breaking it down into a set of smaller
+ changes increases the odds that any of the work will be committed to the
+ main repository.
To address these problems, LLVM uses an incremental development style and we
require contributors to follow this practice when making a large/invasive
change. Some tips:
- Large/invasive changes usually have a number of secondary changes that are
- required before the big change can be made (e.g. API cleanup, etc). These
- sorts of changes can often be done before the major change is done,
- independently of that work.
+ required before the big change can be made (e.g. API cleanup, etc). These
+ sorts of changes can often be done before the major change is done,
+ independently of that work.
- The remaining inter-related work should be decomposed into unrelated sets of
- changes if possible. Once this is done, define the first increment and get
- consensus on what the end goal of the change is.
+ changes if possible. Once this is done, define the first increment and get
+ consensus on what the end goal of the change is.
- Each change in the set can be stand alone (e.g. to fix a bug), or part of a
- planned series of changes that works towards the development goal.
+ planned series of changes that works towards the development goal.
- Each change should be kept as small as possible. This simplifies your work
- (into a logical progression), simplifies code review and reduces the chance
- that you will get negative feedback on the change. Small increments also
- facilitate the maintenance of a high quality code base.
+ (into a logical progression), simplifies code review and reduces the chance
+ that you will get negative feedback on the change. Small increments also
+ facilitate the maintenance of a high quality code base.
- Often, an independent precursor to a big change is to add a new API and
- slowly migrate clients to use the new API. Each change to use the new API
- is often \"obvious\" and can be committed without review. Once the new API
- is in place and used, it is much easier to replace the underlying
- implementation of the API. This implementation change is logically separate
- from the API change.
+ slowly migrate clients to use the new API. Each change to use the new API
+ is often "obvious" and can be committed without review. Once the new API
+ is in place and used, it is much easier to replace the underlying
+ implementation of the API. This implementation change is logically separate
+ from the API change.
If you are interested in making a large change, and this scares you, please
make sure to first {ref}`discuss the change/gather consensus <discuss the
@@ -623,37 +620,37 @@ or any other potentially disruptive situation thought to be worth raising
awareness of. For such changes, the following should be done:
- When performing the code review for the change, please add any applicable
- \"vendors\" github team to the review for their awareness. The purpose of
- these groups is to give vendors early notice that potentially disruptive
- changes are being considered but have not yet been accepted. Vendors can
- give early testing feedback on the changes to alert us to unacceptable
- breakages. The current list of vendor groups is:
+ "vendors" github team to the review for their awareness. The purpose of
+ these groups is to give vendors early notice that potentially disruptive
+ changes are being considered but have not yet been accepted. Vendors can
+ give early testing feedback on the changes to alert us to unacceptable
+ breakages. The current list of vendor groups is:
- - [Clang vendors](https://github.com/orgs/llvm/teams/clang-vendors)
- - [libc++ vendors](https://github.com/orgs/llvm/teams/libcxx-vendors)
+ - [Clang vendors](https://github.com/orgs/llvm/teams/clang-vendors)
+ - [libc++ vendors](https://github.com/orgs/llvm/teams/libcxx-vendors)
- People interested in joining the vendors group can do so by clicking the
- \"Join team\" button on the linked github pages above.
+ People interested in joining the vendors group can do so by clicking the
+ "Join team" button on the linked github pages above.
- When committing the change to the repository, add appropriate information
- about the potentially breaking changes to the `Potentially Breaking Changes`
- section of the project's release notes. The release note should have
- information about what the change is, what is potentially disruptive about
- it, as well as any code examples, links, and motivation that is appropriate
- to share with users. This helps users to learn about potential issues with
- upgrading to that release.
+ about the potentially breaking changes to the `Potentially Breaking Changes`
+ section of the project's release notes. The release note should have
+ information about what the change is, what is potentially disruptive about
+ it, as well as any code examples, links, and motivation that is appropriate
+ to share with users. This helps users to learn about potential issues with
+ upgrading to that release.
- After the change has been committed to the repository, the potentially
- disruptive changes described in the release notes should be posted to the
- [Announcements](https://discourse.llvm.org/c/announce/) channel on
- Discourse. The post should be tagged with the `potentially-breaking` label
- and a label specific to the project (such as `clang`, `llvm`, etc). This is
- another mechanism by which we can give pre-release notice to users about
- potentially disruptive changes. It is a lower-traffic alternative to the
- joining \"vendors\" group. To automatically be notified of new
- announcements with the `potentially-breaking` label, go to your user
- preferences page in Discourse, and add the label to one of the watch
- categories under `Notifications->Tags`.
+ disruptive changes described in the release notes should be posted to the
+ [Announcements](https://discourse.llvm.org/c/announce/) channel on
+ Discourse. The post should be tagged with the `potentially-breaking` label
+ and a label specific to the project (such as `clang`, `llvm`, etc). This is
+ another mechanism by which we can give pre-release notice to users about
+ potentially disruptive changes. It is a lower-traffic alternative to the
+ joining "vendors" group. To automatically be notified of new
+ announcements with the `potentially-breaking` label, go to your user
+ preferences page in Discourse, and add the label to one of the watch
+ categories under `Notifications->Tags`.
### Attribution of Changes
@@ -661,8 +658,8 @@ When contributors submit a patch to an LLVM project, other developers with
commit access may merge the PR for the author (based on the progression of code
review, etc.). GitHub will automatically ensure that authorship is preserved,
and one does not need to take any further action. We do not want the source
-code to be littered with random attributions \"this code written by J. Random
-Hacker\" (this is noisy and distracting). In practice, the revision control
+code to be littered with random attributions "this code written by J. Random
+Hacker" (this is noisy and distracting). In practice, the revision control
system keeps a perfect history of who changed what, and the CREDITS.txt file
describes higher-level contributions. If you need to adjust authorship for any
reason, please follow the attribution of changes in the simple manner as
@@ -678,8 +675,8 @@ a patch privately, encourage them to submit it as a GitHub PR first.
Our previous version control system (subversion) did not distinguish between
the author and the committer like git does. As such, older commits used a
-different attribution mechanism. The previous method was to include \"Patch by
-John Doe.\" in a separate line of the commit message and there are automated
+different attribution mechanism. The previous method was to include "Patch by
+John Doe." in a separate line of the commit message and there are automated
processes that rely on this format.
### Bans
@@ -708,46 +705,46 @@ backwards compatibility. The rules are intended as a balance between convenience
for llvm users and not imposing a big burden on llvm developers:
- The textual format is not backwards compatible. We don't change it too often,
- but there are no specific promises.
+ but there are no specific promises.
- Additions and changes to the IR should be reflected in
- `test/Bitcode/compatibility.ll`.
+ `test/Bitcode/compatibility.ll`.
- The current LLVM version supports loading any bitcode since version 3.0.
- After each X.Y release, `compatibility.ll` must be copied to
- `compatibility-X.Y.ll`. The corresponding bitcode file should be assembled
- using the X.Y build and committed as `compatibility-X.Y.ll.bc`.
+ `compatibility-X.Y.ll`. The corresponding bitcode file should be assembled
+ using the X.Y build and committed as `compatibility-X.Y.ll.bc`.
- Newer releases can ignore features from older releases, but they cannot
- miscompile them. For example, if nsw is ever replaced with something else,
- dropping it would be a valid way to upgrade the IR.
+ miscompile them. For example, if nsw is ever replaced with something else,
+ dropping it would be a valid way to upgrade the IR.
- Debug metadata is special in that it is currently dropped during upgrades.
- Non-debug metadata is defined to be safe to drop, so a valid way to upgrade
- it is to drop it. That is not very user friendly and a bit more effort is
- expected, but no promises are made.
+ it is to drop it. That is not very user friendly and a bit more effort is
+ expected, but no promises are made.
- Legacy bitcode may have degraded performance when compared to
- the compiled output with the legacy compiler.
+ the compiled output with the legacy compiler.
### C API Changes
-- Stability Guarantees: The C API is, in general, a \"best effort\" for
- stability. This means that we make every attempt to keep the C API stable,
- but that stability will be limited by the abstractness of the interface and
- the stability of the C++ API that it wraps. In practice, this means that
- things like \"create debug info\" or \"create this type of instruction\"
- are likely to be less stable than \"take this IR file and JIT it for my
- current machine\".
+- Stability Guarantees: The C API is, in general, a "best effort" for
+ stability. This means that we make every attempt to keep the C API stable,
+ but that stability will be limited by the abstractness of the interface and
+ the stability of the C++ API that it wraps. In practice, this means that
+ things like "create debug info" or "create this type of instruction"
+ are likely to be less stable than "take this IR file and JIT it for my
+ current machine".
- Release stability: We won't break the C API on the release branch with
- patches that go on that branch, with the exception that we will fix an
- unintentional C API break that will keep the release consistent with both
- the previous and next release.
+ patches that go on that branch, with the exception that we will fix an
+ unintentional C API break that will keep the release consistent with both
+ the previous and next release.
- Testing: Patches to the C API are expected to come with tests just like any
- other patch.
+ other patch.
- Including new things into the API: If an LLVM subcomponent has a C API
- already included, then expanding that C API is acceptable. Adding C API for
- subcomponents that don't currently have one needs to be discussed on the
- [LLVM Discourse forums](https://discourse.llvm.org) for design and
- maintainability feedback prior to implementation.
+ already included, then expanding that C API is acceptable. Adding C API for
+ subcomponents that don't currently have one needs to be discussed on the
+ [LLVM Discourse forums](https://discourse.llvm.org) for design and
+ maintainability feedback prior to implementation.
- Documentation: Any changes to the C API are required to be documented in the
- release notes so that it's clear to external users who do not follow the
- project how the C API is changing and evolving.
+ release notes so that it's clear to external users who do not follow the
+ project how the C API is changing and evolving.
(toolchain)=
### Updating Toolchain Requirements
@@ -805,33 +802,33 @@ their patch with every possible configuration.
*If your commit broke the build:*
- Fix the build as soon as possible as this might block other contributors or
- downstream users.
+ downstream users.
- If you need more time to analyze and fix the bug, please revert your change
- to unblock others.
+ to unblock others.
*If someone else broke the build and this blocks your work*
- Comment on the code review in
- [GitHub](https://github.com/llvm/llvm-project/pulls) (if available) or
- email the author, explain the problem and how this impacts you. Add a link
- to the broken build and the error message so folks can understand the
- problem.
+ [GitHub](https://github.com/llvm/llvm-project/pulls) (if available) or
+ email the author, explain the problem and how this impacts you. Add a link
+ to the broken build and the error message so folks can understand the
+ problem.
- Revert the commit if this blocks your work, see
- [revert_policy](#revert_policy) .
+ [revert_policy](#revert_policy) .
*If a build/worker is permanently broken*
- 1st step: contact the owner of the worker. You can find the name and
- contact information for the *Admin* of worker on the page of the build in
- the *Worker* tab:
+ contact information for the *Admin* of worker on the page of the build in
+ the *Worker* tab:
- 
+ 
- 2nd step: If the owner does not respond or fix the worker, please escalate
- to Galina Kostanova, the maintainer of the BuildBot master.
+ to Galina Kostanova, the maintainer of the BuildBot master.
- 3rd step: If Galina could not help you, please escalate to the
- [Infrastructure Working Group](mailto:iwg at llvm.org).
+ [Infrastructure Working Group](mailto:iwg at llvm.org).
(new-llvm-components)=
## Introducing New Components into LLVM
@@ -868,63 +865,63 @@ proven stable, and later moved to non-experimental.
The differences between both classes are:
- Experimental targets are not built by default (they need to be explicitly
- enabled at CMake time).
+ enabled at CMake time).
- Test failures, bugs, and build breakages that only appear when the
- experimental target is enabled, caused by changes unrelated to the target, are
- the responsibility of the community behind the target to fix.
+ experimental target is enabled, caused by changes unrelated to the target, are
+ the responsibility of the community behind the target to fix.
The basic rules for a back-end to be upstreamed in **experimental** mode are:
- Every target must have at least one {ref}`maintainer<maintainers>`. The
- `Maintainers.md` file has to be updated as part of the first merge. These
- maintainers make sure that changes to the target get reviewed and steers
- the overall effort.
+ `Maintainers.md` file has to be updated as part of the first merge. These
+ maintainers make sure that changes to the target get reviewed and steers
+ the overall effort.
- There must be an active community behind the target. This community will
- help maintain the target by providing buildbots, fixing bugs, answering the
- LLVM community's questions and making sure the new target doesn't break any
- of the other targets, or generic code. This behavior is expected to
- continue throughout the lifetime of the target's code.
+ help maintain the target by providing buildbots, fixing bugs, answering the
+ LLVM community's questions and making sure the new target doesn't break any
+ of the other targets, or generic code. This behavior is expected to
+ continue throughout the lifetime of the target's code.
- The code must be free of contentious issues, for example, large
- changes in how the IR behaves or should be formed by the front-ends,
- unless agreed by the majority of the community via refactoring of the
- ({doc}`IR standard<LangRef>`) **before** the merge of the new target changes,
- following the {ref}`IR backwards compatibility`.
+ changes in how the IR behaves or should be formed by the front-ends,
+ unless agreed by the majority of the community via refactoring of the
+ ({doc}`IR standard<LangRef>`) **before** the merge of the new target changes,
+ following the {ref}`IR backwards compatibility`.
- The code conforms to all of the policies laid out in this developer policy
- document, including license, patent, and coding standards.
+ document, including license, patent, and coding standards.
- The target should have either reasonable documentation on how it works
- (ISA, ABI, etc.) or a publicly available simulator/hardware (either free or
- cheap enough) - preferably both. This allows developers to validate
- assumptions, understand constraints and review code that can affect the
- target.
+ (ISA, ABI, etc.) or a publicly available simulator/hardware (either free or
+ cheap enough) - preferably both. This allows developers to validate
+ assumptions, understand constraints and review code that can affect the
+ target.
In addition, the rules for a back-end to be promoted to **official** are:
- The target must have addressed every other minimum requirement and
- have been stable in tree for at least 3 months. This cool down
- period is to make sure that the back-end and the target community can
- endure continuous upstream development for the foreseeable future.
+ have been stable in tree for at least 3 months. This cool down
+ period is to make sure that the back-end and the target community can
+ endure continuous upstream development for the foreseeable future.
- The target's code must have been completely adapted to this policy
- as well as the {doc}`coding standards<CodingStandards>`. Any exceptions that
- were made to move into experimental mode must have been fixed **before**
- becoming official.
+ as well as the {doc}`coding standards<CodingStandards>`. Any exceptions that
+ were made to move into experimental mode must have been fixed **before**
+ becoming official.
- The test coverage needs to be broad and well written (small tests, well
- documented). The build target `check-all` must pass with the new target
- built, and where applicable, the `test-suite` must also pass without
- errors, in at least one configuration (publicly demonstrated, for example,
- via buildbots).
+ documented). The build target `check-all` must pass with the new target
+ built, and where applicable, the `test-suite` must also pass without
+ errors, in at least one configuration (publicly demonstrated, for example,
+ via buildbots).
- Public buildbots need to be created and actively maintained, unless
- the target requires no additional buildbots (ex. `check-all` covers
- all tests). The more relevant and public the new target's CI infrastructure
- is, the more the LLVM community will embrace it.
+ the target requires no additional buildbots (ex. `check-all` covers
+ all tests). The more relevant and public the new target's CI infrastructure
+ is, the more the LLVM community will embrace it.
To **continue** as a supported and official target:
- The maintainer(s) must continue following these rules throughout the lifetime
- of the target. Continuous violations of aforementioned rules and policies
- could lead to complete removal of the target from the code base.
+ of the target. Continuous violations of aforementioned rules and policies
+ could lead to complete removal of the target from the code base.
- Degradation in support, documentation or test coverage will make the target
- as nuisance to other targets and be considered a candidate for deprecation
- and ultimately removed.
+ as nuisance to other targets and be considered a candidate for deprecation
+ and ultimately removed.
In essence, these rules are necessary for targets to gain and retain their
status, but also markers to define bit-rot, and will be used to clean up the
@@ -933,35 +930,35 @@ tree from unmaintained targets.
Those wishing to add a new target to LLVM must follow the procedure below:
1. Read this section and make sure your target follows all requirements. For
- minor issues, your community will be responsible for making all necessary
- adjustments soon after the initial merge.
+ minor issues, your community will be responsible for making all necessary
+ adjustments soon after the initial merge.
2. Send a request for comment (RFC) to the [LLVM Discourse
- forums](https://discourse.llvm.org) describing your target and how it
- follows all the requirements and what work has been done and will need to
- be done to accommodate the official target requirements. Make sure to
- expose any and all controversial issues, changes needed in the base code,
- table gen, etc. See the {doc}`RFC process <RFCProcess>` documentation for
- more details.
+ forums](https://discourse.llvm.org) describing your target and how it
+ follows all the requirements and what work has been done and will need to
+ be done to accommodate the official target requirements. Make sure to
+ expose any and all controversial issues, changes needed in the base code,
+ table gen, etc. See the {doc}`RFC process <RFCProcess>` documentation for
+ more details.
3. Once the response is positive, the LLVM community can start reviewing the
- actual patches (but they can be prepared before, to support the RFC).
- Create a sequence of N patches, numbered '1/N' to 'N/N' (make sure N is an
- actual number, not the letter 'N'), that completes the basic structure of
- the target.
+ actual patches (but they can be prepared before, to support the RFC).
+ Create a sequence of N patches, numbered '1/N' to 'N/N' (make sure N is an
+ actual number, not the letter 'N'), that completes the basic structure of
+ the target.
4. The initial patch should add documentation, maintainers, and triple support
- in clang and LLVM. The following patches add TableGen infrastructure to
- describe the target and lower instructions to assembly. The final patch
- must show that the target can lower correctly with extensive LIT tests (IR
- to MIR, MIR to ASM, etc).
+ in clang and LLVM. The following patches add TableGen infrastructure to
+ describe the target and lower instructions to assembly. The final patch
+ must show that the target can lower correctly with extensive LIT tests (IR
+ to MIR, MIR to ASM, etc).
5. Some patches may be approved before others, but only after *all* patches are
- approved that the whole set can be merged in one go. This is to guarantee
- that all changes are good as a single block.
+ approved that the whole set can be merged in one go. This is to guarantee
+ that all changes are good as a single block.
6. After the initial merge, the target community can stop numbering patches and
- start working asynchronously on the target to complete support. They should
- still seek review from those who helped them in the initial phase, to make
- sure the progress is still consistent.
+ start working asynchronously on the target to complete support. They should
+ still seek review from those who helped them in the initial phase, to make
+ sure the progress is still consistent.
7. Once all official requirements have been fulfilled (as above), the
- maintainers should request the target to be enabled by default by sending
- another RFC to the [LLVM Discourse forums](https://discourse.llvm.org).
+ maintainers should request the target to be enabled by default by sending
+ another RFC to the [LLVM Discourse forums](https://discourse.llvm.org).
### Adding an Established Project To the LLVM Monorepo
@@ -976,7 +973,7 @@ Like new targets, most projects already in the monorepo are considered to be in
the *core tier* of our {doc}`support policy<SupportPolicy>`. The burden to add
things to the LLVM monorepo needs to be very high - code that is added to this
repository is checked out by everyone in the community. As such, we hold
-components to a high bar similar to \"official targets\", they:
+components to a high bar similar to "official targets", they:
- Must be generally aligned with the mission of the LLVM project to advance
compilers, languages, tools, runtimes, etc.
@@ -993,7 +990,7 @@ components to a high bar similar to \"official targets\", they:
a clear path to resolving them.
- Must be proposed through the LLVM RFC process, and have its addition
approved by the LLVM community - this ultimately mediates the resolution
- of the \"should\" concerns above. See the {doc}`RFC process <RFCProcess>`
+ of the "should" concerns above. See the {doc}`RFC process <RFCProcess>`
documentation for more details.
If you have a project that you think would make sense to add to the LLVM
@@ -1003,13 +1000,13 @@ can take some time and iteration - please don't be discouraged or intimidated
by that!
If you have an earlier stage project that you think is aligned with LLVM, please
-see the \"Incubating New Projects\" section.
+see the "Incubating New Projects" section.
### Incubating New Projects
The burden to add a new project to the LLVM monorepo is intentionally very high,
but that can have a chilling effect on new and innovative projects. To help
-foster these sorts of projects, LLVM supports an \"incubator\" process that is
+foster these sorts of projects, LLVM supports an "incubator" process that is
much easier to get started with. It provides space for potentially valuable,
new top-level and sub-projects to reach a critical mass before they have enough
code to prove their utility and grow a community. This also allows
@@ -1038,24 +1035,22 @@ criteria:
(see suggested wording below).
- Must be proposed through the LLVM RFC process, and have its addition
approved by the LLVM community - this ultimately mediates the resolution
- of the \"should\" concerns above. See the {doc}`RFC process <RFCProcess>`
+ of the "should" concerns above. See the {doc}`RFC process <RFCProcess>`
documentation for more details.
That said, the project need not have any code to get started, and need not have
an established community at all! Furthermore, incubating projects may pass
-through transient states that violate the \"Should\" guidelines above, or would
+through transient states that violate the "Should" guidelines above, or would
otherwise make them unsuitable for direct inclusion in the monorepo (e.g.
dependencies that have not yet been factored appropriately, leveraging
experimental components or APIs that are not yet upstream, etc).
When approved, the llvm-admin group can grant the new project:
-: - A new repository in the LLVM Github Organization - but not the LLVM
- monorepo.
- - New mailing list, discourse forum, and/or discord chat hosted with
- other LLVM forums.
- - Other infrastructure integration can be discussed on a case-by-case
- basis.
+- A new repository in the LLVM Github Organization - but not the LLVM monorepo.
+- New mailing list, discourse forum, and/or discord chat hosted with other LLVM
+ forums.
+- Other infrastructure integration can be discussed on a case-by-case basis.
Graduation to the mono-repo would follow existing processes and standards for
becoming a first-class part of the monorepo. Similarly, an incubating project
@@ -1090,14 +1085,14 @@ specific uses of LLVM, such as GC support passes.)
The recommended workflow is:
1. Implement a basic version of the pass and add it to the pass pipeline behind
- a flag that is disabled by default. The initial version should focus on
- handling simple cases correctly and efficiently.
+ a flag that is disabled by default. The initial version should focus on
+ handling simple cases correctly and efficiently.
2. Enable the pass by default. Separating this step allows easily disabling the
- pass if issues are encountered, without having to revert the entire
- implementation.
+ pass if issues are encountered, without having to revert the entire
+ implementation.
3. Incrementally extend the pass with new functionality. As the pass is already
- enabled, it becomes easier to identify the specific change that has caused a
- regression in correctness, optimization quality or compile-time.
+ enabled, it becomes easier to identify the specific change that has caused a
+ regression in correctness, optimization quality or compile-time.
When enabling a pass, certain requirements must be met (in no particular
order):
@@ -1109,7 +1104,7 @@ order):
workloads. Improvements seen only on synthetic benchmarks may be
insufficient.
- **Compile-Time:** The pass should not have a large impact on
- compile-time, where the evaluation of what \"large\" means is up to
+ compile-time, where the evaluation of what "large" means is up to
reviewer discretion, and may differ based on the value the pass provides.
In any case, it is expected that a concerted effort has been made to
mitigate the compile-time impact, both for the average case, and for
@@ -1185,24 +1180,24 @@ The last paragraph notwithstanding, the LLVM Project is in the middle of a large
effort to change licenses, which aims to solve several problems:
- The old licenses made it difficult to move code from (e.g.) the compiler to
- runtime libraries, because runtime libraries used a different license from
- the rest of the compiler.
+ runtime libraries, because runtime libraries used a different license from
+ the rest of the compiler.
- Some contributions were not submitted to LLVM due to concerns that
- the patent grant required by the project was overly broad.
+ the patent grant required by the project was overly broad.
- The patent grant was unique to the LLVM Project, not written by a lawyer, and
- was difficult to determine what protection was provided (if any).
+ was difficult to determine what protection was provided (if any).
The scope of relicensing is all code that is considered part of the LLVM
project, including the main LLVM repository, runtime libraries (compiler_rt,
OpenMP, etc), Polly, and all other subprojects. There are a few exceptions:
- Code imported from other projects (e.g. Google Test, Autoconf, etc) will
- remain as it is. This code isn't developed as part of the LLVM project, it
- is used by LLVM.
+ remain as it is. This code isn't developed as part of the LLVM project, it
+ is used by LLVM.
- Some subprojects are impractical or uninteresting to relicense (e.g.
- llvm-gcc and dragonegg). These will be split off from the LLVM project
- (e.g. to separate GitHub projects), allowing interested people to continue
- their development elsewhere.
+ llvm-gcc and dragonegg). These will be split off from the LLVM project
+ (e.g. to separate GitHub projects), allowing interested people to continue
+ their development elsewhere.
To relicense LLVM, we will be seeking approval from all of the copyright
holders of code in the repository, or potentially remove/rewrite code if we
@@ -1216,8 +1211,8 @@ both the new license and the legacy license.
If you are a contributor to LLVM with contributions committed before 2019-01-19
and have not done so already, please do follow the instructions at
-<https://foundation.llvm.org/docs/relicensing/>, under section \"Individual
-Relicensing Agreement\" to relicense your contributions under the new license.
+<https://foundation.llvm.org/docs/relicensing/>, under section "Individual
+Relicensing Agreement" to relicense your contributions under the new license.
(open source licensing terms)=
### New LLVM Project License Framework
@@ -1225,7 +1220,7 @@ Relicensing Agreement\" to relicense your contributions under the new license.
Contributions to LLVM are licensed under the [Apache License, Version
2.0](https://www.apache.org/licenses/LICENSE-2.0), with two limited exceptions
intended to ensure that LLVM is very permissively licensed. Collectively, the
-name of this license is \"Apache 2.0 License with LLVM exceptions\". The
+name of this license is "Apache 2.0 License with LLVM exceptions". The
exceptions read:
---- LLVM Exceptions to the Apache 2.0 License ----
@@ -1248,30 +1243,30 @@ We intend to keep LLVM perpetually open source and available under a permissive
license - this fosters the widest adoption of LLVM by
**allowing commercial products to be derived from LLVM** with few restrictions
and without a requirement for making any derived works also open source. In
-particular, LLVM's license is not a \"copyleft\" license like the GPL.
+particular, LLVM's license is not a "copyleft" license like the GPL.
-The \"Apache 2.0 License with LLVM exceptions\" allows you to:
+The "Apache 2.0 License with LLVM exceptions" allows you to:
- freely download and use LLVM (in whole or in part) for personal, internal,
- or commercial purposes.
+ or commercial purposes.
- include LLVM in packages or distributions you create.
- combine LLVM with code licensed under every other major open source
- license (including BSD, MIT, GPLv2, GPLv3\...).
+ license (including BSD, MIT, GPLv2, GPLv3\...).
- make changes to LLVM code without being required to contribute it back
- to the project - contributions are appreciated though!
+ to the project - contributions are appreciated though!
However, it imposes these limitations on you:
- You must retain the copyright notice if you redistribute LLVM: You cannot
- strip the copyright headers off or replace them with your own.
+ strip the copyright headers off or replace them with your own.
- Binaries that include LLVM must reproduce the copyright notice (e.g. in an
- included README file or in an \"About\" box), unless the LLVM code was added as
- a by-product of compilation. For example, if an LLVM runtime library like
- compiler_rt or libc++ was automatically included into your application by the
- compiler, you do not need to attribute it.
+ included README file or in an "About" box), unless the LLVM code was added as
+ a by-product of compilation. For example, if an LLVM runtime library like
+ compiler_rt or libc++ was automatically included into your application by the
+ compiler, you do not need to attribute it.
- You can't use our names to promote your products (LLVM derived or not) -
- though you can make truthful statements about your use of the LLVM code,
- without implying our sponsorship.
+ though you can make truthful statements about your use of the LLVM code,
+ without implying our sponsorship.
- There's no warranty on LLVM at all.
We want LLVM code to be widely used, and believe that this provides a model
@@ -1288,14 +1283,14 @@ of code to the project contribute the rights to use any of their patents that
would otherwise be infringed by that code contribution (protecting uses of that
code). Further, the patent grant is revoked from anyone who files a patent
lawsuit about code in LLVM - this protects the community by providing a
-\"patent commons\" for the code base and reducing the odds of patent lawsuits
+"patent commons" for the code base and reducing the odds of patent lawsuits
in general.
The license specifically scopes which patents are included with code
contributions. To help explain this, the [Apache License
FAQ](http://www.apache.org/foundation/license-faq.html) explains this scope
using some questions and answers, which we reproduce here for your convenience
-(for reference, the \"ASF\" is the Apache Software Foundation, the guidance
+(for reference, the "ASF" is the Apache Software Foundation, the guidance
still holds though):
Q1: If I own a patent and contribute to a Work, and, at the time my
@@ -1346,14 +1341,14 @@ this:
- You can freely distribute LLVM.
- You must retain the copyright notice if you redistribute LLVM.
- Binaries derived from LLVM must reproduce the copyright notice (e.g. in an
- included README file).
+ included README file).
- You can't use our names to promote your LLVM derived products.
- There's no warranty on LLVM at all.
We believe this fosters the widest adoption of LLVM because it **allows
commercial products to be derived from LLVM** with few restrictions and without
a requirement for making any derived works also open source (i.e. LLVM's
-license is not a \"copyleft\" license like the GPL). We suggest that you read the
+license is not a "copyleft" license like the GPL). We suggest that you read the
[License](http://www.opensource.org/licenses/UoI-NCSA.php) if further
clarification is needed.
>From d201822aa7afaf806487c62d7257c9e8a501839b Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Wed, 3 Jun 2026 20:49:41 +0000
Subject: [PATCH 3/3] Apply suggestion manually
---
llvm/docs/CMake.md | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/docs/CMake.md b/llvm/docs/CMake.md
index 9eef605217c62..d97af85057a32 100644
--- a/llvm/docs/CMake.md
+++ b/llvm/docs/CMake.md
@@ -1292,10 +1292,8 @@ add_library(LLVMPassname MODULE Pass.cpp)
Note if you intend for this pass to be merged into the LLVM source tree at some
point in the future it might make more sense to use LLVM's internal
-`add_llvm_library` function with the MODULE argument instead by\...
-
-Adding the following to `<project dir>/CMakeLists.txt` (after
-`find_package(LLVM ...)`)
+`add_llvm_library` function with the MODULE argument instead by adding the
+following to `<project dir>/CMakeLists.txt` (after `find_package(LLVM ...)`):
``` cmake
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
More information about the llvm-branch-commits
mailing list