[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
Mon Jun 22 15:52:29 PDT 2026


https://github.com/rnk updated https://github.com/llvm/llvm-project/pull/201244

>From 60cb10ac6842b933e77cca19af2e4da1584af9eb Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Mon, 22 Jun 2026 15:41:00 -0700
Subject: [PATCH] [docs] Migrate 22 popular LLVM docs to MyST

---
 llvm/docs/CMake.md                   | 1675 +++++-----
 llvm/docs/CodeGenerator.md           | 1966 ++++++------
 llvm/docs/CodingStandards.md         | 1771 +++++------
 llvm/docs/CommandGuide/index.md      |  197 +-
 llvm/docs/Contributing.md            |  221 +-
 llvm/docs/DeveloperPolicy.md         | 1327 ++++----
 llvm/docs/GettingInvolved.md         |  534 ++--
 llvm/docs/GettingStarted.md          | 1051 +++----
 llvm/docs/GettingStartedTutorials.md |   76 +-
 llvm/docs/GitHub.md                  |  497 ++-
 llvm/docs/Passes.md                  |  705 ++---
 llvm/docs/ProgrammersManual.md       | 4375 ++++++++++++--------------
 llvm/docs/RFCProcess.md              |   70 +-
 llvm/docs/Reference.md               |  409 ++-
 llvm/docs/SourceLevelDebugging.md    | 2861 ++++++++---------
 llvm/docs/TableGen/index.md          |  345 +-
 llvm/docs/TestingGuide.md            | 1185 ++++---
 llvm/docs/UserGuides.md              |  567 ++--
 llvm/docs/WritingAnLLVMBackend.md    | 2625 ++++++++--------
 llvm/docs/WritingAnLLVMNewPMPass.md  |  310 +-
 llvm/docs/WritingAnLLVMPass.md       |  965 +++---
 llvm/docs/conf.py                    |    9 +-
 llvm/docs/index.md                   |  128 +-
 23 files changed, 11468 insertions(+), 12401 deletions(-)

diff --git a/llvm/docs/CMake.md b/llvm/docs/CMake.md
index 4d6aa2b99b9c9..d97af85057a32 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
+1. [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:
+2. Open a shell. Your development tools must be reachable from this shell
+   through the `PATH` environment variable.
 
-   .. code-block:: console
+3. Create a build directory. Building LLVM in the source
+   directory is not supported. `cd` to this directory:
 
-     $ mkdir mybuilddir
-     $ cd mybuilddir
+   ``` console
+   $ mkdir mybuilddir
+   $ cd mybuilddir
+   ```
 
-#. Execute this command in the shell replacing `path/to/llvm/source/root` with
+4. Execute this command in the shell replacing `path/to/llvm/source/root` with
    the path to the root of your LLVM source tree:
 
-   .. code-block:: console
-
-     $ cmake path/to/llvm/source/root
+   ``` 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`_ section for
-   a list of build parameters that you can modify.
+   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`_ 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.
-
-#. After CMake has finished running, use IDE project files, or start
+   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:
 
-   .. code-block:: console
+   ``` console
+   $ cmake --build .
+   ```
 
-     $ 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.
-
-#. After LLVM has finished building, install it from the build directory:
-
-   .. code-block:: console
+   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
 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:
+CMake cache files are utilized using CMake's `-C` flag:
 
-.. code-block:: console
-
-  $ 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,240 @@ 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
+  - `-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
+  - `-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
+- 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``
+- 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
-
-  $ make check-all
+``` console
+$ 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`.
+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`_ section for variables used when
-cross-compiling.
+Also see the [LLVM-related variables](#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
+- `<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.**
+  `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`.
 
-  find_package(LLVM REQUIRED CONFIG)
+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.
 
-  separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
-  add_definitions(${LLVM_DEFINITIONS_LIST})
-  include_directories(${LLVM_INCLUDE_DIRS})
+(cmake-out-of-source-pass)=
+### Developing LLVM passes out of source
 
-  add_subdirectory(<pass name>)
+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.
 
-Contents of ``<project dir>/<pass name>/CMakeLists.txt``:
+``` none
+<project dir>/
+    |
+    CMakeLists.txt
+    <pass name>/
+        |
+        CMakeLists.txt
+        Pass.cpp
+        ...
+```
 
-.. code-block:: cmake
+Contents of `<project dir>/CMakeLists.txt`:
 
-  add_library(LLVMPassname MODULE Pass.cpp)
+``` cmake
+find_package(LLVM REQUIRED CONFIG)
 
-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...
+separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
+add_definitions(${LLVM_DEFINITIONS_LIST})
+include_directories(${LLVM_INCLUDE_DIRS})
 
+add_subdirectory(<pass name>)
+```
 
-Adding the following to ``<project dir>/CMakeLists.txt`` (after
-``find_package(LLVM ...)``)
+Contents of `<project dir>/<pass name>/CMakeLists.txt`:
 
-.. code-block:: cmake
+``` cmake
+add_library(LLVMPassname MODULE Pass.cpp)
+```
 
-  list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
-  include(AddLLVM)
+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 ...)`):
 
-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..3dba6cdc22fed 100644
--- a/llvm/docs/Contributing.md
+++ b/llvm/docs/Contributing.md
@@ -1,124 +1,119 @@
-==================================
-Contributing to LLVM
-==================================
+# 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
+```console
+% git clang-format HEAD~1
+```
 
-  % 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
-
-  # To create a new commit.
-  % git commit -a
-  # To add to the most recent commit.
-  % git commit --amend -a
+```console
+# 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 +130,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 +163,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
-
-  % ln -sf ../../llvm/utils/git/pre-push.py .git/hooks/pre-push
+```console
+% 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..a447903167131 100644
--- a/llvm/docs/DeveloperPolicy.md
+++ b/llvm/docs/DeveloperPolicy.md
@@ -1,112 +1,99 @@
-.. _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.
-
-#. Establish the project's :ref:`copyright, license, and patent
+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.
 
-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
+- {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
+- 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>`.
 
-* 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.
+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
@@ -115,23 +102,19 @@ 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.
-
-.. _code review:
+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 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,21 +124,20 @@ 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
+- 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
+- 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
+- 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
@@ -172,10 +154,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.
@@ -191,7 +173,7 @@ 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
+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
@@ -206,133 +188,122 @@ 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``
+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
-----------
+(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``
+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
+  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
+  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
+- 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
+- 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.
+- 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
+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
+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.
 
-* 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
+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
@@ -344,11 +315,8 @@ 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
@@ -364,55 +332,48 @@ 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
+- 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
+  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
+- 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
+  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
+- 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
+- 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
+- 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
+  [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.
+- 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,10 +385,8 @@ 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
@@ -436,86 +395,86 @@ 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
+- 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
+- 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
+- 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,
+- 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>`
+- 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).
+- 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
+- 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
+  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
+- 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
+- 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
+  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
+- 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.
+- 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
+  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
+  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,
+- 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
+- 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)=
+### 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
+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
+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.
@@ -527,10 +486,9 @@ adhering to our Developer Policy and Code of Conduct. Reviewers should clearly s
 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
@@ -540,20 +498,19 @@ 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
+<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
+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
@@ -561,24 +518,21 @@ If you have recently been granted commit access, these policies apply:
    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
+   {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
+   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
+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 `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.
+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
--------------------------------------
+### 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,10 +542,8 @@ 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
@@ -603,14 +555,12 @@ 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.
+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-changes:
-
-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 +568,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
+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.
-
-#. 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.
+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:
+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
+- 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
+- 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
+- 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
+- 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
+- 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:
+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.
 
-Making Potentially Breaking Changes
------------------------------------
+(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 +619,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
+- 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>`_
+  - [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``
+- 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
+- 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
+  [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
+  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``.
+  `Notifications->Tags`.
 
-Attribution of Changes
-----------------------
+### 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
@@ -739,12 +679,11 @@ 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
+{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.
@@ -756,122 +695,99 @@ 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,
+- 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
+- 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
+- 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
+- Legacy bitcode may have degraded performance when compared to
   the compiled output with the legacy compiler.
 
-C API Changes
--------------
+### C API Changes
 
-* Stability Guarantees: The C API is, in general, a "best effort" for stability.
+- 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
+- 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
+- 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
+- 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
+  [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
--------------------------------
+(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,44 +800,45 @@ 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
+- 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 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
+  ![image](buildbot_worker_contact.png)
 
-* 2nd step: If the owner does not respond or fix the worker, please escalate
+- 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>`_.
 
-.. _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.
@@ -929,16 +846,15 @@ 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`_.
+[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,72 +863,62 @@ 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
+- 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
+- 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
+- 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
+  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
+  ({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.
+- 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
+- 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
+- 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
+- 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
+- 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
+- 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
+- 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.
 
@@ -1025,11 +931,12 @@ 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
+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>`
+   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
@@ -1049,51 +956,50 @@ Those wishing to add a new target to LLVM must follow the procedure below:
    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`_.
+   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.
+- 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.
 
-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
@@ -1107,27 +1013,27 @@ 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
@@ -1137,30 +1043,30 @@ 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`_.
+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
@@ -1185,62 +1091,58 @@ The recommended workflow is:
    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.
+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.
+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
 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.
+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.
@@ -1256,40 +1158,38 @@ 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 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
+- 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:
+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
+- 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
+- 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.
@@ -1307,39 +1207,33 @@ 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
+<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
 
-.. _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
+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:
-
-::
+exceptions". The exceptions read:
 
-   ---- LLVM Exceptions to the Apache 2.0 License ----
+    ---- 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.
+    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
@@ -1349,135 +1243,130 @@ particular, LLVM's license is not a "copyleft" license like the GPL.
 
 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
+- 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
+- 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
+- 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) -
+- 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.
+- 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
+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:
-
-Patents
--------
+(patent license)=
+### 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
+(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
+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._
+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
+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
+- 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'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](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
+(**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
+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 4803b31d77811..a172481f81df9 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
      -
-     - `Minutes/docs <https://docs.google.com/document/d/1x5-RbOC6-jnI_NcJ9Dp4pSmGhhNe7lUevuWUIB46TeM/edit?usp=sharing>`__
+     - [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..7a65486034ecb 100644
--- a/llvm/docs/GettingStartedTutorials.md
+++ b/llvm/docs/GettingStartedTutorials.md
@@ -1,47 +1,47 @@
-Getting Started/Tutorials
-=========================
+# 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 c89b549eb871a..28ea11eb994d9 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,78 +857,68 @@ 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.
 
-``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
@@ -1026,77 +926,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 26a6c13edd094..5f6937d2ab9f5 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 linearly probed hash table.  It excels at supporting
+`DenseSet` is a simple linearly 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,63 +2150,57 @@ 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.
 
@@ -2380,33 +2209,32 @@ 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: linear probing is very cache
+The `StringMap` is very fast for several reasons: linear 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`.
 
-Like ``DenseMap``, ``StringMap`` iterators are invalidated whenever an insertion
-or erasure occurs.  To erase matching elements in a single pass, use the
-``remove_if`` member instead of erasing while iterating.
+Like `DenseMap`, `StringMap` iterators are invalidated whenever an insertion
+or erasure occurs. To erase matching elements in a single pass, use the
+`remove_if` member instead of erasing while iterating.
 
-.. _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.
@@ -2415,94 +2243,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 linearly probed hash table.  It excels at supporting
+`DenseMap` is a simple linearly 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.
@@ -2511,17 +2333,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
@@ -2529,61 +2350,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,
@@ -2594,164 +2410,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
@@ -2760,265 +2562,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*
@@ -3027,194 +2803,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
@@ -3233,187 +2988,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
@@ -3427,28 +3169,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
@@ -3469,14 +3208,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
@@ -3489,242 +3226,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
@@ -3733,429 +3460,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,
@@ -4163,72 +3866,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
@@ -4236,21 +3934,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..cddcc9056128d 100644
--- a/llvm/docs/Reference.md
+++ b/llvm/docs/Reference.md
@@ -1,258 +1,243 @@
-Reference
-=========
+# 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..67ddd69f08ae9 100644
--- a/llvm/docs/TestingGuide.md
+++ b/llvm/docs/TestingGuide.md
@@ -1,83 +1,76 @@
-=================================
-LLVM Testing Infrastructure Guide
-=================================
+# LLVM Testing Infrastructure Guide
 
-.. contents::
-   :local:
+```{contents}
+:local:
+```
 
-.. toctree::
-   :hidden:
+```{toctree}
+:hidden:
 
-   TestSuiteGuide
+TestSuiteGuide
+```
 
-Overview
-========
+## 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 +87,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.
+The `test-suite` module contains more comprehensive tests including whole C
+and C++ programs. See the {doc}`TestSuiteGuide` for details.
 
-Unit and Regression tests
--------------------------
+### Unit and Regression tests
 
-To run all of the LLVM unit tests, use the ``check-llvm-unit`` target:
+To run all of the LLVM unit tests, use the `check-llvm-unit` target:
 
-.. code-block:: bash
+```bash
+% make check-llvm-unit
+```
 
-    % 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
+```bash
+% cmake -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_ASSERTIONS=On
+```
 
-    % 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
-
-    % make check-all
+```bash
+% 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:
-
-.. code-block:: bash
+`Integer/BitPacked.ll` test by itself, you can run:
 
-    % llvm-lit <path to llvm-project>/llvm/test/Integer/BitPacked.ll
+```bash
+% 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:
-
-.. code-block:: llvm
+Below is an example of legal `RUN` lines in a `.ll` file:
 
-    ; RUN: llvm-as < %s | llvm-dis > %t1
-    ; RUN: llvm-dis < %s.bc-13 > %t2
-    ; RUN: diff %t1 %t2
+```llvm
+; 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.
+`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:
+For example, to generate assertions in an {program}`llc`-based test, after
+adding one or more `RUN` lines, use:
 
- .. code-block:: bash
+```bash
+% llvm/utils/update_llc_test_checks.py --llc-binary build/bin/llc test.ll
+```
 
-     % 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 +331,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 +339,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 +361,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,
+using `split-file` to extract them. For example,
 
-.. code-block:: llvm
+```llvm
+; RUN: split-file %s %t
+; RUN: llvm-link -S %t/a.ll %t/b.ll | FileCheck %s
 
-  ; 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
-
-  ;;;;; ident.ll:
+```llvm
+;;;;; 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::
+```{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.
+```
 
-  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
+```
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: opt -S a.ll ... | FileCheck %s
 
-    ; CHECK: hello
+; CHECK: hello
 
-    ;--- a.cc
-    int va;
-    ;--- gen
-    clang --target=x86_64-linux -S -emit-llvm -g a.cc -o -
+;--- a.cc
+int va;
+;--- gen
+clang --target=x86_64-linux -S -emit-llvm -g a.cc -o -
 
-    ;--- a.ll
-    # content generated by the script 'gen'
+;--- a.ll
+# content generated by the script 'gen'
+```
 
-.. code-block:: bash
+```bash
+PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.ll
+```
 
-   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``:
+tested outputs a full path to the input file.  For example, {program}`opt` by
+default outputs a `ModuleID`:
 
-.. code-block:: console
+```console
+$ cat example.ll
+define i32 @main() nounwind {
+    ret i32 0
+}
 
-  $ 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:
+```llvm
+; RUN: opt -S %s | FileCheck
 
-.. code-block:: llvm
+define i32 @main() nounwind {
+    ; CHECK-NOT: load
+    ret i32 0
+}
+```
 
-  ; RUN: opt -S %s | FileCheck
+This test will fail if placed into a `download` directory.
 
-  define i32 @main() nounwind {
-      ; CHECK-NOT: load
-      ret i32 0
-  }
+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.
 
-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.
-
-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 +567,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 +613,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 +1109,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..af9781b66c692 100644
--- a/llvm/docs/conf.py
+++ b/llvm/docs/conf.py
@@ -39,7 +39,14 @@
     if not tags.has("builder-man"):
         raise
 else:
-    myst_enable_extensions = ["substitution"]
+    myst_enable_extensions = ["deflist", "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 4fd63dcf61e94..e933810197c42 100644
--- a/llvm/docs/index.md
+++ b/llvm/docs/index.md
@@ -1,10 +1,11 @@
-About
-========
+# About
 
-.. warning::
+```{warning}
+If you are using a released version of LLVM, see [the download page]
+to find your documentation.
+```
 
-   If you are using a released version of LLVM, see `the download page
-   <https://llvm.org/releases/>`_ 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,96 +14,91 @@ 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:
+```{toctree}
+:hidden:
 
-   FAQ
-   Lexicon
+FAQ
+Lexicon
+```
 
-:doc:`FAQ`
-  Frequently asked questions.
+{doc}`FAQ`
+: Frequently asked questions.
 
-:doc:`Lexicon`
-  Glossary.
+{doc}`Lexicon`
+: Glossary.
 
-`Introduction to the LLVM Compiler`__
-  Presentation providing a users introduction to LLVM.
+[Introduction to the LLVM Compiler]
+: Presentation providing a users introduction to LLVM.
 
-  .. __: https://llvm.org/pubs/2008-10-04-ACAT-LLVM-Intro.html
-
-`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
-   ProjectGovernance
+GettingInvolved
+RFCProcess
+ProjectGovernance
+```
 
-* :doc:`GettingInvolved`
-* :ref:`development-process`
-* :doc:`RFCProcess`
-* :doc:`ProjectGovernance`
-* :ref:`lists-forums`
-* :ref:`meetups-social-events`
-* :ref:`community-proposals`
+* {doc}`GettingInvolved`
+* {ref}`development-process`
+* {doc}`RFCProcess`
+* {doc}`ProjectGovernance`
+* {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`



More information about the llvm-branch-commits mailing list