[llvm-branch-commits] [llvm] [LLVM][docs] Finish MyST migration for remaining docs (batch 11) (PR #223100)

Reid Kleckner via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Sep 13 20:02:35 PDT 2026


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

>From a13af687c8b79726b759aff781ef5420afee6125 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 11 Sep 2026 17:30:27 +0000
Subject: [PATCH 1/4] [LLVM][docs] Rename reST docs to Markdown (batch 11)

---
 llvm/docs/{MarkedUpDisassembly.rst => MarkedUpDisassembly.md}     | 0
 llvm/docs/{MeetupGuidelines.rst => MeetupGuidelines.md}           | 0
 llvm/docs/{MemTagSanitizer.rst => MemTagSanitizer.md}             | 0
 ...axationAnnotations.rst => MemoryModelRelaxationAnnotations.md} | 0
 llvm/docs/{PCSectionsMetadata.rst => PCSectionsMetadata.md}       | 0
 llvm/docs/{Projects.rst => Projects.md}                           | 0
 llvm/docs/Proposals/{GitHubMove.rst => GitHubMove.md}             | 0
 llvm/docs/Proposals/{TestSuite.rst => TestSuite.md}               | 0
 .../Proposals/{VectorPredication.rst => VectorPredication.md}     | 0
 llvm/docs/{QualGroup.rst => QualGroup.md}                         | 0
 llvm/docs/{ReleaseProcess.rst => ReleaseProcess.md}               | 0
 .../{ScudoHardenedAllocator.rst => ScudoHardenedAllocator.md}     | 0
 llvm/docs/{Security.rst => Security.md}                           | 0
 ...rityTransparencyReports.rst => SecurityTransparencyReports.md} | 0
 llvm/docs/{SegmentedStacks.rst => SegmentedStacks.md}             | 0
 llvm/docs/{StackMaps.rst => StackMaps.md}                         | 0
 llvm/docs/{Statepoints.rst => Statepoints.md}                     | 0
 llvm/docs/{SupportPolicy.rst => SupportPolicy.md}                 | 0
 llvm/docs/{SystemLibrary.rst => SystemLibrary.md}                 | 0
 llvm/docs/TableGen/{BackEnds.rst => BackEnds.md}                  | 0
 llvm/docs/TableGen/{BackGuide.rst => BackGuide.md}                | 0
 llvm/docs/TableGen/{ProgRef.rst => ProgRef.md}                    | 0
 llvm/docs/{TransformMetadata.rst => TransformMetadata.md}         | 0
 llvm/docs/{TypeMetadata.rst => TypeMetadata.md}                   | 0
 llvm/docs/{UndefinedBehavior.rst => UndefinedBehavior.md}         | 0
 llvm/docs/{VectorizationPlan.rst => VectorizationPlan.md}         | 0
 llvm/docs/{XRay.rst => XRay.md}                                   | 0
 llvm/docs/{XRayExample.rst => XRayExample.md}                     | 0
 llvm/docs/{XRayFDRFormat.rst => XRayFDRFormat.md}                 | 0
 llvm/docs/{YamlIO.rst => YamlIO.md}                               | 0
 30 files changed, 0 insertions(+), 0 deletions(-)
 rename llvm/docs/{MarkedUpDisassembly.rst => MarkedUpDisassembly.md} (100%)
 rename llvm/docs/{MeetupGuidelines.rst => MeetupGuidelines.md} (100%)
 rename llvm/docs/{MemTagSanitizer.rst => MemTagSanitizer.md} (100%)
 rename llvm/docs/{MemoryModelRelaxationAnnotations.rst => MemoryModelRelaxationAnnotations.md} (100%)
 rename llvm/docs/{PCSectionsMetadata.rst => PCSectionsMetadata.md} (100%)
 rename llvm/docs/{Projects.rst => Projects.md} (100%)
 rename llvm/docs/Proposals/{GitHubMove.rst => GitHubMove.md} (100%)
 rename llvm/docs/Proposals/{TestSuite.rst => TestSuite.md} (100%)
 rename llvm/docs/Proposals/{VectorPredication.rst => VectorPredication.md} (100%)
 rename llvm/docs/{QualGroup.rst => QualGroup.md} (100%)
 rename llvm/docs/{ReleaseProcess.rst => ReleaseProcess.md} (100%)
 rename llvm/docs/{ScudoHardenedAllocator.rst => ScudoHardenedAllocator.md} (100%)
 rename llvm/docs/{Security.rst => Security.md} (100%)
 rename llvm/docs/{SecurityTransparencyReports.rst => SecurityTransparencyReports.md} (100%)
 rename llvm/docs/{SegmentedStacks.rst => SegmentedStacks.md} (100%)
 rename llvm/docs/{StackMaps.rst => StackMaps.md} (100%)
 rename llvm/docs/{Statepoints.rst => Statepoints.md} (100%)
 rename llvm/docs/{SupportPolicy.rst => SupportPolicy.md} (100%)
 rename llvm/docs/{SystemLibrary.rst => SystemLibrary.md} (100%)
 rename llvm/docs/TableGen/{BackEnds.rst => BackEnds.md} (100%)
 rename llvm/docs/TableGen/{BackGuide.rst => BackGuide.md} (100%)
 rename llvm/docs/TableGen/{ProgRef.rst => ProgRef.md} (100%)
 rename llvm/docs/{TransformMetadata.rst => TransformMetadata.md} (100%)
 rename llvm/docs/{TypeMetadata.rst => TypeMetadata.md} (100%)
 rename llvm/docs/{UndefinedBehavior.rst => UndefinedBehavior.md} (100%)
 rename llvm/docs/{VectorizationPlan.rst => VectorizationPlan.md} (100%)
 rename llvm/docs/{XRay.rst => XRay.md} (100%)
 rename llvm/docs/{XRayExample.rst => XRayExample.md} (100%)
 rename llvm/docs/{XRayFDRFormat.rst => XRayFDRFormat.md} (100%)
 rename llvm/docs/{YamlIO.rst => YamlIO.md} (100%)

diff --git a/llvm/docs/MarkedUpDisassembly.rst b/llvm/docs/MarkedUpDisassembly.md
similarity index 100%
rename from llvm/docs/MarkedUpDisassembly.rst
rename to llvm/docs/MarkedUpDisassembly.md
diff --git a/llvm/docs/MeetupGuidelines.rst b/llvm/docs/MeetupGuidelines.md
similarity index 100%
rename from llvm/docs/MeetupGuidelines.rst
rename to llvm/docs/MeetupGuidelines.md
diff --git a/llvm/docs/MemTagSanitizer.rst b/llvm/docs/MemTagSanitizer.md
similarity index 100%
rename from llvm/docs/MemTagSanitizer.rst
rename to llvm/docs/MemTagSanitizer.md
diff --git a/llvm/docs/MemoryModelRelaxationAnnotations.rst b/llvm/docs/MemoryModelRelaxationAnnotations.md
similarity index 100%
rename from llvm/docs/MemoryModelRelaxationAnnotations.rst
rename to llvm/docs/MemoryModelRelaxationAnnotations.md
diff --git a/llvm/docs/PCSectionsMetadata.rst b/llvm/docs/PCSectionsMetadata.md
similarity index 100%
rename from llvm/docs/PCSectionsMetadata.rst
rename to llvm/docs/PCSectionsMetadata.md
diff --git a/llvm/docs/Projects.rst b/llvm/docs/Projects.md
similarity index 100%
rename from llvm/docs/Projects.rst
rename to llvm/docs/Projects.md
diff --git a/llvm/docs/Proposals/GitHubMove.rst b/llvm/docs/Proposals/GitHubMove.md
similarity index 100%
rename from llvm/docs/Proposals/GitHubMove.rst
rename to llvm/docs/Proposals/GitHubMove.md
diff --git a/llvm/docs/Proposals/TestSuite.rst b/llvm/docs/Proposals/TestSuite.md
similarity index 100%
rename from llvm/docs/Proposals/TestSuite.rst
rename to llvm/docs/Proposals/TestSuite.md
diff --git a/llvm/docs/Proposals/VectorPredication.rst b/llvm/docs/Proposals/VectorPredication.md
similarity index 100%
rename from llvm/docs/Proposals/VectorPredication.rst
rename to llvm/docs/Proposals/VectorPredication.md
diff --git a/llvm/docs/QualGroup.rst b/llvm/docs/QualGroup.md
similarity index 100%
rename from llvm/docs/QualGroup.rst
rename to llvm/docs/QualGroup.md
diff --git a/llvm/docs/ReleaseProcess.rst b/llvm/docs/ReleaseProcess.md
similarity index 100%
rename from llvm/docs/ReleaseProcess.rst
rename to llvm/docs/ReleaseProcess.md
diff --git a/llvm/docs/ScudoHardenedAllocator.rst b/llvm/docs/ScudoHardenedAllocator.md
similarity index 100%
rename from llvm/docs/ScudoHardenedAllocator.rst
rename to llvm/docs/ScudoHardenedAllocator.md
diff --git a/llvm/docs/Security.rst b/llvm/docs/Security.md
similarity index 100%
rename from llvm/docs/Security.rst
rename to llvm/docs/Security.md
diff --git a/llvm/docs/SecurityTransparencyReports.rst b/llvm/docs/SecurityTransparencyReports.md
similarity index 100%
rename from llvm/docs/SecurityTransparencyReports.rst
rename to llvm/docs/SecurityTransparencyReports.md
diff --git a/llvm/docs/SegmentedStacks.rst b/llvm/docs/SegmentedStacks.md
similarity index 100%
rename from llvm/docs/SegmentedStacks.rst
rename to llvm/docs/SegmentedStacks.md
diff --git a/llvm/docs/StackMaps.rst b/llvm/docs/StackMaps.md
similarity index 100%
rename from llvm/docs/StackMaps.rst
rename to llvm/docs/StackMaps.md
diff --git a/llvm/docs/Statepoints.rst b/llvm/docs/Statepoints.md
similarity index 100%
rename from llvm/docs/Statepoints.rst
rename to llvm/docs/Statepoints.md
diff --git a/llvm/docs/SupportPolicy.rst b/llvm/docs/SupportPolicy.md
similarity index 100%
rename from llvm/docs/SupportPolicy.rst
rename to llvm/docs/SupportPolicy.md
diff --git a/llvm/docs/SystemLibrary.rst b/llvm/docs/SystemLibrary.md
similarity index 100%
rename from llvm/docs/SystemLibrary.rst
rename to llvm/docs/SystemLibrary.md
diff --git a/llvm/docs/TableGen/BackEnds.rst b/llvm/docs/TableGen/BackEnds.md
similarity index 100%
rename from llvm/docs/TableGen/BackEnds.rst
rename to llvm/docs/TableGen/BackEnds.md
diff --git a/llvm/docs/TableGen/BackGuide.rst b/llvm/docs/TableGen/BackGuide.md
similarity index 100%
rename from llvm/docs/TableGen/BackGuide.rst
rename to llvm/docs/TableGen/BackGuide.md
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.md
similarity index 100%
rename from llvm/docs/TableGen/ProgRef.rst
rename to llvm/docs/TableGen/ProgRef.md
diff --git a/llvm/docs/TransformMetadata.rst b/llvm/docs/TransformMetadata.md
similarity index 100%
rename from llvm/docs/TransformMetadata.rst
rename to llvm/docs/TransformMetadata.md
diff --git a/llvm/docs/TypeMetadata.rst b/llvm/docs/TypeMetadata.md
similarity index 100%
rename from llvm/docs/TypeMetadata.rst
rename to llvm/docs/TypeMetadata.md
diff --git a/llvm/docs/UndefinedBehavior.rst b/llvm/docs/UndefinedBehavior.md
similarity index 100%
rename from llvm/docs/UndefinedBehavior.rst
rename to llvm/docs/UndefinedBehavior.md
diff --git a/llvm/docs/VectorizationPlan.rst b/llvm/docs/VectorizationPlan.md
similarity index 100%
rename from llvm/docs/VectorizationPlan.rst
rename to llvm/docs/VectorizationPlan.md
diff --git a/llvm/docs/XRay.rst b/llvm/docs/XRay.md
similarity index 100%
rename from llvm/docs/XRay.rst
rename to llvm/docs/XRay.md
diff --git a/llvm/docs/XRayExample.rst b/llvm/docs/XRayExample.md
similarity index 100%
rename from llvm/docs/XRayExample.rst
rename to llvm/docs/XRayExample.md
diff --git a/llvm/docs/XRayFDRFormat.rst b/llvm/docs/XRayFDRFormat.md
similarity index 100%
rename from llvm/docs/XRayFDRFormat.rst
rename to llvm/docs/XRayFDRFormat.md
diff --git a/llvm/docs/YamlIO.rst b/llvm/docs/YamlIO.md
similarity index 100%
rename from llvm/docs/YamlIO.rst
rename to llvm/docs/YamlIO.md

>From 2cc0aefc413074a1f1f548c238ffff96c2d84241 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 11 Sep 2026 17:30:39 +0000
Subject: [PATCH 2/4] [LLVM][docs] Convert remaining reST docs with rst2myst
 (batch 11)

---
 llvm/docs/MarkedUpDisassembly.md              |   55 +-
 llvm/docs/MeetupGuidelines.md                 |   67 +-
 llvm/docs/MemTagSanitizer.md                  |   68 +-
 llvm/docs/MemoryModelRelaxationAnnotations.md |  519 +--
 llvm/docs/PCSectionsMetadata.md               |  137 +-
 llvm/docs/Projects.md                         |  312 +-
 llvm/docs/Proposals/GitHubMove.md             | 1363 ++++----
 llvm/docs/Proposals/TestSuite.md              |  472 ++-
 llvm/docs/Proposals/VectorPredication.md      |   58 +-
 llvm/docs/QualGroup.md                        |  304 +-
 llvm/docs/ReleaseProcess.md                   |  188 +-
 llvm/docs/ScudoHardenedAllocator.md           |  156 +-
 llvm/docs/Security.md                         |  248 +-
 llvm/docs/SecurityTransparencyReports.md      |  538 ++-
 llvm/docs/SegmentedStacks.md                  |   71 +-
 llvm/docs/StackMaps.md                        |  386 +--
 llvm/docs/Statepoints.md                      |  694 ++--
 llvm/docs/SupportPolicy.md                    |  204 +-
 llvm/docs/SystemLibrary.md                    |   10 +-
 llvm/docs/TableGen/BackEnds.md                | 1394 ++++----
 llvm/docs/TableGen/BackGuide.md               |  926 +++--
 llvm/docs/TableGen/ProgRef.md                 | 2991 +++++++++--------
 llvm/docs/TransformMetadata.md                |  434 ++-
 llvm/docs/TypeMetadata.md                     |  293 +-
 llvm/docs/UndefinedBehavior.md                |  474 ++-
 llvm/docs/VectorizationPlan.md                |  129 +-
 llvm/docs/XRay.md                             |  347 +-
 llvm/docs/XRayExample.md                      |  429 ++-
 llvm/docs/XRayFDRFormat.md                    |  324 +-
 llvm/docs/YamlIO.md                           | 1477 ++++----
 30 files changed, 7249 insertions(+), 7819 deletions(-)

diff --git a/llvm/docs/MarkedUpDisassembly.md b/llvm/docs/MarkedUpDisassembly.md
index b7843818b70eb..b3fc4da1c5527 100644
--- a/llvm/docs/MarkedUpDisassembly.md
+++ b/llvm/docs/MarkedUpDisassembly.md
@@ -1,10 +1,6 @@
-=======================================
-LLVM's Optional Rich Disassembly Output
-=======================================
+# LLVM's Optional Rich Disassembly Output
 
-
-Introduction
-============
+## Introduction
 
 LLVM's default disassembly output is raw text. To allow consumers more ability
 to introspect the instructions' textual representation or to reformat for a more
@@ -21,23 +17,21 @@ mismatches between consumers and producers. That is, the syntax generally does
 not carry semantics beyond "this text has an annotation," so consumers can
 simply ignore annotations they do not understand or do not care about.
 
-After calling ``LLVMCreateDisasm()`` to create a disassembler context the
+After calling `LLVMCreateDisasm()` to create a disassembler context the
 optional output is enable with this call:
 
-.. code-block:: c
-
-    LLVMSetDisasmOptions(DC, LLVMDisassembler_Option_UseMarkup);
+```c
+LLVMSetDisasmOptions(DC, LLVMDisassembler_Option_UseMarkup);
+```
 
-Then subsequent calls to ``LLVMDisasmInstruction()`` will return output strings
+Then subsequent calls to `LLVMDisasmInstruction()` will return output strings
 with the marked up annotations.
 
-Instruction Annotations
-=======================
+## Instruction Annotations
 
-.. _contextual markups:
+(contextual-markups)=
 
-Contextual markups
-------------------
+### Contextual markups
 
 Annotated assembly display will supply contextual markup to help clients more
 efficiently implement things like pretty printers. Most markup will be target
@@ -46,13 +40,13 @@ specific knowledge.
 
 Annotated assembly goes through the normal instruction printer, but optionally
 includes contextual tags on portions of the instruction string. An annotation
-is any '<' '>' delimited section of text(1).
-
-.. code-block:: bat
+is any '\<' '>' delimited section of text(1).
 
-    annotation: '<' tag-name tag-modifier-list ':' annotated-text '>'
-    tag-name: identifier
-    tag-modifier-list: comma delimited identifier list
+```bat
+annotation: '<' tag-name tag-modifier-list ':' annotated-text '>'
+tag-name: identifier
+tag-modifier-list: comma delimited identifier list
+```
 
 The tag-name is an identifier which gives the type of the annotation. For the
 first pass, this will be very simple, with memory references, registers, and
@@ -68,17 +62,16 @@ clients.
 For example, a possible annotation of an ARM load of a stack-relative location
 might be annotated as:
 
-.. code-block:: text
+```text
+ldr <reg gpr:r0>, <mem regoffset:[<reg gpr:sp>, <imm:#4>]>
+```
 
-   ldr <reg gpr:r0>, <mem regoffset:[<reg gpr:sp>, <imm:#4>]>
+1: For assembly dialects in which '\<' and/or '>' are legal tokens, a literal token is escaped by following immediately with a repeat of the character. For example, a literal '\<' character is output as '\<<' in an annotated assembly string.
 
-
-1: For assembly dialects in which '<' and/or '>' are legal tokens, a literal token is escaped by following immediately with a repeat of the character.  For example, a literal '<' character is output as '<<' in an annotated assembly string.
-
-C API Details
--------------
+### C API Details
 
 The intended consumers of this information use the C API, therefore the new C
 API function for the disassembler will be added to provide an option to produce
-disassembled instructions with annotations, ``LLVMSetDisasmOptions()`` and the
-``LLVMDisassembler_Option_UseMarkup`` option (see above).
+disassembled instructions with annotations, `LLVMSetDisasmOptions()` and the
+`LLVMDisassembler_Option_UseMarkup` option (see above).
+
diff --git a/llvm/docs/MeetupGuidelines.md b/llvm/docs/MeetupGuidelines.md
index 493593eadfb5f..33fa2b4cd4668 100644
--- a/llvm/docs/MeetupGuidelines.md
+++ b/llvm/docs/MeetupGuidelines.md
@@ -1,82 +1,75 @@
-=====================================
-How to start LLVM Social in your town
-=====================================
+# How to start LLVM Social in your town
 
 Here are several ideas you can take into account when designing your specific
 LLVM Social.
 
 Before you start, it is essential to make sure that the meetup is as welcoming
 as any other event related to LLVM. Therefore you shall follow LLVM's
-`Code of Conduct <https://llvm.org/docs/CodeOfConduct.html>`_.
+[Code of Conduct](https://llvm.org/docs/CodeOfConduct.html).
 
 Other than that - your mileage may vary. Please adapt your social to what works
 best for your specific situation.
 
-General suggestions
--------------------
+## General suggestions
 
-* We highly recommend that you join the official LLVM meetup organization. In
+- We highly recommend that you join the official LLVM meetup organization. In
   addition to covering the cost of the meetup, all LLVM meetups are advertised
   together and easily found by potential attendees. Please contact
-  tanyalattner at llvm.org for more details.
-* Beware of cultural differences: what works well in one region may not work in
+  <mailto:tanyalattner at llvm.org> for more details.
+- Beware of cultural differences: what works well in one region may not work in
   other part of the world.
-* Do not be alone to organize the meetup. Try to work with a couple other
+- Do not be alone to organize the meetup. Try to work with a couple other
   organizers. This is more motivating as an organizer, and this makes the
   meetup more resilient over time.
-* Each event can have a different form such as a social event, or
+- Each event can have a different form such as a social event, or
   a hackathon/workshop, or a 'mini-conference' with one or more talks. You do
   not have to stick to one format forever.
-* Whatever format you choose, `LLVM Weekly <http://llvmweekly.org/>`_ is an
+- Whatever format you choose, [LLVM Weekly](http://llvmweekly.org/) is an
   excellent topic starter: go through the 3-4 recent LLVM Weekly posts and
   prepare a list of the most interesting/notable news and discuss them with the
   group.
 
-Advertisement
--------------
+## Advertisement
 
-* Try to advertise via similar meetups/user groups
-* Advertise your meetup on the mailing lists (llvm-dev, cfe-dev, lldb-dev,
+- Try to advertise via similar meetups/user groups
+- Advertise your meetup on the mailing lists (llvm-dev, cfe-dev, lldb-dev,
   ...). Feel free to post to all of them, or at least to llvm-dev.
   But as these mailing lists have high traffic and some LLVM developers are not
   very active on them, you may reach more interested people using the mailing
   feature from meetup.com.
-* Advertise the meetup on Twitter and mention
-  `@llvmweekly <http://twitter.com/llvmweekly>`_ and
-  `@llvmorg <http://twitter.com/llvmorg>`_.
-* Announce the next meetup in advance, and remind in one week or so.
+- Advertise the meetup on Twitter and mention
+  [@llvmweekly](http://twitter.com/llvmweekly) and
+  [@llvmorg](http://twitter.com/llvmorg).
+- Announce the next meetup in advance, and remind in one week or so.
 
-Tech talks
-----------
+## Tech talks
 
-* It’s a great idea to have several talks scheduled for several upcoming
+- It’s a great idea to have several talks scheduled for several upcoming
   meetups to get the ball rolling.
-* Keep looking for speakers far in advance, ideally you should have 2-3
+- Keep looking for speakers far in advance, ideally you should have 2-3
   speakers ready in the pipeline.
-* Try to record the talks if possible. It adds visibility to the meetup and
+- Try to record the talks if possible. It adds visibility to the meetup and
   just a good idea in general. Any modern smartphone or tablet should work, but
   you can also get a camera. Though, it is recommended to get an external
   microphone for better sound.
 
-Where to host the meetup?
--------------------------
+## Where to host the meetup?
 
-* Look around for bars/café with projectors.
-* Talk to tech companies in the area.
-* Some co-working spaces provide their facilities for non-profit (i.e., you do
+- Look around for bars/café with projectors.
+- Talk to tech companies in the area.
+- Some co-working spaces provide their facilities for non-profit (i.e., you do
   not charge attendees any fees) meetups.
-* Ask nearby universities or university departments.
+- Ask nearby universities or university departments.
 
-How to pick the date?
----------------------
+## How to pick the date?
 
-* Make sure you do not clash with the similar meetups in the city (e.g.,
+- Make sure you do not clash with the similar meetups in the city (e.g.,
   C++ user groups).
-* Prefer not to have a meetup the same week when the other similar meetups
+- Prefer not to have a meetup the same week when the other similar meetups
   happen (e.g., it’s not a good idea to have LLVM meetup on Thursday after
   C++ meetup on Wednesday).
-* Meetups on weekends may attract people who live far away from the city,
+- Meetups on weekends may attract people who live far away from the city,
   but the people who live in the city may not attend.
-* Make a poll, but beware that not every responder will join (we had ~20 votes
+- Make a poll, but beware that not every responder will join (we had ~20 votes
   on the poll, while only ~8 people attended).
 
diff --git a/llvm/docs/MemTagSanitizer.md b/llvm/docs/MemTagSanitizer.md
index 8fba126cd4c37..f54bec6188eab 100644
--- a/llvm/docs/MemTagSanitizer.md
+++ b/llvm/docs/MemTagSanitizer.md
@@ -1,18 +1,14 @@
-================
-MemTagSanitizer
-================
+# MemTagSanitizer
 
-
-Introduction
-============
+## Introduction
 
 **Note:** this page describes a tool under development. Part of this
-functionality is planned but not implemented.  Hardware capable of
+functionality is planned but not implemented. Hardware capable of
 running MemTagSanitizer does not exist as of Oct 2019.
 
 MemTagSanitizer is a fast memory error detector and **a code hardening
-tool** based on the Armv8.5-A `Memory Tagging Extension`_. It
-detects a similar class of errors as `AddressSanitizer`_ or `HardwareAssistedAddressSanitizer`_, but with
+tool** based on the Armv8.5-A [Memory Tagging Extension][memory tagging extension]. It
+detects a similar class of errors as [AddressSanitizer][addresssanitizer] or [HardwareAssistedAddressSanitizer][hardwareassistedaddresssanitizer], but with
 **much** lower overhead.
 
 MemTagSanitizer overhead is expected to be in low single digits, both
@@ -22,37 +18,33 @@ MemTagSanitizer is code hardening in production binaries, where it is
 expected to be a strong mitigation for both stack and heap-based
 memory bugs.
 
+## Usage
 
-Usage
-=====
-
-Compile and link your program with the ``-fsanitize=memtag`` flag. This
+Compile and link your program with the `-fsanitize=memtag` flag. This
 will only work when targeting AArch64 Android with the memory tagging extension.
-One possible way to achieve that is to add ``--target=aarch64-linux-android -march=armv8+memtag``
+One possible way to achieve that is to add `--target=aarch64-linux-android -march=armv8+memtag`
 to your compilation flags.
 
 Note that doing this will override existing flags of the same type. Assuming that
 you are already targeting AArch64 Android, an alternative is to add
-``-Xclang -target-feature -Xclang +mte`` to your compilation flags. This
+`-Xclang -target-feature -Xclang +mte` to your compilation flags. This
 adds the memory tagging feature, without changing anything else.
 
-Implementation
-==============
+## Implementation
 
-See `HardwareAssistedAddressSanitizer`_ for a general overview of a
-tag-based approach to memory safety.  MemTagSanitizer follows a
+See [HardwareAssistedAddressSanitizer][hardwareassistedaddresssanitizer] for a general overview of a
+tag-based approach to memory safety. MemTagSanitizer follows a
 similar implementation strategy, but with the tag storage (shadow)
 provided by the hardware.
 
 A quick overview of MTE hardware capabilities:
 
-* Every 16 aligned bytes of memory can be assigned a 4-bit Allocation Tag.
-* Every pointer can have a 4-bit Address Tag that is in its most significant byte.
-* Most memory access instructions generate an exception if Address Tag != Allocation Tag.
-* Special instructions are provided for fast tag manipulation.
+- Every 16 aligned bytes of memory can be assigned a 4-bit Allocation Tag.
+- Every pointer can have a 4-bit Address Tag that is in its most significant byte.
+- Most memory access instructions generate an exception if Address Tag != Allocation Tag.
+- Special instructions are provided for fast tag manipulation.
 
-Stack instrumentation
-=====================
+## Stack instrumentation
 
 Stack-based memory errors are detected by updating Allocation Tag for
 each local variable to a random value at the start of its lifetime,
@@ -71,31 +63,29 @@ For this reason MemTagSanitizer generates at most one random tag per
 function, called a "base tag". Other stack variables, if there are
 any, are assigned tags at a fixed offset from the base.
 
-Please refer to `this document
-<https://github.com/google/sanitizers/wiki/Stack-instrumentation-with-ARM-Memory-Tagging-Extension-(MTE)>`_
+Please refer to [this document](<https://github.com/google/sanitizers/wiki/Stack-instrumentation-with-ARM-Memory-Tagging-Extension-(MTE)>)
 for more details about stack instrumentation.
 
-Heap tagging
-============
+## Heap tagging
 
 **Note:** this part is not implemented as of Oct 2019.
 
-MemTagSanitizer will use :doc:`ScudoHardenedAllocator`
+MemTagSanitizer will use {doc}`ScudoHardenedAllocator`
 with additional code to update memory tags when
 
-* New memory is obtained from the system.
-* An allocation is freed.
+- New memory is obtained from the system.
+- An allocation is freed.
 
 There is no need to change Allocation Tags for the bulk of the
 allocated memory in malloc(), as long as a pointer with the matching
 Address Tag is returned.
 
-More information
-================
+## More information
+
+- [LLVM Developer Meeting 2018 talk on Memory Tagging](https://llvm.org/devmtg/2018-10/slides/Serebryany-Stepanov-Tsyrklevich-Memory-Tagging-Slides-LLVM-2018.pdf)
+- [Memory Tagging Whitepaper](https://arxiv.org/pdf/1802.09517.pdf)
 
-* `LLVM Developer Meeting 2018 talk on Memory Tagging <https://llvm.org/devmtg/2018-10/slides/Serebryany-Stepanov-Tsyrklevich-Memory-Tagging-Slides-LLVM-2018.pdf>`_
-* `Memory Tagging Whitepaper <https://arxiv.org/pdf/1802.09517.pdf>`_
+[addresssanitizer]: https://clang.llvm.org/docs/AddressSanitizer.html
+[hardwareassistedaddresssanitizer]: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
+[memory tagging extension]: https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-a-profile-architecture-2018-developments-armv85a
 
-.. _Memory Tagging Extension: https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-a-profile-architecture-2018-developments-armv85a
-.. _AddressSanitizer: https://clang.llvm.org/docs/AddressSanitizer.html
-.. _HardwareAssistedAddressSanitizer: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
diff --git a/llvm/docs/MemoryModelRelaxationAnnotations.md b/llvm/docs/MemoryModelRelaxationAnnotations.md
index a009a5a97331d..81fe32c85083f 100644
--- a/llvm/docs/MemoryModelRelaxationAnnotations.md
+++ b/llvm/docs/MemoryModelRelaxationAnnotations.md
@@ -1,19 +1,15 @@
-===================================
-Memory Model Relaxation Annotations
-===================================
+# Memory Model Relaxation Annotations
 
-
-Introduction
-============
+## Introduction
 
 Memory Model Relaxation Annotations (MMRAs) are target-defined properties
 on instructions that can be used to selectively relax constraints placed
 by the memory model. For example:
 
-* The use of ``VulkanMemoryModel`` in a SPIRV program allows certain
-  memory operations to be reordered across ``acquire`` or ``release``
+- The use of `VulkanMemoryModel` in a SPIRV program allows certain
+  memory operations to be reordered across `acquire` or `release`
   operations.
-* OpenCL APIs expose primitives to only fence a specific set of address
+- OpenCL APIs expose primitives to only fence a specific set of address
   spaces. Carrying that information to the backend can enable the
   use of faster synchronization instructions, rather than fencing all
   address spaces everytime.
@@ -23,327 +19,335 @@ memory model.
 As such, they are attached to an operation using LLVM metadata which
 can always be dropped without affecting correctness.
 
-Definitions
-===========
+## Definitions
 
 memory operation
-    A load, a store, an atomic, or a function call that is marked as
-    accessing memory.
+
+: A load, a store, an atomic, or a function call that is marked as
+  accessing memory.
 
 synchronizing operation
-    An instruction that synchronizes memory with other threads (e.g.
-    an atomic or a fence).
 
-tag
-    Metadata attached to a memory or synchronizing operation
-    that represents some target-defined property regarding memory
-    synchronization.
+: An instruction that synchronizes memory with other threads (e.g.
+  an atomic or a fence).
 
-    An operation may have multiple tags that each represent a different
-    property.
+tag
 
-    A tag is composed of a pair of metadata string: a *prefix* and a *suffix*.
+: Metadata attached to a memory or synchronizing operation
+  that represents some target-defined property regarding memory
+  synchronization.
 
-    In LLVM IR, the pair is represented using a metadata tuple.
-    In other cases (comments, documentation, etc.), we may use the
-    ``prefix:suffix`` notation.
-    For example:
+  An operation may have multiple tags that each represent a different
+  property.
 
-    .. code-block::
-      :caption: Example: Tags in Metadata
+  A tag is composed of a pair of metadata string: a *prefix* and a *suffix*.
 
-      !0 = !{!"scope", !"workgroup"}  # scope:workgroup
-      !1 = !{!"scope", !"device"}     # scope:device
-      !2 = !{!"scope", !"system"}     # scope:system
+  In LLVM IR, the pair is represented using a metadata tuple.
+  In other cases (comments, documentation, etc.), we may use the
+  `prefix:suffix` notation.
+  For example:
 
-    .. note::
+  ```{code-block}
+  :caption: 'Example: Tags in Metadata'
 
-      The only semantics relevant to the optimizer is the
-      "compatibility" relation defined below. All other
-      semantics are target defined.
+  !0 = !{!"scope", !"workgroup"}  # scope:workgroup
+  !1 = !{!"scope", !"device"}     # scope:device
+  !2 = !{!"scope", !"system"}     # scope:system
+  ```
 
-    Tags can also be organised in lists to allow operations
-    to specify all of the tags they belong to. Such a list
-    is referred to as a "set of tags".
+  :::{note}
+  The only semantics relevant to the optimizer is the
+  "compatibility" relation defined below. All other
+  semantics are target defined.
+  :::
 
-    .. code-block::
-      :caption: Example: Set of Tags in Metadata
+  Tags can also be organised in lists to allow operations
+  to specify all of the tags they belong to. Such a list
+  is referred to as a "set of tags".
 
-      !0 = !{!"scope", !"workgroup"}
-      !1 = !{!"sync-as", !"private"}
-      !2 = !{!0, !2}
+  ```{code-block}
+  :caption: 'Example: Set of Tags in Metadata'
 
-    .. note::
+  !0 = !{!"scope", !"workgroup"}
+  !1 = !{!"sync-as", !"private"}
+  !2 = !{!0, !2}
+  ```
 
-      If an operation does not have MMRA metadata, it's treated as if
-      it has an empty list (``!{}``) of tags.
+  :::{note}
+  If an operation does not have MMRA metadata, it's treated as if
+  it has an empty list (`!{}`) of tags.
+  :::
 
-    Note that it is not an error if a tag is not recognized by the
-    instruction it is applied to, or by the current target.
-    Such tags are simply ignored.
+  Note that it is not an error if a tag is not recognized by the
+  instruction it is applied to, or by the current target.
+  Such tags are simply ignored.
 
-    Both synchronizing operations and memory operations can have
-    zero or more tags attached to them using the ``!mmra`` syntax.
+  Both synchronizing operations and memory operations can have
+  zero or more tags attached to them using the `!mmra` syntax.
 
-    For the sake of readability in examples below,
-    we use a (non-functional) short syntax to represent MMMRA metadata:
+  For the sake of readability in examples below,
+  we use a (non-functional) short syntax to represent MMMRA metadata:
 
-    .. code-block::
-      :caption: Short Syntax Example
+  ```{code-block}
+  :caption: Short Syntax Example
 
-      store %ptr1 # foo:bar
-      store %ptr1 !mmra !{!"foo", !"bar"}
+  store %ptr1 # foo:bar
+  store %ptr1 !mmra !{!"foo", !"bar"}
+  ```
 
-    These two notations can be used in this document and are strictly
-    equivalent. However, only the second version is functional.
+  These two notations can be used in this document and are strictly
+  equivalent. However, only the second version is functional.
 
 compatibility
-    Two sets of tags are said to be *compatible* iff, for every unique
-    tag prefix P present in at least one set:
 
-    - the other set contains no tag with prefix P, or
-    - at least one tag with prefix P is common to both sets.
+: Two sets of tags are said to be *compatible* iff, for every unique
+  tag prefix P present in at least one set:
 
-    The above definition implies that an empty set is always compatible
-    with any other set. This is an important property as it ensures that
-    if a transform drops the metadata on an operation, it can never affect
-    correctness. In other words, the memory model cannot be relaxed further
-    by deleting metadata from instructions.
+  - the other set contains no tag with prefix P, or
+  - at least one tag with prefix P is common to both sets.
 
-.. _HappensBefore:
+  The above definition implies that an empty set is always compatible
+  with any other set. This is an important property as it ensures that
+  if a transform drops the metadata on an operation, it can never affect
+  correctness. In other words, the memory model cannot be relaxed further
+  by deleting metadata from instructions.
 
-The *happens-before* Relation
-==============================
+(happensbefore)=
+
+## The *happens-before* Relation
 
 Compatibility checks can be used to opt out of the *happens-before* relation
 established between two instructions.
 
 Ordering
-    When two instructions' metadata are not compatible, any program order
-    between them are not in *happens-before*.
 
-    For example, consider two tags ``foo:bar`` and
-    ``foo:baz`` exposed by a target:
+: When two instructions' metadata are not compatible, any program order
+  between them are not in *happens-before*.
 
-    .. code-block::
+  For example, consider two tags `foo:bar` and
+  `foo:baz` exposed by a target:
 
-       A: store %ptr1                 # foo:bar
-       B: store %ptr2                 # foo:baz
-       X: store atomic release %ptr3  # foo:bar
+  ```
+  A: store %ptr1                 # foo:bar
+  B: store %ptr2                 # foo:baz
+  X: store atomic release %ptr3  # foo:bar
+  ```
 
-    In the above figure, ``A`` is compatible with ``X``, and hence ``A``
-    happens-before ``X``. But ``B`` is not compatible with
-    ``X``, and hence it is not happens-before ``X``.
+  In the above figure, `A` is compatible with `X`, and hence `A`
+  happens-before `X`. But `B` is not compatible with
+  `X`, and hence it is not happens-before `X`.
 
 Synchronization
-    If an synchronizing operation has one or more tags, then whether it
-    synchronizes-with and participates in the  ``seq_cst`` order with
-    other operations is target dependent.
 
-    Whether the following example synchronizes with another sequence depends
-    on the target-defined semantics of ``foo:bar`` and ``foo:bux``.
+: If an synchronizing operation has one or more tags, then whether it
+  synchronizes-with and participates in the `seq_cst` order with
+  other operations is target dependent.
 
-    .. code-block::
+  Whether the following example synchronizes with another sequence depends
+  on the target-defined semantics of `foo:bar` and `foo:bux`.
 
-       fence release               # foo:bar
-       store atomic %ptr1          # foo:bux
+  ```
+  fence release               # foo:bar
+  store atomic %ptr1          # foo:bux
+  ```
 
-Examples
---------
+### Examples
 
 Example 1:
-    .. code-block::
 
-      A: store ptr addrspace(1) %ptr2                  # sync-as:1 vulkan:nonprivate
-      B: store atomic release ptr addrspace(1) %ptr3   # sync-as:0 vulkan:nonprivate
+: ```
+  A: store ptr addrspace(1) %ptr2                  # sync-as:1 vulkan:nonprivate
+  B: store atomic release ptr addrspace(1) %ptr3   # sync-as:0 vulkan:nonprivate
+  ```
 
-    A and B are not ordered relative to each other
-    (no *happens-before*) because their sets of tags are not compatible.
+  A and B are not ordered relative to each other
+  (no *happens-before*) because their sets of tags are not compatible.
 
-    Note that the ``sync-as`` value does not have to match the ``addrspace`` value.
-    e.g. In Example 1, a store-release to a location in ``addrspace(1)`` wants to
-    only synchronize with operations happening in ``addrspace(0)``.
+  Note that the `sync-as` value does not have to match the `addrspace` value.
+  e.g. In Example 1, a store-release to a location in `addrspace(1)` wants to
+  only synchronize with operations happening in `addrspace(0)`.
 
 Example 2:
-    .. code-block::
 
-      A: store ptr addrspace(1) %ptr2                 # sync-as:1 vulkan:nonprivate
-      B: store atomic release ptr addrspace(1) %ptr3  # sync-as:1 vulkan:nonprivate
+: ```
+  A: store ptr addrspace(1) %ptr2                 # sync-as:1 vulkan:nonprivate
+  B: store atomic release ptr addrspace(1) %ptr3  # sync-as:1 vulkan:nonprivate
+  ```
 
-    The ordering of A and B is unaffected because their set of tags are
-    compatible.
+  The ordering of A and B is unaffected because their set of tags are
+  compatible.
 
-    Note that A and B may or may not be in *happens-before* due to other reasons.
+  Note that A and B may or may not be in *happens-before* due to other reasons.
 
 Example 3:
-    .. code-block::
 
-      A: store ptr addrspace(1) %ptr2                 # sync-as:1 vulkan:nonprivate
-      B: store atomic release ptr addrspace(1) %ptr3  # vulkan:nonprivate
+: ```
+  A: store ptr addrspace(1) %ptr2                 # sync-as:1 vulkan:nonprivate
+  B: store atomic release ptr addrspace(1) %ptr3  # vulkan:nonprivate
+  ```
 
-    The ordering of A and B is unaffected because their set of tags are
-    compatible.
+  The ordering of A and B is unaffected because their set of tags are
+  compatible.
 
 Example 4:
-    .. code-block::
 
-      A: store ptr addrspace(1) %ptr2                 # sync-as:1
-      B: store atomic release ptr addrspace(1) %ptr3  # sync-as:2
+: ```
+  A: store ptr addrspace(1) %ptr2                 # sync-as:1
+  B: store atomic release ptr addrspace(1) %ptr3  # sync-as:2
+  ```
 
-    A and B do not have to be ordered relative to each other
-    (no *happens-before*) because their sets of tags are not compatible.
+  A and B do not have to be ordered relative to each other
+  (no *happens-before*) because their sets of tags are not compatible.
 
-Use-cases
-=========
+## Use-cases
 
-SPIRV ``NonPrivatePointer``
----------------------------
+### SPIRV `NonPrivatePointer`
 
 MMRAs can support the SPIRV capability
-``VulkanMemoryModel``, where synchronizing operations only affect
-memory operations that specify ``NonPrivatePointer`` semantics.
+`VulkanMemoryModel`, where synchronizing operations only affect
+memory operations that specify `NonPrivatePointer` semantics.
 
 The example below is generated from a SPIRV program using the
 following recipe:
 
-- Add ``vulkan:nonprivate`` to every synchronizing operation.
-- Add ``vulkan:nonprivate`` to every non-atomic memory operation
-  that is marked ``NonPrivatePointer``.
-- Add ``vulkan:private`` to tags of every non-atomic memory operation
-  that is not marked ``NonPrivatePointer``.
-
-.. code-block::
-
-   Thread T1:
-    A: store %ptr1                 # vulkan:nonprivate
-    B: store %ptr2                 # vulkan:private
-    X: store atomic release %ptr3  # vulkan:nonprivate
-
-   Thread T2:
-    Y: load atomic acquire %ptr3   # vulkan:nonprivate
-    C: load %ptr2                  # vulkan:private
-    D: load %ptr1                  # vulkan:nonprivate
-
-Compatibility ensures that operation ``A`` is ordered
-relative to ``X`` while operation ``D`` is ordered relative to ``Y``.
-If ``X`` synchronizes with ``Y``, then ``A`` happens-before ``D``.
-No such relation can be inferred about operations ``B`` and ``C``.
-
-.. note::
-   The `Vulkan Memory Model <https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#memory-model-non-private>`_
-   considers all atomic operation non-private.
-
-   Whether ``vulkan:nonprivate`` would be specified on atomic operations is
-   an implementation detail, as an atomic operation is always ``nonprivate``.
-   The implementation may choose to be explicit and emit IR with
-   ``vulkan:nonprivate`` on every atomic operation, or it could choose to
-   only emit ``vulkan::private`` and assume ``vulkan:nonprivate``
-   by default.
-
-Operations marked with ``vulkan:private`` effectively opt out of the
+- Add `vulkan:nonprivate` to every synchronizing operation.
+- Add `vulkan:nonprivate` to every non-atomic memory operation
+  that is marked `NonPrivatePointer`.
+- Add `vulkan:private` to tags of every non-atomic memory operation
+  that is not marked `NonPrivatePointer`.
+
+```
+Thread T1:
+ A: store %ptr1                 # vulkan:nonprivate
+ B: store %ptr2                 # vulkan:private
+ X: store atomic release %ptr3  # vulkan:nonprivate
+
+Thread T2:
+ Y: load atomic acquire %ptr3   # vulkan:nonprivate
+ C: load %ptr2                  # vulkan:private
+ D: load %ptr1                  # vulkan:nonprivate
+```
+
+Compatibility ensures that operation `A` is ordered
+relative to `X` while operation `D` is ordered relative to `Y`.
+If `X` synchronizes with `Y`, then `A` happens-before `D`.
+No such relation can be inferred about operations `B` and `C`.
+
+:::{note}
+The [Vulkan Memory Model](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#memory-model-non-private)
+considers all atomic operation non-private.
+
+Whether `vulkan:nonprivate` would be specified on atomic operations is
+an implementation detail, as an atomic operation is always `nonprivate`.
+The implementation may choose to be explicit and emit IR with
+`vulkan:nonprivate` on every atomic operation, or it could choose to
+only emit `vulkan::private` and assume `vulkan:nonprivate`
+by default.
+:::
+
+Operations marked with `vulkan:private` effectively opt out of the
 happens-before order in a SPIRV program since they are incompatible
 with every synchronizing operation. Note that SPIRV operations that
-are not marked ``NonPrivatePointer`` are not entirely private to the
+are not marked `NonPrivatePointer` are not entirely private to the
 thread --- they are implicitly synchronized at the start or end of a
 thread by the Vulkan *system-synchronizes-with* relationship. This
 example assumes that the target-defined semantics of
-``vulkan:private`` correctly implements this property.
+`vulkan:private` correctly implements this property.
 
 This scheme is general enough to express the interoperability of SPIRV
 programs with other environments.
 
-.. code-block::
-
-   Thread T1:
-   A: store %ptr1                 # vulkan:nonprivate
-   X: store atomic release %ptr2  # vulkan:nonprivate
+```
+Thread T1:
+A: store %ptr1                 # vulkan:nonprivate
+X: store atomic release %ptr2  # vulkan:nonprivate
 
-   Thread T2:
-   Y: load atomic acquire %ptr2   # foo:bar
-   B: load %ptr1
+Thread T2:
+Y: load atomic acquire %ptr2   # foo:bar
+B: load %ptr1
+```
 
-In the above example, thread ``T1`` originates from a SPIRV program
-while thread ``T2`` originates from a non-SPIRV program. Whether ``X``
-can synchronize with ``Y`` is target defined.  If ``X`` synchronizes
-with ``Y``, then ``A`` happens before ``B`` (because A/X and
+In the above example, thread `T1` originates from a SPIRV program
+while thread `T2` originates from a non-SPIRV program. Whether `X`
+can synchronize with `Y` is target defined. If `X` synchronizes
+with `Y`, then `A` happens before `B` (because A/X and
 Y/B are compatible).
 
-Implementation Example
-~~~~~~~~~~~~~~~~~~~~~~
+#### Implementation Example
 
-Consider the implementation of SPIRV ``NonPrivatePointer`` on a target
+Consider the implementation of SPIRV `NonPrivatePointer` on a target
 where all memory operations are cached, and the entire cache is
-flushed or invalidated at a ``release`` or ``acquire`` respectively. A
+flushed or invalidated at a `release` or `acquire` respectively. A
 possible scheme is that when translating a SPIRV program, memory
-operations marked ``NonPrivatePointer`` should not be cached, and the
-cache contents should not be touched during an ``acquire`` and
-``release`` operation.
+operations marked `NonPrivatePointer` should not be cached, and the
+cache contents should not be touched during an `acquire` and
+`release` operation.
 
-This could be implemented using the tags that share the ``vulkan:`` prefix,
+This could be implemented using the tags that share the `vulkan:` prefix,
 as follows:
 
 - For memory operations:
 
-  - Operations with ``vulkan:nonprivate`` should bypass the cache.
-  - Operations with ``vulkan:private`` should be cached.
+  - Operations with `vulkan:nonprivate` should bypass the cache.
+  - Operations with `vulkan:private` should be cached.
   - Operations that specify neither or both should conservatively
     bypass the cache to ensure correctness.
 
 - For synchronizing operations:
 
-  - Operations with ``vulkan:nonprivate`` should not flush or
+  - Operations with `vulkan:nonprivate` should not flush or
     invalidate the cache.
-  - Operations with ``vulkan:private`` should flush or invalidate the cache.
+  - Operations with `vulkan:private` should flush or invalidate the cache.
   - Operations that specify neither or both should conservatively
     flush or invalidate the cache to ensure correctness.
 
-.. note::
-   In such an implementation, dropping the metadata on an operation, while
-   not affecting correctness, may have big performance implications.
-   e.g. an operation bypasses the cache when it shouldn't.
+:::{note}
+In such an implementation, dropping the metadata on an operation, while
+not affecting correctness, may have big performance implications.
+e.g. an operation bypasses the cache when it shouldn't.
+:::
 
-Memory Types
-------------
+### Memory Types
 
 MMRAs may express the selective synchronization of
 different memory types.
 
-As an example, a target may expose an ``sync-as:<N>`` tag to
+As an example, a target may expose an `sync-as:<N>` tag to
 pass information about which address spaces are synchronized by the
 execution of a synchronizing operation.
 
-.. note::
-  Address spaces are used here as a common example, but this concept
-  can apply for other "memory types". What "memory types" means here is
-  up to the target.
-
-.. code-block::
-
-   # let 1 = global address space
-   # let 3 = local address space
-
-   Thread T1:
-   A: store %ptr1                                  # sync-as:1
-   B: store %ptr2                                  # sync-as:3
-   X: store atomic release ptr addrspace(0) %ptr3  # sync-as:3
-
-   Thread T2:
-   Y: load atomic acquire ptr addrspace(0) %ptr3   # sync-as:3
-   C: load %ptr2                                   # sync-as:3
-   D: load %ptr1                                   # sync-as:1
-
-In the above figure, ``X`` and ``Y`` are atomic operations on a
-location in the ``global``  address space. If ``X`` synchronizes with
-``Y``, then ``B`` happens-before ``C`` in the ``local`` address
-space. But no such statement can be made about operations ``A`` and
-``D``, although they are performed on a location in the ``global``
+:::{note}
+Address spaces are used here as a common example, but this concept
+can apply for other "memory types". What "memory types" means here is
+up to the target.
+:::
+
+```
+# let 1 = global address space
+# let 3 = local address space
+
+Thread T1:
+A: store %ptr1                                  # sync-as:1
+B: store %ptr2                                  # sync-as:3
+X: store atomic release ptr addrspace(0) %ptr3  # sync-as:3
+
+Thread T2:
+Y: load atomic acquire ptr addrspace(0) %ptr3   # sync-as:3
+C: load %ptr2                                   # sync-as:3
+D: load %ptr1                                   # sync-as:1
+```
+
+In the above figure, `X` and `Y` are atomic operations on a
+location in the `global` address space. If `X` synchronizes with
+`Y`, then `B` happens-before `C` in the `local` address
+space. But no such statement can be made about operations `A` and
+`D`, although they are performed on a location in the `global`
 address space.
 
-Implementation Example: Adding Address Space Information to Fences
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Implementation Example: Adding Address Space Information to Fences
 
 Languages such as OpenCL C provide fence operations such as
-``atomic_work_item_fence`` that can take an explicit address
+`atomic_work_item_fence` that can take an explicit address
 space to fence.
 
 By default, LLVM has no means to carry that information in the IR, so
@@ -354,28 +358,26 @@ performance impact in high-performance applications.
 
 MMRAs may be used to preserve that information at the IR level, all the
 way through code generation. For example, a fence that only affects the
-global address space ``addrspace(1)`` may be lowered as
-
-.. code-block::
+global address space `addrspace(1)` may be lowered as
 
-    fence release # sync-as:1
+```
+fence release # sync-as:1
+```
 
-and the target may use the presence of ``sync-as:1`` to infer that it
+and the target may use the presence of `sync-as:1` to infer that it
 must only emit instruction to fence the global address space.
 
 Note that as MMRAs are opt in, a fence that does not have MMRA metadata
 could still be lowered conservatively, so this optimization would only
 apply if the front-end emits the MMRA metadata on the fence instructions.
 
-Additional Topics
-=================
+## Additional Topics
 
-.. note::
+:::{note}
+The following sections are informational.
+:::
 
-  The following sections are informational.
-
-Performance Impact
-------------------
+### Performance Impact
 
 MMRAs are a way to capture optimization opportunities in the program.
 But when an operation mentions no tags or conflicting tags,
@@ -391,10 +393,9 @@ Note that targets can always choose to ignore (or even drop) MMRAs
 and revert to the default behavior/codegen heuristics without
 affecting correctness.
 
-Consequences of the Absence of *happens-before*
------------------------------------------------
+### Consequences of the Absence of *happens-before*
 
-In the :ref:`happens-before<HappensBefore>` section, we defined how an
+In the {ref}`happens-before<HappensBefore>` section, we defined how an
 *happens-before* relation between two instruction can be broken
 by leveraging compatibility between MMRAs. When the instructions
 are incompatible and there is no *happens-before* relation, we say
@@ -422,8 +423,7 @@ In the absence of *happens-before*, there is no such requirement and
 no waiting or flushing is required. This may noticeably speed up
 execution in some cases.
 
-Combining Operations
---------------------
+### Combining Operations
 
 If a pass can combine multiple memory or synchronizing operations
 into one, it needs to be able to combine MMRAs. One possible way to
@@ -432,9 +432,9 @@ achieve this is by doing a prefix-wise union of the tag sets.
 Let A and B be two tags set, and U be the prefix-wise union of A and B.
 For every unique tag prefix P present in A or B:
 
-* If either A or B has no tags with prefix P, no tags with prefix
+- If either A or B has no tags with prefix P, no tags with prefix
   P are added to U.
-* If both A and B have at least one tag with prefix P, all tags with prefix
+- If both A and B have at least one tag with prefix P, all tags with prefix
   P from both sets are added to U.
 
 Passes should avoid aggressively combining MMRAs, as this can result
@@ -449,31 +449,32 @@ of combining the MMRAs can use the prefix-wise union described above.
 
 Examples:
 
-.. code-block::
-
-    A: store release %ptr1  # foo:x, foo:y, bar:x
-    B: store release %ptr2  # foo:x, bar:y
-
-    # Unique prefixes P = [foo, bar]
-    # "foo:x" is common to A and B so it's added to U.
-    # "bar:x" != "bar:y" so it's not added to U.
-    U: store release %ptr3  # foo:x
+```
+A: store release %ptr1  # foo:x, foo:y, bar:x
+B: store release %ptr2  # foo:x, bar:y
 
-.. code-block::
+# Unique prefixes P = [foo, bar]
+# "foo:x" is common to A and B so it's added to U.
+# "bar:x" != "bar:y" so it's not added to U.
+U: store release %ptr3  # foo:x
+```
 
-    A: store release %ptr1  # foo:x, foo:y
-    B: store release %ptr2  # foo:x, bux:y
+```
+A: store release %ptr1  # foo:x, foo:y
+B: store release %ptr2  # foo:x, bux:y
 
-    # Unique prefixes P = [foo, bux]
-    # "foo:x" is common to A and B so it's added to U.
-    # No tags have the prefix "bux" in A.
-    U: store release %ptr3  # foo:x
+# Unique prefixes P = [foo, bux]
+# "foo:x" is common to A and B so it's added to U.
+# No tags have the prefix "bux" in A.
+U: store release %ptr3  # foo:x
+```
 
-.. code-block::
+```
+A: store release %ptr1
+B: store release %ptr2  # foo:x, bar:y
 
-    A: store release %ptr1
-    B: store release %ptr2  # foo:x, bar:y
+# Unique prefixes P = [foo, bar]
+# No tags with "foo" or "bar" in A, so no tags added.
+U: store release %ptr3
+```
 
-    # Unique prefixes P = [foo, bar]
-    # No tags with "foo" or "bar" in A, so no tags added.
-    U: store release %ptr3
diff --git a/llvm/docs/PCSectionsMetadata.md b/llvm/docs/PCSectionsMetadata.md
index 222fa0726a0b0..22b29f43af29a 100644
--- a/llvm/docs/PCSectionsMetadata.md
+++ b/llvm/docs/PCSectionsMetadata.md
@@ -1,126 +1,113 @@
-=========================
-LLVM PC Sections Metadata
-=========================
+# LLVM PC Sections Metadata
 
-
-Introduction
-============
+## Introduction
 
 PC Sections Metadata can be attached to instructions and functions, for which
 addresses, viz. program counters (PCs), are to be emitted in specially encoded
-binary sections. Metadata is assigned as an ``MDNode`` of the ``MD_pcsections``
-(``!pcsections``) kind; the following section describes the metadata format.
+binary sections. Metadata is assigned as an `MDNode` of the `MD_pcsections`
+(`!pcsections`) kind; the following section describes the metadata format.
 
-Metadata Format
-===============
+## Metadata Format
 
-An arbitrary number of interleaved ``MDString`` and constant operators can be
-added, where a new ``MDString`` always denotes a section name, followed by an
+An arbitrary number of interleaved `MDString` and constant operators can be
+added, where a new `MDString` always denotes a section name, followed by an
 arbitrary number of auxiliary constant data encoded along the PC of the
-instruction or function. The first operator must be a ``MDString`` denoting the
+instruction or function. The first operator must be a `MDString` denoting the
 first section.
 
-.. code-block:: none
-
-  !0 = !{
-    !"<section#1>"
-    [ , !1 ... ]
-    [ !"<section#2">
-      [ , !2 ... ]
-      ... ]
-  }
-  !1 = !{ iXX <aux-consts#1>, ... }
-  !2 = !{ iXX <aux-consts#2>, ... }
-  ...
-
-The occurrence of ``section#1``, ``section#2``, ..., ``section#N`` in the
+```none
+!0 = !{
+  !"<section#1>"
+  [ , !1 ... ]
+  [ !"<section#2">
+    [ , !2 ... ]
+    ... ]
+}
+!1 = !{ iXX <aux-consts#1>, ... }
+!2 = !{ iXX <aux-consts#2>, ... }
+...
+```
+
+The occurrence of `section#1`, `section#2`, ..., `section#N` in the
 metadata causes the backend to emit the PC for the associated instruction or
 function to all named sections. For each emitted PC in a section #N, the
-constants ``aux-consts#N`` in the tuple ``!N`` will be emitted after the PC.
+constants `aux-consts#N` in the tuple `!N` will be emitted after the PC.
 Multiple tuples with constant data may be provided after a section name string
-(e.g. ``!0 = !{"s1", !1, !2}``), and a single constant tuple may be reused for
-different sections (e.g. ``!0 = !{"s1", !1, "s2", !1}``).
+(e.g. `!0 = !{"s1", !1, !2}`), and a single constant tuple may be reused for
+different sections (e.g. `!0 = !{"s1", !1, "s2", !1}`).
 
-Binary Encoding
-===============
+## Binary Encoding
 
 *Instructions* result in emitting a single PC, and *functions* result in
 emission of the start of the function and a 32-bit size. This is followed by
 the auxiliary constants that followed the respective section name in the
-``MD_pcsections`` metadata.
+`MD_pcsections` metadata.
 
-To avoid relocations in the final binary, each PC address stored at ``entry``
-is a relative relocation, computed as ``pc - entry``. To decode, a user has to
-compute ``entry + *entry``.
+To avoid relocations in the final binary, each PC address stored at `entry`
+is a relative relocation, computed as `pc - entry`. To decode, a user has to
+compute `entry + *entry`.
 
 The size of each entry depends on the code model. With large and medium sized
 code models, the entry size matches pointer size. For any smaller code model
 the entry size is just 32 bits.
 
-Encoding Options
-----------------
+### Encoding Options
 
-Optional encoding options can be passed in the first ``MDString`` operator:
-``<section>!<options>``. The following options are available:
+Optional encoding options can be passed in the first `MDString` operator:
+`<section>!<options>`. The following options are available:
 
-    * ``C`` -- Compress constant integers of size 2-8 bytes as ULEB128; this
-      includes the function size (but excludes the PC entry).
+> - `C` -- Compress constant integers of size 2-8 bytes as ULEB128; this
+>   includes the function size (but excludes the PC entry).
 
-For example, ``foo!C`` will emit into section ``foo`` with all constants
+For example, `foo!C` will emit into section `foo` with all constants
 encoded as ULEB128.
 
-Guarantees on Code Generation
-=============================
+## Guarantees on Code Generation
 
-Attaching ``!pcsections`` metadata to LLVM IR instructions *shall not* affect
+Attaching `!pcsections` metadata to LLVM IR instructions *shall not* affect
 optimizations or code generation outside the requested PC sections.
 
 While relying on LLVM IR metadata to request PC sections makes the above
 guarantee relatively trivial, propagation of metadata through the optimization
 and code generation pipeline has the following guarantees.
 
-Metadata Propagation
---------------------
+### Metadata Propagation
 
 In general, LLVM *does not make any guarantees* about preserving IR metadata
-(attached to an ``Instruction``) through IR transformations. When using PC
-sections metadata, this guarantee is unchanged, and ``!pcsections`` metadata is
+(attached to an `Instruction`) through IR transformations. When using PC
+sections metadata, this guarantee is unchanged, and `!pcsections` metadata is
 remains *optional* until lowering to machine IR (MIR).
 
-Note for Code Generation
-------------------------
+### Note for Code Generation
 
 As with other LLVM IR metadata, there are no requirements for LLVM IR
-transformation passes to preserve ``!pcsections`` metadata, with the following
+transformation passes to preserve `!pcsections` metadata, with the following
 exceptions:
 
-    * The ``AtomicExpandPass`` shall preserve ``!pcsections`` metadata
-      according to the below rules 1-4.
+> - The `AtomicExpandPass` shall preserve `!pcsections` metadata
+>   according to the below rules 1-4.
 
-When translating LLVM IR to MIR, the ``!pcsections`` metadata shall be copied
-from the source ``Instruction`` to the target ``MachineInstr`` (set with
-``MachineInstr::setPCSections()``). The instruction selectors and MIR
+When translating LLVM IR to MIR, the `!pcsections` metadata shall be copied
+from the source `Instruction` to the target `MachineInstr` (set with
+`MachineInstr::setPCSections()`). The instruction selectors and MIR
 optimization passes shall preserve PC sections metadata as follows:
 
-    1. Replacements will preserve PC sections metadata of the replaced
-       instruction.
-
-    2. Duplications will preserve PC sections metadata of the copied
-       instruction.
+> 1. Replacements will preserve PC sections metadata of the replaced
+>    instruction.
+> 2. Duplications will preserve PC sections metadata of the copied
+>    instruction.
+> 3. Merging will preserve PC sections metadata of one of the two
+>    instructions (no guarantee on which instruction's metadata is used).
+> 4. Deletions will lose PC sections metadata.
 
-    3. Merging will preserve PC sections metadata of one of the two
-       instructions (no guarantee on which instruction's metadata is used).
+This is similar to debug info, and the `BuildMI()` helper provides a
+convenient way to propagate debug info and `!pcsections` metadata in the
+`MIMetadata` bundle.
 
-    4. Deletions will lose PC sections metadata.
+### Note for Metadata Users
 
-This is similar to debug info, and the ``BuildMI()`` helper provides a
-convenient way to propagate debug info and ``!pcsections`` metadata in the
-``MIMetadata`` bundle.
-
-Note for Metadata Users
------------------------
-
-Use cases for ``!pcsections`` metadata should either be fully tolerant to
-missing metadata, or the passes inserting ``!pcsections`` metadata should run
+Use cases for `!pcsections` metadata should either be fully tolerant to
+missing metadata, or the passes inserting `!pcsections` metadata should run
 *after* all LLVM IR optimization passes to preserve the metadata until being
 translated to MIR.
+
diff --git a/llvm/docs/Projects.md b/llvm/docs/Projects.md
index db15bba4b87de..0896364892227 100644
--- a/llvm/docs/Projects.md
+++ b/llvm/docs/Projects.md
@@ -1,255 +1,241 @@
-========================
-Creating an LLVM Project
-========================
+# Creating an LLVM Project
 
-
-Overview
-========
+## Overview
 
 The LLVM build system is designed to facilitate the building of third party
-projects that use LLVM header files, libraries, and tools.  In order to use
-these facilities, a ``Makefile`` from a project must do the following things:
+projects that use LLVM header files, libraries, and tools. In order to use
+these facilities, a `Makefile` from a project must do the following things:
 
-* Set ``make`` variables. There are several variables that a ``Makefile`` needs
+- Set `make` variables. There are several variables that a `Makefile` needs
   to set to use the LLVM build system:
 
-  * ``PROJECT_NAME`` - The name by which your project is known.
-  * ``LLVM_SRC_ROOT`` - The root of the LLVM source tree.
-  * ``LLVM_OBJ_ROOT`` - The root of the LLVM object tree.
-  * ``PROJ_SRC_ROOT`` - The root of the project's source tree.
-  * ``PROJ_OBJ_ROOT`` - The root of the project's object tree.
-  * ``PROJ_INSTALL_ROOT`` - The root installation directory.
-  * ``LEVEL`` - The relative path from the current directory to the
-    project's root ``($PROJ_OBJ_ROOT)``.
+  - `PROJECT_NAME` - The name by which your project is known.
+  - `LLVM_SRC_ROOT` - The root of the LLVM source tree.
+  - `LLVM_OBJ_ROOT` - The root of the LLVM object tree.
+  - `PROJ_SRC_ROOT` - The root of the project's source tree.
+  - `PROJ_OBJ_ROOT` - The root of the project's object tree.
+  - `PROJ_INSTALL_ROOT` - The root installation directory.
+  - `LEVEL` - The relative path from the current directory to the
+    project's root `($PROJ_OBJ_ROOT)`.
 
-* Include ``Makefile.config`` from ``$(LLVM_OBJ_ROOT)``.
+- Include `Makefile.config` from `$(LLVM_OBJ_ROOT)`.
 
-* Include ``Makefile.rules`` from ``$(LLVM_SRC_ROOT)``.
+- Include `Makefile.rules` from `$(LLVM_SRC_ROOT)`.
 
 There are two ways that you can set all of these variables:
 
-* You can write your own ``Makefiles`` which hard-code these values.
-
-* You can use the pre-made LLVM sample project. This sample project includes
-  ``Makefiles``, a configure script that can be used to configure the location
+- You can write your own `Makefiles` which hard-code these values.
+- You can use the pre-made LLVM sample project. This sample project includes
+  `Makefiles`, a configure script that can be used to configure the location
   of LLVM, and the ability to support multiple object directories from a single
   source directory.
 
 If you want to devise your own build system, studying other projects and LLVM
-``Makefiles`` will probably provide enough information on how to write your own
-``Makefiles``.
+`Makefiles` will probably provide enough information on how to write your own
+`Makefiles`.
 
-Source Tree Layout
-==================
+## Source Tree Layout
 
 In order to use the LLVM build system, you will want to organize your source
-code so that it can benefit from the build system's features.  Mainly, you want
+code so that it can benefit from the build system's features. Mainly, you want
 your source tree layout to look similar to the LLVM source tree layout.
 
 Underneath your top level directory, you should have the following directories:
 
 **lib**
 
-    This subdirectory should contain all of your library source code.  For each
-    library that you build, you will have one directory in **lib** that will
-    contain that library's source code.
-
-    Libraries can be object files, archives, or dynamic libraries.  The **lib**
-    directory is just a convenient place for libraries as it places them all in
-    a directory from which they can be linked later.
+> This subdirectory should contain all of your library source code. For each
+> library that you build, you will have one directory in **lib** that will
+> contain that library's source code.
+>
+> Libraries can be object files, archives, or dynamic libraries. The **lib**
+> directory is just a convenient place for libraries as it places them all in
+> a directory from which they can be linked later.
 
 **include**
 
-    This subdirectory should contain any header files that are global to your
-    project. By global, we mean that they are used by more than one library or
-    executable of your project.
-
-    By placing your header files in **include**, they will be found
-    automatically by the LLVM build system.  For example, if you have a file
-    **include/jazz/note.h**, then your source files can include it simply with
-    **#include "jazz/note.h"**.
+> This subdirectory should contain any header files that are global to your
+> project. By global, we mean that they are used by more than one library or
+> executable of your project.
+>
+> By placing your header files in **include**, they will be found
+> automatically by the LLVM build system. For example, if you have a file
+> **include/jazz/note.h**, then your source files can include it simply with
+> **#include "jazz/note.h"**.
 
 **tools**
 
-    This subdirectory should contain all of your source code for executables.
-    For each program that you build, you will have one directory in **tools**
-    that will contain that program's source code.
+> This subdirectory should contain all of your source code for executables.
+> For each program that you build, you will have one directory in **tools**
+> that will contain that program's source code.
 
 **test**
 
-    This subdirectory should contain tests that verify that your code works
-    correctly.  Automated tests are especially useful.
-
-    Currently, the LLVM build system provides basic support for tests. The LLVM
-    system provides the following:
+> This subdirectory should contain tests that verify that your code works
+> correctly. Automated tests are especially useful.
+>
+> Currently, the LLVM build system provides basic support for tests. The LLVM
+> system provides the following:
 
-* LLVM contains regression tests in ``llvm/test``.  These tests are run by the
-  :doc:`Lit <CommandGuide/lit>` testing tool.  This test procedure uses ``RUN``
-  lines in the actual test case to determine how to run the test.  See the
-  :doc:`TestingGuide` for more details.
+- LLVM contains regression tests in `llvm/test`. These tests are run by the
+  {doc}`Lit <CommandGuide/lit>` testing tool. This test procedure uses `RUN`
+  lines in the actual test case to determine how to run the test. See the
+  {doc}`TestingGuide` for more details.
 
-* LLVM contains an optional package called ``llvm-test``, which provides
+- LLVM contains an optional package called `llvm-test`, which provides
   benchmarks and programs that are known to compile with the Clang front
   end. You can use these programs to test your code, gather statistical
   information, and compare it to the current LLVM performance statistics.
 
-  Currently, there is no way to hook your tests directly into the ``llvm/test``
+  Currently, there is no way to hook your tests directly into the `llvm/test`
   testing harness. You will simply need to find a way to use the source
   provided within that directory on your own.
 
 Typically, you will want to build your **lib** directory first followed by your
 **tools** directory.
 
-Writing LLVM Style Makefiles
-============================
+## Writing LLVM Style Makefiles
 
 The LLVM build system provides a convenient way to build libraries and
-executables.  Most of your project Makefiles will only need to define a few
-variables.  Below is a list of the variables one can set and what they can
+executables. Most of your project Makefiles will only need to define a few
+variables. Below is a list of the variables one can set and what they can
 do:
 
-Required Variables
-------------------
-
-``LEVEL``
+### Required Variables
 
-    This variable is the relative path from this ``Makefile`` to the top
-    directory of your project's source code.  For example, if your source code
-    is in ``/tmp/src``, then the ``Makefile`` in ``/tmp/src/jump/high``
-    would set ``LEVEL`` to ``"../.."``.
+`LEVEL`
 
-Variables for Building Subdirectories
--------------------------------------
+> This variable is the relative path from this `Makefile` to the top
+> directory of your project's source code. For example, if your source code
+> is in `/tmp/src`, then the `Makefile` in `/tmp/src/jump/high`
+> would set `LEVEL` to `"../.."`.
 
-``DIRS``
+### Variables for Building Subdirectories
 
-    This is a space separated list of subdirectories that should be built.  They
-    will be built, one at a time, in the order specified.
+`DIRS`
 
-``PARALLEL_DIRS``
+> This is a space separated list of subdirectories that should be built. They
+> will be built, one at a time, in the order specified.
 
-    This is a list of directories that can be built in parallel. These will be
-    built after the directories in DIRS have been built.
+`PARALLEL_DIRS`
 
-``OPTIONAL_DIRS``
+> This is a list of directories that can be built in parallel. These will be
+> built after the directories in DIRS have been built.
 
-    This is a list of directories that can be built if they exist, but will not
-    cause an error if they do not exist.  They are built serially in the order
-    in which they are listed.
+`OPTIONAL_DIRS`
 
-Variables for Building Libraries
---------------------------------
+> This is a list of directories that can be built if they exist, but will not
+> cause an error if they do not exist. They are built serially in the order
+> in which they are listed.
 
-``LIBRARYNAME``
+### Variables for Building Libraries
 
-    This variable contains the base name of the library that will be built.  For
-    example, to build a library named ``libsample.a``, ``LIBRARYNAME`` should
-    be set to ``sample``.
+`LIBRARYNAME`
 
-``BUILD_ARCHIVE``
+> This variable contains the base name of the library that will be built. For
+> example, to build a library named `libsample.a`, `LIBRARYNAME` should
+> be set to `sample`.
 
-    By default, a library is a ``.o`` file that is linked directly into a
-    program.  To build an archive (also known as a static library), set the
-    ``BUILD_ARCHIVE`` variable.
+`BUILD_ARCHIVE`
 
-``SHARED_LIBRARY``
+> By default, a library is a `.o` file that is linked directly into a
+> program. To build an archive (also known as a static library), set the
+> `BUILD_ARCHIVE` variable.
 
-    If ``SHARED_LIBRARY`` is defined in your Makefile, a shared (or dynamic)
-    library will be built.
+`SHARED_LIBRARY`
 
-Variables for Building Programs
--------------------------------
+> If `SHARED_LIBRARY` is defined in your Makefile, a shared (or dynamic)
+> library will be built.
 
-``TOOLNAME``
+### Variables for Building Programs
 
-    This variable contains the name of the program that will be built.  For
-    example, to build an executable named ``sample``, ``TOOLNAME`` should be set
-    to ``sample``.
+`TOOLNAME`
 
-``USEDLIBS``
+> This variable contains the name of the program that will be built. For
+> example, to build an executable named `sample`, `TOOLNAME` should be set
+> to `sample`.
 
-    This variable holds a space separated list of libraries that should be
-    linked into the program.  These libraries must be libraries that come from
-    your **lib** directory.  The libraries must be specified without their
-    ``lib`` prefix.  For example, to link ``libsample.a``, you would set
-    ``USEDLIBS`` to ``sample.a``.
+`USEDLIBS`
 
-    Note that this works only for statically linked libraries.
+> This variable holds a space separated list of libraries that should be
+> linked into the program. These libraries must be libraries that come from
+> your **lib** directory. The libraries must be specified without their
+> `lib` prefix. For example, to link `libsample.a`, you would set
+> `USEDLIBS` to `sample.a`.
+>
+> Note that this works only for statically linked libraries.
 
-``LLVMLIBS``
+`LLVMLIBS`
 
-    This variable holds a space separated list of libraries that should be
-    linked into the program.  These libraries must be LLVM libraries.  The
-    libraries must be specified without their ``lib`` prefix.  For example, to
-    link with a driver that performs an IR transformation you might set
-    ``LLVMLIBS`` to this minimal set of libraries ``LLVMSupport.a LLVMCore.a
-    LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a
-    LLVMScalarOpts.a LLVMTarget.a``.
+> This variable holds a space separated list of libraries that should be
+> linked into the program. These libraries must be LLVM libraries. The
+> libraries must be specified without their `lib` prefix. For example, to
+> link with a driver that performs an IR transformation you might set
+> `LLVMLIBS` to this minimal set of libraries `LLVMSupport.a LLVMCore.a
+> LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a
+> LLVMScalarOpts.a LLVMTarget.a`.
+>
+> Note that this works only for statically linked libraries. LLVM is split
+> into a large number of static libraries, and the list of libraries you
+> require may be much longer than the list above. To see a full list of
+> libraries use: `llvm-config --libs all`. Using `LINK_COMPONENTS` as
+> described below, obviates the need to set `LLVMLIBS`.
 
-    Note that this works only for statically linked libraries. LLVM is split
-    into a large number of static libraries, and the list of libraries you
-    require may be much longer than the list above. To see a full list of
-    libraries use: ``llvm-config --libs all``.  Using ``LINK_COMPONENTS`` as
-    described below, obviates the need to set ``LLVMLIBS``.
+`LINK_COMPONENTS`
 
-``LINK_COMPONENTS``
+> This variable holds a space separated list of components that the LLVM
+> `Makefiles` pass to the `llvm-config` tool to generate a link line for
+> the program. For example, to link with all LLVM libraries use
+> `LINK_COMPONENTS = all`.
 
-    This variable holds a space separated list of components that the LLVM
-    ``Makefiles`` pass to the ``llvm-config`` tool to generate a link line for
-    the program. For example, to link with all LLVM libraries use
-    ``LINK_COMPONENTS = all``.
+`LIBS`
 
-``LIBS``
+> To link dynamic libraries, add `-l<library base name>` to the `LIBS`
+> variable. The LLVM build system will look in the same places for dynamic
+> libraries as it does for static libraries.
+>
+> For example, to link `libsample.so`, you would have the following line in
+> your `Makefile`:
+>
+> > ```makefile
+> > LIBS += -lsample
+> > ```
 
-    To link dynamic libraries, add ``-l<library base name>`` to the ``LIBS``
-    variable.  The LLVM build system will look in the same places for dynamic
-    libraries as it does for static libraries.
+Note that `LIBS` must occur in the Makefile after the inclusion of
+`Makefile.common`.
 
-    For example, to link ``libsample.so``, you would have the following line in
-    your ``Makefile``:
+### Miscellaneous Variables
 
-        .. code-block:: makefile
+`CFLAGS` & `CPPFLAGS`
 
-          LIBS += -lsample
+> This variable can be used to add options to the C and C++ compiler,
+> respectively. It is typically used to add options that tell the compiler
+> the location of additional directories to search for header files.
+>
+> It is highly suggested that you append to `CFLAGS` and `CPPFLAGS` as
+> opposed to overwriting them. The LLVM `Makefiles` may already have
+> useful options in them that you may not want to overwrite.
 
-Note that ``LIBS`` must occur in the Makefile after the inclusion of
-``Makefile.common``.
-
-Miscellaneous Variables
------------------------
-
-``CFLAGS`` & ``CPPFLAGS``
-
-    This variable can be used to add options to the C and C++ compiler,
-    respectively.  It is typically used to add options that tell the compiler
-    the location of additional directories to search for header files.
-
-    It is highly suggested that you append to ``CFLAGS`` and ``CPPFLAGS`` as
-    opposed to overwriting them.  The LLVM ``Makefiles`` may already have
-    useful options in them that you may not want to overwrite.
-
-Placement of Object Code
-========================
+## Placement of Object Code
 
 The final location of built libraries and executables will depend upon whether
-you do a ``Debug``, ``Release``, or ``Profile`` build.
+you do a `Debug`, `Release`, or `Profile` build.
 
 Libraries
 
-    All libraries (static and dynamic) will be stored in
-    ``PROJ_OBJ_ROOT/<type>/lib``, where *type* is ``Debug``, ``Release``, or
-    ``Profile`` for a debug, optimized, or profiled build, respectively.
+> All libraries (static and dynamic) will be stored in
+> `PROJ_OBJ_ROOT/<type>/lib`, where *type* is `Debug`, `Release`, or
+> `Profile` for a debug, optimized, or profiled build, respectively.
 
 Executables
 
-    All executables will be stored in ``PROJ_OBJ_ROOT/<type>/bin``, where *type*
-    is ``Debug``, ``Release``, or ``Profile`` for a debug, optimized, or
-    profiled build, respectively.
+> All executables will be stored in `PROJ_OBJ_ROOT/<type>/bin`, where *type*
+> is `Debug`, `Release`, or `Profile` for a debug, optimized, or
+> profiled build, respectively.
 
-Further Help
-============
+## Further Help
 
 If you have any questions or need any help creating an LLVM project, the LLVM
-team would be more than happy to help.  You can always post your questions to
-the `Discourse forums
-<https://discourse.llvm.org>`_.
+team would be more than happy to help. You can always post your questions to
+the [Discourse forums](https://discourse.llvm.org).
+
diff --git a/llvm/docs/Proposals/GitHubMove.md b/llvm/docs/Proposals/GitHubMove.md
index 76a871af3559e..100e38c24b8fb 100644
--- a/llvm/docs/Proposals/GitHubMove.md
+++ b/llvm/docs/Proposals/GitHubMove.md
@@ -1,25 +1,19 @@
-==============================
-Moving LLVM Projects to GitHub
-==============================
+# Moving LLVM Projects to GitHub
 
-Current Status
-==============
+## Current Status
 
-We are planning to complete the transition to GitHub by Oct 21, 2019.  See
-the GitHub migration `status page <https://llvm.org/GitHubMigrationStatus.html>`_
+We are planning to complete the transition to GitHub by Oct 21, 2019. See
+the GitHub migration [status page](https://llvm.org/GitHubMigrationStatus.html)
 for the latest updates and instructions for how to migrate your workflows.
 
-
-Introduction
-============
+## Introduction
 
 This is a proposal to move our current revision control system from our own
 hosted Subversion to GitHub. Below are the financial and technical arguments as
 to why we are proposing such a move and how people (and validation
 infrastructure) will continue to work with a Git-based LLVM.
 
-What This Proposal is *Not* About
-=================================
+## What This Proposal is *Not* About
 
 Changing the development policy.
 
@@ -31,11 +25,9 @@ Contributors will continue to earn commit access on demand under the Developer
 Policy, except that that a GitHub account will be required instead of SVN
 username/password-hash.
 
-Why Git, and Why GitHub?
-========================
+## Why Git, and Why GitHub?
 
-Why Move At All?
-----------------
+### Why Move At All?
 
 This discussion began because we currently host our own Subversion server
 and Git mirror on a voluntary basis. The LLVM Foundation sponsors the server and
@@ -50,8 +42,7 @@ We should take advantage of one of the services out there (GitHub, GitLab,
 and BitBucket, among others) that offer better service (24/7 stability, disk
 space, Git server, code browsing, forking facilities, etc) for free.
 
-Why Git?
---------
+### Why Git?
 
 Many new coders nowadays start with Git, and a lot of people have never used
 SVN, CVS, or anything else. Websites like GitHub have changed the landscape
@@ -64,19 +55,18 @@ through the Git-SVN integration.
 
 Git allows you to:
 
-* Commit, squash, merge, and fork locally without touching the remote server.
-* Maintain local branches, enabling multiple threads of development.
-* Collaborate on these branches (e.g. through your own fork of llvm on GitHub).
-* Inspect the repository history (blame, log, bisect) without Internet access.
-* Maintain remote forks and branches on Git hosting services and
+- Commit, squash, merge, and fork locally without touching the remote server.
+- Maintain local branches, enabling multiple threads of development.
+- Collaborate on these branches (e.g. through your own fork of llvm on GitHub).
+- Inspect the repository history (blame, log, bisect) without Internet access.
+- Maintain remote forks and branches on Git hosting services and
   integrate back to the main repository.
 
 In addition, because Git seems to be replacing many OSS projects' version
 control systems, there are many tools that are built over Git.
 Future tooling may support Git first (if not only).
 
-Why GitHub?
------------
+### Why GitHub?
 
 GitHub, like GitLab and BitBucket, provides free code hosting for open source
 projects. Any of these could replace the code-hosting infrastructure that we
@@ -87,15 +77,14 @@ distribute the contents of the repositories depending on region and load.
 
 GitHub has one important advantage over GitLab and
 BitBucket: it offers read-write **SVN** access to the repository
-(https://github.com/blog/626-announcing-svn-support).
+(<https://github.com/blog/626-announcing-svn-support>).
 This would enable people to continue working post-migration as though our code
 were still canonically in an SVN repository.
 
 In addition, there are already multiple LLVM mirrors on GitHub, indicating that
 part of our community has already settled there.
 
-On Managing Revision Numbers with Git
--------------------------------------
+### On Managing Revision Numbers with Git
 
 The current SVN repository hosts all the LLVM sub-projects alongside each other.
 A single revision number (e.g. r123456) thus identifies a consistent version of
@@ -109,17 +98,17 @@ past discussions about Git:
 
 - "The 'branch' I most care about is mainline, and losing the ability to say
   'fixed in r1234' (with some sort of monotonically increasing number) would
-  be a tragic loss." [LattnerRevNum]_
+  be a tragic loss." [^cite_lattnerrevnum]
 - "I like those results sorted by time and the chronology should be obvious, but
   timestamps are incredibly cumbersome and make it difficult to verify that a
-  given checkout matches a given set of results." [TrickRevNum]_
+  given checkout matches a given set of results." [^cite_trickrevnum]
 - "There is still the major regression with unreadable version numbers.
   Given the amount of Bugzilla traffic with 'Fixed in...', that's a
-  non-trivial issue." [JSonnRevNum]_
-- "Sequential IDs are important for LNT and llvmlab bisection tool." [MatthewsRevNum]_.
+  non-trivial issue." [^cite_jsonnrevnum]
+- "Sequential IDs are important for LNT and llvmlab bisection tool." [^cite_matthewsrevnum].
 
 However, Git can emulate this increasing revision number:
-``git rev-list --count <commit-hash>``. This identifier is unique only
+`git rev-list --count <commit-hash>`. This identifier is unique only
 within a single branch, but this means the tuple `(num, branch-name)` uniquely
 identifies a commit.
 
@@ -127,35 +116,31 @@ We can thus use this revision number to ensure that e.g. `clang -v` reports a
 user-friendly revision number (e.g. `main-12345` or `4.0-5321`), addressing
 the objections raised above with respect to this aspect of Git.
 
-What About Branches and Merges?
--------------------------------
+### What About Branches and Merges?
 
 In contrast to SVN, Git makes branching easy. Git's commit history is
 represented as a DAG, a departure from SVN's linear history. However, we propose
 to mandate making merge commits illegal in our canonical Git repository.
 
 Unfortunately, GitHub does not support server side hooks to enforce such a
-policy.  We must rely on the community to avoid pushing merge commits.
+policy. We must rely on the community to avoid pushing merge commits.
 
 GitHub offers a feature called `Status Checks`: a branch protected by
 `status checks` requires commits to be explicitly allowed before the push can happen.
 We could supply a pre-push hook on the client side that would run and check the
-history, before allowing the commit being pushed [statuschecks]_.
+history, before allowing the commit being pushed [^cite_statuschecks].
 However this solution would be somewhat fragile (how do you update a script
 installed on every developer machine?) and prevents SVN access to the
 repository.
 
-What About Commit Emails?
--------------------------
+### What About Commit Emails?
 
 We will need a new bot to send emails for each commit. This proposal leaves the
 email format unchanged besides the commit URL.
 
-Straw Man Migration Plan
-========================
+## Straw Man Migration Plan
 
-Step #1 : Before The Move
--------------------------
+### Step #1 : Before The Move
 
 1. Update docs to mention the move, so people are aware of what is going on.
 2. Set up a read-only version of the GitHub project, mirroring our current SVN
@@ -164,15 +149,14 @@ Step #1 : Before The Move
    umbrella repository update (if the multirepo is selected) or the read-only
    Git views for the sub-projects (if the monorepo is selected).
 
-Step #2 : Git Move
-------------------
+### Step #2 : Git Move
 
 4. Update the buildbots to pick up updates and commits from the GitHub
    repository. Not all bots have to migrate at this point, but it'll help
    provide infrastructure testing.
 5. Update Phabricator to pick up commits from the GitHub repository.
 6. LNT and llvmlab have to be updated: they rely on unique monotonically
-   increasing integer across branch [MatthewsRevNum]_.
+   increasing integer across branch [^cite_matthewsrevnum].
 7. Instruct downstream integrators to pick up commits from the GitHub
    repository.
 8. Review and prepare an update for the LLVM documentation.
@@ -184,29 +168,25 @@ owners.
 The migration will pause here until all dependencies have cleared, and all
 problems have been solved.
 
-Step #3: Write Access Move
---------------------------
+### Step #3: Write Access Move
 
-9. Collect developers' GitHub account information, and add them to the project.
+09. Collect developers' GitHub account information, and add them to the project.
 10. Switch the SVN repository to read-only and allow pushes to the GitHub repository.
 11. Update the documentation.
 12. Mirror Git to SVN.
 
-Step #4 : Post Move
--------------------
+### Step #4 : Post Move
 
 13. Archive the SVN repository.
 14. Update links on the LLVM website pointing to viewvc/klaus/phab etc. to
     point to GitHub instead.
 
-GitHub Repository Description
-=============================
+## GitHub Repository Description
 
-Monorepo
-----------------
+### Monorepo
 
-The LLVM git repository hosted at https://github.com/llvm/llvm-project contains all
-sub-projects in a single source tree.  It is often referred to as a monorepo and
+The LLVM git repository hosted at <https://github.com/llvm/llvm-project> contains all
+sub-projects in a single source tree. It is often referred to as a monorepo and
 mimics an export of the current SVN repository, with each sub-project having its
 own top-level directory. Not all sub-projects are used for building toolchains.
 For example, www/ and test-suite/ are not part of the monorepo.
@@ -214,138 +194,132 @@ For example, www/ and test-suite/ are not part of the monorepo.
 Putting all sub-projects in a single checkout makes cross-project refactoring
 naturally simple:
 
- * New sub-projects can be trivially split out for better reuse and/or layering
-   (e.g., to allow libSupport and/or LIT to be used by runtimes without adding a
-   dependency on LLVM).
- * Changing an API in LLVM and upgrading the sub-projects will always be done in
-   a single commit, designing away a common source of temporary build breakage.
- * Moving code across sub-project (during refactoring for instance) in a single
-   commit enables accurate `git blame` when tracking code change history.
- * Tooling based on `git grep` works natively across sub-projects, allowing to
-   easier find refactoring opportunities across projects (for example reusing a
-   datastructure initially in LLDB by moving it into libSupport).
- * Having all the sources present encourages maintaining the other sub-projects
-   when changing API.
+> - New sub-projects can be trivially split out for better reuse and/or layering
+>   (e.g., to allow libSupport and/or LIT to be used by runtimes without adding a
+>   dependency on LLVM).
+> - Changing an API in LLVM and upgrading the sub-projects will always be done in
+>   a single commit, designing away a common source of temporary build breakage.
+> - Moving code across sub-project (during refactoring for instance) in a single
+>   commit enables accurate `git blame` when tracking code change history.
+> - Tooling based on `git grep` works natively across sub-projects, allowing to
+>   easier find refactoring opportunities across projects (for example reusing a
+>   datastructure initially in LLDB by moving it into libSupport).
+> - Having all the sources present encourages maintaining the other sub-projects
+>   when changing API.
 
 Finally, the monorepo maintains the property of the existing SVN repository that
 the sub-projects move synchronously, and a single revision number (or commit
 hash) identifies the state of the development across all projects.
 
-.. _build_single_project:
+(build-single-project)=
 
-Building a single sub-project
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Building a single sub-project
 
 Even though there is a single source tree, you are not required to build
-all sub-projects together.  It is trivial to configure builds for a single
+all sub-projects together. It is trivial to configure builds for a single
 sub-project.
 
-For example::
+For example:
 
-  mkdir build && cd build
-  # Configure only LLVM (default)
-  cmake path/to/monorepo
-  # Configure LLVM and lld
-  cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=lld
-  # Configure LLVM and clang
-  cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=clang
+```
+mkdir build && cd build
+# Configure only LLVM (default)
+cmake path/to/monorepo
+# Configure LLVM and lld
+cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=lld
+# Configure LLVM and clang
+cmake path/to/monorepo -DLLVM_ENABLE_PROJECTS=clang
+```
 
-.. _git-svn-mirror:
+(git-svn-mirror)=
 
-Outstanding Questions
----------------------
+### Outstanding Questions
 
-Read-only sub-project mirrors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Read-only sub-project mirrors
 
 With the Monorepo, it is undecided whether the existing single-subproject
-mirrors (e.g. https://git.llvm.org/git/compiler-rt.git) will continue to
+mirrors (e.g. <https://git.llvm.org/git/compiler-rt.git>) will continue to
 be maintained.
 
-Read/write SVN bridge
-^^^^^^^^^^^^^^^^^^^^^
+#### Read/write SVN bridge
 
-GitHub supports a read/write SVN bridge for its repositories.  However,
+GitHub supports a read/write SVN bridge for its repositories. However,
 there have been issues with this bridge working correctly in the past,
 so it's not clear if this is something that will be supported going forward.
 
-Monorepo Drawbacks
-------------------
-
- * Using the monolithic repository may add overhead for those contributing to a
-   standalone sub-project, particularly on runtimes like libcxx and compiler-rt
-   that don't rely on LLVM; currently, a fresh clone of libcxx is only 15MB (vs.
-   1GB for the monorepo), and the commit rate of LLVM may cause more frequent
-   `git push` collisions when upstreaming. Affected contributors may be able to
-   use the SVN bridge or the single-subproject Git mirrors. However, it's
-   undecided if these projects will continue to be maintained.
- * Using the monolithic repository may add overhead for those *integrating* a
-   standalone sub-project, even if they aren't contributing to it, due to the
-   same disk space concern as the point above. The availability of the
-   sub-project Git mirrors would addresses this.
- * Preservation of the existing read/write SVN-based workflows relies on the
-   GitHub SVN bridge, which is an extra dependency. Maintaining this locks us
-   into GitHub and could restrict future workflow changes.
-
-Workflows
-^^^^^^^^^
-
- * :ref:`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`.
- * :ref:`Checkout/Clone Multiple Projects, with Commit Access <workflow-monocheckout-multicommit>`.
- * :ref:`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`.
- * :ref:`Branching/Stashing/Updating for Local Development or Experiments <workflow-mono-branching>`.
- * :ref:`Bisecting <workflow-mono-bisecting>`.
-
-Workflow Before/After
-=====================
+### Monorepo Drawbacks
+
+> - Using the monolithic repository may add overhead for those contributing to a
+>   standalone sub-project, particularly on runtimes like libcxx and compiler-rt
+>   that don't rely on LLVM; currently, a fresh clone of libcxx is only 15MB (vs.
+>   1GB for the monorepo), and the commit rate of LLVM may cause more frequent
+>   `git push` collisions when upstreaming. Affected contributors may be able to
+>   use the SVN bridge or the single-subproject Git mirrors. However, it's
+>   undecided if these projects will continue to be maintained.
+> - Using the monolithic repository may add overhead for those *integrating* a
+>   standalone sub-project, even if they aren't contributing to it, due to the
+>   same disk space concern as the point above. The availability of the
+>   sub-project Git mirrors would addresses this.
+> - Preservation of the existing read/write SVN-based workflows relies on the
+>   GitHub SVN bridge, which is an extra dependency. Maintaining this locks us
+>   into GitHub and could restrict future workflow changes.
+
+#### Workflows
+
+> - {ref}`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`.
+> - {ref}`Checkout/Clone Multiple Projects, with Commit Access <workflow-monocheckout-multicommit>`.
+> - {ref}`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`.
+> - {ref}`Branching/Stashing/Updating for Local Development or Experiments <workflow-mono-branching>`.
+> - {ref}`Bisecting <workflow-mono-bisecting>`.
+
+## Workflow Before/After
 
 This section goes through a few examples of workflows, intended to illustrate
 how end-users or developers would interact with the repository for
 various use-cases.
 
-.. _workflow-checkout-commit:
-
-Checkout/Clone a Single Project, with Commit Access
----------------------------------------------------
+(workflow-checkout-commit)=
 
-Currently
-^^^^^^^^^
+### Checkout/Clone a Single Project, with Commit Access
 
-::
+#### Currently
 
-  # direct SVN checkout
-  svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm
-  # or using the read-only Git view, with git-svn
-  git clone https://llvm.org/git/llvm.git
-  cd llvm
-  git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
-  git config svn-remote.svn.fetch :refs/remotes/origin/main
-  git svn rebase -l  # -l avoids fetching ahead of the git mirror.
+```
+# direct SVN checkout
+svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm
+# or using the read-only Git view, with git-svn
+git clone https://llvm.org/git/llvm.git
+cd llvm
+git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
+git config svn-remote.svn.fetch :refs/remotes/origin/main
+git svn rebase -l  # -l avoids fetching ahead of the git mirror.
+```
 
 Commits are performed using `svn commit` or with the sequence `git commit` and
 `git svn dcommit`.
 
-.. _workflow-multicheckout-nocommit:
+(workflow-multicheckout-nocommit)=
 
-Monorepo Variant
-^^^^^^^^^^^^^^^^
+#### Monorepo Variant
 
 With the monorepo variant, there are a few options, depending on your
 constraints. First, you could just clone the full repository:
 
-git clone https://github.com/llvm/llvm-project.git
+git clone <https://github.com/llvm/llvm-project.git>
 
 At this point you have every sub-project (llvm, clang, lld, lldb, ...), which
-:ref:`doesn't imply you have to build all of them <build_single_project>`. You
+{ref}`doesn't imply you have to build all of them <build_single_project>`. You
 can still build only compiler-rt for instance. In this way it's not different
 from someone who would check out all the projects with SVN today.
 
 If you want to avoid checking out all the sources, you can hide the other
-directories using a Git sparse checkout::
+directories using a Git sparse checkout:
 
-  git config core.sparseCheckout true
-  echo /compiler-rt > .git/info/sparse-checkout
-  git read-tree -mu HEAD
+```
+git config core.sparseCheckout true
+echo /compiler-rt > .git/info/sparse-checkout
+git read-tree -mu HEAD
+```
 
 The data for all sub-projects is still in your `.git` directory, but in your
 checkout, you only see `compiler-rt`.
@@ -357,9 +331,11 @@ care about. If you are using sparse checkout, the files from other projects
 won't appear on your disk. The only effect is that your commit hash changes.
 
 You can check whether the changes in the last fetch are relevant to your commit
-by running::
+by running:
 
-  git log origin/main@{1}..origin/main -- libcxx
+```
+git log origin/main@{1}..origin/main -- libcxx
+```
 
 This command can be hidden in a script so that `git llvmpush` would perform all
 these steps, fail only if such a dependent change exists, and show immediately
@@ -368,66 +344,66 @@ the change that prevented the push. An immediate repeat of the command would
 Note that today with SVN or git-svn, this step is not possible since the
 "rebase" implicitly happens while committing (unless a conflict occurs).
 
-Checkout/Clone Multiple Projects, with Commit Access
-----------------------------------------------------
+### Checkout/Clone Multiple Projects, with Commit Access
 
 Let's look how to assemble llvm+clang+libcxx at a given revision.
 
-Currently
-^^^^^^^^^
-
-::
-
-  svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm -r $REVISION
-  cd llvm/tools
-  svn co https://llvm.org/svn/llvm-project/clang/trunk clang -r $REVISION
-  cd ../projects
-  svn co https://llvm.org/svn/llvm-project/libcxx/trunk libcxx -r $REVISION
-
-Or using git-svn::
-
-  git clone https://llvm.org/git/llvm.git
-  cd llvm/
-  git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
-  git config svn-remote.svn.fetch :refs/remotes/origin/main
-  git svn rebase -l
-  git checkout `git svn find-rev -B r258109`
-  cd tools
-  git clone https://llvm.org/git/clang.git
-  cd clang/
-  git svn init https://llvm.org/svn/llvm-project/clang/trunk --username=<username>
-  git config svn-remote.svn.fetch :refs/remotes/origin/main
-  git svn rebase -l
-  git checkout `git svn find-rev -B r258109`
-  cd ../../projects/
-  git clone https://llvm.org/git/libcxx.git
-  cd libcxx
-  git svn init https://llvm.org/svn/llvm-project/libcxx/trunk --username=<username>
-  git config svn-remote.svn.fetch :refs/remotes/origin/main
-  git svn rebase -l
-  git checkout `git svn find-rev -B r258109`
+#### Currently
+
+```
+svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm -r $REVISION
+cd llvm/tools
+svn co https://llvm.org/svn/llvm-project/clang/trunk clang -r $REVISION
+cd ../projects
+svn co https://llvm.org/svn/llvm-project/libcxx/trunk libcxx -r $REVISION
+```
+
+Or using git-svn:
+
+```
+git clone https://llvm.org/git/llvm.git
+cd llvm/
+git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
+git config svn-remote.svn.fetch :refs/remotes/origin/main
+git svn rebase -l
+git checkout `git svn find-rev -B r258109`
+cd tools
+git clone https://llvm.org/git/clang.git
+cd clang/
+git svn init https://llvm.org/svn/llvm-project/clang/trunk --username=<username>
+git config svn-remote.svn.fetch :refs/remotes/origin/main
+git svn rebase -l
+git checkout `git svn find-rev -B r258109`
+cd ../../projects/
+git clone https://llvm.org/git/libcxx.git
+cd libcxx
+git svn init https://llvm.org/svn/llvm-project/libcxx/trunk --username=<username>
+git config svn-remote.svn.fetch :refs/remotes/origin/main
+git svn rebase -l
+git checkout `git svn find-rev -B r258109`
+```
 
 Note that the list would be longer with more sub-projects.
 
-.. _workflow-monocheckout-multicommit:
+(workflow-monocheckout-multicommit)=
 
-Monorepo Variant
-^^^^^^^^^^^^^^^^
+#### Monorepo Variant
 
 The repository contains natively the source for every sub-projects at the right
-revision, which makes this straightforward::
+revision, which makes this straightforward:
 
-  git clone https://github.com/llvm/llvm-project.git
-  cd llvm-projects
-  git checkout $REVISION
+```
+git clone https://github.com/llvm/llvm-project.git
+cd llvm-projects
+git checkout $REVISION
+```
 
 As before, at this point clang, llvm, and libcxx are stored in directories
 alongside each other.
 
-.. _workflow-cross-repo-commit:
+(workflow-cross-repo-commit)=
 
-Commit an API Change in LLVM and Update the Sub-projects
---------------------------------------------------------
+### Commit an API Change in LLVM and Update the Sub-projects
 
 Today this is possible, even though not common (at least not documented) for
 subversion users and for git-svn users. For example, few Git users try to update
@@ -440,67 +416,74 @@ the umbrella repo's updater bot to group all of them into a single revision.
 
 The monorepo variant handles this natively.
 
-Branching/Stashing/Updating for Local Development or Experiments
-----------------------------------------------------------------
+### Branching/Stashing/Updating for Local Development or Experiments
 
-Currently
-^^^^^^^^^
+#### Currently
 
 SVN does not allow this use case, but developers that are currently using
 git-svn can do it. Let's look in practice what it means when dealing with
 multiple sub-projects.
 
-To update the repository to tip of trunk::
+To update the repository to tip of trunk:
 
-  git pull
-  cd tools/clang
-  git pull
-  cd ../../projects/libcxx
-  git pull
+```
+git pull
+cd tools/clang
+git pull
+cd ../../projects/libcxx
+git pull
+```
 
-To create a new branch::
+To create a new branch:
 
-  git checkout -b MyBranch
-  cd tools/clang
-  git checkout -b MyBranch
-  cd ../../projects/libcxx
-  git checkout -b MyBranch
+```
+git checkout -b MyBranch
+cd tools/clang
+git checkout -b MyBranch
+cd ../../projects/libcxx
+git checkout -b MyBranch
+```
 
-To switch branches::
+To switch branches:
 
-  git checkout AnotherBranch
-  cd tools/clang
-  git checkout AnotherBranch
-  cd ../../projects/libcxx
-  git checkout AnotherBranch
+```
+git checkout AnotherBranch
+cd tools/clang
+git checkout AnotherBranch
+cd ../../projects/libcxx
+git checkout AnotherBranch
+```
 
-.. _workflow-mono-branching:
+(workflow-mono-branching)=
 
-Monorepo Variant
-^^^^^^^^^^^^^^^^
+#### Monorepo Variant
 
 Regular Git commands are sufficient, because everything is in a single
 repository:
 
-To update the repository to tip of trunk::
+To update the repository to tip of trunk:
 
-  git pull
+```
+git pull
+```
 
-To create a new branch::
+To create a new branch:
 
-  git checkout -b MyBranch
+```
+git checkout -b MyBranch
+```
 
-To switch branches::
+To switch branches:
 
-  git checkout AnotherBranch
+```
+git checkout AnotherBranch
+```
 
-Bisecting
----------
+### Bisecting
 
 Assuming a developer is looking for a bug in clang (or lld, or lldb, ...).
 
-Currently
-^^^^^^^^^
+#### Currently
 
 SVN does not have builtin bisection support, but the single revision across
 sub-projects makes it possible to script around.
@@ -509,156 +492,160 @@ Using the existing Git read-only view of the repositories, it is possible to use
 the native Git bisection script over the llvm repository, and use some scripting
 to synchronize the clang repository to match the llvm revision.
 
-.. _workflow-mono-bisecting:
+(workflow-mono-bisecting)=
 
-Monorepo Variant
-^^^^^^^^^^^^^^^^
+#### Monorepo Variant
 
 Bisecting on the monorepo is straightforward, and very similar to the above,
 except that the bisection script does not need to include the
 `git submodule update` step.
 
 The same example, finding which commit introduces a regression where clang-3.9
-crashes but not clang-3.8 passes, will look like::
+crashes but not clang-3.8 passes, will look like:
 
-  git bisect start releases/3.9.x releases/3.8.x
-  git bisect run ./bisect_script.sh
+```
+git bisect start releases/3.9.x releases/3.8.x
+git bisect run ./bisect_script.sh
+```
 
-With the `bisect_script.sh` script being::
+With the `bisect_script.sh` script being:
 
-  #!/bin/sh
-  cd $BUILD_DIR
+```
+#!/bin/sh
+cd $BUILD_DIR
 
-  ninja clang || exit 125   # an exit code of 125 asks "git bisect"
-                            # to "skip" the current commit
+ninja clang || exit 125   # an exit code of 125 asks "git bisect"
+                          # to "skip" the current commit
 
-  ./bin/clang some_crash_test.cpp
+./bin/clang some_crash_test.cpp
+```
 
 Also, since the monorepo handles commits update across multiple projects, you're
 less like to encounter a build failure where a commit change an API in LLVM and
 another later one "fixes" the build in clang.
 
-Moving Local Branches to the Monorepo
-=====================================
+## Moving Local Branches to the Monorepo
 
 Suppose you have been developing against the existing LLVM git
-mirrors.  You have one or more git branches that you want to migrate
+mirrors. You have one or more git branches that you want to migrate
 to the "final monorepo".
 
 The simplest way to migrate such branches is with the
-``migrate-downstream-fork.py`` tool at
-https://github.com/jyknight/llvm-git-migration.
-
-Basic migration
----------------
-
-Basic instructions for ``migrate-downstream-fork.py`` are in the
-Python script and are expanded on below to a more general recipe::
-
-  # Make a repository which will become your final local mirror of the
-  # monorepo.
-  mkdir my-monorepo
-  git -C my-monorepo init
-
-  # Add a remote to the monorepo.
-  git -C my-monorepo remote add upstream/monorepo https://github.com/llvm/llvm-project.git
-
-  # Add remotes for each git mirror you use, from upstream as well as
-  # your local mirror.  All projects are listed here but you need only
-  # import those for which you have local branches.
-  my_projects=( clang
-                clang-tools-extra
-                compiler-rt
-                debuginfo-tests
-                libcxx
-                libcxxabi
-                libunwind
-                lld
-                lldb
-                llvm
-                openmp
-                polly )
-  for p in ${my_projects[@]}; do
-    git -C my-monorepo remote add upstream/split/${p} https://github.com/llvm-mirror/${p}.git
-    git -C my-monorepo remote add local/split/${p} https://my.local.mirror.org/${p}.git
-  done
-
-  # Pull in all the commits.
-  git -C my-monorepo fetch --all
-
-  # Run migrate-downstream-fork to rewrite local branches on top of
-  # the upstream monorepo.
-  (
-     cd my-monorepo
-     migrate-downstream-fork.py \
-       refs/remotes/local \
-       refs/tags \
-       --new-repo-prefix=refs/remotes/upstream/monorepo \
-       --old-repo-prefix=refs/remotes/upstream/split \
-       --source-kind=split \
-       --revmap-out=monorepo-map.txt
-  )
-
-  # Octopus-merge the resulting local split histories to unify them.
-
-  # Assumes local work on local split mirrors is on main (and
-  # upstream is presumably represented by some other branch like
-  # upstream/main).
-  my_local_branch="main"
-
-  git -C my-monorepo branch --no-track local/octopus/main \
-    $(git -C my-monorepo merge-base refs/remotes/upstream/monorepo/main \
-                                    refs/remotes/local/split/llvm/${my_local_branch})
-  git -C my-monorepo checkout local/octopus/${my_local_branch}
-
-  subproject_branches=()
-  for p in ${my_projects[@]}; do
-    subproject_branch=${p}/local/monorepo/${my_local_branch}
-    git -C my-monorepo branch ${subproject_branch} \
-      refs/remotes/local/split/${p}/${my_local_branch}
-    if [[ "${p}" != "llvm" ]]; then
-      subproject_branches+=( ${subproject_branch} )
-    fi
-  done
-
-  git -C my-monorepo merge ${subproject_branches[@]}
-
-  for p in ${my_projects[@]}; do
-    subproject_branch=${p}/local/monorepo/${my_local_branch}
-    git -C my-monorepo branch -d ${subproject_branch}
-  done
-
-  # Create local branches for upstream monorepo branches.
-  for ref in $(git -C my-monorepo for-each-ref --format="%(refname)" \
-                   refs/remotes/upstream/monorepo); do
-    upstream_branch=${ref#refs/remotes/upstream/monorepo/}
-    git -C my-monorepo branch upstream/${upstream_branch} ${ref}
-  done
-
-The above gets you to a state like the following::
-
-  U1 - U2 - U3 <- upstream/main
-    \   \    \
-     \   \    - Llld1 - Llld2 -
-      \   \                    \
-       \   - Lclang1 - Lclang2-- Lmerge <- local/octopus/main
-        \                      /
-         - Lllvm1 - Lllvm2-----
+`migrate-downstream-fork.py` tool at
+<https://github.com/jyknight/llvm-git-migration>.
+
+### Basic migration
+
+Basic instructions for `migrate-downstream-fork.py` are in the
+Python script and are expanded on below to a more general recipe:
+
+```
+# Make a repository which will become your final local mirror of the
+# monorepo.
+mkdir my-monorepo
+git -C my-monorepo init
+
+# Add a remote to the monorepo.
+git -C my-monorepo remote add upstream/monorepo https://github.com/llvm/llvm-project.git
+
+# Add remotes for each git mirror you use, from upstream as well as
+# your local mirror.  All projects are listed here but you need only
+# import those for which you have local branches.
+my_projects=( clang
+              clang-tools-extra
+              compiler-rt
+              debuginfo-tests
+              libcxx
+              libcxxabi
+              libunwind
+              lld
+              lldb
+              llvm
+              openmp
+              polly )
+for p in ${my_projects[@]}; do
+  git -C my-monorepo remote add upstream/split/${p} https://github.com/llvm-mirror/${p}.git
+  git -C my-monorepo remote add local/split/${p} https://my.local.mirror.org/${p}.git
+done
+
+# Pull in all the commits.
+git -C my-monorepo fetch --all
+
+# Run migrate-downstream-fork to rewrite local branches on top of
+# the upstream monorepo.
+(
+   cd my-monorepo
+   migrate-downstream-fork.py \
+     refs/remotes/local \
+     refs/tags \
+     --new-repo-prefix=refs/remotes/upstream/monorepo \
+     --old-repo-prefix=refs/remotes/upstream/split \
+     --source-kind=split \
+     --revmap-out=monorepo-map.txt
+)
+
+# Octopus-merge the resulting local split histories to unify them.
+
+# Assumes local work on local split mirrors is on main (and
+# upstream is presumably represented by some other branch like
+# upstream/main).
+my_local_branch="main"
+
+git -C my-monorepo branch --no-track local/octopus/main \
+  $(git -C my-monorepo merge-base refs/remotes/upstream/monorepo/main \
+                                  refs/remotes/local/split/llvm/${my_local_branch})
+git -C my-monorepo checkout local/octopus/${my_local_branch}
+
+subproject_branches=()
+for p in ${my_projects[@]}; do
+  subproject_branch=${p}/local/monorepo/${my_local_branch}
+  git -C my-monorepo branch ${subproject_branch} \
+    refs/remotes/local/split/${p}/${my_local_branch}
+  if [[ "${p}" != "llvm" ]]; then
+    subproject_branches+=( ${subproject_branch} )
+  fi
+done
+
+git -C my-monorepo merge ${subproject_branches[@]}
+
+for p in ${my_projects[@]}; do
+  subproject_branch=${p}/local/monorepo/${my_local_branch}
+  git -C my-monorepo branch -d ${subproject_branch}
+done
+
+# Create local branches for upstream monorepo branches.
+for ref in $(git -C my-monorepo for-each-ref --format="%(refname)" \
+                 refs/remotes/upstream/monorepo); do
+  upstream_branch=${ref#refs/remotes/upstream/monorepo/}
+  git -C my-monorepo branch upstream/${upstream_branch} ${ref}
+done
+```
+
+The above gets you to a state like the following:
+
+```
+U1 - U2 - U3 <- upstream/main
+  \   \    \
+   \   \    - Llld1 - Llld2 -
+    \   \                    \
+     \   - Lclang1 - Lclang2-- Lmerge <- local/octopus/main
+      \                      /
+       - Lllvm1 - Lllvm2-----
+```
 
 Each branched component has its branch rewritten on top of the
 monorepo and all components are unified by a giant octopus merge.
 
 If additional active local branches need to be preserved, the above
-operations following the assignment to ``my_local_branch`` should be
-done for each branch.  Ref paths will need to be updated to map the
-local branch to the corresponding upstream branch.  If local branches
+operations following the assignment to `my_local_branch` should be
+done for each branch. Ref paths will need to be updated to map the
+local branch to the corresponding upstream branch. If local branches
 have no corresponding upstream branch, then the creation of
-``local/octopus/<local branch>`` need not use ``git-merge-base`` to
+`local/octopus/<local branch>` need not use `git-merge-base` to
 pinpoint its root commit; it may simply be branched from the
-appropriate component branch (say, ``llvm/local_release_X``).
+appropriate component branch (say, `llvm/local_release_X`).
 
-Zipping local history
----------------------
+### Zipping local history
 
 The octopus merge is suboptimal for many cases, because walking back
 through the history of one component leaves the other components fixed
@@ -667,417 +654,433 @@ at a history that likely makes things unbuildable.
 Some downstream users track the order commits were made to subprojects
 with some kind of "umbrella" project that imports the project git
 mirrors as submodules, similar to the multirepo umbrella proposed
-above.  Such an umbrella repository looks something like this::
+above. Such an umbrella repository looks something like this:
 
-   UM1 ---- UM2 -- UM3 -- UM4 ---- UM5 ---- UM6 ---- UM7 ---- UM8 <- main
-   |        |             |        |        |        |        |
-  Lllvm1   Llld1         Lclang1  Lclang2  Lllvm2   Llld2     Lmyproj1
+```
+ UM1 ---- UM2 -- UM3 -- UM4 ---- UM5 ---- UM6 ---- UM7 ---- UM8 <- main
+ |        |             |        |        |        |        |
+Lllvm1   Llld1         Lclang1  Lclang2  Lllvm2   Llld2     Lmyproj1
+```
 
 The vertical bars represent submodule updates to a particular local
-commit in the project mirror.  ``UM3`` in this case is a commit of
+commit in the project mirror. `UM3` in this case is a commit of
 some local umbrella repository state that is not a submodule update,
-perhaps a ``README`` or project build script update.  Commit ``UM8``
-updates a submodule of local project ``myproj``.
+perhaps a `README` or project build script update. Commit `UM8`
+updates a submodule of local project `myproj`.
 
-The tool ``zip-downstream-fork.py`` at
-https://github.com/greened/llvm-git-migration/tree/zip can be used to
+The tool `zip-downstream-fork.py` at
+<https://github.com/greened/llvm-git-migration/tree/zip> can be used to
 convert the umbrella history into a monorepo-based history with
-commits in the order implied by submodule updates::
-
-  U1 - U2 - U3 <- upstream/main
-   \    \    \
-    \    -----\---------------                                    local/zip--.
-     \         \              \                                               |
-    - Lllvm1 - Llld1 - UM3 -  Lclang1 - Lclang2 - Lllvm2 - Llld2 - Lmyproj1 <-'
-
-
-The ``U*`` commits represent upstream commits to the monorepo main
-branch.  Each submodule update in the local ``UM*`` commits brought in
-a subproject tree at some local commit.  The trees in the ``L*1``
-commits represent merges from upstream.  These result in edges from
-the ``U*`` commits to their corresponding rewritten ``L*1`` commits.
-The ``L*2`` commits did not do any merges from upstream.
-
-Note that the merge from ``U2`` to ``Lclang1`` appears redundant, but
-if, say, ``U3`` changed some files in upstream clang, the ``Lclang1``
-commit appearing after the ``Llld1`` commit would actually represent a
-clang tree *earlier* in the upstream clang history.  We want the
-``local/zip`` branch to accurately represent the state of our umbrella
-history and so the edge ``U2 -> Lclang1`` is a visual reminder of what
-clang's tree actually looks like in ``Lclang1``.
-
-Even so, the edge ``U3 -> Llld1`` could be problematic for future
-merges from upstream.  git will think that we've already merged from
-``U3``, and we have, except for the state of the clang tree.  One
-possible mitigation strategy is to manually diff clang between ``U2``
-and ``U3`` and apply those updates to ``local/zip``.  Another,
+commits in the order implied by submodule updates:
+
+```
+U1 - U2 - U3 <- upstream/main
+ \    \    \
+  \    -----\---------------                                    local/zip--.
+   \         \              \                                               |
+  - Lllvm1 - Llld1 - UM3 -  Lclang1 - Lclang2 - Lllvm2 - Llld2 - Lmyproj1 <-'
+```
+
+The `U*` commits represent upstream commits to the monorepo main
+branch. Each submodule update in the local `UM*` commits brought in
+a subproject tree at some local commit. The trees in the `L*1`
+commits represent merges from upstream. These result in edges from
+the `U*` commits to their corresponding rewritten `L*1` commits.
+The `L*2` commits did not do any merges from upstream.
+
+Note that the merge from `U2` to `Lclang1` appears redundant, but
+if, say, `U3` changed some files in upstream clang, the `Lclang1`
+commit appearing after the `Llld1` commit would actually represent a
+clang tree *earlier* in the upstream clang history. We want the
+`local/zip` branch to accurately represent the state of our umbrella
+history and so the edge `U2 -> Lclang1` is a visual reminder of what
+clang's tree actually looks like in `Lclang1`.
+
+Even so, the edge `U3 -> Llld1` could be problematic for future
+merges from upstream. git will think that we've already merged from
+`U3`, and we have, except for the state of the clang tree. One
+possible mitigation strategy is to manually diff clang between `U2`
+and `U3` and apply those updates to `local/zip`. Another,
 possibly simpler strategy is to freeze local work on downstream
 branches and merge all submodules from the latest upstream before
-running ``zip-downstream-fork.py``.  If downstream merged each project
+running `zip-downstream-fork.py`. If downstream merged each project
 from upstream in lockstep without any intervening local commits, then
-things should be fine without any special action.  We anticipate this
+things should be fine without any special action. We anticipate this
 to be the common case.
 
-The tree for ``Lclang1`` outside of clang will represent the state of
-things at ``U3`` since all of the upstream projects not participating
+The tree for `Lclang1` outside of clang will represent the state of
+things at `U3` since all of the upstream projects not participating
 in the umbrella history should be in a state respecting the commit
-``U3``.  The trees for llvm and lld should correctly represent commits
-``Lllvm1`` and ``Llld1``, respectively.
+`U3`. The trees for llvm and lld should correctly represent commits
+`Lllvm1` and `Llld1`, respectively.
 
-Commit ``UM3`` changed files not related to submodules and we need
-somewhere to put them.  It is not safe in general to put them in the
+Commit `UM3` changed files not related to submodules and we need
+somewhere to put them. It is not safe in general to put them in the
 monorepo root directory because they may conflict with files in the
-monorepo.  Let's assume we want them in a directory ``local`` in the
+monorepo. Let's assume we want them in a directory `local` in the
 monorepo.
 
 **Example 1: Umbrella looks like the monorepo**
 
 For this example, we'll assume that each subproject appears in its own
 top-level directory in the umbrella, just as they do in the monorepo .
-Let's also assume that we want the files in directory ``myproj`` to
-appear in ``local/myproj``.
-
-Given the above run of ``migrate-downstream-fork.py``, a recipe to
-create the zipped history is below::
-
-  # Import any non-LLVM repositories the umbrella references.
-  git -C my-monorepo remote add localrepo \
-                                https://my.local.mirror.org/localrepo.git
-  git fetch localrepo
-
-  subprojects=( clang clang-tools-extra compiler-rt debuginfo-tests libclc
-                libcxx libcxxabi libunwind lld lldb llgo llvm openmp
-                parallel-libs polly pstl )
-
-  # Import histories for upstream split projects (this was probably
-  # already done for the ``migrate-downstream-fork.py`` run).
-  for project in ${subprojects[@]}; do
-    git remote add upstream/split/${project} \
-                   https://github.com/llvm-mirror/${subproject}.git
-    git fetch umbrella/split/${project}
-  done
-
-  # Import histories for downstream split projects (this was probably
-  # already done for the ``migrate-downstream-fork.py`` run).
-  for project in ${subprojects[@]}; do
-    git remote add local/split/${project} \
-                   https://my.local.mirror.org/${subproject}.git
-    git fetch local/split/${project}
-  done
-
-  # Import umbrella history.
-  git -C my-monorepo remote add umbrella \
-                                https://my.local.mirror.org/umbrella.git
-  git fetch umbrella
-
-  # Put myproj in local/myproj
-  echo "myproj local/myproj" > my-monorepo/submodule-map.txt
-
-  # Rewrite history
-  (
-    cd my-monorepo
-    zip-downstream-fork.py \
-      refs/remotes/umbrella \
-      --new-repo-prefix=refs/remotes/upstream/monorepo \
-      --old-repo-prefix=refs/remotes/upstream/split \
-      --revmap-in=monorepo-map.txt \
-      --revmap-out=zip-map.txt \
-      --subdir=local \
-      --submodule-map=submodule-map.txt \
-      --update-tags
-   )
-
-   # Create the zip branch (assuming umbrella main is wanted).
-   git -C my-monorepo branch --no-track local/zip/main refs/remotes/umbrella/main
+Let's also assume that we want the files in directory `myproj` to
+appear in `local/myproj`.
+
+Given the above run of `migrate-downstream-fork.py`, a recipe to
+create the zipped history is below:
+
+```
+# Import any non-LLVM repositories the umbrella references.
+git -C my-monorepo remote add localrepo \
+                              https://my.local.mirror.org/localrepo.git
+git fetch localrepo
+
+subprojects=( clang clang-tools-extra compiler-rt debuginfo-tests libclc
+              libcxx libcxxabi libunwind lld lldb llgo llvm openmp
+              parallel-libs polly pstl )
+
+# Import histories for upstream split projects (this was probably
+# already done for the ``migrate-downstream-fork.py`` run).
+for project in ${subprojects[@]}; do
+  git remote add upstream/split/${project} \
+                 https://github.com/llvm-mirror/${subproject}.git
+  git fetch umbrella/split/${project}
+done
+
+# Import histories for downstream split projects (this was probably
+# already done for the ``migrate-downstream-fork.py`` run).
+for project in ${subprojects[@]}; do
+  git remote add local/split/${project} \
+                 https://my.local.mirror.org/${subproject}.git
+  git fetch local/split/${project}
+done
+
+# Import umbrella history.
+git -C my-monorepo remote add umbrella \
+                              https://my.local.mirror.org/umbrella.git
+git fetch umbrella
+
+# Put myproj in local/myproj
+echo "myproj local/myproj" > my-monorepo/submodule-map.txt
+
+# Rewrite history
+(
+  cd my-monorepo
+  zip-downstream-fork.py \
+    refs/remotes/umbrella \
+    --new-repo-prefix=refs/remotes/upstream/monorepo \
+    --old-repo-prefix=refs/remotes/upstream/split \
+    --revmap-in=monorepo-map.txt \
+    --revmap-out=zip-map.txt \
+    --subdir=local \
+    --submodule-map=submodule-map.txt \
+    --update-tags
+ )
+
+ # Create the zip branch (assuming umbrella main is wanted).
+ git -C my-monorepo branch --no-track local/zip/main refs/remotes/umbrella/main
+```
 
 Note that if the umbrella has submodules to non-LLVM repositories,
-``zip-downstream-fork.py`` needs to know about them to be able to
-rewrite commits.  That is why the first step above is to fetch commits
+`zip-downstream-fork.py` needs to know about them to be able to
+rewrite commits. That is why the first step above is to fetch commits
 from such repositories.
 
-With ``--update-tags`` the tool will migrate annotated tags pointing
-to submodule commits that were inlined into the zipped history.  If
+With `--update-tags` the tool will migrate annotated tags pointing
+to submodule commits that were inlined into the zipped history. If
 the umbrella pulled in an upstream commit that happened to have a tag
 pointing to it, that tag will be migrated, which is almost certainly
-not what is wanted.  The tag can always be moved back to its original
-commit after rewriting, or the ``--update-tags`` option may be
+not what is wanted. The tag can always be moved back to its original
+commit after rewriting, or the `--update-tags` option may be
 discarded and any local tags would then be migrated manually.
 
 **Example 2: Nested sources layout**
 
 The tool handles nested submodules (e.g. llvm is a submodule in
-umbrella and clang is a submodule in llvm).  The file
-``submodule-map.txt`` is a list of pairs, one per line.  The first
+umbrella and clang is a submodule in llvm). The file
+`submodule-map.txt` is a list of pairs, one per line. The first
 pair item describes the path to a submodule in the umbrella
-repository.  The second pair item describes the path where trees for
+repository. The second pair item describes the path where trees for
 that submodule should be written in the zipped history.
 
 Let's say your umbrella repository is actually the llvm repository and
 it has submodules in the "nested sources" layout (clang in
-tools/clang, etc.).  Let's also say ``projects/myproj`` is a submodule
-pointing to some downstream repository.  The submodule map file should
+tools/clang, etc.). Let's also say `projects/myproj` is a submodule
+pointing to some downstream repository. The submodule map file should
 look like this (we still want myproj mapped the same way as
-previously)::
-
-  tools/clang clang
-  tools/clang/tools/extra clang-tools-extra
-  projects/compiler-rt compiler-rt
-  projects/debuginfo-tests debuginfo-tests
-  projects/libclc libclc
-  projects/libcxx libcxx
-  projects/libcxxabi libcxxabi
-  projects/libunwind libunwind
-  tools/lld lld
-  tools/lldb lldb
-  projects/openmp openmp
-  tools/polly polly
-  projects/myproj local/myproj
+previously):
+
+```
+tools/clang clang
+tools/clang/tools/extra clang-tools-extra
+projects/compiler-rt compiler-rt
+projects/debuginfo-tests debuginfo-tests
+projects/libclc libclc
+projects/libcxx libcxx
+projects/libcxxabi libcxxabi
+projects/libunwind libunwind
+tools/lld lld
+tools/lldb lldb
+projects/openmp openmp
+tools/polly polly
+projects/myproj local/myproj
+```
 
 If a submodule path does not appear in the map, the tools assumes it
-should be placed in the same place in the monorepo.  That means if you
+should be placed in the same place in the monorepo. That means if you
 use the "nested sources" layout in your umrella, you *must* provide
 map entries for all of the projects in your umbrella (except llvm).
 Otherwise trees from submodule updates will appear underneath llvm in
 the zippped history.
 
 Because llvm is itself the umbrella, we use --subdir to write its
-content into ``llvm`` in the zippped history::
-
-  # Import any non-LLVM repositories the umbrella references.
-  git -C my-monorepo remote add localrepo \
-                                https://my.local.mirror.org/localrepo.git
-  git fetch localrepo
-
-  subprojects=( clang clang-tools-extra compiler-rt debuginfo-tests libclc
-                libcxx libcxxabi libunwind lld lldb llgo llvm openmp
-                parallel-libs polly pstl )
-
-  # Import histories for upstream split projects (this was probably
-  # already done for the ``migrate-downstream-fork.py`` run).
-  for project in ${subprojects[@]}; do
-    git remote add upstream/split/${project} \
-                   https://github.com/llvm-mirror/${subproject}.git
-    git fetch umbrella/split/${project}
-  done
-
-  # Import histories for downstream split projects (this was probably
-  # already done for the ``migrate-downstream-fork.py`` run).
-  for project in ${subprojects[@]}; do
-    git remote add local/split/${project} \
-                   https://my.local.mirror.org/${subproject}.git
-    git fetch local/split/${project}
-  done
-
-  # Import umbrella history.  We want this under a different refspec
-  # so zip-downstream-fork.py knows what it is.
-  git -C my-monorepo remote add umbrella \
-                                 https://my.local.mirror.org/llvm.git
-  git fetch umbrella
-
-  # Create the submodule map.
-  echo "tools/clang clang" > my-monorepo/submodule-map.txt
-  echo "tools/clang/tools/extra clang-tools-extra" >> my-monorepo/submodule-map.txt
-  echo "projects/compiler-rt compiler-rt" >> my-monorepo/submodule-map.txt
-  echo "projects/debuginfo-tests debuginfo-tests" >> my-monorepo/submodule-map.txt
-  echo "projects/libclc libclc" >> my-monorepo/submodule-map.txt
-  echo "projects/libcxx libcxx" >> my-monorepo/submodule-map.txt
-  echo "projects/libcxxabi libcxxabi" >> my-monorepo/submodule-map.txt
-  echo "projects/libunwind libunwind" >> my-monorepo/submodule-map.txt
-  echo "tools/lld lld" >> my-monorepo/submodule-map.txt
-  echo "tools/lldb lldb" >> my-monorepo/submodule-map.txt
-  echo "projects/openmp openmp" >> my-monorepo/submodule-map.txt
-  echo "tools/polly polly" >> my-monorepo/submodule-map.txt
-  echo "projects/myproj local/myproj" >> my-monorepo/submodule-map.txt
-
-  # Rewrite history
-  (
-    cd my-monorepo
-    zip-downstream-fork.py \
-      refs/remotes/umbrella \
-      --new-repo-prefix=refs/remotes/upstream/monorepo \
-      --old-repo-prefix=refs/remotes/upstream/split \
-      --revmap-in=monorepo-map.txt \
-      --revmap-out=zip-map.txt \
-      --subdir=llvm \
-      --submodule-map=submodule-map.txt \
-      --update-tags
-   )
-
-   # Create the zip branch (assuming umbrella main is wanted).
-   git -C my-monorepo branch --no-track local/zip/main refs/remotes/umbrella/main
-
-
-Comments at the top of ``zip-downstream-fork.py`` describe in more
+content into `llvm` in the zippped history:
+
+```
+# Import any non-LLVM repositories the umbrella references.
+git -C my-monorepo remote add localrepo \
+                              https://my.local.mirror.org/localrepo.git
+git fetch localrepo
+
+subprojects=( clang clang-tools-extra compiler-rt debuginfo-tests libclc
+              libcxx libcxxabi libunwind lld lldb llgo llvm openmp
+              parallel-libs polly pstl )
+
+# Import histories for upstream split projects (this was probably
+# already done for the ``migrate-downstream-fork.py`` run).
+for project in ${subprojects[@]}; do
+  git remote add upstream/split/${project} \
+                 https://github.com/llvm-mirror/${subproject}.git
+  git fetch umbrella/split/${project}
+done
+
+# Import histories for downstream split projects (this was probably
+# already done for the ``migrate-downstream-fork.py`` run).
+for project in ${subprojects[@]}; do
+  git remote add local/split/${project} \
+                 https://my.local.mirror.org/${subproject}.git
+  git fetch local/split/${project}
+done
+
+# Import umbrella history.  We want this under a different refspec
+# so zip-downstream-fork.py knows what it is.
+git -C my-monorepo remote add umbrella \
+                               https://my.local.mirror.org/llvm.git
+git fetch umbrella
+
+# Create the submodule map.
+echo "tools/clang clang" > my-monorepo/submodule-map.txt
+echo "tools/clang/tools/extra clang-tools-extra" >> my-monorepo/submodule-map.txt
+echo "projects/compiler-rt compiler-rt" >> my-monorepo/submodule-map.txt
+echo "projects/debuginfo-tests debuginfo-tests" >> my-monorepo/submodule-map.txt
+echo "projects/libclc libclc" >> my-monorepo/submodule-map.txt
+echo "projects/libcxx libcxx" >> my-monorepo/submodule-map.txt
+echo "projects/libcxxabi libcxxabi" >> my-monorepo/submodule-map.txt
+echo "projects/libunwind libunwind" >> my-monorepo/submodule-map.txt
+echo "tools/lld lld" >> my-monorepo/submodule-map.txt
+echo "tools/lldb lldb" >> my-monorepo/submodule-map.txt
+echo "projects/openmp openmp" >> my-monorepo/submodule-map.txt
+echo "tools/polly polly" >> my-monorepo/submodule-map.txt
+echo "projects/myproj local/myproj" >> my-monorepo/submodule-map.txt
+
+# Rewrite history
+(
+  cd my-monorepo
+  zip-downstream-fork.py \
+    refs/remotes/umbrella \
+    --new-repo-prefix=refs/remotes/upstream/monorepo \
+    --old-repo-prefix=refs/remotes/upstream/split \
+    --revmap-in=monorepo-map.txt \
+    --revmap-out=zip-map.txt \
+    --subdir=llvm \
+    --submodule-map=submodule-map.txt \
+    --update-tags
+ )
+
+ # Create the zip branch (assuming umbrella main is wanted).
+ git -C my-monorepo branch --no-track local/zip/main refs/remotes/umbrella/main
+```
+
+Comments at the top of `zip-downstream-fork.py` describe in more
 detail how the tool works and various implications of its operation.
 
-Importing local repositories
-----------------------------
+### Importing local repositories
 
 You may have additional repositories that integrate with the LLVM
-ecosystem, essentially extending it with new tools.  If such
+ecosystem, essentially extending it with new tools. If such
 repositories are tightly coupled with LLVM, it may make sense to
 import them into your local mirror of the monorepo.
 
 If such repositories participated in the umbrella repository used
 during the zipping process above, they will automatically be added to
-the monorepo.  For downstream repositories that don't participate in
-an umbrella setup, the ``import-downstream-repo.py`` tool at
-https://github.com/greened/llvm-git-migration/tree/import can help with
-getting them into the monorepo.  A recipe follows::
-
-  # Import downstream repo history into the monorepo.
-  git -C my-monorepo remote add myrepo https://my.local.mirror.org/myrepo.git
-  git fetch myrepo
-
-  my_local_tags=( refs/tags/release
-                  refs/tags/hotfix )
-
-  (
-    cd my-monorepo
-    import-downstream-repo.py \
-      refs/remotes/myrepo \
-      ${my_local_tags[@]} \
-      --new-repo-prefix=refs/remotes/upstream/monorepo \
-      --subdir=myrepo \
-      --tag-prefix="myrepo-"
-   )
-
-   # Preserve release branches.
-   for ref in $(git -C my-monorepo for-each-ref --format="%(refname)" \
-                  refs/remotes/myrepo/release); do
-     branch=${ref#refs/remotes/myrepo/}
-     git -C my-monorepo branch --no-track myrepo/${branch} ${ref}
-   done
-
-   # Preserve main.
-   git -C my-monorepo branch --no-track myrepo/main refs/remotes/myrepo/main
-
-   # Merge main.
-   git -C my-monorepo checkout local/zip/main  # Or local/octopus/main
-   git -C my-monorepo merge myrepo/main
+the monorepo. For downstream repositories that don't participate in
+an umbrella setup, the `import-downstream-repo.py` tool at
+<https://github.com/greened/llvm-git-migration/tree/import> can help with
+getting them into the monorepo. A recipe follows:
+
+```
+# Import downstream repo history into the monorepo.
+git -C my-monorepo remote add myrepo https://my.local.mirror.org/myrepo.git
+git fetch myrepo
+
+my_local_tags=( refs/tags/release
+                refs/tags/hotfix )
+
+(
+  cd my-monorepo
+  import-downstream-repo.py \
+    refs/remotes/myrepo \
+    ${my_local_tags[@]} \
+    --new-repo-prefix=refs/remotes/upstream/monorepo \
+    --subdir=myrepo \
+    --tag-prefix="myrepo-"
+ )
+
+ # Preserve release branches.
+ for ref in $(git -C my-monorepo for-each-ref --format="%(refname)" \
+                refs/remotes/myrepo/release); do
+   branch=${ref#refs/remotes/myrepo/}
+   git -C my-monorepo branch --no-track myrepo/${branch} ${ref}
+ done
+
+ # Preserve main.
+ git -C my-monorepo branch --no-track myrepo/main refs/remotes/myrepo/main
+
+ # Merge main.
+ git -C my-monorepo checkout local/zip/main  # Or local/octopus/main
+ git -C my-monorepo merge myrepo/main
+```
 
 You may want to merge other corresponding branches, for example
-``myrepo`` release branches if they were in lockstep with LLVM project
+`myrepo` release branches if they were in lockstep with LLVM project
 releases.
 
-``--tag-prefix`` tells ``import-downstream-repo.py`` to rename
-annotated tags with the given prefix.  Due to limitations with
-``fast_filter_branch.py``, unannotated tags cannot be renamed
-(``fast_filter_branch.py`` considers them branches, not tags).  Since
+`--tag-prefix` tells `import-downstream-repo.py` to rename
+annotated tags with the given prefix. Due to limitations with
+`fast_filter_branch.py`, unannotated tags cannot be renamed
+(`fast_filter_branch.py` considers them branches, not tags). Since
 the upstream monorepo had its tags rewritten with an "llvmorg-"
-prefix, name conflicts should not be an issue.  ``--tag-prefix`` can
+prefix, name conflicts should not be an issue. `--tag-prefix` can
 be used to more clearly indicate which tags correspond to various
 imported repositories.
 
-Given this repository history::
-
-  R1 - R2 - R3 <- main
-       ^
-       |
-    release/1
-
-The above recipe results in a history like this::
-
-  U1 - U2 - U3 <- upstream/main
-   \    \    \
-    \    -----\---------------                                         local/zip--.
-     \         \              \                                                    |
-    - Lllvm1 - Llld1 - UM3 -  Lclang1 - Lclang2 - Lllvm2 - Llld2 - Lmyproj1 - M1 <-'
-                                                                             /
-                                                                 R1 - R2 - R3  <-.
-                                                                      ^           |
-                                                                      |           |
-                                                               myrepo-release/1   |
-                                                                                  |
-                                                                     myrepo/main--'
-
-Commits ``R1``, ``R2`` and ``R3`` have trees that *only* contain blobs
-from ``myrepo``.  If you require commits from ``myrepo`` to be
+Given this repository history:
+
+```
+R1 - R2 - R3 <- main
+     ^
+     |
+  release/1
+```
+
+The above recipe results in a history like this:
+
+```
+U1 - U2 - U3 <- upstream/main
+ \    \    \
+  \    -----\---------------                                         local/zip--.
+   \         \              \                                                    |
+  - Lllvm1 - Llld1 - UM3 -  Lclang1 - Lclang2 - Lllvm2 - Llld2 - Lmyproj1 - M1 <-'
+                                                                           /
+                                                               R1 - R2 - R3  <-.
+                                                                    ^           |
+                                                                    |           |
+                                                             myrepo-release/1   |
+                                                                                |
+                                                                   myrepo/main--'
+```
+
+Commits `R1`, `R2` and `R3` have trees that *only* contain blobs
+from `myrepo`. If you require commits from `myrepo` to be
 interleaved with commits on local project branches (for example,
-interleaved with ``llvm1``, ``llvm2``, etc. above) and myrepo doesn't
+interleaved with `llvm1`, `llvm2`, etc. above) and myrepo doesn't
 appear in an umbrella repository, a new tool will need to be
-developed.  Creating such a tool would involve:
+developed. Creating such a tool would involve:
 
-1. Modifying ``fast_filter_branch.py`` to optionally take a
+1. Modifying `fast_filter_branch.py` to optionally take a
    revlist directly rather than generating it itself
-
 2. Creating a tool to generate an interleaved ordering of local
-   commits based on some criteria (``zip-downstream-fork.py`` uses the
+   commits based on some criteria (`zip-downstream-fork.py` uses the
    umbrella history as its criterion)
-
 3. Generating such an ordering and feeding it to
-   ``fast_filter_branch.py`` as a revlist
+   `fast_filter_branch.py` as a revlist
 
 Some care will also likely need to be taken to handle merge commits,
 to ensure the parents of such commits migrate correctly.
 
-Scrubbing the Local Monorepo
-----------------------------
+### Scrubbing the Local Monorepo
 
 Once all of the migrating, zipping and importing is done, it's time to
-clean up.  The python tools use ``git-fast-import`` which leaves a lot
+clean up. The python tools use `git-fast-import` which leaves a lot
 of cruft around and we want to shrink our new monorepo mirror as much
-as possible.  Here is one way to do it::
-
-  git -C my-monorepo checkout main
-
-  # Delete branches we no longer need.  Do this for any other branches
-  # you merged above.
-  git -C my-monorepo branch -D local/zip/main || true
-  git -C my-monorepo branch -D local/octopus/main || true
-
-  # Remove remotes.
-  git -C my-monorepo remote remove upstream/monorepo
-
-  for p in ${my_projects[@]}; do
-    git -C my-monorepo remote remove upstream/split/${p}
-    git -C my-monorepo remote remove local/split/${p}
-  done
-
-  git -C my-monorepo remote remove localrepo
-  git -C my-monorepo remote remove umbrella
-  git -C my-monorepo remote remove myrepo
-
-  # Add anything else here you don't need.  refs/tags/release is
-  # listed below assuming tags have been rewritten with a local prefix.
-  # If not, remove it from this list.
-  refs_to_clean=(
-    refs/original
-    refs/remotes
-    refs/tags/backups
-    refs/tags/release
-  )
-
-  git -C my-monorepo for-each-ref --format="%(refname)" ${refs_to_clean[@]} |
-    xargs -n1 --no-run-if-empty git -C my-monorepo update-ref -d
-
-  git -C my-monorepo reflog expire --all --expire=now
-
-  # fast_filter_branch.py might have gc running in the background.
-  while ! git -C my-monorepo \
-    -c gc.reflogExpire=0 \
-    -c gc.reflogExpireUnreachable=0 \
-    -c gc.rerereresolved=0 \
-    -c gc.rerereunresolved=0 \
-    -c gc.pruneExpire=now \
-    gc --prune=now; do
-    continue
-  done
-
-  # Takes a LOOOONG time!
-  git -C my-monorepo repack -A -d -f --depth=250 --window=250
-
-  git -C my-monorepo prune-packed
-  git -C my-monorepo prune
-
-You should now have a trim monorepo.  Upload it to your git server and
+as possible. Here is one way to do it:
+
+```
+git -C my-monorepo checkout main
+
+# Delete branches we no longer need.  Do this for any other branches
+# you merged above.
+git -C my-monorepo branch -D local/zip/main || true
+git -C my-monorepo branch -D local/octopus/main || true
+
+# Remove remotes.
+git -C my-monorepo remote remove upstream/monorepo
+
+for p in ${my_projects[@]}; do
+  git -C my-monorepo remote remove upstream/split/${p}
+  git -C my-monorepo remote remove local/split/${p}
+done
+
+git -C my-monorepo remote remove localrepo
+git -C my-monorepo remote remove umbrella
+git -C my-monorepo remote remove myrepo
+
+# Add anything else here you don't need.  refs/tags/release is
+# listed below assuming tags have been rewritten with a local prefix.
+# If not, remove it from this list.
+refs_to_clean=(
+  refs/original
+  refs/remotes
+  refs/tags/backups
+  refs/tags/release
+)
+
+git -C my-monorepo for-each-ref --format="%(refname)" ${refs_to_clean[@]} |
+  xargs -n1 --no-run-if-empty git -C my-monorepo update-ref -d
+
+git -C my-monorepo reflog expire --all --expire=now
+
+# fast_filter_branch.py might have gc running in the background.
+while ! git -C my-monorepo \
+  -c gc.reflogExpire=0 \
+  -c gc.reflogExpireUnreachable=0 \
+  -c gc.rerereresolved=0 \
+  -c gc.rerereunresolved=0 \
+  -c gc.pruneExpire=now \
+  gc --prune=now; do
+  continue
+done
+
+# Takes a LOOOONG time!
+git -C my-monorepo repack -A -d -f --depth=250 --window=250
+
+git -C my-monorepo prune-packed
+git -C my-monorepo prune
+```
+
+You should now have a trim monorepo. Upload it to your git server and
 happy hacking!
 
-References
-==========
+## References
+
+[^cite_lattnerrevnum]: Chris Lattner, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041739.html>
+
+[^cite_trickrevnum]: Andrew Trick, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041721.html>
+
+[^cite_jsonnrevnum]: Joerg Sonnenberger, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041688.html>
+
+[^cite_matthewsrevnum]: Chris Matthews, <http://lists.llvm.org/pipermail/cfe-dev/2016-July/049886.html>
+
+[^cite_statuschecks]: GitHub status-checks, <https://help.github.com/articles/about-required-status-checks/>
 
-.. [LattnerRevNum] Chris Lattner, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041739.html
-.. [TrickRevNum] Andrew Trick, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041721.html
-.. [JSonnRevNum] Joerg Sonnenberger, http://lists.llvm.org/pipermail/llvm-dev/2011-July/041688.html
-.. [MatthewsRevNum] Chris Matthews, http://lists.llvm.org/pipermail/cfe-dev/2016-July/049886.html
-.. [statuschecks] GitHub status-checks, https://help.github.com/articles/about-required-status-checks/
diff --git a/llvm/docs/Proposals/TestSuite.md b/llvm/docs/Proposals/TestSuite.md
index 3cccefb1ff129..e606312049d54 100644
--- a/llvm/docs/Proposals/TestSuite.md
+++ b/llvm/docs/Proposals/TestSuite.md
@@ -1,10 +1,6 @@
-=====================
-Test-Suite Extensions
-=====================
+# Test-Suite Extensions
 
-
-Abstract
-========
+## Abstract
 
 These are ideas for additional programs, benchmarks, applications and
 algorithms that could be added to the LLVM Test-Suite.
@@ -15,21 +11,18 @@ Most probably, the reason why the programs below have not been added to
 the test-suite yet is that nobody has found time to do it. But there
 might be other issues as well, such as
 
- * Licensing (Support can still be added as external module,
-              like for the SPEC benchmarks)
-
- * Language (in particular, there is no official LLVM frontend
-             for FORTRAN yet)
+> - Licensing (Support can still be added as external module,
+>   : like for the SPEC benchmarks)
+> - Language (in particular, there is no official LLVM frontend
+>   : for FORTRAN yet)
+> - Parallelism (currently, all programs in test-suite use
+>   : one thread only)
 
- * Parallelism (currently, all programs in test-suite use
-                one thread only)
+## Benchmarks
 
-Benchmarks
-==========
+### SPEC CPU 2017
 
-SPEC CPU 2017
--------------
-https://www.spec.org/cpu2017/
+<https://www.spec.org/cpu2017/>
 
 The following have not been included yet because they contain Fortran
 code.
@@ -38,281 +31,272 @@ In case of cactuBSSN only a small portion is Fortran. The hosts's
 Fortran compiler could be used for these parts.
 
 Note that CMake's Ninja generator has difficulties with Fortran. See the
-`CMake documentation <https://cmake.org/cmake/help/v3.13/generator/Ninja.html#fortran-support>`_
+[CMake documentation](https://cmake.org/cmake/help/v3.13/generator/Ninja.html#fortran-support)
 for details.
 
- * 503.bwaves_r/603.bwaves_s
- * 507.cactuBSSN_r
- * 521.wrf_r/621.wrf_s
- * 527.cam4_r/627.cam4_s
- * 628.pop2_s
- * 548.exchange2_r/648.exchange2_s
- * 549.fotonik3d_r/649.fotonik3d_s
- * 554.roms_r/654.roms_s
-
-SPEC OMP2012
-------------
-https://www.spec.org/omp2012/
-
- * 350.md
- * 351.bwaves
- * 352.nab
- * 357.bt331
- * 358.botsalgn
- * 359.botsspar
- * 360.ilbdc
- * 362.fma3d
- * 363.swim
- * 367.imagick
- * 370.mgrid331
- * 371.applu331
- * 372.smithwa
- * 376.kdtree
-
-OpenCV
-------
-https://opencv.org/
-
-OpenMP 4.x SIMD Benchmarks
---------------------------
-https://github.com/flwende/simd_benchmarks
-
-PWM-benchmarking
-----------------
-https://github.com/tbepler/PWM-benchmarking
-
-SLAMBench
----------
-https://github.com/pamela-project/slambench
-
-FireHose
---------
-http://firehose.sandia.gov/
-
-A Benchmark for the C/C++ Standard Library
-------------------------------------------
-https://github.com/hiraditya/std-benchmark
-
-OpenBenchmarking.org CPU / Processor Suite
-------------------------------------------
-https://openbenchmarking.org/suite/pts/cpu
+> - 503.bwaves_r/603.bwaves_s
+> - 507.cactuBSSN_r
+> - 521.wrf_r/621.wrf_s
+> - 527.cam4_r/627.cam4_s
+> - 628.pop2_s
+> - 548.exchange2_r/648.exchange2_s
+> - 549.fotonik3d_r/649.fotonik3d_s
+> - 554.roms_r/654.roms_s
+
+### SPEC OMP2012
+
+<https://www.spec.org/omp2012/>
+
+> - 350.md
+> - 351.bwaves
+> - 352.nab
+> - 357.bt331
+> - 358.botsalgn
+> - 359.botsspar
+> - 360.ilbdc
+> - 362.fma3d
+> - 363.swim
+> - 367.imagick
+> - 370.mgrid331
+> - 371.applu331
+> - 372.smithwa
+> - 376.kdtree
+
+### OpenCV
+
+<https://opencv.org/>
+
+### OpenMP 4.x SIMD Benchmarks
+
+<https://github.com/flwende/simd_benchmarks>
+
+### PWM-benchmarking
+
+<https://github.com/tbepler/PWM-benchmarking>
+
+### SLAMBench
+
+<https://github.com/pamela-project/slambench>
+
+### FireHose
+
+<http://firehose.sandia.gov/>
+
+### A Benchmark for the C/C++ Standard Library
+
+<https://github.com/hiraditya/std-benchmark>
+
+### OpenBenchmarking.org CPU / Processor Suite
+
+<https://openbenchmarking.org/suite/pts/cpu>
 
 This is a subset of the
-`Phoronix Test Suite <https://github.com/phoronix-test-suite/phoronix-test-suite/>`_
+[Phoronix Test Suite](https://github.com/phoronix-test-suite/phoronix-test-suite/)
 and is itself a collection of benchmark suites
 
-Parboil Benchmarks
-------------------
-http://impact.crhc.illinois.edu/parboil/parboil.aspx
+### Parboil Benchmarks
 
-MachSuite
----------
-https://breagen.github.io/MachSuite/
+<http://impact.crhc.illinois.edu/parboil/parboil.aspx>
 
-Rodinia
--------
-http://lava.cs.virginia.edu/Rodinia/download_links.htm
+### MachSuite
+
+<https://breagen.github.io/MachSuite/>
+
+### Rodinia
+
+<http://lava.cs.virginia.edu/Rodinia/download_links.htm>
 
 Rodinia has already been partially included in
 MultiSource/Benchmarks/Rodinia. Benchmarks still missing are:
 
- * streamcluster
- * particlefilter
- * nw
- * nn
- * myocyte
- * mummergpu
- * lud
- * leukocyte
- * lavaMD
- * kmeans
- * hotspot3D
- * heartwall
- * cfd
- * bfs
- * b+tree
-
-vecmathlib tests harness
-------------------------
-https://bitbucket.org/eschnett/vecmathlib/wiki/Home
-
-PARSEC
-------
-http://parsec.cs.princeton.edu/
-
-Graph500 reference implementations
-----------------------------------
-https://github.com/graph500/graph500/tree/v2-spec
-
-NAS Parallel Benchmarks
------------------------
-https://www.nas.nasa.gov/publications/npb.html
+> - streamcluster
+> - particlefilter
+> - nw
+> - nn
+> - myocyte
+> - mummergpu
+> - lud
+> - leukocyte
+> - lavaMD
+> - kmeans
+> - hotspot3D
+> - heartwall
+> - cfd
+> - bfs
+> - b+tree
+
+### vecmathlib tests harness
+
+<https://bitbucket.org/eschnett/vecmathlib/wiki/Home>
+
+### PARSEC
+
+<http://parsec.cs.princeton.edu/>
+
+### Graph500 reference implementations
+
+<https://github.com/graph500/graph500/tree/v2-spec>
+
+### NAS Parallel Benchmarks
+
+<https://www.nas.nasa.gov/publications/npb.html>
 
 The official benchmark is written in Fortran, but an unofficial
 C-translation is available as well:
-https://github.com/benchmark-subsetting/NPB3.0-omp-C
+<https://github.com/benchmark-subsetting/NPB3.0-omp-C>
 
-DARPA HPCS SSCA#2 C/OpenMP reference implementation
----------------------------------------------------
-http://www.highproductivity.org/SSCABmks.htm
+### DARPA HPCS SSCA#2 C/OpenMP reference implementation
+
+<http://www.highproductivity.org/SSCABmks.htm>
 
 This web site does not exist any more, but there seems to be a copy of
 some of the benchmarks
-https://github.com/gtcasl/hpc-benchmarks/tree/master/SSCA2v2.2
+<https://github.com/gtcasl/hpc-benchmarks/tree/master/SSCA2v2.2>
+
+### Kokkos
+
+<https://github.com/kokkos/kokkos-kernels/tree/master/perf_test>
+<https://github.com/kokkos/kokkos/tree/master/benchmarks>
+
+### PolyMage
 
-Kokkos
-------
-https://github.com/kokkos/kokkos-kernels/tree/master/perf_test
-https://github.com/kokkos/kokkos/tree/master/benchmarks
+<https://github.com/bondhugula/polymage-benchmarks>
 
-PolyMage
---------
-https://github.com/bondhugula/polymage-benchmarks
+### PolyBench
 
-PolyBench
----------
-https://sourceforge.net/projects/polybench/
+<https://sourceforge.net/projects/polybench/>
 
 A modified version of Polybench 3.2 is already presented in
 SingleSource/Benchmarks/Polybench. A newer version 4.2.1 is available.
 
-High Performance Geometric Multigrid
-------------------------------------
-https://crd.lbl.gov/departments/computer-science/PAR/research/hpgmg/
+### High Performance Geometric Multigrid
 
-RAJA Performance Suite
-----------------------
-https://github.com/LLNL/RAJAPerf
+<https://crd.lbl.gov/departments/computer-science/PAR/research/hpgmg/>
 
-CORAL-2 Benchmarks
-------------------
-https://asc.llnl.gov/coral-2-benchmarks/
+### RAJA Performance Suite
+
+<https://github.com/LLNL/RAJAPerf>
+
+### CORAL-2 Benchmarks
+
+<https://asc.llnl.gov/coral-2-benchmarks/>
 
 Many of its programs have already been integrated in
 MultiSource/Benchmarks/DOE-ProxyApps-C and
 MultiSource/Benchmarks/DOE-ProxyApps-C++.
 
- * Nekbone
- * QMCPack
- * LAMMPS
- * Kripke
- * Quicksilver
- * PENNANT
- * Big Data Analytic Suite
- * Deep Learning Suite
- * Stream
- * Stride
- * ML/DL micro-benchmark
- * Pynamic
- * ACME
- * VPIC
- * Laghos
- * Parallel Integer Sort
- * Havoq
-
-NWChem
-------
-http://www.nwchem-sw.org/index.php/Benchmarks
-
-TVM
-----
-https://github.com/dmlc/tvm/tree/main/apps/benchmark
-
-HydroBench
-----------
-https://github.com/HydroBench/Hydro
-
-ParRes
-------
-https://github.com/ParRes/Kernels/tree/default/Cxx11
-
-Applications/Libraries
-======================
-
-GnuPG
------
-https://gnupg.org/
-
-Blitz++
--------
-https://sourceforge.net/projects/blitz/
-
-FFmpeg
-------
-https://ffmpeg.org/
-
-FreePOOMA
----------
-http://www.nongnu.org/freepooma/
-
-FTensors
---------
-http://www.wlandry.net/Projects/FTensor
-
-rawspeed
---------
-https://github.com/darktable-org/rawspeed
+> - Nekbone
+> - QMCPack
+> - LAMMPS
+> - Kripke
+> - Quicksilver
+> - PENNANT
+> - Big Data Analytic Suite
+> - Deep Learning Suite
+> - Stream
+> - Stride
+> - ML/DL micro-benchmark
+> - Pynamic
+> - ACME
+> - VPIC
+> - Laghos
+> - Parallel Integer Sort
+> - Havoq
+
+### NWChem
+
+<http://www.nwchem-sw.org/index.php/Benchmarks>
+
+### TVM
+
+<https://github.com/dmlc/tvm/tree/main/apps/benchmark>
+
+### HydroBench
+
+<https://github.com/HydroBench/Hydro>
+
+### ParRes
+
+<https://github.com/ParRes/Kernels/tree/default/Cxx11>
+
+## Applications/Libraries
+
+### GnuPG
+
+<https://gnupg.org/>
+
+### Blitz++
+
+<https://sourceforge.net/projects/blitz/>
+
+### FFmpeg
+
+<https://ffmpeg.org/>
+
+### FreePOOMA
+
+<http://www.nongnu.org/freepooma/>
+
+### FTensors
+
+<http://www.wlandry.net/Projects/FTensor>
+
+### rawspeed
+
+<https://github.com/darktable-org/rawspeed>
 
 Its test dataset is 756 MB in size, which is too large to be included
 into the test-suite repository.
 
-C++ Performance Benchmarks
---------------------------
-https://gitlab.com/chriscox/CppPerformanceBenchmarks
+### C++ Performance Benchmarks
+
+<https://gitlab.com/chriscox/CppPerformanceBenchmarks>
+
+## Generic Algorithms
 
-Generic Algorithms
-==================
+### Image processing
 
-Image processing
-----------------
+#### Resampling
 
-Resampling
-``````````
+> - Bilinear
+> - Bicubic
+> - Lanczos
 
- * Bilinear
- * Bicubic
- * Lanczos
+#### Dither
 
-Dither
-``````
+> - Threshold
+> - Random
+> - Halftone
+> - Bayer
+> - Floyd-Steinberg
+> - Jarvis
+> - Stucki
+> - Burkes
+> - Sierra
+> - Atkinson
+> - Gradient-based
 
- * Threshold
- * Random
- * Halftone
- * Bayer
- * Floyd-Steinberg
- * Jarvis
- * Stucki
- * Burkes
- * Sierra
- * Atkinson
- * Gradient-based
+#### Feature detection
 
-Feature detection
-`````````````````
+> - Harris
+> - Histogram of Oriented Gradients
 
- * Harris
- * Histogram of Oriented Gradients
+#### Color conversion
 
-Color conversion
-````````````````
+> - RGB to grayscale
+> - HSL to RGB
 
- * RGB to grayscale
- * HSL to RGB
+### Graph
 
-Graph
------
+#### Search Algorithms
 
-Search Algorithms
-`````````````````
+> - Breadth-First-Search
+> - Depth-First-Search
+> - Dijkstra's algorithm
+> - A-Star
 
- * Breadth-First-Search
- * Depth-First-Search
- * Dijkstra's algorithm
- * A-Star
+#### Spanning Tree
 
-Spanning Tree
-`````````````
+> - Kruskal's algorithm
+> - Prim's algorithm
 
- * Kruskal's algorithm
- * Prim's algorithm
diff --git a/llvm/docs/Proposals/VectorPredication.md b/llvm/docs/Proposals/VectorPredication.md
index 8fa6f92f425b8..db0456c0c1d3a 100644
--- a/llvm/docs/Proposals/VectorPredication.md
+++ b/llvm/docs/Proposals/VectorPredication.md
@@ -1,49 +1,41 @@
-==========================
-Vector Predication Roadmap
-==========================
+# Vector Predication Roadmap
 
-
-Motivation
-==========
+## Motivation
 
 This proposal defines a roadmap towards native vector predication in LLVM,
 specifically for vector instructions with a mask and/or an explicit vector
-length.  LLVM currently has no target-independent means to model predicated
+length. LLVM currently has no target-independent means to model predicated
 vector instructions for modern SIMD ISAs such as AVX512, ARM SVE, the RISC-V V
-extension and NEC SX-Aurora.  Only some predicated vector operations, such as
-masked loads and stores, are available through intrinsics [MaskedIR]_.
+extension and NEC SX-Aurora. Only some predicated vector operations, such as
+masked loads and stores, are available through intrinsics [^cite_maskedir].
 
 The Vector Predication (VP) extensions is a concrete RFC and prototype
-implementation to achieve native vector predication in LLVM.  The VP prototype
+implementation to achieve native vector predication in LLVM. The VP prototype
 and all related discussions can be found in the VP patch on Phabricator
-[VPRFC]_.
+[^cite_vprfc].
 
-Roadmap
-=======
+## Roadmap
 
-1. IR-level VP intrinsics
--------------------------
+### 1. IR-level VP intrinsics
 
 - There is a consensus on the semantics/instruction set of VP.
 - VP intrinsics and attributes are available on IR level.
-- TTI has capability flags for VP (``supportsVP()``?,
-  ``haveActiveVectorLength()``?).
+- TTI has capability flags for VP (`supportsVP()`?,
+  `haveActiveVectorLength()`?).
 
 Result: VP usable for IR-level vectorizers (LV, VPlan, RegionVectorizer),
 potential integration in Clang with builtins.
 
-2. CodeGen support
-------------------
+### 2. CodeGen support
 
 - VP intrinsics translate to first-class SDNodes
-  (eg  ``llvm.vp.fdiv.* -> vp_fdiv``).
+  (eg `llvm.vp.fdiv.* -> vp_fdiv`).
 - VP legalization (legalize explicit vector length to mask (AVX512), legalize VP
   SDNodes to pre-existing ones (SSE, NEON)).
 
 Result: Backend development based on VP SDNodes.
 
-3. Lift InstSimplify/InstCombine/DAGCombiner to VP
---------------------------------------------------
+### 3. Lift InstSimplify/InstCombine/DAGCombiner to VP
 
 - Introduce PredicatedInstruction, PredicatedBinaryOperator, .. helper classes
   that match standard vector IR and VP intrinsics.
@@ -55,31 +47,29 @@ Result: Backend development based on VP SDNodes.
 
 Result: Optimization of VP intrinsics on par with standard vector instructions.
 
-4. Deprecate llvm.masked.* / llvm.experimental.reduce.*
--------------------------------------------------------
+### 4. Deprecate llvm.masked.\* / llvm.experimental.reduce.\*
 
-- Modernize llvm.masked.* / llvm.experimental.reduce* by translating to VP.
+- Modernize llvm.masked.\* / llvm.experimental.reduce\* by translating to VP.
 - DCE transitional APIs.
 
 Result: VP has superseded earlier vector intrinsics.
 
-5. Predicated IR Instructions
------------------------------
+### 5. Predicated IR Instructions
 
 - Vector instructions have an optional mask and vector length parameter. These
   lower to VP SDNodes (from Stage 2).
 - Phase out VP intrinsics, only keeping those that are not equivalent to
-  vectorized scalar instructions (reduce,  shuffles, ..)
+  vectorized scalar instructions (reduce, shuffles, ..)
 - InstCombine/InstSimplify expect predication in regular Instructions (Stage (3)
   has laid the groundwork).
 
 Result: Native vector predication in IR.
 
-References
-==========
+## References
+
+[^cite_maskedir]: `llvm.masked.*` intrinsics,
+    <https://llvm.org/docs/LangRef.html#masked-vector-load-and-store-intrinsics>
 
-.. [MaskedIR] `llvm.masked.*` intrinsics,
-   https://llvm.org/docs/LangRef.html#masked-vector-load-and-store-intrinsics
+[^cite_vprfc]: RFC: Prototype & Roadmap for vector predication in LLVM,
+    <https://reviews.llvm.org/D57504>
 
-.. [VPRFC] RFC: Prototype & Roadmap for vector predication in LLVM,
-   https://reviews.llvm.org/D57504
diff --git a/llvm/docs/QualGroup.md b/llvm/docs/QualGroup.md
index e2efa6d60490e..f3b2c17b27183 100644
--- a/llvm/docs/QualGroup.md
+++ b/llvm/docs/QualGroup.md
@@ -1,52 +1,46 @@
-========================
-LLVM Qualification Group
-========================
+# LLVM Qualification Group
 
-Introduction
-============
+## Introduction
 
-The LLVM Qualification Group is an open working group within the LLVM community. 
-It was created to coordinate efforts around enabling the use of LLVM components 
-in safety-critical applications governed by functional safety standards 
-such as IEC 61508 (for general E/E/PE systems), IEC 62304 (medical devices), 
+The LLVM Qualification Group is an open working group within the LLVM community.
+It was created to coordinate efforts around enabling the use of LLVM components
+in safety-critical applications governed by functional safety standards
+such as IEC 61508 (for general E/E/PE systems), IEC 62304 (medical devices),
 ISO 26262 (automotive), DO-178C (aerospace), and EN 50716 (railways).
 
-Motivation
-==========
+## Motivation
 
 LLVM is increasingly used in safety-critical domains (e.g., automotive, aerospace, medical),
-but currently lacks a shared structure to address the specific needs of functional safety, 
-such as systematic assurance arguments, tool qualification artifacts, and their associated 
+but currently lacks a shared structure to address the specific needs of functional safety,
+such as systematic assurance arguments, tool qualification artifacts, and their associated
 documentation.
 
 A more open, upstream, reusable, and collaborative approach would benefit the wider ecosystem.
 This group serves as a public forum for those interested in improving LLVM’s suitability for
 use in such environments.
 
-Goals
-=====
+## Goals
 
 The Qualification Group aims to:
 
-* Facilitate open discussion around tool confidence and qualification practices
-* Identify areas for upstream improvements (e.g., traceability hooks, quality evidence)
-* Share safety-relevant documentation and argumentation templates
-* Coordinate efforts across users and vendors working toward similar goals
-* Act as a point of contact for safety-related collaboration
+- Facilitate open discussion around tool confidence and qualification practices
+- Identify areas for upstream improvements (e.g., traceability hooks, quality evidence)
+- Share safety-relevant documentation and argumentation templates
+- Coordinate efforts across users and vendors working toward similar goals
+- Act as a point of contact for safety-related collaboration
 
 The group is non-enforcing and does not control any part of the codebase.
 All technical decisions remain subject to the standard LLVM review and governance process.
 
-Group Composition
-=================
+## Group Composition
 
-Group Members
--------------
+### Group Members
 
 The members of the LLVM Qualification Group represent a diverse cross-section of the LLVM community, including individual contributors, researchers, vendor representatives, and experts in the field of software qualification, including reliability, quality, safety, and/or security.
-They meet the criteria for inclusion described in the sub-sections below and are identified as `active contributors <#contribution-principles>`_.
+They meet the criteria for inclusion described in the sub-sections below and are identified as [active contributors](#contribution-principles).
 Knowing their handles help us keep track of who’s who across platforms, coordinate activities, and recognize contributions.
 
+```{eval-rst}
 .. list-table::
    :widths: 20 20 20 20 20
    :header-rows: 1
@@ -87,81 +81,77 @@ Knowing their handles help us keep track of who’s who across platforms, coordi
      - quarkz99
      - zakyHermawan
 
+```
 
 Organizations are limited to three representatives within the group to maintain diversity.
 
-Participation
--------------
+### Participation
 
 There are several ways to participate:
 
-* Join discussions on the `LLVM Discourse <https://discourse.llvm.org/>`_ forum, under the "Community" category.
-* Engage in conversations on the LLVM Community Discord in the `#fusa-qual-wg <https://discord.com/channels/636084430946959380/1389362444169773117>`_ channel. Note: You need to join the community's `Discord chat server <https://llvm.org/docs/GettingInvolved.html#discord>`_ first.
-* Join our monthly sync-up calls. Details on working sessions and meeting minutes are shared on the :doc:`GettingInvolved` page.
-* Contribute ideas, feedback, or patches via GitHub, Discourse, or directly in working documents.
+- Join discussions on the [LLVM Discourse](https://discourse.llvm.org/) forum, under the "Community" category.
+- Engage in conversations on the LLVM Community Discord in the [#fusa-qual-wg](https://discord.com/channels/636084430946959380/1389362444169773117) channel. Note: You need to join the community's [Discord chat server](https://llvm.org/docs/GettingInvolved.html#discord) first.
+- Join our monthly sync-up calls. Details on working sessions and meeting minutes are shared on the {doc}`GettingInvolved` page.
+- Contribute ideas, feedback, or patches via GitHub, Discourse, or directly in working documents.
 
-Contribution Principles
------------------------
+### Contribution Principles
 
 We understand that most members contribute in a limited capacity due to their primary responsibilities. This initiative is volunteer-driven, and we operate with the following shared principles:
 
-* **Acknowledgement of limited bandwidth:** We recognize that no one is working full-time on this group, and participation will vary based on individual availability and priorities.
-* **Small and consistent contributions are valuable:** We believe that steady ongoing contributions, even if minimal, are crucial for long-term success, as long as there is coordination and respect for each other's time. Even small contributions (e.g., a few hours per month) can significantly advance the group's goals and have an impact. 
-* **Realistic progress expectations:** Given the voluntary nature and no full-time involvement, we expect our progress to be slow. This group was initiated in July 2025. Concrete outcomes in 1-2 years would be considered excellent for this type of cross-company and voluntary collaboration.
-* **Respect for differing capacities:** We value every member’s engagement, whether large or small, often or sporadically, as it all contributes to the overall effort. Even contributions that may seem small, such as sharing an idea or pointing out a relevant resource, are meaningful and important.
+- **Acknowledgement of limited bandwidth:** We recognize that no one is working full-time on this group, and participation will vary based on individual availability and priorities.
+- **Small and consistent contributions are valuable:** We believe that steady ongoing contributions, even if minimal, are crucial for long-term success, as long as there is coordination and respect for each other's time. Even small contributions (e.g., a few hours per month) can significantly advance the group's goals and have an impact.
+- **Realistic progress expectations:** Given the voluntary nature and no full-time involvement, we expect our progress to be slow. This group was initiated in July 2025. Concrete outcomes in 1-2 years would be considered excellent for this type of cross-company and voluntary collaboration.
+- **Respect for differing capacities:** We value every member’s engagement, whether large or small, often or sporadically, as it all contributes to the overall effort. Even contributions that may seem small, such as sharing an idea or pointing out a relevant resource, are meaningful and important.
 
 However, we need a balance between flexibility, structure, and enough organization to move forward together. Thus, to support coordination and clarity, the group distinguishes between **active contributors** and **observers / interested participants**.
 
 **Active contributors** are members who provide regular and substantive contributions to the group’s work. This includes ongoing engagement in at least one of the following:
 
-* Participation in sync-ups or asynchronous discussions (via Discord or Discourse),
-* Contributions to qualification artifacts, methodologies, documentation, structured reviews, or feedback on proposals and drafts,
-* Analysis, research activities, or support for coordination, outreach, or other working tasks.
+- Participation in sync-ups or asynchronous discussions (via Discord or Discourse),
+- Contributions to qualification artifacts, methodologies, documentation, structured reviews, or feedback on proposals and drafts,
+- Analysis, research activities, or support for coordination, outreach, or other working tasks.
 
-Active contribution implies sustained engagement that meaningfully advances the group’s objectives. Participation may be synchronous or asynchronous, depending on availability. Participation status reflects current bandwidth and coordination needs and may be updated during the `biannual membership review <#membership-review>`_.
+Active contribution implies sustained engagement that meaningfully advances the group’s objectives. Participation may be synchronous or asynchronous, depending on availability. Participation status reflects current bandwidth and coordination needs and may be updated during the [biannual membership review](#membership-review).
 
-**Observers**, or **interested participants** are anyone who follows the group’s work and may participate when availability allows. 
-This is an open status and does not require the `nomination process <#nomination-process>`_ used for active contributors. 
-Observers remain welcome to attend meetings, provide feedback, and contribute at any time. 
+**Observers**, or **interested participants** are anyone who follows the group’s work and may participate when availability allows.
+This is an open status and does not require the [nomination process](#nomination-process) used for active contributors.
+Observers remain welcome to attend meetings, provide feedback, and contribute at any time.
 Moreover, observer status does not imply reduced importance or access within the group.
 
-Membership Criteria
--------------------
+### Membership Criteria
 
 Membership in the LLVM Qualification Group is intended for individuals with relevant experience or active engagement in qualification-related efforts. Categories include:
 
 **Individual Contributors**
 
-  * Experience in software/tool qualification (e.g., reliability, quality, safety, security); OR  
-  * Active involvement in LLVM-related qualification efforts; OR  
-  * Significant LLVM contributions related to qualification in the past year (code, discussion, resolving related challenges).
+> - Experience in software/tool qualification (e.g., reliability, quality, safety, security); OR
+> - Active involvement in LLVM-related qualification efforts; OR
+> - Significant LLVM contributions related to qualification in the past year (code, discussion, resolving related challenges).
 
 **Researchers**
 
-  * Active research, publication, or development of methodologies, frameworks, or tools aimed at improving LLVM quality and reliability.
+> - Active research, publication, or development of methodologies, frameworks, or tools aimed at improving LLVM quality and reliability.
 
 **Vendor Contacts**
 
-  * Represent organizations building or using LLVM-based tools in safety-critical environments; OR  
-  * Require involvement due to organizational role in qualification or compliance.
+> - Represent organizations building or using LLVM-based tools in safety-critical environments; OR
+> - Require involvement due to organizational role in qualification or compliance.
 
-Nomination Process
-------------------
+### Nomination Process
 
 Individuals may nominate themselves or be nominated by an existing member. Nominations should:
 
-* Explain the nominee’s background and relevance to qualification efforts.
-* Be submitted via this form: `Participant Introduction & Membership <https://forms.gle/cE1kHjqkKNtafUrD7>`_
-* Be communicated to an active LLVM Qualification Group member (e.g., on the Discord channel).
+- Explain the nominee’s background and relevance to qualification efforts.
+- Be submitted via this form: [Participant Introduction & Membership](https://forms.gle/cE1kHjqkKNtafUrD7)
+- Be communicated to an active LLVM Qualification Group member (e.g., on the Discord channel).
 
-This nomination process applies to becoming an **active contributor**. People who simply wish to 
-follow the group’s work or participate occasionally may do so as observers / interested participants, 
+This nomination process applies to becoming an **active contributor**. People who simply wish to
+follow the group’s work or participate occasionally may do so as observers / interested participants,
 without a formal nomination process.
 
 Nominations are discussed within the group. If consensus is reached, the nominee is accepted. Otherwise, a majority vote will decide.
 
-Membership Review
------------------
+### Membership Review
 
 To ensure the group remains active and focused, member participation is reviewed every six months. Inactive members may be removed following this review.
 
@@ -169,52 +159,46 @@ During the biannual membership review, members who have not participated in disc
 
 This transition is procedural and does not restrict participation. Members may resume **active contributor** status at any time when their engagement increases.
 
-Decision Making
----------------
+### Decision Making
 
 The LLVM Qualification Working Group aims to make decisions transparently, collaboratively, and without unnecessary formality. The goal is to maintain efficiency while encouraging broad participation and mutual understanding.
 
 This section describes the lightweight process used to handle proposals and decisions within the group. It may be revised as the group evolves and gains experience.
 
-Principles
-^^^^^^^^^^
+#### Principles
 
-* **Consensus first:** The preferred mode of decision-making is consensus through open discussion (primarily on Discord or during sync-up meetings).
-* **Inclusiveness and respect:** All viewpoints are encouraged, and members are expected to contribute constructively toward reaching a shared understanding.
-* **Transparency:** Discussions leading to a decision should be visible to the group and, whenever appropriate, summarized in public channels (e.g., Discourse meeting notes, Discord channel, documentation updates).
+- **Consensus first:** The preferred mode of decision-making is consensus through open discussion (primarily on Discord or during sync-up meetings).
+- **Inclusiveness and respect:** All viewpoints are encouraged, and members are expected to contribute constructively toward reaching a shared understanding.
+- **Transparency:** Discussions leading to a decision should be visible to the group and, whenever appropriate, summarized in public channels (e.g., Discourse meeting notes, Discord channel, documentation updates).
 
-Consensus and Time Limits
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Consensus and Time Limits
 
 Discussions remain open until a clear consensus emerges, meaning no sustained objections have been raised after reasonable discussion.
 
 To prevent open-ended debates, if no new viewpoints are expressed after an agreed period (e.g., 2 weeks), the moderator (typically the person who started the discussion thread) may take one of the following actions:
 
-* **Summarize the apparent consensus** and close the discussion, or
-* **Postpone the topic** to the next sync-up meeting if the outcome remains unclear, or
-* **Call for a short vote** to confirm the group’s position.
+- **Summarize the apparent consensus** and close the discussion, or
+- **Postpone the topic** to the next sync-up meeting if the outcome remains unclear, or
+- **Call for a short vote** to confirm the group’s position.
 
-Voting Procedure
-^^^^^^^^^^^^^^^^
+#### Voting Procedure
 
 When consensus cannot be reached or when a clear yes/no decision is needed:
 
-* The moderator may call for a **simple vote** using emoji reactions on Discord or a similar visible method.
-* A decision passes if it receives a **majority (>50%)** of votes among **participants who voted.** Non-votes are **not counted** in the total.
-* To ensure decisions reflect the collective position of the group, **at least three-quarters of the total core members** must participate in the vote for it to be considered valid.
-* If results are evenly split **(50/50)**, or if participation falls below this threshold, the topic may be postponed to the next sync-up meeting for further discussion.
+- The moderator may call for a **simple vote** using emoji reactions on Discord or a similar visible method.
+- A decision passes if it receives a **majority (>50%)** of votes among **participants who voted.** Non-votes are **not counted** in the total.
+- To ensure decisions reflect the collective position of the group, **at least three-quarters of the total core members** must participate in the vote for it to be considered valid.
+- If results are evenly split **(50/50)**, or if participation falls below this threshold, the topic may be postponed to the next sync-up meeting for further discussion.
 
-Documentation
-^^^^^^^^^^^^^
+#### Documentation
 
 Final decisions should be briefly documented (e.g., in meeting minutes, the corresponding GitHub issue, or Discord discussion thread). Once stable, the resulting policy or outcome may be reflected in this documentation for reference.
 
-Working Group artifacts
-=======================
+## Working Group artifacts
 
 The LLVM Qualification Working Group develops and maintains its public
 artifacts and working materials in the
-`fusa-qual-wg directory of the llvm-wgs repository <https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg>`_.
+[fusa-qual-wg directory of the llvm-wgs repository](https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg).
 
 **This directory is the central location for the group's technical outputs**,
 including qualification guidance, documentation templates, analyses,
@@ -231,67 +215,61 @@ application.
 Feedback and contributions are welcome through the standard GitHub review
 process and the group's public discussion channels.
 
-Current Topics & Backlog
-========================
+## Current Topics & Backlog
 
 Our working group is actively engaged in discussions about the project's
-direction and tackling technical challenges. You can find our current 
-discussions, challenges, and the project backlog in the following 
-document: `Backlog <https://docs.google.com/document/d/10YZZ72ba09Ck_OiJaP9C4-7DeUiveaIKTE3IkaSKjzA/edit?usp=sharing>`_
+direction and tackling technical challenges. You can find our current
+discussions, challenges, and the project backlog in the following
+document: [Backlog](https://docs.google.com/document/d/10YZZ72ba09Ck_OiJaP9C4-7DeUiveaIKTE3IkaSKjzA/edit?usp=sharing)
 
 This document serves as our central hub for all ongoing topics and will
-be updated regularly to reflect our progress. We welcome your 
+be updated regularly to reflect our progress. We welcome your
 contributions and feedback.
 
-Meeting Materials
-=================
+## Meeting Materials
 
 Meeting agendas, minutes, and supporting materials are published to ensure transparency and continuity.
 
 Upcoming and past meeting agendas, and meeting minutes are published in a dedicated thread
-on the LLVM Discourse forum: `Meeting Agendas and Minutes <https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148>`_ 
+on the LLVM Discourse forum: [Meeting Agendas and Minutes](https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148)
 
 Slides used to support discussions during sync-up meetings are stored in a
-`dedicated Google Drive folder <https://drive.google.com/drive/u/1/folders/1nu3JAanE0gqQDll0S9ofVy4FOFezc6Mm>`_.
+[dedicated Google Drive folder](https://drive.google.com/drive/u/1/folders/1nu3JAanE0gqQDll0S9ofVy4FOFezc6Mm).
 Note that the naming convention for these slides is *YYYYMM*\_llvm_qual_wg.
 
 While Discourse is our active communication channel for agendas and announcements,
 the `llvm-wgs` repository is our durable, central location for both WG artifacts and meeting records.
-The `meeting directory in the llvm-wgs repository <https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings>`_
+The [meeting directory in the llvm-wgs repository](https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings)
 provides the long-term archive of the working group's meeting records. It contains:
 
-* `archived meeting materials <https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings/materials>`_, and
-* `archived meeting agendas and minutes <https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings/minutes>`_.
+- [archived meeting materials](https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings/materials), and
+- [archived meeting agendas and minutes](https://github.com/llvm/llvm-wgs/tree/main/fusa-qual-wg/meetings/minutes).
 
-AI Transcription Policy
-=======================
+## AI Transcription Policy
 
-Objective
----------
+### Objective
 
 The LLVM Qualification Group may enable AI auto-transcription (currently using Gemini) during sync-up calls in order to:
 
-* Make complex discussions easier to follow.
-* Reduce the effort of manual note-taking.
-* Support inclusivity for participants who are not native English speakers.
+- Make complex discussions easier to follow.
+- Reduce the effort of manual note-taking.
+- Support inclusivity for participants who are not native English speakers.
 
-Usage
------
+### Usage
 
 The purpose of auto-transcripts is to:
 
-* Ensure participants can remain engaged during the sync-up meeting (particularly helpful for non-native English speakers or when audio clarity is limited).
-* Serve as an aid for preparing the meeting minutes that are published on Discourse:
-  `Meeting Agendas and Minutes <https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148>`_
+- Ensure participants can remain engaged during the sync-up meeting (particularly helpful for non-native English speakers or when audio clarity is limited).
+- Serve as an aid for preparing the meeting minutes that are published on Discourse:
+  [Meeting Agendas and Minutes](https://discourse.llvm.org/t/llvm-qualification-wg-sync-ups-meeting-minutes/87148)
 
 Additional safeguards include:
 
-* Transcript files are private to the note-taker(s) and never circulated to attendees or the public.
-* Transcript files are permanently deleted once the minutes are posted.
-* The meeting chair or scribe remains responsible for reviewing the transcript, ensuring accuracy, and editing out sensitive details in the official minutes.
+- Transcript files are private to the note-taker(s) and never circulated to attendees or the public.
+- Transcript files are permanently deleted once the minutes are posted.
+- The meeting chair or scribe remains responsible for reviewing the transcript, ensuring accuracy, and editing out sensitive details in the official minutes.
 
-Vendor Retention
-----------------
+### Vendor Retention
 
 Long-term storage or model-training settings are disabled on the account used for organizing the working group calls.
 
@@ -299,73 +277,69 @@ However, according to Google’s Gemini documentation, even with all history fea
 
 This retention period cannot currently be shortened.
 
-Consent
--------
+### Consent
 
-* At the start of each sync-up, participants will be asked if they are comfortable with enabling auto-transcription.
-* If any participant objects, auto-transcription will be disabled for that meeting.
-* Participants may also request at any point that parts of the discussion not be transcribed.
+- At the start of each sync-up, participants will be asked if they are comfortable with enabling auto-transcription.
+- If any participant objects, auto-transcription will be disabled for that meeting.
+- Participants may also request at any point that parts of the discussion not be transcribed.
 
-Recordings
-----------
+### Recordings
 
-* Meetings are not recorded by default.
-* Exceptions are made only when explicit approval from attendees is obtained (e.g., for a special-hosted demo).
+- Meetings are not recorded by default.
+- Exceptions are made only when explicit approval from attendees is obtained (e.g., for a special-hosted demo).
 
-Transparency & Feedback
------------------------
+### Transparency & Feedback
 
 We want to ensure this practice remains transparent and comfortable for everyone. If any group members have concerns (e.g., about names appearing in transcripts or minutes), they are encouraged to raise them on Discourse or Discord so they can be addressed.
 
-Code of Conduct
-===============
+## Code of Conduct
 
-We are committed to fostering a respectful, inclusive, and constructive environment 
-where contributors from diverse backgrounds and organizations can collaborate 
-on qualification-related efforts in the LLVM ecosystem. 
+We are committed to fostering a respectful, inclusive, and constructive environment
+where contributors from diverse backgrounds and organizations can collaborate
+on qualification-related efforts in the LLVM ecosystem.
 To support this goal, we adopt the following principles:
 
-Let's Build This Together
--------------------------
-This is a space for shared ownership and mutual learning. If you're here, you belong. 
+### Let's Build This Together
+
+This is a space for shared ownership and mutual learning. If you're here, you belong.
 Help us shape a group where trust, technical rigor, and collaboration go hand in hand.
 
-Respect and Inclusion
----------------------
-* Treat all participants with respect and dignity, regardless of background, experience level, employer, or role in the community.
-* Be welcoming and supportive. We value a diversity of opinions and expertise.
-* Assume good intent, and ask questions before drawing conclusions.
-
-Constructive Collaboration
---------------------------
-* Keep discussions focused, technical, and solution-oriented.
-* Provide thoughtful, actionable feedback. Avoid sarcasm, dismissive remarks, or personal criticism.
-* Recognize that contributors have different constraints and priorities. Seek alignment, not perfection.
-
-Transparency and Openness
--------------------------
-* Share relevant information openly to enable others to contribute effectively.
-* Document decisions and rationales so others can understand and build on them.
-* Clearly distinguish between personal opinions, organizational positions, and community consensus.
-
-Unacceptable Behavior
----------------------
+### Respect and Inclusion
+
+- Treat all participants with respect and dignity, regardless of background, experience level, employer, or role in the community.
+- Be welcoming and supportive. We value a diversity of opinions and expertise.
+- Assume good intent, and ask questions before drawing conclusions.
+
+### Constructive Collaboration
+
+- Keep discussions focused, technical, and solution-oriented.
+- Provide thoughtful, actionable feedback. Avoid sarcasm, dismissive remarks, or personal criticism.
+- Recognize that contributors have different constraints and priorities. Seek alignment, not perfection.
+
+### Transparency and Openness
+
+- Share relevant information openly to enable others to contribute effectively.
+- Document decisions and rationales so others can understand and build on them.
+- Clearly distinguish between personal opinions, organizational positions, and community consensus.
+
+### Unacceptable Behavior
+
 We will not tolerate:
 
-* Harassment, discrimination, or exclusionary behavior.
-* Disruptive conduct in meetings or communication channels.
-* Using this group for marketing, lobbying, or promoting non-collaborative commercial agendas.
+- Harassment, discrimination, or exclusionary behavior.
+- Disruptive conduct in meetings or communication channels.
+- Using this group for marketing, lobbying, or promoting non-collaborative commercial agendas.
 
-Safety and Trust
-----------------
-* We aim to build qualification artifacts that others can trust. Similarly, we aim to be trustworthy collaborators.
-* If you see something concerning, speak up respectfully or contact the group organizer(s) privately.
-* We follow the LLVM Community :doc:`Code of Conduct <CodeOfConduct>`, which applies across all official LLVM communication spaces.
+### Safety and Trust
 
-Contact
-=======
+- We aim to build qualification artifacts that others can trust. Similarly, we aim to be trustworthy collaborators.
+- If you see something concerning, speak up respectfully or contact the group organizer(s) privately.
+- We follow the LLVM Community {doc}`Code of Conduct <CodeOfConduct>`, which applies across all official LLVM communication spaces.
+
+## Contact
 
 For more information or to get involved:
 
-* Refer to our initial `RFC: Proposal to Establish a Safety Group in LLVM <https://discourse.llvm.org/t/rfc-proposal-to-establish-a-safety-group-in-llvm/86916>`_ on the LLVM Discourse forum.
-* Join the conversation on the LLVM Community Discord in the `#fusa-qual-wg <https://discord.com/channels/636084430946959380/1389362444169773117>`_ channel.
+- Refer to our initial [RFC: Proposal to Establish a Safety Group in LLVM](https://discourse.llvm.org/t/rfc-proposal-to-establish-a-safety-group-in-llvm/86916) on the LLVM Discourse forum.
+- Join the conversation on the LLVM Community Discord in the [#fusa-qual-wg](https://discord.com/channels/636084430946959380/1389362444169773117) channel.
+
diff --git a/llvm/docs/ReleaseProcess.md b/llvm/docs/ReleaseProcess.md
index 6b8d988860e99..d210c5a69649c 100644
--- a/llvm/docs/ReleaseProcess.md
+++ b/llvm/docs/ReleaseProcess.md
@@ -1,29 +1,21 @@
-=============================
-How To Validate a New Release
-=============================
+# How To Validate a New Release
 
-
-Introduction
-============
+## Introduction
 
 This document contains information about testing the release candidates that
 will ultimately be the next LLVM release. For more information on how to
-manage the actual release, please refer to :doc:`HowToReleaseLLVM`.
+manage the actual release, please refer to {doc}`HowToReleaseLLVM`.
 
-Overview of the Release Process
--------------------------------
+### Overview of the Release Process
 
 Once the release process starts, the Release Manager will ask for volunteers,
 and it'll be the role of each volunteer to:
 
-* Test and benchmark the previous release
-
-* Test and benchmark each release candidate, comparing to the previous release
+- Test and benchmark the previous release
+- Test and benchmark each release candidate, comparing to the previous release
   and candidates
-
-* Identify, reduce and report every regression found during tests and benchmarks
-
-* Make sure the critical bugs get fixed and merged to the next release candidate
+- Identify, reduce and report every regression found during tests and benchmarks
+- Make sure the critical bugs get fixed and merged to the next release candidate
 
 Not all bugs or regressions are show-stoppers and it's a bit of a grey area what
 should be fixed before the next candidate and what can wait until the next
@@ -31,102 +23,93 @@ release.
 
 It'll depend on:
 
-* The severity of the bug, how many people it affects and if it's a regression
+- The severity of the bug, how many people it affects and if it's a regression
   or a known bug. Known bugs are "unsupported features" and some bugs can be
   disabled if they have been implemented recently.
-
-* The stage in the release. Less critical bugs should be considered to be
+- The stage in the release. Less critical bugs should be considered to be
   fixed between RC1 and RC2, but not so much at the end of it.
-
-* If it's a correctness or a performance regression. Performance regression
+- If it's a correctness or a performance regression. Performance regression
   tends to be taken more lightly than correctness.
 
-.. _scripts:
+(scripts)=
 
-Scripts
-=======
+## Scripts
 
-The scripts are in the ``utils/release`` directory.
+The scripts are in the `utils/release` directory.
 
-test-release.sh
----------------
+### test-release.sh
 
 This script will check-out, configure and compile LLVM+Clang (+ most add-ons,
-like ``compiler-rt``, ``libcxx``, ``libomp`` and ``clang-extra-tools``) in
+like `compiler-rt`, `libcxx`, `libomp` and `clang-extra-tools`) in
 three stages, and will test the final stage.
 It'll have installed the final binaries on the Phase3/Releasei(+Asserts)
 directory, and that's the one you should use for the test-suite and other
 external tests.
 
-To run the script on a specific release candidate run::
+To run the script on a specific release candidate run:
 
-   ./test-release.sh \
-        -release 3.3 \
-        -rc 1 \
-        -no-64bit \
-        -test-asserts \
-        -no-compare-files
+```
+./test-release.sh \
+     -release 3.3 \
+     -rc 1 \
+     -no-64bit \
+     -test-asserts \
+     -no-compare-files
+```
 
 Each system will require different options. For instance, x86_64 will
-obviously not need ``-no-64bit`` while 32-bit systems will, or the script will
+obviously not need `-no-64bit` while 32-bit systems will, or the script will
 fail.
 
 The important flags to get right are:
 
-* On the pre-release, you should change ``-rc 1`` to ``-final``. On RC2,
-  change it to ``-rc 2`` and so on.
-
-* On non-release testing, you can use ``-final`` in conjunction with
-  ``-no-checkout``, but you'll have to create the ``final`` directory by hand
-  and link the correct source dir to ``final/llvm.src``.
-
-* For release candidates, you need ``-test-asserts``, or it won't create a
+- On the pre-release, you should change `-rc 1` to `-final`. On RC2,
+  change it to `-rc 2` and so on.
+- On non-release testing, you can use `-final` in conjunction with
+  `-no-checkout`, but you'll have to create the `final` directory by hand
+  and link the correct source dir to `final/llvm.src`.
+- For release candidates, you need `-test-asserts`, or it won't create a
   "Release+Asserts" directory, which is needed for release testing and
   benchmarking. This will take twice as long.
-
-* On the final candidate you just need Release builds, and that's the binary
+- On the final candidate you just need Release builds, and that's the binary
   directory you'll have to pack.
-
-* On macOS, you must export ``MACOSX_DEPLOYMENT_TARGET=10.9`` before running
+- On macOS, you must export `MACOSX_DEPLOYMENT_TARGET=10.9` before running
   the script.
 
 This script builds three phases of Clang+LLVM twice each (Release and
 Release+Asserts), so use screen or nohup to avoid headaches, since it'll take
 a long time.
 
-Use the ``--help`` option to see all the options and chose it according to
+Use the `--help` option to see all the options and chose it according to
 your needs.
 
-
-findRegressions-nightly.py
---------------------------
+### findRegressions-nightly.py
 
 TODO
 
-.. _test-suite:
+(test-suite)=
 
-Test Suite
-==========
+## Test Suite
 
-
-Follow the `LNT Quick Start Guide
-<https://llvm.org/docs/lnt/quickstart.html>`__ link on how to set-up the
+Follow the [LNT Quick Start Guide](https://llvm.org/docs/lnt/quickstart.html) link on how to set-up the
 test-suite
 
 The binary location you'll have to use for testing is inside the
-``rcN/Phase3/Release+Asserts/llvmCore-REL-RC.install``.
+`rcN/Phase3/Release+Asserts/llvmCore-REL-RC.install`.
 Link that directory to an easier location and run the test-suite.
 
 An example on the run command line, assuming you created a link from the correct
-install directory to ``~/devel/llvm/install``::
-
-   ./sandbox/bin/python sandbox/bin/lnt runtest \
-       nt \
-       -j4 \
-       --sandbox sandbox \
-       --test-suite ~/devel/llvm/test/test-suite \
-       --cc ~/devel/llvm/install/bin/clang \
-       --cxx ~/devel/llvm/install/bin/clang++
+install directory to `~/devel/llvm/install`:
+
+```
+./sandbox/bin/python sandbox/bin/lnt runtest \
+    nt \
+    -j4 \
+    --sandbox sandbox \
+    --test-suite ~/devel/llvm/test/test-suite \
+    --cc ~/devel/llvm/install/bin/clang \
+    --cxx ~/devel/llvm/install/bin/clang++
+```
 
 It should have no new regressions, compared to the previous release or release
 candidate. You don't need to fix all the bugs in the test-suite, since they're
@@ -140,11 +123,9 @@ as blocker, and all the other bugs as important, but not necessarily blocking
 the release to proceed. They can be set as "known failures" and to be
 fixed on a future date.
 
-.. _pre-release-process:
-
-Pre-Release Process
-===================
+(pre-release-process)=
 
+## Pre-Release Process
 
 When the release process is announced on the mailing list, you should prepare
 for the testing, by applying the same testing you'll do on the release
@@ -152,27 +133,22 @@ candidates, on the previous release.
 
 You should:
 
-* Download the previous release sources from
-  https://llvm.org/releases/download.html.
-
-* Run the test-release.sh script on ``final`` mode (change ``-rc 1`` to
-  ``-final``).
-
-* Once all three stages are done, it'll test the final stage.
-
-* Using the ``Phase3/Release+Asserts/llvmCore-MAJ.MIN-final.install`` base,
+- Download the previous release sources from
+  <https://llvm.org/releases/download.html>.
+- Run the test-release.sh script on `final` mode (change `-rc 1` to
+  `-final`).
+- Once all three stages are done, it'll test the final stage.
+- Using the `Phase3/Release+Asserts/llvmCore-MAJ.MIN-final.install` base,
   run the test-suite.
 
-If the final phase's ``make check-all`` failed, it's a good idea to also test
+If the final phase's `make check-all` failed, it's a good idea to also test
 the intermediate stages by going on the obj directory and running
-``make check-all`` to find if there's at least one stage that passes (helps
+`make check-all` to find if there's at least one stage that passes (helps
 when reducing the error for bug report purposes).
 
-.. _release-process:
-
-Release Process
-===============
+(release-process)=
 
+## Release Process
 
 When the Release Manager sends you the release candidate, download all sources,
 unzip on the same directory (there will be sym-links from the appropriate places
@@ -180,44 +156,36 @@ to them), and run the release test as above.
 
 You should:
 
-* Download the current candidate sources from where the release manager points
-  you (ex. https://llvm.org/pre-releases/3.3/rc1/).
-
-* Repeat the steps above with ``-rc 1``, ``-rc 2`` etc modes and run the
+- Download the current candidate sources from where the release manager points
+  you (ex. <https://llvm.org/pre-releases/3.3/rc1/>).
+- Repeat the steps above with `-rc 1`, `-rc 2` etc modes and run the
   test-suite the same way.
-
-* Compare the results, report all errors on Bugzilla and publish the binary blob
+- Compare the results, report all errors on Bugzilla and publish the binary blob
   where the release manager can grab it.
 
 Once the release manager announces that the latest candidate is the good one,
-you have to pack the ``Release`` (no Asserts) install directory on ``Phase3``
+you have to pack the `Release` (no Asserts) install directory on `Phase3`
 and that will be the official binary.
 
-* Rename (or link) ``clang+llvm-REL-ARCH-ENV`` to the .install directory
-
-* Tar that into the same name with ``.tar.gz`` extension from outside the
+- Rename (or link) `clang+llvm-REL-ARCH-ENV` to the .install directory
+- Tar that into the same name with `.tar.gz` extension from outside the
   directory
+- Make it available for the release manager to download
 
-* Make it available for the release manager to download
-
-.. _bug-reporting:
-
-Bug Reporting Process
-=====================
+(bug-reporting)=
 
+## Bug Reporting Process
 
 If you found regressions or failures when comparing a release candidate with the
 previous release, follow the rules below:
 
-* Critical bugs on compilation should be fixed as soon as possible, possibly
+- Critical bugs on compilation should be fixed as soon as possible, possibly
   before releasing the binary blobs.
-
-* Check-all tests should be fixed before the next release candidate, but can
+- Check-all tests should be fixed before the next release candidate, but can
   wait until the test-suite run is finished.
-
-* Bugs in the test suite or unimportant check-all tests can be fixed in between
+- Bugs in the test suite or unimportant check-all tests can be fixed in between
   release candidates.
-
-* New features or recent big changes, when close to the release, should have
+- New features or recent big changes, when close to the release, should have
   done in a way that it's easy to disable. If they misbehave, prefer disabling
   them than releasing an unstable (but untested) binary package.
+
diff --git a/llvm/docs/ScudoHardenedAllocator.md b/llvm/docs/ScudoHardenedAllocator.md
index 7ac6522f90a49..a1982c978ef0b 100644
--- a/llvm/docs/ScudoHardenedAllocator.md
+++ b/llvm/docs/ScudoHardenedAllocator.md
@@ -1,28 +1,23 @@
-========================
-Scudo Hardened Allocator
-========================
+# Scudo Hardened Allocator
 
-
-Introduction
-============
+## Introduction
 
 The Scudo Hardened Allocator is a user-mode allocator, originally based on LLVM
 Sanitizers'
-`CombinedAllocator <https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h>`_.
+[CombinedAllocator](https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h).
 It aims at providing additional mitigation against heap based vulnerabilities,
 while maintaining good performance. Scudo is currently the default allocator in
-`Fuchsia <https://fuchsia.dev/>`_, and in `Android <https://www.android.com/>`_
+[Fuchsia](https://fuchsia.dev/), and in [Android](https://www.android.com/)
 since Android 11.
 
 The name "Scudo" comes from the Italian word for
-`shield <https://www.collinsdictionary.com/dictionary/italian-english/scudo>`_
+[shield](https://www.collinsdictionary.com/dictionary/italian-english/scudo)
 (and Escudo in Spanish).
 
-Design
-======
+## Design
+
+### Allocator
 
-Allocator
----------
 Scudo was designed with security in mind, but aims at striking a good balance
 between security and performance. It was designed to be highly tunable and
 configurable, and while we provide some default configurations, we encourage
@@ -35,17 +30,14 @@ The allocator combines several components that serve distinct purposes:
   sizes by carving reserved memory regions into blocks of identical size. There
   are currently two Primary allocators implemented, specific to 32- and 64-bit
   architectures. It is configurable via compile time options.
-
 - the Secondary allocator: slower, it services larger allocation sizes via the
   memory mapping primitives of the underlying operating system. Secondary backed
   allocations are surrounded by Guard Pages. It is also configurable via compile
   time options.
-
 - the thread specific data Registry: defines how local caches operate for each
   thread. There are currently two models implemented: the exclusive model where
   each thread holds its own caches (using the ELF TLS); or the shared model
   where threads share a fixed size pool of caches.
-
 - the Quarantine: offers a way to delay the deallocation operations, preventing
   blocks to be immediately available for reuse. Blocks held will be recycled
   once certain size criteria are reached. This is essentially a delayed freelist
@@ -53,14 +45,13 @@ The allocator combines several components that serve distinct purposes:
   costly in terms of performance and memory footprint, is mostly controlled by
   runtime options and is disabled by default.
 
-Allocations Header
-------------------
+### Allocations Header
+
 Every chunk of heap memory returned to an application by the allocator will be
 preceded by a header. This has two purposes:
 
 - being to store various information about the chunk, that can be leveraged to
   ensure consistency of the heap operations;
-
 - being able to detect potential corruption. For this purpose, the header is
   checksummed and corruption of the header will be detected when said header is
   accessed (note that if the corrupted header is not accessed, the corruption
@@ -70,18 +61,13 @@ The following information is stored in the header:
 
 - the class ID for that chunk, which identifies the region where the chunk
   resides for Primary backed allocations, or 0 for Secondary backed allocations;
-
 - the state of the chunk (available, allocated or quarantined);
-
 - the allocation type (malloc, new, new[] or memalign), to detect potential
   mismatches in the allocation APIs used;
-
 - the size (Primary) or unused bytes amount (Secondary) for that chunk, which is
   necessary for reallocation or sized-deallocation operations;
-
 - the offset of the chunk, which is the distance in bytes from the beginning of
   the returned chunk to the beginning of the backend allocation (the "block");
-
 - the 16-bit checksum;
 
 This header fits within 8 bytes on all platforms supported, and contributes to a
@@ -97,8 +83,8 @@ as two consecutive chunks could belong to different threads. We work on local
 copies and use compare-exchange primitives to update the headers in the heap
 memory, and avoid any type of double-fetching.
 
-Randomness
-----------
+### Randomness
+
 Randomness is a critical factor to the additional security provided by the
 allocator. The allocator trusts the memory mapping primitives of the OS to
 provide pages at (mostly) non-predictable locations in memory, as well as the
@@ -107,8 +93,8 @@ incorrect, the security will be greatly reduced. Scudo further randomizes how
 blocks are allocated in the Primary, can randomize how caches are assigned to
 threads.
 
-Memory reclaiming
------------------
+### Memory reclaiming
+
 Primary and Secondary allocators have different behaviors with regard to
 reclaiming. While Secondary mapped allocations can be unmapped on deallocation,
 it isn't the case for the Primary, which could lead to a steady growth of the
@@ -118,23 +104,22 @@ released: this generally means they won't count towards the RSS of a process and
 be zero filled on subsequent accesses). This is done in the deallocation path,
 and several options exist to tune this behavior.
 
-Usage
-=====
+## Usage
+
+### Platform
 
-Platform
---------
 If using Fuchsia or an Android version greater than 11, your memory allocations
 are already service by Scudo (note that Android Svelte configurations still use
 jemalloc).
 
-Library
--------
+### Library
+
 The allocator static library can be built from the LLVM tree thanks to the
-``scudo_standalone`` CMake rule. The associated tests can be exercised thanks to
-the ``check-scudo_standalone`` CMake rule.
+`scudo_standalone` CMake rule. The associated tests can be exercised thanks to
+the `check-scudo_standalone` CMake rule.
 
 Linking the static library to your project can require the use of the
-``whole-archive`` linker flag (or equivalent), depending on your linker.
+`whole-archive` linker flag (or equivalent), depending on your linker.
 Additional flags might also be necessary.
 
 Your linked binary should now make use of the Scudo allocation and deallocation
@@ -142,49 +127,46 @@ functions.
 
 You may also build Scudo like this:
 
-.. code:: console
-
-  cd $LLVM/compiler-rt/lib
-  clang++ -fPIC -std=c++17 -msse4.2 -O2 -pthread -shared \
-    -I scudo/standalone/include \
-    scudo/standalone/*.cpp \
-    -o $HOME/libscudo.so
+```console
+cd $LLVM/compiler-rt/lib
+clang++ -fPIC -std=c++17 -msse4.2 -O2 -pthread -shared \
+  -I scudo/standalone/include \
+  scudo/standalone/*.cpp \
+  -o $HOME/libscudo.so
+```
 
 and then use it with existing binaries as follows:
 
-.. code:: console
+```console
+LD_PRELOAD=$HOME/libscudo.so ./a.out
+```
 
-  LD_PRELOAD=$HOME/libscudo.so ./a.out
+### Clang
 
-Clang
------
 With a recent version of Clang (post rL317337), the "old" version of the
 allocator can be linked with a binary at compilation using the
-``-fsanitize=scudo`` command-line argument, if the target platform is supported.
+`-fsanitize=scudo` command-line argument, if the target platform is supported.
 Currently, the only other sanitizer Scudo is compatible with is UBSan
-(eg: ``-fsanitize=scudo,undefined``). Compiling with Scudo will also enforce
+(eg: `-fsanitize=scudo,undefined`). Compiling with Scudo will also enforce
 PIE for the output binary.
 
 We will transition this to the standalone Scudo version in the future.
 
-Options
--------
+### Options
+
 Several aspects of the allocator can be configured on a per process basis
 through the following ways:
 
-- at compile time, by defining ``SCUDO_DEFAULT_OPTIONS`` to the options string
+- at compile time, by defining `SCUDO_DEFAULT_OPTIONS` to the options string
   you want set by default;
-
-- by defining a ``__scudo_default_options`` function in one's program that
+- by defining a `__scudo_default_options` function in one's program that
   returns the options string to be parsed. Said function must have the following
-  prototype: ``extern "C" const char* __scudo_default_options(void)``, with a
+  prototype: `extern "C" const char* __scudo_default_options(void)`, with a
   default visibility. This will override the compile time define;
-
 - through the environment variable SCUDO_OPTIONS, containing the options string
   to be parsed. Options defined this way will override any definition made
-  through ``__scudo_default_options``.
-
-- via the standard ``mallopt`` `API <https://man7.org/linux/man-pages/man3/mallopt.3.html>`_,
+  through `__scudo_default_options`.
+- via the standard `mallopt` [API](https://man7.org/linux/man-pages/man3/mallopt.3.html),
   using parameters that are Scudo specific.
 
 When dealing with the options string, it follows a syntax similar to ASan, where
@@ -192,21 +174,21 @@ distinct options can be assigned in the same string, separated by colons.
 
 For example, using the environment variable:
 
-.. code:: console
-
-  SCUDO_OPTIONS="delete_size_mismatch=false:release_to_os_interval_ms=-1" ./a.out
+```console
+SCUDO_OPTIONS="delete_size_mismatch=false:release_to_os_interval_ms=-1" ./a.out
+```
 
 Or using the function:
 
-.. code:: cpp
-
-  extern "C" const char *__scudo_default_options() {
-    return "delete_size_mismatch=false:release_to_os_interval_ms=-1";
-  }
-
+```cpp
+extern "C" const char *__scudo_default_options() {
+  return "delete_size_mismatch=false:release_to_os_interval_ms=-1";
+}
+```
 
 The following "string" options are available:
 
+```{eval-rst}
 +---------------------------------+----------------+-------------------------------------------------+
 | Option                          | Default        | Description                                     |
 +---------------------------------+----------------+-------------------------------------------------+
@@ -264,13 +246,15 @@ The following "string" options are available:
 |                                 |                | the scudo_malloc_set_track_allocation_stacks    |
 |                                 |                | function.                                       |
 +---------------------------------+----------------+-------------------------------------------------+
+```
 
 Additional flags can be specified, for example if Scudo if compiled with
-`GWP-ASan <https://llvm.org/docs/GwpAsan.html>`_ support.
+[GWP-ASan](https://llvm.org/docs/GwpAsan.html) support.
 
 The following "mallopt" options are available (options are defined in
-``include/scudo/interface.h``):
+`include/scudo/interface.h`):
 
+```{eval-rst}
 +---------------------------+-------------------------------------------------------+
 | Option                    | Description                                           |
 +---------------------------+-------------------------------------------------------+
@@ -308,52 +292,46 @@ The following "mallopt" options are available (options are defined in
 | M_TSDS_COUNT_MAX          | Increases the maximum number of TSDs that can be used |
 |                           | up to the limit specified at compile time.            |
 +---------------------------+-------------------------------------------------------+
+```
 
-Error Types
-===========
+## Error Types
 
 The allocator will output an error message, and potentially terminate the
 process, when an unexpected behavior is detected. The output usually starts with
-``"Scudo ERROR:"`` followed by a short summary of the problem that occurred as
+`"Scudo ERROR:"` followed by a short summary of the problem that occurred as
 well as the pointer(s) involved. Once again, Scudo is meant to be a mitigation,
 and might not be the most useful of tools to help you root-cause the issue,
-please consider `ASan <https://github.com/google/sanitizers/wiki/AddressSanitizer>`_
+please consider [ASan](https://github.com/google/sanitizers/wiki/AddressSanitizer)
 for this purpose.
 
 Here is a list of the current error messages and their potential cause:
 
-- ``"corrupted chunk header"``: the checksum verification of the chunk header
+- `"corrupted chunk header"`: the checksum verification of the chunk header
   has failed. This is likely due to one of two things: the header was
   overwritten (partially or totally), or the pointer passed to the function is
   not a chunk at all;
-
-- ``"race on chunk header"``: two different threads are attempting to manipulate
+- `"race on chunk header"`: two different threads are attempting to manipulate
   the same header at the same time. This is usually symptomatic of a
   race-condition or general lack of locking when performing operations on that
   chunk;
-
-- ``"invalid chunk state"``: the chunk is not in the expected state for a given
+- `"invalid chunk state"`: the chunk is not in the expected state for a given
   operation, eg: it is not allocated when trying to free it, or it's not
   quarantined when trying to recycle it, etc. A double-free is the typical
   reason this error would occur;
-
-- ``"misaligned pointer"``: we strongly enforce basic alignment requirements, 8
+- `"misaligned pointer"`: we strongly enforce basic alignment requirements, 8
   bytes on 32-bit platforms, 16 bytes on 64-bit platforms. If a pointer passed
   to our functions does not fit those, something is definitely wrong.
-
-- ``"allocation type mismatch"``: when the optional deallocation type mismatch
+- `"allocation type mismatch"`: when the optional deallocation type mismatch
   check is enabled, a deallocation function called on a chunk has to match the
   type of function that was called to allocate it. Security implications of such
   a mismatch are not necessarily obvious but situational at best;
-
-- ``"invalid sized delete"``: when the C++14 sized delete operator is used, and
+- `"invalid sized delete"`: when the C++14 sized delete operator is used, and
   the optional check enabled, this indicates that the size passed when
   deallocating a chunk is not congruent with the one requested when allocating
-  it. This is likely to be a `compiler issue <https://software.intel.com/en-us/forums/intel-c-compiler/topic/783942>`_,
+  it. This is likely to be a [compiler issue](https://software.intel.com/en-us/forums/intel-c-compiler/topic/783942),
   as was the case with Intel C++ Compiler, or some type confusion on the object
   being deallocated;
-
-- ``"RSS limit exhausted"``: the maximum RSS optionally specified has been
+- `"RSS limit exhausted"`: the maximum RSS optionally specified has been
   exceeded;
 
 Several other error messages relate to parameter checking on the libc allocation
diff --git a/llvm/docs/Security.md b/llvm/docs/Security.md
index 9c586437d25c1..108532838faad 100644
--- a/llvm/docs/Security.md
+++ b/llvm/docs/Security.md
@@ -1,6 +1,4 @@
-============================
-LLVM Security Response Group
-============================
+# LLVM Security Response Group
 
 The LLVM Security Response Group has the following goals:
 
@@ -8,79 +6,74 @@ The LLVM Security Response Group has the following goals:
 2. Organize fixes, code reviews, and release management for said issues.
 3. Allow distributors time to investigate and deploy fixes before wide dissemination of vulnerabilities or mitigation shortcomings.
 4. Ensure timely notification and release to vendors who package and distribute LLVM-based toolchains and projects.
-5. Ensure timely notification to users of LLVM-based toolchains whose compiled code is security-sensitive, through the `CVE process`_.
+5. Ensure timely notification to users of LLVM-based toolchains whose compiled code is security-sensitive, through the [CVE process][cve process].
 
 *Note*: these goals ensure timely action, provide disclosure timing when issues are reported, and respect vendors' / packagers' / users' constraints.
 
 The LLVM Security Response Group is private. It is composed of trusted LLVM contributors. Its discussions remain within the LLVM Security Response Group (plus issue reporter and key experts) while an issue is being investigated. After an issue becomes public, the entirety of the group’s discussions pertaining to that issue also become public.
 
-.. _report-security-issue:
+(report-security-issue)=
 
-How to report a security issue?
-===============================
+## How to report a security issue?
 
-To report a security issue in any of the LLVM projects, please use the `report a vulnerability`_ feature in the `llvm/llvm-security-repo`_ repository on github, under the "Security" tab.
+To report a security issue in any of the LLVM projects, please use the [report a vulnerability][report a vulnerability] feature in the [llvm/llvm-security-repo][llvm/llvm-security-repo] repository on github, under the "Security" tab.
 
-We aim to acknowledge your report within two business days since you first reach out. If you do not receive any response by then, you can escalate by posting on the `Discourse forums`_ asking to get in touch with someone from the LLVM Security Response Group. **The escalation mailing list is public**: avoid discussing or mentioning the specific issue when posting on it.
+We aim to acknowledge your report within two business days since you first reach out. If you do not receive any response by then, you can escalate by posting on the [Discourse forums][discourse forums] asking to get in touch with someone from the LLVM Security Response Group. **The escalation mailing list is public**: avoid discussing or mentioning the specific issue when posting on it.
 
+## Group Composition
 
-Group Composition
-=================
-
-Security Response Group Members
--------------------------------
+### Security Response Group Members
 
 The members of the group represent a wide cross-section of the community, and
 meet the criteria for inclusion below. The list is in the format
 `* ${full_name} (${affiliation}) [${github_username}]`. If a github
 username for an individual isn't available, the brackets will be empty.
 
-* Abhay Kanhere (Apple) [@AbhayKanhere]
-* Ahmed Bougacha (Apple) [@ahmedbougacha]
-* Artur Pilipenko (Azul Systems Inc) []
-* Boovaragavan Dasarathan (Nvidia) [@mrragava]
-* Dimitry Andric (individual; FreeBSD) [@DimitryAndric]
-* Ed Maste (individual; FreeBSD) [@emaste]
-* Gabor Spaits (HighTec EDV Systeme) [@spaits]
-* George Burgess IV (Google) [@gburgessiv]
-* Kristof Beyls (ARM) [@kbeyls]
-* Mario Cupelli (HighTec EDV Systeme) [@mariocup]
-* Matthew Riley (Google) [@mmdriley]
-* Matthew Voss (Sony) [@ormris]
-* Nikhil Gupta (Nvidia) []
-* Oliver Hunt (Apple) [@ojhunt]
-* Peter Smith (ARM) [@smithp35]
-* Pietro Albini (Oxide Computer Company; Rust) [@pietroalbini]
-* Serge Guelton (Mozilla) [@serge-sans-paille]
-* Sergey Zverev (Intel) [@offsake]
-* Shayne Hiet-Block (Microsoft) [@GreatKeeper]
-* Tim Penge (Sony) [@tpenge]
-* Tulio Magno Quites Machado Filho (Red Hat) [@tuliom]
-* Will Huhn (Intel) [@wphuhn-intel]
-* Yvan Roux (ST) [@yroux]
-
-Criteria
---------
-
-* Nominees for LLVM Security Response Group membership should fall in one of these groups:
+- Abhay Kanhere (Apple) [@AbhayKanhere]
+- Ahmed Bougacha (Apple) [@ahmedbougacha]
+- Artur Pilipenko (Azul Systems Inc) []
+- Boovaragavan Dasarathan (Nvidia) [@mrragava]
+- Dimitry Andric (individual; FreeBSD) [@DimitryAndric]
+- Ed Maste (individual; FreeBSD) [@emaste]
+- Gabor Spaits (HighTec EDV Systeme) [@spaits]
+- George Burgess IV (Google) [@gburgessiv]
+- Kristof Beyls (ARM) [@kbeyls]
+- Mario Cupelli (HighTec EDV Systeme) [@mariocup]
+- Matthew Riley (Google) [@mmdriley]
+- Matthew Voss (Sony) [@ormris]
+- Nikhil Gupta (Nvidia) []
+- Oliver Hunt (Apple) [@ojhunt]
+- Peter Smith (ARM) [@smithp35]
+- Pietro Albini (Oxide Computer Company; Rust) [@pietroalbini]
+- Serge Guelton (Mozilla) [@serge-sans-paille]
+- Sergey Zverev (Intel) [@offsake]
+- Shayne Hiet-Block (Microsoft) [@GreatKeeper]
+- Tim Penge (Sony) [@tpenge]
+- Tulio Magno Quites Machado Filho (Red Hat) [@tuliom]
+- Will Huhn (Intel) [@wphuhn-intel]
+- Yvan Roux (ST) [@yroux]
+
+### Criteria
+
+- Nominees for LLVM Security Response Group membership should fall in one of these groups:
 
   - Individual contributors:
 
-    + Specializes in fixing compiler-based security related issues or often participates in their exploration and resolution.
-    + Has a track record of finding security vulnerabilities and responsible disclosure of those vulnerabilities.
-    + Is a compiler expert who has specific interests in knowing about, resolving, and preventing future security vulnerabilities.
-    + Has actively contributed non-trivial code to the LLVM project in the last year.
+    - Specializes in fixing compiler-based security related issues or often participates in their exploration and resolution.
+    - Has a track record of finding security vulnerabilities and responsible disclosure of those vulnerabilities.
+    - Is a compiler expert who has specific interests in knowing about, resolving, and preventing future security vulnerabilities.
+    - Has actively contributed non-trivial code to the LLVM project in the last year.
 
   - Researchers:
 
-    + Has a track record of finding security vulnerabilities and responsible disclosure of those vulnerabilities.
-    + Is a compiler expert who has specific interests in knowing about, resolving, and preventing future security vulnerabilities.
+    - Has a track record of finding security vulnerabilities and responsible disclosure of those vulnerabilities.
+    - Is a compiler expert who has specific interests in knowing about, resolving, and preventing future security vulnerabilities.
 
   - Vendor contacts:
 
-    + Represents an organization or company which ships products that include their own copy of LLVM. Due to their position in the organization, the nominee has a reasonable need to know about security issues and disclosure embargoes.
+    - Represents an organization or company which ships products that include their own copy of LLVM. Due to their position in the organization, the nominee has a reasonable need to know about security issues and disclosure embargoes.
 
-* Additionally, the following are necessary but not sufficient criteria for membership in the LLVM Security Response Group:
+- Additionally, the following are necessary but not sufficient criteria for membership in the LLVM Security Response Group:
 
   - If already in the LLVM Security Response Group, has actively participated in one (if any) security issue in the last year.
   - If already in the LLVM Security Response Group, has actively participated in most membership discussions in the last year.
@@ -89,120 +82,103 @@ Criteria
   - When nominated as a vendor contact, their position with that vendor remains the same as when originally nominated.
   - Nominees are trusted by existing LLVM Security Response Group members to keep communications embargoed while still active.
 
-Nomination process
-------------------
+### Nomination process
 
 Anyone who feels they meet these criteria can nominate themselves, or may be nominated by a third party such as an existing LLVM Security Response Group member. The nomination should state whether the nominee is nominated as an individual, researcher, or as a vendor contact. It should clearly describe the grounds for nomination.
 
-For the moment, nominations are generally proposed, discussed, and voted on using a GitHub pull request. An `example nomination is available here`_. The use of pull requests helps keep membership discussions open, transparent, and easily accessible to LLVM developers in many ways. If, for any reason, a fully-world-readable nomination seems inappropriate, you may reach out to the LLVM Security Response Group via the `report a vulnerability`_ route, and a discussion can be had about the best way to approach nomination, given the constraints that individuals are under.
+For the moment, nominations are generally proposed, discussed, and voted on using a GitHub pull request. An [example nomination is available here][example nomination is available here]. The use of pull requests helps keep membership discussions open, transparent, and easily accessible to LLVM developers in many ways. If, for any reason, a fully-world-readable nomination seems inappropriate, you may reach out to the LLVM Security Response Group via the [report a vulnerability][report a vulnerability] route, and a discussion can be had about the best way to approach nomination, given the constraints that individuals are under.
 
-Choosing new members
---------------------
+### Choosing new members
 
 If a nomination for LLVM Security Response Group membership is supported by a majority of existing LLVM Security Response Group members, then it carries within five business days unless an existing member of the Security Response Group objects. If an objection is raised, the LLVM Security Response Group members should discuss the matter and try to come to consensus; failing this, the nomination will succeed only by a two-thirds supermajority vote of the LLVM Security Response Group.
 
-Accepting membership
---------------------
+### Accepting membership
 
-Before new LLVM Security Response Group membership is finalized, the successful nominee should accept membership and agree to abide by this security policy, particularly `Privileges and Responsibilities of LLVM Security Response Group Members`_ below.
+Before new LLVM Security Response Group membership is finalized, the successful nominee should accept membership and agree to abide by this security policy, particularly [Privileges and Responsibilities of LLVM Security Response Group Members] below.
 
-Keeping Membership Current
---------------------------
+### Keeping Membership Current
 
-* At least every six months, the LLVM Security Response Group applies the above criteria. The membership list is pruned accordingly.
-* Any LLVM Security Response Group member can ask that the criteria be applied within the next five business days.
-* If a member of the LLVM Security Response Group does not act in accordance with the letter and spirit of this policy, then their LLVM Security Response Group membership can be revoked by a majority vote of the members, not including the person under consideration for revocation. After a member calls for a revocation vote, voting will be open for five business days.
-* Emergency suspension: an LLVM Security Response Group member who blatantly disregards the LLVM Security Policy may have their membership temporarily suspended on the request of any two members. In such a case, the requesting members should notify the LLVM Security Response Group with a description of the offense. At this point, membership will be temporarily suspended for five business days, pending outcome of the vote for permanent revocation.
-* The LLVM Board may remove any member from the LLVM Security Response Group.
+- At least every six months, the LLVM Security Response Group applies the above criteria. The membership list is pruned accordingly.
+- Any LLVM Security Response Group member can ask that the criteria be applied within the next five business days.
+- If a member of the LLVM Security Response Group does not act in accordance with the letter and spirit of this policy, then their LLVM Security Response Group membership can be revoked by a majority vote of the members, not including the person under consideration for revocation. After a member calls for a revocation vote, voting will be open for five business days.
+- Emergency suspension: an LLVM Security Response Group member who blatantly disregards the LLVM Security Policy may have their membership temporarily suspended on the request of any two members. In such a case, the requesting members should notify the LLVM Security Response Group with a description of the offense. At this point, membership will be temporarily suspended for five business days, pending outcome of the vote for permanent revocation.
+- The LLVM Board may remove any member from the LLVM Security Response Group.
 
-Transparency Report
--------------------
+### Transparency Report
 
 Every year, the LLVM Security Response Group must publish a transparency report. The intent of this report is to keep the community informed by summarizing the disclosures that have been made public in the last year. It shall contain a list of all public disclosures, as well as statistics on time to fix issues, length of embargo periods, and so on.
 
-The transparency reports are published at :doc:`SecurityTransparencyReports`.
-
+The transparency reports are published at {doc}`SecurityTransparencyReports`.
 
-Privileges and Responsibilities of LLVM Security Response Group Members
-=======================================================================
+## Privileges and Responsibilities of LLVM Security Response Group Members
 
-Access
-------
+### Access
 
-LLVM Security Response Group members will be subscribed to a private `Discussion Medium`_. It will be used for technical discussions of security issues, as well as process discussions about matters such as disclosure timelines and group membership. Members have access to all security issues.
+LLVM Security Response Group members will be subscribed to a private [Discussion Medium]. It will be used for technical discussions of security issues, as well as process discussions about matters such as disclosure timelines and group membership. Members have access to all security issues.
 
-Confidentiality
----------------
+### Confidentiality
 
 Members of the LLVM Security Response Group will be expected to treat LLVM security issue information shared with the group as confidential until publicly disclosed:
 
-* Members should not disclose security issue information to non-members unless both members are employed by the same vendor of a LLVM based product, in which case information can be shared within that organization on a need-to-know basis and handled as confidential information normally is within that organization.
-* If the LLVM Security Response Group agrees, designated members may share issues with vendors of non-LLVM based products if their product suffers from the same issue. The non-LLVM vendor should be asked to respect the issue’s embargo date, and to not share the information beyond the need-to-know people within their organization.
-* If the LLVM Security Response Group agrees, key experts can be brought in to help address particular issues. The key expert should be asked to respect the issue’s embargo date, and to not share the information.
+- Members should not disclose security issue information to non-members unless both members are employed by the same vendor of a LLVM based product, in which case information can be shared within that organization on a need-to-know basis and handled as confidential information normally is within that organization.
+- If the LLVM Security Response Group agrees, designated members may share issues with vendors of non-LLVM based products if their product suffers from the same issue. The non-LLVM vendor should be asked to respect the issue’s embargo date, and to not share the information beyond the need-to-know people within their organization.
+- If the LLVM Security Response Group agrees, key experts can be brought in to help address particular issues. The key expert should be asked to respect the issue’s embargo date, and to not share the information.
 
-Disclosure
-----------
+### Disclosure
 
 Following the process below, the LLVM Security Response Group decides on embargo date for public disclosure for each Security issue. An embargo may be lifted before the agreed-upon date if all vendors planning to ship a fix have already done so, and if the reporter does not object.
 
-Collaboration
--------------
+### Collaboration
 
 Members of the LLVM Security Response Group are expected to:
 
-* Promptly share any LLVM vulnerabilities they become aware of.
-* Volunteer to drive issues forward.
-* Help evaluate the severity of incoming issues.
-* Help write and review patches to address security issues.
-* Participate in the member nomination and removal processes.
+- Promptly share any LLVM vulnerabilities they become aware of.
+- Volunteer to drive issues forward.
+- Help evaluate the severity of incoming issues.
+- Help write and review patches to address security issues.
+- Participate in the member nomination and removal processes.
 
-.. _security-group-discussion-medium:
+(security-group-discussion-medium)=
 
-Discussion Medium
-=================
+## Discussion Medium
 
 The medium used to host LLVM Security Response Group discussions is security-sensitive. It should therefore run on infrastructure which can meet our security expectations.
 
-We use `GitHub's mechanism to privately report security vulnerabilities`_ to have security discussions:
+We use [GitHub's mechanism to privately report security vulnerabilities][github's mechanism to privately report security vulnerabilities] to have security discussions:
 
-* File security issues.
-* Discuss security improvements to LLVM.
+- File security issues.
+- Discuss security improvements to LLVM.
 
 We also occasionally need to discuss logistics of the LLVM Security Response Group itself:
 
-* Nominate new members.
-* Propose member removal.
-* Suggest policy changes.
+- Nominate new members.
+- Propose member removal.
+- Suggest policy changes.
 
-We often have these discussions publicly, in our :ref:`monthly public sync-up call <online-sync-ups>` and on the Discourse forums.  For internal or confidential discussions, we also use a private mailing list.
+We often have these discussions publicly, in our {ref}`monthly public sync-up call <online-sync-ups>` and on the Discourse forums. For internal or confidential discussions, we also use a private mailing list.
 
-Process
-=======
+## Process
 
 The following process occurs on the discussion medium for each reported issue:
 
-* A security issue reporter (not necessarily an LLVM contributor) reports an issue.
-* Within two business days, a member of the LLVM Security Response Group is put in charge of driving the issue to an acceptable resolution. This champion doesn’t need to be the same person for each issue. This person can self-nominate.
-* Members of the LLVM Security Response Group discuss in which circumstances (if any) an issue is relevant to security, and determine if it is a security issue.
-* Negotiate an embargo date for public disclosure, with a default minimum time limit of ninety days.
-* LLVM Security Response Group members can recommend that key experts be pulled in to specific issue discussions. The key expert can be pulled in unless there are objections from other LLVM Security Response Group members.
-* Patches are written and reviewed.
-* Backporting security patches from recent versions to old versions cannot always work. It is up to the LLVM Security Response Group to decide if such backporting should be done, and how far back.
-* The LLVM Security Response Group figures out how the LLVM project’s own releases, as well as individual vendors’ releases, can be timed to patch the issue simultaneously.
-* Embargo date can be delayed or pulled forward at the LLVM Security Response Group’s discretion.
-* The issue champion obtains a CVE entry from MITRE_.
-* Once the embargo expires, the patch is posted publicly according to LLVM’s usual code review process.
-* All security issues (as well as nomination / removal discussions) become public within approximately fourteen weeks of the fix landing in the LLVM repository. Precautions should be taken to avoid disclosing particularly sensitive data included in the report (e.g. username and password pairs).
-
-
-Changes to the Policy
-=====================
+- A security issue reporter (not necessarily an LLVM contributor) reports an issue.
+- Within two business days, a member of the LLVM Security Response Group is put in charge of driving the issue to an acceptable resolution. This champion doesn’t need to be the same person for each issue. This person can self-nominate.
+- Members of the LLVM Security Response Group discuss in which circumstances (if any) an issue is relevant to security, and determine if it is a security issue.
+- Negotiate an embargo date for public disclosure, with a default minimum time limit of ninety days.
+- LLVM Security Response Group members can recommend that key experts be pulled in to specific issue discussions. The key expert can be pulled in unless there are objections from other LLVM Security Response Group members.
+- Patches are written and reviewed.
+- Backporting security patches from recent versions to old versions cannot always work. It is up to the LLVM Security Response Group to decide if such backporting should be done, and how far back.
+- The LLVM Security Response Group figures out how the LLVM project’s own releases, as well as individual vendors’ releases, can be timed to patch the issue simultaneously.
+- Embargo date can be delayed or pulled forward at the LLVM Security Response Group’s discretion.
+- The issue champion obtains a CVE entry from [MITRE][mitre].
+- Once the embargo expires, the patch is posted publicly according to LLVM’s usual code review process.
+- All security issues (as well as nomination / removal discussions) become public within approximately fourteen weeks of the fix landing in the LLVM repository. Precautions should be taken to avoid disclosing particularly sensitive data included in the report (e.g. username and password pairs).
+
+## Changes to the Policy
 
 The LLVM Security Policy may be changed by majority vote of the LLVM Security Response Group. Such changes also need to be approved by the LLVM Board.
 
-
-What is considered a security issue?
-====================================
+## What is considered a security issue?
 
 We define "security-sensitive" to mean that a discovered bug or vulnerability
 may require coordinated disclosure, and therefore should be reported to the LLVM
@@ -223,23 +199,23 @@ as security-sensitive but need significant work to get to the stage where that's
 manageable. The LLVM community will need to decide whether it wants to invest in
 making these parts of the code securable, and maintain these security properties
 over time. In all cases the LLVM Security Response Group
-`should be consulted <security-group-discussion-medium_>`__, since they'll be
+[should be consulted][security-group-discussion-medium], since they'll be
 responding to security issues filed against these parts of the codebase.
 
 The security-sensitive parts of the LLVM Project currently are the following:
 
-* Code generation: most miscompilations are not security sensitive. However, a
+- Code generation: most miscompilations are not security sensitive. However, a
   miscompilation where there are clear indications that it can result in the
   produced binary becoming significantly easier to exploit could be considered
   security sensitive, and should be reported to the security response group.
-* Run-time libraries: only parts of the run-time libraries are considered
+- Run-time libraries: only parts of the run-time libraries are considered
   security-sensitive. The parts that are not considered security-sensitive are
   documented below.
 
 The following parts of the LLVM Project are currently treated as non-security
 sensitive:
 
-* LLVM's language frontends, analyzers, optimizers, and code generators for
+- LLVM's language frontends, analyzers, optimizers, and code generators for
   which a malicious input can cause undesirable behavior. For example, a
   maliciously crafted C, Rust or bitcode input file can cause arbitrary code to
   execute in LLVM. These parts of LLVM haven't been hardened, and handling
@@ -247,18 +223,19 @@ sensitive:
   more readily perform malicious things. For example, vulnerabilities in clang,
   clangd, or the LLVM optimizer in a JIT caused by untrusted inputs are not
   security-sensitive.
-* The following parts of the run-time libraries are explicitly not considered
+
+- The following parts of the run-time libraries are explicitly not considered
   security-sensitive:
 
-  * parts of the run-time libraries that are not meant to be included in
+  - parts of the run-time libraries that are not meant to be included in
     production binaries. For example, most sanitizers are not considered
     security-sensitive as they are meant to be used during development only, not
     in production.
-  * for libc and libc++: if a user calls library functionality in an undefined
+  - for libc and libc++: if a user calls library functionality in an undefined
     or otherwise incorrect way, this will most likely not be considered a
     security issue, unless the libc/libc++ documentation explicitly promises to
     harden or catch that specific undefined behaviour or incorrect usage.
-  * unwinding and exception handling: the implementations are not hardened
+  - unwinding and exception handling: the implementations are not hardened
     against malformed or malicious unwind or exception handling data. This is
     not considered security sensitive.
 
@@ -268,11 +245,12 @@ in-scope for this security process or not, err towards assuming that it is. The
 Security Response Group might agree or disagree and will explain its rationale
 in the report, as well as update this document through the above process.
 
-.. _CVE process: https://cve.mitre.org
-.. _report a vulnerability: https://github.com/llvm/llvm-security-repo/security/advisories/new
-.. _llvm/llvm-security-repo: https://github.com/llvm/llvm-security-repo/security
-.. _GitHub's mechanism to privately report security vulnerabilities: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability
-.. _GitHub security: https://help.github.com/en/articles/about-maintainer-security-advisories
-.. _Discourse forums: https://discourse.llvm.org
-.. _MITRE: https://cve.mitre.org
-.. _example nomination is available here: https://github.com/llvm/llvm-project/pull/92174
+[cve process]: https://cve.mitre.org
+[discourse forums]: https://discourse.llvm.org
+[example nomination is available here]: https://github.com/llvm/llvm-project/pull/92174
+[github security]: https://help.github.com/en/articles/about-maintainer-security-advisories
+[github's mechanism to privately report security vulnerabilities]: https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability
+[llvm/llvm-security-repo]: https://github.com/llvm/llvm-security-repo/security
+[mitre]: https://cve.mitre.org
+[report a vulnerability]: https://github.com/llvm/llvm-security-repo/security/advisories/new
+
diff --git a/llvm/docs/SecurityTransparencyReports.md b/llvm/docs/SecurityTransparencyReports.md
index 711e6d8ae6b88..6cdb1fd2fbddb 100644
--- a/llvm/docs/SecurityTransparencyReports.md
+++ b/llvm/docs/SecurityTransparencyReports.md
@@ -1,6 +1,12 @@
-========================================
-LLVM Security Group Transparency Reports
-========================================
+---
+substitutions:
+  br: |-
+    ```{raw} html
+    <br/>
+    ```
+---
+
+# LLVM Security Group Transparency Reports
 
 This page lists the yearly LLVM Security Response group transparency reports.
 
@@ -18,52 +24,48 @@ Each Chromium issue has 3 URLs, the first is the original URL recorded in
 previous transparency reports. The second is the redirect URL to the archive.
 The third is to the GitHub archive issue.
 
-2021
-----
+## 2021
 
-The :doc:`LLVM security group <Security>` was established on the 10th of July
-2020 by the act of the `initial
-commit <https://github.com/llvm/llvm-project/commit/7bf73bcf6d93>`_ describing
-the purpose of the group and the processes it follows.  Many of the group's
+The {doc}`LLVM security group <Security>` was established on the 10th of July
+2020 by the act of the [initial
+commit](https://github.com/llvm/llvm-project/commit/7bf73bcf6d93) describing
+the purpose of the group and the processes it follows. Many of the group's
 processes were still not well-defined enough for the group to operate well.
 Over the course of 2021, the key processes were defined well enough to enable
 the group to operate reasonably well:
 
-* We defined details on how to report security issues, see `this commit on
-  20th of May 2021 <https://github.com/llvm/llvm-project/commit/c9dbaa4c86d2>`_
-* We refined the nomination process for new group members, see `this
-  commit on 30th of July 2021 <https://github.com/llvm/llvm-project/commit/4c98e9455aad>`_
-* We started writing an annual transparency report (you're reading the 2021
+- We defined details on how to report security issues, see [this commit on
+  20th of May 2021](https://github.com/llvm/llvm-project/commit/c9dbaa4c86d2)
+- We refined the nomination process for new group members, see [this
+  commit on 30th of July 2021](https://github.com/llvm/llvm-project/commit/4c98e9455aad)
+- We started writing an annual transparency report (you're reading the 2021
   report here).
 
 Over the course of 2021, we had 2 people leave the LLVM Security group and 4
 people join.
 
 In 2021, the security group received 13 issue reports that were made publicly
-visible before 31st of December 2021.  The security group judged 2 of these
+visible before 31st of December 2021. The security group judged 2 of these
 reports to be security issues:
 
-* original: https://bugs.chromium.org/p/llvm/issues/detail?id=5
-  redirect: https://issuetracker.google.com/issues/42410043 archive:
-  https://github.com/llvm/llvm-project/issues/125709
-
-* original: https://bugs.chromium.org/p/llvm/issues/detail?id=11
-  redirect: https://issuetracker.google.com/issues/42410002 archive:
-  https://github.com/llvm/llvm-project/issues/127644
+- original: <https://bugs.chromium.org/p/llvm/issues/detail?id=5>
+  redirect: <https://issuetracker.google.com/issues/42410043> archive:
+  <https://github.com/llvm/llvm-project/issues/125709>
+- original: <https://bugs.chromium.org/p/llvm/issues/detail?id=11>
+  redirect: <https://issuetracker.google.com/issues/42410002> archive:
+  <https://github.com/llvm/llvm-project/issues/127644>
 
 Both issues were addressed with source changes: #5 in clangd/vscode-clangd, and
-#11 in llvm-project.  No dedicated LLVM release was made for either.
+#11 in llvm-project. No dedicated LLVM release was made for either.
 
 We believe that with the publishing of this first annual transparency report,
 the security group now has implemented all necessary processes for the group to
 operate as promised. The group's processes can be improved further, and we do
 expect further improvements to get implemented in 2022. Many of the potential
-improvements end up being discussed on the `monthly public call on LLVM's
-security group <https://llvm.org/docs/GettingInvolved.html#online-sync-ups>`_.
+improvements end up being discussed on the [monthly public call on LLVM's
+security group](https://llvm.org/docs/GettingInvolved.html#online-sync-ups).
 
-
-2022
-----
+## 2022
 
 In this section we report on the issues the group received in 2022, or on issues
 that were received earlier, but were disclosed in 2022.
@@ -73,105 +75,84 @@ the time of writing this transparency report.
 
 5 of these were judged to be security issues:
 
-* https://bugs.chromium.org/p/llvm/issues/detail?id=17 reports a miscompile in LLVM
+- <https://bugs.chromium.org/p/llvm/issues/detail?id=17> reports a miscompile in LLVM
   that can result in the frame pointer and return address being overwritten. This
-  was fixed. Redirect: https://issuetracker.google.com/issues/42410008 archive:
-  https://github.com/llvm/llvm-project/issues/127645
-
-* https://bugs.chromium.org/p/llvm/issues/detail?id=19 reports a vulnerability in
+  was fixed. Redirect: <https://issuetracker.google.com/issues/42410008> archive:
+  <https://github.com/llvm/llvm-project/issues/127645>
+- <https://bugs.chromium.org/p/llvm/issues/detail?id=19> reports a vulnerability in
   `std::filesystem::remove_all` in libc++. This was fixed.
-  Redirect: https://issuetracker.google.com/issues/42410010 archive:
-  https://github.com/llvm/llvm-project/issues/127647
-
-* https://bugs.chromium.org/p/llvm/issues/detail?id=23 reports a new Spectre
+  Redirect: <https://issuetracker.google.com/issues/42410010> archive:
+  <https://github.com/llvm/llvm-project/issues/127647>
+- <https://bugs.chromium.org/p/llvm/issues/detail?id=23> reports a new Spectre
   gadget variant that Speculative Load Hardening (SLH) does not mitigate. No
   extension to SLH was implemented to also mitigate against this variant.
-  Redirect: https://issuetracker.google.com/issues/42410015 archive:
-  https://github.com/llvm/llvm-project/issues/127648
-
-* https://bugs.chromium.org/p/llvm/issues/detail?id=30 reports missing memory
+  Redirect: <https://issuetracker.google.com/issues/42410015> archive:
+  <https://github.com/llvm/llvm-project/issues/127648>
+- <https://bugs.chromium.org/p/llvm/issues/detail?id=30> reports missing memory
   safety protection on the (C++) exception handling path. A number of fixes
-  were implemented. Redirect: https://issuetracker.google.com/issues/42410023
-  archive: https://github.com/llvm/llvm-project/issues/127649
-
-* https://bugs.chromium.org/p/llvm/issues/detail?id=33 reports the RETBLEED
+  were implemented. Redirect: <https://issuetracker.google.com/issues/42410023>
+  archive: <https://github.com/llvm/llvm-project/issues/127649>
+- <https://bugs.chromium.org/p/llvm/issues/detail?id=33> reports the RETBLEED
   vulnerability. The outcome was clang growing a new security hardening feature
-  `-mfunction-return=thunk-extern`, see https://reviews.llvm.org/D129572.
-  Redirect: https://issuetracker.google.com/issues/42410026 archive:
-  https://github.com/llvm/llvm-project/issues/127650
-
+  `-mfunction-return=thunk-extern`, see <https://reviews.llvm.org/D129572>.
+  Redirect: <https://issuetracker.google.com/issues/42410026> archive:
+  <https://github.com/llvm/llvm-project/issues/127650>
 
 No dedicated LLVM releases were made for any of the above issues.
 
-2023
-----
+## 2023
 
 In this section we report on the issues the group received in 2023, or on issues
 that were received earlier, but were disclosed in 2023.
 
 9 of these were judged to be security issues:
 
- * https://bugs.chromium.org/p/llvm/issues/detail?id=36 reports the presence of
-   .git folder in https://llvm.org/.git. Redirect:
-   https://issuetracker.google.com/issues/42410029 archive:
-   https://github.com/llvm/llvm-project/issues/131841
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=66 reports the presence of a
-   GitHub Personal Access token in a DockerHub imaage. Redirect
-   https://issuetracker.google.com/issues/42410060 archive:
-   https://github.com/llvm/llvm-project/issues/131846
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=42 reports a potential gap
-   in the Armv8.1-m BTI protection, involving a combination of large switch statements
-   and __builtin_unreachable() in the default case. Redirect:
-   https://issuetracker.google.com/issues/42410035 archive:
-   https://github.com/llvm/llvm-project/issues/131848
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=43 reports a dependency
-   on an old version of xml2js with a CVE filed against it. Redirect:
-   https://issuetracker.google.com/issues/42410036 archive:
-   https://github.com/llvm/llvm-project/issues/131849
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=45 reports a number of
-   dependencies that have had vulnerabilities reported against them. Redirect:
-   https://issuetracker.google.com/issues/42410038 archive:
-   https://github.com/llvm/llvm-project/issues/131851
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=46 is related to
-   issue 43. Redirect https://issuetracker.google.com/issues/42410039 archive:
-   https://github.com/llvm/llvm-project/issues/131852
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=48 reports a buffer overflow in
-   std::format from -fexperimental-library. Redirect:
-   https://issuetracker.google.com/issues/42410041 archive:
-   https://github.com/llvm/llvm-project/issues/131856
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=54 reports a memory leak in
-   basic_string move assignment when built with libc++ versions <=6.0 and run against
-   newer libc++ shared/dylibs. Redirect:
-   https://issuetracker.google.com/issues/42410047 archive:
-   https://github.com/llvm/llvm-project/issues/131857
-
- * https://bugs.chromium.org/p/llvm/issues/detail?id=56 reports an out
-   of bounds buffer store introduced by LLVM backends, that regressed
-   due to a procedural oversight. Redirect
-   https://issuetracker.google.com/issues/42410049 archive:
-   https://github.com/llvm/llvm-project/issues/131858
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=36> reports the presence of
+>   .git folder in <https://llvm.org/.git>. Redirect:
+>   <https://issuetracker.google.com/issues/42410029> archive:
+>   <https://github.com/llvm/llvm-project/issues/131841>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=66> reports the presence of a
+>   GitHub Personal Access token in a DockerHub imaage. Redirect
+>   <https://issuetracker.google.com/issues/42410060> archive:
+>   <https://github.com/llvm/llvm-project/issues/131846>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=42> reports a potential gap
+>   in the Armv8.1-m BTI protection, involving a combination of large switch statements
+>   and \_\_builtin_unreachable() in the default case. Redirect:
+>   <https://issuetracker.google.com/issues/42410035> archive:
+>   <https://github.com/llvm/llvm-project/issues/131848>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=43> reports a dependency
+>   on an old version of xml2js with a CVE filed against it. Redirect:
+>   <https://issuetracker.google.com/issues/42410036> archive:
+>   <https://github.com/llvm/llvm-project/issues/131849>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=45> reports a number of
+>   dependencies that have had vulnerabilities reported against them. Redirect:
+>   <https://issuetracker.google.com/issues/42410038> archive:
+>   <https://github.com/llvm/llvm-project/issues/131851>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=46> is related to
+>   issue 43. Redirect <https://issuetracker.google.com/issues/42410039> archive:
+>   <https://github.com/llvm/llvm-project/issues/131852>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=48> reports a buffer overflow in
+>   std::format from -fexperimental-library. Redirect:
+>   https://issuetracker.google.com/issues/42410041 archive:
+>   https://github.com/llvm/llvm-project/issues/131856
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=54> reports a memory leak in
+>   basic_string move assignment when built with libc++ versions \<=6.0 and run against
+>   newer libc++ shared/dylibs. Redirect:
+>   <https://issuetracker.google.com/issues/42410047> archive:
+>   <https://github.com/llvm/llvm-project/issues/131857>
+> - <https://bugs.chromium.org/p/llvm/issues/detail?id=56> reports an out
+>   of bounds buffer store introduced by LLVM backends, that regressed
+>   due to a procedural oversight. Redirect
+>   <https://issuetracker.google.com/issues/42410049> archive:
+>   <https://github.com/llvm/llvm-project/issues/131858>
 
 No dedicated LLVM releases were made for any of the above issues.
 
 Over the course of 2023 we had one person join the LLVM Security Group.
 
-2024
-----
+## 2024
 
-.. |br| raw:: html
-
-  <br/>
-
-
-Introduction
-^^^^^^^^^^^^
+### Introduction
 
 In the first half of 2024, LLVM used the Chromium issue tracker to enable
 reporting security issues responsibly. We switched over to using GitHub's
@@ -187,43 +168,41 @@ This transparency report doesn't necessarily mention all issues that were deemed
 duplicates of other issues, or tickets only created to test the bug tracking
 system.
 
-Security issues fixed under a coordinated disclosure process
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Security issues fixed under a coordinated disclosure process
 
 This section lists the reported issues where we ended up implementing fixes
 under a coordinated disclosure process. While we were still using the Chromium
 issue tracker, we did not write security advisories for such issues. Since we
 started using the GitHub issues tracker for security issues, we're now
 publishing security advisories for those issues at
-https://github.com/llvm/llvm-security-repo/security/advisories/.
+<https://github.com/llvm/llvm-security-repo/security/advisories/>.
 
-1. “Unexpected behavior when using LTO and branch-protection together” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=58 |br|
-   redirect: https://issuetracker.google.com/issues/42410051 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132185
+1. “Unexpected behavior when using LTO and branch-protection together” {{ br }}
+   Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=58> {{ br }}
+   redirect: <https://issuetracker.google.com/issues/42410051> {{ br }}
+   archive: <https://github.com/llvm/llvm-project/issues/132185>
 2. “Security weakness in PCS for CMSE”
-   (`CVE-2024-0151 <https://nvd.nist.gov/vuln/detail/CVE-2024-0151>`_) |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=68 |br|
-   redirect: https://issuetracker.google.com/issues/42410062 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132186
+   ([CVE-2024-0151](https://nvd.nist.gov/vuln/detail/CVE-2024-0151)) {{ br }}
+   Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=68> {{ br }}
+   redirect: <https://issuetracker.google.com/issues/42410062> {{ br }}
+   archive: <https://github.com/llvm/llvm-project/issues/132186>
 3. “CMSE secure state may leak from stack to floating-point registers”
-   (`CVE-2024-7883 <https://www.cve.org/cverecord?id=CVE-2024-7883>`_) |br|
+   ([CVE-2024-7883](https://www.cve.org/cverecord?id=CVE-2024-7883)) {{ br }}
    Details are available at
-   `GHSA-wh65-j229-6wfp <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-wh65-j229-6wfp>`_
-
-Supply chain security related issues and project services-related issues
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-1. “GitHub User Involved in xz backdoor may have attempted to change to clang in order to help hide the exploit” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=71 |br|
-   redirect: https://issuetracker.google.com/issues/42410066 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132187
-2. “llvmbot account suspended due to suspicious login” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=72 |br|
-   redirect: https://issuetracker.google.com/issues/42410067 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132243
-3. “.git Exposure” |br|
-   GHSA-mr8r-vvrc-w6rq |br|
+   [GHSA-wh65-j229-6wfp](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-wh65-j229-6wfp)
+
+### Supply chain security related issues and project services-related issues
+
+1. “GitHub User Involved in xz backdoor may have attempted to change to clang in order to help hide the exploit” {{ br }}
+   Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=71> {{ br }}
+   redirect: <https://issuetracker.google.com/issues/42410066> {{ br }}
+   archive: <https://github.com/llvm/llvm-project/issues/132187>
+2. “llvmbot account suspended due to suspicious login” {{ br }}
+   Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=72> {{ br }}
+   redirect: <https://issuetracker.google.com/issues/42410067> {{ br }}
+   archive: <https://github.com/llvm/llvm-project/issues/132243>
+3. “.git Exposure” {{ br }}
+   GHSA-mr8r-vvrc-w6rq {{ br }}
    The .git directory was accessible via web browsers under apt.llvm.org, a site
    used to serve Debian/Ubuntu nightly packages. This issue has been addressed
    by removing the directory, and is not considered a security issue for the
@@ -231,8 +210,8 @@ Supply chain security related issues and project services-related issues
    the apt website, and was mirroring an open-source project maintained on
    github (under opencollab/llvm-jenkins.debian.net). The issue is not believed
    to have leaked any non-public information.
-4. “llvm/llvm-project repo potentially vulnerable to GITHUB\_TOKEN leaks” |br|
-   GHSA-f5xj-84f9-mrw6 |br|
+4. “llvm/llvm-project repo potentially vulnerable to GITHUB_TOKEN leaks” {{ br }}
+   GHSA-f5xj-84f9-mrw6 {{ br }}
    GitHub access tokens were being leaked in artifacts generated by GitHub
    Actions workflows. The vulnerability was first reported publicly as
    ArtiPACKED, generally applicable to GitHub projects, leading to an audit of
@@ -241,10 +220,10 @@ Supply chain security related issues and project services-related issues
    affected, but only exposed tokens that were ephemeral and read-only, so was
    not deemed a privilege escalation concern. The workflow was fixed in a
    configuration change as PR
-   `106310 <https://github.com/llvm/llvm-project/pull/106310>`_. Older exposed
+   [106310](https://github.com/llvm/llvm-project/pull/106310). Older exposed
    tokens all expired, and the issue is closed as resolved.
-5. “RCE in Buildkite Pipeline” |br|
-   GHSA-2j6q-qcfm-3wcx |br|
+5. “RCE in Buildkite Pipeline” {{ br }}
+   GHSA-2j6q-qcfm-3wcx {{ br }}
    A Buildkite CI pipeline (llvm-project/rust-llvm-integrate-prototype) allowed
    Remote Code Execution on the CI runner. The pipeline automatically runs a
    test job when PRs are filed on the rust-lang/rust repo, but those PRs point
@@ -254,113 +233,109 @@ Supply chain security related issues and project services-related issues
    been addressed with internal configuration changes by owners of the Buildkite
    pipeline.
 
-Issues deemed to not require coordinated action before disclosing publicly
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-1. “Clang Address Sanitizer gives False Negative for Array Out of Bounds Compiled with Optimization” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=57 |br|
-   redirect: https://issuetracker.google.com/issues/42410050 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132191
-2. “Found exposed .svn folder” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=59 |br|
-   redirect: https://issuetracker.google.com/issues/42410052
-   archive: https://github.com/llvm/llvm-project/issues/132192
-3. “Arbitrary code execution when combining SafeStack \+ dynamic stack allocations \+ \_\_builtin\_setjmp/longjmp” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=60 |br|
-   redirect: https://issuetracker.google.com/issues/42410054
-   archive: https://github.com/llvm/llvm-project/issues/132220
-4. “RISC-V: Constants are allocated in writeable .sdata section” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=61 |br|
-   redirect: https://issuetracker.google.com/issues/42410055 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132223
-5. “Manifest File with Out-of-Date Dependencies with CVEs” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=62 |br|
-   redirect: https://issuetracker.google.com/issues/42410056 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132225
-6. “Non-const derived ctor should fail compilation when having a consteval base ctor” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=67 |br|
-   redirect: https://issuetracker.google.com/issues/42410061 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132226
-7. “Wrong assembly code generation. Branching to the corrupted "LR".” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=69 |br|
-   redirect: https://issuetracker.google.com/issues/42410063 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132229
-8. “Security bug report” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=70 |br|
-   redirect: https://issuetracker.google.com/issues/42410065 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132233
-9. “Using ASan with setuid binaries can lead to arbitrary file write and elevation of privileges” |br|
-   Details are available at https://bugs.chromium.org/p/llvm/issues/detail?id=73 |br|
-   redirect: https://issuetracker.google.com/issues/42410068 |br|
-   archive: https://github.com/llvm/llvm-project/issues/132235
-10. “Interesting bugs for bool variable in clang projects and aarch64 modes outputting inaccurate results.” |br|
-    GHSA-w7qc-292v-5xh6 |br|
+### Issues deemed to not require coordinated action before disclosing publicly
+
+01. “Clang Address Sanitizer gives False Negative for Array Out of Bounds Compiled with Optimization” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=57> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410050> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132191>
+02. “Found exposed .svn folder” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=59> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410052>
+    archive: <https://github.com/llvm/llvm-project/issues/132192>
+03. “Arbitrary code execution when combining SafeStack + dynamic stack allocations + \_\_builtin_setjmp/longjmp” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=60> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410054>
+    archive: <https://github.com/llvm/llvm-project/issues/132220>
+04. “RISC-V: Constants are allocated in writeable .sdata section” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=61> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410055> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132223>
+05. “Manifest File with Out-of-Date Dependencies with CVEs” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=62> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410056> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132225>
+06. “Non-const derived ctor should fail compilation when having a consteval base ctor” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=67> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410061> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132226>
+07. “Wrong assembly code generation. Branching to the corrupted "LR".” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=69> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410063> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132229>
+08. “Security bug report” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=70> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410065> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132233>
+09. “Using ASan with setuid binaries can lead to arbitrary file write and elevation of privileges” {{ br }}
+    Details are available at <https://bugs.chromium.org/p/llvm/issues/detail?id=73> {{ br }}
+    redirect: <https://issuetracker.google.com/issues/42410068> {{ br }}
+    archive: <https://github.com/llvm/llvm-project/issues/132235>
+10. “Interesting bugs for bool variable in clang projects and aarch64 modes outputting inaccurate results.” {{ br }}
+    GHSA-w7qc-292v-5xh6 {{ br }}
     The issue reported is on a source code example having undefined behaviour
-    (UB), somewhat similar to this: https://godbolt.org/z/vo4P7bPYr.
-    Therefore, this issue was closed as not a security issue in the compiler. |br|
+    (UB), somewhat similar to this: <https://godbolt.org/z/vo4P7bPYr>.
+    Therefore, this issue was closed as not a security issue in the compiler. {{ br }}
     As part of the analysis on this issue, it was deemed useful to document this
     example of UB and similar cases to help users of compilers understand how UB
-    in source code can lead to security issues. |br|
+    in source code can lead to security issues. {{ br }}
     We concluded that probably the best option to do so is to create a regular
-    public issue at https://github.com/llvm/llvm-project/issues, with the same
+    public issue at <https://github.com/llvm/llvm-project/issues>, with the same
     title as the security issue, and to attach a PDF (which should easily be
     created using a “print-to-pdf” method in the browser) containing all
     comments. Such public tickets probably need some consistent way to indicate
     they come from security issues that after analysis were deemed to be outside
     the LLVM threat model or weren't accepted as a
     needs-resolution-work-in-private security issue for other reasons. The LLVM
-    Security Response group has so far not taken action to progress this idea. |br|
+    Security Response group has so far not taken action to progress this idea. {{ br }}
     There was also a suggestion of potentially adding a short section in
-    https://llsoftsec.github.io/llsoftsecbook/#compiler-introduced-security-vulnerabilities
+    <https://llsoftsec.github.io/llsoftsecbook/#compiler-introduced-security-vulnerabilities>
     that summarizes a short example showing that type aliasing UB can and is
     causing security vulnerabilities.
-11. “llvm-libc qsort can use very large amounts of stack if an attacker can control its input list” |br|
-    GHSA-gw5j-473x-p29m |br|
+11. “llvm-libc qsort can use very large amounts of stack if an attacker can control its input list” {{ br }}
+    GHSA-gw5j-473x-p29m {{ br }}
     If the llvm-libc `qsort` function is used in a context where its input list
     comes from an attacker, then the attacker can craft a list that causes
     `qsort`'s stack usage to be linear in the size of the input array,
-    potentially overflowing the available memory region for the stack. |br|
+    potentially overflowing the available memory region for the stack. {{ br }}
     After discussion with stakeholders, including maintainers for llvm-libc, the
     conclusion was that this doesn't have to be processed as a security issue
     needing coordinated disclosure. An improvement to `qsort`'s implementation
     was implemented through pull request
-    https://github.com/llvm/llvm-project/pull/110849.
-12. “VersionFromVCS.cmake may leak secrets in released builds” |br|
-    GHSA-rcw6-jqvr-fcrx |br|
+    <https://github.com/llvm/llvm-project/pull/110849>.
+12. “VersionFromVCS.cmake may leak secrets in released builds” {{ br }}
+    GHSA-rcw6-jqvr-fcrx {{ br }}
     The LLVM build system may leak secrets of VCS configuration into release
     builds if the user clones the repo with an https link that contains their
-    username and/or password. |br|
+    username and/or password. {{ br }}
     Mitigations were implemented in
-    https://github.com/llvm/llvm-project/pull/105220,
-    https://github.com/llvm/llvm-project/commit/57dc09341e5eef758b1abce78822c51069157869.
+    <https://github.com/llvm/llvm-project/pull/105220>,
+    <https://github.com/llvm/llvm-project/commit/57dc09341e5eef758b1abce78822c51069157869>.
     An issue was raised to suggest one more mitigation to be implemented at
-    https://github.com/llvm/llvm-project/issues/109030.
+    <https://github.com/llvm/llvm-project/issues/109030>.
 
-Invalid issues
-^^^^^^^^^^^^^^
+### Invalid issues
 
 The LLVM security group received 5 issues which were created accidentally or
 were not related to the LLVM project. The subject lines for these were:
 
-* “Found this in my android”
-* “\[Not a new security issue\] Continued discussion for GHSA-w7qc-292v-5xh6”
-* “please delete it.”
-* “Please help me to delete it.”
-* “llvm code being used in malicious hacking of network and children's devices”
+- “Found this in my android”
+- “[Not a new security issue] Continued discussion for GHSA-w7qc-292v-5xh6”
+- “please delete it.”
+- “Please help me to delete it.”
+- “llvm code being used in malicious hacking of network and children's devices”
 
 Furthermore, we had 2 tickets that were created to test the setup and workflow
 as part of migrating to GitHub's “security advisory”-based reporting:
 
-1. “Test if new draft security advisory gets emailed to LLVM security group” |br|
+1. “Test if new draft security advisory gets emailed to LLVM security group” {{ br }}
    GHSA-82m9-xvw3-rvpv
-2. “Test that a non-admin can create an advisory (no vulnerability).” |br|
+2. “Test that a non-admin can create an advisory (no vulnerability).” {{ br }}
    GHSA-34gr-6c7h-cc93
 
-2025
-----
+## 2025
 
-Introduction
-^^^^^^^^^^^^
+### Introduction
 
 2025 was the first year all reports were submitted using Github. We report on
 the issues the group received in 2025, or on issues that were received
@@ -379,102 +354,98 @@ In 2025, we received 2 invalid issues that we believe that have been created
 automatically and 1 issue appeared to be created using generative AI. That
 issue was considered to be invalid.
 
-Security issues fixed under a coordinated disclosure process
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Security issues fixed under a coordinated disclosure process
 
 This section lists the reported issues where we ended up implementing fixes
 under a coordinated disclosure process. The security advisories for those
 issues can be found at
-https://github.com/llvm/llvm-security-repo/security/advisories/.
+<https://github.com/llvm/llvm-security-repo/security/advisories/>.
 
-1. “CMSE secure state may leak from stack to floating-point registers” |br|
+1. “CMSE secure state may leak from stack to floating-point registers” {{ br }}
    Details are available at
-   `GHSA-wh65-j229-6wfp <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-wh65-j229-6wfp>`_
-2. “Binary executable injection vulnerability in clang-linker-wrapper.exe” |br|
+   [GHSA-wh65-j229-6wfp](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-wh65-j229-6wfp)
+2. “Binary executable injection vulnerability in clang-linker-wrapper.exe” {{ br }}
    Details are available at
-   `GHSA-hrx2-grgx-9vhg <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-hrx2-grgx-9vhg>`_
+   [GHSA-hrx2-grgx-9vhg](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-hrx2-grgx-9vhg)
 
-Supply chain security related issues and project services-related issues
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Supply chain security related issues and project services-related issues
 
 1. “Critical Supply Chain Vulnerability in RockstarGames/llvm-project
-   (CVE-2025-30066)” |br|
+   (CVE-2025-30066)” {{ br }}
    Details are available at
-   `GHSA-3fq9-qcq4-8jjr <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-3fq9-qcq4-8jjr>`_ |br|
+   [GHSA-3fq9-qcq4-8jjr](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-3fq9-qcq4-8jjr) {{ br }}
    The issue had already been fixed with commit
-   `6616acd80cd91 <https://github.com/llvm/llvm-project/commit/6616acd80cd91a0075e3cd481bb9a6d82fd4ea9e>`_.
+   [6616acd80cd91](https://github.com/llvm/llvm-project/commit/6616acd80cd91a0075e3cd481bb9a6d82fd4ea9e).
 2. “CVE-2022-25883 and CVE-2022-3517 with respect to
-   llvm-project/mlir/utils/vscode/package-lock.json” |br|
+   llvm-project/mlir/utils/vscode/package-lock.json” {{ br }}
    Details are available at
-   `GHSA-g72r-487m-m6hh <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-g72r-487m-m6hh>`_ |br|
+   [GHSA-g72r-487m-m6hh](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-g72r-487m-m6hh) {{ br }}
    Packages have been updated with
-   `PR 144479 <https://github.com/llvm/llvm-project/pull/144479>`_.
+   [PR 144479](https://github.com/llvm/llvm-project/pull/144479).
 
-Issues deemed to not require coordinated action before disclosing publicly
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Issues deemed to not require coordinated action before disclosing publicly
 
-1. “Coroutine Frame-Oriented Programming: A new exploitation method using C++ coroutines” |br|
-   Details are available at
-   `GHSA-v8pv-j8f5-qqcg <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-v8pv-j8f5-qqcg>`_ |br|
-   The researchers shared a new exploitation method that leverages the
-   implementation of C++ routines. Their
-   `paper <https://www.usenix.org/conference/usenixsecurity25/presentation/bajo>`_
-   describing the technique has been published and is available publicly.
-2. “Security Bug in String Assign Function (libc++)” |br|
-   Details are available at
-   `GHSA-m967-6j3p-jrwc <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-m967-6j3p-jrwc>`_ |br|
-   There has been an agreement that the proof of concept had undefined
-   behavior which makes it out of scope according to
-   `the LLVM threat model <https://llvm.org/docs/Security.html#what-is-considered-a-security-issue>`_.
-3. “\[clangd\] heap-use-after-free in clangd when generating diagnostics” |br|
-   Details are available at
-   `GHSA-5426-9r4h-7whf <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-5426-9r4h-7whf>`_ |br|
-   It has been agreed this report fell out of scope because it was caused by
-   untrusted inputs, as described in
-   `the LLVM threat model <https://llvm.org/docs/Security.html#what-is-considered-a-security-issue>`_.
-4. “A compiler optimization bug may cause signed integer overflow detection
-   be bypassed” |br|
-   Details are available at
-   `GHSA-w6jm-h8j9-q33r <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-w6jm-h8j9-q33r>`_ |br|
-   There has been an agreement that the PoC had undefined behavior which makes
-   it out of scope according to
-   `the LLVM threat model <https://llvm.org/docs/Security.html#what-is-considered-a-security-issue>`_.
-5. “libomp: Crash (OOB Write / ASan BUS Error) involving omp\_init\_lock under
-   high concurrency” |br|
-   Details are available at
-   `GHSA-cfhc-jxq2-97mf <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-cfhc-jxq2-97mf>`_ |br|
-   The group agreed to close this as not a security issue because the code
-   was written without taking into consideration the expectations from the
-   OpenMP specification.
-6. “\[MLIR\] head-use-after-free in mlir-lsp-server on completion request” |br|
-   Details are available at
-   `GHSA-8j9r-qc4r-q9fh <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-8j9r-qc4r-q9fh>`_ |br|
-   This report fell out of scope because it was caused by untrusted inputs,
-   as described in
-   `the LLVM threat model <https://llvm.org/docs/Security.html#what-is-considered-a-security-issue>`_.
-7. “\[clangd/clang\] heap-buffer-overflow in clang/lib/Sema/SemaExprCXX.cpp:9144” |br|
-   Details are available at
-   `GHSA-qq8q-r524-8vw9 <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-qq8q-r524-8vw9>`_ |br|
-   This issue and the following 3 were concluded to be outside of the
-   `LLVM threat model <https://llvm.org/docs/Security.html#what-is-considered-a-security-issue>`_.
-8. “\[clangd\] heap-buffer-overflow in clang/lib/Sema/SemaExprCXX.cpp:8876” |br|
-   Details are available at
-   `GHSA-3xm9-vccr-fxx5 <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-3xm9-vccr-fxx5>`_
-9. “\[clangd/clang\] heap-use-after-free at clang/Sema/Ownership.h:81” |br|
-   Details are available at
-   `GHSA-qj36-2p7g-83gv <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-qj36-2p7g-83gv>`_
-10. “Clang 20.1.0 Compiler Internal Error (Crash) during AST Parsing of C++23” |br|
+01. “Coroutine Frame-Oriented Programming: A new exploitation method using C++ coroutines” {{ br }}
+    Details are available at
+    [GHSA-v8pv-j8f5-qqcg](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-v8pv-j8f5-qqcg) {{ br }}
+    The researchers shared a new exploitation method that leverages the
+    implementation of C++ routines. Their
+    [paper](https://www.usenix.org/conference/usenixsecurity25/presentation/bajo)
+    describing the technique has been published and is available publicly.
+02. “Security Bug in String Assign Function (libc++)” {{ br }}
+    Details are available at
+    [GHSA-m967-6j3p-jrwc](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-m967-6j3p-jrwc) {{ br }}
+    There has been an agreement that the proof of concept had undefined
+    behavior which makes it out of scope according to
+    [the LLVM threat model](https://llvm.org/docs/Security.html#what-is-considered-a-security-issue).
+03. “[clangd] heap-use-after-free in clangd when generating diagnostics” {{ br }}
+    Details are available at
+    [GHSA-5426-9r4h-7whf](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-5426-9r4h-7whf) {{ br }}
+    It has been agreed this report fell out of scope because it was caused by
+    untrusted inputs, as described in
+    [the LLVM threat model](https://llvm.org/docs/Security.html#what-is-considered-a-security-issue).
+04. “A compiler optimization bug may cause signed integer overflow detection
+    be bypassed” {{ br }}
     Details are available at
-    `GHSA-p2g2-89wf-7gcm <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-p2g2-89wf-7gcm>`_
-11. “Compiler-induced non-constant-time code” |br|
+    [GHSA-w6jm-h8j9-q33r](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-w6jm-h8j9-q33r) {{ br }}
+    There has been an agreement that the PoC had undefined behavior which makes
+    it out of scope according to
+    [the LLVM threat model](https://llvm.org/docs/Security.html#what-is-considered-a-security-issue).
+05. “libomp: Crash (OOB Write / ASan BUS Error) involving omp_init_lock under
+    high concurrency” {{ br }}
     Details are available at
-    `GHSA-627p-g235-23pm <https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-627p-g235-23pm>`_ |br|
+    [GHSA-cfhc-jxq2-97mf](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-cfhc-jxq2-97mf) {{ br }}
+    The group agreed to close this as not a security issue because the code
+    was written without taking into consideration the expectations from the
+    OpenMP specification.
+06. “[MLIR] head-use-after-free in mlir-lsp-server on completion request” {{ br }}
+    Details are available at
+    [GHSA-8j9r-qc4r-q9fh](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-8j9r-qc4r-q9fh) {{ br }}
+    This report fell out of scope because it was caused by untrusted inputs,
+    as described in
+    [the LLVM threat model](https://llvm.org/docs/Security.html#what-is-considered-a-security-issue).
+07. “[clangd/clang] heap-buffer-overflow in clang/lib/Sema/SemaExprCXX.cpp:9144” {{ br }}
+    Details are available at
+    [GHSA-qq8q-r524-8vw9](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-qq8q-r524-8vw9) {{ br }}
+    This issue and the following 3 were concluded to be outside of the
+    [LLVM threat model](https://llvm.org/docs/Security.html#what-is-considered-a-security-issue).
+08. “[clangd] heap-buffer-overflow in clang/lib/Sema/SemaExprCXX.cpp:8876” {{ br }}
+    Details are available at
+    [GHSA-3xm9-vccr-fxx5](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-3xm9-vccr-fxx5)
+09. “[clangd/clang] heap-use-after-free at clang/Sema/Ownership.h:81” {{ br }}
+    Details are available at
+    [GHSA-qj36-2p7g-83gv](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-qj36-2p7g-83gv)
+10. “Clang 20.1.0 Compiler Internal Error (Crash) during AST Parsing of C++23” {{ br }}
+    Details are available at
+    [GHSA-p2g2-89wf-7gcm](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-p2g2-89wf-7gcm)
+11. “Compiler-induced non-constant-time code” {{ br }}
+    Details are available at
+    [GHSA-627p-g235-23pm](https://github.com/llvm/llvm-security-repo/security/advisories/GHSA-627p-g235-23pm) {{ br }}
     The reporters shared a pre-print article evaluating non-constant-time
     code generated by Clang. We all agreed this did not need coordinated
     disclosure because Clang offers no guarantees of constant-time code.
 
-Invalid issues
-^^^^^^^^^^^^^^
+### Invalid issues
 
 The LLVM security group received 5 issues which were created accidentally or
 were not related to the LLVM project. The subject lines for these were:
@@ -482,5 +453,6 @@ were not related to the LLVM project. The subject lines for these were:
 1. “llvm-Bug”
 2. “Potential Negative Number Used as Index”
 3. “I was recently hacked... maybe you folks might know the dev?”
-4. “ASP.NETconfiguration: Creating Debug Binary in ``[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows``”
-5. “ASP.NETconfiguration: Creating Debug Binary in ``[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows``”
+4. “ASP.NETconfiguration: Creating Debug Binary in `[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows`”
+5. “ASP.NETconfiguration: Creating Debug Binary in `[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows`”
+
diff --git a/llvm/docs/SegmentedStacks.md b/llvm/docs/SegmentedStacks.md
index a688320a9b0bc..a23541379612d 100644
--- a/llvm/docs/SegmentedStacks.md
+++ b/llvm/docs/SegmentedStacks.md
@@ -1,10 +1,6 @@
-========================
-Segmented Stacks in LLVM
-========================
+# Segmented Stacks in LLVM
 
-
-Introduction
-============
+## Introduction
 
 Segmented stack allows stack space to be allocated incrementally than as a
 monolithic chunk (of some worst case size) at thread initialization. This is
@@ -12,64 +8,61 @@ done by allocating stack blocks (henceforth called *stacklets*) and linking them
 into a doubly linked list. The function prologue is responsible for checking if
 the current stacklet has enough space for the function to execute; and if not,
 call into the libgcc runtime to allocate more stack space. Segmented stacks are
-enabled with the ``"split-stack"`` attribute on LLVM functions.
+enabled with the `"split-stack"` attribute on LLVM functions.
 
-The runtime functionality is `already there in libgcc
-<http://gcc.gnu.org/wiki/SplitStacks>`_.
+The runtime functionality is [already there in libgcc](http://gcc.gnu.org/wiki/SplitStacks).
 
-Implementation Details
-======================
+## Implementation Details
 
-.. _allocating stacklets:
+(allocating-stacklets)=
 
-Allocating Stacklets
---------------------
+### Allocating Stacklets
 
 As mentioned above, the function prologue checks if the current stacklet has
 enough space. The current approach is to use a slot in the TCB to store the
 current stack limit (minus the amount of space needed to allocate a new block) -
-this slot's offset is again dictated by ``libgcc``. The generated
+this slot's offset is again dictated by `libgcc`. The generated
 assembly looks like this on x86-64:
 
-.. code-block:: text
-
-    leaq     -8(%rsp), %r10
-    cmpq     %fs:112,  %r10
-    jg       .LBB0_2
+```text
+  leaq     -8(%rsp), %r10
+  cmpq     %fs:112,  %r10
+  jg       .LBB0_2
 
-    # More stack space needs to be allocated
-    movabsq  $8, %r10   # The amount of space needed
-    movabsq  $0, %r11   # The total size of arguments passed on stack
-    callq    __morestack
-    ret                 # The reason for this extra return is explained below
-  .LBB0_2:
-    # Usual prologue continues here
+  # More stack space needs to be allocated
+  movabsq  $8, %r10   # The amount of space needed
+  movabsq  $0, %r11   # The total size of arguments passed on stack
+  callq    __morestack
+  ret                 # The reason for this extra return is explained below
+.LBB0_2:
+  # Usual prologue continues here
+```
 
 The size of function arguments on the stack needs to be passed to
-``__morestack`` (this function is implemented in ``libgcc``) since that number
+`__morestack` (this function is implemented in `libgcc`) since that number
 of bytes has to be copied from the previous stacklet to the current one. This is
 so that SP (and FP) relative addressing of function arguments work as expected.
 
-The unusual ``ret`` is needed to have the function which made a call to
-``__morestack`` return correctly. ``__morestack``, instead of returning, calls
-into ``.LBB0_2``. This is possible since both, the size of the ``ret``
-instruction and the PC of call to ``__morestack`` are known. When the function
-body returns, control is transferred back to ``__morestack``. ``__morestack``
+The unusual `ret` is needed to have the function which made a call to
+`__morestack` return correctly. `__morestack`, instead of returning, calls
+into `.LBB0_2`. This is possible since both, the size of the `ret`
+instruction and the PC of call to `__morestack` are known. When the function
+body returns, control is transferred back to `__morestack`. `__morestack`
 then de-allocates the new stacklet, restores the correct SP value, and does a
 second return, which returns control to the correct caller.
 
-Variable Sized Allocas
-----------------------
+### Variable Sized Allocas
 
-The section on `allocating stacklets`_ automatically assumes that every stack
-frame will be of fixed size. However, LLVM allows the use of the ``llvm.alloca``
+The section on [allocating stacklets] automatically assumes that every stack
+frame will be of fixed size. However, LLVM allows the use of the `llvm.alloca`
 intrinsic to allocate dynamically sized blocks of memory on the stack. When
 faced with such a variable-sized alloca, code is generated to:
 
-* Check if the current stacklet has enough space. If yes, just bump the SP, like
+- Check if the current stacklet has enough space. If yes, just bump the SP, like
   in the normal case.
-* If not, generate a call to ``libgcc``, which allocates the memory from the
+- If not, generate a call to `libgcc`, which allocates the memory from the
   heap.
 
 The memory allocated from the heap is linked into a list in the current
 stacklet, and freed along with the same. This prevents a memory leak.
+
diff --git a/llvm/docs/StackMaps.md b/llvm/docs/StackMaps.md
index 5d58759d95fb8..2d07a0aaa2c3c 100644
--- a/llvm/docs/StackMaps.md
+++ b/llvm/docs/StackMaps.md
@@ -1,17 +1,13 @@
-===================================
-Stack maps and patch points in LLVM
-===================================
+# Stack maps and patch points in LLVM
 
-
-Definitions
-===========
+## Definitions
 
 In this document we refer to the "runtime" collectively as all
 components that serve as the LLVM client, including the LLVM IR
 generator, object code consumer, and code patcher.
 
-A stack map records the location of ``live values`` at a particular
-instruction address. These ``live values`` do not refer to all the
+A stack map records the location of `live values` at a particular
+instruction address. These `live values` do not refer to all the
 LLVM values live across the stack map. Instead, they are only the
 values that the runtime requires to be live at this point. For
 example, they may be the values the runtime will need to resume
@@ -19,7 +15,7 @@ program execution at that point independent of the compiled function
 containing the stack map.
 
 LLVM emits stack map data into the object code within a designated
-:ref:`stackmap-section`. This stack map data contains a record for
+{ref}`stackmap-section`. This stack map data contains a record for
 each stack map. The record stores the stack map's instruction address
 and contains an entry for each mapped value. Each entry encodes a
 value's location as a register, stack offset, or constant.
@@ -29,10 +25,9 @@ patching a new instruction sequence at run time. Patch points look
 much like calls to LLVM. They take arguments that follow a calling
 convention and may return a value. They also imply stack map
 generation, which allows the runtime to locate the patchpoint and
-find the location of ``live values`` at that point.
+find the location of `live values` at that point.
 
-Motivation
-==========
+## Motivation
 
 This functionality is currently experimental but is potentially useful
 in a variety of settings, the most obvious being a runtime (JIT)
@@ -42,15 +37,14 @@ optimizing the retrieval of properties in dynamically typed languages
 such as JavaScript.
 
 The intrinsics documented here are currently used by the JavaScript
-compiler within the open source WebKit project, see the `FTL JIT
-<https://trac.webkit.org/wiki/FTLJIT>`_, but they are designed to be
+compiler within the open source WebKit project, see the [FTL JIT](https://trac.webkit.org/wiki/FTLJIT), but they are designed to be
 used whenever stack maps or code patching are needed. Because the
 intrinsics have experimental status, compatibility across LLVM
 releases is not guaranteed.
 
 The stack map functionality described in this document is separate
 from the functionality described in
-:ref:`stack-map`. `GCFunctionMetadata` provides the location of
+{ref}`stack-map`. `GCFunctionMetadata` provides the location of
 pointers into a collected heap captured by the `GCRoot` intrinsic,
 which can also be considered a "stack map". Unlike the stack maps
 defined above, the `GCFunctionMetadata` stack map interface does not
@@ -60,64 +54,58 @@ stack map. The stack maps described here could potentially provide
 richer information to a garbage collecting runtime, but that usage
 will not be discussed in this document.
 
-Intrinsics
-==========
+## Intrinsics
 
 The following two kinds of intrinsics can be used to implement stack
-maps and patch points: ``llvm.experimental.stackmap`` and
-``llvm.experimental.patchpoint``. Both kinds of intrinsics generate a
+maps and patch points: `llvm.experimental.stackmap` and
+`llvm.experimental.patchpoint`. Both kinds of intrinsics generate a
 stack map record, and they both allow some form of code patching. They
-can be used independently (i.e. ``llvm.experimental.patchpoint``
+can be used independently (i.e. `llvm.experimental.patchpoint`
 implicitly generates a stack map without the need for an additional
-call to ``llvm.experimental.stackmap``). The choice of which to use
+call to `llvm.experimental.stackmap`). The choice of which to use
 depends on whether it is necessary to reserve space for code patching
 and whether any of the intrinsic arguments should be lowered according
-to calling conventions. ``llvm.experimental.stackmap`` does not
+to calling conventions. `llvm.experimental.stackmap` does not
 reserve any space, nor does it expect any call arguments. If the
 runtime patches code at the stack map's address, it will destructively
 overwrite the program text. This is unlike
-``llvm.experimental.patchpoint``, which reserves space for in-place
+`llvm.experimental.patchpoint`, which reserves space for in-place
 patching without overwriting surrounding code. The
-``llvm.experimental.patchpoint`` intrinsic also lowers a specified
+`llvm.experimental.patchpoint` intrinsic also lowers a specified
 number of arguments according to its calling convention. This allows
 patched code to make in-place function calls without marshaling.
 
 Each instance of one of these intrinsics generates a stack map record
-in the :ref:`stackmap-section`. The record includes an ID, allowing
+in the {ref}`stackmap-section`. The record includes an ID, allowing
 the runtime to uniquely identify the stack map, and the offset within
 the code from the beginning of the enclosing function.
 
-'``llvm.experimental.stackmap``' Intrinsic
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Syntax:
-"""""""
+### '`llvm.experimental.stackmap`' Intrinsic
 
-::
+#### Syntax:
 
-      declare void
-        @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>, ...)
+```
+declare void
+  @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>, ...)
+```
 
-Overview:
-"""""""""
+#### Overview:
 
-The '``llvm.experimental.stackmap``' intrinsic records the location of
+The '`llvm.experimental.stackmap`' intrinsic records the location of
 specified values in the stack map without generating any code.
 
-Operands:
-"""""""""
+#### Operands:
 
 The first operand is an ID to be encoded within the stack map. The
 second operand is the number of shadow bytes following the
 intrinsic. These first two operands should be immediate, e.g. cannot
 be passed as variables. The variable number of operands that follow are
-the ``live values`` for which locations will be recorded in the stack map.
+the `live values` for which locations will be recorded in the stack map.
 
 To use this intrinsic as a bare-bones stack map, with no code patching
 support, the number of shadow bytes can be set to zero.
 
-Semantics:
-""""""""""
+#### Semantics:
 
 The stack map intrinsic generates no code in place, unless nops are
 needed to cover its shadow (see below). However, its offset from
@@ -131,8 +119,8 @@ record without checking uniqueness.
 
 LLVM guarantees a shadow of instructions following the stack map's
 instruction offset during which neither the end of the basic block nor
-another call to ``llvm.experimental.stackmap`` or
-``llvm.experimental.patchpoint`` may occur. This allows the runtime to
+another call to `llvm.experimental.stackmap` or
+`llvm.experimental.patchpoint` may occur. This allows the runtime to
 patch the code at this point in response to an event triggered from
 outside the code. The code for instructions following the stack map
 may be emitted in the stack map's shadow, and these instructions may
@@ -143,106 +131,101 @@ the runtime does not need to consider this corner case.
 
 For example, a stack map with 8-byte shadow:
 
-.. code-block:: llvm
-
-  call void @runtime()
-  call void (i64, i32, ...) @llvm.experimental.stackmap(i64 77, i32 8,
-                                                        ptr %ptr)
-  %val = load i64, ptr %ptr
-  %add = add i64 %val, 3
-  ret i64 %add
+```llvm
+call void @runtime()
+call void (i64, i32, ...) @llvm.experimental.stackmap(i64 77, i32 8,
+                                                      ptr %ptr)
+%val = load i64, ptr %ptr
+%add = add i64 %val, 3
+ret i64 %add
+```
 
 May require one byte of nop-padding:
 
-.. code-block:: none
-
-  0x00 callq _runtime
-  0x05 nop                <--- stack map address
-  0x06 movq (%rdi), %rax
-  0x07 addq $3, %rax
-  0x0a popq %rdx
-  0x0b ret                <---- end of 8-byte shadow
+```none
+0x00 callq _runtime
+0x05 nop                <--- stack map address
+0x06 movq (%rdi), %rax
+0x07 addq $3, %rax
+0x0a popq %rdx
+0x0b ret                <---- end of 8-byte shadow
+```
 
 Now, if the runtime needs to invalidate the compiled code, it may
 patch 8 bytes of code at the stack map's address at follows:
 
-.. code-block:: none
-
-  0x00 callq _runtime
-  0x05 movl  $0xffff, %rax <--- patched code at stack map address
-  0x0a callq *%rax         <---- end of 8-byte shadow
+```none
+0x00 callq _runtime
+0x05 movl  $0xffff, %rax <--- patched code at stack map address
+0x0a callq *%rax         <---- end of 8-byte shadow
+```
 
 This way, after the normal call to the runtime returns, the code will
 execute a patched call to a special entry point that can rebuild a
 stack frame from the values located by the stack map.
 
-'``llvm.experimental.patchpoint.*``' Intrinsic
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### '`llvm.experimental.patchpoint.*`' Intrinsic
 
-Syntax:
-"""""""
+#### Syntax:
 
-::
+```
+declare void
+  @llvm.experimental.patchpoint.void(i64 <id>, i32 <numBytes>,
+                                     ptr <target>, i32 <numArgs>, ...)
+declare i64
+  @llvm.experimental.patchpoint.i64(i64 <id>, i32 <numBytes>,
+                                    ptr <target>, i32 <numArgs>, ...)
+```
 
-      declare void
-        @llvm.experimental.patchpoint.void(i64 <id>, i32 <numBytes>,
-                                           ptr <target>, i32 <numArgs>, ...)
-      declare i64
-        @llvm.experimental.patchpoint.i64(i64 <id>, i32 <numBytes>,
-                                          ptr <target>, i32 <numArgs>, ...)
+#### Overview:
 
-Overview:
-"""""""""
-
-The '``llvm.experimental.patchpoint.*``' intrinsics creates a function
-call to the specified ``<target>`` and records the location of specified
+The '`llvm.experimental.patchpoint.*`' intrinsics creates a function
+call to the specified `<target>` and records the location of specified
 values in the stack map.
 
-Operands:
-"""""""""
+#### Operands:
 
 The first operand is an ID, the second operand is the number of bytes
 reserved for the patchable region, the third operand is the target
 address of a function (optionally null), and the fourth operand
 specifies how many of the following variable operands are considered
 function call arguments. The remaining variable number of operands are
-the ``live values`` for which locations will be recorded in the stack
+the `live values` for which locations will be recorded in the stack
 map.
 
-Semantics:
-""""""""""
+#### Semantics:
 
 The patch point intrinsic generates a stack map. It also emits a
-function call to the address specified by ``<target>`` if the address
+function call to the address specified by `<target>` if the address
 is not a constant null. The function call and its arguments are
 lowered according to the calling convention specified at the
 intrinsic's callsite. Variants of the intrinsic with non-void return
 type also return a value according to calling convention.
 
-On PowerPC, note that ``<target>`` must be the ABI function pointer for the
+On PowerPC, note that `<target>` must be the ABI function pointer for the
 intended target of the indirect call. Specifically, when compiling for the
-ELF V1 ABI, ``<target>`` is the function-descriptor address normally used as
+ELF V1 ABI, `<target>` is the function-descriptor address normally used as
 the C/C++ function-pointer representation.
 
 Requesting zero patch point arguments is valid. In this case, all
 variable operands are handled just like
-``llvm.experimental.stackmap.*``. The difference is that space will
+`llvm.experimental.stackmap.*`. The difference is that space will
 still be reserved for patching, a call will be emitted, and a return
 value is allowed.
 
 The location of the arguments are not normally recorded in the stack
 map because they are already fixed by the calling convention. The
-remaining ``live values`` will have their location recorded, which
+remaining `live values` will have their location recorded, which
 could be a register, stack location, or constant. A special calling
 convention has been introduced for use with stack maps, anyregcc,
 which forces the arguments to be loaded into registers but allows
 those register to be dynamically allocated. These argument registers
 will have their register locations recorded in the stack map in
-addition to the remaining ``live values``.
+addition to the remaining `live values`.
 
-The patch point also emits nops to cover at least ``<numBytes>`` of
+The patch point also emits nops to cover at least `<numBytes>` of
 instruction encoding space. Hence, the client must ensure that
-``<numBytes>`` is enough to encode a call to the target address on the
+`<numBytes>` is enough to encode a call to the target address on the
 supported targets. If the call target is constant null, then there is
 no minimum requirement. A zero-byte null target patchpoint is
 valid.
@@ -254,111 +237,111 @@ patching is not allowed. The runtime must patch all reserved bytes,
 padding with nops if necessary.
 
 This example shows a patch point reserving 15 bytes, with one argument
-in $rdi, and a return value in $rax per native calling convention:
-
-.. code-block:: llvm
+in \$rdi, and a return value in \$rax per native calling convention:
 
-  %target = inttoptr i64 -281474976710654 to ptr
-  %val = call i64 (i64, i32, ...)
-           @llvm.experimental.patchpoint.i64(i64 78, i32 15,
-                                             ptr %target, i32 1, ptr %ptr)
-  %add = add i64 %val, 3
-  ret i64 %add
+```llvm
+%target = inttoptr i64 -281474976710654 to ptr
+%val = call i64 (i64, i32, ...)
+         @llvm.experimental.patchpoint.i64(i64 78, i32 15,
+                                           ptr %target, i32 1, ptr %ptr)
+%add = add i64 %val, 3
+ret i64 %add
+```
 
 May generate:
 
-.. code-block:: none
-
-  0x00 movabsq $0xffff000000000002, %r11 <--- patch point address
-  0x0a callq   *%r11
-  0x0d nop
-  0x0e nop                               <--- end of reserved 15-bytes
-  0x0f addq    $0x3, %rax
-  0x10 movl    %rax, 8(%rsp)
+```none
+0x00 movabsq $0xffff000000000002, %r11 <--- patch point address
+0x0a callq   *%r11
+0x0d nop
+0x0e nop                               <--- end of reserved 15-bytes
+0x0f addq    $0x3, %rax
+0x10 movl    %rax, 8(%rsp)
+```
 
 Note that no stack map locations will be recorded. If the patched code
 sequence does not need arguments fixed to specific calling convention
-registers, then the ``anyregcc`` convention may be used:
-
-.. code-block:: none
+registers, then the `anyregcc` convention may be used:
 
-  %val = call anyregcc @llvm.experimental.patchpoint(i64 78, i32 15,
-                                                     ptr %target, i32 1,
-                                                     ptr %ptr)
+```none
+%val = call anyregcc @llvm.experimental.patchpoint(i64 78, i32 15,
+                                                   ptr %target, i32 1,
+                                                   ptr %ptr)
+```
 
 The stack map now indicates the location of the %ptr argument and
 return value:
 
-.. code-block:: none
-
-  Stack Map: ID=78, Loc0=%r9 Loc1=%r8
+```none
+Stack Map: ID=78, Loc0=%r9 Loc1=%r8
+```
 
 The patch code sequence may now use the argument that happened to be
 allocated in %r8 and return a value allocated in %r9:
 
-.. code-block:: none
-
-  0x00 movslq 4(%r8) %r9              <--- patched code at patch point address
-  0x03 nop
-  ...
-  0x0e nop                            <--- end of reserved 15-bytes
-  0x0f addq    $0x3, %r9
-  0x10 movl    %r9, 8(%rsp)
+```none
+0x00 movslq 4(%r8) %r9              <--- patched code at patch point address
+0x03 nop
+...
+0x0e nop                            <--- end of reserved 15-bytes
+0x0f addq    $0x3, %r9
+0x10 movl    %r9, 8(%rsp)
+```
 
-.. _stackmap-format:
+(stackmap-format)=
 
-Stack Map Format
-================
+## Stack Map Format
 
 The existence of a stack map or patch point intrinsic within an LLVM
-Module forces code emission to create a :ref:`stackmap-section`. The
+Module forces code emission to create a {ref}`stackmap-section`. The
 format of this section follows:
 
-.. code-block:: none
-
-  Header {
-    uint8  : Stack Map Version (current version is 3)
+```none
+Header {
+  uint8  : Stack Map Version (current version is 3)
+  uint8  : Reserved (expected to be 0)
+  uint16 : Reserved (expected to be 0)
+}
+uint32 : NumFunctions
+uint32 : NumConstants
+uint32 : NumRecords
+StkSizeRecord[NumFunctions] {
+  uint64 : Function Address
+  uint64 : Stack Size (or UINT64_MAX if not statically known)
+  uint64 : Record Count
+}
+Constants[NumConstants] {
+  uint64 : LargeConstant
+}
+StkMapRecord[NumRecords] {
+  uint64 : PatchPoint ID
+  uint32 : Instruction Offset
+  uint16 : Reserved (record flags)
+  uint16 : NumLocations
+  Location[NumLocations] {
+    uint8  : Register | Direct | Indirect | Constant | ConstantIndex
     uint8  : Reserved (expected to be 0)
+    uint16 : Location Size
+    uint16 : Dwarf RegNum
     uint16 : Reserved (expected to be 0)
+    int32  : Offset or SmallConstant
   }
-  uint32 : NumFunctions
-  uint32 : NumConstants
-  uint32 : NumRecords
-  StkSizeRecord[NumFunctions] {
-    uint64 : Function Address
-    uint64 : Stack Size (or UINT64_MAX if not statically known)
-    uint64 : Record Count
-  }
-  Constants[NumConstants] {
-    uint64 : LargeConstant
-  }
-  StkMapRecord[NumRecords] {
-    uint64 : PatchPoint ID
-    uint32 : Instruction Offset
-    uint16 : Reserved (record flags)
-    uint16 : NumLocations
-    Location[NumLocations] {
-      uint8  : Register | Direct | Indirect | Constant | ConstantIndex
-      uint8  : Reserved (expected to be 0)
-      uint16 : Location Size
-      uint16 : Dwarf RegNum
-      uint16 : Reserved (expected to be 0)
-      int32  : Offset or SmallConstant
-    }
-    uint32 : Padding (only if required to align to 8 byte)
-    uint16 : Padding
-    uint16 : NumLiveOuts
-    LiveOuts[NumLiveOuts]
-      uint16 : Dwarf RegNum
-      uint8  : Reserved
-      uint8  : Size in Bytes
-    }
-    uint32 : Padding (only if required to align to 8 byte)
+  uint32 : Padding (only if required to align to 8 byte)
+  uint16 : Padding
+  uint16 : NumLiveOuts
+  LiveOuts[NumLiveOuts]
+    uint16 : Dwarf RegNum
+    uint8  : Reserved
+    uint8  : Size in Bytes
   }
+  uint32 : Padding (only if required to align to 8 byte)
+}
+```
 
 The first byte of each location encodes a type that indicates how to
-interpret the ``RegNum`` and ``Offset`` fields as follows:
+interpret the `RegNum` and `Offset` fields as follows:
 
+```{eval-rst}
 ======== ========== =================== ===========================
 Encoding Type       Value               Description
 -------- ---------- ------------------- ---------------------------
@@ -368,18 +351,19 @@ Encoding Type       Value               Description
 0x4      Constant   Offset              Small constant
 0x5      ConstIndex Constants[Offset]   Large constant
 ======== ========== =================== ===========================
+```
 
 In the common case, a value is available in a register, and the
-``Offset`` field will be zero. Values spilled to the stack are encoded
-as ``Indirect`` locations. The runtime must load those values from a
-stack address, typically in the form ``[BP + Offset]``. If an
-``alloca`` value is passed directly to a stack map intrinsic, then
+`Offset` field will be zero. Values spilled to the stack are encoded
+as `Indirect` locations. The runtime must load those values from a
+stack address, typically in the form `[BP + Offset]`. If an
+`alloca` value is passed directly to a stack map intrinsic, then
 LLVM may fold the frame index into the stack map as an optimization to
 avoid allocating a register or stack slot. These frame indices will be
-encoded as ``Direct`` locations in the form ``BP + Offset``. LLVM may
+encoded as `Direct` locations in the form `BP + Offset`. LLVM may
 also optimize constants by emitting them directly in the stack map,
-either in the ``Offset`` of a ``Constant`` location or in the constant
-pool, referred to by ``ConstantIndex`` locations.
+either in the `Offset` of a `Constant` location or in the constant
+pool, referred to by `ConstantIndex` locations.
 
 At each callsite, a "liveout" register list is also recorded. These
 are the registers that are live across the stackmap and therefore must
@@ -391,11 +375,11 @@ Each entry in the liveout register list contains a DWARF register
 number and size in bytes. The stackmap format deliberately omits
 specific subregister information. Instead the runtime must interpret
 this information conservatively. For example, if the stackmap reports
-one byte at ``%rax``, then the value may be in either ``%al`` or
-``%ah``. It doesn't matter in practice, because the runtime will
-simply save ``%rax``. However, if the stackmap reports 16 bytes at
-``%ymm0``, then the runtime can safely optimize by saving only
-``%xmm0``.
+one byte at `%rax`, then the value may be in either `%al` or
+`%ah`. It doesn't matter in practice, because the runtime will
+simply save `%rax`. However, if the stackmap reports 16 bytes at
+`%ymm0`, then the runtime can safely optimize by saving only
+`%xmm0`.
 
 The stack map format is a contract between an LLVM SVN revision and
 the runtime. It is currently experimental and may change in the short
@@ -411,28 +395,26 @@ Stackmap support is currently only implemented for 64-bit
 platforms. However, a 32-bit implementation should be able to use the
 same format with an insignificant amount of wasted space.
 
-.. _stackmap-section:
+(stackmap-section)=
 
-Stack Map Section
-^^^^^^^^^^^^^^^^^
+### Stack Map Section
 
 A JIT compiler can easily access this section by providing its own
 memory manager via the LLVM C API
-``LLVMCreateSimpleMCJITMemoryManager()``. When creating the memory
+`LLVMCreateSimpleMCJITMemoryManager()`. When creating the memory
 manager, the JIT provides a callback:
-``LLVMMemoryManagerAllocateDataSectionCallback()``. When LLVM creates
+`LLVMMemoryManagerAllocateDataSectionCallback()`. When LLVM creates
 this section, it invokes the callback and passes the section name. The
 JIT can record the in-memory address of the section at this time and
 later parse it to recover the stack map data.
 
 For MachO (e.g. on Darwin), the stack map section name is
-"__llvm_stackmaps". The segment name is "__LLVM_STACKMAPS".
+"\_\_llvm_stackmaps". The segment name is "\_\_LLVM_STACKMAPS".
 
 For ELF (e.g. on Linux), the stack map section name is
-".llvm_stackmaps".  The segment name is "__LLVM_STACKMAPS".
+".llvm_stackmaps". The segment name is "\_\_LLVM_STACKMAPS".
 
-Stack Map Usage
-===============
+## Stack Map Usage
 
 The stack map support described in this document can be used to
 precisely determine the location of values at a specific position in
@@ -474,10 +456,9 @@ also allow meta-data to be added to the intrinsic call to express
 aliasing, thereby allowing optimizations to hoist certain loads above
 stack maps.
 
-Direct Stack Map Entries
-^^^^^^^^^^^^^^^^^^^^^^^^
+### Direct Stack Map Entries
 
-As shown in :ref:`stackmap-section`, a Direct stack map location
+As shown in {ref}`stackmap-section`, a Direct stack map location
 records the address of frame index. This address is itself the value
 that the runtime requested. This differs from Indirect locations,
 which refer to a stack locations from which the requested values must
@@ -486,11 +467,11 @@ while Indirect locations handle register spills.
 
 For example:
 
-.. code-block:: none
-
-  entry:
-    %a = alloca i64...
-    llvm.experimental.stackmap(i64 <ID>, i32 <shadowBytes>, ptr %a)
+```none
+entry:
+  %a = alloca i64...
+  llvm.experimental.stackmap(i64 <ID>, i32 <shadowBytes>, ptr %a)
+```
 
 The runtime can determine this alloca's relative location on the
 stack immediately after compilation, or at any time thereafter. This
@@ -505,11 +486,10 @@ transformations must not substitute the alloca with any intervening
 value. This can be verified by the runtime simply by checking that the
 stack map's location is a Direct location type.
 
-
-Supported Architectures
-=======================
+## Supported Architectures
 
 Support for StackMap generation and the related intrinsics requires
-some code for each backend.  Today, only a subset of LLVM's backends
-are supported.  The currently supported architectures are X86_64,
+some code for each backend. Today, only a subset of LLVM's backends
+are supported. The currently supported architectures are X86_64,
 PowerPC, AArch64 and SystemZ.
+
diff --git a/llvm/docs/Statepoints.md b/llvm/docs/Statepoints.md
index e4bc56dd58b95..5a39f643e0f00 100644
--- a/llvm/docs/Statepoints.md
+++ b/llvm/docs/Statepoints.md
@@ -1,49 +1,44 @@
-=====================================
-Garbage Collection Safepoints in LLVM
-=====================================
+# Garbage Collection Safepoints in LLVM
 
-
-Status
-=======
+## Status
 
 This document describes a set of extensions to LLVM to support garbage
-collection.  By now, these mechanisms are well proven with commercial java
+collection. By now, these mechanisms are well proven with commercial java
 implementation with a fully relocating collector having shipped using them.
 There are a couple places where bugs might still linger; these are called out
 below.
 
 They are still listed as "experimental" to indicate that no forward or backward
-compatibility guarantees are offered across versions.  If your use case is such
+compatibility guarantees are offered across versions. If your use case is such
 that you need some form of forward compatibility guarantee, please raise the
 issue on the llvm-dev mailing list.
 
 LLVM still supports an alternate mechanism for conservative garbage collection
-support using the ``gcroot`` intrinsic.  The ``gcroot`` mechanism is mostly of
+support using the `gcroot` intrinsic. The `gcroot` mechanism is mostly of
 historical interest at this point with one exception - its implementation of
 shadow stacks has been used successfully by a number of language frontends and
 is still supported.
 
-Overview & Core Concepts
-========================
+## Overview & Core Concepts
 
 To collect dead objects, garbage collectors must be able to identify
 any references to objects contained within executing code, and,
-depending on the collector, potentially update them.  The collector
+depending on the collector, potentially update them. The collector
 does not need this information at all points in code - that would make
 the problem much harder - but only at well-defined points in the
 execution known as 'safepoints' For most collectors, it is sufficient
-to track at least one copy of each unique pointer value.  However, for
+to track at least one copy of each unique pointer value. However, for
 a collector which wishes to relocate objects directly reachable from
 running code, a higher standard is required.
 
 One additional challenge is that the compiler may compute intermediate
 results ("derived pointers") which point outside of the allocation or
-even into the middle of another allocation.  The eventual use of this
+even into the middle of another allocation. The eventual use of this
 intermediate value must yield an address within the bounds of the
 allocation, but such "exterior derived pointers" may be visible to the
-collector.  Given this, a garbage collector can not safely rely on the
+collector. Given this, a garbage collector can not safely rely on the
 runtime value of an address to indicate the object it is associated
-with.  If the garbage collector wishes to move any object, the
+with. If the garbage collector wishes to move any object, the
 compiler must provide a mapping, for each pointer, to an indication of
 its allocation.
 
@@ -51,97 +46,93 @@ To simplify the interaction between a collector and the compiled code,
 most garbage collectors are organized in terms of three abstractions:
 load barriers, store barriers, and safepoints.
 
-#. A load barrier is a bit of code executed immediately after the
+1. A load barrier is a bit of code executed immediately after the
    machine load instruction, but before any use of the value loaded.
    Depending on the collector, such a barrier may be needed for all
    loads, merely loads of a particular type (in the original source
    language), or none at all.
-
-#. Analogously, a store barrier is a code fragment that runs
+2. Analogously, a store barrier is a code fragment that runs
    immediately before the machine store instruction, but after the
-   computation of the value stored.  The most common use of a store
+   computation of the value stored. The most common use of a store
    barrier is to update a 'card table' in a generational garbage
    collector.
-
-#. A safepoint is a location at which pointers visible to the compiled
+3. A safepoint is a location at which pointers visible to the compiled
    code (i.e. currently in registers or on the stack) are allowed to
-   change.  After the safepoint completes, the actual pointer value
+   change. After the safepoint completes, the actual pointer value
    may differ, but the 'object' (as seen by the source language)
    pointed to will not.
 
-  Note that the term 'safepoint' is somewhat overloaded.  It refers to
-  both the location at which the machine state is parsable and the
-  coordination protocol involved in bring application threads to a
-  point at which the collector can safely use that information.  The
-  term "statepoint" as used in this document refers exclusively to the
-  former.
+> Note that the term 'safepoint' is somewhat overloaded. It refers to
+> both the location at which the machine state is parsable and the
+> coordination protocol involved in bring application threads to a
+> point at which the collector can safely use that information. The
+> term "statepoint" as used in this document refers exclusively to the
+> former.
 
 This document focuses on the last item - compiler support for
-safepoints in generated code.  We will assume that an outside
-mechanism has decided where to place safepoints.  From our
-perspective, all safepoints will be function calls.  To support
+safepoints in generated code. We will assume that an outside
+mechanism has decided where to place safepoints. From our
+perspective, all safepoints will be function calls. To support
 relocation of objects directly reachable from values in compiled code,
 the collector must be able to:
 
-#. identify every copy of a pointer (including copies introduced by
+1. identify every copy of a pointer (including copies introduced by
    the compiler itself) at the safepoint,
-#. identify which object each pointer relates to, and
-#. potentially update each of those copies.
+2. identify which object each pointer relates to, and
+3. potentially update each of those copies.
 
 This document describes the mechanism by which an LLVM based compiler
 can provide this information to a language runtime/collector, and
 ensure that all pointers can be read and updated if desired.
 
-Abstract Machine Model
-^^^^^^^^^^^^^^^^^^^^^^^
+### Abstract Machine Model
 
 At a high level, LLVM has been extended to support compiling to an abstract
 machine which extends the actual target with a non-integral pointer type
-suitable for representing a garbage collected reference to an object.  In
+suitable for representing a garbage collected reference to an object. In
 particular, such non-integral pointer type have no defined mapping to an
-integer representation.  This semantic quirk allows the runtime to pick a
+integer representation. This semantic quirk allows the runtime to pick a
 integer mapping for each point in the program allowing relocations of objects
 without visible effects.
 
-This high level abstract machine model is used for most of the optimizer.  As
+This high level abstract machine model is used for most of the optimizer. As
 a result, transform passes do not need to be extended to look through explicit
-relocation sequence.  Before starting code generation, we switch
-representations to an explicit form.  The exact location chosen for lowering
+relocation sequence. Before starting code generation, we switch
+representations to an explicit form. The exact location chosen for lowering
 is an implementation detail.
 
 Note that most of the value of the abstract machine model comes for collectors
-which need to model potentially relocatable objects.  For a compiler which
+which need to model potentially relocatable objects. For a compiler which
 supports only a non-relocating collector, you may wish to consider starting
 with the fully explicit form.
 
 Warning: There is one currently known semantic hole in the definition of
-non-integral pointers which has not been addressed upstream.  To work around
+non-integral pointers which has not been addressed upstream. To work around
 this, you need to disable speculation of loads unless the memory type
-(non-integral pointer vs anything else) is known to unchanged.  That is, it is
+(non-integral pointer vs anything else) is known to unchanged. That is, it is
 not safe to speculate a load if doing causes a non-integral pointer value to
-be loaded as any other type or vice versa.  In practice, this restriction is
+be loaded as any other type or vice versa. In practice, this restriction is
 well isolated to isSafeToSpeculate in ValueTracking.cpp.
 
-Explicit Representation
-^^^^^^^^^^^^^^^^^^^^^^^
+### Explicit Representation
 
 A frontend could directly generate this low level explicit form, but
-doing so may inhibit optimization.  Instead, it is recommended that
+doing so may inhibit optimization. Instead, it is recommended that
 compilers with relocating collectors target the abstract machine model just
 described.
 
 The heart of the explicit approach is to construct (or rewrite) the IR in a
 manner where the possible updates performed by the garbage collector are
-explicitly visible in the IR.  Doing so requires that we:
+explicitly visible in the IR. Doing so requires that we:
 
-#. create a new SSA value for each potentially relocated pointer, and
+1. create a new SSA value for each potentially relocated pointer, and
    ensure that no uses of the original (non relocated) value is
    reachable after the safepoint,
-#. specify the relocation in a way which is opaque to the compiler to
+2. specify the relocation in a way which is opaque to the compiler to
    ensure that the optimizer can not introduce new uses of an
    unrelocated value after a statepoint. This prevents the optimizer
    from performing unsound optimizations.
-#. recording a mapping of live pointers (and the allocation they're
+3. recording a mapping of live pointers (and the allocation they're
    associated with) for each statepoint.
 
 At the most abstract level, inserting a safepoint can be thought of as
@@ -150,46 +141,46 @@ function which both calls the original target of the call, returns
 its result, and returns updated values for any live pointers to
 garbage collected objects.
 
-  Note that the task of identifying all live pointers to garbage
-  collected values, transforming the IR to expose a pointer giving the
-  base object for every such live pointer, and inserting all the
-  intrinsics correctly is explicitly out of scope for this document.
-  The recommended approach is to use the :ref:`utility passes
-  <statepoint-utilities>` described below.
+> Note that the task of identifying all live pointers to garbage
+> collected values, transforming the IR to expose a pointer giving the
+> base object for every such live pointer, and inserting all the
+> intrinsics correctly is explicitly out of scope for this document.
+> The recommended approach is to use the {ref}`utility passes
+> <statepoint-utilities>` described below.
 
 This abstract function call is concretely represented by a sequence of
 intrinsic calls known collectively as a "statepoint relocation sequence".
 
 Let's consider a simple call in LLVM IR:
 
-.. code-block:: llvm
-
-  declare void @foo()
-  define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
-         gc "statepoint-example" {
-    call void @foo()
-    ret ptr addrspace(1) %obj
-  }
+```llvm
+declare void @foo()
+define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
+       gc "statepoint-example" {
+  call void @foo()
+  ret ptr addrspace(1) %obj
+}
+```
 
 Depending on our language we may need to allow a safepoint during the execution
-of ``foo``. If so, we need to let the collector update local values in the
-current frame.  If we don't, we'll be accessing a potential invalid reference
+of `foo`. If so, we need to let the collector update local values in the
+current frame. If we don't, we'll be accessing a potential invalid reference
 once we eventually return from the call.
 
-In this example, we need to relocate the SSA value ``%obj``.  Since we can't
-actually change the value in the SSA value ``%obj``, we need to introduce a new
-SSA value ``%obj.relocated`` which represents the potentially changed value of
-``%obj`` after the safepoint and update any following uses appropriately.  The
+In this example, we need to relocate the SSA value `%obj`. Since we can't
+actually change the value in the SSA value `%obj`, we need to introduce a new
+SSA value `%obj.relocated` which represents the potentially changed value of
+`%obj` after the safepoint and update any following uses appropriately. The
 resulting relocation sequence is:
 
-.. code-block:: llvm
-
-  define ptr addrspace(1) @test(ptr addrspace(1) %obj)
-         gc "statepoint-example" {
-    %safepoint = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %obj)]
-    %obj.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint, i32 0, i32 0)
-    ret ptr addrspace(1) %obj.relocated
-  }
+```llvm
+define ptr addrspace(1) @test(ptr addrspace(1) %obj)
+       gc "statepoint-example" {
+  %safepoint = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %obj)]
+  %obj.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint, i32 0, i32 0)
+  ret ptr addrspace(1) %obj.relocated
+}
+```
 
 Ideally, this sequence would have been represented as a M argument, N
 return value function (where M is the number of values being
@@ -198,96 +189,94 @@ value + each relocated value), but LLVM does not easily support such a
 representation.
 
 Instead, the statepoint intrinsic marks the actual site of the
-safepoint or statepoint.  The statepoint returns a token value (which
-exists only at compile time).  To get back the original return value
-of the call, we use the ``gc.result`` intrinsic.  To get the relocation
-of each pointer in turn, we use the ``gc.relocate`` intrinsic with the
-appropriate index.  Note that both the ``gc.relocate`` and ``gc.result`` are
-tied to the statepoint.  The combination forms a "statepoint relocation
+safepoint or statepoint. The statepoint returns a token value (which
+exists only at compile time). To get back the original return value
+of the call, we use the `gc.result` intrinsic. To get the relocation
+of each pointer in turn, we use the `gc.relocate` intrinsic with the
+appropriate index. Note that both the `gc.relocate` and `gc.result` are
+tied to the statepoint. The combination forms a "statepoint relocation
 sequence" and represents the entirety of a parseable call or 'statepoint'.
 
 When lowered, this example would generate the following x86 assembly:
 
-.. code-block:: gas
-
-	  .globl	test1
-	  .align	16, 0x90
-	  pushq	%rax
-	  callq	foo
-  .Ltmp1:
-	  movq	(%rsp), %rax  # This load is redundant (oops!)
-	  popq	%rdx
-	  retq
+```gas
+        .globl        test1
+        .align        16, 0x90
+        pushq %rax
+        callq foo
+.Ltmp1:
+        movq  (%rsp), %rax  # This load is redundant (oops!)
+        popq  %rdx
+        retq
+```
 
 Each of the potentially relocated values has been spilled to the
 stack, and a record of that location has been recorded to the
-:ref:`Stack Map section <stackmap-section>`.  If the garbage collector
+{ref}`Stack Map section <stackmap-section>`. If the garbage collector
 needs to update any of these pointers during the call, it knows
 exactly what to change.
 
 The relevant parts of the StackMap section for our example are:
 
-.. code-block:: gas
-
-  # This describes the call site
-  # Stack Maps: callsite 2882400000
-	  .quad	2882400000
-	  .long	.Ltmp1-test1
-	  .short	0
-  # .. 8 entries skipped ..
-  # This entry describes the spill slot which is directly addressable
-  # off RSP with offset 0.  Given the value was spilled with a pushq,
-  # that makes sense.
-  # Stack Maps:   Loc 8: Direct RSP     [encoding: .byte 2, .byte 8, .short 7, .int 0]
-	  .byte	2
-	  .byte	8
-	  .short	7
-	  .long	0
-
-This example was taken from the tests for the :ref:`RewriteStatepointsForGC`
-utility pass.  As such, its full StackMap can be easily examined with the
+```gas
+# This describes the call site
+# Stack Maps: callsite 2882400000
+        .quad 2882400000
+        .long .Ltmp1-test1
+        .short        0
+# .. 8 entries skipped ..
+# This entry describes the spill slot which is directly addressable
+# off RSP with offset 0.  Given the value was spilled with a pushq,
+# that makes sense.
+# Stack Maps:   Loc 8: Direct RSP     [encoding: .byte 2, .byte 8, .short 7, .int 0]
+        .byte 2
+        .byte 8
+        .short        7
+        .long 0
+```
+
+This example was taken from the tests for the {ref}`RewriteStatepointsForGC`
+utility pass. As such, its full StackMap can be easily examined with the
 following command.
 
-.. code-block:: bash
+```bash
+opt -rewrite-statepoints-for-gc test/Transforms/RewriteStatepointsForGC/basics.ll -S | llc -debug-only=stackmaps
+```
 
-  opt -rewrite-statepoints-for-gc test/Transforms/RewriteStatepointsForGC/basics.ll -S | llc -debug-only=stackmaps
-
-Simplifications for Non-Relocating GCs
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Simplifications for Non-Relocating GCs
 
 Some of the complexity in the previous example is unnecessary for a
-non-relocating collector.  While a non-relocating collector still needs the
+non-relocating collector. While a non-relocating collector still needs the
 information about which location contain live references, it doesn't need to
-represent explicit relocations.  As such, the previously described explicit
-lowering can be simplified to remove all of the ``gc.relocate`` intrinsic
+represent explicit relocations. As such, the previously described explicit
+lowering can be simplified to remove all of the `gc.relocate` intrinsic
 calls and leave uses in terms of the original reference value.
 
 Here's the explicit lowering for the previous example for a non-relocating
 collector:
 
-.. code-block:: llvm
-
-  define void @manual_frame(ptr %a, ptr %b) gc "statepoint-example" {
-    %alloca = alloca ptr
-    %allocb = alloca ptr
-    store ptr %a, ptr %alloca
-    store ptr %b, ptr %allocb
-    call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr %alloca, ptr %allocb)]
-    ret void
-  }
+```llvm
+define void @manual_frame(ptr %a, ptr %b) gc "statepoint-example" {
+  %alloca = alloca ptr
+  %allocb = alloca ptr
+  store ptr %a, ptr %alloca
+  store ptr %b, ptr %allocb
+  call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr %alloca, ptr %allocb)]
+  ret void
+}
+```
 
-Recording On Stack Regions
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Recording On Stack Regions
 
 In addition to the explicit relocation form previously described, the
 statepoint infrastructure also allows the listing of allocas within the gc
-pointer list.  Allocas can be listed with or without additional explicit gc
+pointer list. Allocas can be listed with or without additional explicit gc
 pointer values and relocations.
 
 An alloca in the gc region of the statepoint operand list will cause the
 address of the stack region to be listed in the stackmap for the statepoint.
 
-This mechanism can be used to describe explicit spill slots if desired.  It
+This mechanism can be used to describe explicit spill slots if desired. It
 then becomes the generator's responsibility to ensure that values are
 spill/filled to/from the alloca as needed on either side of the safepoint.
 Note that there is no way to indicate a corresponding base pointer for such
@@ -300,43 +289,41 @@ references provided that the collector can map from the location on the
 stack to a heap map describing the internal layout of the references the
 collector needs to process.
 
-WARNING: At the moment, this alternate form is not well exercised.  It is
+WARNING: At the moment, this alternate form is not well exercised. It is
 recommended to use this with caution and expect to have to fix a few bugs.
 In particular, the RewriteStatepointsForGC utility pass does not do
 anything for allocas today.
 
-Base & Derived Pointers
-^^^^^^^^^^^^^^^^^^^^^^^
+### Base & Derived Pointers
 
 A "base pointer" is one which points to the starting address of an allocation
-(object).  A "derived pointer" is one which is offset from a base pointer by
-some amount.  When relocating objects, a garbage collector needs to be able
+(object). A "derived pointer" is one which is offset from a base pointer by
+some amount. When relocating objects, a garbage collector needs to be able
 to relocate each derived pointer associated with an allocation to the same
 offset from the new address.
 
 "Interior derived pointers" remain within the bounds of the allocation
-they're associated with.  As a result, the base object can be found at
+they're associated with. As a result, the base object can be found at
 runtime provided the bounds of allocations are known to the runtime system.
 
 "Exterior derived pointers" are outside the bounds of the associated object;
-they may even fall within *another* allocations address range.  As a result,
+they may even fall within *another* allocations address range. As a result,
 there is no way for a garbage collector to determine which allocation they
 are associated with at runtime and compiler support is needed.
 
-The ``gc.relocate`` intrinsic supports an explicit operand for describing the
-allocation associated with a derived pointer.  This operand is frequently
+The `gc.relocate` intrinsic supports an explicit operand for describing the
+allocation associated with a derived pointer. This operand is frequently
 referred to as the base operand, but does not strictly speaking have to be
 a base pointer, but it does need to lie within the bounds of the associated
-allocation.  Some collectors may require that the operand be an actual base
+allocation. Some collectors may require that the operand be an actual base
 pointer rather than merely an internal derived pointer. Note that during
 lowering both the base and derived pointer operands are required to be live
 over the associated call safepoint even if the base is otherwise unused
 afterwards.
 
-.. _gc_transition_args:
+(gc-transition-args)=
 
-GC Transitions
-^^^^^^^^^^^^^^^^^^
+### GC Transitions
 
 As a practical consideration, many garbage-collected systems allow code that is
 collector-aware ("managed code") to call code that is not collector-aware
@@ -349,63 +336,63 @@ statepoint may be marked as a GC transition, and data that is necessary to
 perform the transition (if any) may be provided as additional arguments to the
 statepoint.
 
-  Note that although in many cases statepoints may be inferred to be GC
-  transitions based on the function symbols involved (e.g. a call from a
-  function with GC strategy "foo" to a function with GC strategy "bar"),
-  indirect calls that are also GC transitions must also be supported. This
-  requirement is the driving force behind the decision to require that GC
-  transitions are explicitly marked.
+> Note that although in many cases statepoints may be inferred to be GC
+> transitions based on the function symbols involved (e.g. a call from a
+> function with GC strategy "foo" to a function with GC strategy "bar"),
+> indirect calls that are also GC transitions must also be supported. This
+> requirement is the driving force behind the decision to require that GC
+> transitions are explicitly marked.
 
-Let's revisit the sample given above, this time treating the call to ``@foo``
+Let's revisit the sample given above, this time treating the call to `@foo`
 as a GC transition. Depending on our target, the transition code may need to
 access some extra state in order to inform the collector of the transition.
 Let's assume a hypothetical GC--somewhat unimaginatively named "hypothetical-gc"
 --that requires that a TLS variable must be written to before and after a call
 to unmanaged code. The resulting relocation sequence is:
 
-.. code-block:: llvm
-
-  @flag = thread_local global i32 0, align 4
+```llvm
+ at flag = thread_local global i32 0, align 4
 
-  define i8 addrspace(1)* @test1(i8 addrspace(1) *%obj)
-         gc "hypothetical-gc" {
+define i8 addrspace(1)* @test1(i8 addrspace(1) *%obj)
+       gc "hypothetical-gc" {
 
-    %0 = call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 1, i32* @Flag, i32 0, i8 addrspace(1)* %obj)
-    %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 7, i32 7)
-    ret i8 addrspace(1)* %obj.relocated
-  }
+  %0 = call token (i64, i32, void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 1, i32* @Flag, i32 0, i8 addrspace(1)* %obj)
+  %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %0, i32 7, i32 7)
+  ret i8 addrspace(1)* %obj.relocated
+}
+```
 
 During lowering, this will result in an instruction selection DAG that looks
 something like:
 
-::
-
-  CALLSEQ_START
-  ...
-  GC_TRANSITION_START (lowered i32 *@Flag), SRCVALUE i32* Flag
-  STATEPOINT
-  GC_TRANSITION_END (lowered i32 *@Flag), SRCVALUE i32 *Flag
-  ...
-  CALLSEQ_END
+```
+CALLSEQ_START
+...
+GC_TRANSITION_START (lowered i32 *@Flag), SRCVALUE i32* Flag
+STATEPOINT
+GC_TRANSITION_END (lowered i32 *@Flag), SRCVALUE i32 *Flag
+...
+CALLSEQ_END
+```
 
 In order to generate the necessary transition code, the backend for each target
-supported by "hypothetical-gc" must be modified to lower ``GC_TRANSITION_START``
-and ``GC_TRANSITION_END`` nodes appropriately when the "hypothetical-gc"
+supported by "hypothetical-gc" must be modified to lower `GC_TRANSITION_START`
+and `GC_TRANSITION_END` nodes appropriately when the "hypothetical-gc"
 strategy is in use for a particular function. Assuming that such lowering has
 been added for X86, the generated assembly would be:
 
-.. code-block:: gas
-
-	  .globl	test1
-	  .align	16, 0x90
-	  pushq	%rax
-	  movl $1, %fs:Flag at TPOFF
-	  callq	foo
-	  movl $0, %fs:Flag at TPOFF
-  .Ltmp1:
-	  movq	(%rsp), %rax  # This load is redundant (oops!)
-	  popq	%rdx
-	  retq
+```gas
+        .globl        test1
+        .align        16, 0x90
+        pushq %rax
+        movl $1, %fs:Flag at TPOFF
+        callq foo
+        movl $0, %fs:Flag at TPOFF
+.Ltmp1:
+        movq  (%rsp), %rax  # This load is redundant (oops!)
+        popq  %rdx
+        retq
+```
 
 Note that the design as presented above is not fully implemented: in particular,
 strategy-specific lowering is not present, and all GC transitions are emitted as
@@ -413,227 +400,221 @@ as single no-op before and after the call instruction. These no-ops are often
 removed by the backend during dead machine instruction elimination.
 
 Before the abstract machine model is lowered to the explicit statepoint model
-of relocations by the :ref:`RewriteStatepointsForGC` pass it is possible for
+of relocations by the {ref}`RewriteStatepointsForGC` pass it is possible for
 any derived pointer to get its base pointer and offset from the base pointer
-by using the ``gc.get.pointer.base`` and the ``gc.get.pointer.offset``
+by using the `gc.get.pointer.base` and the `gc.get.pointer.offset`
 intrinsics respectively. These intrinsics are inlined by the
-:ref:`RewriteStatepointsForGC` pass and must not be used after this pass.
+{ref}`RewriteStatepointsForGC` pass and must not be used after this pass.
 
+(statepoint-stackmap-format)=
 
-.. _statepoint-stackmap-format:
-
-Stack Map Format
-================
+## Stack Map Format
 
 Locations for each pointer value which may need read and/or updated by
 the runtime or collector are provided in a separate section of the
 generated object file as specified in the PatchPoint documentation.
 This special section is encoded per the
-:ref:`Stack Map format <stackmap-format>`.
+{ref}`Stack Map format <stackmap-format>`.
 
 The general expectation is that a JIT compiler will parse and discard this
-format; it is not particularly memory efficient.  If you need an alternate
+format; it is not particularly memory efficient. If you need an alternate
 format (e.g. for an ahead of time compiler), see discussion under
-:ref: `open work items <OpenWork>` below.
+\:ref: `open work items <OpenWork>` below.
 
 Each statepoint generates the following Locations:
 
-* Constant which describes the calling convention of the call target. This
-  constant is a valid :ref:`calling convention identifier <callingconv>` for
+- Constant which describes the calling convention of the call target. This
+  constant is a valid {ref}`calling convention identifier <callingconv>` for
   the version of LLVM used to generate the stackmap. No additional compatibility
   guarantees are made for this constant over what LLVM provides elsewhere w.r.t.
   these identifiers.
-* Constant which describes the flags passed to the statepoint intrinsic
-* Constant which describes number of following deopt *Locations* (not
-  operands).  Will be 0 if no "deopt" bundle is provided.
-* Variable number of Locations, one for each deopt parameter listed in the
-  "deopt" operand bundle.  At the moment, only deopt parameters with a bitwidth
-  of 64 bits or less are supported.  Values of a type larger than 64 bits can be
+- Constant which describes the flags passed to the statepoint intrinsic
+- Constant which describes number of following deopt *Locations* (not
+  operands). Will be 0 if no "deopt" bundle is provided.
+- Variable number of Locations, one for each deopt parameter listed in the
+  "deopt" operand bundle. At the moment, only deopt parameters with a bitwidth
+  of 64 bits or less are supported. Values of a type larger than 64 bits can be
   specified and reported only if a) the value is constant at the call site, and
   b) the constant can be represented with less than 64 bits (assuming zero
   extension to the original bitwidth).
-* Variable number of relocation records, each of which consists of
-  exactly two Locations.  Relocation records are described in detail
+- Variable number of relocation records, each of which consists of
+  exactly two Locations. Relocation records are described in detail
   below.
 
 Each relocation record provides sufficient information for a collector to
-relocate one or more derived pointers.  Each record consists of a pair of
-Locations.  The second element in the record represents the pointer (or
-pointers) which need updated.  The first element in the record provides a
+relocate one or more derived pointers. Each record consists of a pair of
+Locations. The second element in the record represents the pointer (or
+pointers) which need updated. The first element in the record provides a
 pointer to the base of the object with which the pointer(s) being relocated is
-associated.  This information is required for handling generalized derived
+associated. This information is required for handling generalized derived
 pointers since a pointer may be outside the bounds of the original allocation,
-but still needs to be relocated with the allocation.  Additionally:
+but still needs to be relocated with the allocation. Additionally:
 
-* It is guaranteed that the base pointer must also appear explicitly as a
+- It is guaranteed that the base pointer must also appear explicitly as a
   relocation pair if used after the statepoint.
-* There may be fewer relocation records then gc parameters in the IR
+- There may be fewer relocation records then gc parameters in the IR
   statepoint. Each *unique* pair will occur at least once; duplicates
   are possible.
-* The Locations within each record may either be of pointer size or a
-  multiple of pointer size.  In the later case, the record must be
+- The Locations within each record may either be of pointer size or a
+  multiple of pointer size. In the later case, the record must be
   interpreted as describing a sequence of pointers and their corresponding
   base pointers. If the Location is of size N x sizeof(pointer), then
   there will be N records of one pointer each contained within the Location.
   Both Locations in a pair can be assumed to be of the same size.
 
 Note that the Locations used in each section may describe the same
-physical location.  e.g. A stack slot may appear as a deopt location,
+physical location. e.g. A stack slot may appear as a deopt location,
 a gc base pointer, and a gc derived pointer.
 
 The LiveOut section of the StkMapRecord will be empty for a statepoint
 record.
 
-Safepoint Semantics & Verification
-==================================
+## Safepoint Semantics & Verification
 
 The fundamental correctness property for the compiled code's
-correctness w.r.t. the garbage collector is a dynamic one.  It must be
+correctness w.r.t. the garbage collector is a dynamic one. It must be
 the case that there is no dynamic trace such that an operation
 involving a potentially relocated pointer is observably-after a
-safepoint which could relocate it.  'observably-after' is this usage
+safepoint which could relocate it. 'observably-after' is this usage
 means that an outside observer could observe this sequence of events
 in a way which precludes the operation being performed before the
 safepoint.
 
 To understand why this 'observable-after' property is required,
 consider a null comparison performed on the original copy of a
-relocated pointer.  Assuming that control flow follows the safepoint,
+relocated pointer. Assuming that control flow follows the safepoint,
 there is no way to observe externally whether the null comparison is
-performed before or after the safepoint.  (Remember, the original
-Value is unmodified by the safepoint.)  The compiler is free to make
+performed before or after the safepoint. (Remember, the original
+Value is unmodified by the safepoint.) The compiler is free to make
 either scheduling choice.
 
 The actual correctness property implemented is slightly stronger than
-this.  We require that there be no *static path* on which a
+this. We require that there be no *static path* on which a
 potentially relocated pointer is 'observably-after' it may have been
-relocated.  This is slightly stronger than is strictly necessary (and
+relocated. This is slightly stronger than is strictly necessary (and
 thus may disallow some otherwise valid programs), but greatly
 simplifies reasoning about correctness of the compiled code.
 
 By construction, this property will be upheld by the optimizer if
-correctly established in the source IR.  This is a key invariant of
+correctly established in the source IR. This is a key invariant of
 the design.
 
 The existing IR Verifier pass has been extended to check most of the
 local restrictions on the intrinsics mentioned in their respective
-documentation.  The current implementation in LLVM does not check the
+documentation. The current implementation in LLVM does not check the
 key relocation invariant, but this is ongoing work on developing such
-a verifier.  Please ask on llvm-dev if you're interested in
+a verifier. Please ask on llvm-dev if you're interested in
 experimenting with the current version.
 
-.. _statepoint-utilities:
+(statepoint-utilities)=
 
-Utility Passes for Safepoint Insertion
-======================================
+## Utility Passes for Safepoint Insertion
 
-.. _RewriteStatepointsForGC:
+(rewritestatepointsforgc)=
 
-RewriteStatepointsForGC
-^^^^^^^^^^^^^^^^^^^^^^^^
+### RewriteStatepointsForGC
 
 The pass RewriteStatepointsForGC transforms a function's IR to lower from the
 abstract machine model described above to the explicit statepoint model of
-relocations.  To do this, it replaces all calls or invokes of functions which
-might contain a safepoint poll with a ``gc.statepoint`` and associated full
-relocation sequence, including all required ``gc.relocates``.
+relocations. To do this, it replaces all calls or invokes of functions which
+might contain a safepoint poll with a `gc.statepoint` and associated full
+relocation sequence, including all required `gc.relocates`.
 
-This pass only applies to GCStrategy instances where the ``UseRS4GC`` flag
+This pass only applies to GCStrategy instances where the `UseRS4GC` flag
 is set. The two builtin GC strategies with this set are the
 "statepoint-example" and "coreclr" strategies.
 
 As an example, given this code:
 
-.. code-block:: llvm
-
-  define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
-         gc "statepoint-example" {
-    call void @foo()
-    ret ptr addrspace(1) %obj
-  }
+```llvm
+define ptr addrspace(1) @test1(ptr addrspace(1) %obj)
+       gc "statepoint-example" {
+  call void @foo()
+  ret ptr addrspace(1) %obj
+}
+```
 
 The pass would produce this IR:
 
-.. code-block:: llvm
-
-  define ptr addrspace(1) @test_rs4gc(ptr addrspace(1) %obj) gc "statepoint-example" {
-    %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %obj) ]
-    %obj.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%obj, %obj)
-    ret ptr addrspace(1) %obj.relocated
-  }
+```llvm
+define ptr addrspace(1) @test_rs4gc(ptr addrspace(1) %obj) gc "statepoint-example" {
+  %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %obj) ]
+  %obj.relocated = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%obj, %obj)
+  ret ptr addrspace(1) %obj.relocated
+}
+```
 
 In the above examples, the addrspace(1) marker on the pointers is the mechanism
-that the ``statepoint-example`` GC strategy uses to distinguish references from
-non references.  This is controlled via GCStrategy::isGCManagedPointer. The
-``statepoint-example`` and ``coreclr`` strategies (the only two default
+that the `statepoint-example` GC strategy uses to distinguish references from
+non references. This is controlled via GCStrategy::isGCManagedPointer. The
+`statepoint-example` and `coreclr` strategies (the only two default
 strategies that support statepoints) both use addrspace(1) to determine which
 pointers are references, however custom strategies don't have to follow this
 convention.
 
 This pass can be used an utility function by a language frontend that doesn't
 want to manually reason about liveness, base pointers, or relocation when
-constructing IR.  As currently implemented, RewriteStatepointsForGC must be
+constructing IR. As currently implemented, RewriteStatepointsForGC must be
 run after SSA construction (i.e. mem2ref).
 
 RewriteStatepointsForGC will ensure that appropriate base pointers are listed
-for every relocation created.  It will do so by duplicating code as needed to
+for every relocation created. It will do so by duplicating code as needed to
 propagate the base pointer associated with each pointer being relocated to
-the appropriate safepoints.  The implementation assumes that the following
+the appropriate safepoints. The implementation assumes that the following
 IR constructs produce base pointers: loads from the heap, addresses of global
 variables, function arguments, function return values. Constant pointers (such
-as null) are also assumed to be base pointers.  In practice, this constraint
+as null) are also assumed to be base pointers. In practice, this constraint
 can be relaxed to producing interior derived pointers provided the target
 collector can find the associated allocation from an arbitrary interior
 derived pointer.
 
-By default RewriteStatepointsForGC passes in ``0xABCDEF00`` as the statepoint
-ID and ``0`` as the number of patchable bytes to the newly constructed
-``gc.statepoint``.  These values can be configured on a per-callsite
-basis using the attributes ``"statepoint-id"`` and
-``"statepoint-num-patch-bytes"``.  If a call site is marked with a
-``"statepoint-id"`` function attribute and its value is a positive
+By default RewriteStatepointsForGC passes in `0xABCDEF00` as the statepoint
+ID and `0` as the number of patchable bytes to the newly constructed
+`gc.statepoint`. These values can be configured on a per-callsite
+basis using the attributes `"statepoint-id"` and
+`"statepoint-num-patch-bytes"`. If a call site is marked with a
+`"statepoint-id"` function attribute and its value is a positive
 integer (represented as a string), then that value is used as the ID
-of the newly constructed ``gc.statepoint``.  If a call site is marked
-with a ``"statepoint-num-patch-bytes"`` function attribute and its
+of the newly constructed `gc.statepoint`. If a call site is marked
+with a `"statepoint-num-patch-bytes"` function attribute and its
 value is a positive integer, then that value is used as the 'num patch
-bytes' parameter of the newly constructed ``gc.statepoint``.  The
-``"statepoint-id"`` and ``"statepoint-num-patch-bytes"`` attributes
-are not propagated to the ``gc.statepoint`` call or invoke if they
+bytes' parameter of the newly constructed `gc.statepoint`. The
+`"statepoint-id"` and `"statepoint-num-patch-bytes"` attributes
+are not propagated to the `gc.statepoint` call or invoke if they
 could be successfully parsed.
 
 In practice, RewriteStatepointsForGC should be run much later in the pass
-pipeline, after most optimization is already done.  This helps to improve
+pipeline, after most optimization is already done. This helps to improve
 the quality of the generated code when compiled with garbage collection support.
 
-.. _RewriteStatepointsForGC_intrinsic_lowering:
+(rewritestatepointsforgc-intrinsic-lowering)=
 
-RewriteStatepointsForGC intrinsic lowering
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### RewriteStatepointsForGC intrinsic lowering
 
 As a part of lowering to the explicit model of relocations
 RewriteStatepointsForGC performs GC specific lowering for the following
 intrinsics:
 
-* ``gc.get.pointer.base``
-* ``gc.get.pointer.offset``
-* ``llvm.memcpy.element.unordered.atomic.*``
-* ``llvm.memmove.element.unordered.atomic.*``
+- `gc.get.pointer.base`
+- `gc.get.pointer.offset`
+- `llvm.memcpy.element.unordered.atomic.*`
+- `llvm.memmove.element.unordered.atomic.*`
 
 There are two possible lowerings for the memcpy and memmove operations:
 GC leaf lowering and GC parseable lowering. If a call is explicitly marked with
 "gc-leaf-function" attribute the call is lowered to a GC leaf call to
-'``__llvm_memcpy_element_unordered_atomic_*``' or
-'``__llvm_memmove_element_unordered_atomic_*``' symbol. Such a call can not
+'`__llvm_memcpy_element_unordered_atomic_*`' or
+'`__llvm_memmove_element_unordered_atomic_*`' symbol. Such a call can not
 take a safepoint. Otherwise, the call is made GC parseable by wrapping the
 call into a statepoint. This makes it possible to take a safepoint during
 copy operation. Note that a GC parseable copy operation is not required to
 take a safepoint. For example, a short copy operation may be performed without
 taking a safepoint.
 
-GC parseable calls to '``llvm.memcpy.element.unordered.atomic.*``',
-'``llvm.memmove.element.unordered.atomic.*``' intrinsics are lowered to calls
-to '``__llvm_memcpy_element_unordered_atomic_safepoint_*``',
-'``__llvm_memmove_element_unordered_atomic_safepoint_*``' symbols respectively.
+GC parseable calls to '`llvm.memcpy.element.unordered.atomic.*`',
+'`llvm.memmove.element.unordered.atomic.*`' intrinsics are lowered to calls
+to '`__llvm_memcpy_element_unordered_atomic_safepoint_*`',
+'`__llvm_memmove_element_unordered_atomic_safepoint_*`' symbols respectively.
 This way the runtime can provide implementations of copy operations with and
 without safepoints.
 
@@ -645,18 +626,16 @@ pointers to be available in the copy operation. In order to make the base
 pointers available RewriteStatepointsForGC replaces derived pointers with base
 pointer and offset pairs. For example:
 
-.. code-block:: llvm
+```llvm
+declare void @__llvm_memcpy_element_unordered_atomic_safepoint_1(
+  i8 addrspace(1)*  %dest_base, i64 %dest_offset,
+  i8 addrspace(1)*  %src_base, i64 %src_offset,
+  i64 %length)
+```
 
-  declare void @__llvm_memcpy_element_unordered_atomic_safepoint_1(
-    i8 addrspace(1)*  %dest_base, i64 %dest_offset,
-    i8 addrspace(1)*  %src_base, i64 %src_offset,
-    i64 %length)
+(placesafepoints)=
 
-
-.. _PlaceSafepoints:
-
-PlaceSafepoints
-^^^^^^^^^^^^^^^^
+### PlaceSafepoints
 
 The pass PlaceSafepoints inserts safepoint polls sufficient to ensure running
 code checks for a safepoint request on a timely manner. This pass is expected
@@ -665,128 +644,117 @@ relocation sequences.
 
 As an example, given input IR of the following:
 
-.. code-block:: llvm
-
-  define void @test() gc "statepoint-example" {
-    call void @foo()
-    ret void
-  }
-
-  declare void @do_safepoint()
-  define void @gc.safepoint_poll() {
-    call void @do_safepoint()
-    ret void
-  }
+```llvm
+define void @test() gc "statepoint-example" {
+  call void @foo()
+  ret void
+}
 
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+  call void @do_safepoint()
+  ret void
+}
+```
 
 This pass would produce the following IR:
 
-.. code-block:: llvm
-
-  define void @test() gc "statepoint-example" {
-    call void @do_safepoint()
-    call void @foo()
-    ret void
-  }
-
-In this case, we've added an (unconditional) entry safepoint poll.  Note that
-despite appearances, the entry poll is not necessarily redundant.  We'd have to
-know that ``foo`` and ``test`` were not mutually recursive for the poll to be
-redundant.  In practice, you'd probably want to your poll definition to contain
+```llvm
+define void @test() gc "statepoint-example" {
+  call void @do_safepoint()
+  call void @foo()
+  ret void
+}
+```
+
+In this case, we've added an (unconditional) entry safepoint poll. Note that
+despite appearances, the entry poll is not necessarily redundant. We'd have to
+know that `foo` and `test` were not mutually recursive for the poll to be
+redundant. In practice, you'd probably want to your poll definition to contain
 a conditional branch of some form.
 
 At the moment, PlaceSafepoints can insert safepoint polls at method entry and
-loop backedges locations.  Extending this to work with return polls would be
+loop backedges locations. Extending this to work with return polls would be
 straight forward if desired.
 
 PlaceSafepoints includes a number of optimizations to avoid placing safepoint
 polls at particular sites unless needed to ensure timely execution of a poll
-under normal conditions.  PlaceSafepoints does not attempt to ensure timely
+under normal conditions. PlaceSafepoints does not attempt to ensure timely
 execution of a poll under worst case conditions such as heavy system paging.
 
 The implementation of a safepoint poll action is specified by looking up a
-function of the name ``gc.safepoint_poll`` in the containing Module.  The body
-of this function is inserted at each poll site desired.  While calls or invokes
-inside this method are transformed to a ``gc.statepoints``, recursive poll
+function of the name `gc.safepoint_poll` in the containing Module. The body
+of this function is inserted at each poll site desired. While calls or invokes
+inside this method are transformed to a `gc.statepoints`, recursive poll
 insertion is not performed.
 
 This pass is useful for any language frontend which only has to support
-garbage collection semantics at safepoints.  If you need other abstract
+garbage collection semantics at safepoints. If you need other abstract
 frame information at safepoints (e.g. for deoptimization or introspection),
-you can insert safepoint polls in the frontend.  If you have the later case,
-please ask on llvm-dev for suggestions.  There's been a good amount of work
+you can insert safepoint polls in the frontend. If you have the later case,
+please ask on llvm-dev for suggestions. There's been a good amount of work
 done on making such a scheme work well in practice which is not yet documented
 here.
 
-
-Supported Architectures
-=======================
+## Supported Architectures
 
 Support for statepoint generation requires some code for each backend.
 Today, only Aarch64 and X86_64 are supported.
 
-.. _OpenWork:
+(openwork)=
 
-Limitations and Half Baked Ideas
-================================
+## Limitations and Half Baked Ideas
 
-Mixing References and Raw Pointers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Mixing References and Raw Pointers
 
 Support for languages which allow unmanaged pointers to garbage collected
 objects (i.e. pass a pointer to an object to a C routine) in the abstract
-machine model.  At the moment, the best idea on how to approach this
+machine model. At the moment, the best idea on how to approach this
 involves an intrinsic or opaque function which hides the connection between
-the reference value and the raw pointer.  The problem is that having a
+the reference value and the raw pointer. The problem is that having a
 ptrtoint or inttoptr cast (which is common for such use cases) breaks the
 rules used for inferring base pointers for arbitrary references when
-lowering out of the abstract model to the explicit physical model.  Note
+lowering out of the abstract model to the explicit physical model. Note
 that a frontend which lowers directly to the physical model doesn't have
 any problems here.
 
-Objects on the Stack
-^^^^^^^^^^^^^^^^^^^^
+### Objects on the Stack
 
 As noted above, the explicit lowering supports objects allocated on the
 stack provided the collector can find a heap map given the stack address.
 
 The missing pieces are a) integration with rewriting (RS4GC) from the
 abstract machine model and b) support for optionally decomposing on stack
-objects so as not to require heap maps for them.  The later is required
+objects so as not to require heap maps for them. The later is required
 for ease of integration with some collectors.
 
-Lowering Quality and Representation Overhead
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Lowering Quality and Representation Overhead
 
-The current statepoint lowering is known to be somewhat poor.  In the very
+The current statepoint lowering is known to be somewhat poor. In the very
 long term, we'd like to integrate statepoints with the register allocator;
-in the near term this is unlikely to happen.  We've found the quality of
+in the near term this is unlikely to happen. We've found the quality of
 lowering to be relatively unimportant as hot-statepoints are almost always
 inliner bugs.
 
 Concerns have been raised that the statepoint representation results in a
 large amount of IR being produced for some examples and that this
-contributes to higher than expected memory usage and compile times.  There's
+contributes to higher than expected memory usage and compile times. There's
 no immediate plans to make changes due to this, but alternate models may be
 explored in the future.
 
-Relocations Along Exceptional Edges
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+### Relocations Along Exceptional Edges
 
-Relocations along exceptional paths are currently broken in ToT.  In
+Relocations along exceptional paths are currently broken in ToT. In
 particular, there is current no way to represent a rethrow on a path which
-also has relocations.  See `this llvm-dev discussion
-<https://groups.google.com/forum/#!topic/llvm-dev/AE417XjgxvI>`_ for more
+also has relocations. See [this llvm-dev discussion](https://groups.google.com/forum/#!topic/llvm-dev/AE417XjgxvI) for more
 detail.
 
-Bugs and Enhancements
-=====================
+## Bugs and Enhancements
 
 Currently known bugs and enhancements under consideration can be
-tracked by performing a `bugzilla search
-<https://bugs.llvm.org/buglist.cgi?cmdtype=runnamed&namedcmd=Statepoint%20Bugs&list_id=64342>`_
+tracked by performing a [bugzilla search](https://bugs.llvm.org/buglist.cgi?cmdtype=runnamed&namedcmd=Statepoint%20Bugs&list_id=64342)
 for [Statepoint] in the summary field. When filing new bugs, please
-use this tag so that interested parties see the newly filed bug.  As
-with most LLVM features, design discussions take place on the `Discourse forums <https://discourse.llvm.org>`_ and patches
-should be sent to `llvm-commits
-<http://lists.llvm.org/mailman/listinfo/llvm-commits>`_ for review.
+use this tag so that interested parties see the newly filed bug. As
+with most LLVM features, design discussions take place on the [Discourse forums](https://discourse.llvm.org) and patches
+should be sent to [llvm-commits](http://lists.llvm.org/mailman/listinfo/llvm-commits) for review.
+
diff --git a/llvm/docs/SupportPolicy.md b/llvm/docs/SupportPolicy.md
index 0766522a9c578..3f22b36ea15db 100644
--- a/llvm/docs/SupportPolicy.md
+++ b/llvm/docs/SupportPolicy.md
@@ -1,6 +1,4 @@
-=============================
-LLVM Community Support Policy
-=============================
+# LLVM Community Support Policy
 
 As a compilation infrastructure, LLVM has multiple types of users, both
 downstream and upstream, of many combinations of its projects, tools and
@@ -27,14 +25,13 @@ the external repositories that need them.
 But the maintenance costs of such diverse ecosystem is non trivial, so we divide
 the level of support in two tiers: core and peripheral, with two
 different levels of impact and responsibilities. Those tiers refer only to the
-main repository (``llvm-project``) and not the other repositories in our git
+main repository (`llvm-project`) and not the other repositories in our git
 project, unless explicitly stated.
 
 Regardless of the tier, all code must follow the existing policies on quality,
 reviews, style, etc.
 
-Core Tier
-=========
+## Core Tier
 
 The core tier encompasses all of the code in the main repository that is
 in production, is actively tested and released in a regular schedule, including
@@ -44,31 +41,28 @@ tools, etc.
 It is the responsibility of **every** LLVM developer to care for the core tier
 regardless of where their work is applied to.
 
-What is covered
----------------
+### What is covered
 
 The core tier is composed of:
- * Core code (``llvm-project``) present in official releases and buildbots:
-   compiler, debugger, linker, libraries, etc, including infrastructure code
-   (table-gen, lit, file-check, unit-tests, etc).
- * Build infrastructure that creates releases and buildbots (CMake, scripts).
- * `Phabricator <https://github.com/llvm/phabricator>`_ and
-   `buildbot <https://github.com/llvm/llvm-zorg>`_ infrastructure.
- * The `test-suite <https://github.com/llvm/llvm-test-suite>`_.
+: - Core code (`llvm-project`) present in official releases and buildbots:
+    compiler, debugger, linker, libraries, etc, including infrastructure code
+    (table-gen, lit, file-check, unit-tests, etc).
+  - Build infrastructure that creates releases and buildbots (CMake, scripts).
+  - [Phabricator](https://github.com/llvm/phabricator) and
+    [buildbot](https://github.com/llvm/llvm-zorg) infrastructure.
+  - The [test-suite](https://github.com/llvm/llvm-test-suite).
 
-Requirements
-------------
+### Requirements
 
 Code in this tier must:
- * Keep official buildbots green, with warnings on breakages being emailed to
-   all affected developers. Those must be fixed as soon as possible or patches
-   must be reverted, as per review policy.
- * Bit-rot of a component in the core tier will result in that component being
-   downgraded to the peripheral tier or being removed. Sub-communities can
-   avoid this by fixing all raised issues in a timely manner.
+: - Keep official buildbots green, with warnings on breakages being emailed to
+    all affected developers. Those must be fixed as soon as possible or patches
+    must be reverted, as per review policy.
+  - Bit-rot of a component in the core tier will result in that component being
+    downgraded to the peripheral tier or being removed. Sub-communities can
+    avoid this by fixing all raised issues in a timely manner.
 
-Peripheral Tier
-===============
+## Peripheral Tier
 
 The peripheral tier encompass the parts of LLVM that cater to a specific
 sub-community and which don't usually affect the core components directly.
@@ -81,65 +75,62 @@ It is the responsibility of each sub-community to care about their own parts
 and the intersection of that with the core tier and other peripheral parts.
 
 There are three main groups of code that fit in this category:
- * Code that is making its way into LLVM, via the `experimental <https://llvm.org/docs/DeveloperPolicy.html#introducing-new-components-into-llvm>`_
-   roadmap or similar efforts.
- * Code that is making its way out of LLVM, via deprecation, replacement or
-   bit-rot, and will be removed if the sub-community that cares about it
-   cannot maintain it.
- * Code that isn't meant to be in LLVM core and can coexist with the code in
-   the core tier (and others in the peripheral tier) long term, without causing
-   breakages or disturbances.
-
-What is covered
----------------
+: - Code that is making its way into LLVM, via the [experimental](https://llvm.org/docs/DeveloperPolicy.html#introducing-new-components-into-llvm)
+    roadmap or similar efforts.
+  - Code that is making its way out of LLVM, via deprecation, replacement or
+    bit-rot, and will be removed if the sub-community that cares about it
+    cannot maintain it.
+  - Code that isn't meant to be in LLVM core and can coexist with the code in
+    the core tier (and others in the peripheral tier) long term, without causing
+    breakages or disturbances.
+
+### What is covered
 
 The peripheral tier is composed of:
- * Experimental targets and options that haven't been enable by default yet.
- * Main repository projects that don't get released or regularly tested.
- * Legacy tools and scripts that aren't used in upstream validation.
- * Alternative build systems (ex. GN, Bazel) and related infrastructure.
- * Tools support (ex. gdb scripts, editor configuration, helper scripts).
+: - Experimental targets and options that haven't been enable by default yet.
+  - Main repository projects that don't get released or regularly tested.
+  - Legacy tools and scripts that aren't used in upstream validation.
+  - Alternative build systems (ex. GN, Bazel) and related infrastructure.
+  - Tools support (ex. gdb scripts, editor configuration, helper scripts).
 
-Requirements
-------------
+### Requirements
 
 Code in this tier must:
- * Have a clear benefit for residing in the main repository, catering to an
-   active sub-community (upstream or downstream).
- * Be actively maintained by such sub-community and have its problems addressed
-   in a timely manner.
+: - Have a clear benefit for residing in the main repository, catering to an
+    active sub-community (upstream or downstream).
+  - Be actively maintained by such sub-community and have its problems addressed
+    in a timely manner.
 
 Code in this tier must **not**:
- * Break or invalidate core tier code or infrastructure. If that happens
-   accidentally, reverting functionality and working on the issues offline
-   is the only acceptable course of action.
- * Negatively affect development of core tier code, with the sub-community
-   involved responsible for making changes to address specific concerns.
- * Negatively affect other peripheral tier code, with the sub-communities
-   involved tasked to resolve the issues, still making sure the solution doesn't
-   break or invalidate the core tier.
- * Impose sub-optimal implementation strategies on core tier components as a
-   result of idiosyncrasies in the peripheral component.
- * Have build infrastructure that spams all developers about their breakages.
- * Fall into disrepair. This is a reflection of lack of an active sub-community
-   and will result in removal.
+: - Break or invalidate core tier code or infrastructure. If that happens
+    accidentally, reverting functionality and working on the issues offline
+    is the only acceptable course of action.
+  - Negatively affect development of core tier code, with the sub-community
+    involved responsible for making changes to address specific concerns.
+  - Negatively affect other peripheral tier code, with the sub-communities
+    involved tasked to resolve the issues, still making sure the solution doesn't
+    break or invalidate the core tier.
+  - Impose sub-optimal implementation strategies on core tier components as a
+    result of idiosyncrasies in the peripheral component.
+  - Have build infrastructure that spams all developers about their breakages.
+  - Fall into disrepair. This is a reflection of lack of an active sub-community
+    and will result in removal.
 
 Code in this tier should:
- * Have infrastructure to test, whenever meaningful, with either no warnings or
-   notification contained within the sub-community.
- * Have support and testing that scales with the complexity and resilience of
-   the component, with the bar for simple and gracefully-degrading components
-   (such as editor bindings) much lower than for complex components that must
-   remain fresh with HEAD (such as experimental back-ends or alternative build
-   systems).
- * Have a document making clear the status of implementation, level of support
-   available, who the sub-community is and, if applicable, roadmap for inclusion
-   into the core tier.
- * Be restricted to a specific directory or have a consistent pattern (ex.
-   unique file suffix), making it easy to remove when necessary.
-
-Inclusion Policy
-================
+: - Have infrastructure to test, whenever meaningful, with either no warnings or
+    notification contained within the sub-community.
+  - Have support and testing that scales with the complexity and resilience of
+    the component, with the bar for simple and gracefully-degrading components
+    (such as editor bindings) much lower than for complex components that must
+    remain fresh with HEAD (such as experimental back-ends or alternative build
+    systems).
+  - Have a document making clear the status of implementation, level of support
+    available, who the sub-community is and, if applicable, roadmap for inclusion
+    into the core tier.
+  - Be restricted to a specific directory or have a consistent pattern (ex.
+    unique file suffix), making it easy to remove when necessary.
+
+## Inclusion Policy
 
 To add a new peripheral component, send an RFC to the appropriate dev list
 proposing its addition and explaining how it will meet the support requirements
@@ -163,8 +154,7 @@ are not added too close to a release branch. The time will depend on the size
 and complexity of the component, so adding release and testing managers on the
 RFC and review is strongly advisable.
 
-Deprecation Policy
-==================
+## Deprecation Policy
 
 The LLVM code base has a number of files that aren't being actively maintained.
 But not all of those files are obstructing the development of the project and
@@ -174,17 +164,16 @@ useful for downstream users.
 For code to remain in the repository, its presence must not impose an undue
 burden on maintaining other components (core or peripheral).
 
-Warnings
---------
+### Warnings
 
 There are multiple types of issues that might trigger a request for deprecation,
 including (but not limited to):
 
- * Changes in a component consistently break other areas of the project.
- * Components go broken for long periods of time (weeks or more).
- * Clearly superior alternatives are in use and maintenance is painful.
- * Builds and tests are harder / take longer, increasing the cost of
-   maintenance, overtaking the perceived benefits.
+> - Changes in a component consistently break other areas of the project.
+> - Components go broken for long periods of time (weeks or more).
+> - Clearly superior alternatives are in use and maintenance is painful.
+> - Builds and tests are harder / take longer, increasing the cost of
+>   maintenance, overtaking the perceived benefits.
 
 If the maintenance cost is higher than it is acceptable by the majority of
 developers, it means that either the sub-community is too small (and the extra
@@ -192,8 +181,7 @@ cost should be paid locally), or not active enough (and the problems won't be
 fixed any time soon). In either case, removal of such problematic component is
 justified.
 
-Steps for removal
------------------
+### Steps for removal
 
 However clear the needs for removal are, we should take an incremental approach
 to deprecating code, especially when there's still a sub-community that cares
@@ -201,25 +189,28 @@ about it. In that sense, code will never be removed outright without a series
 of steps are taken.
 
 A minimum set of steps should be:
- #. A proposal for removal / deactivation should be made to the Discourse forums 
-    (under the appropriate category), with a clear
-    statement of the maintenance costs imposed and the alternatives, if
-    applicable.
- #. There must be enough consensus on the list that removal is warranted, and no
-    pending proposals to fix the situation from a sub-community.
- #. An announcement for removal must be made on the same lists, with ample time
-    for downstream users to take action on their local infrastructure. The time
-    will depend on what is being removed.
-
-    #. If a script or documents are to be removed, they can always be pulled
-       from previous revision, and can be removed within days.
-    #. if a whole target is removed, we need to first announce publicly, and
-       potentially mark as deprecated in one release, only to remove on the
-       next release.
-    #. Everything else will fall in between those two extremes.
- #. The removal is made by either the proposer or the sub-community that used to
-    maintain it, with replacements and arrangements made atomically on the same
-    commit.
+: 1. A proposal for removal / deactivation should be made to the Discourse forums
+     (under the appropriate category), with a clear
+     statement of the maintenance costs imposed and the alternatives, if
+     applicable.
+
+  2. There must be enough consensus on the list that removal is warranted, and no
+     pending proposals to fix the situation from a sub-community.
+
+  3. An announcement for removal must be made on the same lists, with ample time
+     for downstream users to take action on their local infrastructure. The time
+     will depend on what is being removed.
+
+     1. If a script or documents are to be removed, they can always be pulled
+        from previous revision, and can be removed within days.
+     2. if a whole target is removed, we need to first announce publicly, and
+        potentially mark as deprecated in one release, only to remove on the
+        next release.
+     3. Everything else will fall in between those two extremes.
+
+  4. The removal is made by either the proposer or the sub-community that used to
+     maintain it, with replacements and arrangements made atomically on the same
+     commit.
 
 If a proposal for removal is delayed by the promise a sub-community will take
 care of the code affected, the sub-community will have a time to fix all the
@@ -227,8 +218,7 @@ issues (depending on each case, as above), and if those are not fixed in time, a
 subsequent request for removal should be made and the community may elect to
 eject the component without further attempts to fix.
 
-Reinstatement
--------------
+### Reinstatement
 
 If a component is removed from LLVM, it may, at a later date, request inclusion
 of a modified version, with evidence that all of the issues were fixed and that
diff --git a/llvm/docs/SystemLibrary.md b/llvm/docs/SystemLibrary.md
index 4409532153a68..044ececb6503f 100644
--- a/llvm/docs/SystemLibrary.md
+++ b/llvm/docs/SystemLibrary.md
@@ -1,9 +1,7 @@
-==============
-System Library
-==============
+# System Library
 
-Moved
-=====
+## Moved
 
 The System Library has been renamed to Support Library with documentation
-available at :doc:`SupportLibrary`. Please, change your links to that page.
+available at {doc}`SupportLibrary`. Please, change your links to that page.
+
diff --git a/llvm/docs/TableGen/BackEnds.md b/llvm/docs/TableGen/BackEnds.md
index dead1ba129178..47b7be492332f 100644
--- a/llvm/docs/TableGen/BackEnds.md
+++ b/llvm/docs/TableGen/BackEnds.md
@@ -1,10 +1,6 @@
-=================
-TableGen BackEnds
-=================
+# TableGen BackEnds
 
-
-Introduction
-============
+## Introduction
 
 TableGen backends are at the core of TableGen's functionality. The source
 files provide the classes and records that are parsed and end up as a
@@ -26,18 +22,18 @@ warnings, tips) and attributes, so more on the textual end of the scale.
 MLIR uses TableGen to define operations, operation dialects, and operation
 traits.
 
-See the :doc:`TableGen Programmer's Reference <./ProgRef>` for an in-depth
-description of TableGen, and the :doc:`TableGen Backend Developer's Guide
+See the {doc}`TableGen Programmer's Reference <./ProgRef>` for an in-depth
+description of TableGen, and the {doc}`TableGen Backend Developer's Guide
 <./BackGuide>` for a guide to writing a new backend.
 
-LLVM BackEnds
-=============
+## LLVM BackEnds
 
-.. warning::
-   This portion is incomplete. Each section below needs three subsections:
-   description of its purpose with a list of users, output generated from
-   generic input, and finally why it needed a new backend (in case there's
-   something similar).
+:::{warning}
+This portion is incomplete. Each section below needs three subsections:
+description of its purpose with a list of users, output generated from
+generic input, and finally why it needed a new backend (in case there's
+something similar).
+:::
 
 Overall, each backend will take the same TableGen file type and transform into
 similar output for different targets/uses. There is an implicit contract between
@@ -48,10 +44,10 @@ sections. Based on whether the file is included by a header or a source file,
 or even in which context of each file the include is being used, you have
 to define a macro just before including it, to get the right output:
 
-.. code-block:: c++
-
-  #define GET_REGINFO_TARGET_DESC
-  #include "ARMGenRegisterInfo.inc"
+```c++
+#define GET_REGINFO_TARGET_DESC
+#include "ARMGenRegisterInfo.inc"
+```
 
 And just part of the generated file would be included. This is useful if
 you need the same information in multiple formats (instantiation, initialization,
@@ -61,48 +57,45 @@ to re-compile the TableGen file multiple times.
 Sometimes, multiple macros might be defined before the same include file to
 output multiple blocks:
 
-.. code-block:: c++
-
-  #define GET_REGISTER_MATCHER
-  #define GET_SUBTARGET_FEATURE_NAME
-  #define GET_MATCHER_IMPLEMENTATION
-  #include "ARMGenAsmMatcher.inc"
+```c++
+#define GET_REGISTER_MATCHER
+#define GET_SUBTARGET_FEATURE_NAME
+#define GET_MATCHER_IMPLEMENTATION
+#include "ARMGenAsmMatcher.inc"
+```
 
 The macros will be undef'd automatically as they're used, in the include file.
 
-On all LLVM back-ends, the ``llvm-tblgen`` binary will be executed on the root
-TableGen file ``<Target>.td``, which should include all others. This guarantees
+On all LLVM back-ends, the `llvm-tblgen` binary will be executed on the root
+TableGen file `<Target>.td`, which should include all others. This guarantees
 that all information needed is accessible, and that no duplication is needed
 in the TableGen files.
 
-CodeEmitter
------------
+### CodeEmitter
 
-**Purpose**: ``CodeEmitterGen`` uses the descriptions of instructions and their fields to
-construct an automated code emitter: a function that, given a ``MachineInstr``,
+**Purpose**: `CodeEmitterGen` uses the descriptions of instructions and their fields to
+construct an automated code emitter: a function that, given a `MachineInstr`,
 returns the (currently, 32-bit unsigned) value of the instruction.
 
 **Output**: C++ code, implementing the target's CodeEmitter
-class by overriding the virtual functions as ``<Target>CodeEmitter::function()``.
+class by overriding the virtual functions as `<Target>CodeEmitter::function()`.
 
-**Usage**: Used to include directly at the end of ``<Target>MCCodeEmitter.cpp``.
+**Usage**: Used to include directly at the end of `<Target>MCCodeEmitter.cpp`.
 
-RegisterInfo
-------------
+### RegisterInfo
 
 **Purpose**: This tablegen backend is responsible for emitting a description of a target
-register file for a code generator.  It uses instances of the Register,
+register file for a code generator. It uses instances of the Register,
 RegisterAliases, and RegisterClass classes to gather this information.
 
 **Output**: C++ code with enums and structures representing the register mappings,
 properties, masks, etc.
 
-**Usage**: Both on ``<Target>BaseRegisterInfo`` and ``<Target>MCTargetDesc`` (headers
+**Usage**: Both on `<Target>BaseRegisterInfo` and `<Target>MCTargetDesc` (headers
 and source files) with macros defining in which they are for declaration vs.
 initialization issues.
 
-InstrInfo
----------
+### InstrInfo
 
 **Purpose**: This tablegen backend is responsible for emitting a description of the target
 instruction set for the code generator. (what are the differences from CodeEmitter?)
@@ -110,78 +103,71 @@ instruction set for the code generator. (what are the differences from CodeEmitt
 **Output**: C++ code with enums and structures representing the instruction mappings,
 properties, masks, etc.
 
-**Usage**: Both on ``<Target>BaseInstrInfo`` and ``<Target>MCTargetDesc`` (headers
+**Usage**: Both on `<Target>BaseInstrInfo` and `<Target>MCTargetDesc` (headers
 and source files) with macros defining in which they are for declaration vs.
 initialization issues.
 
-AsmWriter
----------
+### AsmWriter
 
 **Purpose**: Emits an assembly printer for the current target.
 
-**Output**: Implementation of ``<Target>InstPrinter::printInstruction()``, among
+**Output**: Implementation of `<Target>InstPrinter::printInstruction()`, among
 other things.
 
-**Usage**: Included directly into ``InstPrinter/<Target>InstPrinter.cpp``.
+**Usage**: Included directly into `InstPrinter/<Target>InstPrinter.cpp`.
 
-AsmMatcher
-----------
+### AsmMatcher
 
 **Purpose**: Emits a target specifier matcher for
-converting parsed assembly operands in the ``MCInst`` structures. It also
+converting parsed assembly operands in the `MCInst` structures. It also
 emits a matcher for custom operand parsing. Extensive documentation is
-written on the ``AsmMatcherEmitter.cpp`` file.
+written on the `AsmMatcherEmitter.cpp` file.
 
 **Output**: Assembler parsers' matcher functions, declarations, etc.
 
-**Usage**: Used in back-ends' ``AsmParser/<Target>AsmParser.cpp`` for
+**Usage**: Used in back-ends' `AsmParser/<Target>AsmParser.cpp` for
 building the AsmParser class.
 
-Disassembler
-------------
+### Disassembler
 
 **Purpose**: Contains disassembler table emitters for various
 architectures. Extensive documentation is written on the
-``DisassemblerEmitter.cpp`` file.
+`DisassemblerEmitter.cpp` file.
 
 **Output**: Decoding tables, static decoding functions, etc.
 
-**Usage**: Directly included in ``Disassembler/<Target>Disassembler.cpp``
+**Usage**: Directly included in `Disassembler/<Target>Disassembler.cpp`
 to cater for all default decodings, after all hand-made ones.
 
-PseudoLowering
---------------
+### PseudoLowering
 
 **Purpose**: Generate pseudo instruction lowering.
 
-**Output**: Implements ``<Target>AsmPrinter::emitPseudoExpansionLowering()``.
+**Output**: Implements `<Target>AsmPrinter::emitPseudoExpansionLowering()`.
 
-**Usage**: Included directly into ``<Target>AsmPrinter.cpp``.
+**Usage**: Included directly into `<Target>AsmPrinter.cpp`.
 
-CallingConv
------------
+### CallingConv
 
 **Purpose**: Responsible for emitting descriptions of the calling
 conventions supported by this target.
 
 **Output**: Implement static functions to deal with calling conventions
-chained by matching styles, returning ``false`` on no match.
+chained by matching styles, returning `false` on no match.
 
 **Usage**: Used in ISelLowering and FastIsel as function pointers to
 implementation returned by a CC selection function.
 
-DAGISel
--------
+### DAGISel
 
 **Purpose**: Generate a DAG instruction selector.
 
 **Output**: Creates huge functions for automating DAG selection.
 
-**Usage**: Included in ``<Target>ISelDAGToDAG.cpp`` inside the target's
-implementation of ``SelectionDAGISel``.
+**Usage**: Included in `<Target>ISelDAGToDAG.cpp` inside the target's
+implementation of `SelectionDAGISel`.
 
-DFAPacketizer
--------------
+### DFAPacketizer
 
 **Purpose**: This class parses the Schedule.td file and produces an API that
 can be used to reason about whether an instruction can be added to a packet
@@ -191,45 +177,40 @@ to functional units as instructions are added to a packet.
 
 **Output**: Scheduling tables for GPU back-ends (Hexagon, AMD).
 
-**Usage**: Included directly on ``<Target>InstrInfo.cpp``.
+**Usage**: Included directly on `<Target>InstrInfo.cpp`.
 
-FastISel
---------
+### FastISel
 
 **Purpose**: This tablegen backend emits code for use by the "fast"
 instruction selection algorithm. See the comments at the top of
-``lib/CodeGen/SelectionDAG/FastISel.cpp`` for background. This file
+`lib/CodeGen/SelectionDAG/FastISel.cpp` for background. This file
 scans through the target's tablegen instruction-info files
 and extracts instructions with obvious-looking patterns, and it emits
 code to look up these instructions by type and operator.
 
-**Output**: Generates ``Predicate`` and ``FastEmit`` methods.
+**Output**: Generates `Predicate` and `FastEmit` methods.
 
 **Usage**: Implements private methods of the targets' implementation
-of ``FastISel`` class.
+of `FastISel` class.
 
-Subtarget
----------
+### Subtarget
 
 **Purpose**: Generate subtarget enumerations.
 
 **Output**: Enums, globals, local tables for sub-target information.
 
-**Usage**: Populates ``<Target>Subtarget`` and
-``MCTargetDesc/<Target>MCTargetDesc`` files (both headers and source).
+**Usage**: Populates `<Target>Subtarget` and
+`MCTargetDesc/<Target>MCTargetDesc` files (both headers and source).
 
-Intrinsic
----------
+### Intrinsic
 
 **Purpose**: Generate (target) intrinsic information.
 
-OptParserDefs
--------------
+### OptParserDefs
 
 **Purpose**: Print enum values for a class.
 
-SearchableTables
-----------------
+### SearchableTables
 
 **Purpose**: Generate custom searchable tables.
 
@@ -240,237 +221,199 @@ from TableGen records. The ARM and AArch64 targets use this backend to generate
 tables of system registers; the AMDGPU target uses it to generate meta-data
 about complex image and memory buffer instructions.
 
-See `SearchableTables Reference`_ for a detailed description.
+See [SearchableTables Reference] for a detailed description.
 
-CTags
------
+### CTags
 
 **Purpose**: This tablegen backend emits an index of definitions in ctags(1)
 format. A helper script, utils/TableGen/tdtags, provides an easier-to-use
 interface; run 'tdtags -H' for documentation.
 
-X86EVEX2VEX
------------
+### X86EVEX2VEX
 
 **Purpose**: This X86 specific tablegen backend emits tables that map EVEX
 encoded instructions to their VEX encoded identical instruction.
 
-Clang BackEnds
-==============
+## Clang BackEnds
 
-ClangAttrClasses
-----------------
+### ClangAttrClasses
 
 **Purpose**: Creates Attrs.inc, which contains semantic attribute class
-declarations for any attribute in ``Attr.td`` that has not set ``ASTNode = 0``.
-This file is included as part of ``Attr.h``.
+declarations for any attribute in `Attr.td` that has not set `ASTNode = 0`.
+This file is included as part of `Attr.h`.
 
-ClangAttrParserStringSwitches
------------------------------
+### ClangAttrParserStringSwitches
 
-**Purpose**: Creates ``AttrParserStringSwitches.inc``, which contains
-``StringSwitch::Case`` statements for parser-related string switches. Each switch
-is given its own macro (such as ``CLANG_ATTR_ARG_CONTEXT_LIST``, or
-``CLANG_ATTR_IDENTIFIER_ARG_LIST``), which is expected to be defined before
-including ``AttrParserStringSwitches.inc``, and undefined after.
+**Purpose**: Creates `AttrParserStringSwitches.inc`, which contains
+`StringSwitch::Case` statements for parser-related string switches. Each switch
+is given its own macro (such as `CLANG_ATTR_ARG_CONTEXT_LIST`, or
+`CLANG_ATTR_IDENTIFIER_ARG_LIST`), which is expected to be defined before
+including `AttrParserStringSwitches.inc`, and undefined after.
 
-ClangAttrImpl
--------------
+### ClangAttrImpl
 
-**Purpose**: Creates ``AttrImpl.inc``, which contains semantic attribute class
-definitions for any attribute in ``Attr.td`` that has not set ``ASTNode = 0``.
-This file is included as part of ``AttrImpl.cpp``.
+**Purpose**: Creates `AttrImpl.inc`, which contains semantic attribute class
+definitions for any attribute in `Attr.td` that has not set `ASTNode = 0`.
+This file is included as part of `AttrImpl.cpp`.
 
-ClangAttrList
--------------
+### ClangAttrList
 
-**Purpose**: Creates ``AttrList.inc``, which is used when a list of semantic
-attribute identifiers is required. For instance, ``AttrKinds.h`` includes this
-file to generate the list of ``attr::Kind`` enumeration values. This list is
+**Purpose**: Creates `AttrList.inc`, which is used when a list of semantic
+attribute identifiers is required. For instance, `AttrKinds.h` includes this
+file to generate the list of `attr::Kind` enumeration values. This list is
 separated out into multiple categories: attributes, inheritable attributes, and
 inheritable parameter attributes. This categorization happens automatically
-based on information in ``Attr.td`` and is used to implement the ``classof``
-functionality required for ``dyn_cast`` and similar APIs.
+based on information in `Attr.td` and is used to implement the `classof`
+functionality required for `dyn_cast` and similar APIs.
 
-ClangAttrPCHRead
-----------------
+### ClangAttrPCHRead
 
-**Purpose**: Creates ``AttrPCHRead.inc``, which is used to deserialize attributes
-in the ``ASTReader::ReadAttributes`` function.
+**Purpose**: Creates `AttrPCHRead.inc`, which is used to deserialize attributes
+in the `ASTReader::ReadAttributes` function.
 
-ClangAttrPCHWrite
------------------
+### ClangAttrPCHWrite
 
-**Purpose**: Creates ``AttrPCHWrite.inc``, which is used to serialize attributes in
-the ``ASTWriter::WriteAttributes`` function.
+**Purpose**: Creates `AttrPCHWrite.inc`, which is used to serialize attributes in
+the `ASTWriter::WriteAttributes` function.
 
-ClangAttrSpellings
----------------------
+### ClangAttrSpellings
 
-**Purpose**: Creates ``AttrSpellings.inc``, which is used to implement the
-``__has_attribute`` feature test macro.
+**Purpose**: Creates `AttrSpellings.inc`, which is used to implement the
+`__has_attribute` feature test macro.
 
-ClangAttrSpellingListIndex
---------------------------
+### ClangAttrSpellingListIndex
 
-**Purpose**: Creates ``AttrSpellingListIndex.inc``, which is used to map parsed
+**Purpose**: Creates `AttrSpellingListIndex.inc`, which is used to map parsed
 attribute spellings (including which syntax or scope was used) to an attribute
 spelling list index. These spelling list index values are internal
 implementation details exposed via
-``AttributeList::getAttributeSpellingListIndex``.
+`AttributeList::getAttributeSpellingListIndex`.
 
-ClangAttrVisitor
--------------------
+### ClangAttrVisitor
 
-**Purpose**: Creates ``AttrVisitor.inc``, which is used when implementing
+**Purpose**: Creates `AttrVisitor.inc`, which is used when implementing
 recursive AST visitors.
 
-ClangAttrTemplateInstantiate
-----------------------------
+### ClangAttrTemplateInstantiate
 
-**Purpose**: Creates ``AttrTemplateInstantiate.inc``, which implements the
-``instantiateTemplateAttribute`` function, used when instantiating a template
+**Purpose**: Creates `AttrTemplateInstantiate.inc`, which implements the
+`instantiateTemplateAttribute` function, used when instantiating a template
 that requires an attribute to be cloned.
 
-ClangAttrParsedAttrList
------------------------
+### ClangAttrParsedAttrList
 
-**Purpose**: Creates ``AttrParsedAttrList.inc``, which is used to generate the
-``AttributeList::Kind`` parsed attribute enumeration.
+**Purpose**: Creates `AttrParsedAttrList.inc`, which is used to generate the
+`AttributeList::Kind` parsed attribute enumeration.
 
-ClangAttrParsedAttrImpl
------------------------
+### ClangAttrParsedAttrImpl
 
-**Purpose**: Creates ``AttrParsedAttrImpl.inc``, which is used by
-``AttributeList.cpp`` to implement several functions on the ``AttributeList``
-class. This functionality is implemented via the ``AttrInfoMap ParsedAttrInfo``
+**Purpose**: Creates `AttrParsedAttrImpl.inc`, which is used by
+`AttributeList.cpp` to implement several functions on the `AttributeList`
+class. This functionality is implemented via the `AttrInfoMap ParsedAttrInfo`
 array, which contains one element per parsed attribute object.
 
-ClangAttrParsedAttrKinds
-------------------------
+### ClangAttrParsedAttrKinds
 
-**Purpose**: Creates ``AttrParsedAttrKinds.inc``, which is used to implement the
-``AttributeList::getKind`` function, mapping a string (and syntax) to a parsed
-attribute ``AttributeList::Kind`` enumeration.
+**Purpose**: Creates `AttrParsedAttrKinds.inc`, which is used to implement the
+`AttributeList::getKind` function, mapping a string (and syntax) to a parsed
+attribute `AttributeList::Kind` enumeration.
 
-ClangAttrIsTypeDependent
-------------------------
+### ClangAttrIsTypeDependent
 
-**Purpose**: Creates ``AttrIsTypeDependent.inc``, which is used to implement the
-``Sema::CheckAttributesOnDeducedType`` function, mapping an attribute kind to a
+**Purpose**: Creates `AttrIsTypeDependent.inc`, which is used to implement the
+`Sema::CheckAttributesOnDeducedType` function, mapping an attribute kind to a
 Sema function if it exists.
 
-ClangAttrDump
--------------
+### ClangAttrDump
 
-**Purpose**: Creates ``AttrDump.inc``, which dumps information about an attribute.
-It is used to implement ``ASTDumper::dumpAttr``.
+**Purpose**: Creates `AttrDump.inc`, which dumps information about an attribute.
+It is used to implement `ASTDumper::dumpAttr`.
 
-ClangDiagsDefs
---------------
+### ClangDiagsDefs
 
 Generate Clang diagnostics definitions.
 
-ClangDiagGroups
----------------
+### ClangDiagGroups
 
 Generate Clang diagnostic groups.
 
-ClangDiagsIndexName
--------------------
+### ClangDiagsIndexName
 
 Generate Clang diagnostic name index.
 
-ClangCommentNodes
------------------
+### ClangCommentNodes
 
 Generate Clang AST comment nodes.
 
-ClangDeclNodes
---------------
+### ClangDeclNodes
 
 Generate Clang AST declaration nodes.
 
-ClangStmtNodes
---------------
+### ClangStmtNodes
 
 Generate Clang AST statement nodes.
 
-ClangSACheckers
----------------
+### ClangSACheckers
 
 Generate Clang Static Analyzer checkers.
 
-ClangCommentHTMLTags
---------------------
+### ClangCommentHTMLTags
 
 Generate efficient matchers for HTML tag names that are used in documentation comments.
 
-ClangCommentHTMLTagsProperties
-------------------------------
+### ClangCommentHTMLTagsProperties
 
 Generate efficient matchers for HTML tag properties.
 
-ClangCommentHTMLNamedCharacterReferences
-----------------------------------------
+### ClangCommentHTMLNamedCharacterReferences
 
 Generate function to translate named character references to UTF-8 sequences.
 
-ClangCommentCommandInfo
------------------------
+### ClangCommentCommandInfo
 
 Generate command properties for commands that are used in documentation comments.
 
-ClangCommentCommandList
------------------------
+### ClangCommentCommandList
 
 Generate list of commands that are used in documentation comments.
 
-ArmNeon
--------
+### ArmNeon
 
-Generate ``arm_neon.h`` for clang.
+Generate `arm_neon.h` for clang.
 
-ArmNeonSema
------------
+### ArmNeonSema
 
 Generate ARM NEON sema support for clang.
 
-ArmNeonTest
------------
+### ArmNeonTest
 
 Generate ARM NEON tests for clang.
 
-AttrDocs
---------
+### AttrDocs
 
-**Purpose**: Creates ``AttributeReference.md`` from ``AttrDocs.td``, and is
+**Purpose**: Creates `AttributeReference.md` from `AttrDocs.td`, and is
 used for documenting user-facing attributes.
 
-General BackEnds
-================
+## General BackEnds
 
-Print Records
--------------
+### Print Records
 
-The TableGen command option ``--print-records`` invokes a simple backend
+The TableGen command option `--print-records` invokes a simple backend
 that prints all the classes and records defined in the source files. This is
-the default backend option. See the :doc:`TableGen Backend Developer's Guide
+the default backend option. See the {doc}`TableGen Backend Developer's Guide
 <./BackGuide>` for more information.
 
-Print Detailed Records
-----------------------
+### Print Detailed Records
 
-The TableGen command option ``--print-detailed-records`` invokes a backend
+The TableGen command option `--print-detailed-records` invokes a backend
 that prints all the global variables, classes, and records defined in the
 source files, with more detail than the default record printer. See the
-:doc:`TableGen Backend Developer's Guide <./BackGuide>` for more
+{doc}`TableGen Backend Developer's Guide <./BackGuide>` for more
 information.
 
-JSON Reference
---------------
+### JSON Reference
 
-**Purpose**: Output all the values in every ``def``, as a JSON data
+**Purpose**: Output all the values in every `def`, as a JSON data
 structure that can be easily parsed by a variety of languages. Useful
 for writing custom backends without having to modify TableGen itself,
 or for performing auxiliary analysis on the same TableGen data passed
@@ -481,43 +424,38 @@ to a built-in backend.
 The root of the output file is a JSON object (i.e., dictionary),
 containing the following fixed keys:
 
-* ``!tablegen_json_version``: a numeric version field that will
+- `!tablegen_json_version`: a numeric version field that will
   increase if an incompatible change is ever made to the structure of
   this data. The format described here corresponds to version 1.
-
-* ``!instanceof``: a dictionary whose keys are the class names defined
+- `!instanceof`: a dictionary whose keys are the class names defined
   in the TableGen input. For each key, the corresponding value is an
-  array of strings giving the names of ``def`` records that derive
-  from that class. So ``root["!instanceof"]["Instruction"]``, for
+  array of strings giving the names of `def` records that derive
+  from that class. So `root["!instanceof"]["Instruction"]`, for
   example, would list the names of all the records deriving from the
-  class ``Instruction``.
+  class `Instruction`.
 
-For each ``def`` record, the root object also has a key for the record
+For each `def` record, the root object also has a key for the record
 name. The corresponding value is a subsidiary object containing the
 following fixed keys:
 
-* ``!superclasses``: an array of strings giving the names of all the
+- `!superclasses`: an array of strings giving the names of all the
   classes that this record derives from.
-
-* ``!fields``: an array of strings giving the names of all the variables
-  in this record that were defined with the ``field`` keyword.
-
-* ``!name``: a string giving the name of the record. This is always
+- `!fields`: an array of strings giving the names of all the variables
+  in this record that were defined with the `field` keyword.
+- `!name`: a string giving the name of the record. This is always
   identical to the key in the JSON root object corresponding to this
   record's dictionary. (If the record is anonymous, the name is
   arbitrary.)
-
-* ``!anonymous``: a boolean indicating whether the record's name was
-  specified by the TableGen input (if it is ``false``), or invented by
-  TableGen itself (if ``true``).
-
-* ``!locs``: an array of strings giving the source locations associated with
-  this record. For records instantiated from a ``multiclass``, this gives the
-  location of each ``def`` or ``defm``, starting with the inner-most
-  ``multiclass``, and ending with the top-level ``defm``. Each string contains
+- `!anonymous`: a boolean indicating whether the record's name was
+  specified by the TableGen input (if it is `false`), or invented by
+  TableGen itself (if `true`).
+- `!locs`: an array of strings giving the source locations associated with
+  this record. For records instantiated from a `multiclass`, this gives the
+  location of each `def` or `defm`, starting with the inner-most
+  `multiclass`, and ending with the top-level `defm`. Each string contains
   the file name and line number, separated by a colon.
 
-For each variable defined in a record, the ``def`` object for that
+For each variable defined in a record, the `def` object for that
 record also has a key for the variable name. The corresponding value
 is a translation into JSON of the variable's value, using the
 conventions described below.
@@ -525,479 +463,457 @@ conventions described below.
 Some TableGen data types are translated directly into the
 corresponding JSON type:
 
-* A completely undefined value (e.g., for a variable declared without
+- A completely undefined value (e.g., for a variable declared without
   initializer in some superclass of this record, and never initialized
   by the record itself or any other superclass) is emitted as the JSON
-  ``null`` value.
-
-* ``int`` and ``bit`` values are emitted as numbers. Note that
-  TableGen ``int`` values are capable of holding integers too large to
+  `null` value.
+- `int` and `bit` values are emitted as numbers. Note that
+  TableGen `int` values are capable of holding integers too large to
   be exactly representable in IEEE double precision. The integer
   literal in the JSON output will show the full exact integer value.
   So if you need to retrieve large integers with full precision, you
   should use a JSON reader capable of translating such literals back
   into 64-bit integers without losing precision, such as Python's
-  standard ``json`` module.
-
-* ``string`` and ``code`` values are emitted as JSON strings.
-
-* ``list<T>`` values, for any element type ``T``, are emitted as JSON
+  standard `json` module.
+- `string` and `code` values are emitted as JSON strings.
+- `list<T>` values, for any element type `T`, are emitted as JSON
   arrays. Each element of the array is represented in turn using these
   same conventions.
-
-* ``bits`` values are also emitted as arrays. A ``bits`` array is
+- `bits` values are also emitted as arrays. A `bits` array is
   ordered from least-significant bit to most-significant. So the
-  element with index ``i`` corresponds to the bit described as
-  ``x{i}`` in TableGen source. However, note that this means that
+  element with index `i` corresponds to the bit described as
+  `x{i}` in TableGen source. However, note that this means that
   scripting languages are likely to *display* the array in the
   opposite order from the way it appears in the TableGen source or in
-  the diagnostic ``-print-records`` output.
+  the diagnostic `-print-records` output.
 
 All other TableGen value types are emitted as a JSON object,
-containing two standard fields: ``kind`` is a discriminator describing
-which kind of value the object represents, and ``printable`` is a
+containing two standard fields: `kind` is a discriminator describing
+which kind of value the object represents, and `printable` is a
 string giving the same representation of the value that would appear
-in ``-print-records``.
+in `-print-records`.
 
-* A reference to a ``def`` object has ``kind=="def"``, and has an
-  extra field ``def`` giving the name of the object referred to.
+- A reference to a `def` object has `kind=="def"`, and has an
+  extra field `def` giving the name of the object referred to.
 
-* A reference to another variable in the same record has
-  ``kind=="var"``, and has an extra field ``var`` giving the name of
+- A reference to another variable in the same record has
+  `kind=="var"`, and has an extra field `var` giving the name of
   the variable referred to.
 
-* A reference to a specific bit of a ``bits``-typed variable in the
-  same record has ``kind=="varbit"``, and has two extra fields:
-  ``var`` gives the name of the variable referred to, and ``index``
+- A reference to a specific bit of a `bits`-typed variable in the
+  same record has `kind=="varbit"`, and has two extra fields:
+  `var` gives the name of the variable referred to, and `index`
   gives the index of the bit.
 
-* A value of type ``dag`` has ``kind=="dag"``, and has two extra
-  fields. ``operator`` gives the initial value after the opening
-  parenthesis of the dag initializer; ``args`` is an array giving the
-  following arguments. The elements of ``args`` are arrays of length
+- A value of type `dag` has `kind=="dag"`, and has two extra
+  fields. `operator` gives the initial value after the opening
+  parenthesis of the dag initializer; `args` is an array giving the
+  following arguments. The elements of `args` are arrays of length
   2, giving the value of each argument followed by its colon-suffixed
   name (if any). For example, in the JSON representation of the dag
-  value ``(Op 22, "hello":$foo)`` (assuming that ``Op`` is the name of
-  a record defined elsewhere with a ``def`` statement):
-
-  * ``operator`` will be an object in which ``kind=="def"`` and
-    ``def=="Op"``
+  value `(Op 22, "hello":$foo)` (assuming that `Op` is the name of
+  a record defined elsewhere with a `def` statement):
 
-  * ``args`` will be the array ``[[22, null], ["hello", "foo"]]``.
+  - `operator` will be an object in which `kind=="def"` and
+    `def=="Op"`
+  - `args` will be the array `[[22, null], ["hello", "foo"]]`.
 
-* If any other kind of value or complicated expression appears in the
-  output, it will have ``kind=="complex"``, and no additional fields.
+- If any other kind of value or complicated expression appears in the
+  output, it will have `kind=="complex"`, and no additional fields.
   These values are not expected to be needed by backends. The standard
-  ``printable`` field can be used to extract a representation of them
+  `printable` field can be used to extract a representation of them
   in TableGen source syntax if necessary.
 
-SearchableTables Reference
---------------------------
+### SearchableTables Reference
 
-A TableGen include file, ``SearchableTable.td``, provides classes for
+A TableGen include file, `SearchableTable.td`, provides classes for
 generating C++ searchable tables. These tables are described in the
-following sections. To generate the C++ code, run ``llvm-tblgen`` with the
-``--gen-searchable-tables`` option, which invokes the backend that generates
+following sections. To generate the C++ code, run `llvm-tblgen` with the
+`--gen-searchable-tables` option, which invokes the backend that generates
 the tables from the records you provide.
 
 Each of the data structures generated for searchable tables is guarded by an
-``#ifdef``. This allows you to include the generated ``.inc`` file and select only
+`#ifdef`. This allows you to include the generated `.inc` file and select only
 certain data structures for inclusion. The examples below show the macro
 names used in these guards.
 
-Generic Enumerated Types
-~~~~~~~~~~~~~~~~~~~~~~~~
+#### Generic Enumerated Types
 
-The ``GenericEnum`` class makes it easy to define a C++ enumerated type and
+The `GenericEnum` class makes it easy to define a C++ enumerated type and
 the enumerated *elements* of that type. To define the type, define a record
-whose parent class is ``GenericEnum`` and whose name is the desired enum
+whose parent class is `GenericEnum` and whose name is the desired enum
 type. This class provides three fields, which you can set in the record
-using the ``let`` statement.
+using the `let` statement.
 
-* ``string FilterClass``. The enum type will have one element for each record
+- `string FilterClass`. The enum type will have one element for each record
   that derives from this class. These records are collected to assemble the
   complete set of elements.
-
-* ``string NameField``. The name of a field *in the collected records* that specifies
+- `string NameField`. The name of a field *in the collected records* that specifies
   the name of the element. If a record has no such field, the record's
   name will be used.
-
-* ``string ValueField``. The name of a field *in the collected records* that
+- `string ValueField`. The name of a field *in the collected records* that
   specifies the numerical value of the element. If a record has no such
   field, it will be assigned an integer value. Values are assigned in
   alphabetical order starting with 0.
-
-* ``string UnderlyingType``. The name of the underlying C++ data type
+- `string UnderlyingType`. The name of the underlying C++ data type
   of the enum. If a record has no such field, there will be no specification
   in the generated enum.
 
 Here is an example where the values of the elements are specified
-explicitly, as a template argument to the ``BEntry`` class. The resulting
+explicitly, as a template argument to the `BEntry` class. The resulting
 C++ code is shown.
 
-.. code-block:: text
-
-  def BValues : GenericEnum {
-    let FilterClass = "BEntry";
-    let NameField = "Name";
-    let ValueField = "Encoding";
-  }
-
-  class BEntry<bits<16> enc> {
-    string Name = NAME;
-    bits<16> Encoding = enc;
-  }
-
-  def BFoo   : BEntry<0xac>;
-  def BBar   : BEntry<0x14>;
-  def BZoo   : BEntry<0x80>;
-  def BSnork : BEntry<0x4c>;
-
-.. code-block:: text
-
-  #ifdef GET_BValues_DECL
-  enum BValues {
-    BBar = 20,
-    BFoo = 172,
-    BSnork = 76,
-    BZoo = 128,
-  };
-  #endif
+```text
+def BValues : GenericEnum {
+  let FilterClass = "BEntry";
+  let NameField = "Name";
+  let ValueField = "Encoding";
+}
+
+class BEntry<bits<16> enc> {
+  string Name = NAME;
+  bits<16> Encoding = enc;
+}
+
+def BFoo   : BEntry<0xac>;
+def BBar   : BEntry<0x14>;
+def BZoo   : BEntry<0x80>;
+def BSnork : BEntry<0x4c>;
+```
+
+```text
+#ifdef GET_BValues_DECL
+enum BValues {
+  BBar = 20,
+  BFoo = 172,
+  BSnork = 76,
+  BZoo = 128,
+};
+#endif
+```
 
 In the following example, the values of the elements are assigned
 automatically. Note that values are assigned from 0, in alphabetical order
 by element name.
 
-.. code-block:: text
-
-  def CEnum : GenericEnum {
-    let FilterClass = "CEnum";
-    let UnderlyingType = "uint32_t";
-  }
-
-  class CEnum;
+```text
+def CEnum : GenericEnum {
+  let FilterClass = "CEnum";
+  let UnderlyingType = "uint32_t";
+}
 
-  def CFoo : CEnum;
-  def CBar : CEnum;
-  def CBaz : CEnum;
+class CEnum;
 
-.. code-block:: text
-
-  #ifdef GET_CEnum_DECL
-  enum CEnum : uint32_t {
-    CBar = 0,
-    CBaz = 1,
-    CFoo = 2,
-  };
-  #endif
+def CFoo : CEnum;
+def CBar : CEnum;
+def CBaz : CEnum;
+```
 
+```text
+#ifdef GET_CEnum_DECL
+enum CEnum : uint32_t {
+  CBar = 0,
+  CBaz = 1,
+  CFoo = 2,
+};
+#endif
+```
 
-Generic Tables
-~~~~~~~~~~~~~~
+#### Generic Tables
 
-The ``GenericTable`` class is used to define a searchable generic table.
+The `GenericTable` class is used to define a searchable generic table.
 TableGen produces C++ code to define the table entries and also produces
 the declaration and definition of a function to search the table based on a
 primary key. To define the table, define a record whose parent class is
-``GenericTable`` and whose name is the name of the global table of entries.
+`GenericTable` and whose name is the name of the global table of entries.
 This class provides the following fields.
 
-* ``string FilterClass``. The table will have one entry for each record
+- `string FilterClass`. The table will have one entry for each record
   that derives from this class.
-
-* ``string FilterClassField``. This is an optional field of ``FilterClass``
+- `string FilterClassField`. This is an optional field of `FilterClass`
   which should be `bit` type. If specified, only those records with this field
   being true will have corresponding entries in the table. This field won't be
-  included in generated C++ fields if it isn't included in ``Fields`` list.
-
-* ``string CppTypeName``. The name of the C++ struct/class type of the
-  table that holds the entries. If unspecified, the ``FilterClass`` name is
+  included in generated C++ fields if it isn't included in `Fields` list.
+- `string CppTypeName`. The name of the C++ struct/class type of the
+  table that holds the entries. If unspecified, the `FilterClass` name is
   used.
-
-* ``list<string> Fields``. A list of the names of the fields *in the
+- `list<string> Fields`. A list of the names of the fields *in the
   collected records* that contain the data for the table entries. The order of
   this list determines the order of the values in the C++ initializers. See
   below for information about the types of these fields.
-
-* ``list<string> PrimaryKey``. The list of fields that make up the
+- `list<string> PrimaryKey`. The list of fields that make up the
   primary key.
-
-* ``string PrimaryKeyName``. The name of the generated C++ function
+- `string PrimaryKeyName`. The name of the generated C++ function
   that performs a lookup on the primary key.
-
-* ``bit PrimaryKeyEarlyOut``. See the third example below.
-
-* ``bit PrimaryKeyReturnRange``. when set to 1, modifies the lookup function’s
+- `bit PrimaryKeyEarlyOut`. See the third example below.
+- `bit PrimaryKeyReturnRange`. when set to 1, modifies the lookup function’s
   definition to return a range of results rather than a single pointer to the
   object. This feature proves useful when multiple objects meet the criteria
   specified by the lookup function. Currently, it is supported only for primary
   lookup functions. Refer to the second example below for further details.
-
-* ``bit DisallowSparseTable``. When set to 1 (the default), prevents the
+- `bit DisallowSparseTable`. When set to 1 (the default), prevents the
   emitter from generating a sparse direct-lookup array for this table. Set to
   0 to allow the emitter to emit a sparse directly-indexed array when the
   primary key qualifies (see below).
 
 TableGen attempts to deduce the type of each of the table fields so that it
-can format the C++ initializers in the emitted table. It can deduce ``bit``,
-``bits<n>``, ``string``, ``Intrinsic``, and ``Instruction``.  These can be
+can format the C++ initializers in the emitted table. It can deduce `bit`,
+`bits<n>`, `string`, `Intrinsic`, and `Instruction`. These can be
 used in the primary key. Any other field types must be specified
 explicitly; this is done as shown in the second example below. Such fields
 cannot be used in the primary key.
 
 One special case of the field type has to do with code. Arbitrary code is
 represented by a string, but has to be emitted as a C++ initializer without
-quotes. If the code field was defined using a code literal (``[{...}]``),
+quotes. If the code field was defined using a code literal (`[{...}]`),
 then TableGen will know to emit it without quotes. However, if it was
 defined using a string literal or complex string expression, then TableGen
 will not know. In this case, you can force TableGen to treat the field as
-code by including the following line in the ``GenericTable`` record, where
+code by including the following line in the `GenericTable` record, where
 *xxx* is the code field name.
 
-.. code-block:: text
-
-  string TypeOf_xxx = "code";
+```text
+string TypeOf_xxx = "code";
+```
 
 Here is an example where TableGen can deduce the field types. Note that the
 table entry records are anonymous; the names of entry records are
 irrelevant.
 
-.. code-block:: text
-
-  def ATable : GenericTable {
-    let FilterClass = "AEntry";
-    let FilterClassField = "IsNeeded";
-    let Fields = ["Str", "Val1", "Val2"];
-    let PrimaryKey = ["Val1", "Val2"];
-    let PrimaryKeyName = "lookupATableByValues";
-  }
-
-  class AEntry<string str, int val1, int val2, bit isNeeded> {
-    string Str = str;
-    bits<8> Val1 = val1;
-    bits<10> Val2 = val2;
-    bit IsNeeded = isNeeded;
-  }
-
-  def : AEntry<"Bob",   5, 3, 1>;
-  def : AEntry<"Carol", 2, 6, 1>;
-  def : AEntry<"Ted",   4, 4, 1>;
-  def : AEntry<"Alice", 4, 5, 1>;
-  def : AEntry<"Costa", 2, 1, 1>;
-  def : AEntry<"Dale",  2, 1, 0>;
-
-Here is the generated C++ code. The declaration of ``lookupATableByValues``
-is guarded by ``GET_ATable_DECL``, while the definitions are guarded by
-``GET_ATable_IMPL``.
-
-.. code-block:: text
-
-  #ifdef GET_ATable_DECL
-  const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2);
-  #endif
-
-  #ifdef GET_ATable_IMPL
-  constexpr AEntry ATable[] = {
-    { "Costa", 0x2, 0x1 }, // 0
-    { "Carol", 0x2, 0x6 }, // 1
-    { "Ted", 0x4, 0x4 }, // 2
-    { "Alice", 0x4, 0x5 }, // 3
-    { "Bob", 0x5, 0x3 }, // 4
-    /* { "Dale", 0x2, 0x1 }, // 5 */ // We don't generate this line as `IsNeeded` is 0.
+```text
+def ATable : GenericTable {
+  let FilterClass = "AEntry";
+  let FilterClassField = "IsNeeded";
+  let Fields = ["Str", "Val1", "Val2"];
+  let PrimaryKey = ["Val1", "Val2"];
+  let PrimaryKeyName = "lookupATableByValues";
+}
+
+class AEntry<string str, int val1, int val2, bit isNeeded> {
+  string Str = str;
+  bits<8> Val1 = val1;
+  bits<10> Val2 = val2;
+  bit IsNeeded = isNeeded;
+}
+
+def : AEntry<"Bob",   5, 3, 1>;
+def : AEntry<"Carol", 2, 6, 1>;
+def : AEntry<"Ted",   4, 4, 1>;
+def : AEntry<"Alice", 4, 5, 1>;
+def : AEntry<"Costa", 2, 1, 1>;
+def : AEntry<"Dale",  2, 1, 0>;
+```
+
+Here is the generated C++ code. The declaration of `lookupATableByValues`
+is guarded by `GET_ATable_DECL`, while the definitions are guarded by
+`GET_ATable_IMPL`.
+
+```text
+#ifdef GET_ATable_DECL
+const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2);
+#endif
+
+#ifdef GET_ATable_IMPL
+constexpr AEntry ATable[] = {
+  { "Costa", 0x2, 0x1 }, // 0
+  { "Carol", 0x2, 0x6 }, // 1
+  { "Ted", 0x4, 0x4 }, // 2
+  { "Alice", 0x4, 0x5 }, // 3
+  { "Bob", 0x5, 0x3 }, // 4
+  /* { "Dale", 0x2, 0x1 }, // 5 */ // We don't generate this line as `IsNeeded` is 0.
+};
+
+const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {
+  struct KeyType {
+    uint8_t Val1;
+    uint16_t Val2;
   };
-
-  const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {
-    struct KeyType {
-      uint8_t Val1;
-      uint16_t Val2;
-    };
-    KeyType Key = { Val1, Val2 };
-    auto Table = ArrayRef(ATable);
-    auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
-      [](const AEntry &LHS, const KeyType &RHS) {
-        if (LHS.Val1 < RHS.Val1)
-          return true;
-        if (LHS.Val1 > RHS.Val1)
-          return false;
-        if (LHS.Val2 < RHS.Val2)
-          return true;
-        if (LHS.Val2 > RHS.Val2)
-          return false;
+  KeyType Key = { Val1, Val2 };
+  auto Table = ArrayRef(ATable);
+  auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
+    [](const AEntry &LHS, const KeyType &RHS) {
+      if (LHS.Val1 < RHS.Val1)
+        return true;
+      if (LHS.Val1 > RHS.Val1)
         return false;
-      });
-
-    if (Idx == Table.end() ||
-        Key.Val1 != Idx->Val1 ||
-        Key.Val2 != Idx->Val2)
-      return nullptr;
-    return &*Idx;
-  }
-  #endif
-
-The table entries in ``ATable`` are sorted in order by ``Val1``, and within
-each of those values, by ``Val2``. This allows a binary search of the table,
-which is performed in the lookup function by ``std::lower_bound``. The
+      if (LHS.Val2 < RHS.Val2)
+        return true;
+      if (LHS.Val2 > RHS.Val2)
+        return false;
+      return false;
+    });
+
+  if (Idx == Table.end() ||
+      Key.Val1 != Idx->Val1 ||
+      Key.Val2 != Idx->Val2)
+    return nullptr;
+  return &*Idx;
+}
+#endif
+```
+
+The table entries in `ATable` are sorted in order by `Val1`, and within
+each of those values, by `Val2`. This allows a binary search of the table,
+which is performed in the lookup function by `std::lower_bound`. The
 lookup function returns a reference to the found table entry, or the null
 pointer if no entry is found.
 
 The emitter selects the lookup strategy automatically based on the primary key:
 
-* **Dense direct lookup**: used when the primary key is a single integral field
+- **Dense direct lookup**: used when the primary key is a single integral field
   whose values form a contiguous range. A compact array is emitted and the
   lookup function indexes into it directly.
-
-* **Sparse direct lookup**: used when ``DisallowSparseTable = 0``, the primary
-  key is a single ``bits<N>`` field with N ≤ 12, ``PrimaryKeyReturnRange`` is
+- **Sparse direct lookup**: used when `DisallowSparseTable = 0`, the primary
+  key is a single `bits<N>` field with N ≤ 12, `PrimaryKeyReturnRange` is
   false, and the table has no secondary search indexes. The emitter allocates a
-  directly-indexed array of ``2^N`` entries. Empty slots are filled with a
+  directly-indexed array of `2^N` entries. Empty slots are filled with a
   sentinel value in the key field such that the in-place key comparison in the
-  lookup function returns ``nullptr`` for them. This trades memory for
+  lookup function returns `nullptr` for them. This trades memory for
   O(1) lookup.
+- **Binary search**: the default for all other cases. Entries are sorted by the
+  primary key and `std::lower_bound` is used in the lookup function.
 
-* **Binary search**: the default for all other cases. Entries are sorted by the
-  primary key and ``std::lower_bound`` is used in the lookup function.
-
-This example includes a field whose type TableGen cannot deduce. The ``Kind``
-field uses the enumerated type ``CEnum`` defined above. To inform TableGen
-of the type, the record derived from ``GenericTable`` must include a string field
-named ``TypeOf_``\ *field*, where *field* is the name of the field whose type
+This example includes a field whose type TableGen cannot deduce. The `Kind`
+field uses the enumerated type `CEnum` defined above. To inform TableGen
+of the type, the record derived from `GenericTable` must include a string field
+named `TypeOf_`*field*, where *field* is the name of the field whose type
 is required.
 
-.. code-block:: text
-
-  def CTable : GenericTable {
-    let FilterClass = "CEntry";
-    let Fields = ["Name", "Kind", "Encoding"];
-    string TypeOf_Kind = "CEnum";
-    let PrimaryKey = ["Encoding"];
-    let PrimaryKeyName = "lookupCEntryByEncoding";
-  }
-
-  class CEntry<string name, CEnum kind, int enc> {
-    string Name = name;
-    CEnum Kind = kind;
-    bits<16> Encoding = enc;
-  }
-
-  def : CEntry<"Apple", CFoo, 10>;
-  def : CEntry<"Pear",  CBaz, 15>;
-  def : CEntry<"Apple", CBar, 13>;
+```text
+def CTable : GenericTable {
+  let FilterClass = "CEntry";
+  let Fields = ["Name", "Kind", "Encoding"];
+  string TypeOf_Kind = "CEnum";
+  let PrimaryKey = ["Encoding"];
+  let PrimaryKeyName = "lookupCEntryByEncoding";
+}
+
+class CEntry<string name, CEnum kind, int enc> {
+  string Name = name;
+  CEnum Kind = kind;
+  bits<16> Encoding = enc;
+}
+
+def : CEntry<"Apple", CFoo, 10>;
+def : CEntry<"Pear",  CBaz, 15>;
+def : CEntry<"Apple", CBar, 13>;
+```
 
 Here is the generated C++ code.
 
-.. code-block:: text
-
-  #ifdef GET_CTable_DECL
-  const CEntry *lookupCEntryByEncoding(uint16_t Encoding);
-  #endif
-
-  #ifdef GET_CTable_IMPL
-  constexpr CEntry CTable[] = {
-    { "Apple", CFoo, 0xA }, // 0
-    { "Apple", CBar, 0xD }, // 1
-    { "Pear", CBaz, 0xF }, // 2
+```text
+#ifdef GET_CTable_DECL
+const CEntry *lookupCEntryByEncoding(uint16_t Encoding);
+#endif
+
+#ifdef GET_CTable_IMPL
+constexpr CEntry CTable[] = {
+  { "Apple", CFoo, 0xA }, // 0
+  { "Apple", CBar, 0xD }, // 1
+  { "Pear", CBaz, 0xF }, // 2
+};
+
+const CEntry *lookupCEntryByEncoding(uint16_t Encoding) {
+  struct KeyType {
+    uint16_t Encoding;
   };
-
-  const CEntry *lookupCEntryByEncoding(uint16_t Encoding) {
-    struct KeyType {
-      uint16_t Encoding;
-    };
-    KeyType Key = { Encoding };
-    auto Table = ArrayRef(CTable);
-    auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
-      [](const CEntry &LHS, const KeyType &RHS) {
-        if (LHS.Encoding < RHS.Encoding)
-          return true;
-        if (LHS.Encoding > RHS.Encoding)
-          return false;
+  KeyType Key = { Encoding };
+  auto Table = ArrayRef(CTable);
+  auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
+    [](const CEntry &LHS, const KeyType &RHS) {
+      if (LHS.Encoding < RHS.Encoding)
+        return true;
+      if (LHS.Encoding > RHS.Encoding)
         return false;
-      });
+      return false;
+    });
 
-    if (Idx == Table.end() ||
-        Key.Encoding != Idx->Encoding)
-      return nullptr;
-    return &*Idx;
-  }
+  if (Idx == Table.end() ||
+      Key.Encoding != Idx->Encoding)
+    return nullptr;
+  return &*Idx;
+}
+```
 
 In the above example, lets add one more record with encoding same as that of
-record ``CEntry<"Pear",  CBaz, 15>``.
-
-.. code-block:: text
-
-  def CFoobar : CEnum;
-  def : CEntry<"Banana", CFoobar, 15>;
-
-Below is the new generated ``CTable``
-
-.. code-block:: text
-
-  #ifdef GET_Table_IMPL
-  constexpr CEntry Table[] = {
-    { "Apple", CFoo, 0xA }, // 0
-    { "Apple", CBar, 0xD }, // 1
-    { "Banana", CFoobar, 0xF }, // 2
-    { "Pear", CBaz, 0xF }, // 3
-  };
-
-Since ``Banana`` lexicographically appears first, therefore in the ``CEntry``
-table, record with name ``Banana`` will come before the record with name
-``Pear``. Because of this, the ``lookupCEntryByEncoding`` function will always
-return a pointer to the record with name ``Banana`` even though in some cases
-the correct result can be the record with name ``Pear``. Such kind of scenario
+record `CEntry<"Pear",  CBaz, 15>`.
+
+```text
+def CFoobar : CEnum;
+def : CEntry<"Banana", CFoobar, 15>;
+```
+
+Below is the new generated `CTable`
+
+```text
+#ifdef GET_Table_IMPL
+constexpr CEntry Table[] = {
+  { "Apple", CFoo, 0xA }, // 0
+  { "Apple", CBar, 0xD }, // 1
+  { "Banana", CFoobar, 0xF }, // 2
+  { "Pear", CBaz, 0xF }, // 3
+};
+```
+
+Since `Banana` lexicographically appears first, therefore in the `CEntry`
+table, record with name `Banana` will come before the record with name
+`Pear`. Because of this, the `lookupCEntryByEncoding` function will always
+return a pointer to the record with name `Banana` even though in some cases
+the correct result can be the record with name `Pear`. Such kind of scenario
 makes the existing lookup function insufficient because they always return a
 pointer to a single entry from the table, but instead it should return a range
 of results because multiple entries match the criteria sought by the lookup
 function. In this case, the definition of the lookup function needs to be
 modified to return a range of results which can be done by setting
-``PrimaryKeyReturnRange``.
-
-.. code-block:: text
-
-  def CTable : GenericTable {
-    let FilterClass = "CEntry";
-    let Fields = ["Name", "Kind", "Encoding"];
-    string TypeOf_Kind = "CEnum";
-    let PrimaryKey = ["Encoding"];
-    let PrimaryKeyName = "lookupCEntryByEncoding";
-    let PrimaryKeyReturnRange = true;
-  }
+`PrimaryKeyReturnRange`.
+
+```text
+def CTable : GenericTable {
+  let FilterClass = "CEntry";
+  let Fields = ["Name", "Kind", "Encoding"];
+  string TypeOf_Kind = "CEnum";
+  let PrimaryKey = ["Encoding"];
+  let PrimaryKeyName = "lookupCEntryByEncoding";
+  let PrimaryKeyReturnRange = true;
+}
+```
 
 Here is the modified lookup function.
 
-.. code-block:: text
-
-  llvm::iterator_range<const CEntry *> lookupCEntryByEncoding(uint16_t Encoding) {
-    struct KeyType {
-      uint16_t Encoding;
-    };
-    KeyType Key = {Encoding};
-    struct Comp {
-      bool operator()(const CEntry &LHS, const KeyType &RHS) const {
-        if (LHS.Encoding < RHS.Encoding)
-          return true;
-        if (LHS.Encoding > RHS.Encoding)
-          return false;
+```text
+llvm::iterator_range<const CEntry *> lookupCEntryByEncoding(uint16_t Encoding) {
+  struct KeyType {
+    uint16_t Encoding;
+  };
+  KeyType Key = {Encoding};
+  struct Comp {
+    bool operator()(const CEntry &LHS, const KeyType &RHS) const {
+      if (LHS.Encoding < RHS.Encoding)
+        return true;
+      if (LHS.Encoding > RHS.Encoding)
         return false;
-      }
-      bool operator()(const KeyType &LHS, const CEntry &RHS) const {
-        if (LHS.Encoding < RHS.Encoding)
-          return true;
-        if (LHS.Encoding > RHS.Encoding)
-          return false;
+      return false;
+    }
+    bool operator()(const KeyType &LHS, const CEntry &RHS) const {
+      if (LHS.Encoding < RHS.Encoding)
+        return true;
+      if (LHS.Encoding > RHS.Encoding)
         return false;
-      }
-    };
-    auto Table = ArrayRef(Table);
-    auto It = std::equal_range(Table.begin(), Table.end(), Key, Comp());
-    return llvm::make_range(It.first, It.second);
-  }
+      return false;
+    }
+  };
+  auto Table = ArrayRef(Table);
+  auto It = std::equal_range(Table.begin(), Table.end(), Key, Comp());
+  return llvm::make_range(It.first, It.second);
+}
+```
 
 The new lookup function will return an iterator range with first pointer to the
 first result and the last pointer to the last matching result from the table.
 However, please note that the support for emitting a modified definition exists
-for ``PrimaryKeyName`` only.
+for `PrimaryKeyName` only.
 
-The ``PrimaryKeyEarlyOut`` field, when set to 1, modifies the lookup
+The `PrimaryKeyEarlyOut` field, when set to 1, modifies the lookup
 function so that it tests the first field of the primary key to determine
 whether it is within the range of the collected records' primary keys. If
 not, the function returns the null pointer without performing the binary
@@ -1005,209 +921,207 @@ search. This is useful for tables that provide data for only some of the
 elements of a larger enum-based space. The first field of the primary key
 must be an integral type; it cannot be a string.
 
-Adding ``let PrimaryKeyEarlyOut = 1`` to the ``ATable`` above:
-
-.. code-block:: text
+Adding `let PrimaryKeyEarlyOut = 1` to the `ATable` above:
 
-  def ATable : GenericTable {
-    let FilterClass = "AEntry";
-    let Fields = ["Str", "Val1", "Val2"];
-    let PrimaryKey = ["Val1", "Val2"];
-    let PrimaryKeyName = "lookupATableByValues";
-    let PrimaryKeyEarlyOut = 1;
-  }
+```text
+def ATable : GenericTable {
+  let FilterClass = "AEntry";
+  let Fields = ["Str", "Val1", "Val2"];
+  let PrimaryKey = ["Val1", "Val2"];
+  let PrimaryKeyName = "lookupATableByValues";
+  let PrimaryKeyEarlyOut = 1;
+}
+```
 
 causes the lookup function to change as follows:
 
-.. code-block:: text
+```text
+const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {
+  if ((Val1 < 0x2) ||
+      (Val1 > 0x5))
+    return nullptr;
 
-  const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {
-    if ((Val1 < 0x2) ||
-        (Val1 > 0x5))
-      return nullptr;
-
-    struct KeyType {
-    ...
+  struct KeyType {
+  ...
+```
 
-We can construct two GenericTables with the same ``FilterClass``, so that they
+We can construct two GenericTables with the same `FilterClass`, so that they
 select from the same overall set of records, but assign them with different
-``FilterClassField`` values so that they include different subsets of the
+`FilterClassField` values so that they include different subsets of the
 records of that class.
 
 For example, we can create two tables that contain only even or odd records.
-Fields ``IsEven`` and ``IsOdd`` won't be included in generated C++ fields
-because they aren't included in ``Fields`` list.
-
-.. code-block:: text
-
-  class EEntry<bits<8> value> {
-    bits<8> Value = value;
-    bit IsEven = !eq(!and(value, 1), 0);
-    bit IsOdd = !not(IsEven);
-  }
-
-  foreach i = {1-10} in {
-    def : EEntry<i>;
-  }
-
-  def EEntryEvenTable : GenericTable {
-    let FilterClass = "EEntry";
-    let FilterClassField = "IsEven";
-    let Fields = ["Value"];
-    let PrimaryKey = ["Value"];
-    let PrimaryKeyName = "lookupEEntryEvenTableByValue";
-  }
-
-  def EEntryOddTable : GenericTable {
-    let FilterClass = "EEntry";
-    let FilterClassField = "IsOdd";
-    let Fields = ["Value"];
-    let PrimaryKey = ["Value"];
-    let PrimaryKeyName = "lookupEEntryOddTableByValue";
-  }
+Fields `IsEven` and `IsOdd` won't be included in generated C++ fields
+because they aren't included in `Fields` list.
+
+```text
+class EEntry<bits<8> value> {
+  bits<8> Value = value;
+  bit IsEven = !eq(!and(value, 1), 0);
+  bit IsOdd = !not(IsEven);
+}
+
+foreach i = {1-10} in {
+  def : EEntry<i>;
+}
+
+def EEntryEvenTable : GenericTable {
+  let FilterClass = "EEntry";
+  let FilterClassField = "IsEven";
+  let Fields = ["Value"];
+  let PrimaryKey = ["Value"];
+  let PrimaryKeyName = "lookupEEntryEvenTableByValue";
+}
+
+def EEntryOddTable : GenericTable {
+  let FilterClass = "EEntry";
+  let FilterClassField = "IsOdd";
+  let Fields = ["Value"];
+  let PrimaryKey = ["Value"];
+  let PrimaryKeyName = "lookupEEntryOddTableByValue";
+}
+```
 
 The generated tables are:
 
-.. code-block:: text
-
-  constexpr EEntry EEntryEvenTable[] = {
-    { 0x2 }, // 0
-    { 0x4 }, // 1
-    { 0x6 }, // 2
-    { 0x8 }, // 3
-    { 0xA }, // 4
-  };
-
-  constexpr EEntry EEntryOddTable[] = {
-    { 0x1 }, // 0
-    { 0x3 }, // 1
-    { 0x5 }, // 2
-    { 0x7 }, // 3
-    { 0x9 }, // 4
-  };
-
-Here is an example of a sparse direct-lookup table. ``FTable`` uses a 4-bit
-primary key (``bits<4>``), so the emitter allocates an array of
-``2^4 = 16`` entries.
-
-.. code-block:: text
-
-  def FTable : GenericTable {
-    let FilterClass = "FEntry";
-    let Fields = ["Key", "Val"];
-    let PrimaryKey = ["Key"];
-    let PrimaryKeyName = "lookupFTableByKey";
-    let DisallowSparseTable = false;
-  }
-
-Here is the generated C++ code. The declaration of ``lookupFTableByKey`` is
-guarded by ``GET_FTable_DECL``, while the definitions are guarded by
-``GET_FTable_IMPL``.
-
-.. code-block:: text
-
-  #ifdef GET_FTable_DECL
-  const FEntry *lookupFTableByKey(uint8_t Key);
-  #endif
-
-  #ifdef GET_FTable_IMPL
-  constexpr FEntry FTable[] = {
-    { 0xF, 0x0 }, // 0
-    { 0xE, 0x0 }, // 1
-    { 0x2, 0xA }, // 2
-    { 0xC, 0x0 }, // 3
-    { 0xB, 0x0 }, // 4
-    { 0x5, 0x14 }, // 5
-    { 0x9, 0x0 }, // 6
-    { 0x8, 0x0 }, // 7
-    { 0x7, 0x0 }, // 8
-    { 0x6, 0x0 }, // 9
-    { 0x5, 0x0 }, // 10
-    { 0x4, 0x0 }, // 11
-    { 0x3, 0x0 }, // 12
-    { 0xD, 0x1E }, // 13
-    { 0x1, 0x0 }, // 14
-    { 0x0, 0x0 }, // 15
-  };
-
-  const FEntry *lookupFTableByKey(uint8_t Key) {
-    if (Key >= 16)
-      return nullptr;
-    const auto *Entry = &FTable[Key];
-    return Entry->Key == Key ? Entry : nullptr;
-  }
-  #endif
-
-Empty slots are filled with a sentinel value in the ``Key`` field
-(``(15 ^ Idx)``) so that the in-place comparison ``Entry->Key == Key``
-returns ``nullptr`` for them without a separate presence array.
-
-Search Indexes
-~~~~~~~~~~~~~~
-
-The ``SearchIndex`` class is used to define additional lookup functions for
+```text
+constexpr EEntry EEntryEvenTable[] = {
+  { 0x2 }, // 0
+  { 0x4 }, // 1
+  { 0x6 }, // 2
+  { 0x8 }, // 3
+  { 0xA }, // 4
+};
+
+constexpr EEntry EEntryOddTable[] = {
+  { 0x1 }, // 0
+  { 0x3 }, // 1
+  { 0x5 }, // 2
+  { 0x7 }, // 3
+  { 0x9 }, // 4
+};
+```
+
+Here is an example of a sparse direct-lookup table. `FTable` uses a 4-bit
+primary key (`bits<4>`), so the emitter allocates an array of
+`2^4 = 16` entries.
+
+```text
+def FTable : GenericTable {
+  let FilterClass = "FEntry";
+  let Fields = ["Key", "Val"];
+  let PrimaryKey = ["Key"];
+  let PrimaryKeyName = "lookupFTableByKey";
+  let DisallowSparseTable = false;
+}
+```
+
+Here is the generated C++ code. The declaration of `lookupFTableByKey` is
+guarded by `GET_FTable_DECL`, while the definitions are guarded by
+`GET_FTable_IMPL`.
+
+```text
+#ifdef GET_FTable_DECL
+const FEntry *lookupFTableByKey(uint8_t Key);
+#endif
+
+#ifdef GET_FTable_IMPL
+constexpr FEntry FTable[] = {
+  { 0xF, 0x0 }, // 0
+  { 0xE, 0x0 }, // 1
+  { 0x2, 0xA }, // 2
+  { 0xC, 0x0 }, // 3
+  { 0xB, 0x0 }, // 4
+  { 0x5, 0x14 }, // 5
+  { 0x9, 0x0 }, // 6
+  { 0x8, 0x0 }, // 7
+  { 0x7, 0x0 }, // 8
+  { 0x6, 0x0 }, // 9
+  { 0x5, 0x0 }, // 10
+  { 0x4, 0x0 }, // 11
+  { 0x3, 0x0 }, // 12
+  { 0xD, 0x1E }, // 13
+  { 0x1, 0x0 }, // 14
+  { 0x0, 0x0 }, // 15
+};
+
+const FEntry *lookupFTableByKey(uint8_t Key) {
+  if (Key >= 16)
+    return nullptr;
+  const auto *Entry = &FTable[Key];
+  return Entry->Key == Key ? Entry : nullptr;
+}
+#endif
+```
+
+Empty slots are filled with a sentinel value in the `Key` field
+(`(15 ^ Idx)`) so that the in-place comparison `Entry->Key == Key`
+returns `nullptr` for them without a separate presence array.
+
+#### Search Indexes
+
+The `SearchIndex` class is used to define additional lookup functions for
 generic tables. To define an additional function, define a record whose parent
-class is ``SearchIndex`` and whose name is the name of the desired lookup
+class is `SearchIndex` and whose name is the name of the desired lookup
 function. This class provides three fields.
 
-* ``GenericTable Table``. The name of the table that is to receive another
+- `GenericTable Table`. The name of the table that is to receive another
   lookup function.
+- `list<string> Key`. The list of fields that make up the secondary key.
+- `bit EarlyOut`. See the third example in [Generic Tables].
 
-* ``list<string> Key``. The list of fields that make up the secondary key.
-
-* ``bit EarlyOut``. See the third example in `Generic Tables`_.
+Here is an example of a secondary key added to the `CTable` above. The
+generated function looks up entries based on the `Name` and `Kind` fields.
 
-Here is an example of a secondary key added to the ``CTable`` above. The
-generated function looks up entries based on the ``Name`` and ``Kind`` fields.
+```text
+def lookupCEntry : SearchIndex {
+  let Table = CTable;
+  let Key = ["Name", "Kind"];
+}
+```
 
-.. code-block:: text
+This use of `SearchIndex` generates the following additional C++ code.
 
-  def lookupCEntry : SearchIndex {
-    let Table = CTable;
-    let Key = ["Name", "Kind"];
-  }
+```text
+const CEntry *lookupCEntry(StringRef Name, unsigned Kind);
 
-This use of ``SearchIndex`` generates the following additional C++ code.
+...
 
-.. code-block:: text
+const CEntry *lookupCEntryByName(StringRef Name, unsigned Kind) {
+  struct IndexType {
+    const char * Name;
+    unsigned Kind;
+    unsigned _index;
+  };
+  static const struct IndexType Index[] = {
+    { "APPLE", CBar, 1 },
+    { "APPLE", CFoo, 0 },
+    { "PEAR", CBaz, 2 },
+  };
 
-  const CEntry *lookupCEntry(StringRef Name, unsigned Kind);
+  struct KeyType {
+    std::string Name;
+    unsigned Kind;
+  };
+  KeyType Key = { Name.upper(), Kind };
+  auto Table = ArrayRef(Index);
+  auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
+    [](const IndexType &LHS, const KeyType &RHS) {
+      int CmpName = StringRef(LHS.Name).compare(RHS.Name);
+      if (CmpName < 0) return true;
+      if (CmpName > 0) return false;
+      if ((unsigned)LHS.Kind < (unsigned)RHS.Kind)
+        return true;
+      if ((unsigned)LHS.Kind > (unsigned)RHS.Kind)
+        return false;
+      return false;
+    });
 
-  ...
+  if (Idx == Table.end() ||
+      Key.Name != Idx->Name ||
+      Key.Kind != Idx->Kind)
+    return nullptr;
+  return &CTable[Idx->_index];
+}
+```
 
-  const CEntry *lookupCEntryByName(StringRef Name, unsigned Kind) {
-    struct IndexType {
-      const char * Name;
-      unsigned Kind;
-      unsigned _index;
-    };
-    static const struct IndexType Index[] = {
-      { "APPLE", CBar, 1 },
-      { "APPLE", CFoo, 0 },
-      { "PEAR", CBaz, 2 },
-    };
-
-    struct KeyType {
-      std::string Name;
-      unsigned Kind;
-    };
-    KeyType Key = { Name.upper(), Kind };
-    auto Table = ArrayRef(Index);
-    auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,
-      [](const IndexType &LHS, const KeyType &RHS) {
-        int CmpName = StringRef(LHS.Name).compare(RHS.Name);
-        if (CmpName < 0) return true;
-        if (CmpName > 0) return false;
-        if ((unsigned)LHS.Kind < (unsigned)RHS.Kind)
-          return true;
-        if ((unsigned)LHS.Kind > (unsigned)RHS.Kind)
-          return false;
-        return false;
-      });
-
-    if (Idx == Table.end() ||
-        Key.Name != Idx->Name ||
-        Key.Kind != Idx->Kind)
-      return nullptr;
-    return &CTable[Idx->_index];
-  }
diff --git a/llvm/docs/TableGen/BackGuide.md b/llvm/docs/TableGen/BackGuide.md
index 6cc6f04afe901..1e232c1cbeb28 100644
--- a/llvm/docs/TableGen/BackGuide.md
+++ b/llvm/docs/TableGen/BackGuide.md
@@ -1,12 +1,11 @@
-===================================
-TableGen Backend Developer's Guide
-===================================
+# TableGen Backend Developer's Guide
 
+```{eval-rst}
 .. sectnum::
 
+```
 
-Introduction
-============
+## Introduction
 
 The purpose of TableGen is to generate complex output files based on
 information from source files that are significantly easier to code than the
@@ -14,22 +13,21 @@ output files would be, and also easier to maintain and modify over time. The
 information is coded in a declarative style involving classes and records,
 which are then processed by TableGen. The internalized records are passed on
 to various backends, which extract information from a subset of the records
-and generate an output file. These output files are typically ``.inc`` files
+and generate an output file. These output files are typically `.inc` files
 for C++, but they may be any type of file that the backend developer needs.
 
 This document is a guide to writing a backend for TableGen. It is not a
 complete reference manual, but rather a guide to using the facilities
 provided by TableGen for the backends. For a complete reference to the
 various data structures and functions involved, see the primary TableGen
-header file (``record.h``) and/or the Doxygen documentation.
+header file (`record.h`) and/or the Doxygen documentation.
 
-This document assumes that you have read the :doc:`TableGen Programmer's
+This document assumes that you have read the {doc}`TableGen Programmer's
 Reference <./ProgRef>`, which provides a detailed reference for coding
 TableGen source files. For a description of the existing backends, see
-:doc:`TableGen BackEnds <./BackEnds>`.
+{doc}`TableGen BackEnds <./BackEnds>`.
 
-Data Structures
-===============
+## Data Structures
 
 The following sections describe the data structures that contain the classes
 and records that are collected from the TableGen source files by the
@@ -39,811 +37,727 @@ class, while the term *record* refers to a concrete record.
 Unless otherwise noted, functions associated with classes are instance
 functions.
 
-``RecordKeeper``
-----------------
+### `RecordKeeper`
 
-An instance of the ``RecordKeeper`` class acts as the container for all the
-classes and records parsed and collected by TableGen. The ``RecordKeeper``
+An instance of the `RecordKeeper` class acts as the container for all the
+classes and records parsed and collected by TableGen. The `RecordKeeper`
 instance is passed to the backend when it is invoked by TableGen. This class
-is usually abbreviated ``RK``.
+is usually abbreviated `RK`.
 
 There are two maps in the recordkeeper, one for classes and one for records
 (the latter often referred to as *defs*). Each map maps the class or record
-name to an instance of the ``Record`` class (see `Record`_), which contains
+name to an instance of the `Record` class (see [Record]), which contains
 all the information about that class or record.
 
-In addition to the two maps, the ``RecordKeeper`` instance contains:
+In addition to the two maps, the `RecordKeeper` instance contains:
 
-* A map that maps the names of global variables to their values.
+- A map that maps the names of global variables to their values.
   Global variables are defined in TableGen files with outer
-  ``defvar`` statements.
+  `defvar` statements.
+- A counter for naming anonymous records.
 
-* A counter for naming anonymous records.
+The `RecordKeeper` class provides a few useful functions.
 
-The ``RecordKeeper`` class provides a few useful functions.
+- Functions to get the complete class and record maps.
+- Functions to get a subset of the records based on their parent classes.
+- Functions to get individual classes, records, and globals, by name.
 
-* Functions to get the complete class and record maps.
-
-* Functions to get a subset of the records based on their parent classes.
-
-* Functions to get individual classes, records, and globals, by name.
-
-A ``RecordKeeper`` instance can be printed to an output stream with the ``<<``
+A `RecordKeeper` instance can be printed to an output stream with the `<<`
 operator.
 
-``Record``
-----------
+### `Record`
 
 Each class or record built by TableGen is represented by an instance of
-the ``Record`` class. The ``RecordKeeper`` instance contains one map for the
+the `Record` class. The `RecordKeeper` instance contains one map for the
 classes and one for the records. The primary data members of a record are
 the record name, the vector of field names and their values, and the vector of
 superclasses of the record.
 
-The record name is stored as a pointer to an ``Init`` (see `Init`_), which
+The record name is stored as a pointer to an `Init` (see [Init]), which
 is a class whose instances hold TableGen values (sometimes referred to as
 *initializers*). The field names and values are stored in a vector of
-``RecordVal`` instances (see `RecordVal`_), each of which contains both the
+`RecordVal` instances (see [RecordVal]), each of which contains both the
 field name and its value. The superclass vector contains a sequence of
 pairs, with each pair including the superclass record and its source
 file location.
 
-In addition to those members, a ``Record`` instance contains:
+In addition to those members, a `Record` instance contains:
 
-* A vector of source file locations that includes the record definition
+- A vector of source file locations that includes the record definition
   itself, plus the locations of any multiclasses involved in its definition.
+- For a class record, a vector of the class's template arguments.
+- An instance of `DefInit` (see [DefInit]) corresponding to this record.
+- A unique record ID.
+- A boolean that specifies whether this is a class definition.
+- A boolean that specifies whether this is an anonymous record.
 
-* For a class record, a vector of the class's template arguments.
-
-* An instance of ``DefInit`` (see `DefInit`_) corresponding to this record.
-
-* A unique record ID.
-
-* A boolean that specifies whether this is a class definition.
+The `Record` class provides many useful functions.
 
-* A boolean that specifies whether this is an anonymous record.
-
-The ``Record`` class provides many useful functions.
-
-* Functions to get the record name, fields, source file locations,
+- Functions to get the record name, fields, source file locations,
   template arguments, and unique ID.
-
-* Functions to get all the record's superclasses or just its direct
+- Functions to get all the record's superclasses or just its direct
   superclasses.
-
-* Functions to get a particular field value by specifying its name in various
+- Functions to get a particular field value by specifying its name in various
   forms and returning its value in various forms
-  (see `Getting Record Names and Fields`_).
-
-* Boolean functions to check the various attributes of the record.
+  (see [Getting Record Names and Fields]).
+- Boolean functions to check the various attributes of the record.
 
-A ``Record`` instance can be printed to an output stream with the ``<<``
+A `Record` instance can be printed to an output stream with the `<<`
 operator.
 
+### `RecordVal`
 
-``RecordVal``
--------------
-
-Each field of a record is stored in an instance of the ``RecordVal`` class.
-The ``Record`` instance includes a vector of these value instances. A
-``RecordVal`` instance contains the name of the field, stored in an ``Init``
+Each field of a record is stored in an instance of the `RecordVal` class.
+The `Record` instance includes a vector of these value instances. A
+`RecordVal` instance contains the name of the field, stored in an `Init`
 instance. It also contains the value of the field, likewise stored in an
-``Init``. (A better name for this class might be ``RecordField``.)
+`Init`. (A better name for this class might be `RecordField`.)
 
-In addition to those primary members, the ``RecordVal`` has other data members.
+In addition to those primary members, the `RecordVal` has other data members.
 
-* The source file location of the field definition.
+- The source file location of the field definition.
+- The type of the field, stored as an instance
+  of the `RecTy` class (see [RecTy]).
 
-* The type of the field, stored as an instance
-  of the ``RecTy`` class (see `RecTy`_).
+The `RecordVal` class provides some useful functions.
 
-The ``RecordVal`` class provides some useful functions.
+- Functions to get the name of the field in various forms.
+- A function to get the type of the field.
+- A function to get the value of the field.
+- A function to get the source file location.
 
-* Functions to get the name of the field in various forms.
+Note that field values are more easily obtained directly from the `Record`
+instance (see [Record]).
 
-* A function to get the type of the field.
-
-* A function to get the value of the field.
-
-* A function to get the source file location.
-
-Note that field values are more easily obtained directly from the ``Record``
-instance (see `Record`_).
-
-A ``RecordVal`` instance can be printed to an output stream with the ``<<``
+A `RecordVal` instance can be printed to an output stream with the `<<`
 operator.
 
-``RecTy``
----------
+### `RecTy`
 
-The ``RecTy`` class is used to represent the types of field values. It is
+The `RecTy` class is used to represent the types of field values. It is
 the base class for a series of subclasses, one for each of the
-available field types. The ``RecTy`` class has one data member that is an
+available field types. The `RecTy` class has one data member that is an
 enumerated type specifying the specific type of field value. (A better
-name for this class might be ``FieldTy``.)
-
-The ``RecTy`` class provides a few useful functions.
+name for this class might be `FieldTy`.)
 
-* A virtual function to get the type name as a string.
+The `RecTy` class provides a few useful functions.
 
-* A virtual function to check whether all the values of this type can
+- A virtual function to get the type name as a string.
+- A virtual function to check whether all the values of this type can
   be converted to another given type.
-
-* A virtual function to check whether this type is a subtype of
+- A virtual function to check whether this type is a subtype of
   another given type.
-
-* A function to get the corresponding ``list``
+- A function to get the corresponding `list`
   type for lists with elements of this type. For example, the function
-  returns the ``list<int>`` type when called with the ``int`` type.
-
-The subclasses that inherit from ``RecTy`` are
-``BitRecTy``,
-``BitsRecTy``,
-``CodeRecTy``,
-``DagRecTy``,
-``IntRecTy``,
-``ListRecTy``,
-``RecordRecTy``, and
-``StringRecTy``.
+  returns the `list<int>` type when called with the `int` type.
+
+The subclasses that inherit from `RecTy` are
+`BitRecTy`,
+`BitsRecTy`,
+`CodeRecTy`,
+`DagRecTy`,
+`IntRecTy`,
+`ListRecTy`,
+`RecordRecTy`, and
+`StringRecTy`.
 Some of these classes have additional members that
 are described in the following subsections.
 
-*All* of the classes derived from ``RecTy`` provide the ``get()`` function.
-It returns an instance of ``RecTy`` corresponding to the derived class.
-Some of the ``get()`` functions require an argument to
+*All* of the classes derived from `RecTy` provide the `get()` function.
+It returns an instance of `RecTy` corresponding to the derived class.
+Some of the `get()` functions require an argument to
 specify which particular variant of the type is desired. These arguments are
 described in the following subsections.
 
-A ``RecTy`` instance can be printed to an output stream with the ``<<``
+A `RecTy` instance can be printed to an output stream with the `<<`
 operator.
 
-.. warning::
-  It is not specified whether there is a single ``RecTy`` instance of a
-  particular type or multiple instances.
-
+:::{warning}
+It is not specified whether there is a single `RecTy` instance of a
+particular type or multiple instances.
+:::
 
-``BitsRecTy``
-~~~~~~~~~~~~~
+#### `BitsRecTy`
 
-This class includes a data member with the size of the ``bits`` value and a
+This class includes a data member with the size of the `bits` value and a
 function to get that size.
 
-The ``get()`` function takes the length of the sequence, *n*, and returns the
-``BitsRecTy`` type corresponding to ``bits<``\ *n*\ ``>``.
+The `get()` function takes the length of the sequence, *n*, and returns the
+`BitsRecTy` type corresponding to `bits<`*n*`>`.
 
-``ListRecTy``
-~~~~~~~~~~~~~
+#### `ListRecTy`
 
 This class includes a data member that specifies the type of the list's
 elements and a function to get that type.
 
-The ``get()`` function takes the ``RecTy`` *type* of the list members and
-returns the ``ListRecTy`` type corresponding to ``list<``\ *type*\ ``>``.
-
+The `get()` function takes the `RecTy` *type* of the list members and
+returns the `ListRecTy` type corresponding to `list<`*type*`>`.
 
-``RecordRecTy``
-~~~~~~~~~~~~~~~
+#### `RecordRecTy`
 
 This class includes data members that contain the list of parent classes of
 this record. It also provides a function to obtain the array of classes and
-two functions to get the iterator ``begin()`` and ``end()`` values. The
+two functions to get the iterator `begin()` and `end()` values. The
 class defines a type for the return values of the latter two functions.
 
-.. code-block:: text
+```text
+using const_record_iterator = Record * const *;
+```
 
-  using const_record_iterator = Record * const *;
-
-The ``get()`` function takes an ``ArrayRef`` of pointers to the ``Record``
-instances of the *direct* superclasses of the record and returns the ``RecordRecTy``
+The `get()` function takes an `ArrayRef` of pointers to the `Record`
+instances of the *direct* superclasses of the record and returns the `RecordRecTy`
 corresponding to the record inheriting from those superclasses.
 
-``Init``
---------
+### `Init`
 
-The ``Init`` class is used to represent TableGen values.  The name derives
+The `Init` class is used to represent TableGen values. The name derives
 from *initialization value*. This class should not be confused with the
-``RecordVal`` class, which represents record fields, both their names and
-values. The ``Init`` class is the base class for a series of subclasses, one
-for each of the available value types. The primary data member of ``Init``
+`RecordVal` class, which represents record fields, both their names and
+values. The `Init` class is the base class for a series of subclasses, one
+for each of the available value types. The primary data member of `Init`
 is an enumerated type that represents the specific type of the value.
 
-The ``Init`` class provides a few useful functions.
-
-* A function to get the type enumerator.
+The `Init` class provides a few useful functions.
 
-* A boolean virtual function to determine whether a value is completely
+- A function to get the type enumerator.
+- A boolean virtual function to determine whether a value is completely
   specified; that is, has no uninitialized subvalues.
-
-* Virtual functions to get the value as a string.
-
-* Virtual functions to cast the value to other types, implement the bit
+- Virtual functions to get the value as a string.
+- Virtual functions to cast the value to other types, implement the bit
   range feature of TableGen, and implement the list slice feature.
+- A virtual function to get a particular bit of the value.
 
-* A virtual function to get a particular bit of the value.
-
-The subclasses that inherit directly from ``Init`` are
-``UnsetInit`` and ``TypedInit``.
+The subclasses that inherit directly from `Init` are
+`UnsetInit` and `TypedInit`.
 
-An ``Init`` instance can be printed to an output stream with the ``<<``
+An `Init` instance can be printed to an output stream with the `<<`
 operator.
 
-.. warning::
-  It is not specified whether two separate initialization values with
-  the same underlying type and value (e.g., two strings with the value
-  "Hello") are represented by two ``Init``\ s or share the same ``Init``.
+:::{warning}
+It is not specified whether two separate initialization values with
+the same underlying type and value (e.g., two strings with the value
+"Hello") are represented by two `Init`s or share the same `Init`.
+:::
 
-``UnsetInit``
-~~~~~~~~~~~~~
+#### `UnsetInit`
 
-This class, a subclass of ``Init``, represents the unset (uninitialized)
-value. The static function ``get()`` can be used to obtain the singleton
-``Init`` of this type.
+This class, a subclass of `Init`, represents the unset (uninitialized)
+value. The static function `get()` can be used to obtain the singleton
+`Init` of this type.
 
+#### `TypedInit`
 
-``TypedInit``
-~~~~~~~~~~~~~
-
-This class, a subclass of ``Init``, acts as the parent class of the classes
+This class, a subclass of `Init`, acts as the parent class of the classes
 that represent specific value types (except for the unset value). These
-classes include ``BitInit``, ``BitsInit``, ``DagInit``, ``DefInit``,
-``IntInit``, ``ListInit``, and ``StringInit``. (There are additional derived
+classes include `BitInit`, `BitsInit`, `DagInit`, `DefInit`,
+`IntInit`, `ListInit`, and `StringInit`. (There are additional derived
 types used by the TableGen parser.)
 
-This class includes a data member that specifies the ``RecTy`` type of the
-value. It provides a function to get that ``RecTy`` type.
+This class includes a data member that specifies the `RecTy` type of the
+value. It provides a function to get that `RecTy` type.
 
-``BitInit``
-~~~~~~~~~~~
+#### `BitInit`
 
-The ``BitInit`` class is a subclass of ``TypedInit``. Its instances
+The `BitInit` class is a subclass of `TypedInit`. Its instances
 represent the possible values of a bit: 0 or 1. It includes a data member
 that contains the bit.
 
-*All* of the classes derived from ``TypedInit`` provide the following functions:
+*All* of the classes derived from `TypedInit` provide the following functions:
 
-* A static function named ``get()`` that returns an ``Init`` representing
-  the specified value(s). In the case of ``BitInit``, ``get(true)`` returns
-  an instance of ``BitInit`` representing true, while ``get(false)`` returns
+- A static function named `get()` that returns an `Init` representing
+  the specified value(s). In the case of `BitInit`, `get(true)` returns
+  an instance of `BitInit` representing true, while `get(false)` returns
   an instance
   representing false. As noted above, it is not specified whether there
-  is exactly one or more than one ``BitInit`` representing true (or false).
-
-* A function named ``GetValue()`` that returns the value of the instance
-  in a more direct form, in this case as a ``bool``.
+  is exactly one or more than one `BitInit` representing true (or false).
+- A function named `GetValue()` that returns the value of the instance
+  in a more direct form, in this case as a `bool`.
 
-``BitsInit``
-~~~~~~~~~~~~
+#### `BitsInit`
 
-The ``BitsInit`` class is a subclass of ``TypedInit``. Its instances
+The `BitsInit` class is a subclass of `TypedInit`. Its instances
 represent sequences of bits, from high-order to low-order. It includes a
 data member with the length of the sequence and a vector of pointers to
-``Init`` instances, one per bit.
+`Init` instances, one per bit.
 
-The class provides the usual ``get()`` function. It does not provide the
-``getValue()`` function.
+The class provides the usual `get()` function. It does not provide the
+`getValue()` function.
 
 The class provides the following additional functions.
 
-* A function to get the number of bits in the sequence.
-
-* A function that gets a bit specified by an integer index.
+- A function to get the number of bits in the sequence.
+- A function that gets a bit specified by an integer index.
 
-``DagInit``
-~~~~~~~~~~~
+#### `DagInit`
 
-The ``DagInit`` class is a subclass of ``TypedInit``. Its instances
-represent the possible directed acyclic graphs (``dag``).
+The `DagInit` class is a subclass of `TypedInit`. Its instances
+represent the possible directed acyclic graphs (`dag`).
 
-The class includes a pointer to an ``Init`` for the DAG operator and a
-pointer to a ``StringInit`` for the operator name. It includes the count of
+The class includes a pointer to an `Init` for the DAG operator and a
+pointer to a `StringInit` for the operator name. It includes the count of
 DAG operands and the count of operand names. Finally, it includes a vector of
-pointers to ``Init`` instances for the operands and another to
-``StringInit`` instances for the operand names.
+pointers to `Init` instances for the operands and another to
+`StringInit` instances for the operand names.
 (The DAG operands are also referred to as *arguments*.)
 
-The class provides two forms of the usual ``get()`` function. It does not
-provide the usual ``getValue()`` function.
+The class provides two forms of the usual `get()` function. It does not
+provide the usual `getValue()` function.
 
 The class provides many additional functions:
 
-* Functions to get the operator in various forms and to get the
+- Functions to get the operator in various forms and to get the
   operator name in various forms.
-
-* Functions to determine whether there are any operands and to get the
+- Functions to determine whether there are any operands and to get the
   number of operands.
-
-* Functions to get the operands, both individually and together.
-
-* Functions to determine whether there are any names and to
+- Functions to get the operands, both individually and together.
+- Functions to determine whether there are any names and to
   get the number of names.
-
-* Functions to get the names, both individually and together.
-
-* Functions to get the operand iterator ``begin()`` and ``end()`` values.
-
-* Functions to get the name iterator ``begin()`` and ``end()`` values.
+- Functions to get the names, both individually and together.
+- Functions to get the operand iterator `begin()` and `end()` values.
+- Functions to get the name iterator `begin()` and `end()` values.
 
 The class defines two types for the return values of the operand and name
 iterators.
 
-.. code-block:: text
-
-  using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator;
-  using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator;
-
+```text
+using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator;
+using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator;
+```
 
-``DefInit``
-~~~~~~~~~~~
+#### `DefInit`
 
-The ``DefInit`` class is a subclass of ``TypedInit``. Its instances
+The `DefInit` class is a subclass of `TypedInit`. Its instances
 represent the records that were collected by TableGen. It includes a data
-member that is a pointer to the record's ``Record`` instance.
+member that is a pointer to the record's `Record` instance.
 
-The class provides the usual ``get()`` function. It does not provide
-``getValue()``. Instead, it provides ``getDef()``, which returns the
-``Record`` instance.
+The class provides the usual `get()` function. It does not provide
+`getValue()`. Instead, it provides `getDef()`, which returns the
+`Record` instance.
 
-``IntInit``
-~~~~~~~~~~~
+#### `IntInit`
 
-The ``IntInit`` class is a subclass of ``TypedInit``. Its instances
+The `IntInit` class is a subclass of `TypedInit`. Its instances
 represent the possible values of a 64-bit integer. It includes a data member
 that contains the integer.
 
-The class provides the usual ``get()`` and ``getValue()`` functions. The
-latter function returns the integer as an ``int64_t``.
+The class provides the usual `get()` and `getValue()` functions. The
+latter function returns the integer as an `int64_t`.
 
-The class also provides a function, ``getBit()``, to obtain a specified bit
+The class also provides a function, `getBit()`, to obtain a specified bit
 of the integer value.
 
-``ListInit``
-~~~~~~~~~~~~
+#### `ListInit`
 
-The ``ListInit`` class is a subclass of ``TypedInit``. Its instances
+The `ListInit` class is a subclass of `TypedInit`. Its instances
 represent lists of elements of some type. It includes a data member with the
-length of the list and a vector of pointers to ``Init`` instances, one per
+length of the list and a vector of pointers to `Init` instances, one per
 element.
 
-The class provides the usual ``get()`` and ``getValues()`` functions. The
-latter function returns an ``ArrayRef`` of the vector of pointers to ``Init``
+The class provides the usual `get()` and `getValues()` functions. The
+latter function returns an `ArrayRef` of the vector of pointers to `Init`
 instances.
 
 The class provides these additional functions:
 
-* A function to get the element type.
-
-* Functions to get the length of the vector and to determine whether
+- A function to get the element type.
+- Functions to get the length of the vector and to determine whether
   it is empty.
-
-* Functions to get an element specified by an integer index and return
+- Functions to get an element specified by an integer index and return
   it in various forms.
-
-* Functions to get the iterator ``begin()`` and ``end()`` values. The
+- Functions to get the iterator `begin()` and `end()` values. The
   class defines a type for the return type of these two functions.
 
-.. code-block:: text
+```text
+using const_iterator = Init *const *;
+```
 
-  using const_iterator = Init *const *;
+#### `StringInit`
 
-
-``StringInit``
-~~~~~~~~~~~~~~
-
-The ``StringInit`` class is a subclass of ``TypedInit``. Its instances
+The `StringInit` class is a subclass of `TypedInit`. Its instances
 represent arbitrary-length strings. It includes a data member
-that contains a ``StringRef`` of the value.
+that contains a `StringRef` of the value.
 
-The class provides the usual ``get()`` and ``getValue()`` functions. The
-latter function returns the ``StringRef``.
+The class provides the usual `get()` and `getValue()` functions. The
+latter function returns the `StringRef`.
 
-Creating a New Backend
-======================
+## Creating a New Backend
 
 The following steps are required to create a new backend for TableGen.
 
-#. Invent a name for your backend C++ file, say ``GenAddressModes``.
-
-#. Write the new backend, using the file ``TableGenBackendSkeleton.cpp``
+1. Invent a name for your backend C++ file, say `GenAddressModes`.
+2. Write the new backend, using the file `TableGenBackendSkeleton.cpp`
    as a starting point.
-
-#. Determine which instance of TableGen requires the new backend. There is
+3. Determine which instance of TableGen requires the new backend. There is
    one instance for Clang and another for LLVM. Or you may be building
    your own instance.
-
-#. Add your backend C++ file to the appropriate ``CMakeLists.txt`` file so
+4. Add your backend C++ file to the appropriate `CMakeLists.txt` file so
    that it will be built.
+5. Add your C++ file to the system.
 
-#. Add your C++ file to the system.
+## The Backend Skeleton
 
-The Backend Skeleton
-====================
-
-The file ``TableGenBackendSkeleton.cpp`` provides a skeleton C++ translation
+The file `TableGenBackendSkeleton.cpp` provides a skeleton C++ translation
 unit for writing a new TableGen backend. Here are a few notes on the file:
 
-* The list of includes is the minimal list required by most backends.
+- The list of includes is the minimal list required by most backends.
 
-* As with all LLVM C++ files, it has a ``using namespace llvm;`` statement.
+- As with all LLVM C++ files, it has a `using namespace llvm;` statement.
   It also has an anonymous namespace that contains all the file-specific
   data structure definitions, along with the class embodying the emitter
-  data members and functions. Continuing with the ``GenAddressModes`` example,
-  this class is named ``AddressModesEmitter``.
+  data members and functions. Continuing with the `GenAddressModes` example,
+  this class is named `AddressModesEmitter`.
 
-* The constructor for the emitter class accepts a ``RecordKeeper`` reference,
-  typically named ``RK``. The ``RecordKeeper`` reference is saved in a data
+- The constructor for the emitter class accepts a `RecordKeeper` reference,
+  typically named `RK`. The `RecordKeeper` reference is saved in a data
   member so that records can be obtained from it. This data member is usually
-  named ``Records``.
+  named `Records`.
 
-* One function is named ``run``. It is invoked by the backend's "main
+- One function is named `run`. It is invoked by the backend's "main
   function" to collect records and emit the output file. It accepts an instance
-  of the ``raw_ostream`` class, typically named ``OS``. The output file is
+  of the `raw_ostream` class, typically named `OS`. The output file is
   emitted by writing to this stream.
 
-* The ``run`` function should use the ``emitSourceFileHeader`` helper function
+- The `run` function should use the `emitSourceFileHeader` helper function
   to include a standard header in the emitted file.
 
-* Register the class or the function as the command-line option
-  with ``llvm/TableGen/TableGenBackend.h``.
-
-  * Use ``llvm::TableGen::Emitter::OptClass<AddressModesEmitter>``
-    if the class has the constructor ``(RK)`` and
-    the method ``run(OS)``.
+- Register the class or the function as the command-line option
+  with `llvm/TableGen/TableGenBackend.h`.
 
-  * Otherwise, use ``llvm::TableGen::Emitter::Opt``.
+  - Use `llvm::TableGen::Emitter::OptClass<AddressModesEmitter>`
+    if the class has the constructor `(RK)` and
+    the method `run(OS)`.
+  - Otherwise, use `llvm::TableGen::Emitter::Opt`.
 
 All the examples in the remainder of this document will assume the naming
 conventions used in the skeleton file.
 
-Getting Classes
-===============
-
-The ``RecordKeeper`` class provides two functions for getting the
-``Record`` instances for classes defined in the TableGen files.
+## Getting Classes
 
-* ``getClasses()`` returns a ``RecordMap`` reference for all the classes.
+The `RecordKeeper` class provides two functions for getting the
+`Record` instances for classes defined in the TableGen files.
 
-* ``getClass(``\ *name*\ ``)`` returns a ``Record`` reference for the named
+- `getClasses()` returns a `RecordMap` reference for all the classes.
+- `getClass(`*name*`)` returns a `Record` reference for the named
   class.
 
 If you need to iterate over all the class records:
 
-.. code-block:: text
-
-  for (auto ClassPair : Records.getClasses()) {
-    Record *ClassRec = ClassPair.second.get();
-    ...
-  }
-
-``ClassPair.second`` gets the class's ``unique_ptr``, and then ``.get()`` gets the
-class ``Record`` itself.
+```text
+for (auto ClassPair : Records.getClasses()) {
+  Record *ClassRec = ClassPair.second.get();
+  ...
+}
+```
 
+`ClassPair.second` gets the class's `unique_ptr`, and then `.get()` gets the
+class `Record` itself.
 
-Getting Records
-===============
+## Getting Records
 
-The ``RecordKeeper`` class provides four functions for getting the
-``Record`` instances for concrete records defined in the TableGen files.
+The `RecordKeeper` class provides four functions for getting the
+`Record` instances for concrete records defined in the TableGen files.
 
-* ``getDefs()`` returns a ``RecordMap`` reference for all the concrete
+- `getDefs()` returns a `RecordMap` reference for all the concrete
   records.
-
-* ``getDef(``\ *name*\ ``)`` returns a ``Record`` reference for the named
+- `getDef(`*name*`)` returns a `Record` reference for the named
   concrete record.
-
-* ``getAllDerivedDefinitions(``\ *classname*\ ``)`` returns a vector of
-  ``Record`` references for the concrete records that derive from the
+- `getAllDerivedDefinitions(`*classname*`)` returns a vector of
+  `Record` references for the concrete records that derive from the
   given class.
-
-* ``getAllDerivedDefinitions(``\ *classnames*\ ``)`` returns
-  a vector of ``Record`` references for the concrete records that derive from
+- `getAllDerivedDefinitions(`*classnames*`)` returns
+  a vector of `Record` references for the concrete records that derive from
   *all* of the given classes.
 
-This statement obtains all the records that derive from the ``Attribute``
+This statement obtains all the records that derive from the `Attribute`
 class and iterates over them.
 
-.. code-block:: text
-
-  auto AttrRecords = Records.getAllDerivedDefinitions("Attribute");
-  for (Record *AttrRec : AttrRecords) {
-    ...
-  }
+```text
+auto AttrRecords = Records.getAllDerivedDefinitions("Attribute");
+for (Record *AttrRec : AttrRecords) {
+  ...
+}
+```
 
-Getting Record Names and Fields
-===============================
+## Getting Record Names and Fields
 
-As described above (see `Record`_), there are multiple functions that
+As described above (see [Record]), there are multiple functions that
 return the name of a record. One particularly useful one is
-``getNameInitAsString()``, which returns the name as a ``std::string``.
+`getNameInitAsString()`, which returns the name as a `std::string`.
 
 There are also multiple functions that return the fields of a record. To
 obtain and iterate over all the fields:
 
-.. code-block:: text
-
-  for (const RecordVal &Field : SomeRec->getValues()) {
-    ...
-  }
+```text
+for (const RecordVal &Field : SomeRec->getValues()) {
+  ...
+}
+```
 
-You will recall that ``RecordVal`` is the class whose instances contain
+You will recall that `RecordVal` is the class whose instances contain
 information about the fields in records.
 
-The ``getValue()`` function returns the ``RecordVal`` instance for a field
+The `getValue()` function returns the `RecordVal` instance for a field
 specified by name. There are multiple overloaded functions, some taking a
-``StringRef`` and others taking a ``const Init *``. Some functions return a
-``RecordVal *`` and others return a ``const RecordVal *``. If the field does
+`StringRef` and others taking a `const Init *`. Some functions return a
+`RecordVal *` and others return a `const RecordVal *`. If the field does
 not exist, a fatal error message is printed.
 
 More often than not, you are interested in the value of the field, not all
-the information in the ``RecordVal``. There is a large set of functions that
+the information in the `RecordVal`. There is a large set of functions that
 take a field name in some form and return its value. One function,
-``getValueInit``, returns the value as an ``Init *``. Another function,
-``isValueUnset``, returns a boolean specifying whether the value is unset
+`getValueInit`, returns the value as an `Init *`. Another function,
+`isValueUnset`, returns a boolean specifying whether the value is unset
 (uninitialized).
 
 Most of the functions return the value in some more useful form. For
 example:
 
-.. code-block:: text
-
-  std::vector<int64_t> RegCosts =
-      SomeRec->getValueAsListOfInts("RegCosts");
+```text
+std::vector<int64_t> RegCosts =
+    SomeRec->getValueAsListOfInts("RegCosts");
+```
 
-The field ``RegCosts`` is assumed to be a list of integers. That list is
-returned as a ``std::vector`` of 64-bit integers. If the field is not a list
+The field `RegCosts` is assumed to be a list of integers. That list is
+returned as a `std::vector` of 64-bit integers. If the field is not a list
 of integers, a fatal error message is printed.
 
-Here is a function that returns a field value as a ``Record``, but returns
+Here is a function that returns a field value as a `Record`, but returns
 null if the field does not exist.
 
-.. code-block:: text
-
-  if (Record *BaseRec = SomeRec->getValueAsOptionalDef(BaseFieldName)) {
-    ...
-  }
+```text
+if (Record *BaseRec = SomeRec->getValueAsOptionalDef(BaseFieldName)) {
+  ...
+}
+```
 
 The field is assumed to have another record as its value. That record is returned
-as a pointer to a ``Record``. If the field does not exist or is unset, the
+as a pointer to a `Record`. If the field does not exist or is unset, the
 function returns null.
 
-Getting Record Superclasses
-===========================
+## Getting Record Superclasses
 
-The ``Record`` class provides a function to obtain the direct superclasses
-of a record. It is named ``getDirectSuperClasses`` and returns an
-``ArrayRef`` of an array of ``std::pair`` instances. Each pair consists of a
-pointer to the ``Record`` instance for a superclass record and an instance
-of the ``SMRange`` class. The range indicates the source file locations of
+The `Record` class provides a function to obtain the direct superclasses
+of a record. It is named `getDirectSuperClasses` and returns an
+`ArrayRef` of an array of `std::pair` instances. Each pair consists of a
+pointer to the `Record` instance for a superclass record and an instance
+of the `SMRange` class. The range indicates the source file locations of
 the beginning and end of the class definition.
 
-This example obtains the direct superclasses of the ``Prototype`` record and
+This example obtains the direct superclasses of the `Prototype` record and
 then iterates over the pairs in the returned array.
 
-.. code-block:: text
-
-  ArrayRef<std::pair<const Record *, SMRange>>
-      Superclasses = Prototype->getDirectSuperClasses();
-  for (const auto &[Super, Range] : Superclasses) {
-    ...
-  }
+```text
+ArrayRef<std::pair<const Record *, SMRange>>
+    Superclasses = Prototype->getDirectSuperClasses();
+for (const auto &[Super, Range] : Superclasses) {
+  ...
+}
+```
 
-The ``Record`` class also provides a function, ``getSuperClasses``, to
+The `Record` class also provides a function, `getSuperClasses`, to
 return a vector of *all* superclasses of a record. The superclasses are in
 postorder: the order in which the superclasses were visited while copying
 their fields into the record.
 
-Emitting Text to the Output Stream
-==================================
+## Emitting Text to the Output Stream
 
-The ``run`` function is passed a ``raw_ostream`` to which it prints the
+The `run` function is passed a `raw_ostream` to which it prints the
 output file. By convention, this stream is saved in the emitter class member
-named ``OS``, although some ``run`` functions are simple and just use the
+named `OS`, although some `run` functions are simple and just use the
 stream without saving it. The output can be produced by writing values
-directly to the output stream, or by using the ``std::format()`` or
-``llvm::formatv()`` functions.
-
-.. code-block:: text
+directly to the output stream, or by using the `std::format()` or
+`llvm::formatv()` functions.
 
-  OS << "#ifndef " << NodeName << "\n";
+```text
+OS << "#ifndef " << NodeName << "\n";
 
-  OS << format("0x%0*x, ", Digits, Value);
+OS << format("0x%0*x, ", Digits, Value);
+```
 
-Instances of the following classes can be printed using the ``<<`` operator:
-``RecordKeeper``,
-``Record``,
-``RecTy``,
-``RecordVal``, and
-``Init``.
+Instances of the following classes can be printed using the `<<` operator:
+`RecordKeeper`,
+`Record`,
+`RecTy`,
+`RecordVal`, and
+`Init`.
 
-The helper function ``emitSourceFileHeader()`` prints the header comment
+The helper function `emitSourceFileHeader()` prints the header comment
 that should be included at the top of every output file. A call to it is
-included in the skeleton backend file ``TableGenBackendSkeleton.cpp``.
+included in the skeleton backend file `TableGenBackendSkeleton.cpp`.
 
-Printing Error Messages
-=======================
+## Printing Error Messages
 
 TableGen records are often derived from multiple classes and also often
 defined through a sequence of multiclasses. Because of this, it can be
 difficult for backends to report clear error messages with accurate source
-file locations.  To make error reporting easier, five error reporting
+file locations. To make error reporting easier, five error reporting
 functions are provided, each with four overloads.
 
-* ``PrintWarning`` prints a message tagged as a warning.
-
-* ``PrintError`` prints a message tagged as an error.
-
-* ``PrintFatalError`` prints a message tagged as an error and then terminates.
-
-* ``PrintNote`` prints a note. It is often used after one of the previous
+- `PrintWarning` prints a message tagged as a warning.
+- `PrintError` prints a message tagged as an error.
+- `PrintFatalError` prints a message tagged as an error and then terminates.
+- `PrintNote` prints a note. It is often used after one of the previous
   functions to provide more information.
-
-* ``PrintFatalNote`` prints a note and then terminates.
+- `PrintFatalNote` prints a note and then terminates.
 
 Each of these five functions is overloaded four times.
 
-* ``PrintError(const Twine &Msg)``:
+- `PrintError(const Twine &Msg)`:
   Prints the message with no source file location.
-
-* ``PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg)``:
+- `PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg)`:
   Prints the message followed by the specified source line,
   along with a pointer to the item in error. The array of
-  source file locations is typically taken from a ``Record`` instance.
-
-* ``PrintError(const Record *Rec, const Twine &Msg)``:
+  source file locations is typically taken from a `Record` instance.
+- `PrintError(const Record *Rec, const Twine &Msg)`:
   Prints the message followed by the source line associated with the
-  specified record (see `Record`_).
-
-* ``PrintError(const RecordVal *RecVal, const Twine &Msg)``:
+  specified record (see [Record]).
+- `PrintError(const RecordVal *RecVal, const Twine &Msg)`:
   Prints the message followed by the source line associated with the
-  specified record field (see `RecordVal`_).
+  specified record field (see [RecordVal]).
 
 Using these functions, the goal is to produce the most specific error report
 possible.
 
-Debugging Tools
-===============
+## Debugging Tools
 
 TableGen provides some tools to aid in debugging backends.
 
-The ``PrintRecords`` Backend
-----------------------------
+### The `PrintRecords` Backend
 
-The TableGen command option ``--print-records`` invokes a simple backend
+The TableGen command option `--print-records` invokes a simple backend
 that prints all the classes and records defined in the source files. This is
 the default backend option. The format of the output is guaranteed to be
 constant over time, so that the output can be compared in tests. The output
 looks like this:
 
-.. code-block:: text
-
-  ------------- Classes -----------------
-  ...
-  class XEntry<string XEntry:str = ?, int XEntry:val1 = ?> { // XBase
-    string Str = XEntry:str;
-    bits<8> Val1 = { !cast<bits<8>>(XEntry:val1){7}, ... };
-    bit Val3 = 1;
-  }
-  ...
-  ------------- Defs -----------------
-  def ATable {	// GenericTable
-    string FilterClass = "AEntry";
-    string CppTypeName = "AEntry";
-    list<string> Fields = ["Str", "Val1", "Val2"];
-    list<string> PrimaryKey = ["Val1", "Val2"];
-    string PrimaryKeyName = "lookupATableByValues";
-    bit PrimaryKeyEarlyOut = 0;
-  }
-  ...
-  def anonymous_0 {	// AEntry
-    string Str = "Bob";
-    bits<8> Val1 = { 0, 0, 0, 0, 0, 1, 0, 1 };
-    bits<10> Val2 = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
-  }
+```text
+------------- Classes -----------------
+...
+class XEntry<string XEntry:str = ?, int XEntry:val1 = ?> { // XBase
+  string Str = XEntry:str;
+  bits<8> Val1 = { !cast<bits<8>>(XEntry:val1){7}, ... };
+  bit Val3 = 1;
+}
+...
+------------- Defs -----------------
+def ATable {  // GenericTable
+  string FilterClass = "AEntry";
+  string CppTypeName = "AEntry";
+  list<string> Fields = ["Str", "Val1", "Val2"];
+  list<string> PrimaryKey = ["Val1", "Val2"];
+  string PrimaryKeyName = "lookupATableByValues";
+  bit PrimaryKeyEarlyOut = 0;
+}
+...
+def anonymous_0 {     // AEntry
+  string Str = "Bob";
+  bits<8> Val1 = { 0, 0, 0, 0, 0, 1, 0, 1 };
+  bits<10> Val2 = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
+}
+```
 
 Classes are shown with their template arguments, parent classes (following
-``//``), and fields. Records are shown with their parent classes and
-fields. Note that anonymous records are named ``anonymous_0``,
-``anonymous_1``, etc.
+`//`), and fields. Records are shown with their parent classes and
+fields. Note that anonymous records are named `anonymous_0`,
+`anonymous_1`, etc.
 
-The ``PrintDetailedRecords`` Backend
-------------------------------------
+### The `PrintDetailedRecords` Backend
 
-The TableGen command option ``--print-detailed-records`` invokes a backend
+The TableGen command option `--print-detailed-records` invokes a backend
 that prints all the global variables, classes, and records defined in the
 source files. The format of the output is *not* guaranteed to be constant
 over time. The output looks like this:
 
-.. code-block:: text
-
-  DETAILED RECORDS for file llvm-project\llvm\lib\target\arc\arc.td
-
-  -------------------- Global Variables (5) --------------------
-
-  AMDGPUBufferIntrinsics = [int_amdgcn_s_buffer_load, ...
-  AMDGPUImageDimAtomicIntrinsics = [int_amdgcn_image_atomic_swap_1d, ...
-  ...
-  -------------------- Classes (758) --------------------
-
-  AMDGPUBufferLoad  |IntrinsicsAMDGPU.td:879|
-    Template args:
-      LLVMType AMDGPUBufferLoad:data_ty = llvm_any_ty  |IntrinsicsAMDGPU.td:879|
-    Superclasses: (SDPatternOperator) Intrinsic AMDGPURsrcIntrinsic
-    Fields:
-      list<SDNodeProperty> Properties = [SDNPMemOperand]  |Intrinsics.td:348|
-      string LLVMName = ""  |Intrinsics.td:343|
-  ...
-  -------------------- Records (12303) --------------------
-
-  AMDGPUSample_lz_o  |IntrinsicsAMDGPU.td:560|
-    Defm sequence: |IntrinsicsAMDGPU.td:584| |IntrinsicsAMDGPU.td:566|
-    Superclasses: AMDGPUSampleVariant
-    Fields:
-      string UpperCaseMod = "_LZ_O"  |IntrinsicsAMDGPU.td:542|
-      string LowerCaseMod = "_lz_o"  |IntrinsicsAMDGPU.td:543|
-  ...
-
-* Global variables defined with outer ``defvar`` statements are shown with
+```text
+DETAILED RECORDS for file llvm-project\llvm\lib\target\arc\arc.td
+
+-------------------- Global Variables (5) --------------------
+
+AMDGPUBufferIntrinsics = [int_amdgcn_s_buffer_load, ...
+AMDGPUImageDimAtomicIntrinsics = [int_amdgcn_image_atomic_swap_1d, ...
+...
+-------------------- Classes (758) --------------------
+
+AMDGPUBufferLoad  |IntrinsicsAMDGPU.td:879|
+  Template args:
+    LLVMType AMDGPUBufferLoad:data_ty = llvm_any_ty  |IntrinsicsAMDGPU.td:879|
+  Superclasses: (SDPatternOperator) Intrinsic AMDGPURsrcIntrinsic
+  Fields:
+    list<SDNodeProperty> Properties = [SDNPMemOperand]  |Intrinsics.td:348|
+    string LLVMName = ""  |Intrinsics.td:343|
+...
+-------------------- Records (12303) --------------------
+
+AMDGPUSample_lz_o  |IntrinsicsAMDGPU.td:560|
+  Defm sequence: |IntrinsicsAMDGPU.td:584| |IntrinsicsAMDGPU.td:566|
+  Superclasses: AMDGPUSampleVariant
+  Fields:
+    string UpperCaseMod = "_LZ_O"  |IntrinsicsAMDGPU.td:542|
+    string LowerCaseMod = "_lz_o"  |IntrinsicsAMDGPU.td:543|
+...
+```
+
+- Global variables defined with outer `defvar` statements are shown with
   their values.
-
-* The classes are shown with their source location, template arguments,
+- The classes are shown with their source location, template arguments,
   superclasses, and fields.
-
-* The records are shown with their source location, ``defm`` sequence,
+- The records are shown with their source location, `defm` sequence,
   superclasses, and fields.
 
 Superclasses are shown in the order processed, with indirect superclasses in
 parentheses. Each field is shown with its value and the source location at
 which it was set.
-The ``defm`` sequence gives the locations of the ``defm`` statements that
+The `defm` sequence gives the locations of the `defm` statements that
 were involved in generating the record, in the order they were invoked.
 
-Timing TableGen Phases
-----------------------
+### Timing TableGen Phases
 
 TableGen provides a phase timing feature that produces a report of the time
 used by the various phases of parsing the source files and running the
-selected backend. This feature is enabled with the ``--time-phases`` option
+selected backend. This feature is enabled with the `--time-phases` option
 of the TableGen command.
 
 If the backend is *not* instrumented for timing, then a report such as the
 following is produced. This is the timing for the
-``--print-detailed-records`` backend run on the AMDGPU target.
+`--print-detailed-records` backend run on the AMDGPU target.
 
-.. code-block:: text
+```text
+===-------------------------------------------------------------------------===
+                             TableGen Phase Timing
+===-------------------------------------------------------------------------===
+  Total Execution Time: 101.0106 seconds (102.4819 wall clock)
 
-  ===-------------------------------------------------------------------------===
-                               TableGen Phase Timing
-  ===-------------------------------------------------------------------------===
-    Total Execution Time: 101.0106 seconds (102.4819 wall clock)
-
-     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
-    85.5197 ( 84.9%)   0.1560 ( 50.0%)  85.6757 ( 84.8%)  85.7009 ( 83.6%)  Backend overall
-    15.1789 ( 15.1%)   0.0000 (  0.0%)  15.1789 ( 15.0%)  15.1829 ( 14.8%)  Parse, build records
-     0.0000 (  0.0%)   0.1560 ( 50.0%)   0.1560 (  0.2%)   1.5981 (  1.6%)  Write output
-    100.6986 (100.0%)   0.3120 (100.0%)  101.0106 (100.0%)  102.4819 (100.0%)  Total
+   ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
+  85.5197 ( 84.9%)   0.1560 ( 50.0%)  85.6757 ( 84.8%)  85.7009 ( 83.6%)  Backend overall
+  15.1789 ( 15.1%)   0.0000 (  0.0%)  15.1789 ( 15.0%)  15.1829 ( 14.8%)  Parse, build records
+   0.0000 (  0.0%)   0.1560 ( 50.0%)   0.1560 (  0.2%)   1.5981 (  1.6%)  Write output
+  100.6986 (100.0%)   0.3120 (100.0%)  101.0106 (100.0%)  102.4819 (100.0%)  Total
+```
 
 Note that all the time for the backend is lumped under "Backend overall".
 
 If the backend is instrumented for timing, then its processing is
 divided into phases and each one timed separately. This is the timing for
-the ``--emit-dag-isel`` backend run on the AMDGPU target.
-
-.. code-block:: text
-
-  ===-------------------------------------------------------------------------===
-                               TableGen Phase Timing
-  ===-------------------------------------------------------------------------===
-    Total Execution Time: 746.3868 seconds (747.1447 wall clock)
-
-     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
-    657.7938 ( 88.1%)   0.1404 ( 90.0%)  657.9342 ( 88.1%)  658.6497 ( 88.2%)  Emit matcher table
-    70.2317 (  9.4%)   0.0000 (  0.0%)  70.2317 (  9.4%)  70.2700 (  9.4%)  Convert to matchers
-    14.8825 (  2.0%)   0.0156 ( 10.0%)  14.8981 (  2.0%)  14.9009 (  2.0%)  Parse, build records
-     2.1840 (  0.3%)   0.0000 (  0.0%)   2.1840 (  0.3%)   2.1791 (  0.3%)  Sort patterns
-     1.1388 (  0.2%)   0.0000 (  0.0%)   1.1388 (  0.2%)   1.1401 (  0.2%)  Optimize matchers
-     0.0000 (  0.0%)   0.0000 (  0.0%)   0.0000 (  0.0%)   0.0050 (  0.0%)  Write output
-    746.2308 (100.0%)   0.1560 (100.0%)  746.3868 (100.0%)  747.1447 (100.0%)  Total
+the `--emit-dag-isel` backend run on the AMDGPU target.
+
+```text
+===-------------------------------------------------------------------------===
+                             TableGen Phase Timing
+===-------------------------------------------------------------------------===
+  Total Execution Time: 746.3868 seconds (747.1447 wall clock)
+
+   ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
+  657.7938 ( 88.1%)   0.1404 ( 90.0%)  657.9342 ( 88.1%)  658.6497 ( 88.2%)  Emit matcher table
+  70.2317 (  9.4%)   0.0000 (  0.0%)  70.2317 (  9.4%)  70.2700 (  9.4%)  Convert to matchers
+  14.8825 (  2.0%)   0.0156 ( 10.0%)  14.8981 (  2.0%)  14.9009 (  2.0%)  Parse, build records
+   2.1840 (  0.3%)   0.0000 (  0.0%)   2.1840 (  0.3%)   2.1791 (  0.3%)  Sort patterns
+   1.1388 (  0.2%)   0.0000 (  0.0%)   1.1388 (  0.2%)   1.1401 (  0.2%)  Optimize matchers
+   0.0000 (  0.0%)   0.0000 (  0.0%)   0.0000 (  0.0%)   0.0050 (  0.0%)  Write output
+  746.2308 (100.0%)   0.1560 (100.0%)  746.3868 (100.0%)  747.1447 (100.0%)  Total
+```
 
 The backend has been divided into four phases and timed separately.
 
-If you want to instrument a backend, refer to the backend ``DAGISelEmitter.cpp``
-and search for ``Records.startTimer``.
+If you want to instrument a backend, refer to the backend `DAGISelEmitter.cpp`
+and search for `Records.startTimer`.
+
diff --git a/llvm/docs/TableGen/ProgRef.md b/llvm/docs/TableGen/ProgRef.md
index d5d0e28da665e..4c2c802fc9fe5 100644
--- a/llvm/docs/TableGen/ProgRef.md
+++ b/llvm/docs/TableGen/ProgRef.md
@@ -1,12 +1,11 @@
-===============================
-TableGen Programmer's Reference
-===============================
+# TableGen Programmer's Reference
 
+```{eval-rst}
 .. sectnum::
 
+```
 
-Introduction
-============
+## Introduction
 
 The purpose of TableGen is to generate complex output files based on
 information from source files that are significantly easier to code than the
@@ -15,41 +14,34 @@ information is coded in a declarative style involving classes and records,
 which are then processed by TableGen. The internalized records are passed on
 to various *backends*, which extract information from a subset of the records
 and generate one or more output files. These output files are typically
-``.inc`` files for C++, but may be any type of file that the backend
+`.inc` files for C++, but may be any type of file that the backend
 developer needs.
 
 This document describes the LLVM TableGen facility in detail. It is intended
 for the programmer who is using TableGen to produce code for a project. If
-you are looking for a simple overview, check out the :doc:`TableGen Overview
-<./index>`.  The various ``*-tblgen`` commands used to invoke TableGen are
-described in :doc:`tblgen Family - Description to C++
+you are looking for a simple overview, check out the {doc}`TableGen Overview
+<./index>`. The various `*-tblgen` commands used to invoke TableGen are
+described in {doc}`tblgen Family - Description to C++
 Code<../CommandGuide/tblgen>`.
 
-An example of a backend is ``RegisterInfo``, which generates the register
+An example of a backend is `RegisterInfo`, which generates the register
 file information for a particular target machine, for use by the LLVM
-target-independent code generator. See :doc:`TableGen Backends <./BackEnds>`
-for a description of the LLVM TableGen backends, and :doc:`TableGen
+target-independent code generator. See {doc}`TableGen Backends <./BackEnds>`
+for a description of the LLVM TableGen backends, and {doc}`TableGen
 Backend Developer's Guide <./BackGuide>` for a guide to writing a new
 backend.
 
 Here are a few of the things backends can do.
 
-* Generate the register file information for a particular target machine.
-
-* Generate the instruction definitions for a target.
-
-* Generate the patterns that the code generator uses to match instructions
+- Generate the register file information for a particular target machine.
+- Generate the instruction definitions for a target.
+- Generate the patterns that the code generator uses to match instructions
   to intermediate representation (IR) nodes.
+- Generate semantic attribute identifiers for Clang.
+- Generate abstract syntax tree (AST) declaration node definitions for Clang.
+- Generate AST statement node definitions for Clang.
 
-* Generate semantic attribute identifiers for Clang.
-
-* Generate abstract syntax tree (AST) declaration node definitions for Clang.
-
-* Generate AST statement node definitions for Clang.
-
-
-Concepts
---------
+### Concepts
 
 TableGen source files contain two primary items: *abstract records* and
 *concrete records*. In this and other TableGen documents, abstract records
@@ -66,16 +58,16 @@ backends will process. Note that TableGen assigns no meaning to fields; the
 meanings are entirely up to the backends and the programs that incorporate
 the output of those backends.
 
-.. note::
-
-  The term "parent class" can refer to a class that is a parent of another
-  class, and also to a class from which a concrete record inherits. This
-  nonstandard use of the term arises because TableGen treats classes and
-  concrete records similarly.
+:::{note}
+The term "parent class" can refer to a class that is a parent of another
+class, and also to a class from which a concrete record inherits. This
+nonstandard use of the term arises because TableGen treats classes and
+concrete records similarly.
+:::
 
 A backend processes some subset of the concrete records built by the
 TableGen parser and emits the output files. These files are usually C++
-``.inc`` files that are included by the programs that require the data in
+`.inc` files that are included by the programs that require the data in
 those records. However, a backend can produce any type of output files. For
 example, it could produce a data file containing messages tagged with
 identifiers and substitution parameters. In a complex use case such as the
@@ -93,14 +85,14 @@ abstracts common "sub-concepts" from the two original concepts.
 In order to make classes more useful, a concrete record (or another class)
 can request a class as a parent class and pass *template arguments* to it.
 These template arguments can be used in the fields of the parent class to
-initialize them in a custom manner. That is, record or class ``A`` can
-request parent class ``S`` with one set of template arguments, while record or class
-``B`` can request ``S`` with a different set of arguments. Without template
+initialize them in a custom manner. That is, record or class `A` can
+request parent class `S` with one set of template arguments, while record or class
+`B` can request `S` with a different set of arguments. Without template
 arguments, many more classes would be required, one for each combination of
 the template arguments.
 
 Both classes and concrete records can include fields that are uninitialized.
-The uninitialized "value" is represented by a question mark (``?``). Classes
+The uninitialized "value" is represented by a question mark (`?`). Classes
 often have uninitialized fields that are expected to be filled in when those
 classes are inherited by concrete records. Even so, some fields of concrete
 records may remain uninitialized.
@@ -111,110 +103,117 @@ multiple concrete records all at once. A multiclass can inherit from other
 multiclasses, which means that the multiclass inherits all the definitions
 from its parent multiclasses.
 
-`Appendix C: Sample Record`_ illustrates a complex record in the Intel X86
+[Appendix C: Sample Record] illustrates a complex record in the Intel X86
 target and the simple way in which it is defined.
 
-Source Files
-============
+## Source Files
 
 TableGen source files are plain ASCII text files. The files can contain
-statements, comments, and blank lines (see `Lexical Analysis`_). The standard file
-extension for TableGen files is ``.td``.
+statements, comments, and blank lines (see [Lexical Analysis]). The standard file
+extension for TableGen files is `.td`.
 
 TableGen files can grow quite large, so there is an include mechanism that
-allows one file to include the content of another file (see `Include
-Files`_). This allows large files to be broken up into smaller ones, and
+allows one file to include the content of another file (see [Include
+Files][include files]). This allows large files to be broken up into smaller ones, and
 also provides a simple library mechanism where multiple source files can
 include the same library file.
 
 TableGen supports a simple preprocessor that can be used to conditionalize
-portions of ``.td`` files. See `Preprocessing Facilities`_ for more
+portions of `.td` files. See [Preprocessing Facilities] for more
 information.
 
-Lexical Analysis
-================
+## Lexical Analysis
 
 The lexical and syntax notation used here is intended to imitate
-`Python's`_ notation. In particular, for lexical definitions, the productions
+[Python's][python's] notation. In particular, for lexical definitions, the productions
 operate at the character level and there is no implied whitespace between
 elements. The syntax definitions operate at the token level, so there is
 implied whitespace between tokens.
 
-.. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation
-
-TableGen supports BCPL-style comments (``// ...``) and nestable C-style
-comments (``/* ... */``).
-TableGen also provides simple `Preprocessing Facilities`_.
+TableGen supports BCPL-style comments (`// ...`) and nestable C-style
+comments (`/* ... */`).
+TableGen also provides simple [Preprocessing Facilities].
 
 Formfeed characters may be used freely in files to produce page breaks when
 the file is printed for review.
 
-The following are the basic punctuation tokens::
+The following are the basic punctuation tokens:
 
-   - + [ ] { } ( ) < > : ; . ... = ? #
+```
+- + [ ] { } ( ) < > : ; . ... = ? #
+```
 
-Literals
---------
+### Literals
 
 Numeric literals take one of the following forms:
 
+```{eval-rst}
 .. productionlist::
    TokInteger: `DecimalInteger` | `HexInteger` | `BinInteger`
    DecimalInteger: ["+" | "-"] ("0"..."9")+
    HexInteger: "0x" ("0"..."9" | "a"..."f" | "A"..."F")+
    BinInteger: "0b" ("0" | "1")+
+```
 
-Observe that the :token:`DecimalInteger` token includes the optional ``+``
-or ``-`` sign, unlike most languages where the sign would be treated as a
+Observe that the {token}`DecimalInteger` token includes the optional `+`
+or `-` sign, unlike most languages where the sign would be treated as a
 unary operator.
 
 TableGen has two kinds of string literals:
 
+```{eval-rst}
 .. productionlist::
    TokString: '"' (non-'"' characters and escapes) '"'
    TokCode: "[{" (text not containing "}]") "}]"
+```
 
-A :token:`TokCode` is nothing more than a multi-line string literal
-delimited by ``[{`` and ``}]``. It can break across lines and the
+A {token}`TokCode` is nothing more than a multi-line string literal
+delimited by `[{` and `}]`. It can break across lines and the
 line breaks are retained in the string.
 
-The current implementation accepts the following escape sequences::
+The current implementation accepts the following escape sequences:
 
-   \\ \' \" \t \n
+```
+\\ \' \" \t \n
+```
 
-Identifiers
------------
+### Identifiers
 
 TableGen has name- and identifier-like tokens, which are case-sensitive.
 
+```{eval-rst}
 .. productionlist::
    ualpha: "a"..."z" | "A"..."Z" | "_"
    TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")*
    TokVarName: "$" `ualpha` (`ualpha` |  "0"..."9")*
+```
 
-Note that, unlike most languages, TableGen allows :token:`TokIdentifier` to
+Note that, unlike most languages, TableGen allows {token}`TokIdentifier` to
 begin with an integer. In case of ambiguity, a token is interpreted as a
 numeric literal rather than an identifier.
 
 TableGen has the following reserved keywords, which cannot be used as
-identifiers::
+identifiers:
 
-   assert     bit           bits          class         code
-   dag        def           dump          else          false
-   foreach    defm          defset        defvar        field
-   if         in            include       int           let
-   list       multiclass    string        then          true
+```
+assert     bit           bits          class         code
+dag        def           dump          else          false
+foreach    defm          defset        defvar        field
+if         in            include       int           let
+list       multiclass    string        then          true
+```
 
-.. warning::
-  The ``field`` reserved word is deprecated, except when used with the
-  CodeEmitterGen backend where it's used to distinguish normal record
-  fields from encoding fields.
+:::{warning}
+The `field` reserved word is deprecated, except when used with the
+CodeEmitterGen backend where it's used to distinguish normal record
+fields from encoding fields.
+:::
 
-Bang operators
---------------
+### Bang operators
 
 TableGen provides "bang operators" that have a wide variety of uses:
 
+```{eval-rst}
 .. productionlist::
    BangOperator: one of
                : !add         !and         !cast         !con         !dag
@@ -228,101 +227,114 @@ TableGen provides "bang operators" that have a wide variety of uses:
                : !setdagname  !setdagop    !setdagopname !shl         !size
                : !sra         !srl         !strconcat    !sub         !subst
                : !substr      !tail        !tolower      !toupper     !xor
+```
 
-The ``!cond`` operator has a slightly different
+The `!cond` operator has a slightly different
 syntax compared to other bang operators, so it is defined separately:
 
+```{eval-rst}
 .. productionlist::
    CondOperator: !cond
+```
 
-See `Appendix A: Bang Operators`_ for a description of each bang operator.
+See [Appendix A: Bang Operators] for a description of each bang operator.
 
-Include files
--------------
+### Include files
 
 TableGen has an include mechanism. The content of the included file
-lexically replaces the ``include`` directive and is then parsed as if it were
+lexically replaces the `include` directive and is then parsed as if it were
 originally in the main file.
 
+```{eval-rst}
 .. productionlist::
    IncludeDirective: "include" `TokString`
+```
 
 Portions of the main file and included files can be conditionalized using
 preprocessor directives.
 
+```{eval-rst}
 .. productionlist::
    PreprocessorDirective: "#define" | "#ifdef" | "#ifndef"
+```
 
-Types
-=====
+## Types
 
 The TableGen language is statically typed, using a simple but complete type
 system. Types are used to check for errors, to perform implicit conversions,
 and to help interface designers constrain the allowed input. Every value is
 required to have an associated type.
 
-TableGen supports a mixture of low-level types (e.g., ``bit``) and
-high-level types (e.g., ``dag``). This flexibility allows you to describe a
+TableGen supports a mixture of low-level types (e.g., `bit`) and
+high-level types (e.g., `dag`). This flexibility allows you to describe a
 wide range of records conveniently and compactly.
 
+```{eval-rst}
 .. productionlist::
    Type: "bit" | "int" | "string" | "dag" | "code"
        :| "bits" "<" `TokInteger` ">"
        :| "list" "<" `Type` ">"
        :| `ClassID`
    ClassID: `TokIdentifier`
+```
+
+`bit`
+
+: A `bit` is a boolean value that can be 0 or 1.
+
+`int`
+
+: The `int` type represents a simple 64-bit integer value, such as 5 or
+  -42.
+
+`string`
+
+: The `string` type represents an ordered sequence of characters of arbitrary
+  length.
+
+`code`
+
+: The keyword `code` is an alias for `string` which may be used to
+  indicate string values that are code.
+
+`bits<`*n*`>`
+
+: The `bits` type is a fixed-sized integer of arbitrary length *n* that
+  is treated as separate bits. These bits can be accessed individually.
+  A field of this type is useful for representing an instruction operation
+  code, register number, or address mode/register/displacement. The bits of
+  the field can be set individually or as subfields. For example, in an
+  instruction address, the addressing mode, base register number, and
+  displacement can be set separately.
+
+`list<`*type*`>`
+
+: This type represents a list whose elements are of the *type* specified in
+  angle brackets. The element type is arbitrary; it can even be another
+  list type. List elements are indexed from 0.
 
-``bit``
-    A ``bit`` is a boolean value that can be 0 or 1.
-
-``int``
-    The ``int`` type represents a simple 64-bit integer value, such as 5 or
-    -42.
-
-``string``
-    The ``string`` type represents an ordered sequence of characters of arbitrary
-    length.
-
-``code``
-    The keyword ``code`` is an alias for ``string`` which may be used to
-    indicate string values that are code.
-
-``bits<``\ *n*\ ``>``
-    The ``bits`` type is a fixed-sized integer of arbitrary length *n* that
-    is treated as separate bits. These bits can be accessed individually.
-    A field of this type is useful for representing an instruction operation
-    code, register number, or address mode/register/displacement.  The bits of
-    the field can be set individually or as subfields. For example, in an
-    instruction address, the addressing mode, base register number, and
-    displacement can be set separately.
-
-``list<``\ *type*\ ``>``
-    This type represents a list whose elements are of the *type* specified in
-    angle brackets. The element type is arbitrary; it can even be another
-    list type. List elements are indexed from 0.
-
-``dag``
-    This type represents a nestable directed acyclic graph (DAG) of nodes.
-    Each node has an *operator* and zero or more *arguments* (or *operands*).
-    An argument can be
-    another ``dag`` object, allowing an arbitrary tree of nodes and edges.
-    As an example, DAGs are used to represent code patterns for use by
-    the code generator instruction selection algorithms. See `Directed
-    acyclic graphs (DAGs)`_ for more details;
-
-:token:`ClassID`
-    Specifying a class name in a type context indicates
-    that the type of the defined value must
-    be a subclass of the specified class. This is useful in conjunction with
-    the ``list`` type; for example, to constrain the elements of the list to a
-    common base class (e.g., a ``list<Register>`` can only contain definitions
-    derived from the ``Register`` class).
-    The :token:`ClassID` must name a class that has been previously
-    declared or defined.
-
-
-Values and Expressions
-======================
+`dag`
+
+: This type represents a nestable directed acyclic graph (DAG) of nodes.
+  Each node has an *operator* and zero or more *arguments* (or *operands*).
+  An argument can be
+  another `dag` object, allowing an arbitrary tree of nodes and edges.
+  As an example, DAGs are used to represent code patterns for use by
+  the code generator instruction selection algorithms. See [Directed
+  acyclic graphs (DAGs)][directed acyclic graphs (dags)] for more details;
+
+{token}`ClassID`
+
+: Specifying a class name in a type context indicates
+  that the type of the defined value must
+  be a subclass of the specified class. This is useful in conjunction with
+  the `list` type; for example, to constrain the elements of the list to a
+  common base class (e.g., a `list<Register>` can only contain definitions
+  derived from the `Register` class).
+  The {token}`ClassID` must name a class that has been previously
+  declared or defined.
+
+## Values and Expressions
 
 There are many contexts in TableGen statements where a value is required. A
 common example is in the definition of a record, where each field is
@@ -332,9 +344,10 @@ allow the TableGen file to be written in a syntax that is natural for the
 application.
 
 Note that all of the values have rules for converting them from one type to
-another. For example, these rules allow you to assign a value like ``7``
-to an entity of type ``bits<4>``.
+another. For example, these rules allow you to assign a value like `7`
+to an entity of type `bits<4>`.
 
+```{eval-rst}
 .. productionlist::
    Value: `SimpleValue` `ValueSuffix`*
         :| `Value` "#" [`Value`]
@@ -351,19 +364,21 @@ to an entity of type ``bits<4>``.
                :| `Value` "..." `Value`
                :| `Value` "-" `Value`
                :| `Value` `TokInteger`
+```
 
-.. warning::
-  The peculiar last form of :token:`RangePiece` and :token:`SliceElement` is
-  due to the fact that the "``-``" is included in the :token:`TokInteger`,
-  hence ``1-5`` gets lexed as two consecutive tokens, with values ``1`` and
-  ``-5``, instead of "1", "-", and "5".
-  The use of hyphen as the range punctuation is deprecated.
+:::{warning}
+The peculiar last form of {token}`RangePiece` and {token}`SliceElement` is
+due to the fact that the "`-`" is included in the {token}`TokInteger`,
+hence `1-5` gets lexed as two consecutive tokens, with values `1` and
+`-5`, instead of "1", "-", and "5".
+The use of hyphen as the range punctuation is deprecated.
+:::
 
-Simple values
--------------
+### Simple values
 
-The :token:`SimpleValue` has a number of forms.
+The {token}`SimpleValue` has a number of forms.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue: `SimpleValue1`
               :| `SimpleValue2`
@@ -375,192 +390,226 @@ The :token:`SimpleValue` has a number of forms.
               :| `SimpleValue8`
               :| `SimpleValue9`
    SimpleValue1: `TokInteger` | `TokString`+ | `TokCode`
+```
 
 A value can be an integer literal, a string literal, or a code literal.
 Multiple adjacent string literals are concatenated as in C/C++; the simple
 value is the concatenation of the strings. Code literals become strings and
 are then indistinguishable from them.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue2: "true" | "false"
+```
 
-The ``true`` and ``false`` literals are essentially syntactic sugar for the
+The `true` and `false` literals are essentially syntactic sugar for the
 integer values 1 and 0. They improve the readability of TableGen files when
-boolean values are used in field initializations, bit sequences, ``if``
+boolean values are used in field initializations, bit sequences, `if`
 statements, etc. When parsed, these literals are converted to integers.
 
-.. note::
-
-  Although ``true`` and ``false`` are literal names for 1 and 0, we
-  recommend as a stylistic rule that you use them for boolean
-  values only.
+:::{note}
+Although `true` and `false` are literal names for 1 and 0, we
+recommend as a stylistic rule that you use them for boolean
+values only.
+:::
 
+```{eval-rst}
 .. productionlist::
    SimpleValue3: "?"
+```
 
 A question mark represents an uninitialized value.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue4: "{" [`ValueList`] "}"
    ValueList: `ValueListNE`
    ValueListNE: `Value` ("," `Value`)*
+```
 
 This value represents a sequence of bits, which can be used to initialize a
-``bits<``\ *n*\ ``>`` field (note the braces). When doing so, the values
+`bits<`*n*`>` field (note the braces). When doing so, the values
 must represent a total of *n* bits.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue5: "[" `ValueList` "]" ["<" `Type` ">"]
+```
 
 This value is a list initializer (note the brackets). The values in brackets
-are the elements of the list. The optional :token:`Type` can be used to
+are the elements of the list. The optional {token}`Type` can be used to
 indicate a specific element type; otherwise the element type is inferred
 from the given values. TableGen can usually infer the type, although
-sometimes not when the value is the empty list (``[]``).
+sometimes not when the value is the empty list (`[]`).
 
+```{eval-rst}
 .. productionlist::
    SimpleValue6: "(" `DagArg` [`DagArgList`] ")"
    DagArgList: `DagArg` ("," `DagArg`)*
    DagArg: `Value` [":" `TokVarName`] | `TokVarName`
+```
 
-This represents a DAG initializer (note the parentheses).  The first
-:token:`DagArg` is called the "operator" of the DAG and must be a record.
-See `Directed acyclic graphs (DAGs)`_ for more details.
+This represents a DAG initializer (note the parentheses). The first
+{token}`DagArg` is called the "operator" of the DAG and must be a record.
+See [Directed acyclic graphs (DAGs)] for more details.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue7: `TokIdentifier`
+```
 
 The resulting value is the value of the entity named by the identifier. The
 possible identifiers are described here, but the descriptions will make more
 sense after reading the remainder of this guide.
 
-.. The code for this is exceptionally abstruse. These examples are a
-   best-effort attempt.
+% The code for this is exceptionally abstruse. These examples are a
+% best-effort attempt.
 
-* A template argument of a ``class``, such as the use of ``Bar`` in::
+- A template argument of a `class`, such as the use of `Bar` in:
 
-     class Foo <int Bar> {
-       int Baz = Bar;
-     }
+  ```
+  class Foo <int Bar> {
+    int Baz = Bar;
+  }
+  ```
 
-* The implicit template argument ``NAME`` in a ``class`` or ``multiclass``
-  definition (see `NAME`_).
+- The implicit template argument `NAME` in a `class` or `multiclass`
+  definition (see [NAME]).
 
-* A field local to a ``class``, such as the use of ``Bar`` in::
+- A field local to a `class`, such as the use of `Bar` in:
 
-     class Foo {
-       int Bar = 5;
-       int Baz = Bar;
-     }
+  ```
+  class Foo {
+    int Bar = 5;
+    int Baz = Bar;
+  }
+  ```
 
-* The name of a record definition, such as the use of ``Bar`` in the
-  definition of ``Foo``::
+- The name of a record definition, such as the use of `Bar` in the
+  definition of `Foo`:
 
-     def Bar : SomeClass {
-       int X = 5;
-     }
+  ```
+  def Bar : SomeClass {
+    int X = 5;
+  }
 
-     def Foo {
-       SomeClass Baz = Bar;
-     }
+  def Foo {
+    SomeClass Baz = Bar;
+  }
+  ```
 
-* A field local to a record definition, such as the use of ``Bar`` in::
+- A field local to a record definition, such as the use of `Bar` in:
 
-     def Foo {
-       int Bar = 5;
-       int Baz = Bar;
-     }
+  ```
+  def Foo {
+    int Bar = 5;
+    int Baz = Bar;
+  }
+  ```
 
   Fields inherited from the record's parent classes can be accessed the same way.
 
-* A template argument of a ``multiclass``, such as the use of ``Bar`` in::
+- A template argument of a `multiclass`, such as the use of `Bar` in:
 
-     multiclass Foo <int Bar> {
-       def : SomeClass<Bar>;
-     }
+  ```
+  multiclass Foo <int Bar> {
+    def : SomeClass<Bar>;
+  }
+  ```
 
-* A variable defined with the ``defvar`` or ``defset`` statements.
+- A variable defined with the `defvar` or `defset` statements.
 
-* The iteration variable of a ``foreach``, such as the use of ``i`` in::
+- The iteration variable of a `foreach`, such as the use of `i` in:
 
-     foreach i = 0...5 in
-       def Foo#i;
+  ```
+  foreach i = 0...5 in
+    def Foo#i;
+  ```
 
+```{eval-rst}
 .. productionlist::
    SimpleValue8: `ClassID` "<" `ArgValueList` ">"
+```
 
 This form creates a new anonymous record definition (as would be created by an
-unnamed ``def`` inheriting from the given class with the given template
-arguments; see `def`_) and the value is that record. A field of the record can be
-obtained using a suffix; see `Suffixed Values`_.
+unnamed `def` inheriting from the given class with the given template
+arguments; see [def]) and the value is that record. A field of the record can be
+obtained using a suffix; see [Suffixed Values].
 
 Invoking a class in this manner can provide a simple subroutine facility.
-See `Using Classes as Subroutines`_ for more information.
+See [Using Classes as Subroutines] for more information.
 
+```{eval-rst}
 .. productionlist::
    SimpleValue9: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")"
               :| `CondOperator` "(" `CondClause` ("," `CondClause`)* ")"
    CondClause: `Value` ":" `Value`
+```
 
 The bang operators provide functions that are not available with the other
-simple values. Except in the case of ``!cond``, a bang operator takes a list
+simple values. Except in the case of `!cond`, a bang operator takes a list
 of arguments enclosed in parentheses and performs some function on those
-arguments, producing a value for that bang operator. The ``!cond`` operator
-takes a list of pairs of arguments separated by colons. See `Appendix A:
-Bang Operators`_ for a description of each bang operator.
+arguments, producing a value for that bang operator. The `!cond` operator
+takes a list of pairs of arguments separated by colons. See [Appendix A:
+Bang Operators][appendix a: bang operators] for a description of each bang operator.
 
 The `Type` is only accepted for certain bang operators, and must not be
-``code``.
+`code`.
 
-Suffixed values
----------------
+### Suffixed values
 
-The :token:`SimpleValue` values described above can be specified with
+The {token}`SimpleValue` values described above can be specified with
 certain suffixes. The purpose of a suffix is to obtain a subvalue of the
 primary value. Here are the possible suffixes for some primary *value*.
 
-*value*\ ``{17}``
-    The final value is bit 17 of the integer *value* (note the braces).
+*value*`{17}`
+
+: The final value is bit 17 of the integer *value* (note the braces).
+
+*value*`{8...15}`
+
+: The final value is bits 8--15 of the integer *value*. The order of the
+  bits can be reversed by specifying `{15...8}`.
+
+*value*`[i]`
 
-*value*\ ``{8...15}``
-    The final value is bits 8--15 of the integer *value*. The order of the
-    bits can be reversed by specifying ``{15...8}``.
+: The final value is element `i` of the list *value* (note the brackets).
+  In other words, the brackets act as a subscripting operator on the list.
+  This is the case only when a single element is specified.
 
-*value*\ ``[i]``
-    The final value is element `i` of the list *value* (note the brackets).
-    In other words, the brackets act as a subscripting operator on the list.
-    This is the case only when a single element is specified.
+*value*`[i,]`
 
-*value*\ ``[i,]``
-    The final value is a list that contains a single element `i` of the list.
-    In short, a list slice with a single element.
+: The final value is a list that contains a single element `i` of the list.
+  In short, a list slice with a single element.
 
-*value*\ ``[4...7,17,2...3,4]``
-    The final value is a new list that is a slice of the list *value*.
-    The new list contains elements 4, 5, 6, 7, 17, 2, 3, and 4.
-    Elements may be included multiple times and in any order. This is the result
-    only when more than one element is specified.
+*value*`[4...7,17,2...3,4]`
 
-    *value*\ ``[i,m...n,j,ls]``
-        Each element may be an expression (variables, bang operators).
-        The type of `m` and `n` should be `int`.
-        The type of `i`, `j`, and `ls` should be either `int` or `list<int>`.
+: The final value is a new list that is a slice of the list *value*.
+  The new list contains elements 4, 5, 6, 7, 17, 2, 3, and 4.
+  Elements may be included multiple times and in any order. This is the result
+  only when more than one element is specified.
 
-*value*\ ``.``\ *field*
-    The final value is the value of the specified *field* in the specified
-    record *value*.
+  *value*`[i,m...n,j,ls]`
 
-The paste operator
-------------------
+  : Each element may be an expression (variables, bang operators).
+    The type of `m` and `n` should be `int`.
+    The type of `i`, `j`, and `ls` should be either `int` or `list<int>`.
 
-The paste operator (``#``) is the only infix operator available in TableGen
+*value*`.`*field*
+
+: The final value is the value of the specified *field* in the specified
+  record *value*.
+
+### The paste operator
+
+The paste operator (`#`) is the only infix operator available in TableGen
 expressions. It allows you to concatenate strings or lists, but has a few
 unusual features.
 
 The paste operator can be used when specifying the record name in a
-:token:`Def` or :token:`Defm` statement, in which case it must construct a
-string. If an operand is an undefined name (:token:`TokIdentifier`) or the
-name of a global :token:`Defvar` or :token:`Defset`, it is treated as a
+{token}`Def` or {token}`Defm` statement, in which case it must construct a
+string. If an operand is an undefined name ({token}`TokIdentifier`) or the
+name of a global {token}`Defvar` or {token}`Defset`, it is treated as a
 verbatim string of characters. The value of a global name is not used.
 
 The paste operator can be used in all other value expressions, in which case
@@ -572,78 +621,78 @@ left-hand-side operand is treated normally.
 Values can have a trailing paste operator, in which case the left-hand-side
 operand is concatenated to an empty string.
 
-`Appendix B: Paste Operator Examples`_ presents examples of the behavior of
+[Appendix B: Paste Operator Examples] presents examples of the behavior of
 the paste operator.
 
-Statements
-==========
+## Statements
 
 The following statements may appear at the top level of TableGen source
 files.
 
+```{eval-rst}
 .. productionlist::
    TableGenFile: (`Statement` | `IncludeDirective`
             :| `PreprocessorDirective`)*
    Statement: `Assert` | `Class` | `Def` | `Defm` | `Defset` | `Deftype`
             :| `Defvar` | `Dump`  | `Foreach` | `If` | `Let` | `MultiClass`
+```
 
 The following sections describe each of these top-level statements.
 
+### `class` --- define an abstract record class
 
-``class`` --- define an abstract record class
----------------------------------------------
-
-A ``class`` statement defines an abstract record class from which other
+A `class` statement defines an abstract record class from which other
 classes and records can inherit.
 
+```{eval-rst}
 .. productionlist::
    Class: "class" `ClassID` [`TemplateArgList`] `RecordBody`
    TemplateArgList: "<" `TemplateArgDecl` ("," `TemplateArgDecl`)* ">"
    TemplateArgDecl: `Type` `TokIdentifier` ["=" `Value`]
+```
 
 A class can be parameterized by a list of "template arguments," whose values
 can be used in the class's record body. These template arguments are
 specified each time the class is inherited by another class or record.
 
-If a template argument is not assigned a default value with ``=``, it is
-uninitialized (has the "value" ``?``) and must be specified in the template
+If a template argument is not assigned a default value with `=`, it is
+uninitialized (has the "value" `?`) and must be specified in the template
 argument list when the class is inherited (required argument). If an
 argument is assigned a default value, then it need not be specified in the
 argument list (optional argument). In the declaration, all required template
 arguments must precede any optional arguments. The template argument default
 values are evaluated from left to right.
 
-The :token:`RecordBody` is defined below. It can include a list of
+The {token}`RecordBody` is defined below. It can include a list of
 parent classes from which the current class inherits, along with field
-definitions and other statements. When a class ``C`` inherits from another
-class ``D``, the fields of ``D`` are effectively merged into the fields of
-``C``.
+definitions and other statements. When a class `C` inherits from another
+class `D`, the fields of `D` are effectively merged into the fields of
+`C`.
 
-A given class can only be defined once. A ``class`` statement is
+A given class can only be defined once. A `class` statement is
 considered to define the class if *any* of the following are true (the
-:token:`RecordBody` elements are described below).
+{token}`RecordBody` elements are described below).
 
-* The :token:`TemplateArgList` is present, or
-* The :token:`ParentClassList` in the :token:`RecordBody` is present, or
-* The :token:`Body` in the :token:`RecordBody` is present and not empty.
+- The {token}`TemplateArgList` is present, or
+- The {token}`ParentClassList` in the {token}`RecordBody` is present, or
+- The {token}`Body` in the {token}`RecordBody` is present and not empty.
 
-You can declare an empty class by specifying an empty :token:`TemplateArgList`
-and an empty :token:`RecordBody`. This can serve as a restricted form of
+You can declare an empty class by specifying an empty {token}`TemplateArgList`
+and an empty {token}`RecordBody`. This can serve as a restricted form of
 forward declaration. Note that records derived from a forward-declared
 class will inherit no fields from it, because those records are built when
 their declarations are parsed, and thus before the class is finally defined.
 
-.. _NAME:
+(name)=
 
-Every class has an implicit template argument named ``NAME`` (uppercase),
-which is bound to the name of the :token:`Def` or :token:`Defm` inheriting
+Every class has an implicit template argument named `NAME` (uppercase),
+which is bound to the name of the {token}`Def` or {token}`Defm` inheriting
 from the class. If the class is inherited by an anonymous record, the name
 is unspecified but globally unique.
 
-See `Examples: classes and records`_ for examples.
+See [Examples: classes and records] for examples.
 
-Record Bodies
-`````````````
+#### Record Bodies
 
 Record bodies appear in both class and record definitions. A record body can
 include a parent class list, which specifies the classes from which the
@@ -652,6 +701,7 @@ parent classes of the class or record. The record body also
 includes the main body of the definition, which contains the specification
 of the fields of the class or record.
 
+```{eval-rst}
 .. productionlist::
    RecordBody: `ParentClassList` `Body`
    ParentClassList: [":" `ParentClassListNE`]
@@ -660,20 +710,21 @@ of the fields of the class or record.
    ArgValueList: `PostionalArgValueList` [","] `NamedArgValueList`
    PostionalArgValueList: [`Value` {"," `Value`}*]
    NamedArgValueList: [`NameValue` "=" `Value` {"," `NameValue` "=" `Value`}*]
+```
 
-A :token:`ParentClassList` containing a :token:`MultiClassID` is valid only
-in the class list of a ``defm`` statement. In that case, the ID must be the
+A {token}`ParentClassList` containing a {token}`MultiClassID` is valid only
+in the class list of a `defm` statement. In that case, the ID must be the
 name of a multiclass.
 
 The argument values can be specified in two forms:
 
-* Positional argument (``value``). The value is assigned to the argument in the
-  corresponding position. For ``Foo<a0, a1>``, ``a0`` will be assigned to the first
-  argument and ``a1`` will be assigned to the second argument.
-* Named argument (``name=value``). The value is assigned to the argument with
-  the specified name. For ``Foo<a=a0, b=a1>``, ``a0`` will be assigned to the
-  argument with name ``a`` and ``a1`` will be assigned to the argument with
-  name ``b``.
+- Positional argument (`value`). The value is assigned to the argument in the
+  corresponding position. For `Foo<a0, a1>`, `a0` will be assigned to the first
+  argument and `a1` will be assigned to the second argument.
+- Named argument (`name=value`). The value is assigned to the argument with
+  the specified name. For `Foo<a=a0, b=a1>`, `a0` will be assigned to the
+  argument with name `a` and `a1` will be assigned to the argument with
+  name `b`.
 
 Required arguments can also be specified as a named argument.
 
@@ -681,6 +732,7 @@ Note that the argument can only be specified once regardless of the way (named
 or positional) to specify and positional arguments should precede named
 arguments.
 
+```{eval-rst}
 .. productionlist::
    Body: ";" | "{" `BodyItem`* "}"
    BodyItem: `Type` `TokIdentifier` ["=" `Value`] ";"
@@ -688,9 +740,10 @@ arguments.
            :| "defvar" `TokIdentifier` "=" `Value` ";"
            :| `Assert`
    LetMode: "append" | "prepend"
+```
 
-Note that ``append`` and ``prepend`` are context-sensitive keywords: they are
-only recognized as modifiers immediately after ``let``. In all other positions,
+Note that `append` and `prepend` are context-sensitive keywords: they are
+only recognized as modifiers immediately after `let`. In all other positions,
 they remain valid identifiers (e.g., usable as field names).
 
 A field definition in the body specifies a field to be included in the class
@@ -698,77 +751,77 @@ or record. If no initial value is specified, then the field's value is
 uninitialized. The type must be specified; TableGen will not infer it from
 the value.
 
-The ``let`` form is used to reset a field to a new value. This can be done
+The `let` form is used to reset a field to a new value. This can be done
 for fields defined directly in the body or fields inherited from parent
-classes.  A :token:`RangeList` can be specified to reset certain bits in a
-``bit<n>`` field.
+classes. A {token}`RangeList` can be specified to reset certain bits in a
+`bit<n>` field.
 
-The ``let append`` and ``let prepend`` forms concatenate a value with the
-field's current value instead of replacing it. For ``append``, the new value
-is added after the current value; for ``prepend``, it is added before. The
+The `let append` and `let prepend` forms concatenate a value with the
+field's current value instead of replacing it. For `append`, the new value
+is added after the current value; for `prepend`, it is added before. The
 supported types and concatenation operators are:
 
-* ``list<T>``: uses ``!listconcat``
-* ``string`` / ``code``: uses ``!strconcat``
-* ``dag``: uses ``!con``
+- `list<T>`: uses `!listconcat`
+- `string` / `code`: uses `!strconcat`
+- `dag`: uses `!con`
 
-If the field is currently unset (``?``), ``let append`` and ``let prepend``
+If the field is currently unset (`?`), `let append` and `let prepend`
 simply set the value directly. This is useful for accumulating values across
 a class hierarchy:
 
-.. code-block:: text
-
-  class Base {
-    list<int> items = [2, 3];
-  }
-  class Middle : Base {
-    let append items = [4];       // items = [2, 3, 4]
-  }
-  def Concrete : Middle {
-    let prepend items = [1];      // items = [1, 2, 3, 4]
-  }
-
-A plain ``let`` (without ``append``/``prepend``) always replaces the current
+```text
+class Base {
+  list<int> items = [2, 3];
+}
+class Middle : Base {
+  let append items = [4];       // items = [2, 3, 4]
+}
+def Concrete : Middle {
+  let prepend items = [1];      // items = [1, 2, 3, 4]
+}
+```
+
+A plain `let` (without `append`/`prepend`) always replaces the current
 value, which can be used to opt out of accumulated values.
 
-The ``defvar`` form defines a variable whose value can be used in other
+The `defvar` form defines a variable whose value can be used in other
 value expressions within the body. The variable is not a field: it does not
 become a field of the class or record being defined. Variables are provided
-to hold temporary values while processing the body. See `Defvar in a Record
-Body`_ for more details.
-
-When class ``C2`` inherits from class ``C1``, it acquires all the field
-definitions of ``C1``. As those definitions are merged into class ``C2``, any
-template arguments passed to ``C1`` by ``C2`` are substituted into the
-definitions. In other words, the abstract record fields defined by ``C1`` are
-expanded with the template arguments before being merged into ``C2``.
+to hold temporary values while processing the body. See [Defvar in a Record
+Body][defvar in a record body] for more details.
 
+When class `C2` inherits from class `C1`, it acquires all the field
+definitions of `C1`. As those definitions are merged into class `C2`, any
+template arguments passed to `C1` by `C2` are substituted into the
+definitions. In other words, the abstract record fields defined by `C1` are
+expanded with the template arguments before being merged into `C2`.
 
-.. _def:
+(def)=
 
-``def`` --- define a concrete record
-------------------------------------
+### `def` --- define a concrete record
 
-A ``def`` statement defines a new concrete record.
+A `def` statement defines a new concrete record.
 
+```{eval-rst}
 .. productionlist::
    Def: "def" [`NameValue`] `RecordBody`
    NameValue: `Value` (parsed in a special mode)
+```
 
 The name value is optional. If specified, it is parsed in a special mode
 where undefined (unrecognized) identifiers are interpreted as literal
 strings. In particular, global identifiers are considered unrecognized.
-These include global variables defined by ``defvar`` and ``defset``. A
+These include global variables defined by `defvar` and `defset`. A
 record name can be the null string.
 
 If no name value is given, the record is *anonymous*. The final name of an
 anonymous record is unspecified but globally unique.
 
-Special handling occurs if a ``def`` appears inside a ``multiclass``
-statement. See the ``multiclass`` section below for details.
+Special handling occurs if a `def` appears inside a `multiclass`
+statement. See the `multiclass` section below for details.
 
 A record can inherit from one or more classes by specifying the
-:token:`ParentClassList` clause at the beginning of its record body. All of
+{token}`ParentClassList` clause at the beginning of its record body. All of
 the fields in the parent classes are added to the record. If two or more
 parent classes provide the same field, the record ends up with the field value
 of the last parent class.
@@ -776,47 +829,45 @@ of the last parent class.
 As a special case, the name of a record can be passed as a template argument
 to that record's parent classes. For example:
 
-.. code-block:: text
+```text
+class A <dag d> {
+  dag the_dag = d;
+}
 
-  class A <dag d> {
-    dag the_dag = d;
-  }
-
-  def rec1 : A<(ops rec1)>;
-
-The DAG ``(ops rec1)`` is passed as a template argument to class ``A``. Notice
-that the DAG includes ``rec1``, the record being defined.
+def rec1 : A<(ops rec1)>;
+```
 
-The steps taken to create a new record are somewhat complex. See `How
-records are built`_.
+The DAG `(ops rec1)` is passed as a template argument to class `A`. Notice
+that the DAG includes `rec1`, the record being defined.
 
-See `Examples: classes and records`_ for examples.
+The steps taken to create a new record are somewhat complex. See [How
+records are built][how records are built].
 
+See [Examples: classes and records] for examples.
 
-Examples: classes and records
------------------------------
+### Examples: classes and records
 
 Here is a simple TableGen file with one class and two record definitions.
 
-.. code-block:: text
-
-  class C {
-    bit V = true;
-  }
+```text
+class C {
+  bit V = true;
+}
 
-  def X : C;
-  def Y : C {
-    let V = false;
-    string Greeting = "Hello!";
-  }
+def X : C;
+def Y : C {
+  let V = false;
+  string Greeting = "Hello!";
+}
+```
 
-First, the abstract class ``C`` is defined. It has one field named ``V``
+First, the abstract class `C` is defined. It has one field named `V`
 that is a bit initialized to true.
 
-Next, two records are defined, derived from class ``C``; that is, with ``C``
-as their parent class. Thus they both inherit the ``V`` field. Record ``Y``
-also defines another string field, ``Greeting``, which is initialized to
-``"Hello!"``. In addition, ``Y`` overrides the inherited ``V`` field,
+Next, two records are defined, derived from class `C`; that is, with `C`
+as their parent class. Thus they both inherit the `V` field. Record `Y`
+also defines another string field, `Greeting`, which is initialized to
+`"Hello!"`. In addition, `Y` overrides the inherited `V` field,
 setting it to false.
 
 A class is useful for isolating the common features of multiple records in
@@ -828,766 +879,767 @@ nonparameterized ones. Parameterized classes specify a list of variable
 declarations, which may optionally have defaults, that are bound when the
 class is specified as a parent class of another class or record.
 
-.. code-block:: text
-
-  class FPFormat <bits<3> val> {
-    bits<3> Value = val;
-  }
-
-  def NotFP      : FPFormat<0>;
-  def ZeroArgFP  : FPFormat<1>;
-  def OneArgFP   : FPFormat<2>;
-  def OneArgFPRW : FPFormat<3>;
-  def TwoArgFP   : FPFormat<4>;
-  def CompareFP  : FPFormat<5>;
-  def CondMovFP  : FPFormat<6>;
-  def SpecialFP  : FPFormat<7>;
-
-The purpose of the ``FPFormat`` class is to act as a sort of enumerated
-type. It provides a single field, ``Value``, which holds a 3-bit number. Its
-template argument, ``val``, is used to set the ``Value`` field.  Each of the
-eight records is defined with ``FPFormat`` as its parent class. The
+```text
+class FPFormat <bits<3> val> {
+  bits<3> Value = val;
+}
+
+def NotFP      : FPFormat<0>;
+def ZeroArgFP  : FPFormat<1>;
+def OneArgFP   : FPFormat<2>;
+def OneArgFPRW : FPFormat<3>;
+def TwoArgFP   : FPFormat<4>;
+def CompareFP  : FPFormat<5>;
+def CondMovFP  : FPFormat<6>;
+def SpecialFP  : FPFormat<7>;
+```
+
+The purpose of the `FPFormat` class is to act as a sort of enumerated
+type. It provides a single field, `Value`, which holds a 3-bit number. Its
+template argument, `val`, is used to set the `Value` field. Each of the
+eight records is defined with `FPFormat` as its parent class. The
 enumeration value is passed in angle brackets as the template argument. Each
-record will inherit the ``Value`` field with the appropriate enumeration
+record will inherit the `Value` field with the appropriate enumeration
 value.
 
 Here is a more complex example of classes with template arguments. First, we
-define a class similar to the ``FPFormat`` class above. It takes a template
-argument and uses it to initialize a field named ``Value``. Then we define
-four records that inherit the ``Value`` field with its four different
+define a class similar to the `FPFormat` class above. It takes a template
+argument and uses it to initialize a field named `Value`. Then we define
+four records that inherit the `Value` field with its four different
 integer values.
 
-.. code-block:: text
-
-  class ModRefVal <bits<2> val> {
-    bits<2> Value = val;
-  }
+```text
+class ModRefVal <bits<2> val> {
+  bits<2> Value = val;
+}
 
-  def None   : ModRefVal<0>;
-  def Mod    : ModRefVal<1>;
-  def Ref    : ModRefVal<2>;
-  def ModRef : ModRefVal<3>;
+def None   : ModRefVal<0>;
+def Mod    : ModRefVal<1>;
+def Ref    : ModRefVal<2>;
+def ModRef : ModRefVal<3>;
+```
 
 This is somewhat contrived, but let's say we would like to examine the two
-bits of the ``Value`` field independently. We can define a class that
-accepts a ``ModRefVal`` record as a template argument and splits up its
+bits of the `Value` field independently. We can define a class that
+accepts a `ModRefVal` record as a template argument and splits up its
 value into two fields, one bit each. Then we can define records that inherit from
-``ModRefBits`` and so acquire two fields from it, one for each bit in the
-``ModRefVal`` record passed as the template argument.
-
-.. code-block:: text
-
-  class ModRefBits <ModRefVal mrv> {
-    // Break the value up into its bits, which can provide a nice
-    // interface to the ModRefVal values.
-    bit isMod = mrv.Value{0};
-    bit isRef = mrv.Value{1};
-  }
-
-  // Example uses.
-  def foo   : ModRefBits<Mod>;
-  def bar   : ModRefBits<Ref>;
-  def snork : ModRefBits<ModRef>;
+`ModRefBits` and so acquire two fields from it, one for each bit in the
+`ModRefVal` record passed as the template argument.
+
+```text
+class ModRefBits <ModRefVal mrv> {
+  // Break the value up into its bits, which can provide a nice
+  // interface to the ModRefVal values.
+  bit isMod = mrv.Value{0};
+  bit isRef = mrv.Value{1};
+}
+
+// Example uses.
+def foo   : ModRefBits<Mod>;
+def bar   : ModRefBits<Ref>;
+def snork : ModRefBits<ModRef>;
+```
 
 This illustrates how one class can be defined to reorganize the
 fields in another class, thus hiding the internal representation of that
 other class.
 
-Running ``llvm-tblgen`` on the example prints the following definitions:
-
-.. code-block:: text
-
-  def bar {      // Value
-    bit isMod = 0;
-    bit isRef = 1;
-  }
-  def foo {      // Value
-    bit isMod = 1;
-    bit isRef = 0;
-  }
-  def snork {      // Value
-    bit isMod = 1;
-    bit isRef = 1;
-  }
-
-``let`` --- override fields in classes or records
--------------------------------------------------
-
-A ``let`` statement collects a set of field values (sometimes called
+Running `llvm-tblgen` on the example prints the following definitions:
+
+```text
+def bar {      // Value
+  bit isMod = 0;
+  bit isRef = 1;
+}
+def foo {      // Value
+  bit isMod = 1;
+  bit isRef = 0;
+}
+def snork {      // Value
+  bit isMod = 1;
+  bit isRef = 1;
+}
+```
+
+### `let` --- override fields in classes or records
+
+A `let` statement collects a set of field values (sometimes called
 *bindings*) and applies them to all the classes and records defined by
-statements within the scope of the ``let``.
+statements within the scope of the `let`.
 
+```{eval-rst}
 .. productionlist::
    Let:  "let" `LetList` "in" "{" `Statement`* "}"
       :| "let" `LetList` "in" `Statement`
    LetList: `LetItem` ("," `LetItem`)*
    LetItem: [`LetMode`] `TokIdentifier` [`RangeList`] "=" `Value`
+```
 
-The ``let`` statement establishes a scope, which is a sequence of statements
+The `let` statement establishes a scope, which is a sequence of statements
 in braces or a single statement with no braces. The bindings in the
-:token:`LetList` apply to the statements in that scope.
+{token}`LetList` apply to the statements in that scope.
 
-The field names in the :token:`LetList` must name fields in classes inherited by
+The field names in the {token}`LetList` must name fields in classes inherited by
 the classes and records defined in the statements. The field values are
 applied to the classes and records *after* the records inherit all the fields from
-their parent classes. So the ``let`` acts to override inherited field
-values. A ``let`` cannot override the value of a template argument.
+their parent classes. So the `let` acts to override inherited field
+values. A `let` cannot override the value of a template argument.
 
-Top-level ``let`` statements are often useful when a few fields need to be
-overridden in several records. Here are two examples. Note that ``let``
+Top-level `let` statements are often useful when a few fields need to be
+overridden in several records. Here are two examples. Note that `let`
 statements can be nested.
 
-.. code-block:: text
-
-  let isTerminator = true, isReturn = true, isBarrier = true, hasCtrlDep = true in
-    def RET : I<0xC3, RawFrm, (outs), (ins), "ret", [(X86retflag 0)]>;
-
-  let isCall = true in
-    // All calls clobber the non-callee saved registers...
-    let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
-                MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, XMM0, XMM1, XMM2,
-                XMM3, XMM4, XMM5, XMM6, XMM7, EFLAGS] in {
-      def CALLpcrel32 : Ii32<0xE8, RawFrm, (outs), (ins i32imm:$dst, variable_ops),
-                             "call\t${dst:call}", []>;
-      def CALL32r     : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
-                          "call\t{*}$dst", [(X86call GR32:$dst)]>;
-      def CALL32m     : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops),
-                          "call\t{*}$dst", []>;
-    }
-
-Note that a top-level ``let`` will not override fields defined in the classes or records
+```text
+let isTerminator = true, isReturn = true, isBarrier = true, hasCtrlDep = true in
+  def RET : I<0xC3, RawFrm, (outs), (ins), "ret", [(X86retflag 0)]>;
+
+let isCall = true in
+  // All calls clobber the non-callee saved registers...
+  let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
+              MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, XMM0, XMM1, XMM2,
+              XMM3, XMM4, XMM5, XMM6, XMM7, EFLAGS] in {
+    def CALLpcrel32 : Ii32<0xE8, RawFrm, (outs), (ins i32imm:$dst, variable_ops),
+                           "call\t${dst:call}", []>;
+    def CALL32r     : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
+                        "call\t{*}$dst", [(X86call GR32:$dst)]>;
+    def CALL32m     : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops),
+                        "call\t{*}$dst", []>;
+  }
+```
+
+Note that a top-level `let` will not override fields defined in the classes or records
 themselves.
 
-Top-level ``let`` also supports ``append`` and ``prepend`` modes, which
+Top-level `let` also supports `append` and `prepend` modes, which
 concatenate the value with the field's current value instead of replacing it.
-See the :token:`BodyItem` production for the supported types and semantics.
-
-.. code-block:: text
-
-  let append traits = [NewTrait] in {
-    def MyRecord : Base;
-  }
+See the {token}`BodyItem` production for the supported types and semantics.
 
+```text
+let append traits = [NewTrait] in {
+  def MyRecord : Base;
+}
+```
 
-``multiclass`` --- define multiple records
-------------------------------------------
+### `multiclass` --- define multiple records
 
 While classes with template arguments are a good way to factor out commonality
 between multiple records, multiclasses allow a convenient method for
 defining many records at once. For example, consider a 3-address
-instruction architecture whose instructions come in two formats: ``reg = reg
-op reg`` and ``reg = reg op imm`` (e.g., SPARC). We would like to specify in
+instruction architecture whose instructions come in two formats: `reg = reg
+op reg` and `reg = reg op imm` (e.g., SPARC). We would like to specify in
 one place that these two common formats exist, then in a separate place
-specify what all the operations are. The ``multiclass`` and ``defm``
+specify what all the operations are. The `multiclass` and `defm`
 statements accomplish this goal. You can think of a multiclass as a macro or
 template that expands into multiple records.
 
+```{eval-rst}
 .. productionlist::
    MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`]
              : `ParentClassList`
              : "{" `MultiClassStatement`+ "}"
    MultiClassID: `TokIdentifier`
    MultiClassStatement: `Assert` | `Def` | `Defm` | `Defvar` | `Foreach` | `If` | `Let`
+```
 
 As with regular classes, the multiclass has a name and can accept template
 arguments. A multiclass can inherit from other multiclasses, which causes
 the other multiclasses to be expanded and contribute to the record
 definitions in the inheriting multiclass. The body of the multiclass
-contains a series of statements that define records, using :token:`Def` and
-:token:`Defm`. In addition, :token:`Defvar`, :token:`Foreach`, and
-:token:`Let` statements can be used to factor out even more common elements.
-The :token:`If` and :token:`Assert` statements can also be used.
+contains a series of statements that define records, using {token}`Def` and
+{token}`Defm`. In addition, {token}`Defvar`, {token}`Foreach`, and
+{token}`Let` statements can be used to factor out even more common elements.
+The {token}`If` and {token}`Assert` statements can also be used.
 
 Also as with regular classes, the multiclass has the implicit template
-argument ``NAME`` (see NAME_). When a named (non-anonymous) record is
+argument `NAME` (see [NAME]). When a named (non-anonymous) record is
 defined in a multiclass and the record's name does not include a use of the
-template argument ``NAME``, such a use is automatically *prepended*
-to the name.  That is, the following are equivalent inside a multiclass::
+template argument `NAME`, such a use is automatically *prepended*
+to the name. That is, the following are equivalent inside a multiclass:
 
-    def Foo ...
-    def NAME # Foo ...
+```
+def Foo ...
+def NAME # Foo ...
+```
 
 The records defined in a multiclass are created when the multiclass is
-"instantiated" or "invoked" by a ``defm`` statement outside the multiclass
-definition. Each ``def`` statement in the multiclass produces a record. As
-with top-level ``def`` statements, these definitions can inherit from
+"instantiated" or "invoked" by a `defm` statement outside the multiclass
+definition. Each `def` statement in the multiclass produces a record. As
+with top-level `def` statements, these definitions can inherit from
 multiple parent classes.
 
-See `Examples: multiclasses and defms`_ for examples.
-
+See [Examples: multiclasses and defms] for examples.
 
-``defm`` --- invoke multiclasses to define multiple records
------------------------------------------------------------
+### `defm` --- invoke multiclasses to define multiple records
 
-Once multiclasses have been defined, you use the ``defm`` statement to
+Once multiclasses have been defined, you use the `defm` statement to
 "invoke" them and process the multiple record definitions in those
-multiclasses. Those record definitions are specified by ``def``
-statements in the multiclasses, and indirectly by ``defm`` statements.
+multiclasses. Those record definitions are specified by `def`
+statements in the multiclasses, and indirectly by `defm` statements.
 
+```{eval-rst}
 .. productionlist::
    Defm: "defm" [`NameValue`] `ParentClassList` ";"
+```
 
-The optional :token:`NameValue` is formed in the same way as the name of a
-``def``. The :token:`ParentClassList` is a colon followed by a list of at
+The optional {token}`NameValue` is formed in the same way as the name of a
+`def`. The {token}`ParentClassList` is a colon followed by a list of at
 least one multiclass and any number of regular classes. The multiclasses
-must precede the regular classes. Note that the ``defm`` does not have a
+must precede the regular classes. Note that the `defm` does not have a
 body.
 
 This statement instantiates all the records defined in all the specified
-multiclasses, either directly by ``def`` statements or indirectly by
-``defm`` statements. These records also receive the fields defined in any
+multiclasses, either directly by `def` statements or indirectly by
+`defm` statements. These records also receive the fields defined in any
 regular classes included in the parent class list. This is useful for adding
-a common set of fields to all the records created by the ``defm``.
+a common set of fields to all the records created by the `defm`.
 
-The name is parsed in the same special mode used by ``def``. If the name is
+The name is parsed in the same special mode used by `def`. If the name is
 not included, an unspecified but globally unique name is provided. That is,
-the following examples end up with different names::
+the following examples end up with different names:
 
-    defm    : SomeMultiClass<...>;   // A globally unique name.
-    defm "" : SomeMultiClass<...>;   // An empty name.
+```
+defm    : SomeMultiClass<...>;   // A globally unique name.
+defm "" : SomeMultiClass<...>;   // An empty name.
+```
 
-The ``defm`` statement can be used in a multiclass body. When this occurs,
-the second variant is equivalent to::
+The `defm` statement can be used in a multiclass body. When this occurs,
+the second variant is equivalent to:
 
-  defm NAME : SomeMultiClass<...>;
+```
+defm NAME : SomeMultiClass<...>;
+```
 
-More generally, when ``defm`` occurs in a multiclass and its name does not
-include a use of the implicit template argument ``NAME``, then ``NAME`` will
+More generally, when `defm` occurs in a multiclass and its name does not
+include a use of the implicit template argument `NAME`, then `NAME` will
 be prepended automatically. That is, the following are equivalent inside a
-multiclass::
+multiclass:
 
-    defm Foo        : SomeMultiClass<...>;
-    defm NAME # Foo : SomeMultiClass<...>;
+```
+defm Foo        : SomeMultiClass<...>;
+defm NAME # Foo : SomeMultiClass<...>;
+```
 
-See `Examples: multiclasses and defms`_ for examples.
+See [Examples: multiclasses and defms] for examples.
 
-Examples: multiclasses and defms
---------------------------------
+### Examples: multiclasses and defms
 
-Here is a simple example using ``multiclass`` and ``defm``.  Consider a
+Here is a simple example using `multiclass` and `defm`. Consider a
 3-address instruction architecture whose instructions come in two formats:
-``reg = reg op reg`` and ``reg = reg op imm`` (immediate). The SPARC is an
+`reg = reg op reg` and `reg = reg op imm` (immediate). The SPARC is an
 example of such an architecture.
 
-.. code-block:: text
-
-  def ops;
-  def GPR;
-  def Imm;
-  class inst <int opc, string asmstr, dag operandlist>;
-
-  multiclass ri_inst <int opc, string asmstr> {
-    def _rr : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
-                     (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
-    def _ri : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
-                     (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
-  }
-
-  // Define records for each instruction in the RR and RI formats.
-  defm ADD : ri_inst<0b111, "add">;
-  defm SUB : ri_inst<0b101, "sub">;
-  defm MUL : ri_inst<0b100, "mul">;
-
-Each use of the ``ri_inst`` multiclass defines two records, one with the
-``_rr`` suffix and one with ``_ri``. Recall that the name of the ``defm``
+```text
+def ops;
+def GPR;
+def Imm;
+class inst <int opc, string asmstr, dag operandlist>;
+
+multiclass ri_inst <int opc, string asmstr> {
+  def _rr : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
+                   (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
+  def _ri : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
+                   (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
+}
+
+// Define records for each instruction in the RR and RI formats.
+defm ADD : ri_inst<0b111, "add">;
+defm SUB : ri_inst<0b101, "sub">;
+defm MUL : ri_inst<0b100, "mul">;
+```
+
+Each use of the `ri_inst` multiclass defines two records, one with the
+`_rr` suffix and one with `_ri`. Recall that the name of the `defm`
 that uses a multiclass is prepended to the names of the records defined in
-that multiclass. So the resulting definitions are named::
+that multiclass. So the resulting definitions are named:
 
-  ADD_rr, ADD_ri
-  SUB_rr, SUB_ri
-  MUL_rr, MUL_ri
+```
+ADD_rr, ADD_ri
+SUB_rr, SUB_ri
+MUL_rr, MUL_ri
+```
 
-Without the ``multiclass`` feature, the instructions would have to be
+Without the `multiclass` feature, the instructions would have to be
 defined as follows.
 
-.. code-block:: text
-
-  def ops;
-  def GPR;
-  def Imm;
-  class inst <int opc, string asmstr, dag operandlist>;
-
-  class rrinst <int opc, string asmstr>
-    : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
-             (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
-
-  class riinst <int opc, string asmstr>
-    : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
-             (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
-
-  // Define records for each instruction in the RR and RI formats.
-  def ADD_rr : rrinst<0b111, "add">;
-  def ADD_ri : riinst<0b111, "add">;
-  def SUB_rr : rrinst<0b101, "sub">;
-  def SUB_ri : riinst<0b101, "sub">;
-  def MUL_rr : rrinst<0b100, "mul">;
-  def MUL_ri : riinst<0b100, "mul">;
-
-A ``defm`` can be used in a multiclass to "invoke" other multiclasses and
+```text
+def ops;
+def GPR;
+def Imm;
+class inst <int opc, string asmstr, dag operandlist>;
+
+class rrinst <int opc, string asmstr>
+  : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
+           (ops GPR:$dst, GPR:$src1, GPR:$src2)>;
+
+class riinst <int opc, string asmstr>
+  : inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
+           (ops GPR:$dst, GPR:$src1, Imm:$src2)>;
+
+// Define records for each instruction in the RR and RI formats.
+def ADD_rr : rrinst<0b111, "add">;
+def ADD_ri : riinst<0b111, "add">;
+def SUB_rr : rrinst<0b101, "sub">;
+def SUB_ri : riinst<0b101, "sub">;
+def MUL_rr : rrinst<0b100, "mul">;
+def MUL_ri : riinst<0b100, "mul">;
+```
+
+A `defm` can be used in a multiclass to "invoke" other multiclasses and
 create the records defined in those multiclasses in addition to the records
-defined in the current multiclass. In the following example, the ``basic_s``
-and ``basic_p`` multiclasses contain ``defm`` statements that refer to the
-``basic_r`` multiclass. The ``basic_r`` multiclass contains only ``def``
+defined in the current multiclass. In the following example, the `basic_s`
+and `basic_p` multiclasses contain `defm` statements that refer to the
+`basic_r` multiclass. The `basic_r` multiclass contains only `def`
 statements.
 
-.. code-block:: text
-
-  class Instruction <bits<4> opc, string Name> {
-    bits<4> opcode = opc;
-    string name = Name;
-  }
-
-  multiclass basic_r <bits<4> opc> {
-    def rr : Instruction<opc, "rr">;
-    def rm : Instruction<opc, "rm">;
-  }
-
-  multiclass basic_s <bits<4> opc> {
-    defm SS : basic_r<opc>;
-    defm SD : basic_r<opc>;
-    def X : Instruction<opc, "x">;
-  }
-
-  multiclass basic_p <bits<4> opc> {
-    defm PS : basic_r<opc>;
-    defm PD : basic_r<opc>;
-    def Y : Instruction<opc, "y">;
-  }
-
-  defm ADD : basic_s<0xf>, basic_p<0xf>;
-
-The final ``defm`` creates the following records, five from the ``basic_s``
-multiclass and five from the ``basic_p`` multiclass::
-
-  ADDSSrr, ADDSSrm
-  ADDSDrr, ADDSDrm
-  ADDX
-  ADDPSrr, ADDPSrm
-  ADDPDrr, ADDPDrm
-  ADDY
-
-A ``defm`` statement, both at top level and in a multiclass, can inherit
+```text
+class Instruction <bits<4> opc, string Name> {
+  bits<4> opcode = opc;
+  string name = Name;
+}
+
+multiclass basic_r <bits<4> opc> {
+  def rr : Instruction<opc, "rr">;
+  def rm : Instruction<opc, "rm">;
+}
+
+multiclass basic_s <bits<4> opc> {
+  defm SS : basic_r<opc>;
+  defm SD : basic_r<opc>;
+  def X : Instruction<opc, "x">;
+}
+
+multiclass basic_p <bits<4> opc> {
+  defm PS : basic_r<opc>;
+  defm PD : basic_r<opc>;
+  def Y : Instruction<opc, "y">;
+}
+
+defm ADD : basic_s<0xf>, basic_p<0xf>;
+```
+
+The final `defm` creates the following records, five from the `basic_s`
+multiclass and five from the `basic_p` multiclass:
+
+```
+ADDSSrr, ADDSSrm
+ADDSDrr, ADDSDrm
+ADDX
+ADDPSrr, ADDPSrm
+ADDPDrr, ADDPDrm
+ADDY
+```
+
+A `defm` statement, both at top level and in a multiclass, can inherit
 from regular classes in addition to multiclasses. The rule is that the
 regular classes must be listed after the multiclasses, and there must be at least
 one multiclass.
 
-.. code-block:: text
-
-  class XD {
-    bits<4> Prefix = 11;
-  }
-  class XS {
-    bits<4> Prefix = 12;
-  }
-  class I <bits<4> op> {
-    bits<4> opcode = op;
-  }
-
-  multiclass R {
-    def rr : I<4>;
-    def rm : I<2>;
-  }
-
-  multiclass Y {
-    defm SS : R, XD;    // First multiclass R, then regular class XD.
-    defm SD : R, XS;
-  }
-
-  defm Instr : Y;
+```text
+class XD {
+  bits<4> Prefix = 11;
+}
+class XS {
+  bits<4> Prefix = 12;
+}
+class I <bits<4> op> {
+  bits<4> opcode = op;
+}
+
+multiclass R {
+  def rr : I<4>;
+  def rm : I<2>;
+}
+
+multiclass Y {
+  defm SS : R, XD;    // First multiclass R, then regular class XD.
+  defm SD : R, XS;
+}
+
+defm Instr : Y;
+```
 
 This example will create four records, shown here in alphabetical order with
 their fields.
 
-.. code-block:: text
-
-  def InstrSDrm {
-    bits<4> opcode = { 0, 0, 1, 0 };
-    bits<4> Prefix = { 1, 1, 0, 0 };
-  }
-
-  def InstrSDrr {
-    bits<4> opcode = { 0, 1, 0, 0 };
-    bits<4> Prefix = { 1, 1, 0, 0 };
-  }
-
-  def InstrSSrm {
-    bits<4> opcode = { 0, 0, 1, 0 };
-    bits<4> Prefix = { 1, 0, 1, 1 };
-  }
-
-  def InstrSSrr {
-    bits<4> opcode = { 0, 1, 0, 0 };
-    bits<4> Prefix = { 1, 0, 1, 1 };
-  }
-
-It's also possible to use ``let`` statements inside multiclasses, providing
+```text
+def InstrSDrm {
+  bits<4> opcode = { 0, 0, 1, 0 };
+  bits<4> Prefix = { 1, 1, 0, 0 };
+}
+
+def InstrSDrr {
+  bits<4> opcode = { 0, 1, 0, 0 };
+  bits<4> Prefix = { 1, 1, 0, 0 };
+}
+
+def InstrSSrm {
+  bits<4> opcode = { 0, 0, 1, 0 };
+  bits<4> Prefix = { 1, 0, 1, 1 };
+}
+
+def InstrSSrr {
+  bits<4> opcode = { 0, 1, 0, 0 };
+  bits<4> Prefix = { 1, 0, 1, 1 };
+}
+```
+
+It's also possible to use `let` statements inside multiclasses, providing
 another way to factor out commonality from the records, especially when
 using several levels of multiclass instantiations.
 
-.. code-block:: text
-
-  multiclass basic_r <bits<4> opc> {
-    let Predicates = [HasSSE2] in {
-      def rr : Instruction<opc, "rr">;
-      def rm : Instruction<opc, "rm">;
-    }
-    let Predicates = [HasSSE3] in
-      def rx : Instruction<opc, "rx">;
+```text
+multiclass basic_r <bits<4> opc> {
+  let Predicates = [HasSSE2] in {
+    def rr : Instruction<opc, "rr">;
+    def rm : Instruction<opc, "rm">;
   }
+  let Predicates = [HasSSE3] in
+    def rx : Instruction<opc, "rx">;
+}
 
-  multiclass basic_ss <bits<4> opc> {
-    let IsDouble = false in
-      defm SS : basic_r<opc>;
-
-    let IsDouble = true in
-      defm SD : basic_r<opc>;
-  }
+multiclass basic_ss <bits<4> opc> {
+  let IsDouble = false in
+    defm SS : basic_r<opc>;
 
-  defm ADD : basic_ss<0xf>;
+  let IsDouble = true in
+    defm SD : basic_r<opc>;
+}
 
+defm ADD : basic_ss<0xf>;
+```
 
-``defset`` --- create a definition set
---------------------------------------
+### `defset` --- create a definition set
 
-The ``defset`` statement is used to collect a set of records into a global
+The `defset` statement is used to collect a set of records into a global
 list of records.
 
+```{eval-rst}
 .. productionlist::
    Defset: "defset" `Type` `TokIdentifier` "=" "{" `Statement`* "}"
+```
 
-All records defined inside the braces via ``def`` and ``defm`` are defined
+All records defined inside the braces via `def` and `defm` are defined
 as usual, and they are also collected in a global list of the given name
-(:token:`TokIdentifier`).
+({token}`TokIdentifier`).
 
-The specified type must be ``list<``\ *class*\ ``>``, where *class* is some
-record class.  The ``defset`` statement establishes a scope for its
+The specified type must be `list<`*class*`>`, where *class* is some
+record class. The `defset` statement establishes a scope for its
 statements. It is an error to define a record in the scope of the
-``defset`` that is not of type *class*.
+`defset` that is not of type *class*.
 
-The ``defset`` statement can be nested. The inner ``defset`` adds the
+The `defset` statement can be nested. The inner `defset` adds the
 records to its own set, and all those records are also added to the outer
 set.
 
 Anonymous records created inside initialization expressions using the
-``ClassID<...>`` syntax are not collected in the set.
+`ClassID<...>` syntax are not collected in the set.
 
-``deftype`` --- define a type
---------------------------------
+### `deftype` --- define a type
 
-A ``deftype`` statement defines a type. The type can be used throughout the
+A `deftype` statement defines a type. The type can be used throughout the
 statements that follow the definition.
 
+```{eval-rst}
 .. productionlist::
    Deftype: "deftype" `TokIdentifier` "=" `Type` ";"
+```
 
-The identifier on the left of the ``=`` is defined to be a type name
-whose actual type is given by the type expression on the right of the ``=``.
+The identifier on the left of the `=` is defined to be a type name
+whose actual type is given by the type expression on the right of the `=`.
 
 Currently, only primitive types and type aliases are supported to be the source
 type and `deftype` statements can only appear at the top level.
 
-``defvar`` --- define a variable
---------------------------------
+### `defvar` --- define a variable
 
-A ``defvar`` statement defines a global variable. Its value can be used
+A `defvar` statement defines a global variable. Its value can be used
 throughout the statements that follow the definition.
 
+```{eval-rst}
 .. productionlist::
    Defvar: "defvar" `TokIdentifier` "=" `Value` ";"
+```
 
-The identifier on the left of the ``=`` is defined to be a global variable
-whose value is given by the value expression on the right of the ``=``. The
+The identifier on the left of the `=` is defined to be a global variable
+whose value is given by the value expression on the right of the `=`. The
 type of the variable is automatically inferred.
 
 Once a variable has been defined, it cannot be set to another value.
 
-Variables defined in a top-level ``foreach`` go out of scope at the end of
+Variables defined in a top-level `foreach` go out of scope at the end of
 each loop iteration, so their value in one iteration is not available in
-the next iteration.  The following ``defvar`` will not work::
+the next iteration. The following `defvar` will not work:
 
-  defvar i = !add(i, 1);
+```
+defvar i = !add(i, 1);
+```
 
-Variables can also be defined with ``defvar`` in a record body. See
-`Defvar in a Record Body`_ for more details.
+Variables can also be defined with `defvar` in a record body. See
+[Defvar in a Record Body] for more details.
 
-``foreach`` --- iterate over a sequence of statements
------------------------------------------------------
+### `foreach` --- iterate over a sequence of statements
 
-The ``foreach`` statement iterates over a series of statements, varying a
+The `foreach` statement iterates over a series of statements, varying a
 variable over a sequence of values.
 
+```{eval-rst}
 .. productionlist::
    Foreach: "foreach" `ForeachIterator` "in" "{" `Statement`* "}"
           :| "foreach" `ForeachIterator` "in" `Statement`
    ForeachIterator: `TokIdentifier` "=" (`RangeList` | `RangePiece` | `Value`)
+```
 
-The body of the ``foreach`` is a series of statements in braces or a
+The body of the `foreach` is a series of statements in braces or a
 single statement with no braces. The statements are re-evaluated once for
 each value in the range list, range piece, or single value. On each
-iteration, the :token:`TokIdentifier` variable is set to the value and can
+iteration, the {token}`TokIdentifier` variable is set to the value and can
 be used in the statements.
 
 The statement list establishes an inner scope. Variables local to a
-``foreach`` go out of scope at the end of each loop iteration, so their
+`foreach` go out of scope at the end of each loop iteration, so their
 values do not carry over from one iteration to the next. Foreach loops may
 be nested.
 
-.. Note that the productions involving RangeList and RangePiece have precedence
-   over the more generic value parsing based on the first token.
-
-.. code-block:: text
+% Note that the productions involving RangeList and RangePiece have precedence
+% over the more generic value parsing based on the first token.
 
-  foreach i = [0, 1, 2, 3] in {
-    def R#i : Register<...>;
-    def F#i : Register<...>;
-  }
+```text
+foreach i = [0, 1, 2, 3] in {
+  def R#i : Register<...>;
+  def F#i : Register<...>;
+}
+```
 
-This loop defines records named ``R0``, ``R1``, ``R2``, and ``R3``, along
-with ``F0``, ``F1``, ``F2``, and ``F3``.
+This loop defines records named `R0`, `R1`, `R2`, and `R3`, along
+with `F0`, `F1`, `F2`, and `F3`.
 
-``dump`` --- print messages to stderr
--------------------------------------
+### `dump` --- print messages to stderr
 
-A ``dump`` statement prints the input string to standard error
+A `dump` statement prints the input string to standard error
 output. It is intended for debugging purposes.
 
-* At top level, the message is printed immediately.
-
-* Within a record/class/multiclass, `dump` gets evaluated at each
+- At top level, the message is printed immediately.
+- Within a record/class/multiclass, `dump` gets evaluated at each
   instantiation point of the containing record.
 
+```{eval-rst}
 .. productionlist::
    Dump: "dump" `Value` ";"
+```
 
-The :token:`Value` is an arbitrary string expression.
+The {token}`Value` is an arbitrary string expression.
 For example, it can be used in combination with `!repr` to investigate
 the values passed to a multiclass:
 
-.. code-block:: text
-
-  multiclass MC<dag s> {
-    dump "s = " # !repr(s);
-  }
-
+```text
+multiclass MC<dag s> {
+  dump "s = " # !repr(s);
+}
+```
 
-``if`` --- select statements based on a test
---------------------------------------------
+### `if` --- select statements based on a test
 
-The ``if`` statement allows one of two statement groups to be selected based
+The `if` statement allows one of two statement groups to be selected based
 on the value of an expression.
 
+```{eval-rst}
 .. productionlist::
    If: "if" `Value` "then" `IfBody`
      :| "if" `Value` "then" `IfBody` "else" `IfBody`
    IfBody: "{" `Statement`* "}" | `Statement`
+```
 
 The value expression is evaluated. If it evaluates to true (in the same
 sense used by the bang operators), then the statements following the
-``then`` reserved word are processed. Otherwise, if there is an ``else``
-reserved word, the statements following the ``else`` are processed. If the
-value is false and there is no ``else`` arm, no statements are processed.
+`then` reserved word are processed. Otherwise, if there is an `else`
+reserved word, the statements following the `else` are processed. If the
+value is false and there is no `else` arm, no statements are processed.
 
-Because the braces around the ``then`` statements are optional, this grammar rule
+Because the braces around the `then` statements are optional, this grammar rule
 has the usual ambiguity with "dangling else" clauses, and it is resolved in
-the usual way: in a case like ``if v1 then if v2 then {...} else {...}``, the
-``else`` associates with the inner ``if`` rather than the outer one.
+the usual way: in a case like `if v1 then if v2 then {...} else {...}`, the
+`else` associates with the inner `if` rather than the outer one.
 
-The :token:`IfBody` of the then and else arms of the ``if`` establish an
-inner scope. Any ``defvar`` variables defined in the bodies go out of scope
-when the bodies are finished (see `Defvar in a Record Body`_ for more details).
+The {token}`IfBody` of the then and else arms of the `if` establish an
+inner scope. Any `defvar` variables defined in the bodies go out of scope
+when the bodies are finished (see [Defvar in a Record Body] for more details).
 
-The ``if`` statement can also be used in a record :token:`Body`.
+The `if` statement can also be used in a record {token}`Body`.
 
+### `assert` --- check that a condition is true
 
-``assert`` --- check that a condition is true
----------------------------------------------
-
-The ``assert`` statement checks a boolean condition to be sure that it is true
+The `assert` statement checks a boolean condition to be sure that it is true
 and prints an error message if it is not.
 
+```{eval-rst}
 .. productionlist::
    Assert: "assert" `Value` "," `Value` ";"
+```
 
-The first :token:`Value` is a boolean condition. If it is true, the
+The first {token}`Value` is a boolean condition. If it is true, the
 statement does nothing. If the condition is false, it prints a nonfatal
-error message. The second :token:`Value` is a message, which can be an
+error message. The second {token}`Value` is a message, which can be an
 arbitrary string expression. It is included in the error message as a
-note. The exact behavior of the ``assert`` statement depends on its
+note. The exact behavior of the `assert` statement depends on its
 placement.
 
-* At top level, the assertion is checked immediately.
-
-* In a record definition, the statement is saved and all assertions are
+- At top level, the assertion is checked immediately.
+- In a record definition, the statement is saved and all assertions are
   checked after the record is completely built.
-
-* In a class definition, the assertions are saved and inherited by all
+- In a class definition, the assertions are saved and inherited by all
   the subclasses and records that inherit from the class. The assertions are
   then checked when the records are completely built.
-
-* In a multiclass definition, the assertions are saved with the other
+- In a multiclass definition, the assertions are saved with the other
   components of the multiclass and then checked each time the multiclass
-  is instantiated with ``defm``.
+  is instantiated with `defm`.
 
 Using assertions in TableGen files can simplify record checking in TableGen
-backends. Here is an example of an ``assert`` in two class definitions.
-
-.. code-block:: text
+backends. Here is an example of an `assert` in two class definitions.
 
-  class PersonName<string name> {
-    assert !le(!size(name), 32), "person name is too long: " # name;
-    string Name = name;
-  }
+```text
+class PersonName<string name> {
+  assert !le(!size(name), 32), "person name is too long: " # name;
+  string Name = name;
+}
 
-  class Person<string name, int age> : PersonName<name> {
-    assert !and(!ge(age, 1), !le(age, 120)), "person age is invalid: " # age;
-    int Age = age;
-  }
+class Person<string name, int age> : PersonName<name> {
+  assert !and(!ge(age, 1), !le(age, 120)), "person age is invalid: " # age;
+  int Age = age;
+}
 
-  def Rec20 : Person<"Donald Knuth", 60> {
-    ...
-  }
+def Rec20 : Person<"Donald Knuth", 60> {
+  ...
+}
+```
 
+## Additional Details
 
-Additional Details
-==================
-
-Directed acyclic graphs (DAGs)
-------------------------------
+### Directed acyclic graphs (DAGs)
 
 A directed acyclic graph can be represented directly in TableGen using the
-``dag`` datatype. A DAG node consists of an operator and zero or more
+`dag` datatype. A DAG node consists of an operator and zero or more
 arguments (or operands). Each argument can be of any desired type. By using
 another DAG node as an argument, an arbitrary graph of DAG nodes can be
 built.
 
-The syntax of a ``dag`` instance is:
+The syntax of a `dag` instance is:
 
-  ``(`` *operator* *argument1*\ ``,`` *argument2*\ ``,`` ... ``)``
+> `(` *operator* *argument1*`,` *argument2*`,` ... `)`
 
 The operator must be present and must be a record. There can be zero or more
 arguments, separated by commas. The operator and arguments can have three
 formats.
 
-====================== =============================================
-Format                 Meaning
-====================== =============================================
-*value*                argument value
-*value*\ ``:``\ *name* argument value and associated name
-*name*                 argument name with unset (uninitialized) value
-====================== =============================================
+| Format           | Meaning                                        |
+| ---------------- | ---------------------------------------------- |
+| *value*          | argument value                                 |
+| *value*`:`*name* | argument value and associated name             |
+| *name*           | argument name with unset (uninitialized) value |
 
 The *value* can be any TableGen value. The *name*, if present, must be a
-:token:`TokVarName`, which starts with a dollar sign (``$``). The purpose of
+{token}`TokVarName`, which starts with a dollar sign (`$`). The purpose of
 a name is to tag an operator or argument in a DAG with a particular meaning,
 or to associate an argument in one DAG with a like-named argument in another
 DAG.
 
 The following bang operators are useful for working with DAGs:
-``!con``, ``!dag``, ``!empty``, ``!foreach``, ``!getdagarg``, ``!getdagname``,
-``!getdagop``, ``!getdagopname``, ``!setdagarg``, ``!setdagname``, ``!setdagop``,
-``!setdagopname``, ``!size``.
+`!con`, `!dag`, `!empty`, `!foreach`, `!getdagarg`, `!getdagname`,
+`!getdagop`, `!getdagopname`, `!setdagarg`, `!setdagname`, `!setdagop`,
+`!setdagopname`, `!size`.
 
-Defvar in a record body
------------------------
+### Defvar in a record body
 
-In addition to defining global variables, the ``defvar`` statement can
-be used inside the :token:`Body` of a class or record definition to define
-local variables. Template arguments of ``class`` or ``multiclass`` can be
+In addition to defining global variables, the `defvar` statement can
+be used inside the {token}`Body` of a class or record definition to define
+local variables. Template arguments of `class` or `multiclass` can be
 used in the value expression. The scope of the variable extends from the
-``defvar`` statement to the end of the body. It cannot be set to a different
-value within its scope. The ``defvar`` statement can also be used in the statement
-list of a ``foreach``, which establishes a scope.
+`defvar` statement to the end of the body. It cannot be set to a different
+value within its scope. The `defvar` statement can also be used in the statement
+list of a `foreach`, which establishes a scope.
 
-A variable named ``V`` in an inner scope shadows (hides) any variables ``V``
+A variable named `V` in an inner scope shadows (hides) any variables `V`
 in outer scopes. In particular, there are several cases:
 
-* ``V`` in a record body shadows a global ``V``.
-
-* ``V`` in a record body shadows template argument ``V``.
-
-* ``V`` in template arguments shadows a global ``V``.
-
-* ``V`` in a ``foreach`` statement list shadows any ``V`` in surrounding record or
+- `V` in a record body shadows a global `V`.
+- `V` in a record body shadows template argument `V`.
+- `V` in template arguments shadows a global `V`.
+- `V` in a `foreach` statement list shadows any `V` in surrounding record or
   global scopes.
 
-Variables defined in a ``foreach`` go out of scope at the end of
+Variables defined in a `foreach` go out of scope at the end of
 each loop iteration, so their value in one iteration is not available in
-the next iteration.  The following ``defvar`` will not work::
+the next iteration. The following `defvar` will not work:
 
-  defvar i = !add(i, 1)
+```
+defvar i = !add(i, 1)
+```
 
-How records are built
----------------------
+### How records are built
 
 The following steps are taken by TableGen when a record is built. Classes are simply
 abstract records and so go through the same steps.
 
-1. Build the record name (:token:`NameValue`) and create an empty record.
-
-2. Parse the parent classes in the :token:`ParentClassList` from left to
+1. Build the record name ({token}`NameValue`) and create an empty record.
+2. Parse the parent classes in the {token}`ParentClassList` from left to
    right, visiting each parent class's ancestor classes from top to bottom.
 
-  a. Add the fields from the parent class to the record.
-  b. Substitute the template arguments into those fields.
-  c. Add the parent class to the record's list of inherited classes.
+> 1. Add the fields from the parent class to the record.
+> 2. Substitute the template arguments into those fields.
+> 3. Add the parent class to the record's list of inherited classes.
 
-3. Apply any top-level ``let`` bindings to the record. Recall that top-level
+3. Apply any top-level `let` bindings to the record. Recall that top-level
    bindings only apply to inherited fields.
-
 4. Parse the body of the record.
 
-  * Add any fields to the record.
-  * Modify the values of fields according to local ``let`` statements.
-  * Define any ``defvar`` variables.
+> - Add any fields to the record.
+> - Modify the values of fields according to local `let` statements.
+> - Define any `defvar` variables.
 
 5. Make a pass over all the fields to resolve any inter-field references.
-
 6. Add the record to the final record list.
 
-Because references between fields are resolved (step 5) after ``let`` bindings are
-applied (step 3), the ``let`` statement has unusual power. For example:
+Because references between fields are resolved (step 5) after `let` bindings are
+applied (step 3), the `let` statement has unusual power. For example:
 
-.. code-block:: text
+```text
+class C <int x> {
+  int Y = x;
+  int Yplus1 = !add(Y, 1);
+  int xplus1 = !add(x, 1);
+}
 
-  class C <int x> {
-    int Y = x;
-    int Yplus1 = !add(Y, 1);
-    int xplus1 = !add(x, 1);
+let Y = 10 in {
+  def rec1 : C<5> {
   }
-
-  let Y = 10 in {
-    def rec1 : C<5> {
-    }
-  }
-
-  def rec2 : C<5> {
-    let Y = 10;
-  }
-
-In both cases, one where a top-level ``let`` is used to bind ``Y`` and one
-where a local ``let`` does the same thing, the results are:
-
-.. code-block:: text
-
-  def rec1 {      // C
-    int Y = 10;
-    int Yplus1 = 11;
-    int xplus1 = 6;
-  }
-  def rec2 {      // C
-    int Y = 10;
-    int Yplus1 = 11;
-    int xplus1 = 6;
-  }
-
-``Yplus1`` is 11 because the ``let Y`` is performed before the ``!add(Y,
-1)`` is resolved. Use this power wisely.
-
-
-Using Classes as Subroutines
-============================
-
-As described in `Simple values`_, a class can be invoked in an expression
+}
+
+def rec2 : C<5> {
+  let Y = 10;
+}
+```
+
+In both cases, one where a top-level `let` is used to bind `Y` and one
+where a local `let` does the same thing, the results are:
+
+```text
+def rec1 {      // C
+  int Y = 10;
+  int Yplus1 = 11;
+  int xplus1 = 6;
+}
+def rec2 {      // C
+  int Y = 10;
+  int Yplus1 = 11;
+  int xplus1 = 6;
+}
+```
+
+`Yplus1` is 11 because the `let Y` is performed before the `!add(Y,
+1)` is resolved. Use this power wisely.
+
+## Using Classes as Subroutines
+
+As described in [Simple values], a class can be invoked in an expression
 and passed template arguments. This causes TableGen to create a new anonymous
 record inheriting from that class. As usual, the record receives all the
 fields defined in the class.
@@ -1595,48 +1647,48 @@ fields defined in the class.
 This feature can be employed as a simple subroutine facility. The class can
 use the template arguments to define various variables and fields, which end
 up in the anonymous record. Those fields can then be retrieved in the
-expression invoking the class as follows. Assume that the field ``ret``
+expression invoking the class as follows. Assume that the field `ret`
 contains the final value of the subroutine.
 
-.. code-block:: text
-
-  int Result = ... CalcValue<arg>.ret ...;
+```text
+int Result = ... CalcValue<arg>.ret ...;
+```
 
-The ``CalcValue`` class is invoked with the template argument ``arg``. It
-calculates a value for the ``ret`` field, which is then retrieved at the
+The `CalcValue` class is invoked with the template argument `arg`. It
+calculates a value for the `ret` field, which is then retrieved at the
 "point of call" in the initialization for the Result field. The anonymous
 record created in this example serves no other purpose than to carry the
 result value.
 
-Here is a practical example. The class ``isValidSize`` determines whether a
-specified number of bytes represents a valid data size. The bit ``ret`` is
-set appropriately. The field ``ValidSize`` obtains its initial value by
-invoking ``isValidSize`` with the data size and retrieving the ``ret`` field
+Here is a practical example. The class `isValidSize` determines whether a
+specified number of bytes represents a valid data size. The bit `ret` is
+set appropriately. The field `ValidSize` obtains its initial value by
+invoking `isValidSize` with the data size and retrieving the `ret` field
 from the resulting anonymous record.
 
-.. code-block:: text
+```text
+class isValidSize<int size> {
+  bit ret = !cond(!eq(size,  1): 1,
+                  !eq(size,  2): 1,
+                  !eq(size,  4): 1,
+                  !eq(size,  8): 1,
+                  !eq(size, 16): 1,
+                  true: 0);
+}
 
-  class isValidSize<int size> {
-    bit ret = !cond(!eq(size,  1): 1,
-                    !eq(size,  2): 1,
-                    !eq(size,  4): 1,
-                    !eq(size,  8): 1,
-                    !eq(size, 16): 1,
-                    true: 0);
-  }
-
-  def Data1 {
-    int Size = ...;
-    bit ValidSize = isValidSize<Size>.ret;
-  }
+def Data1 {
+  int Size = ...;
+  bit ValidSize = isValidSize<Size>.ret;
+}
+```
 
-Preprocessing Facilities
-========================
+## Preprocessing Facilities
 
 The preprocessor embedded in TableGen is intended only for simple
 conditional compilation. It supports the following directives, which are
 specified somewhat informally.
 
+```{eval-rst}
 .. productionlist::
    LineBegin: beginning of line
    LineEnd: newline | return | EOF
@@ -1656,38 +1708,39 @@ specified somewhat informally.
           : "#else" (`WhiteSpaceOrAnyComment`)* `LineEnd`
    PreEndif: `LineBegin` (`WhiteSpaceOrCComment`)*
            : "#endif" (`WhiteSpaceOrAnyComment`)* `LineEnd`
+```
 
-..
-   PreRegContentException: `PreIfdef` | `PreElse` | `PreEndif` | EOF
-   PreRegion: .* - `PreRegContentException`
-             :| `PreIfdef`
-             :  (`PreRegion`)*
-             :  [`PreElse`]
-             :  (`PreRegion`)*
-             :  `PreEndif`
+% PreRegContentException: `PreIfdef` | `PreElse` | `PreEndif` | EOF
+% PreRegion: .* - `PreRegContentException`
+%           :| `PreIfdef`
+%           :  (`PreRegion`)*
+%           :  [`PreElse`]
+%           :  (`PreRegion`)*
+%           :  `PreEndif`
 
-A :token:`MacroName` can be defined anywhere in a TableGen file. The name has
+A {token}`MacroName` can be defined anywhere in a TableGen file. The name has
 no value; it can only be tested to see whether it is defined.
 
-A macro test region begins with an ``#ifdef`` or ``#ifndef`` directive. If
-the macro name is defined (``#ifdef``) or undefined (``#ifndef``), then the
-source code between the directive and the corresponding ``#else`` or
-``#endif`` is processed. If the test fails but there is an ``#else``
-clause, the source code between the ``#else`` and the ``#endif`` is
-processed. If the test fails and there is no ``#else`` clause, then no
+A macro test region begins with an `#ifdef` or `#ifndef` directive. If
+the macro name is defined (`#ifdef`) or undefined (`#ifndef`), then the
+source code between the directive and the corresponding `#else` or
+`#endif` is processed. If the test fails but there is an `#else`
+clause, the source code between the `#else` and the `#endif` is
+processed. If the test fails and there is no `#else` clause, then no
 source code in the test region is processed.
 
 Test regions may be nested, but they must be properly nested. A region
 started in a file must end in that file; that is, must have its
-``#endif`` in the same file.
+`#endif` in the same file.
 
-A :token:`MacroName` may be defined externally using the ``-D`` option on the
-``*-tblgen`` command line::
+A {token}`MacroName` may be defined externally using the `-D` option on the
+`*-tblgen` command line:
 
-  llvm-tblgen self-reference.td -Dmacro1 -Dmacro3
+```
+llvm-tblgen self-reference.td -Dmacro1 -Dmacro3
+```
 
-Appendix A: Bang Operators
-==========================
+## Appendix A: Bang Operators
 
 Bang operators act as functions in value expressions. A bang operator takes
 one or more arguments, operates on them, and produces a result. If the
@@ -1695,593 +1748,663 @@ operator produces a boolean result, the result value will be 1 for true or 0
 for false. When an operator tests a boolean argument, it interprets 0 as false
 and non-0 as true.
 
-``!add(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator adds *a*, *b*, etc., and produces the sum.
-
-``!and(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator does a bitwise AND on *a*, *b*, etc., and produces the
-    result. A logical AND can be performed if all the arguments are either
-    0 or 1. This operator is short-circuit to 0 when the left-most operand
-    is 0.
-
-``!cast<``\ *type*\ ``>(``\ *a*\ ``)``
-    This operator performs a cast on *a* and produces the result.
-    If *a* is not a string, then a straightforward cast is performed, say
-    between an ``int`` and a ``bit``, or between record types. This allows
-    casting a record to a class. If a record is cast to ``string``, the
-    record's name is produced.
-
-    If *a* is a string, then it is treated as a record name and looked up in
-    the list of all defined records. The resulting record is expected to be of
-    the specified *type*.
-
-    For example, if ``!cast<``\ *type*\ ``>(``\ *name*\ ``)``
-    appears in a multiclass definition, or in a
-    class instantiated inside a multiclass definition, and the *name* does not
-    reference any template arguments of the multiclass, then a record by
-    that name must have been instantiated earlier
-    in the source file. If *name* does reference
-    a template argument, then the lookup is delayed until ``defm`` statements
-    instantiating the multiclass (or later, if the defm occurs in another
-    multiclass and template arguments of the inner multiclass that are
-    referenced by *name* are substituted by values that themselves contain
-    references to template arguments of the outer multiclass).
-
-    If the type of *a* does not match *type*, TableGen raises an error.
-
-``!con(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator concatenates the DAG nodes *a*, *b*, etc. Their operations
-    must equal.
-
-    ``!con((op:$lhs a1:$name1, a2:$name2), (op:$rhs b1:$name3))``
-
-    results in the DAG node ``(op:$lhs a1:$name1, a2:$name2, b1:$name3)``.
-    The name of the dag operator is derived from the LHS DAG node if it is
-    set, otherwise from the RHS DAG node.
-
-``!cond(``\ *cond1* ``:`` *val1*\ ``,`` *cond2* ``:`` *val2*\ ``, ...,`` *condn* ``:`` *valn*\ ``)``
-    This operator tests *cond1* and returns *val1* if the result is true.
-    If false, the operator tests *cond2* and returns *val2* if the result is
-    true. And so forth. An error is reported if no conditions are true.
-
-    !cond short-circuits at the first true condition, resolving to that
-    condition's corresponding value.  Subsequent conditions and values are left
-    unresolved.
-
-    This example produces the sign word for an integer::
-
-    !cond(!lt(x, 0) : "negative", !eq(x, 0) : "zero", true : "positive")
-
-``!dag(``\ *op*\ ``,`` *arguments*\ ``,`` *names*\ ``)``
-    This operator creates a DAG node with the given operator and
-    arguments. The *arguments* and *names* arguments must be lists
-    of equal length or uninitialized (``?``). The *names* argument
-    must be of type ``list<string>``.
-
-    Due to limitations of the type system, *arguments* must be a list of items
-    of a common type. In practice, this means that they should either have the
-    same type or be records with a common parent class. Mixing ``dag`` and
-    non-``dag`` items is not possible. However, ``?`` can be used.
-
-    Example: ``!dag(op, [a1, a2, ?], ["name1", "name2", "name3"])`` results in
-    ``(op a1-value:$name1, a2-value:$name2, ?:$name3)``.
-
-``!div(``\ *a*\ ``,`` *b*\ ``)``
-    This operator performs signed division of *a* by *b*, and produces the quotient.
-    Division by 0 produces an error. Division of ``INT64_MIN`` by -1 produces an error.
-
-``!empty(``\ *a*\ ``)``
-    This operator produces 1 if the string, list, or DAG *a* is empty; 0 otherwise.
-    A dag is empty if it has no arguments; the operator does not count.
-
-``!eq(`` *a*\ `,` *b*\ ``)``
-    This operator produces 1 if *a* is equal to *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, ``string``, or
-    record values. Use ``!cast<string>`` to compare other types of objects.
-
-``!exists<``\ *type*\ ``>(``\ *name*\ ``)``
-    This operator produces 1 if a record of the given *type* whose name is *name*
-    exists; 0 otherwise. *name* should be of type *string*.
-
-``!filter(``\ *var*\ ``,`` *list*\ ``,`` *predicate*\ ``)``
-
-    This operator creates a new ``list`` by filtering the elements in
-    *list*. To perform the filtering, TableGen binds the variable *var* to each
-    element and then evaluates the *predicate* expression, which presumably
-    refers to *var*. The predicate must
-    produce a boolean value (``bit``, ``bits``, or ``int``). The value is
-    interpreted as with ``!if``:
-    if the value is 0, the element is not included in the new list. If the value
-    is anything else, the element is included.
-
-``!find(``\ *string1*\ ``,`` *string2*\ [``,`` *start*]\ ``)``
-    This operator searches for *string2* in *string1* and produces its
-    position. The starting position of the search may be specified by *start*,
-    which can range between 0 and the length of *string1*; the default is 0.
-    If the string is not found, the result is -1.
-
-``!foldl(``\ *init*\ ``,`` *list*\ ``,`` *acc*\ ``,`` *var*\ ``,`` *expr*\ ``)``
-    This operator performs a left-fold over the items in *list*. The
-    variable *acc* acts as the accumulator and is initialized to *init*.
-    The variable *var* is bound to each element in the *list*. The
-    expression is evaluated for each element and presumably uses *acc* and
-    *var* to calculate the accumulated value, which ``!foldl`` stores back in
-    *acc*. The type of *acc* is the same as *init*; the type of *var* is the
-    same as the elements of *list*; *expr* must have the same type as *init*.
-
-    The following example computes the total of the ``Number`` field in the
-    list of records in ``RecList``::
-
-      int x = !foldl(0, RecList, total, rec, !add(total, rec.Number));
-
-    If your goal is to filter the list and produce a new list that includes only
-    some of the elements, see ``!filter``.
-
-``!foreach(``\ *var*\ ``,`` *sequence*\ ``,`` *expr*\ ``)``
-    This operator creates a new ``list``/``dag`` in which each element is a
-    function of the corresponding element in the *sequence* ``list``/``dag``.
-    To perform the function, TableGen binds the variable *var* to an element
-    and then evaluates the expression. The expression presumably refers
-    to the variable *var* and calculates the result value.
-
-    If you simply want to create a list of a certain length containing
-    the same value repeated multiple times, see ``!listsplat``.
-
-``!ge(``\ *a*\ `,` *b*\ ``)``
-    This operator produces 1 if *a* is greater than or equal to *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values.
-
-``!getdagarg<``\ *type*\ ``>(``\ *dag*\ ``,``\ *key*\ ``)``
-    This operator retrieves the argument from the given *dag* node by the
-    specified *key*, which is either an integer index or a string name. If that
-    argument is not convertible to the specified *type*, ``?`` is returned.
-
-``!getdagname(``\ *dag*\ ``,``\ *index*\ ``)``
-    This operator retrieves the argument name from the given *dag* node by the
-    specified *index*. If that argument has no name associated, ``?`` is
-    returned.
-
-``!getdagop(``\ *dag*\ ``)`` --or-- ``!getdagop<``\ *type*\ ``>(``\ *dag*\ ``)``
-    This operator produces the operator of the given *dag* node.
-    Example: ``!getdagop((foo 1, 2))`` results in ``foo``. Recall that
-    DAG operators are always records.
-
-    The result of ``!getdagop`` can be used directly in a context where
-    any record class at all is acceptable (typically placing it into
-    another dag value). But in other contexts, it must be explicitly
-    cast to a particular class. The ``<``\ *type*\ ``>`` syntax is
-    provided to make this easy.
-
-    For example, to assign the result to a value of type ``BaseClass``, you
-    could write either of these::
-
-      BaseClass b = !getdagop<BaseClass>(someDag);
-      BaseClass b = !cast<BaseClass>(!getdagop(someDag));
-
-    But to create a new DAG node that reuses the operator from another, no
-    cast is necessary::
-
-      dag d = !dag(!getdagop(someDag), args, names);
-
-``!getdagopname(``\ *dag*\ ``)``
-    This operator retrieves the name of the given *dag* operator. If the operator
-    has no name associated, ``?`` is returned.
-
-``!gt(``\ *a*\ `,` *b*\ ``)``
-    This operator produces 1 if *a* is greater than *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values.
-
-``!head(``\ *a*\ ``)``
-    This operator produces the zeroth element of the list *a*.
-    (See also ``!tail``.)
-
-``!if(``\ *test*\ ``,`` *then*\ ``,`` *else*\ ``)``
-  This operator evaluates the *test*, which must produce a ``bit`` or
-  ``int``. If the result is not 0, the *then* expression is produced; otherwise
+`!add(`*a*`,` *b*`, ...)`
+
+: This operator adds *a*, *b*, etc., and produces the sum.
+
+`!and(`*a*`,` *b*`, ...)`
+
+: This operator does a bitwise AND on *a*, *b*, etc., and produces the
+  result. A logical AND can be performed if all the arguments are either
+  0 or 1. This operator is short-circuit to 0 when the left-most operand
+  is 0.
+
+`!cast<`*type*`>(`*a*`)`
+
+: This operator performs a cast on *a* and produces the result.
+  If *a* is not a string, then a straightforward cast is performed, say
+  between an `int` and a `bit`, or between record types. This allows
+  casting a record to a class. If a record is cast to `string`, the
+  record's name is produced.
+
+  If *a* is a string, then it is treated as a record name and looked up in
+  the list of all defined records. The resulting record is expected to be of
+  the specified *type*.
+
+  For example, if `!cast<`*type*`>(`*name*`)`
+  appears in a multiclass definition, or in a
+  class instantiated inside a multiclass definition, and the *name* does not
+  reference any template arguments of the multiclass, then a record by
+  that name must have been instantiated earlier
+  in the source file. If *name* does reference
+  a template argument, then the lookup is delayed until `defm` statements
+  instantiating the multiclass (or later, if the defm occurs in another
+  multiclass and template arguments of the inner multiclass that are
+  referenced by *name* are substituted by values that themselves contain
+  references to template arguments of the outer multiclass).
+
+  If the type of *a* does not match *type*, TableGen raises an error.
+
+`!con(`*a*`,` *b*`, ...)`
+
+: This operator concatenates the DAG nodes *a*, *b*, etc. Their operations
+  must equal.
+
+  `!con((op:$lhs a1:$name1, a2:$name2), (op:$rhs b1:$name3))`
+
+  results in the DAG node `(op:$lhs a1:$name1, a2:$name2, b1:$name3)`.
+  The name of the dag operator is derived from the LHS DAG node if it is
+  set, otherwise from the RHS DAG node.
+
+`!cond(`*cond1* `:` *val1*`,` *cond2* `:` *val2*`, ...,` *condn* `:` *valn*`)`
+
+: This operator tests *cond1* and returns *val1* if the result is true.
+  If false, the operator tests *cond2* and returns *val2* if the result is
+  true. And so forth. An error is reported if no conditions are true.
+
+  !cond short-circuits at the first true condition, resolving to that
+  condition's corresponding value. Subsequent conditions and values are left
+  unresolved.
+
+  This example produces the sign word for an integer:
+
+  ```
+  !cond(!lt(x, 0) : "negative", !eq(x, 0) : "zero", true : "positive")
+  ```
+
+`!dag(`*op*`,` *arguments*`,` *names*`)`
+
+: This operator creates a DAG node with the given operator and
+  arguments. The *arguments* and *names* arguments must be lists
+  of equal length or uninitialized (`?`). The *names* argument
+  must be of type `list<string>`.
+
+  Due to limitations of the type system, *arguments* must be a list of items
+  of a common type. In practice, this means that they should either have the
+  same type or be records with a common parent class. Mixing `dag` and
+  non-`dag` items is not possible. However, `?` can be used.
+
+  Example: `!dag(op, [a1, a2, ?], ["name1", "name2", "name3"])` results in
+  `(op a1-value:$name1, a2-value:$name2, ?:$name3)`.
+
+`!div(`*a*`,` *b*`)`
+
+: This operator performs signed division of *a* by *b*, and produces the quotient.
+  Division by 0 produces an error. Division of `INT64_MIN` by -1 produces an error.
+
+`!empty(`*a*`)`
+
+: This operator produces 1 if the string, list, or DAG *a* is empty; 0 otherwise.
+  A dag is empty if it has no arguments; the operator does not count.
+
+`!eq(` *a*`,` *b*`)`
+
+: This operator produces 1 if *a* is equal to *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, `string`, or
+  record values. Use `!cast<string>` to compare other types of objects.
+
+`!exists<`*type*`>(`*name*`)`
+
+: This operator produces 1 if a record of the given *type* whose name is *name*
+  exists; 0 otherwise. *name* should be of type *string*.
+
+`!filter(`*var*`,` *list*`,` *predicate*`)`
+
+> This operator creates a new `list` by filtering the elements in
+> *list*. To perform the filtering, TableGen binds the variable *var* to each
+> element and then evaluates the *predicate* expression, which presumably
+> refers to *var*. The predicate must
+> produce a boolean value (`bit`, `bits`, or `int`). The value is
+> interpreted as with `!if`:
+> if the value is 0, the element is not included in the new list. If the value
+> is anything else, the element is included.
+
+`!find(`*string1*`,` *string2*\[`,` *start*\]`)`
+
+: This operator searches for *string2* in *string1* and produces its
+  position. The starting position of the search may be specified by *start*,
+  which can range between 0 and the length of *string1*; the default is 0.
+  If the string is not found, the result is -1.
+
+`!foldl(`*init*`,` *list*`,` *acc*`,` *var*`,` *expr*`)`
+
+: This operator performs a left-fold over the items in *list*. The
+  variable *acc* acts as the accumulator and is initialized to *init*.
+  The variable *var* is bound to each element in the *list*. The
+  expression is evaluated for each element and presumably uses *acc* and
+  *var* to calculate the accumulated value, which `!foldl` stores back in
+  *acc*. The type of *acc* is the same as *init*; the type of *var* is the
+  same as the elements of *list*; *expr* must have the same type as *init*.
+
+  The following example computes the total of the `Number` field in the
+  list of records in `RecList`:
+
+  ```
+  int x = !foldl(0, RecList, total, rec, !add(total, rec.Number));
+  ```
+
+  If your goal is to filter the list and produce a new list that includes only
+  some of the elements, see `!filter`.
+
+`!foreach(`*var*`,` *sequence*`,` *expr*`)`
+
+: This operator creates a new `list`/`dag` in which each element is a
+  function of the corresponding element in the *sequence* `list`/`dag`.
+  To perform the function, TableGen binds the variable *var* to an element
+  and then evaluates the expression. The expression presumably refers
+  to the variable *var* and calculates the result value.
+
+  If you simply want to create a list of a certain length containing
+  the same value repeated multiple times, see `!listsplat`.
+
+`!ge(`*a*`,` *b*`)`
+
+: This operator produces 1 if *a* is greater than or equal to *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, or `string` values.
+
+`!getdagarg<`*type*`>(`*dag*`,`*key*`)`
+
+: This operator retrieves the argument from the given *dag* node by the
+  specified *key*, which is either an integer index or a string name. If that
+  argument is not convertible to the specified *type*, `?` is returned.
+
+`!getdagname(`*dag*`,`*index*`)`
+
+: This operator retrieves the argument name from the given *dag* node by the
+  specified *index*. If that argument has no name associated, `?` is
+  returned.
+
+`!getdagop(`*dag*`)` --or-- `!getdagop<`*type*`>(`*dag*`)`
+
+: This operator produces the operator of the given *dag* node.
+  Example: `!getdagop((foo 1, 2))` results in `foo`. Recall that
+  DAG operators are always records.
+
+  The result of `!getdagop` can be used directly in a context where
+  any record class at all is acceptable (typically placing it into
+  another dag value). But in other contexts, it must be explicitly
+  cast to a particular class. The `<`*type*`>` syntax is
+  provided to make this easy.
+
+  For example, to assign the result to a value of type `BaseClass`, you
+  could write either of these:
+
+  ```
+  BaseClass b = !getdagop<BaseClass>(someDag);
+  BaseClass b = !cast<BaseClass>(!getdagop(someDag));
+  ```
+
+  But to create a new DAG node that reuses the operator from another, no
+  cast is necessary:
+
+  ```
+  dag d = !dag(!getdagop(someDag), args, names);
+  ```
+
+`!getdagopname(`*dag*`)`
+
+: This operator retrieves the name of the given *dag* operator. If the operator
+  has no name associated, `?` is returned.
+
+`!gt(`*a*`,` *b*`)`
+
+: This operator produces 1 if *a* is greater than *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, or `string` values.
+
+`!head(`*a*`)`
+
+: This operator produces the zeroth element of the list *a*.
+  (See also `!tail`.)
+
+`!if(`*test*`,` *then*`,` *else*`)`
+
+: This operator evaluates the *test*, which must produce a `bit` or
+  `int`. If the result is not 0, the *then* expression is produced; otherwise
   the *else* expression is produced.
 
-``!initialized(``\ *a*\ ``)``
-  This operator produces 1 if *a* is not the uninitialized value (``?``) and 0
+`!initialized(`*a*`)`
+
+: This operator produces 1 if *a* is not the uninitialized value (`?`) and 0
   otherwise.
 
-``!instances<``\ *type*\ ``>([``\ *regex*\ ``])``
-    This operator produces a list of records whose type is *type*. If *regex*
-    is provided, only records whose name matches the regular expression *regex*
-    will be included. The format of *regex* is ERE (Extended POSIX Regular
-    Expressions).
-
-    If ``!instances`` is in a class/multiclass/foreach, only these records of
-    *type* that have been instantiated will be considered.
-
-``!interleave(``\ *list*\ ``,`` *delim*\ ``)``
-    This operator concatenates the items in the *list*, interleaving the
-    *delim* string between each pair, and produces the resulting string.
-    The list can be a list of string, int, bits, or bit. An empty list
-    results in an empty string. The delimiter can be the empty string.
-
-``!isa<``\ *type*\ ``>(``\ *a*\ ``)``
-    This operator produces 1 if the type of *a* is a subtype of the given *type*; 0
-    otherwise.
-
-``!le(``\ *a*\ ``,`` *b*\ ``)``
-    This operator produces 1 if *a* is less than or equal to *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values.
-
-``!listconcat(``\ *list1*\ ``,`` *list2*\ ``, ...)``
-    This operator concatenates the list arguments *list1*, *list2*, etc., and
-    produces the resulting list. The lists must have the same element type.
-
-``!listflatten(``\ *list*\ ``)``
-    This operator flattens a list of lists *list* and produces a list with all
-    elements of the constituent lists concatenated. If *list* is of type
-    ``list<list<X>>`` the resulting list is of type ``list<X>``. If *list*'s
-    element type is not a list, the result is *list* itself.
-
-``!listremove(``\ *list1*\ ``,`` *list2*\ ``)``
-    This operator returns a copy of *list1* removing all elements that also occur in
-    *list2*. The lists must have the same element type.
-
-``!listsplat(``\ *value*\ ``,`` *count*\ ``)``
-    This operator produces a list of length *count* whose elements are all
-    equal to the *value*. For example, ``!listsplat(42, 3)`` results in
-    ``[42, 42, 42]``.
-
-``!logtwo(``\ *a*\ ``)``
-    This operator produces the base 2 log of *a* and produces the integer
-    result. The log of 0 or a negative number produces an error. This
-    is a flooring operation.
-
-``!lt(``\ *a*\ `,` *b*\ ``)``
-    This operator produces 1 if *a* is less than *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values.
-
-``!match(``\ *str*\ `,` *regex*\ ``)``
-    This operator produces 1 if the *str* matches the regular expression
-    *regex*. The format of *regex* is ERE (Extended POSIX Regular Expressions).
-
-``!mul(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator multiplies *a*, *b*, etc., and produces the product.
-
-``!ne(``\ *a*\ `,` *b*\ ``)``
-    This operator produces 1 if *a* is not equal to *b*; 0 otherwise.
-    The arguments must be ``bit``, ``bits``, ``int``, ``string``,
-    or record values. Use ``!cast<string>`` to compare other types of objects.
-
-``!not(``\ *a*\ ``)``
-    This operator performs a logical NOT on *a*, which must be
-    an integer. The argument 0 results in 1 (true); any other
-    argument results in 0 (false).
-
-``!or(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator does a bitwise OR on *a*, *b*, etc., and produces the
-    result. A logical OR can be performed if all the arguments are either
-    0 or 1. This operator is short-circuit to -1 (all ones) when the left-most
-    operand is -1.
-
-``!range([``\ *start*\ ``,]`` *end*\ ``[,``\ *step*\ ``])``
-    This operator produces half-open range sequence ``[start : end : step)`` as
-    ``list<int>``. *start* is ``0`` and *step* is ``1`` by default. *step* can
-    be negative and cannot be 0. If *start* ``<`` *end* and *step* is negative,
-    or *start* ``>`` *end* and *step* is positive, the result is an empty list
-    ``[]<int>``.
-
-    For example:
-
-    * ``!range(4)`` is equivalent to ``!range(0, 4, 1)`` and the result is
-      `[0, 1, 2, 3]`.
-    * ``!range(1, 4)`` is equivalent to ``!range(1, 4, 1)`` and the result is
-      `[1, 2, 3]`.
-    * The result of ``!range(0, 4, 2)`` is `[0, 2]`.
-    * The results of ``!range(0, 4, -1)`` and ``!range(4, 0, 1)`` are empty.
-
-``!range(``\ *list*\ ``)``
-    Equivalent to ``!range(0, !size(list))``.
-
-``!repr(``\ *value*\ ``)``
-    Represents *value* as a string. The string format for the value is not
-    guaranteed to be stable. Intended for debugging purposes only.
-
-``!setdagarg(``\ *dag*\ ``,``\ *key*\ ``,``\ *arg*\ ``)``
-    This operator produces a DAG node with the same operator and arguments as
-    *dag*, but replacing the value of the argument specified by the *key* with
-    *arg*. That *key* could be either an integer index or a string name.
-
-``!setdagname(``\ *dag*\ ``,``\ *key*\ ``,``\ *name*\ ``)``
-    This operator produces a DAG node with the same operator and arguments as
-    *dag*, but replacing the name of the argument specified by the *key* with
-    *name*. That *key* could be either an integer index or a string name.
-
-``!setdagop(``\ *dag*\ ``,`` *op*\ ``)``
-    This operator produces a DAG node with the same arguments as *dag*, but with its
-    operator replaced with *op*.
-
-    Example: ``!setdagop((foo 1, 2), bar)`` results in ``(bar 1, 2)``.
-
-``!setdagopname(``\ *dag*\ ``,``\ *name*\ ``)``
-    This operator produces a DAG node with the same operator and arguments as
-    *dag*, but replacing the name of the operator with *name*.
-
-``!shl(``\ *a*\ ``,`` *count*\ ``)``
-    This operator shifts *a* left logically by *count* bits and produces the resulting
-    value. The operation is performed on a 64-bit integer; the result
-    is undefined for shift counts outside 0...63.
-
-``!size(``\ *a*\ ``)``
-    This operator produces the size of the string, list, or dag *a*.
-    The size of a DAG is the number of arguments; the operator does not count.
-
-``!sort(``\ *var*\ ``,`` *list*\ ``,`` *key*\ ``)``
-    This operator creates a new ``list`` containing the same elements as *list*
-    but in sorted order. To determine the order, TableGen binds the variable
-    *var* to each element and evaluates the *key* expression, which presumably
-    refers to *var*. The key must produce a ``string`` or integer value
-    (``bit``, ``bits``, or ``int``); all keys must be of the same type. Elements
-    with equal keys preserve their original relative order, resulting in a
-    stable sort.
-
-    For example, to sort a list of records by their ``Name`` field::
-
-    .. code-block:: text
-
-      list<Thing> sorted = !sort(t, Things, t.Name);
-
-``!sra(``\ *a*\ ``,`` *count*\ ``)``
-    This operator shifts *a* right arithmetically by *count* bits and produces the resulting
-    value. The operation is performed on a 64-bit integer; the result
-    is undefined for shift counts outside 0...63.
-
-``!srl(``\ *a*\ ``,`` *count*\ ``)``
-    This operator shifts *a* right logically by *count* bits and produces the resulting
-    value. The operation is performed on a 64-bit integer; the result
-    is undefined for shift counts outside 0...63.
-
-``!strconcat(``\ *str1*\ ``,`` *str2*\ ``, ...)``
-    This operator concatenates the string arguments *str1*, *str2*, etc., and
-    produces the resulting string.
-
-``!sub(``\ *a*\ ``,`` *b*\ ``)``
-    This operator subtracts *b* from *a* and produces the arithmetic difference.
-
-``!subst(``\ *target*\ ``,`` *repl*\ ``,`` *value*\ ``)``
-    This operator replaces all occurrences of the *target* in the *value* with
-    the *repl* and produces the resulting value. The *value* can
-    be a string, in which case substring substitution is performed.
-
-    The *value* can be a record name, in which case the operator produces the *repl*
-    record if the *target* record name equals the *value* record name; otherwise it
-    produces the *value*.
-
-``!substr(``\ *string*\ ``,`` *start*\ [``,`` *length*]\ ``)``
-    This operator extracts a substring of the given *string*. The starting
-    position of the substring is specified by *start*, which can range
-    between 0 and the length of the string. The length of the substring
-    is specified by *length*; if not specified, the rest of the string is
-    extracted. The *start* and *length* arguments must be integers.
+`!instances<`*type*`>([`*regex*`])`
 
-``!switch(``\ *key*\ ``,`` *case1* ``:`` *val1*\ ``, ...,`` *casen* ``:`` *valn*\ ``,`` *default*\ ``)``
-    This operator compares *key* to each *casei* in turn using ``!eq``.
-    If *key* equals *casei*, the operator returns *vali*. If no case
-    matches, the operator returns *default* --- the trailing argument
-    with no ``:`` is the default value, identified by position. Both 
-    the trailing default and at least one *casei* : *vali* pair are 
-    mandatory.
+: This operator produces a list of records whose type is *type*. If *regex*
+  is provided, only records whose name matches the regular expression *regex*
+  will be included. The format of *regex* is ERE (Extended POSIX Regular
+  Expressions).
 
-    ``!switch`` is a compact form of ``!cond`` using ``!eq`` comparisons.
-    The expression ``!switch(key, c1: v1, c2: v2, vd)`` is equivalent to
-    ``!cond(!eq(key, c1): v1, !eq(key, c2): v2, true: vd)``.
+  If `!instances` is in a class/multiclass/foreach, only these records of
+  *type* that have been instantiated will be considered.
 
-    This example maps an integer size to a register-class name::
+`!interleave(`*list*`,` *delim*`)`
 
-    !switch(size, 1: "byte", 2: "halfword", 4: "word", "unknown")
+: This operator concatenates the items in the *list*, interleaving the
+  *delim* string between each pair, and produces the resulting string.
+  The list can be a list of string, int, bits, or bit. An empty list
+  results in an empty string. The delimiter can be the empty string.
 
-    (See also ``!cond``.)
+`!isa<`*type*`>(`*a*`)`
 
-``!tail(``\ *a*\ ``)``
-    This operator produces a new list with all the elements
-    of the list *a* except for the zeroth one. (See also ``!head``.)
+: This operator produces 1 if the type of *a* is a subtype of the given *type*; 0
+  otherwise.
 
-``!tolower(``\ *a*\ ``)``
-  This operator converts a string input *a* to lower case.
+`!le(`*a*`,` *b*`)`
 
-``!toupper(``\ *a*\ ``)``
-  This operator converts a string input *a* to upper case.
+: This operator produces 1 if *a* is less than or equal to *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, or `string` values.
 
-``!xor(``\ *a*\ ``,`` *b*\ ``, ...)``
-    This operator does a bitwise EXCLUSIVE OR on *a*, *b*, etc., and produces
-    the result. A logical XOR can be performed if all the arguments are either
-    0 or 1.
+`!listconcat(`*list1*`,` *list2*`, ...)`
 
-Appendix B: Paste Operator Examples
-===================================
+: This operator concatenates the list arguments *list1*, *list2*, etc., and
+  produces the resulting list. The lists must have the same element type.
 
-Here is an example illustrating the use of the paste operator in record names.
+`!listflatten(`*list*`)`
 
-.. code-block:: text
+: This operator flattens a list of lists *list* and produces a list with all
+  elements of the constituent lists concatenated. If *list* is of type
+  `list<list<X>>` the resulting list is of type `list<X>`. If *list*'s
+  element type is not a list, the result is *list* itself.
 
-  defvar suffix = "_suffstring";
-  defvar some_ints = [0, 1, 2, 3];
+`!listremove(`*list1*`,` *list2*`)`
 
-  def name # suffix {
-  }
+: This operator returns a copy of *list1* removing all elements that also occur in
+  *list2*. The lists must have the same element type.
 
-  foreach i = [1, 2] in {
-  def rec # i {
-  }
-  }
+`!listsplat(`*value*`,` *count*`)`
 
-The first ``def`` does not use the value of the ``suffix`` variable. The
-second def does use the value of the ``i`` iterator variable, because it is not a
-global name. The following records are produced.
+: This operator produces a list of length *count* whose elements are all
+  equal to the *value*. For example, `!listsplat(42, 3)` results in
+  `[42, 42, 42]`.
 
-.. code-block:: text
+`!logtwo(`*a*`)`
 
-  def namesuffix {
-  }
-  def rec1 {
-  }
-  def rec2 {
-  }
+: This operator produces the base 2 log of *a* and produces the integer
+  result. The log of 0 or a negative number produces an error. This
+  is a flooring operation.
 
-Here is a second example illustrating the paste operator in field value expressions.
+`!lt(`*a*`,` *b*`)`
 
-.. code-block:: text
+: This operator produces 1 if *a* is less than *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, or `string` values.
 
-  def test {
-    string strings = suffix # suffix;
-    list<int> integers = some_ints # [4, 5, 6];
-  }
+`!match(`*str*`,` *regex*`)`
 
-The ``strings`` field expression uses ``suffix`` on both sides of the paste
-operator. It is evaluated normally on the left hand side, but taken verbatim
-on the right hand side. The ``integers`` field expression uses the value of
-the ``some_ints`` variable and a literal list. The following record is
-produced.
+: This operator produces 1 if the *str* matches the regular expression
+  *regex*. The format of *regex* is ERE (Extended POSIX Regular Expressions).
 
-.. code-block:: text
+`!mul(`*a*`,` *b*`, ...)`
 
-  def test {
-    string strings = "_suffstringsuffix";
-    list<int> ints = [0, 1, 2, 3, 4, 5, 6];
-  }
+: This operator multiplies *a*, *b*, etc., and produces the product.
 
+`!ne(`*a*`,` *b*`)`
 
-Appendix C: Sample Record
-=========================
+: This operator produces 1 if *a* is not equal to *b*; 0 otherwise.
+  The arguments must be `bit`, `bits`, `int`, `string`,
+  or record values. Use `!cast<string>` to compare other types of objects.
+
+`!not(`*a*`)`
+
+: This operator performs a logical NOT on *a*, which must be
+  an integer. The argument 0 results in 1 (true); any other
+  argument results in 0 (false).
+
+`!or(`*a*`,` *b*`, ...)`
+
+: This operator does a bitwise OR on *a*, *b*, etc., and produces the
+  result. A logical OR can be performed if all the arguments are either
+  0 or 1. This operator is short-circuit to -1 (all ones) when the left-most
+  operand is -1.
+
+`!range([`*start*`,]` *end*`[,`*step*`])`
+
+: This operator produces half-open range sequence `[start : end : step)` as
+  `list<int>`. *start* is `0` and *step* is `1` by default. *step* can
+  be negative and cannot be 0. If *start* `<` *end* and *step* is negative,
+  or *start* `>` *end* and *step* is positive, the result is an empty list
+  `[]<int>`.
+
+  For example:
+
+  - `!range(4)` is equivalent to `!range(0, 4, 1)` and the result is
+    `[0, 1, 2, 3]`.
+  - `!range(1, 4)` is equivalent to `!range(1, 4, 1)` and the result is
+    `[1, 2, 3]`.
+  - The result of `!range(0, 4, 2)` is `[0, 2]`.
+  - The results of `!range(0, 4, -1)` and `!range(4, 0, 1)` are empty.
+
+`!range(`*list*`)`
+
+: Equivalent to `!range(0, !size(list))`.
+
+`!repr(`*value*`)`
+
+: Represents *value* as a string. The string format for the value is not
+  guaranteed to be stable. Intended for debugging purposes only.
+
+`!setdagarg(`*dag*`,`*key*`,`*arg*`)`
+
+: This operator produces a DAG node with the same operator and arguments as
+  *dag*, but replacing the value of the argument specified by the *key* with
+  *arg*. That *key* could be either an integer index or a string name.
+
+`!setdagname(`*dag*`,`*key*`,`*name*`)`
+
+: This operator produces a DAG node with the same operator and arguments as
+  *dag*, but replacing the name of the argument specified by the *key* with
+  *name*. That *key* could be either an integer index or a string name.
+
+`!setdagop(`*dag*`,` *op*`)`
+
+: This operator produces a DAG node with the same arguments as *dag*, but with its
+  operator replaced with *op*.
+
+  Example: `!setdagop((foo 1, 2), bar)` results in `(bar 1, 2)`.
+
+`!setdagopname(`*dag*`,`*name*`)`
+
+: This operator produces a DAG node with the same operator and arguments as
+  *dag*, but replacing the name of the operator with *name*.
+
+`!shl(`*a*`,` *count*`)`
+
+: This operator shifts *a* left logically by *count* bits and produces the resulting
+  value. The operation is performed on a 64-bit integer; the result
+  is undefined for shift counts outside 0...63.
+
+`!size(`*a*`)`
+
+: This operator produces the size of the string, list, or dag *a*.
+  The size of a DAG is the number of arguments; the operator does not count.
+
+`!sort(`*var*`,` *list*`,` *key*`)`
+
+: This operator creates a new `list` containing the same elements as *list*
+  but in sorted order. To determine the order, TableGen binds the variable
+  *var* to each element and evaluates the *key* expression, which presumably
+  refers to *var*. The key must produce a `string` or integer value
+  (`bit`, `bits`, or `int`); all keys must be of the same type. Elements
+  with equal keys preserve their original relative order, resulting in a
+  stable sort.
+
+  For example, to sort a list of records by their `Name` field:
+
+  ```
+  .. code-block:: text
+  ```
+
+  > list\<Thing> sorted = !sort(t, Things, t.Name);
+
+`!sra(`*a*`,` *count*`)`
+
+: This operator shifts *a* right arithmetically by *count* bits and produces the resulting
+  value. The operation is performed on a 64-bit integer; the result
+  is undefined for shift counts outside 0...63.
+
+`!srl(`*a*`,` *count*`)`
+
+: This operator shifts *a* right logically by *count* bits and produces the resulting
+  value. The operation is performed on a 64-bit integer; the result
+  is undefined for shift counts outside 0...63.
+
+`!strconcat(`*str1*`,` *str2*`, ...)`
+
+: This operator concatenates the string arguments *str1*, *str2*, etc., and
+  produces the resulting string.
+
+`!sub(`*a*`,` *b*`)`
+
+: This operator subtracts *b* from *a* and produces the arithmetic difference.
+
+`!subst(`*target*`,` *repl*`,` *value*`)`
+
+: This operator replaces all occurrences of the *target* in the *value* with
+  the *repl* and produces the resulting value. The *value* can
+  be a string, in which case substring substitution is performed.
+
+  The *value* can be a record name, in which case the operator produces the *repl*
+  record if the *target* record name equals the *value* record name; otherwise it
+  produces the *value*.
+
+`!substr(`*string*`,` *start*\[`,` *length*\]`)`
+
+: This operator extracts a substring of the given *string*. The starting
+  position of the substring is specified by *start*, which can range
+  between 0 and the length of the string. The length of the substring
+  is specified by *length*; if not specified, the rest of the string is
+  extracted. The *start* and *length* arguments must be integers.
+
+`!switch(`*key*`,` *case1* `:` *val1*`, ...,` *casen* `:` *valn*`,` *default*`)`
+
+: This operator compares *key* to each *casei* in turn using `!eq`.
+  If *key* equals *casei*, the operator returns *vali*. If no case
+  matches, the operator returns *default* --- the trailing argument
+  with no `:` is the default value, identified by position. Both
+  the trailing default and at least one *casei* : *vali* pair are
+  mandatory.
+
+  `!switch` is a compact form of `!cond` using `!eq` comparisons.
+  The expression `!switch(key, c1: v1, c2: v2, vd)` is equivalent to
+  `!cond(!eq(key, c1): v1, !eq(key, c2): v2, true: vd)`.
+
+  This example maps an integer size to a register-class name:
+
+  ```
+  !switch(size, 1: "byte", 2: "halfword", 4: "word", "unknown")
+  ```
+
+  (See also `!cond`.)
+
+`!tail(`*a*`)`
+
+: This operator produces a new list with all the elements
+  of the list *a* except for the zeroth one. (See also `!head`.)
+
+`!tolower(`*a*`)`
+
+: This operator converts a string input *a* to lower case.
+
+`!toupper(`*a*`)`
+
+: This operator converts a string input *a* to upper case.
+
+`!xor(`*a*`,` *b*`, ...)`
+
+: This operator does a bitwise EXCLUSIVE OR on *a*, *b*, etc., and produces
+  the result. A logical XOR can be performed if all the arguments are either
+  0 or 1.
+
+## Appendix B: Paste Operator Examples
+
+Here is an example illustrating the use of the paste operator in record names.
+
+```text
+defvar suffix = "_suffstring";
+defvar some_ints = [0, 1, 2, 3];
+
+def name # suffix {
+}
+
+foreach i = [1, 2] in {
+def rec # i {
+}
+}
+```
+
+The first `def` does not use the value of the `suffix` variable. The
+second def does use the value of the `i` iterator variable, because it is not a
+global name. The following records are produced.
+
+```text
+def namesuffix {
+}
+def rec1 {
+}
+def rec2 {
+}
+```
+
+Here is a second example illustrating the paste operator in field value expressions.
+
+```text
+def test {
+  string strings = suffix # suffix;
+  list<int> integers = some_ints # [4, 5, 6];
+}
+```
+
+The `strings` field expression uses `suffix` on both sides of the paste
+operator. It is evaluated normally on the left hand side, but taken verbatim
+on the right hand side. The `integers` field expression uses the value of
+the `some_ints` variable and a literal list. The following record is
+produced.
+
+```text
+def test {
+  string strings = "_suffstringsuffix";
+  list<int> ints = [0, 1, 2, 3, 4, 5, 6];
+}
+```
+
+## Appendix C: Sample Record
 
 One target machine supported by LLVM is the Intel x86. The following output
 from TableGen shows the record that is created to represent the 32-bit
 register-to-register ADD instruction.
 
-.. code-block:: text
-
-  def ADD32rr {	// InstructionEncoding Instruction X86Inst I ITy Sched BinOpRR BinOpRR_RF
-    int Size = 0;
-    string DecoderNamespace = "";
-    list<Predicate> Predicates = [];
-    string DecoderMethod = "";
-    bit hasCompleteDecoder = 1;
-    string Namespace = "X86";
-    dag OutOperandList = (outs GR32:$dst);
-    dag InOperandList = (ins GR32:$src1, GR32:$src2);
-    string AsmString = "add{l}	{$src2, $src1|$src1, $src2}";
-    EncodingByHwMode EncodingInfos = ?;
-    list<dag> Pattern = [(set GR32:$dst, EFLAGS, (X86add_flag GR32:$src1, GR32:$src2))];
-    list<Register> Uses = [];
-    list<Register> Defs = [EFLAGS];
-    int CodeSize = 3;
-    int AddedComplexity = 0;
-    bit isPreISelOpcode = 0;
-    bit isReturn = 0;
-    bit isBranch = 0;
-    bit isEHScopeReturn = 0;
-    bit isIndirectBranch = 0;
-    bit isCompare = 0;
-    bit isMoveImm = 0;
-    bit isMoveReg = 0;
-    bit isBitcast = 0;
-    bit isSelect = 0;
-    bit isBarrier = 0;
-    bit isCall = 0;
-    bit isAdd = 0;
-    bit isTrap = 0;
-    bit canFoldAsLoad = 0;
-    bit mayLoad = ?;
-    bit mayStore = ?;
-    bit mayRaiseFPException = 0;
-    bit isConvertibleToThreeAddress = 1;
-    bit isCommutable = 1;
-    bit isTerminator = 0;
-    bit isReMaterializable = 0;
-    bit isPredicable = 0;
-    bit isUnpredicable = 0;
-    bit hasDelaySlot = 0;
-    bit usesCustomInserter = 0;
-    bit hasPostISelHook = 0;
-    bit hasCtrlDep = 0;
-    bit isNotDuplicable = 0;
-    bit isConvergent = 0;
-    bit isAuthenticated = 0;
-    bit isAsCheapAsAMove = 0;
-    bit hasExtraSrcRegAllocReq = 0;
-    bit hasExtraDefRegAllocReq = 0;
-    bit isRegSequence = 0;
-    bit isPseudo = 0;
-    bit isExtractSubreg = 0;
-    bit isInsertSubreg = 0;
-    bit variadicOpsAreDefs = 0;
-    bit hasSideEffects = ?;
-    bit isCodeGenOnly = 0;
-    bit isAsmParserOnly = 0;
-    bit hasNoSchedulingInfo = 0;
-    InstrItinClass Itinerary = NoItinerary;
-    list<SchedReadWrite> SchedRW = [WriteALU];
-    string Constraints = "$src1 = $dst";
-    string DisableEncoding = "";
-    string PostEncoderMethod = "";
-    bits<64> TSFlags = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 };
-    string AsmMatchConverter = "";
-    string TwoOperandAliasConstraint = "";
-    string AsmVariantName = "";
-    bit UseNamedOperandTable = 0;
-    bit FastISelShouldIgnore = 0;
-    bits<8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 1 };
-    Format Form = MRMDestReg;
-    bits<7> FormBits = { 0, 1, 0, 1, 0, 0, 0 };
-    ImmType ImmT = NoImm;
-    bit ForceDisassemble = 0;
-    OperandSize OpSize = OpSize32;
-    bits<2> OpSizeBits = { 1, 0 };
-    AddressSize AdSize = AdSizeX;
-    bits<2> AdSizeBits = { 0, 0 };
-    Prefix OpPrefix = NoPrfx;
-    bits<3> OpPrefixBits = { 0, 0, 0 };
-    Map OpMap = OB;
-    bits<3> OpMapBits = { 0, 0, 0 };
-    bit hasREX_WPrefix = 0;
-    FPFormat FPForm = NotFP;
-    bit hasLockPrefix = 0;
-    Domain ExeDomain = GenericDomain;
-    bit hasREPPrefix = 0;
-    Encoding OpEnc = EncNormal;
-    bits<2> OpEncBits = { 0, 0 };
-    bit HasVEX_W = 0;
-    bit IgnoresVEX_W = 0;
-    bit EVEX_W1_VEX_W0 = 0;
-    bit hasVEX_4V = 0;
-    bit hasVEX_L = 0;
-    bit ignoresVEX_L = 0;
-    bit hasEVEX_K = 0;
-    bit hasEVEX_Z = 0;
-    bit hasEVEX_L2 = 0;
-    bit hasEVEX_B = 0;
-    bits<3> CD8_Form = { 0, 0, 0 };
-    int CD8_EltSize = 0;
-    bit hasEVEX_RC = 0;
-    bit hasNoTrackPrefix = 0;
-    bits<7> VectSize = { 0, 0, 1, 0, 0, 0, 0 };
-    bits<7> CD8_Scale = { 0, 0, 0, 0, 0, 0, 0 };
-    string FoldGenRegForm = ?;
-    string EVEX2VEXOverride = ?;
-    bit isMemoryFoldable = 1;
-    bit notEVEX2VEXConvertible = 0;
-  }
-
-On the first line of the record, you can see that the ``ADD32rr`` record
+```text
+def ADD32rr { // InstructionEncoding Instruction X86Inst I ITy Sched BinOpRR BinOpRR_RF
+  int Size = 0;
+  string DecoderNamespace = "";
+  list<Predicate> Predicates = [];
+  string DecoderMethod = "";
+  bit hasCompleteDecoder = 1;
+  string Namespace = "X86";
+  dag OutOperandList = (outs GR32:$dst);
+  dag InOperandList = (ins GR32:$src1, GR32:$src2);
+  string AsmString = "add{l}  {$src2, $src1|$src1, $src2}";
+  EncodingByHwMode EncodingInfos = ?;
+  list<dag> Pattern = [(set GR32:$dst, EFLAGS, (X86add_flag GR32:$src1, GR32:$src2))];
+  list<Register> Uses = [];
+  list<Register> Defs = [EFLAGS];
+  int CodeSize = 3;
+  int AddedComplexity = 0;
+  bit isPreISelOpcode = 0;
+  bit isReturn = 0;
+  bit isBranch = 0;
+  bit isEHScopeReturn = 0;
+  bit isIndirectBranch = 0;
+  bit isCompare = 0;
+  bit isMoveImm = 0;
+  bit isMoveReg = 0;
+  bit isBitcast = 0;
+  bit isSelect = 0;
+  bit isBarrier = 0;
+  bit isCall = 0;
+  bit isAdd = 0;
+  bit isTrap = 0;
+  bit canFoldAsLoad = 0;
+  bit mayLoad = ?;
+  bit mayStore = ?;
+  bit mayRaiseFPException = 0;
+  bit isConvertibleToThreeAddress = 1;
+  bit isCommutable = 1;
+  bit isTerminator = 0;
+  bit isReMaterializable = 0;
+  bit isPredicable = 0;
+  bit isUnpredicable = 0;
+  bit hasDelaySlot = 0;
+  bit usesCustomInserter = 0;
+  bit hasPostISelHook = 0;
+  bit hasCtrlDep = 0;
+  bit isNotDuplicable = 0;
+  bit isConvergent = 0;
+  bit isAuthenticated = 0;
+  bit isAsCheapAsAMove = 0;
+  bit hasExtraSrcRegAllocReq = 0;
+  bit hasExtraDefRegAllocReq = 0;
+  bit isRegSequence = 0;
+  bit isPseudo = 0;
+  bit isExtractSubreg = 0;
+  bit isInsertSubreg = 0;
+  bit variadicOpsAreDefs = 0;
+  bit hasSideEffects = ?;
+  bit isCodeGenOnly = 0;
+  bit isAsmParserOnly = 0;
+  bit hasNoSchedulingInfo = 0;
+  InstrItinClass Itinerary = NoItinerary;
+  list<SchedReadWrite> SchedRW = [WriteALU];
+  string Constraints = "$src1 = $dst";
+  string DisableEncoding = "";
+  string PostEncoderMethod = "";
+  bits<64> TSFlags = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 };
+  string AsmMatchConverter = "";
+  string TwoOperandAliasConstraint = "";
+  string AsmVariantName = "";
+  bit UseNamedOperandTable = 0;
+  bit FastISelShouldIgnore = 0;
+  bits<8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 1 };
+  Format Form = MRMDestReg;
+  bits<7> FormBits = { 0, 1, 0, 1, 0, 0, 0 };
+  ImmType ImmT = NoImm;
+  bit ForceDisassemble = 0;
+  OperandSize OpSize = OpSize32;
+  bits<2> OpSizeBits = { 1, 0 };
+  AddressSize AdSize = AdSizeX;
+  bits<2> AdSizeBits = { 0, 0 };
+  Prefix OpPrefix = NoPrfx;
+  bits<3> OpPrefixBits = { 0, 0, 0 };
+  Map OpMap = OB;
+  bits<3> OpMapBits = { 0, 0, 0 };
+  bit hasREX_WPrefix = 0;
+  FPFormat FPForm = NotFP;
+  bit hasLockPrefix = 0;
+  Domain ExeDomain = GenericDomain;
+  bit hasREPPrefix = 0;
+  Encoding OpEnc = EncNormal;
+  bits<2> OpEncBits = { 0, 0 };
+  bit HasVEX_W = 0;
+  bit IgnoresVEX_W = 0;
+  bit EVEX_W1_VEX_W0 = 0;
+  bit hasVEX_4V = 0;
+  bit hasVEX_L = 0;
+  bit ignoresVEX_L = 0;
+  bit hasEVEX_K = 0;
+  bit hasEVEX_Z = 0;
+  bit hasEVEX_L2 = 0;
+  bit hasEVEX_B = 0;
+  bits<3> CD8_Form = { 0, 0, 0 };
+  int CD8_EltSize = 0;
+  bit hasEVEX_RC = 0;
+  bit hasNoTrackPrefix = 0;
+  bits<7> VectSize = { 0, 0, 1, 0, 0, 0, 0 };
+  bits<7> CD8_Scale = { 0, 0, 0, 0, 0, 0, 0 };
+  string FoldGenRegForm = ?;
+  string EVEX2VEXOverride = ?;
+  bit isMemoryFoldable = 1;
+  bit notEVEX2VEXConvertible = 0;
+}
+```
+
+On the first line of the record, you can see that the `ADD32rr` record
 inherited from eight classes. Although the inheritance hierarchy is complex,
 using parent classes is much simpler than specifying the 109 individual
 fields for each instruction.
 
-Here is the code fragment used to define ``ADD32rr`` and multiple other
-``ADD`` instructions:
-
-.. code-block:: text
+Here is the code fragment used to define `ADD32rr` and multiple other
+`ADD` instructions:
 
-  defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
-                           X86add_flag, add, 1, 1, 1>;
+```text
+defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
+                         X86add_flag, add, 1, 1, 1>;
+```
 
-The ``defm`` statement tells TableGen that ``ArithBinOp_RF`` is a
+The `defm` statement tells TableGen that `ArithBinOp_RF` is a
 multiclass, which contains multiple concrete record definitions that inherit
-from ``BinOpRR_RF``. That class, in turn, inherits from ``BinOpRR``, which
-inherits from ``ITy`` and ``Sched``, and so forth. The fields are inherited
-from all the parent classes; for example, ``IsIndirectBranch`` is inherited
-from the ``Instruction`` class.
+from `BinOpRR_RF`. That class, in turn, inherits from `BinOpRR`, which
+inherits from `ITy` and `Sched`, and so forth. The fields are inherited
+from all the parent classes; for example, `IsIndirectBranch` is inherited
+from the `Instruction` class.
+
+[python's]: http://docs.python.org/py3k/reference/introduction.html#notation
+
diff --git a/llvm/docs/TransformMetadata.md b/llvm/docs/TransformMetadata.md
index 42ba63981c468..302a35944db72 100644
--- a/llvm/docs/TransformMetadata.md
+++ b/llvm/docs/TransformMetadata.md
@@ -1,12 +1,8 @@
-.. _transformation-metadata:
+(transformation-metadata)=
 
-============================
-Code Transformation Metadata
-============================
+# Code Transformation Metadata
 
-
-Overview
-========
+## Overview
 
 LLVM transformation passes can be controlled by attaching metadata to
 the code to transform. By default, transformation passes use heuristics
@@ -26,38 +22,36 @@ user/programmer. OpenMP pragmas are an example of the latter.
 If any such metadata is dropped from the program, the code's semantics
 must not change.
 
-Metadata on Loops
-=================
+## Metadata on Loops
 
-Attributes can be attached to loops as described in :ref:`llvm.loop`.
+Attributes can be attached to loops as described in {ref}`llvm.loop`.
 Attributes can describe properties of the loop, disable transformations,
 force specific transformations and set transformation options.
 
 Because metadata nodes are immutable (with the exception of
-``MDNode::replaceOperandWith`` which is dangerous to use on uniqued
-metadata), in order to add or remove a loop attributes, a new ``MDNode``
-must be created and assigned as the new ``llvm.loop`` metadata. Any
-connection between the old ``MDNode`` and the loop is lost. The
-``llvm.loop`` node is also used as LoopID (``Loop::getLoopID()``), i.e.
+`MDNode::replaceOperandWith` which is dangerous to use on uniqued
+metadata), in order to add or remove a loop attributes, a new `MDNode`
+must be created and assigned as the new `llvm.loop` metadata. Any
+connection between the old `MDNode` and the loop is lost. The
+`llvm.loop` node is also used as LoopID (`Loop::getLoopID()`), i.e.
 the loop effectively gets a new identifier. For instance,
-``llvm.mem.parallel_loop_access`` references the LoopID. Therefore, if
+`llvm.mem.parallel_loop_access` references the LoopID. Therefore, if
 the parallel access property is to be preserved after adding/removing
-loop attributes, any ``llvm.mem.parallel_loop_access`` reference must be
+loop attributes, any `llvm.mem.parallel_loop_access` reference must be
 updated to the new LoopID.
 
-Transformation Metadata Structure
-=================================
+## Transformation Metadata Structure
 
 Some attributes describe code transformations (unrolling, vectorizing,
 loop distribution, etc.). They can either be a hint to the optimizer
 that a transformation might be beneficial, instruction to use a specific
 option, , or convey a specific request from the user (such as
-``#pragma clang loop`` or ``#pragma omp simd``).
+`#pragma clang loop` or `#pragma omp simd`).
 
 If a transformation is forced but cannot be carried-out for any reason,
 an optimization-missed warning must be emitted. Semantic information
 such as a transformation being safe (e.g.
-``llvm.mem.parallel_loop_access``) can be unused by the optimizer
+`llvm.mem.parallel_loop_access`) can be unused by the optimizer
 without generating a warning.
 
 Unless explicitly disabled, any optimization pass may heuristically
@@ -66,47 +60,47 @@ metadata for another transformation was specified, applying a different
 transformation before it might be inadvertent due to being applied on a
 different loop or the loop not existing anymore. To avoid having to
 explicitly disable an unknown number of passes, the attribute
-``llvm.loop.disable_nonforced`` disables all optional, high-level,
+`llvm.loop.disable_nonforced` disables all optional, high-level,
 restructuring transformations.
 
 The following example avoids the loop being altered before being
 vectorized, for instance being unrolled.
 
-.. code-block:: llvm
-
-      br i1 %exitcond, label %for.exit, label %for.header, !llvm.loop !0
-    ...
-    !0 = distinct !{!0, !1, !2}
-    !1 = !{!"llvm.loop.vectorize.enable"}
-    !2 = !{!"llvm.loop.disable_nonforced"}
+```llvm
+  br i1 %exitcond, label %for.exit, label %for.header, !llvm.loop !0
+...
+!0 = distinct !{!0, !1, !2}
+!1 = !{!"llvm.loop.vectorize.enable"}
+!2 = !{!"llvm.loop.disable_nonforced"}
+```
 
 After a transformation is applied, follow-up attributes are set on the
 transformed and/or new loop(s). This allows additional attributes
 including followup-transformations to be specified. Specifying multiple
 transformations in the same metadata node is possible for compatibility
 reasons, but their execution order is undefined. For instance, when
-``llvm.loop.vectorize.enable`` and ``llvm.loop.unroll.enable`` are
+`llvm.loop.vectorize.enable` and `llvm.loop.unroll.enable` are
 specified at the same time, unrolling may occur either before or after
 vectorization.
 
 As an example, the following instructs a loop to be vectorized and only
 then unrolled.
 
-.. code-block:: llvm
-
-    !0 = distinct !{!0, !1, !2, !3}
-    !1 = !{!"llvm.loop.vectorize.enable"}
-    !2 = !{!"llvm.loop.disable_nonforced"}
-    !3 = !{!"llvm.loop.vectorize.followup_vectorized", !{"llvm.loop.unroll.enable"}}
+```llvm
+!0 = distinct !{!0, !1, !2, !3}
+!1 = !{!"llvm.loop.vectorize.enable"}
+!2 = !{!"llvm.loop.disable_nonforced"}
+!3 = !{!"llvm.loop.vectorize.followup_vectorized", !{"llvm.loop.unroll.enable"}}
+```
 
 If, and only if, no followup is specified, the pass may add attributes itself.
-For instance, the vectorizer adds a ``llvm.loop.isvectorized`` attribute and
+For instance, the vectorizer adds a `llvm.loop.isvectorized` attribute and
 all attributes from the original loop excluding its loop vectorizer
 attributes. To avoid this, an empty followup attribute can be used, e.g.
 
-.. code-block:: llvm
-
-    !3 = !{!"llvm.loop.vectorize.followup_vectorized"}
+```llvm
+!3 = !{!"llvm.loop.vectorize.followup_vectorized"}
+```
 
 The followup attributes of a transformation that cannot be applied will
 never be added to a loop and are therefore effectively ignored. This means
@@ -116,88 +110,85 @@ The user should receive a warning about the first transformation in the
 transformation chain that could not be applied if it a forced
 transformation. All following transformations are skipped.
 
-Pass-Specific Transformation Metadata
-=====================================
+## Pass-Specific Transformation Metadata
 
 Transformation options are specific to each transformation. In the
 following, we present the model for each LLVM loop optimization pass and
 the metadata to influence them.
 
-Loop Vectorization and Interleaving
------------------------------------
+### Loop Vectorization and Interleaving
 
 Loop vectorization and interleaving is interpreted as a single
 transformation. It is interpreted as forced if
-``!{"llvm.loop.vectorize.enable"}`` is set.
+`!{"llvm.loop.vectorize.enable"}` is set.
 
 Assuming the pre-vectorization loop is
 
-.. code-block:: c
-
-    for (int i = 0; i < n; i+=1) // original loop
-      Stmt(i);
+```c
+for (int i = 0; i < n; i+=1) // original loop
+  Stmt(i);
+```
 
 then the code after vectorization will be approximately (assuming an
 SIMD width of 4):
 
-.. code-block:: c
-
-    int i = 0;
-    if (rtc) {
-      for (; i + 3 < n; i+=4) // vectorized/interleaved loop
-        Stmt(i:i+3);
-    }
-    for (; i < n; i+=1) // epilogue loop
-      Stmt(i);
+```c
+int i = 0;
+if (rtc) {
+  for (; i + 3 < n; i+=4) // vectorized/interleaved loop
+    Stmt(i:i+3);
+}
+for (; i < n; i+=1) // epilogue loop
+  Stmt(i);
+```
 
-where ``rtc`` is a generated runtime check.
+where `rtc` is a generated runtime check.
 
-``llvm.loop.vectorize.followup_vectorized`` will set the attributes for
-the vectorized loop. If not specified, ``llvm.loop.isvectorized`` is
+`llvm.loop.vectorize.followup_vectorized` will set the attributes for
+the vectorized loop. If not specified, `llvm.loop.isvectorized` is
 combined with the original loop's attributes to avoid it being
 vectorized multiple times.
 
-``llvm.loop.vectorize.followup_epilogue`` will set the attributes for
+`llvm.loop.vectorize.followup_epilogue` will set the attributes for
 the remainder loop. If not specified, it will have the original loop's
-attributes combined with ``llvm.loop.isvectorized`` and
-``llvm.loop.unroll.runtime.disable`` (unless the original loop already
+attributes combined with `llvm.loop.isvectorized` and
+`llvm.loop.unroll.runtime.disable` (unless the original loop already
 has unroll metadata).
 
-The attributes specified by ``llvm.loop.vectorize.followup_all`` are
+The attributes specified by `llvm.loop.vectorize.followup_all` are
 added to both loops.
 
 In addition to the above, the vectorizer automatically annotates the
 generated loops with two metadata attributes for remark quality:
 
-- ``llvm.loop.vectorize.body`` is added to the vectorized loop.
-- ``llvm.loop.vectorize.epilogue`` is added to the scalar
+- `llvm.loop.vectorize.body` is added to the vectorized loop.
+- `llvm.loop.vectorize.epilogue` is added to the scalar
   remainder (epilogue) loop.
 
 Together these provide a four-way classification:
 
-- ``body`` only: main vectorized loop body
-- ``epilogue`` only: scalar epilogue loop after vectorization
+- `body` only: main vectorized loop body
+- `epilogue` only: scalar epilogue loop after vectorization
 - Both: vectorized epilogue (a remainder that was itself
   vectorized during epilogue vectorization)
 - Neither: a plain loop not produced by the vectorizer
 
 This is used by subsequent passes (e.g., the loop unroller and
-``WarnMissedTransforms``) to produce more precise optimization remarks.
+`WarnMissedTransforms`) to produce more precise optimization remarks.
 For instance, instead of reporting both "loop unrolled" and "loop not
 unrolled" for the same source line, the unroller can clarify that a
 *vectorized* loop was unrolled while its *scalar epilogue* was not.
 
 When using a follow-up attribute, it replaces any automatically deduced
 attributes for the generated loop in question. Therefore it is
-recommended to add ``llvm.loop.isvectorized`` to
-``llvm.loop.vectorize.followup_all`` which avoids that the loop
+recommended to add `llvm.loop.isvectorized` to
+`llvm.loop.vectorize.followup_all` which avoids that the loop
 vectorizer tries to optimize the loops again.
 
-Loop Unrolling
---------------
+### Loop Unrolling
 
-Unrolling is interpreted as forced any ``!{!"llvm.loop.unroll.enable"}``
-metadata or option (``llvm.loop.unroll.count``, ``llvm.loop.unroll.full``)
+Unrolling is interpreted as forced any `!{!"llvm.loop.unroll.enable"}`
+metadata or option (`llvm.loop.unroll.count`, `llvm.loop.unroll.full`)
 is present. Unrolling can be full unrolling, partial unrolling of a loop
 with constant trip count or runtime unrolling of a loop with a trip
 count unknown at compile-time.
@@ -205,257 +196,251 @@ count unknown at compile-time.
 If the loop has been unrolled fully, there is no followup-loop. For
 partial/runtime unrolling, the original loop of
 
-.. code-block:: c
-
-    for (int i = 0; i < n; i+=1) // original loop
-      Stmt(i);
+```c
+for (int i = 0; i < n; i+=1) // original loop
+  Stmt(i);
+```
 
 is transformed into (using an unroll factor of 4):
 
-.. code-block:: c
-
-    int i = 0;
-    for (; i + 3 < n; i+=4) { // unrolled loop
-      Stmt(i);
-      Stmt(i+1);
-      Stmt(i+2);
-      Stmt(i+3);
-    }
-    for (; i < n; i+=1) // remainder loop
-      Stmt(i);
-
-``llvm.loop.unroll.followup_unrolled`` will set the loop attributes of
+```c
+int i = 0;
+for (; i + 3 < n; i+=4) { // unrolled loop
+  Stmt(i);
+  Stmt(i+1);
+  Stmt(i+2);
+  Stmt(i+3);
+}
+for (; i < n; i+=1) // remainder loop
+  Stmt(i);
+```
+
+`llvm.loop.unroll.followup_unrolled` will set the loop attributes of
 the unrolled loop. If not specified, the attributes of the original loop
-without the ``llvm.loop.unroll.*`` attributes are copied and
-``llvm.loop.unroll.disable`` added to it.
+without the `llvm.loop.unroll.*` attributes are copied and
+`llvm.loop.unroll.disable` added to it.
 
-``llvm.loop.unroll.followup_remainder`` defines the attributes of the
+`llvm.loop.unroll.followup_remainder` defines the attributes of the
 remainder loop. If not specified the remainder loop will have no
 attributes. The remainder loop might not be present due to being fully
 unrolled in which case this attribute has no effect.
 
-Attributes defined in ``llvm.loop.unroll.followup_all`` are added to the
+Attributes defined in `llvm.loop.unroll.followup_all` are added to the
 unrolled and remainder loops.
 
 To avoid that the partially unrolled loop is unrolled again, it is
-recommended to add ``llvm.loop.unroll.disable`` to
-``llvm.loop.unroll.followup_all``. If no follow-up attribute specified
+recommended to add `llvm.loop.unroll.disable` to
+`llvm.loop.unroll.followup_all`. If no follow-up attribute specified
 for a generated loop, it is added automatically.
 
-Unroll-And-Jam
---------------
+### Unroll-And-Jam
 
 Unroll-and-jam uses the following transformation model (here with an
 unroll factor if 2). Currently, it does not support a fallback version
 when the transformation is unsafe.
 
-.. code-block:: c
-
-    for (int i = 0; i < n; i+=1) { // original outer loop
-      Fore(i);
-      for (int j = 0; j < m; j+=1) // original inner loop
-        SubLoop(i, j);
-      Aft(i);
-    }
-
-.. code-block:: c
-
-    int i = 0;
-    for (; i + 1 < n; i+=2) { // unrolled outer loop
-      Fore(i);
-      Fore(i+1);
-      for (int j = 0; j < m; j+=1) { // unrolled inner loop
-        SubLoop(i, j);
-        SubLoop(i+1, j);
-      }
-      Aft(i);
-      Aft(i+1);
-    }
-    for (; i < n; i+=1) { // remainder outer loop
-      Fore(i);
-      for (int j = 0; j < m; j+=1) // remainder inner loop
-        SubLoop(i, j);
-      Aft(i);
-    }
-
-``llvm.loop.unroll_and_jam.followup_outer`` will set the loop attributes
+```c
+for (int i = 0; i < n; i+=1) { // original outer loop
+  Fore(i);
+  for (int j = 0; j < m; j+=1) // original inner loop
+    SubLoop(i, j);
+  Aft(i);
+}
+```
+
+```c
+int i = 0;
+for (; i + 1 < n; i+=2) { // unrolled outer loop
+  Fore(i);
+  Fore(i+1);
+  for (int j = 0; j < m; j+=1) { // unrolled inner loop
+    SubLoop(i, j);
+    SubLoop(i+1, j);
+  }
+  Aft(i);
+  Aft(i+1);
+}
+for (; i < n; i+=1) { // remainder outer loop
+  Fore(i);
+  for (int j = 0; j < m; j+=1) // remainder inner loop
+    SubLoop(i, j);
+  Aft(i);
+}
+```
+
+`llvm.loop.unroll_and_jam.followup_outer` will set the loop attributes
 of the unrolled outer loop. If not specified, the attributes of the
-original outer loop without the ``llvm.loop.unroll.*`` attributes are
-copied and ``llvm.loop.unroll.disable`` added to it.
+original outer loop without the `llvm.loop.unroll.*` attributes are
+copied and `llvm.loop.unroll.disable` added to it.
 
-``llvm.loop.unroll_and_jam.followup_inner`` will set the loop attributes
+`llvm.loop.unroll_and_jam.followup_inner` will set the loop attributes
 of the unrolled inner loop. If not specified, the attributes of the
 original inner loop are used unchanged.
 
-``llvm.loop.unroll_and_jam.followup_remainder_outer`` sets the loop
+`llvm.loop.unroll_and_jam.followup_remainder_outer` sets the loop
 attributes of the outer remainder loop. If not specified it will not
 have any attributes. The remainder loop might not be present due to
 being fully unrolled.
 
-``llvm.loop.unroll_and_jam.followup_remainder_inner`` sets the loop
+`llvm.loop.unroll_and_jam.followup_remainder_inner` sets the loop
 attributes of the inner remainder loop. If not specified it will have
 the attributes of the original inner loop. It the outer remainder loop
 is unrolled, the inner remainder loop might be present multiple times.
 
-Attributes defined in ``llvm.loop.unroll_and_jam.followup_all`` are
+Attributes defined in `llvm.loop.unroll_and_jam.followup_all` are
 added to all of the aforementioned output loops.
 
 To avoid that the unrolled loop is unrolled again, it is
-recommended to add ``llvm.loop.unroll.disable`` to
-``llvm.loop.unroll_and_jam.followup_all``. It suppresses unroll-and-jam
+recommended to add `llvm.loop.unroll.disable` to
+`llvm.loop.unroll_and_jam.followup_all`. It suppresses unroll-and-jam
 as well as an additional inner loop unrolling. If no follow-up
 attribute specified for a generated loop, it is added automatically.
 
-Loop Distribution
------------------
+### Loop Distribution
 
 The LoopDistribution pass tries to separate vectorizable parts of a loop
 from the non-vectorizable part (which otherwise would make the entire
 loop non-vectorizable). Conceptually, it transforms a loop such as
 
-.. code-block:: c
-
-    for (int i = 1; i < n; i+=1) { // original loop
-      A[i] = i;
-      B[i] = 2 + B[i];
-      C[i] = 3 + C[i - 1];
-    }
+```c
+for (int i = 1; i < n; i+=1) { // original loop
+  A[i] = i;
+  B[i] = 2 + B[i];
+  C[i] = 3 + C[i - 1];
+}
+```
 
 into the following code:
 
-.. code-block:: c
-
-    if (rtc) {
-      for (int i = 1; i < n; i+=1) // coincident loop
-        A[i] = i;
-      for (int i = 1; i < n; i+=1) // coincident loop
-        B[i] = 2 + B[i];
-      for (int i = 1; i < n; i+=1) // sequential loop
-        C[i] = 3 + C[i - 1];
-    } else {
-      for (int i = 1; i < n; i+=1) { // fallback loop
-        A[i] = i;
-        B[i] = 2 + B[i];
-        C[i] = 3 + C[i - 1];
-      }
-    }
-
-where ``rtc`` is a generated runtime check.
-
-``llvm.loop.distribute.followup_coincident`` sets the loop attributes of
+```c
+if (rtc) {
+  for (int i = 1; i < n; i+=1) // coincident loop
+    A[i] = i;
+  for (int i = 1; i < n; i+=1) // coincident loop
+    B[i] = 2 + B[i];
+  for (int i = 1; i < n; i+=1) // sequential loop
+    C[i] = 3 + C[i - 1];
+} else {
+  for (int i = 1; i < n; i+=1) { // fallback loop
+    A[i] = i;
+    B[i] = 2 + B[i];
+    C[i] = 3 + C[i - 1];
+  }
+}
+```
+
+where `rtc` is a generated runtime check.
+
+`llvm.loop.distribute.followup_coincident` sets the loop attributes of
 all loops without loop-carried dependencies (i.e. vectorizable loops).
 There might be more than one such loops. If not defined, the loops will
 inherit the original loop's attributes.
 
-``llvm.loop.distribute.followup_sequential`` sets the loop attributes of the
+`llvm.loop.distribute.followup_sequential` sets the loop attributes of the
 loop with potentially unsafe dependencies. There should be at most one
 such loop. If not defined, the loop will inherit the original loop's
 attributes.
 
-``llvm.loop.distribute.followup_fallback`` defines the loop attributes
+`llvm.loop.distribute.followup_fallback` defines the loop attributes
 for the fallback loop, which is a copy of the original loop for when
 loop versioning is required. If undefined, the fallback loop inherits
 all attributes from the original loop.
 
-Attributes defined in ``llvm.loop.distribute.followup_all`` are added to
+Attributes defined in `llvm.loop.distribute.followup_all` are added to
 all of the aforementioned output loops.
 
-It is recommended to add ``llvm.loop.disable_nonforced`` to
-``llvm.loop.distribute.followup_fallback``. This avoids that the
+It is recommended to add `llvm.loop.disable_nonforced` to
+`llvm.loop.distribute.followup_fallback`. This avoids that the
 fallback version (which is likely never executed) is further optimized
 which would increase the code size.
 
-Attributes defined in ``llvm.loop.isdistributed`` are added to successfully
+Attributes defined in `llvm.loop.isdistributed` are added to successfully
 distributed loops to prevent subsequent reprocessing.
 
 As an example, the following instructs a loop to be ignored during
 loop distribution.
 
-.. code-block:: llvm
+```llvm
+!4 = distinct !{!4, !5, !6}
+!5 = !{!"llvm.loop.mustprogress"}
+!6 = !{!"llvm.loop.isdistributed", i32 1}
+```
 
-    !4 = distinct !{!4, !5, !6}
-    !5 = !{!"llvm.loop.mustprogress"}
-    !6 = !{!"llvm.loop.isdistributed", i32 1}
-
-Versioning LICM
----------------
+### Versioning LICM
 
 The pass hoists code out of loops that are only loop-invariant when
 dynamic conditions apply. For instance, it transforms the loop
 
-.. code-block:: c
-
-    for (int i = 0; i < n; i+=1) // original loop
-      A[i] = B[0];
+```c
+for (int i = 0; i < n; i+=1) // original loop
+  A[i] = B[0];
+```
 
 into:
 
-.. code-block:: c
-
-    if (rtc) {
-      auto b = B[0];
-      for (int i = 0; i < n; i+=1) // versioned loop
-        A[i] = b;
-    } else {
-      for (int i = 0; i < n; i+=1) // unversioned loop
-        A[i] = B[0];
-    }
-
-The runtime condition (``rtc``) checks that the array ``A`` and the
+```c
+if (rtc) {
+  auto b = B[0];
+  for (int i = 0; i < n; i+=1) // versioned loop
+    A[i] = b;
+} else {
+  for (int i = 0; i < n; i+=1) // unversioned loop
+    A[i] = B[0];
+}
+```
+
+The runtime condition (`rtc`) checks that the array `A` and the
 element `B[0]` do not alias.
 
 Currently, this transformation does not support followup-attributes.
 
-Loop Interchange
-----------------
+### Loop Interchange
 
-Currently, the ``LoopInterchange`` pass does not use any metadata.
+Currently, the `LoopInterchange` pass does not use any metadata.
 
-Ambiguous Transformation Order
-==============================
+## Ambiguous Transformation Order
 
 If there multiple transformations defined, the order in which they are
 executed depends on the order in LLVM's pass pipeline, which is subject
 to change. The default optimization pipeline (anything higher than
-``-O0``) has the following order.
+`-O0`) has the following order.
 
 When using the legacy pass manager:
 
- - LoopInterchange (if enabled)
- - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
- - VersioningLICM (if enabled)
- - LoopDistribute
- - LoopVectorizer
- - LoopUnrollAndJam (if enabled)
- - LoopUnroll (partial and runtime unrolling)
+> - LoopInterchange (if enabled)
+> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+> - VersioningLICM (if enabled)
+> - LoopDistribute
+> - LoopVectorizer
+> - LoopUnrollAndJam (if enabled)
+> - LoopUnroll (partial and runtime unrolling)
 
 When using the legacy pass manager with LTO:
 
- - LoopInterchange (if enabled)
- - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
- - LoopVectorizer
- - LoopUnroll (partial and runtime unrolling)
+> - LoopInterchange (if enabled)
+> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+> - LoopVectorizer
+> - LoopUnroll (partial and runtime unrolling)
 
 When using the new pass manager:
 
- - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
- - LoopDistribute
- - LoopVectorizer
- - LoopUnrollAndJam (if enabled)
- - LoopUnroll (partial and runtime unrolling)
+> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+> - LoopDistribute
+> - LoopVectorizer
+> - LoopUnrollAndJam (if enabled)
+> - LoopUnroll (partial and runtime unrolling)
 
-Leftover Transformations
-========================
+## Leftover Transformations
 
 Forced transformations that have not been applied after the last
 transformation pass should be reported to the user. The transformation
 passes themselves cannot be responsible for this reporting because they
 might not be in the pipeline, there might be multiple passes able to
-apply a transformation (e.g. ``LoopInterchange`` and Polly) or a
+apply a transformation (e.g. `LoopInterchange` and Polly) or a
 transformation attribute may be 'hidden' inside another passes' followup
 attribute.
 
-The pass ``-transform-warning`` (``WarnMissedTransformationsPass``)
+The pass `-transform-warning` (`WarnMissedTransformationsPass`)
 emits such warnings. It should be placed after the last transformation
 pass.
 
@@ -465,8 +450,9 @@ that is executed later and thus leftover. For instance, a loop nest
 cannot be distributed and then interchanged with the current pass
 pipeline. The loop distribution will execute, but there is no loop
 interchange pass following such that any loop interchange metadata will
-be ignored. The ``-transform-warning`` should emit a warning in this
+be ignored. The `-transform-warning` should emit a warning in this
 case.
 
 Future versions of LLVM may fix this by executing transformations using
 a dynamic ordering.
+
diff --git a/llvm/docs/TypeMetadata.md b/llvm/docs/TypeMetadata.md
index 5fa864dc8ab21..8626fd39598d0 100644
--- a/llvm/docs/TypeMetadata.md
+++ b/llvm/docs/TypeMetadata.md
@@ -1,10 +1,8 @@
-=============
-Type Metadata
-=============
+# Type Metadata
 
 Type metadata is a mechanism that allows IR modules to co-operatively build
 pointer sets corresponding to addresses within a given set of globals. LLVM's
-`control flow integrity`_ implementation uses this metadata to efficiently
+[control flow integrity][control flow integrity] implementation uses this metadata to efficiently
 check (at each call site) that a given address corresponds to either a
 valid vtable or function pointer for a given class or function type, and its
 whole-program devirtualization pass uses the metadata to identify potential
@@ -16,51 +14,49 @@ To use the mechanism, a client creates metadata nodes with two elements:
 2. a metadata object representing an identifier for the type
 
 These metadata nodes are associated with globals by using global object
-metadata attachments with the ``!type`` metadata kind.
+metadata attachments with the `!type` metadata kind.
 
 Each type identifier must exclusively identify either global variables
 or functions.
 
-.. admonition:: Limitation
+:::{admonition} Limitation
+The current implementation only supports attaching metadata to functions on
+the x86-32 and x86-64 architectures.
+:::
 
-  The current implementation only supports attaching metadata to functions on
-  the x86-32 and x86-64 architectures.
-
-An intrinsic, :ref:`llvm.type.test <type.test>`, is used to test whether a
+An intrinsic, {ref}`llvm.type.test <type.test>`, is used to test whether a
 given pointer is associated with a type identifier.
 
-.. _control flow integrity: https://clang.llvm.org/docs/ControlFlowIntegrity.html
-
-Representing Type Information using Type Metadata
-=================================================
+## Representing Type Information using Type Metadata
 
 This section describes how Clang represents C++ type information associated with
 virtual tables using type metadata.
 
 Consider the following inheritance hierarchy:
 
-.. code-block:: c++
-
-  struct A {
-    virtual void f();
-  };
+```c++
+struct A {
+  virtual void f();
+};
 
-  struct B : A {
-    virtual void f();
-    virtual void g();
-  };
+struct B : A {
+  virtual void f();
+  virtual void g();
+};
 
-  struct C {
-    virtual void h();
-  };
+struct C {
+  virtual void h();
+};
 
-  struct D : A, C {
-    virtual void f();
-    virtual void h();
-  };
+struct D : A, C {
+  virtual void f();
+  virtual void h();
+};
+```
 
 The virtual table objects for A, B, C and D look like this (under the Itanium ABI):
 
+```{eval-rst}
 .. csv-table:: Virtual Table Layout for A, B, C, D
   :header: Class, 0, 1, 2, 3, 4, 5, 6
 
@@ -68,11 +64,12 @@ The virtual table objects for A, B, C and D look like this (under the Itanium AB
   B, B::offset-to-top, &B::rtti, &B::f, &B::g
   C, C::offset-to-top, &C::rtti, &C::h
   D, D::offset-to-top, &D::rtti, &D::f, &D::h, D::offset-to-top, &D::rtti, thunk for &D::h
+```
 
-When an object of type A is constructed, the address of ``&A::f`` in A's
-virtual table object is stored in the object's vtable pointer.  In ABI parlance
-this address is known as an `address point`_. Similarly, when an object of type
-B is constructed, the address of ``&B::f`` is stored in the vtable pointer. In
+When an object of type A is constructed, the address of `&A::f` in A's
+virtual table object is stored in the object's vtable pointer. In ABI parlance
+this address is known as an [address point][address point]. Similarly, when an object of type
+B is constructed, the address of `&B::f` is stored in the vtable pointer. In
 this way, the vtable in B's virtual table object is compatible with A's vtable.
 
 D is a little more complicated, due to the use of multiple inheritance. Its
@@ -87,6 +84,7 @@ shown below. The following table shows the name of a class, the offset of an
 address point within that class's vtable and the name of one of the classes
 with which that address point is compatible.
 
+```{eval-rst}
 .. csv-table:: Type Offsets for A, B, C, D
   :header: VTable for, Offset, Compatible Class
 
@@ -97,6 +95,7 @@ with which that address point is compatible.
   D, 16, A
    ,   , D
    , 48, C
+```
 
 The next step is to encode this compatibility information into the IR. The way
 this is done is to create type metadata named after each of the compatible
@@ -104,44 +103,41 @@ classes, with which we associate each of the compatible address points in
 each vtable. For example, these type metadata entries encode the compatibility
 information for the above hierarchy:
 
-::
+```
+ at _ZTV1A = constant [...], !type !0
+ at _ZTV1B = constant [...], !type !0, !type !1
+ at _ZTV1C = constant [...], !type !2
+ at _ZTV1D = constant [...], !type !0, !type !3, !type !4
 
-  @_ZTV1A = constant [...], !type !0
-  @_ZTV1B = constant [...], !type !0, !type !1
-  @_ZTV1C = constant [...], !type !2
-  @_ZTV1D = constant [...], !type !0, !type !3, !type !4
+!0 = !{i64 16, !"_ZTS1A"}
+!1 = !{i64 16, !"_ZTS1B"}
+!2 = !{i64 16, !"_ZTS1C"}
+!3 = !{i64 16, !"_ZTS1D"}
+!4 = !{i64 48, !"_ZTS1C"}
+```
 
-  !0 = !{i64 16, !"_ZTS1A"}
-  !1 = !{i64 16, !"_ZTS1B"}
-  !2 = !{i64 16, !"_ZTS1C"}
-  !3 = !{i64 16, !"_ZTS1D"}
-  !4 = !{i64 48, !"_ZTS1C"}
-
-With this type metadata, we can now use the ``llvm.type.test`` intrinsic to
+With this type metadata, we can now use the `llvm.type.test` intrinsic to
 test whether a given pointer is compatible with a type identifier. Working
-backwards, if ``llvm.type.test`` returns true for a particular pointer,
+backwards, if `llvm.type.test` returns true for a particular pointer,
 we can also statically determine the identities of the virtual functions
 that a particular virtual call may call. For example, if a program assumes
-a pointer to be a member of ``!"_ZST1A"``, we know that the address can
-be only be one of ``_ZTV1A+16``, ``_ZTV1B+16`` or ``_ZTV1D+16`` (i.e. the
+a pointer to be a member of `!"_ZST1A"`, we know that the address can
+be only be one of `_ZTV1A+16`, `_ZTV1B+16` or `_ZTV1D+16` (i.e. the
 address points of the vtables of A, B and D respectively). If we then load
 an address from that pointer, we know that the address can only be one of
-``&A::f``, ``&B::f`` or ``&D::f``.
-
-.. _address point: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
+`&A::f`, `&B::f` or `&D::f`.
 
-Testing Addresses For Type Membership
-=====================================
+## Testing Addresses For Type Membership
 
-If a program tests an address using ``llvm.type.test``, this will cause
-a link-time optimization pass, ``LowerTypeTests``, to replace calls to this
+If a program tests an address using `llvm.type.test`, this will cause
+a link-time optimization pass, `LowerTypeTests`, to replace calls to this
 intrinsic with efficient code to perform type member tests. At a high level,
 the pass will lay out referenced globals in a consecutive memory region in
 the object file, construct bit vectors that map onto that memory region,
-and generate code at each of the ``llvm.type.test`` call sites to test
+and generate code at each of the `llvm.type.test` call sites to test
 pointers against those bit vectors. Because of the layout manipulation, the
 globals' definitions must be available at LTO time. For more information,
-see the `control flow integrity design document`_.
+see the [control flow integrity design document][control flow integrity design document].
 
 A type identifier that identifies functions is transformed into a jump table,
 which is a block of code consisting of one branch instruction for each
@@ -157,76 +153,69 @@ associated with a type identifier, there is no guarantee that its identity
 within the module will be the same as its identity outside of the module,
 as the former will be the jump table entry if a jump table is necessary.
 
-The `GlobalLayoutBuilder`_ class is responsible for laying out the globals
+The [GlobalLayoutBuilder][globallayoutbuilder] class is responsible for laying out the globals
 efficiently to minimize the sizes of the underlying bitsets.
 
-.. _control flow integrity design document: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html
-
-:Example:
-
-::
-
-    target datalayout = "e-p:32:32"
-
-    @a = internal global i32 0, !type !0
-    @b = internal global i32 0, !type !0, !type !1
-    @c = internal global i32 0, !type !1
-    @d = internal global [2 x i32] [i32 0, i32 0], !type !2
-
-    define void @e() !type !3 {
-      ret void
-    }
-
-    define void @f() {
-      ret void
-    }
-
-    declare void @g() !type !3
-
-    !0 = !{i32 0, !"typeid1"}
-    !1 = !{i32 0, !"typeid2"}
-    !2 = !{i32 4, !"typeid2"}
-    !3 = !{i32 0, !"typeid3"}
-
-    declare i1 @llvm.type.test(i8* %ptr, metadata %typeid) nounwind readnone
-
-    define i1 @foo(i32* %p) {
-      %pi8 = bitcast i32* %p to i8*
-      %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid1")
-      ret i1 %x
-    }
-
-    define i1 @bar(i32* %p) {
-      %pi8 = bitcast i32* %p to i8*
-      %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid2")
-      ret i1 %x
-    }
-
-    define i1 @baz(void ()* %p) {
-      %pi8 = bitcast void ()* %p to i8*
-      %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid3")
-      ret i1 %x
-    }
-
-    define void @main() {
-      %a1 = call i1 @foo(i32* @a) ; returns 1
-      %b1 = call i1 @foo(i32* @b) ; returns 1
-      %c1 = call i1 @foo(i32* @c) ; returns 0
-      %a2 = call i1 @bar(i32* @a) ; returns 0
-      %b2 = call i1 @bar(i32* @b) ; returns 1
-      %c2 = call i1 @bar(i32* @c) ; returns 1
-      %d02 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 0)) ; returns 0
-      %d12 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 1)) ; returns 1
-      %e = call i1 @baz(void ()* @e) ; returns 1
-      %f = call i1 @baz(void ()* @f) ; returns 0
-      %g = call i1 @baz(void ()* @g) ; returns 1
-      ret void
-    }
-
-.. _GlobalLayoutBuilder: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
-
-``!vcall_visibility`` Metadata
-==============================
+```
+target datalayout = "e-p:32:32"
+
+ at a = internal global i32 0, !type !0
+ at b = internal global i32 0, !type !0, !type !1
+ at c = internal global i32 0, !type !1
+ at d = internal global [2 x i32] [i32 0, i32 0], !type !2
+
+define void @e() !type !3 {
+  ret void
+}
+
+define void @f() {
+  ret void
+}
+
+declare void @g() !type !3
+
+!0 = !{i32 0, !"typeid1"}
+!1 = !{i32 0, !"typeid2"}
+!2 = !{i32 4, !"typeid2"}
+!3 = !{i32 0, !"typeid3"}
+
+declare i1 @llvm.type.test(i8* %ptr, metadata %typeid) nounwind readnone
+
+define i1 @foo(i32* %p) {
+  %pi8 = bitcast i32* %p to i8*
+  %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid1")
+  ret i1 %x
+}
+
+define i1 @bar(i32* %p) {
+  %pi8 = bitcast i32* %p to i8*
+  %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid2")
+  ret i1 %x
+}
+
+define i1 @baz(void ()* %p) {
+  %pi8 = bitcast void ()* %p to i8*
+  %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid3")
+  ret i1 %x
+}
+
+define void @main() {
+  %a1 = call i1 @foo(i32* @a) ; returns 1
+  %b1 = call i1 @foo(i32* @b) ; returns 1
+  %c1 = call i1 @foo(i32* @c) ; returns 0
+  %a2 = call i1 @bar(i32* @a) ; returns 0
+  %b2 = call i1 @bar(i32* @b) ; returns 1
+  %c2 = call i1 @bar(i32* @c) ; returns 1
+  %d02 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 0)) ; returns 0
+  %d12 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 1)) ; returns 1
+  %e = call i1 @baz(void ()* @e) ; returns 1
+  %f = call i1 @baz(void ()* @f) ; returns 0
+  %g = call i1 @baz(void ()* @g) ; returns 1
+  ret void
+}
+```
+
+## `!vcall_visibility` Metadata
 
 In order to allow removing unused function pointers from vtables, we need to
 know whether every virtual call which could use it is known to the compiler, or
@@ -235,30 +224,31 @@ This is not the same as the linkage of the vtable, because call sites could be
 using a pointer of a more widely-visible base class. For example, consider this
 code:
 
-.. code-block:: c++
-
-  __attribute__((visibility("default")))
-  struct A {
-    virtual void f();
-  };
-
-  __attribute__((visibility("hidden")))
-  struct B : A {
-    virtual void f();
-  };
-
-With LTO, we know that all code which can see the declaration of ``B`` is
-visible to us. However, a pointer to a ``B`` could be cast to ``A*`` and passed
-to another linkage unit, which could then call ``f`` on it. This call would
-load from the vtable for ``B`` (using the object pointer), and then call
-``B::f``. This means we can't remove the function pointer from ``B``'s vtable,
-or the implementation of ``B::f``. However, if we can see all code which knows
-about any dynamic base class (which would be the case if ``B`` only inherited
+```c++
+__attribute__((visibility("default")))
+struct A {
+  virtual void f();
+};
+
+__attribute__((visibility("hidden")))
+struct B : A {
+  virtual void f();
+};
+```
+
+With LTO, we know that all code which can see the declaration of `B` is
+visible to us. However, a pointer to a `B` could be cast to `A*` and passed
+to another linkage unit, which could then call `f` on it. This call would
+load from the vtable for `B` (using the object pointer), and then call
+`B::f`. This means we can't remove the function pointer from `B`'s vtable,
+or the implementation of `B::f`. However, if we can see all code which knows
+about any dynamic base class (which would be the case if `B` only inherited
 from classes with hidden visibility), then this optimisation would be valid.
 
-This concept is represented in IR by the ``!vcall_visibility`` metadata
+This concept is represented in IR by the `!vcall_visibility` metadata
 attached to vtable objects, with the following values:
 
+```{eval-rst}
 .. list-table::
    :header-rows: 1
    :widths: 10 90
@@ -281,10 +271,17 @@ attached to vtable objects, with the following values:
      - **Translation Unit**
            All virtual function calls which might use this vtable are in the
            current module.
+```
 
 In addition, all function pointer loads from a vtable marked with the
-``!vcall_visibility`` metadata (with a non-zero value) must be done using the
-:ref:`llvm.type.checked.load <type.checked.load>` intrinsic, so that virtual
+`!vcall_visibility` metadata (with a non-zero value) must be done using the
+{ref}`llvm.type.checked.load <type.checked.load>` intrinsic, so that virtual
 calls sites can be correlated with the vtables which they might load from.
 Other parts of the vtable (RTTI, offset-to-top, ...) can still be accessed with
 normal loads.
+
+[address point]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
+[control flow integrity]: https://clang.llvm.org/docs/ControlFlowIntegrity.html
+[control flow integrity design document]: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html
+[globallayoutbuilder]: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
+
diff --git a/llvm/docs/UndefinedBehavior.md b/llvm/docs/UndefinedBehavior.md
index 2055244664511..e25d29ec22ed7 100644
--- a/llvm/docs/UndefinedBehavior.md
+++ b/llvm/docs/UndefinedBehavior.md
@@ -1,17 +1,13 @@
-======================================
-LLVM IR Undefined Behavior (UB) Manual
-======================================
+# LLVM IR Undefined Behavior (UB) Manual
 
+## Abstract
 
-Abstract
-========
 This document describes the undefined behavior (UB) in LLVM's IR, including
-undef and poison values, as well as the ``freeze`` instruction.
+undef and poison values, as well as the `freeze` instruction.
 We also provide guidelines on when to use each form of UB.
 
+## Introduction
 
-Introduction
-============
 Undefined behavior (UB) is used to specify the behavior of corner cases for
 which we don't wish to specify the concrete results. UB is also used to provide
 additional constraints to the optimizers (e.g., assumptions that the frontend
@@ -21,15 +17,14 @@ since we are not really interested in the result, we say it is UB.
 
 There exist two forms of undefined behavior in LLVM: immediate UB and deferred
 UB. The latter comes in two flavors: undef and poison values.
-There is also a ``freeze`` instruction to tame the propagation of deferred UB.
+There is also a `freeze` instruction to tame the propagation of deferred UB.
 The lattice of values in LLVM is:
 immediate UB > poison > undef > freeze(poison) > concrete value.
 
 We explain each of the concepts in detail below.
 
+## Immediate UB
 
-Immediate UB
-============
 Immediate UB is the most severe form of UB. It should be avoided whenever
 possible.
 Immediate UB should be used only for operations that trap in most CPUs supported
@@ -40,39 +35,39 @@ The reason that immediate UB should be avoided is that it makes optimizations
 such as hoisting a lot harder.
 Consider the following example:
 
-.. code-block:: llvm
+```llvm
+define i32 @f(i1 %c, i32 %v) {
+  br i1 %c, label %then, label %else
 
-    define i32 @f(i1 %c, i32 %v) {
-      br i1 %c, label %then, label %else
+then:
+  %div = udiv i32 3, %v
+  br label %ret
 
-    then:
-      %div = udiv i32 3, %v
-      br label %ret
+else:
+  br label %ret
 
-    else:
-      br label %ret
-
-    ret:
-      %r = phi i32 [ %div, %then ], [ 0, %else ]
-      ret i32 %r
-    }
+ret:
+  %r = phi i32 [ %div, %then ], [ 0, %else ]
+  ret i32 %r
+}
+```
 
 We might be tempted to simplify this function by removing the branching and
-executing the division speculatively because ``%c`` is true most of times.
+executing the division speculatively because `%c` is true most of times.
 We would obtain the following IR:
 
-.. code-block:: llvm
-
-    define i32 @f(i1 %c, i32 %v) {
-      %div = udiv i32 3, %v
-      %r = select i1 %c, i32 %div, i32 0
-      ret i32 %r
-    }
+```llvm
+define i32 @f(i1 %c, i32 %v) {
+  %div = udiv i32 3, %v
+  %r = select i1 %c, i32 %div, i32 0
+  ret i32 %r
+}
+```
 
 However, this transformation is not correct! Since division triggers UB
 when the divisor is zero, we can only execute speculatively if we are sure we
 don't hit that condition.
-The function above, when called as ``f(false, 0)``, would return 0 before the
+The function above, when called as `f(false, 0)`, would return 0 before the
 optimization, and triggers UB after being optimized.
 
 This example highlights why we minimize the cases that trigger immediate UB
@@ -80,34 +75,32 @@ as much as possible.
 As a rule of thumb, use immediate UB only for the cases that trap the CPU for
 most of the supported architectures.
 
+### Time Travel
 
-Time Travel
------------
 Immediate UB in LLVM IR allows the so-called time travelling. What this means
 is that if a program triggers UB, then we are not required to preserve any of
 its observable behavior, including I/O.
-For example, the following function triggers UB after calling ``printf``:
+For example, the following function triggers UB after calling `printf`:
 
-.. code-block:: llvm
+```llvm
+define void @fn() {
+  call void @printf(...) willreturn
+  unreachable
+}
+```
 
-    define void @fn() {
-      call void @printf(...) willreturn
-      unreachable
-    }
-
-Since we know that ``printf`` will always return, and because LLVM's UB can
-time-travel, it is legal to remove the call to ``printf`` altogether and
+Since we know that `printf` will always return, and because LLVM's UB can
+time-travel, it is legal to remove the call to `printf` altogether and
 optimize the function to simply:
 
-.. code-block:: llvm
-
-    define void @fn() {
-      unreachable
-    }
+```llvm
+define void @fn() {
+  unreachable
+}
+```
 
+## Deferred UB
 
-Deferred UB
-===========
 Deferred UB is a lighter form of UB. It enables instructions to be executed
 speculatively while marking some corner cases as having erroneous values.
 Deferred UB should be used for cases where the semantics offered by common
@@ -118,59 +111,58 @@ offer different semantics when the shift amount is equal to or greater than
 the bitwidth.
 We could solve this tension in one of two ways: 1) pick one of the x86/ARM
 semantics for LLVM, which would make the code emitted for the other architecture
-slower; 2) define that case as yielding ``poison``.
+slower; 2) define that case as yielding `poison`.
 LLVM chose the latter option. For frontends for languages like C or C++
 (e.g., clang), they can map shifts in the source program directly to a shift in
 LLVM IR, since the semantics of C and C++ define such shifts as UB.
 For languages that offer strong semantics, they must use the value of the shift
 conditionally, e.g.:
 
-.. code-block:: llvm
+```llvm
+define i32 @x86_shift(i32 %a, i32 %b) {
+  %mask = and i32 %b, 31
+  %shift = shl i32 %a, %mask
+  ret i32 %shift
+}
+```
 
-    define i32 @x86_shift(i32 %a, i32 %b) {
-      %mask = and i32 %b, 31
-      %shift = shl i32 %a, %mask
-      ret i32 %shift
-    }
-
-
-There are two deferred UB values in LLVM: ``undef`` and ``poison``, which we
+There are two deferred UB values in LLVM: `undef` and `poison`, which we
 describe next.
 
+### Undef Values
 
-Undef Values
-------------
-.. warning::
-   Undef values are deprecated and should be used only when strictly necessary.
-   Uses of undef values should be restricted to representing loads of
-   uninitialized memory. This is the only part of the IR semantics that cannot
-   be replaced with alternatives yet (work in ongoing).
+:::{warning}
+Undef values are deprecated and should be used only when strictly necessary.
+Uses of undef values should be restricted to representing loads of
+uninitialized memory. This is the only part of the IR semantics that cannot
+be replaced with alternatives yet (work in ongoing).
+:::
 
 An undef value represents any value of a given type. Moreover, each use of
 an instruction that depends on undef can observe a different value.
 For example:
 
-.. code-block:: llvm
+```llvm
+define i32 @fn() {
+  %add = add i32 undef, 0
+  %ret = add i32 %add, %add
+  ret i32 %ret
+}
+```
 
-    define i32 @fn() {
-      %add = add i32 undef, 0
-      %ret = add i32 %add, %add
-      ret i32 %ret
-    }
-
-Unsurprisingly, the first addition yields ``undef``.
+Unsurprisingly, the first addition yields `undef`.
 However, the result of the second addition is more subtle. We might be tempted
 to think that it yields an even number. But it might not be!
-Since each (transitive) use of ``undef`` can observe a different value,
-the second addition is equivalent to ``add i32 undef, undef``, which is
-equivalent to ``undef``.
+Since each (transitive) use of `undef` can observe a different value,
+the second addition is equivalent to `add i32 undef, undef`, which is
+equivalent to `undef`.
 Hence, the function above is equivalent to:
 
-.. code-block:: llvm
-
-    define i32 @fn() {
-      ret i32 undef
-    }
+```llvm
+define i32 @fn() {
+  ret i32 undef
+}
+```
 
 Each call to this function may observe a different value, namely any 32-bit
 number (even and odd).
@@ -179,211 +171,206 @@ Because each use of undef can observe a different value, some optimizations
 are wrong if we are not sure a value is not undef.
 Consider a function that multiplies a number by 2:
 
-.. code-block:: llvm
+```llvm
+define i32 @fn(i32 %v) {
+  %mul2 = mul i32 %v, 2
+  ret i32 %mul2
+}
+```
 
-    define i32 @fn(i32 %v) {
-      %mul2 = mul i32 %v, 2
-      ret i32 %mul2
-    }
-
-This function is guaranteed to return an even number, even if ``%v`` is
+This function is guaranteed to return an even number, even if `%v` is
 undef.
 However, as we've seen above, the following function does not:
 
-.. code-block:: llvm
-
-    define i32 @fn(i32 %v) {
-      %mul2 = add i32 %v, %v
-      ret i32 %mul2
-    }
+```llvm
+define i32 @fn(i32 %v) {
+  %mul2 = add i32 %v, %v
+  ret i32 %mul2
+}
+```
 
 This optimization is wrong just because undef values exist, even if they are
-not used in this part of the program as LLVM has no way to tell if ``%v`` is
+not used in this part of the program as LLVM has no way to tell if `%v` is
 undef or not.
 
-Looking at the value lattice, ``undef`` values can only be replaced with either
-a ``freeze`` instruction or a concrete value.
+Looking at the value lattice, `undef` values can only be replaced with either
+a `freeze` instruction or a concrete value.
 A consequence is that giving undef as an operand to an instruction that triggers
 UB for some values of that operand makes the program UB. For example,
-``udiv %x, undef`` is UB since we replace undef with 0 (``udiv %x, 0``),
+`udiv %x, undef` is UB since we replace undef with 0 (`udiv %x, 0`),
 becoming obvious that it is UB.
 
+### Poison Values
 
-Poison Values
--------------
 Poison values are a stronger form of deferred UB than undef. They still
 allow instructions to be executed speculatively, but they taint the whole
 expression DAG (with some exceptions), akin to floating point NaN values.
 
 Example:
 
-.. code-block:: llvm
+```llvm
+define i32 @fn(i32 %a, i32 %b, i32 %c) {
+  %add = add nsw i32 %a, %b
+  %ret = add nsw i32 %add, %c
+  ret i32 %ret
+}
+```
 
-    define i32 @fn(i32 %a, i32 %b, i32 %c) {
-      %add = add nsw i32 %a, %b
-      %ret = add nsw i32 %add, %c
-      ret i32 %ret
-    }
-
-The ``nsw`` attribute in the additions indicates that the operation yields
+The `nsw` attribute in the additions indicates that the operation yields
 poison if there is a signed overflow.
-If the first addition overflows, ``%add`` is poison and thus ``%ret`` is also
+If the first addition overflows, `%add` is poison and thus `%ret` is also
 poison since it taints the whole expression DAG.
 
 Poison values can be replaced with any value of type (undef, concrete values,
-or a ``freeze`` instruction).
+or a `freeze` instruction).
 
+### Propagation of Poison Through Select
 
-Propagation of Poison Through Select
-------------------------------------
 Most instructions return poison if any of their inputs is poison.
-A notable exception is the ``select`` instruction, which is poison if and
+A notable exception is the `select` instruction, which is poison if and
 only if the condition is poison or the selected value is poison.
-This means that ``select`` acts as a barrier for poison propagation, which
+This means that `select` acts as a barrier for poison propagation, which
 impacts which optimizations can be performed.
 
 For example, consider the following function:
 
-.. code-block:: llvm
-
-  define i1 @fn(i32 %x, i32 %y) {
-    %cmp1 = icmp ne i32 %x, 0
-    %cmp2 = icmp ugt i32 %x, %y
-    %and = select i1 %cmp1, i1 %cmp2, i1 false
-    ret i1 %and
-  }
-
-It is not correct to optimize the ``select`` into an ``and`` because when
-``%cmp1`` is false, the ``select`` is only poison if ``%x`` is poison, while
-the ``and`` below is poison if either ``%x`` or ``%y`` are poison.
-
-.. code-block:: llvm
-
-  define i1 @fn(i32 %x, i32 %y) {
-    %cmp1 = icmp ne i32 %x, 0
-    %cmp2 = icmp ugt i32 %x, %y
-    %and = and i1 %cmp1, %cmp2     ;; poison if %x or %y are poison
-    ret i1 %and
-  }
+```llvm
+define i1 @fn(i32 %x, i32 %y) {
+  %cmp1 = icmp ne i32 %x, 0
+  %cmp2 = icmp ugt i32 %x, %y
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+```
+
+It is not correct to optimize the `select` into an `and` because when
+`%cmp1` is false, the `select` is only poison if `%x` is poison, while
+the `and` below is poison if either `%x` or `%y` are poison.
+
+```llvm
+define i1 @fn(i32 %x, i32 %y) {
+  %cmp1 = icmp ne i32 %x, 0
+  %cmp2 = icmp ugt i32 %x, %y
+  %and = and i1 %cmp1, %cmp2     ;; poison if %x or %y are poison
+  ret i1 %and
+}
+```
 
 However, the optimization is possible if all operands of the values are used in
-the condition (notice the flipped operands in the ``select``):
+the condition (notice the flipped operands in the `select`):
 
-.. code-block:: llvm
+```llvm
+define i1 @fn(i32 %x, i32 %y) {
+  %cmp1 = icmp ne i32 %x, 0
+  %cmp2 = icmp ugt i32 %x, %y
+  %and = select i1 %cmp2, i1 %cmp1, i1 false
+  ; ok to replace with:
+  %and = and i1 %cmp1, %cmp2
+  ret i1 %and
+}
+```
 
-  define i1 @fn(i32 %x, i32 %y) {
-    %cmp1 = icmp ne i32 %x, 0
-    %cmp2 = icmp ugt i32 %x, %y
-    %and = select i1 %cmp2, i1 %cmp1, i1 false
-    ; ok to replace with:
-    %and = and i1 %cmp1, %cmp2
-    ret i1 %and
-  }
+## The Freeze Instruction
 
-
-The Freeze Instruction
-======================
 Both undef and poison values sometimes propagate too much down an expression
 DAG. Undef values because each transitive use can observe a different value,
 and poison values because they make the whole DAG poison.
 There are some cases where it is important to stop such propagation.
-This is where the ``freeze`` instruction comes in.
+This is where the `freeze` instruction comes in.
 
 Take the following example function:
 
-.. code-block:: llvm
-
-    define i32 @fn(i32 %n, i1 %c) {
-    entry:
-      br label %loop
+```llvm
+define i32 @fn(i32 %n, i1 %c) {
+entry:
+  br label %loop
 
-    loop:
-      %i = phi i32 [ 0, %entry ], [ %i2, %loop.end ]
-      %cond = icmp ule i32 %i, %n
-      br i1 %cond, label %loop.cont, label %exit
+loop:
+  %i = phi i32 [ 0, %entry ], [ %i2, %loop.end ]
+  %cond = icmp ule i32 %i, %n
+  br i1 %cond, label %loop.cont, label %exit
 
-    loop.cont:
-      br i1 %c, label %then, label %else
+loop.cont:
+  br i1 %c, label %then, label %else
 
-    then:
-      ...
-      br label %loop.end
+then:
+  ...
+  br label %loop.end
 
-    else:
-      ...
-      br label %loop.end
+else:
+  ...
+  br label %loop.end
 
-    loop.end:
-      %i2 = add i32 %i, 1
-      br label %loop
+loop.end:
+  %i2 = add i32 %i, 1
+  br label %loop
 
-    exit:
-      ...
-    }
+exit:
+  ...
+}
+```
 
 Imagine we want to perform loop unswitching on the loop above since the branch
 condition inside the loop is loop invariant.
 We would obtain the following IR:
 
-.. code-block:: llvm
-
-    define i32 @fn(i32 %n, i1 %c) {
-    entry:
-      br i1 %c, label %then, label %else
-
-    then:
-      %i = phi i32 [ 0, %entry ], [ %i2, %then.cont ]
-      %cond = icmp ule i32 %i, %n
-      br i1 %cond, label %then.cont, label %exit
-
-    then.cont:
-      ...
-      %i2 = add i32 %i, 1
-      br label %then
-
-    else:
-      %i3 = phi i32 [ 0, %entry ], [ %i4, %else.cont ]
-      %cond = icmp ule i32 %i3, %n
-      br i1 %cond, label %else.cont, label %exit
-
-    else.cont:
-      ...
-      %i4 = add i32 %i3, 1
-      br label %else
-
-    exit:
-      ...
-    }
-
-There is a subtle catch: when the function is called with ``%n`` being zero,
-the original function did not branch on ``%c``, while the optimized one does.
+```llvm
+define i32 @fn(i32 %n, i1 %c) {
+entry:
+  br i1 %c, label %then, label %else
+
+then:
+  %i = phi i32 [ 0, %entry ], [ %i2, %then.cont ]
+  %cond = icmp ule i32 %i, %n
+  br i1 %cond, label %then.cont, label %exit
+
+then.cont:
+  ...
+  %i2 = add i32 %i, 1
+  br label %then
+
+else:
+  %i3 = phi i32 [ 0, %entry ], [ %i4, %else.cont ]
+  %cond = icmp ule i32 %i3, %n
+  br i1 %cond, label %else.cont, label %exit
+
+else.cont:
+  ...
+  %i4 = add i32 %i3, 1
+  br label %else
+
+exit:
+  ...
+}
+```
+
+There is a subtle catch: when the function is called with `%n` being zero,
+the original function did not branch on `%c`, while the optimized one does.
 Branching on a deferred UB value is immediate UB, hence the transformation is
-wrong in general because ``%c`` may be undef or poison.
+wrong in general because `%c` may be undef or poison.
 
 Cases like this need a way to tame deferred UB values. This is exactly what the
-``freeze`` instruction is for!
-When given a concrete value as argument, ``freeze`` is a no-op, returning the
-argument as-is. When given an undef or poison value, ``freeze`` returns a
+`freeze` instruction is for!
+When given a concrete value as argument, `freeze` is a no-op, returning the
+argument as-is. When given an undef or poison value, `freeze` returns a
 non-deterministic value of the type.
-This is not the same as undef: the value returned by ``freeze`` is the same
+This is not the same as undef: the value returned by `freeze` is the same
 for all users.
 
-Branching on a value returned by ``freeze`` is always safe since it either
+Branching on a value returned by `freeze` is always safe since it either
 evaluates to true or false consistently.
 We can make the loop unswitching optimization above correct as follows:
 
-.. code-block:: llvm
-
-    define i32 @fn(i32 %n, i1 %c) {
-    entry:
-      %c2 = freeze i1 %c
-      br i1 %c2, label %then, label %else
-      ...
-    }
-
+```llvm
+define i32 @fn(i32 %n, i1 %c) {
+entry:
+  %c2 = freeze i1 %c
+  br i1 %c2, label %then, label %else
+  ...
+}
+```
 
-Writing Tests Without Undefined Behavior
-========================================
+## Writing Tests Without Undefined Behavior
 
 When writing tests, it is important to ensure that they don't trigger UB
 unnecessarily. Some automated test reduces sometimes use undef or poison
@@ -393,12 +380,12 @@ to triggering UB.
 For example, imagine that we want to write a test and we don't care about the
 particular divisor value because our optimization kicks in regardless:
 
-.. code-block:: llvm
-
-    define i32 @fn(i8 %a) {
-      %div = udiv i8 %a, poison
-      ...
-    }
+```llvm
+define i32 @fn(i8 %a) {
+  %div = udiv i8 %a, poison
+  ...
+}
+```
 
 The issue with this test is that it triggers immediate UB. This prevents
 verification tools like Alive from validating the correctness of the
@@ -406,28 +393,28 @@ optimization. Hence, it is considered a bad practice to have tests with
 unnecessary immediate UB (unless that is exactly what the test is for).
 The test above should use a dummy function argument instead of using poison:
 
-.. code-block:: llvm
-
-    define i32 @fn(i8 %a, i8 %dummy) {
-      %div = udiv i8 %a, %dummy
-      ...
-    }
+```llvm
+define i32 @fn(i8 %a, i8 %dummy) {
+  %div = udiv i8 %a, %dummy
+  ...
+}
+```
 
 Common sources of immediate UB in tests include branching on undef/poison
 conditions and dereferencing undef/poison/null pointers.
 
-.. note::
-   If you need a placeholder value to pass as an argument to an instruction
-   that may trigger UB, add a new argument to the function rather than using
-   undef or poison.
+:::{note}
+If you need a placeholder value to pass as an argument to an instruction
+that may trigger UB, add a new argument to the function rather than using
+undef or poison.
+:::
 
+## Summary
 
-Summary
-=======
 Undefined behavior (UB) in LLVM IR consists of two well-defined concepts:
 immediate and deferred UB (undef and poison values).
 Passing deferred UB values to certain operations leads to immediate UB.
-This can be avoided in some cases through the use of the ``freeze``
+This can be avoided in some cases through the use of the `freeze`
 instruction.
 
 The lattice of values in LLVM is:
@@ -437,3 +424,4 @@ value can be replaced with a concrete value, but not the other way around).
 
 Undef is now deprecated and should be used only to represent loads of
 uninitialized memory.
+
diff --git a/llvm/docs/VectorizationPlan.md b/llvm/docs/VectorizationPlan.md
index c480ac86d2a59..6df336f3c28e6 100644
--- a/llvm/docs/VectorizationPlan.md
+++ b/llvm/docs/VectorizationPlan.md
@@ -1,12 +1,9 @@
-==================
-Vectorization Plan
-==================
+# Vectorization Plan
 
+## Abstract
 
-Abstract
-========
 The vectorization transformation can be rather complicated, involving several
-potential alternatives, especially for outer-loops [1]_ but also possibly for
+potential alternatives, especially for outer-loops [^footnote-1] but also possibly for
 innermost loops. These alternatives may have significant performance impact,
 both positive and negative. A cost model is therefore employed to identify the
 best alternative, including the alternative of avoiding any transformation
@@ -17,24 +14,22 @@ candidates. It serves for both optimizing candidates including estimating their
 cost reliably, and for performing their final translation into IR. This
 facilitates dealing with multiple vectorization candidates.
 
-Current Status
-==============
+## Current Status
+
 VPlan is currently used to drive code-generation in LoopVectorize. VPlans are
 constructed after all cost-based and most legality-related decisions have been
 taken. As def-use chains between recipes are now fully modeled in VPlan,
 VPlan-based analyses and transformations are used to simplify and modularize
-the vectorization process [10]_. Those include transformations to
+the vectorization process [^footnote-10]. Those include transformations to
 
 1. Legalize the initial VPlan, e.g. by introducing specialized recipes for
    reductions and interleave groups.
-
 2. Optimize the legalized VPlan, e.g. by removing redundant recipes or
    introducing active-lane-masks.
-
 3. Apply unroll- and vectorization-factor specific optimizations, e.g. removing
    the backedge to reiterate the vector loop based on VF & UF.
 
-Refer to :ref:`fig-vplan-transform-pipeline` for an overview of the current
+Refer to {ref}`fig-vplan-transform-pipeline` for an overview of the current
 transformation pipeline.
 
 Note that some legality checks are already done in VPlan, including checking if
@@ -42,45 +37,48 @@ all users of a fixed-order recurrence can be re-ordered. This is implemented as
 a VPlan-to-VPlan transformation that either applies a valid re-ordering or
 bails out marking the VPlan as invalid.
 
-.. _fig-vplan-transform-pipeline:
-.. figure:: ./vplan-transform-pipeline.png
-   :width: 800 px
+(fig-vplan-transform-pipeline)=
 
-   VPlan Transformation Pipeline in 2024
+:::{figure} ./vplan-transform-pipeline.png
+:width: 800 px
 
+VPlan Transformation Pipeline in 2024
+:::
 
 VPlan currently models the complete vector loop, as well as additional parts of
-the vectorization skeleton. Refer to :ref:`fig-vplan-scope` for an overview
+the vectorization skeleton. Refer to {ref}`fig-vplan-scope` for an overview
 of the scope covered by VPlan.
 
-.. _fig-vplan-scope:
-.. figure:: ./vplan-scope.png
-   :width: 800 px
+(fig-vplan-scope)=
 
-   Scope modeled in VPlan in 2024
+:::{figure} ./vplan-scope.png
+:width: 800 px
 
+Scope modeled in VPlan in 2024
+:::
 
-High-level Design
-=================
+## High-level Design
+
+### Vectorization Workflow
 
-Vectorization Workflow
-----------------------
 VPlan-based vectorization involves three major steps, taking a "scenario-based
 approach" to vectorization planning:
 
 1. Legal Step: check if a loop can be legally vectorized; encode constraints and
    artifacts if so.
+
 2. Plan Step:
 
-   a. Build initial VPlans following the constraints and decisions taken by
+   1. Build initial VPlans following the constraints and decisions taken by
       Legal Step 1, and compute their cost.
-   b. Apply optimizations to the VPlans, possibly forking additional VPlans.
+   2. Apply optimizations to the VPlans, possibly forking additional VPlans.
       Prune sub-optimal VPlans having relatively high cost.
+
 3. Execute Step: materialize the best VPlan. Note that this is the only step
    that modifies the IR.
 
-Design Guidelines
------------------
+### Design Guidelines
+
 In what follows, the term "input IR" refers to code that is fed into the
 vectorizer whereas the term "output IR" refers to code that is generated by the
 vectorizer. The output IR contains code that has been vectorized or "widened"
@@ -99,15 +97,15 @@ The design of VPlan follows several high-level guidelines:
 
 3. Support vectorizing additional constructs:
 
-   a. Outer-loop vectorization. In particular, VPlan must be able to model the
+   1. Outer-loop vectorization. In particular, VPlan must be able to model the
       control-flow of the output IR which may include multiple basic-blocks and
       nested loops.
-   b. SLP vectorization.
-   c. Combinations of the above, including nested vectorization: vectorizing
+   2. SLP vectorization.
+   3. Combinations of the above, including nested vectorization: vectorizing
       both an inner loop and an outer-loop at the same time (each with its own
       VF and UF), mixed vectorization: vectorizing a loop with SLP patterns
-      inside [4]_, (re)vectorizing input IR containing vector code.
-   d. Function vectorization [2]_.
+      inside [^footnote-4], (re)vectorizing input IR containing vector code.
+   4. Function vectorization [^footnote-2].
 
 4. Support multiple candidates efficiently. In particular, similar candidates
    related to a range of possible VF's and UF's must be represented efficiently.
@@ -120,7 +118,7 @@ The design of VPlan follows several high-level guidelines:
 
 6. Encapsulate Single-Entry Single-Exit regions (SESE). During vectorization
    such regions may need to be, for example, predicated and linearized, or
-   replicated VF*UF times to handle scalarized and predicated instructions.
+   replicated VF\*UF times to handle scalarized and predicated instructions.
    Innerloops are also modelled as SESE regions.
 
 7. Support instruction-level analysis and transformation, as part of Planning
@@ -129,16 +127,11 @@ The design of VPlan follows several high-level guidelines:
    detection and formation involves searching for and optimizing instruction
    patterns.
 
-Definitions
-===========
+## Definitions
+
 The low-level design of VPlan comprises of the following classes.
 
-:LoopVectorizationPlanner:
-  A LoopVectorizationPlanner is designed to handle the vectorization of a loop
-  or a loop nest. It can construct, optimize and discard one or more VPlans,
-  each VPlan modelling a distinct way to vectorize the loop or the loop nest.
-  Once the best VPlan is determined, including the best VF and UF, this VPlan
-  drives the generation of output IR.
+```{eval-rst}
 
 :VPlan:
   A model of a vectorized candidate for a given input IR loop or loop nest. This
@@ -214,6 +207,12 @@ The low-level design of VPlan comprises of the following classes.
 The Planning Process and VPlan Roadmap
 ======================================
 
+Transforming the Loop Vectorizer to use VPlan follows a staged approach. First,
+VPlan was only used to record the final vectorization decisions, and to execute
+```
+
+## The Planning Process and VPlan Roadmap
+
 Transforming the Loop Vectorizer to use VPlan follows a staged approach. First,
 VPlan was only used to record the final vectorization decisions, and to execute
 them: the Hierarchical CFG models the planned control-flow, and Recipes capture
@@ -244,48 +243,46 @@ them as VPInstructions. Finally, only logic that applies to instructions as a
 group will remain in Recipes, such as interleave groups and potentially other
 idiom groups having synergistic cost.
 
-Related LLVM components
------------------------
-1. SLP Vectorizer: one can compare the VPlan model with LLVM's existing SLP
-   tree, where TSLP [3]_ adds Plan Step 2.b.
+### Related LLVM components
 
+1. SLP Vectorizer: one can compare the VPlan model with LLVM's existing SLP
+   tree, where TSLP [^footnote-3] adds Plan Step 2.b.
 2. RegionInfo: one can compare VPlan's H-CFG with the Region Analysis as used by
-   Polly [7]_.
-
+   Polly [^footnote-7].
 3. Loop Vectorizer: the Vectorization Plan aims to upgrade the infrastructure of
-   the Loop Vectorizer and extend it to handle outer loops [8]_, [9]_.
+   the Loop Vectorizer and extend it to handle outer loops [^footnote-8], [^footnote-9].
 
-References
-----------
-.. [1] "Outer-loop vectorization: revisited for short SIMD architectures", Dorit
+### References
+
+[^footnote-1]: "Outer-loop vectorization: revisited for short SIMD architectures", Dorit
     Nuzman and Ayal Zaks, PACT 2008.
 
-.. [2] "Proposal for function vectorization and loop vectorization with function
-    calls", Xinmin Tian, [`cfe-dev
-    <http://lists.llvm.org/pipermail/cfe-dev/2016-March/047732.html>`_].,
+[^footnote-2]: "Proposal for function vectorization and loop vectorization with function
+    calls", Xinmin Tian, \[[cfe-dev](http://lists.llvm.org/pipermail/cfe-dev/2016-March/047732.html)\].,
     March 2, 2016.
-    See also `review <https://reviews.llvm.org/D22792>`_.
+    See also [review](https://reviews.llvm.org/D22792).
 
-.. [3] "Throttling Automatic Vectorization: When Less is More", Vasileios
+[^footnote-3]: "Throttling Automatic Vectorization: When Less is More", Vasileios
     Porpodas and Tim Jones, PACT 2015 and LLVM Developers' Meeting 2015.
 
-.. [4] "Exploiting mixed SIMD parallelism by reducing data reorganization
+[^footnote-4]: "Exploiting mixed SIMD parallelism by reducing data reorganization
     overhead", Hao Zhou and Jingling Xue, CGO 2016.
 
-.. [5] "Register Allocation via Hierarchical Graph Coloring", David Callahan and
+[^footnote-5]: "Register Allocation via Hierarchical Graph Coloring", David Callahan and
     Brian Koblenz, PLDI 1991
 
-.. [6] "Structural analysis: A new approach to flow analysis in optimizing
+[^footnote-6]: "Structural analysis: A new approach to flow analysis in optimizing
     compilers", M. Sharir, Journal of Computer Languages, Jan. 1980
 
-.. [7] "Enabling Polyhedral Optimizations in LLVM", Tobias Grosser, Diploma
+[^footnote-7]: "Enabling Polyhedral Optimizations in LLVM", Tobias Grosser, Diploma
     thesis, 2011.
 
-.. [8] "Introducing VPlan to the Loop Vectorizer", Gil Rapaport and Ayal Zaks,
+[^footnote-8]: "Introducing VPlan to the Loop Vectorizer", Gil Rapaport and Ayal Zaks,
     European LLVM Developers' Meeting 2017.
 
-.. [9] "Extending LoopVectorizer: OpenMP4.5 SIMD and Outer Loop
+[^footnote-9]: "Extending LoopVectorizer: OpenMP4.5 SIMD and Outer Loop
     Auto-Vectorization", Intel Vectorizer Team, LLVM Developers' Meeting 2016.
 
-.. [10] "VPlan: Status Update and Future Roadmap", Ayal Zaks and Florian Hahn,
-    LLVM Developers' Meeting 2023, https://www.youtube.com/watch?v=SzGP4PgMuLE
+[^footnote-10]: "VPlan: Status Update and Future Roadmap", Ayal Zaks and Florian Hahn,
+    LLVM Developers' Meeting 2023, <https://www.youtube.com/watch?v=SzGP4PgMuLE>
+
diff --git a/llvm/docs/XRay.md b/llvm/docs/XRay.md
index 2a975de8ab9b7..6a306e067a891 100644
--- a/llvm/docs/XRay.md
+++ b/llvm/docs/XRay.md
@@ -1,29 +1,27 @@
-====================
-XRay Instrumentation
-====================
+---
+Version: 1 as of 2016-11-08
+---
 
-:Version: 1 as of 2016-11-08
+# XRay Instrumentation
 
-
-
-Introduction
-============
+## Introduction
 
 XRay is a function call tracing system which combines compiler-inserted
 instrumentation points and a runtime library that can dynamically enable and
 disable the instrumentation.
 
-More high level information about XRay can be found in the `XRay whitepaper`_.
+More high level information about XRay can be found in the [XRay whitepaper][xray whitepaper].
 
 This document describes how to use XRay as implemented in LLVM.
 
-XRay in LLVM
-============
+## XRay in LLVM
 
 XRay consists of three main parts:
 
 - Compiler-inserted instrumentation points.
+
 - A runtime library for enabling/disabling tracing at runtime.
+
 - A suite of tools for analysing the traces.
 
   **NOTE:** As of July 25, 2018 , XRay is only available for the following
@@ -32,13 +30,12 @@ XRay consists of three main parts:
   OpenBSD: x86_64.
 
 The compiler-inserted instrumentation points come in the form of nop-sleds in
-the final generated binary, and an ELF section named ``xray_instr_map`` which
+the final generated binary, and an ELF section named `xray_instr_map` which
 contains entries pointing to these instrumentation points. The runtime library
-relies on being able to access the entries of the ``xray_instr_map``, and
+relies on being able to access the entries of the `xray_instr_map`, and
 overwrite the instrumentation points at runtime.
 
-Using XRay
-==========
+## Using XRay
 
 You can use XRay in a couple of ways:
 
@@ -48,246 +45,228 @@ You can use XRay in a couple of ways:
 The rest of this section covers these main ways and later on how to customize
 what XRay does in an XRay-instrumented binary.
 
-Instrumenting your C/C++/Objective-C Application
-------------------------------------------------
+### Instrumenting your C/C++/Objective-C Application
 
 The easiest way of getting XRay instrumentation for your application is by
-enabling the ``-fxray-instrument`` flag in your clang invocation.
+enabling the `-fxray-instrument` flag in your clang invocation.
 
 For example:
 
-::
-
-  clang -fxray-instrument ...
+```
+clang -fxray-instrument ...
+```
 
 By default, functions that have at least 200 instructions (or contain a loop) will
 get XRay instrumentation points. You can tweak that number through the
-``-fxray-instruction-threshold=`` flag:
+`-fxray-instruction-threshold=` flag:
 
-::
+```
+clang -fxray-instrument -fxray-instruction-threshold=1 ...
+```
 
-  clang -fxray-instrument -fxray-instruction-threshold=1 ...
-
-The loop detection can be disabled with ``-fxray-ignore-loops`` to use only the
+The loop detection can be disabled with `-fxray-ignore-loops` to use only the
 instruction threshold. You can also specifically instrument functions in your
 binary to either always or never be instrumented using source-level attributes.
 You can do it using the GCC-style attributes or C++11-style attributes.
 
-.. code-block:: c++
-
-    [[clang::xray_always_instrument]] void always_instrumented();
+```c++
+[[clang::xray_always_instrument]] void always_instrumented();
 
-    [[clang::xray_never_instrument]] void never_instrumented();
+[[clang::xray_never_instrument]] void never_instrumented();
 
-    void alt_always_instrumented() __attribute__((xray_always_instrument));
+void alt_always_instrumented() __attribute__((xray_always_instrument));
 
-    void alt_never_instrumented() __attribute__((xray_never_instrument));
+void alt_never_instrumented() __attribute__((xray_never_instrument));
+```
 
-When linking a binary, you can either manually link in the `XRay Runtime
-Library`_ or use ``clang`` to link it in automatically with the
-``-fxray-instrument`` flag. Alternatively, you can statically link-in the XRay
+When linking a binary, you can either manually link in the [XRay Runtime
+Library][xray runtime library] or use `clang` to link it in automatically with the
+`-fxray-instrument` flag. Alternatively, you can statically link-in the XRay
 runtime library from compiler-rt -- those archive files will take the name of
 `libclang_rt.xray-{arch}` where `{arch}` is the mnemonic supported by clang
 (x86_64, arm7, etc.).
 
-LLVM Function Attribute
------------------------
+### LLVM Function Attribute
 
-If you're using LLVM IR directly, you can add the ``function-instrument``
+If you're using LLVM IR directly, you can add the `function-instrument`
 string attribute to your functions, to get the similar effect that the
 C/C++/Objective-C source-level attributes would get:
 
-.. code-block:: llvm
+```llvm
+define i32 @always_instrument() uwtable "function-instrument"="xray-always" {
+  ; ...
+}
 
-    define i32 @always_instrument() uwtable "function-instrument"="xray-always" {
-      ; ...
-    }
+define i32 @never_instrument() uwtable "function-instrument"="xray-never" {
+  ; ...
+}
+```
 
-    define i32 @never_instrument() uwtable "function-instrument"="xray-never" {
-      ; ...
-    }
-
-You can also set the ``xray-instruction-threshold`` attribute and provide a
+You can also set the `xray-instruction-threshold` attribute and provide a
 numeric string value for how many instructions should be in the function before
 it gets instrumented.
 
-.. code-block:: llvm
-
-    define i32 @maybe_instrument() uwtable "xray-instruction-threshold"="2" {
-      ; ...
-    }
+```llvm
+define i32 @maybe_instrument() uwtable "xray-instruction-threshold"="2" {
+  ; ...
+}
+```
 
-Special Case File
------------------
+### Special Case File
 
 Attributes can be imbued through the use of special case files instead of
 adding them to the original source files. You can use this to mark certain
 functions and classes to be never, always, or instrumented with first-argument
 logging from a file. The file's format is described below:
 
-.. code-block:: bash
+```bash
+# Comments are supported
+[always]
+fun:always_instrument
+fun:log_arg1=arg1 # Log the first argument for the function
 
-    # Comments are supported
-    [always]
-    fun:always_instrument
-    fun:log_arg1=arg1 # Log the first argument for the function
+[never]
+fun:never_instrument
+```
 
-    [never]
-    fun:never_instrument
-
-These files can be provided through the ``-fxray-attr-list=`` flag to clang.
+These files can be provided through the `-fxray-attr-list=` flag to clang.
 You may have multiple files loaded through multiple instances of the flag.
 
-XRay Runtime Library
---------------------
+### XRay Runtime Library
 
 The XRay Runtime Library is part of the compiler-rt project, which implements
 the runtime components that perform the patching and unpatching of inserted
-instrumentation points. When you use ``clang`` to link your binaries and the
-``-fxray-instrument`` flag, it will automatically link in the XRay runtime.
+instrumentation points. When you use `clang` to link your binaries and the
+`-fxray-instrument` flag, it will automatically link in the XRay runtime.
 
 The default implementation of the XRay runtime will enable XRay instrumentation
-before ``main`` starts, which works for applications that have a short
+before `main` starts, which works for applications that have a short
 lifetime. This implementation also records all function entry and exit events
 which may result in a lot of records in the resulting trace.
 
-Also by default the filename of the XRay trace is ``xray-log.XXXXXX`` where the
-``XXXXXX`` part is randomly generated.
+Also by default the filename of the XRay trace is `xray-log.XXXXXX` where the
+`XXXXXX` part is randomly generated.
 
-These options can be controlled through the ``XRAY_OPTIONS`` environment
+These options can be controlled through the `XRAY_OPTIONS` environment
 variable during program run-time, where we list down the options and their
 defaults below.
 
-+-------------------+-----------------+---------------+------------------------+
-| Option            | Type            | Default       | Description            |
-+===================+=================+===============+========================+
-| patch_premain     | ``bool``        | ``false``     | Whether to patch       |
-|                   |                 |               | instrumentation points |
-|                   |                 |               | before main.           |
-+-------------------+-----------------+---------------+------------------------+
-| xray_mode         | ``const char*`` | ``""``        | Default mode to        |
-|                   |                 |               | install and initialize |
-|                   |                 |               | before ``main``.       |
-+-------------------+-----------------+---------------+------------------------+
-| xray_logfile_base | ``const char*`` | ``xray-log.`` | Filename base for the  |
-|                   |                 |               | XRay logfile.          |
-+-------------------+-----------------+---------------+------------------------+
-| verbosity         | ``int``         | ``0``         | Runtime verbosity      |
-|                   |                 |               | level.                 |
-+-------------------+-----------------+---------------+------------------------+
-
+| Option            | Type          | Default     | Description                                           |
+| ----------------- | ------------- | ----------- | ----------------------------------------------------- |
+| patch_premain     | `bool`        | `false`     | Whether to patch instrumentation points before main.  |
+| xray_mode         | `const char*` | `""`        | Default mode to install and initialize before `main`. |
+| xray_logfile_base | `const char*` | `xray-log.` | Filename base for the XRay logfile.                   |
+| verbosity         | `int`         | `0`         | Runtime verbosity level.                              |
 
 In addition to environment variable, you can also provide your own definition of
-``const char *__xray_default_options(void)`` function, which returns the option
+`const char *__xray_default_options(void)` function, which returns the option
 strings. This method effectively provides default options during program build
-time. For example, you can create an additional source file (e.g. ``xray-opt.c``
-) with the following ``__xray_default_options`` definition:
+time. For example, you can create an additional source file (e.g. `xray-opt.c`
+) with the following `__xray_default_options` definition:
 
-.. code-block:: c
-
-  __attribute__((xray_never_instrument))
-  const char *__xray_default_options() {
-    return "patch_premain=true,xray_mode=xray-basic";
-  }
+```c
+__attribute__((xray_never_instrument))
+const char *__xray_default_options() {
+  return "patch_premain=true,xray_mode=xray-basic";
+}
+```
 
 And link it with the program you want to instrument:
 
-::
-
-  clang -fxray-instrument prog.c xray-opt.c ...
+```
+clang -fxray-instrument prog.c xray-opt.c ...
+```
 
 The instrumented binary will use 'patch_premain=true,xray_mode=xray-basic' by
-default even without setting ``XRAY_OPTIONS``.
+default even without setting `XRAY_OPTIONS`.
 
-Note that you still can override options designated by ``__xray_default_options``
-using ``XRAY_OPTIONS`` during run-time.
+Note that you still can override options designated by `__xray_default_options`
+using `XRAY_OPTIONS` during run-time.
 
 If you choose to not use the default logging implementation that comes with the
 XRay runtime and/or control when/how the XRay instrumentation runs, you may use
 the XRay APIs directly for doing so. To do this, you'll need to include the
-``xray_log_interface.h`` from the compiler-rt ``xray`` directory. The important API
+`xray_log_interface.h` from the compiler-rt `xray` directory. The important API
 functions we list below:
 
-- ``__xray_log_register_mode(...)``: Register a logging implementation against
+- `__xray_log_register_mode(...)`: Register a logging implementation against
   a string Mode identifier. The implementation is an instance of
-  ``XRayLogImpl`` defined in ``xray/xray_log_interface.h``.
-- ``__xray_log_select_mode(...)``: Select the mode to install, associated with
+  `XRayLogImpl` defined in `xray/xray_log_interface.h`.
+- `__xray_log_select_mode(...)`: Select the mode to install, associated with
   a string Mode identifier. Only implementations registered with
-  ``__xray_log_register_mode(...)`` can be chosen with this function.
-- ``__xray_log_init_mode(...)``: This function allows for initializing and
+  `__xray_log_register_mode(...)` can be chosen with this function.
+- `__xray_log_init_mode(...)`: This function allows for initializing and
   re-initializing an installed logging implementation. See
-  ``xray/xray_log_interface.h`` for details, part of the XRay compiler-rt
+  `xray/xray_log_interface.h` for details, part of the XRay compiler-rt
   installation.
 
 Once a logging implementation has been initialized, it can be "stopped" by
-finalizing the implementation through the ``__xray_log_finalize()`` function.
+finalizing the implementation through the `__xray_log_finalize()` function.
 The finalization routine is the opposite of the initialization. When finalized,
 an implementation's data can be cleared out through the
-``__xray_log_flushLog()`` function. For implementations that support in-memory
+`__xray_log_flushLog()` function. For implementations that support in-memory
 processing, these should register an iterator function to provide access to the
-data via the ``__xray_log_set_buffer_iterator(...)`` which allows code calling
-the ``__xray_log_process_buffers(...)`` function to deal with the data in
+data via the `__xray_log_set_buffer_iterator(...)` which allows code calling
+the `__xray_log_process_buffers(...)` function to deal with the data in
 memory.
 
-All of this is better explained in the ``xray/xray_log_interface.h`` header.
+All of this is better explained in the `xray/xray_log_interface.h` header.
 
-Basic Mode
-----------
+### Basic Mode
 
 XRay supports a basic logging mode which will trace the application's
 execution, and periodically append to a single log. This mode can be
-installed/enabled by setting ``xray_mode=xray-basic`` in the ``XRAY_OPTIONS``
-environment variable. Combined with ``patch_premain=true`` this can allow for
+installed/enabled by setting `xray_mode=xray-basic` in the `XRAY_OPTIONS`
+environment variable. Combined with `patch_premain=true` this can allow for
 tracing applications from start to end.
 
-Like all the other modes installed through ``__xray_log_select_mode(...)``, the
-implementation can be configured through the ``__xray_log_init_mode(...)``
+Like all the other modes installed through `__xray_log_select_mode(...)`, the
+implementation can be configured through the `__xray_log_init_mode(...)`
 function, providing the mode string and the flag options. Basic-mode specific
-defaults can be provided in the ``XRAY_BASIC_OPTIONS`` environment variable.
+defaults can be provided in the `XRAY_BASIC_OPTIONS` environment variable.
 
-Flight Data Recorder Mode
--------------------------
+### Flight Data Recorder Mode
 
 XRay supports a logging mode which allows the application to only capture a
 fixed amount of memory's worth of events. Flight Data Recorder (FDR) mode works
 very much like a plane's "black box" which keeps recording data to memory in a
 fixed-size circular queue of buffers, and have the data available
 programmatically until the buffers are finalized and flushed. To use FDR mode
-on your application, you may set the ``xray_mode`` variable to ``xray-fdr`` in
-the ``XRAY_OPTIONS`` environment variable. Additional options to the FDR mode
-implementation can be provided in the ``XRAY_FDR_OPTIONS`` environment
+on your application, you may set the `xray_mode` variable to `xray-fdr` in
+the `XRAY_OPTIONS` environment variable. Additional options to the FDR mode
+implementation can be provided in the `XRAY_FDR_OPTIONS` environment
 variable. Programmatic configuration can be done by calling
-``__xray_log_init_mode("xray-fdr", <configuration string>)`` once it has been
+`__xray_log_init_mode("xray-fdr", <configuration string>)` once it has been
 selected/installed.
 
 When the buffers are flushed to disk, the result is a binary trace format
-described by `XRay FDR format <XRayFDRFormat.html>`_
+described by [XRay FDR format](XRayFDRFormat.html)
 
 When FDR mode is on, it will keep writing and recycling memory buffers until
 the logging implementation is finalized -- at which point it can be flushed and
 re-initialised later. To do this programmatically, we follow the workflow
 provided below:
 
-.. code-block:: c++
+```c++
+// Patch the sleds, if we haven't yet.
+auto patch_status = __xray_patch();
 
-  // Patch the sleds, if we haven't yet.
-  auto patch_status = __xray_patch();
+// Maybe handle the patch_status errors.
 
-  // Maybe handle the patch_status errors.
+// When we want to flush the log, we need to finalize it first, to give
+// threads a chance to return buffers to the queue.
+auto finalize_status = __xray_log_finalize();
+if (finalize_status != XRAY_LOG_FINALIZED) {
+  // maybe retry, or bail out.
+}
 
-  // When we want to flush the log, we need to finalize it first, to give
-  // threads a chance to return buffers to the queue.
-  auto finalize_status = __xray_log_finalize();
-  if (finalize_status != XRAY_LOG_FINALIZED) {
-    // maybe retry, or bail out.
-  }
-
-  // At this point, we are sure that the log is finalized, so we may try
-  // flushing the log.
-  auto flush_status = __xray_log_flushLog();
-  if (flush_status != XRAY_LOG_FLUSHED) {
-    // maybe retry, or bail out.
-  }
+// At this point, we are sure that the log is finalized, so we may try
+// flushing the log.
+auto flush_status = __xray_log_flushLog();
+if (flush_status != XRAY_LOG_FLUSHED) {
+  // maybe retry, or bail out.
+}
+```
 
 The default settings for the FDR mode implementation will create logs named
 similarly to the basic log implementation, but will have a different log
@@ -295,85 +274,80 @@ format. All the trace analysis tools (and the trace reading library) will
 support all versions of the FDR mode format as we add more functionality and
 record types in the future.
 
-  **NOTE:** We do not promise perpetual support for when we update the log
-  versions we support going forward. Deprecation of the formats will be
-  announced and discussed on the developers mailing list.
+> **NOTE:** We do not promise perpetual support for when we update the log
+> versions we support going forward. Deprecation of the formats will be
+> announced and discussed on the developers mailing list.
 
-Trace Analysis Tools
---------------------
+### Trace Analysis Tools
 
 We currently have the beginnings of a trace analysis tool in LLVM, which can be
-found in the ``tools/llvm-xray`` directory. The ``llvm-xray`` tool currently
+found in the `tools/llvm-xray` directory. The `llvm-xray` tool currently
 supports the following subcommands:
 
-- ``extract``: Extract the instrumentation map from a binary, and return it as
+- `extract`: Extract the instrumentation map from a binary, and return it as
   YAML.
-- ``account``: Performs basic function call accounting statistics with various
+- `account`: Performs basic function call accounting statistics with various
   options for sorting, and output formats (supports CSV, YAML, and
   console-friendly TEXT).
-- ``convert``: Converts an XRay log file from one format to another. We can
+- `convert`: Converts an XRay log file from one format to another. We can
   convert from binary XRay traces (both basic and FDR mode) to YAML,
-  `flame-graph <https://github.com/brendangregg/FlameGraph>`_ friendly text
+  [flame-graph](https://github.com/brendangregg/FlameGraph) friendly text
   formats, as well as `Chrome Trace Viewer (catapult)
   <https://github.com/catapult-project/catapult>` formats.
-- ``graph``: Generates a DOT graph of the function call relationships between
+- `graph`: Generates a DOT graph of the function call relationships between
   functions found in an XRay trace.
-- ``stack``: Reconstructs function call stacks from a timeline of function
+- `stack`: Reconstructs function call stacks from a timeline of function
   calls in an XRay trace.
 
 These subcommands use various library components found as part of the XRay
 libraries, distributed with the LLVM distribution. These are:
 
-- ``llvm/XRay/Trace.h`` : A trace reading library for conveniently loading
+- `llvm/XRay/Trace.h` : A trace reading library for conveniently loading
   an XRay trace of supported forms, into a convenient in-memory representation.
   All the analysis tools that deal with traces use this implementation.
-- ``llvm/XRay/Graph.h`` : A semi-generic graph type used by the graph
+- `llvm/XRay/Graph.h` : A semi-generic graph type used by the graph
   subcommand to conveniently represent a function call graph with statistics
   associated with edges and vertices.
-- ``llvm/XRay/InstrumentationMap.h``: A convenient tool for analyzing the
+- `llvm/XRay/InstrumentationMap.h`: A convenient tool for analyzing the
   instrumentation map in XRay-instrumented object files and binaries. The
-  ``extract`` and ``stack`` subcommands uses this particular library.
-
+  `extract` and `stack` subcommands uses this particular library.
 
-Minimizing Binary Size
-----------------------
+### Minimizing Binary Size
 
-XRay supports several different instrumentation points including ``function-entry``,
-``function-exit``, ``custom``, and ``typed`` points. These can be enabled individually
-using the ``-fxray-instrumentation-bundle=`` flag. For example if you only wanted to
+XRay supports several different instrumentation points including `function-entry`,
+`function-exit`, `custom`, and `typed` points. These can be enabled individually
+using the `-fxray-instrumentation-bundle=` flag. For example if you only wanted to
 instrument function entry and custom points you could specify:
 
-::
-
-  clang -fxray-instrument -fxray-instrumentation-bundle=function-entry,custom ...
+```
+clang -fxray-instrument -fxray-instrumentation-bundle=function-entry,custom ...
+```
 
 This will omit the other sled types entirely, reducing the binary size. You can also
 instrument just a sampled subset of functions using instrumentation groups.
 For example, to instrument only a quarter of available functions invoke:
 
-::
-
-  clang -fxray-instrument -fxray-function-groups=4
+```
+clang -fxray-instrument -fxray-function-groups=4
+```
 
 A subset will be chosen arbitrarily based on a hash of the function name. To sample a
-different subset you can specify ``-fxray-selected-function-group=`` with a group number
-in the range of 0 to ``xray-function-groups`` - 1.  Together these options could be used
+different subset you can specify `-fxray-selected-function-group=` with a group number
+in the range of 0 to `xray-function-groups` - 1. Together these options could be used
 to produce multiple binaries with different instrumented subsets. If all you need is
 runtime control over which functions are being traced at any given time it is better
 to selectively patch and unpatch the individual functions you need using the XRay
-Runtime Library's ``__xray_patch_function()`` method.
+Runtime Library's `__xray_patch_function()` method.
 
-Future Work
-===========
+## Future Work
 
 There are a number of ongoing efforts for expanding the toolset building around
 the XRay instrumentation system.
 
-Trace Analysis Tools
---------------------
+### Trace Analysis Tools
 
 - Work is in progress to integrate with or develop tools to visualize findings
-  from an XRay trace. Particularly, the ``stack`` tool is being expanded to
+  from an XRay trace. Particularly, the `stack` tool is being expanded to
   output formats that allow graphing and exploring the duration of time in each
   call stack.
 - With a large instrumented binary, the size of generated XRay traces can
@@ -381,13 +355,12 @@ Trace Analysis Tools
   heuristics for the analysis tools to sift through the traces and surface only
   relevant information.
 
-More Platforms
---------------
+### More Platforms
 
 We're looking forward to contributions to port XRay to more architectures and
 operating systems.
 
-.. References...
+% References...
 
-.. _`XRay whitepaper`: http://research.google.com/pubs/pub45287.html
+[xray whitepaper]: http://research.google.com/pubs/pub45287.html
 
diff --git a/llvm/docs/XRayExample.md b/llvm/docs/XRayExample.md
index ccb02b359d7c3..dc2d591eda85e 100644
--- a/llvm/docs/XRayExample.md
+++ b/llvm/docs/XRayExample.md
@@ -1,171 +1,160 @@
-===================
-Debugging with XRay
-===================
+# Debugging with XRay
 
 This document shows an example of how you would go about analyzing applications
-built with XRay instrumentation. Here we will attempt to debug ``llc``
+built with XRay instrumentation. Here we will attempt to debug `llc`
 compiling some sample LLVM IR generated by Clang.
 
-
-Building with XRay
-------------------
+## Building with XRay
 
 To debug an application with XRay instrumentation, we need to build it with a
-Clang that supports the ``-fxray-instrument`` option. See `XRay <XRay.html>`_
+Clang that supports the `-fxray-instrument` option. See [XRay](XRay.html)
 for more technical details of how XRay works for background information.
 
-In our example, we need to add ``-fxray-instrument`` to the list of flags
+In our example, we need to add `-fxray-instrument` to the list of flags
 passed to Clang when building a binary. Note that we need to link with Clang as
-well to get the XRay runtime linked in appropriately. For building ``llc`` with
+well to get the XRay runtime linked in appropriately. For building `llc` with
 XRay, we do something similar below for our LLVM build:
 
-::
-
-  $ mkdir -p llvm-build && cd llvm-build
-  # Assume that the LLVM sources are at ../llvm
-  $ cmake -GNinja ../llvm -DCMAKE_BUILD_TYPE=Release \
-      -DCMAKE_C_FLAGS_RELEASE="-fxray-instrument" -DCMAKE_CXX_FLAGS="-fxray-instrument" \
-  # Once this finishes, we should build llc
-  $ ninja llc
-
-
-To verify that we have an XRay instrumented binary, we can use ``objdump`` to
-look for the ``xray_instr_map`` section.
+```
+$ mkdir -p llvm-build && cd llvm-build
+# Assume that the LLVM sources are at ../llvm
+$ cmake -GNinja ../llvm -DCMAKE_BUILD_TYPE=Release \
+    -DCMAKE_C_FLAGS_RELEASE="-fxray-instrument" -DCMAKE_CXX_FLAGS="-fxray-instrument" \
+# Once this finishes, we should build llc
+$ ninja llc
+```
 
-::
+To verify that we have an XRay instrumented binary, we can use `objdump` to
+look for the `xray_instr_map` section.
 
-  $ objdump -h -j xray_instr_map ./bin/llc
-  ./bin/llc:     file format elf64-x86-64
+```
+$ objdump -h -j xray_instr_map ./bin/llc
+./bin/llc:     file format elf64-x86-64
 
-  Sections:
-  Idx Name          Size      VMA               LMA               File off  Algn
-   14 xray_instr_map 00002fc0  00000000041516c6  00000000041516c6  03d516c6  2**0
-                    CONTENTS, ALLOC, LOAD, READONLY, DATA
+Sections:
+Idx Name          Size      VMA               LMA               File off  Algn
+ 14 xray_instr_map 00002fc0  00000000041516c6  00000000041516c6  03d516c6  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+```
 
-Getting Traces
---------------
+## Getting Traces
 
 By default, XRay does not write out the trace files or patch the application
-before main starts. If we run ``llc`` it should work like a normally built
+before main starts. If we run `llc` it should work like a normally built
 binary. If we want to get a full trace of the application's operations (of the
 functions we do end up instrumenting with XRay) then we need to enable XRay
-at application start. To do this, XRay checks the ``XRAY_OPTIONS`` environment
+at application start. To do this, XRay checks the `XRAY_OPTIONS` environment
 variable.
 
-::
+```
+# The following doesn't create an XRay trace by default.
+$ ./bin/llc input.ll
 
-  # The following doesn't create an XRay trace by default.
-  $ ./bin/llc input.ll
-
-  # We need to set the XRAY_OPTIONS to enable some features.
-  $ XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" ./bin/llc input.ll
-  ==69819==XRay: Log file in 'xray-log.llc.m35qPB'
+# We need to set the XRAY_OPTIONS to enable some features.
+$ XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" ./bin/llc input.ll
+==69819==XRay: Log file in 'xray-log.llc.m35qPB'
+```
 
 At this point we now have an XRay trace we can start analysing.
 
-The ``llvm-xray`` Tool
-----------------------
+## The `llvm-xray` Tool
 
 Having a trace then allows us to do basic accounting of the functions that were
 instrumented, and how much time we're spending in parts of the code. To make
-sense of this data, we use the ``llvm-xray`` tool which has a few subcommands
+sense of this data, we use the `llvm-xray` tool which has a few subcommands
 to help us understand our trace.
 
 One of the things we can do is to get an accounting of the functions that have
-been instrumented. We can see an example accounting with ``llvm-xray account``:
-
-::
-
-  $ llvm-xray account xray-log.llc.m35qPB --top=10 --sort=sum --sortorder=dsc --instr_map=./bin/llc
-  Functions with latencies: 29
-     funcid      count [      min,       med,       90p,       99p,       max]       sum  function
-        187        360 [ 0.000000,  0.000001,  0.000014,  0.000032,  0.000075]  0.001596  LLLexer.cpp:446:0: llvm::LLLexer::LexIdentifier()
-         85        130 [ 0.000000,  0.000000,  0.000018,  0.000023,  0.000156]  0.000799  X86ISelDAGToDAG.cpp:1984:0: (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDNode*)
-        138        130 [ 0.000000,  0.000000,  0.000017,  0.000155,  0.000155]  0.000774  SelectionDAGISel.cpp:2963:0: llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int)
-        188        103 [ 0.000000,  0.000000,  0.000003,  0.000123,  0.000214]  0.000737  LLParser.cpp:2692:0: llvm::LLParser::ParseValID(llvm::ValID&, llvm::LLParser::PerFunctionState*)
-         88          1 [ 0.000562,  0.000562,  0.000562,  0.000562,  0.000562]  0.000562  X86ISelLowering.cpp:83:0: llvm::X86TargetLowering::X86TargetLowering(llvm::X86TargetMachine const&, llvm::X86Subtarget const&)
-        125        102 [ 0.000001,  0.000003,  0.000010,  0.000017,  0.000049]  0.000471  Verifier.cpp:3714:0: (anonymous namespace)::Verifier::visitInstruction(llvm::Instruction&)
-         90          8 [ 0.000023,  0.000035,  0.000106,  0.000106,  0.000106]  0.000342  X86ISelLowering.cpp:3363:0: llvm::X86TargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const
-        124         32 [ 0.000003,  0.000007,  0.000016,  0.000041,  0.000041]  0.000310  Verifier.cpp:1967:0: (anonymous namespace)::Verifier::visitFunction(llvm::Function const&)
-        123          1 [ 0.000302,  0.000302,  0.000302,  0.000302,  0.000302]  0.000302  LLVMContextImpl.cpp:54:0: llvm::LLVMContextImpl::~LLVMContextImpl()
-        139         46 [ 0.000000,  0.000002,  0.000006,  0.000008,  0.000019]  0.000138  TargetLowering.cpp:506:0: llvm::TargetLowering::SimplifyDemandedBits(llvm::SDValue, llvm::APInt const&, llvm::APInt&, llvm::APInt&, llvm::TargetLowering::TargetLoweringOpt&, unsigned int, bool) const
-
-This shows us that for our input file, ``llc`` spent the most cumulative time
+been instrumented. We can see an example accounting with `llvm-xray account`:
+
+```
+$ llvm-xray account xray-log.llc.m35qPB --top=10 --sort=sum --sortorder=dsc --instr_map=./bin/llc
+Functions with latencies: 29
+   funcid      count [      min,       med,       90p,       99p,       max]       sum  function
+      187        360 [ 0.000000,  0.000001,  0.000014,  0.000032,  0.000075]  0.001596  LLLexer.cpp:446:0: llvm::LLLexer::LexIdentifier()
+       85        130 [ 0.000000,  0.000000,  0.000018,  0.000023,  0.000156]  0.000799  X86ISelDAGToDAG.cpp:1984:0: (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDNode*)
+      138        130 [ 0.000000,  0.000000,  0.000017,  0.000155,  0.000155]  0.000774  SelectionDAGISel.cpp:2963:0: llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int)
+      188        103 [ 0.000000,  0.000000,  0.000003,  0.000123,  0.000214]  0.000737  LLParser.cpp:2692:0: llvm::LLParser::ParseValID(llvm::ValID&, llvm::LLParser::PerFunctionState*)
+       88          1 [ 0.000562,  0.000562,  0.000562,  0.000562,  0.000562]  0.000562  X86ISelLowering.cpp:83:0: llvm::X86TargetLowering::X86TargetLowering(llvm::X86TargetMachine const&, llvm::X86Subtarget const&)
+      125        102 [ 0.000001,  0.000003,  0.000010,  0.000017,  0.000049]  0.000471  Verifier.cpp:3714:0: (anonymous namespace)::Verifier::visitInstruction(llvm::Instruction&)
+       90          8 [ 0.000023,  0.000035,  0.000106,  0.000106,  0.000106]  0.000342  X86ISelLowering.cpp:3363:0: llvm::X86TargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const
+      124         32 [ 0.000003,  0.000007,  0.000016,  0.000041,  0.000041]  0.000310  Verifier.cpp:1967:0: (anonymous namespace)::Verifier::visitFunction(llvm::Function const&)
+      123          1 [ 0.000302,  0.000302,  0.000302,  0.000302,  0.000302]  0.000302  LLVMContextImpl.cpp:54:0: llvm::LLVMContextImpl::~LLVMContextImpl()
+      139         46 [ 0.000000,  0.000002,  0.000006,  0.000008,  0.000019]  0.000138  TargetLowering.cpp:506:0: llvm::TargetLowering::SimplifyDemandedBits(llvm::SDValue, llvm::APInt const&, llvm::APInt&, llvm::APInt&, llvm::TargetLowering::TargetLoweringOpt&, unsigned int, bool) const
+```
+
+This shows us that for our input file, `llc` spent the most cumulative time
 in the lexer (a total of 1 millisecond). If we wanted for example to work with
 this data in a spreadsheet, we can output the results as CSV using the
-``-format=csv`` option to the command for further analysis.
+`-format=csv` option to the command for further analysis.
 
 If we want to get a textual representation of the raw trace we can use the
-``llvm-xray convert`` tool to get YAML output. The first few lines of that
+`llvm-xray convert` tool to get YAML output. The first few lines of that
 output for an example trace would look like the following:
 
-::
-
-  $ llvm-xray convert -f yaml --symbolize --instr_map=./bin/llc xray-log.llc.m35qPB
-  ---
-  header:
-    version:         1
-    type:            0
-    constant-tsc:    true
-    nonstop-tsc:     true
-    cycle-frequency: 2601000000
-  records:
-    - { type: 0, func-id: 110, function: __cxx_global_var_init.8, cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426023268520 }
-    - { type: 0, func-id: 110, function: __cxx_global_var_init.8, cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426023523052 }
-    - { type: 0, func-id: 164, function: __cxx_global_var_init, cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426029925386 }
-    - { type: 0, func-id: 164, function: __cxx_global_var_init, cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426030031128 }
-    - { type: 0, func-id: 142, function: '(anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*)', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426046951388 }
-    - { type: 0, func-id: 142, function: '(anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*)', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426047282020 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426047857332 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426047984152 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426048036584 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426048042292 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426048055056 }
-    - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426048067316 }
-
-Controlling Fidelity
---------------------
+```
+$ llvm-xray convert -f yaml --symbolize --instr_map=./bin/llc xray-log.llc.m35qPB
+---
+header:
+  version:         1
+  type:            0
+  constant-tsc:    true
+  nonstop-tsc:     true
+  cycle-frequency: 2601000000
+records:
+  - { type: 0, func-id: 110, function: __cxx_global_var_init.8, cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426023268520 }
+  - { type: 0, func-id: 110, function: __cxx_global_var_init.8, cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426023523052 }
+  - { type: 0, func-id: 164, function: __cxx_global_var_init, cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426029925386 }
+  - { type: 0, func-id: 164, function: __cxx_global_var_init, cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426030031128 }
+  - { type: 0, func-id: 142, function: '(anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*)', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426046951388 }
+  - { type: 0, func-id: 142, function: '(anonymous namespace)::CommandLineParser::ParseCommandLineOptions(int, char const* const*, llvm::StringRef, llvm::raw_ostream*)', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426047282020 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426047857332 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426047984152 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426048036584 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426048042292 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-enter, tsc: 5434426048055056 }
+  - { type: 0, func-id: 187, function: 'llvm::LLLexer::LexIdentifier()', cpu: 37, thread: 69819, kind: function-exit, tsc: 5434426048067316 }
+```
+
+## Controlling Fidelity
 
 So far in our examples, we haven't been getting full coverage of the functions
 we have in the binary. To get that, we need to modify the compiler flags so
 that we can instrument more (if not all) the functions we have in the binary.
 We have two options for doing that, and we explore both of these below.
 
-Instruction Threshold
-`````````````````````
+### Instruction Threshold
 
 The first "blunt" way of doing this is by setting the minimum threshold for
 function bodies to 1. We can do that with the
-``-fxray-instruction-threshold=N`` flag when building our binary. We rebuild
-``llc`` with this option and observe the results:
-
-::
-
-  $ rm CMakeCache.txt
-  $ cmake -GNinja ../llvm -DCMAKE_BUILD_TYPE=Release \
-      -DCMAKE_C_FLAGS_RELEASE="-fxray-instrument -fxray-instruction-threshold=1" \
-      -DCMAKE_CXX_FLAGS="-fxray-instrument -fxray-instruction-threshold=1"
-  $ ninja llc
-  $ XRAY_OPTIONS="patch_premain=true" ./bin/llc input.ll
-  ==69819==XRay: Log file in 'xray-log.llc.5rqxkU'
-
-  $ llvm-xray account xray-log.llc.5rqxkU --top=10 --sort=sum --sortorder=dsc --instr_map=./bin/llc
-  Functions with latencies: 36652
-   funcid      count [      min,       med,       90p,       99p,       max]       sum  function
-       75          1 [ 0.672368,  0.672368,  0.672368,  0.672368,  0.672368]  0.672368  llc.cpp:271:0: main
-       78          1 [ 0.626455,  0.626455,  0.626455,  0.626455,  0.626455]  0.626455  llc.cpp:381:0: compileModule(char**, llvm::LLVMContext&)
-   139617          1 [ 0.472618,  0.472618,  0.472618,  0.472618,  0.472618]  0.472618  LegacyPassManager.cpp:1723:0: llvm::legacy::PassManager::run(llvm::Module&)
-   139610          1 [ 0.472618,  0.472618,  0.472618,  0.472618,  0.472618]  0.472618  LegacyPassManager.cpp:1681:0: llvm::legacy::PassManagerImpl::run(llvm::Module&)
-   139612          1 [ 0.470948,  0.470948,  0.470948,  0.470948,  0.470948]  0.470948  LegacyPassManager.cpp:1564:0: (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&)
-   139607          2 [ 0.147345,  0.315994,  0.315994,  0.315994,  0.315994]  0.463340  LegacyPassManager.cpp:1530:0: llvm::FPPassManager::runOnModule(llvm::Module&)
-   139605         21 [ 0.000002,  0.000002,  0.102593,  0.213336,  0.213336]  0.463331  LegacyPassManager.cpp:1491:0: llvm::FPPassManager::runOnFunction(llvm::Function&)
-   139563      26096 [ 0.000002,  0.000002,  0.000037,  0.000063,  0.000215]  0.225708  LegacyPassManager.cpp:1083:0: llvm::PMDataManager::findAnalysisPass(void const*, bool)
-   108055        188 [ 0.000002,  0.000120,  0.001375,  0.004523,  0.062624]  0.159279  MachineFunctionPass.cpp:38:0: llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
-    62635         22 [ 0.000041,  0.000046,  0.000050,  0.126744,  0.126744]  0.127715  X86TargetMachine.cpp:242:0: llvm::X86TargetMachine::getSubtargetImpl(llvm::Function const&) const
-
-
-Instrumentation Attributes
-``````````````````````````
+`-fxray-instruction-threshold=N` flag when building our binary. We rebuild
+`llc` with this option and observe the results:
+
+```
+$ rm CMakeCache.txt
+$ cmake -GNinja ../llvm -DCMAKE_BUILD_TYPE=Release \
+    -DCMAKE_C_FLAGS_RELEASE="-fxray-instrument -fxray-instruction-threshold=1" \
+    -DCMAKE_CXX_FLAGS="-fxray-instrument -fxray-instruction-threshold=1"
+$ ninja llc
+$ XRAY_OPTIONS="patch_premain=true" ./bin/llc input.ll
+==69819==XRay: Log file in 'xray-log.llc.5rqxkU'
+
+$ llvm-xray account xray-log.llc.5rqxkU --top=10 --sort=sum --sortorder=dsc --instr_map=./bin/llc
+Functions with latencies: 36652
+ funcid      count [      min,       med,       90p,       99p,       max]       sum  function
+     75          1 [ 0.672368,  0.672368,  0.672368,  0.672368,  0.672368]  0.672368  llc.cpp:271:0: main
+     78          1 [ 0.626455,  0.626455,  0.626455,  0.626455,  0.626455]  0.626455  llc.cpp:381:0: compileModule(char**, llvm::LLVMContext&)
+ 139617          1 [ 0.472618,  0.472618,  0.472618,  0.472618,  0.472618]  0.472618  LegacyPassManager.cpp:1723:0: llvm::legacy::PassManager::run(llvm::Module&)
+ 139610          1 [ 0.472618,  0.472618,  0.472618,  0.472618,  0.472618]  0.472618  LegacyPassManager.cpp:1681:0: llvm::legacy::PassManagerImpl::run(llvm::Module&)
+ 139612          1 [ 0.470948,  0.470948,  0.470948,  0.470948,  0.470948]  0.470948  LegacyPassManager.cpp:1564:0: (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&)
+ 139607          2 [ 0.147345,  0.315994,  0.315994,  0.315994,  0.315994]  0.463340  LegacyPassManager.cpp:1530:0: llvm::FPPassManager::runOnModule(llvm::Module&)
+ 139605         21 [ 0.000002,  0.000002,  0.102593,  0.213336,  0.213336]  0.463331  LegacyPassManager.cpp:1491:0: llvm::FPPassManager::runOnFunction(llvm::Function&)
+ 139563      26096 [ 0.000002,  0.000002,  0.000037,  0.000063,  0.000215]  0.225708  LegacyPassManager.cpp:1083:0: llvm::PMDataManager::findAnalysisPass(void const*, bool)
+ 108055        188 [ 0.000002,  0.000120,  0.001375,  0.004523,  0.062624]  0.159279  MachineFunctionPass.cpp:38:0: llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
+  62635         22 [ 0.000041,  0.000046,  0.000050,  0.126744,  0.126744]  0.127715  X86TargetMachine.cpp:242:0: llvm::X86TargetMachine::getSubtargetImpl(llvm::Function const&) const
+```
+
+### Instrumentation Attributes
 
 The other way is to use configuration files for selecting which functions
 should always be instrumented by the compiler. This gives us a way of ensuring
@@ -177,169 +166,163 @@ instrument, and another for functions to never instrument. The format of these
 files are exactly the same as the SanitizerLists files that control similar
 things for the sanitizer implementations. For example:
 
-::
+```
+# xray-attr-list.txt
+# always instrument functions that match the following filters:
+[always]
+fun:main
 
-  # xray-attr-list.txt
-  # always instrument functions that match the following filters:
-  [always]
-  fun:main
-
-  # never instrument functions that match the following filters:
-  [never]
-  fun:__cxx_*
+# never instrument functions that match the following filters:
+[never]
+fun:__cxx_*
+```
 
 Given the file above we can re-build by providing it to the
-``-fxray-attr-list=`` flag to clang. You can have multiple files, each defining
+`-fxray-attr-list=` flag to clang. You can have multiple files, each defining
 different sets of attribute sets, to be combined into a single list by clang.
 
-The XRay stack tool
--------------------
+## The XRay stack tool
 
-Given a trace, and optionally an instrumentation map, the ``llvm-xray stack``
+Given a trace, and optionally an instrumentation map, the `llvm-xray stack`
 command can be used to analyze a call stack graph constructed from the function
 call timeline.
 
 The way to use the command is to output the top stacks by call count and time spent.
 
-::
-
-  $ llvm-xray stack xray-log.llc.5rqxkU --instr_map=./bin/llc
+```
+$ llvm-xray stack xray-log.llc.5rqxkU --instr_map=./bin/llc
 
-  Unique Stacks: 3069
-  Top 10 Stacks by leaf sum:
+Unique Stacks: 3069
+Top 10 Stacks by leaf sum:
 
-  Sum: 9633790
-  lvl   function                                                            count              sum
-  #0    main                                                                    1         58421550
-  #1    compileModule(char**, llvm::LLVMContext&)                               1         51440360
-  #2    llvm::legacy::PassManagerImpl::run(llvm::Module&)                       1         40535375
-  #3    llvm::FPPassManager::runOnModule(llvm::Module&)                         2         39337525
-  #4    llvm::FPPassManager::runOnFunction(llvm::Function&)                     6         39331465
-  #5    llvm::PMDataManager::verifyPreservedAnalysis(llvm::Pass*)             399         16628590
-  #6    llvm::PMTopLevelManager::findAnalysisPass(void const*)               4584         15155600
-  #7    llvm::PMDataManager::findAnalysisPass(void const*, bool)            32088          9633790
+Sum: 9633790
+lvl   function                                                            count              sum
+#0    main                                                                    1         58421550
+#1    compileModule(char**, llvm::LLVMContext&)                               1         51440360
+#2    llvm::legacy::PassManagerImpl::run(llvm::Module&)                       1         40535375
+#3    llvm::FPPassManager::runOnModule(llvm::Module&)                         2         39337525
+#4    llvm::FPPassManager::runOnFunction(llvm::Function&)                     6         39331465
+#5    llvm::PMDataManager::verifyPreservedAnalysis(llvm::Pass*)             399         16628590
+#6    llvm::PMTopLevelManager::findAnalysisPass(void const*)               4584         15155600
+#7    llvm::PMDataManager::findAnalysisPass(void const*, bool)            32088          9633790
 
-  ..etc..
+..etc..
+```
 
 In the default mode, identical stacks on different threads are independently
 aggregated. In a multithreaded program, you may end up having identical call
 stacks fill your list of top calls.
 
-To address this, you may specify the ``--aggregate-threads`` or
-``--per-thread-stacks`` flags. ``--per-thread-stacks`` treats the thread id as an
-implicit root in each call stack tree, while ``--aggregate-threads`` combines
+To address this, you may specify the `--aggregate-threads` or
+`--per-thread-stacks` flags. `--per-thread-stacks` treats the thread id as an
+implicit root in each call stack tree, while `--aggregate-threads` combines
 identical stacks from all threads.
 
-Flame Graph Generation
-----------------------
+## Flame Graph Generation
 
-The ``llvm-xray stack`` tool may also be used to generate flamegraphs for
+The `llvm-xray stack` tool may also be used to generate flamegraphs for
 visualizing your instrumented invocations. The tool does not generate the graphs
 themselves, but instead generates a format that can be used with Brendan Gregg's
-FlameGraph tool, currently available on `github
-<https://github.com/brendangregg/FlameGraph>`_.
+FlameGraph tool, currently available on [github](https://github.com/brendangregg/FlameGraph).
 
 To generate output for a flamegraph, a few more options are necessary.
 
-- ``--all-stacks`` - Emits all of the stacks.
-- ``--stack-format`` - Choose the flamegraph output format 'flame'.
-- ``--aggregation-type`` - Choose the metric to graph.
+- `--all-stacks` - Emits all of the stacks.
+- `--stack-format` - Choose the flamegraph output format 'flame'.
+- `--aggregation-type` - Choose the metric to graph.
 
 You may pipe the command output directly to the flamegraph tool to obtain an
 svg file.
 
-::
-
-  $ llvm-xray stack xray-log.llc.5rqxkU --instr_map=./bin/llc --stack-format=flame --aggregation-type=time --all-stacks | \
-  /path/to/FlameGraph/flamegraph.pl > flamegraph.svg
+```
+$ llvm-xray stack xray-log.llc.5rqxkU --instr_map=./bin/llc --stack-format=flame --aggregation-type=time --all-stacks | \
+/path/to/FlameGraph/flamegraph.pl > flamegraph.svg
+```
 
 If you open the svg in a browser, mouse events allow exploring the call stacks.
 
-Chrome Trace Viewer Visualization
----------------------------------
+## Chrome Trace Viewer Visualization
 
 We can also generate a trace which can be loaded by the Chrome Trace Viewer
 from the same generated trace:
 
-::
+```
+$ llvm-xray convert --symbolize --instr_map=./bin/llc \
+  --output-format=trace_event xray-log.llc.5rqxkU \
+    | gzip > llc-trace.txt.gz
+```
 
-  $ llvm-xray convert --symbolize --instr_map=./bin/llc \
-    --output-format=trace_event xray-log.llc.5rqxkU \
-      | gzip > llc-trace.txt.gz
+From a Chrome browser, navigating to `chrome:///tracing` allows us to load
+the `sample-trace.txt.gz` file to visualize the execution trace.
 
-From a Chrome browser, navigating to ``chrome:///tracing`` allows us to load
-the ``sample-trace.txt.gz`` file to visualize the execution trace.
+## Further Exploration
 
-Further Exploration
--------------------
-
-The ``llvm-xray`` tool has a few other subcommands that are in various stages
+The `llvm-xray` tool has a few other subcommands that are in various stages
 of being developed. One interesting subcommand that can highlight a few
-interesting things is the ``graph`` subcommand. Given for example the following
+interesting things is the `graph` subcommand. Given for example the following
 toy program that we build with XRay instrumentation, we can see how the
 generated graph may be a helpful indicator of where time is being spent for the
 application.
 
-.. code-block:: c++
-
-  // sample.cc
-  #include <iostream>
-  #include <thread>
-
-  [[clang::xray_always_instrument]] void f() {
-    std::cerr << '.';
-  }
+```c++
+// sample.cc
+#include <iostream>
+#include <thread>
 
-  [[clang::xray_always_instrument]] void g() {
-    for (int i = 0; i < 1 << 10; ++i) {
-      std::cerr << '-';
-    }
-  }
+[[clang::xray_always_instrument]] void f() {
+  std::cerr << '.';
+}
 
-  int main(int argc, char* argv[]) {
-    std::thread t1([] {
-      for (int i = 0; i < 1 << 10; ++i)
-        f();
-    });
-    std::thread t2([] {
-      g();
-    });
-    t1.join();
-    t2.join();
-    std::cerr << '\n';
+[[clang::xray_always_instrument]] void g() {
+  for (int i = 0; i < 1 << 10; ++i) {
+    std::cerr << '-';
   }
+}
+
+int main(int argc, char* argv[]) {
+  std::thread t1([] {
+    for (int i = 0; i < 1 << 10; ++i)
+      f();
+  });
+  std::thread t2([] {
+    g();
+  });
+  t1.join();
+  t2.join();
+  std::cerr << '\n';
+}
+```
 
 We then build the above with XRay instrumentation:
 
-::
-
-  $ clang++ -o sample -O3 sample.cc -std=c++11 -fxray-instrument -fxray-instruction-threshold=1
-  $ XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic" ./sample
+```
+$ clang++ -o sample -O3 sample.cc -std=c++11 -fxray-instrument -fxray-instruction-threshold=1
+$ XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic" ./sample
+```
 
 We can then explore the graph rendering of the trace generated by this sample
 application. We assume you have the graphviz tools available in your system,
-including both ``unflatten`` and ``dot``. If you prefer rendering or exploring
-the graph using another tool, then that should be feasible as well. ``llvm-xray
-graph`` will create DOT format graphs which should be usable in most graph
-rendering applications. One example invocation of the ``llvm-xray graph``
+including both `unflatten` and `dot`. If you prefer rendering or exploring
+the graph using another tool, then that should be feasible as well. `llvm-xray
+graph` will create DOT format graphs which should be usable in most graph
+rendering applications. One example invocation of the `llvm-xray graph`
 command should yield some interesting insights to the workings of C++
 applications:
 
-::
+```
+$ llvm-xray graph xray-log.sample.* -m sample --color-edges=sum --edge-label=sum \
+    | unflatten -f -l10 | dot -Tsvg -o sample.svg
+```
 
-  $ llvm-xray graph xray-log.sample.* -m sample --color-edges=sum --edge-label=sum \
-      | unflatten -f -l10 | dot -Tsvg -o sample.svg
-
-
-Next Steps
-----------
+## Next Steps
 
 If you have some interesting analyses you'd like to implement as part of the
 llvm-xray tool, please feel free to propose them on the llvm-dev@ mailing list.
 The following are some ideas to inspire you in getting involved and potentially
 making things better.
 
-  - Implement a query/filtering library that allows for finding patterns in the
-    XRay traces.
-  - Collecting function call stacks and how often they're encountered in the
-    XRay trace.
+> - Implement a query/filtering library that allows for finding patterns in the
+>   XRay traces.
+> - Collecting function call stacks and how often they're encountered in the
+>   XRay trace.
+
diff --git a/llvm/docs/XRayFDRFormat.md b/llvm/docs/XRayFDRFormat.md
index 86048b78096cf..19005b5a4aca7 100644
--- a/llvm/docs/XRayFDRFormat.md
+++ b/llvm/docs/XRayFDRFormat.md
@@ -1,13 +1,10 @@
-======================================
-XRay Flight Data Recorder Trace Format
-======================================
+---
+Version: 1 as of 2017-07-20
+---
 
-:Version: 1 as of 2017-07-20
+# XRay Flight Data Recorder Trace Format
 
-
-
-Introduction
-============
+## Introduction
 
 When gathering XRay traces in Flight Data Recorder mode, each thread of an
 application will claim buffers to fill with trace data, which at some point
@@ -18,9 +15,7 @@ corresponds to the buffer.
 
 This document describes the format of a trace file.
 
-
-General
-=======
+## General
 
 Each trace file corresponds to a sequence of events in a particular thread.
 
@@ -29,57 +24,28 @@ The file has a header followed by a sequence of discriminated record types.
 The endianness of byte fields matches the endianness of the platform which
 produced the trace file.
 
-
-Header Section
-==============
+## Header Section
 
 A trace file begins with a 32-byte header.
 
-+-------------------+-----------------+----------------------------------------+
-| Field             | Size (bytes)    | Description                            |
-+===================+=================+========================================+
-| version           | ``2``           | Anticipates versioned  readers. This   |
-|                   |                 | document describes the format when     |
-|                   |                 | version == 1                           |
-+-------------------+-----------------+----------------------------------------+
-| type              | ``2``           | An enumeration encoding the type of    |
-|                   |                 | trace. Flight Data Recorder mode       |
-|                   |                 | traces have type == 1                  |
-+-------------------+-----------------+----------------------------------------+
-| bitfield          | ``4``           | Holds parameters that are not aligned  |
-|                   |                 | to bytes. Further described below.     |
-+-------------------+-----------------+----------------------------------------+
-| cycle_frequency   | ``8``           | The frequency in hertz of the CPU      |
-|                   |                 | oscillator used to measure duration of |
-|                   |                 | events in ticks.                       |
-+-------------------+-----------------+----------------------------------------+
-| buffer_size       | ``8``           | The size in bytes of the data portion  |
-|                   |                 | of the trace following the header.     |
-+-------------------+-----------------+----------------------------------------+
-| reserved          | ``8``           | Reserved for future use.               |
-+-------------------+-----------------+----------------------------------------+
+| Field           | Size (bytes) | Description                                                                                |
+| --------------- | ------------ | ------------------------------------------------------------------------------------------ |
+| version         | `2`          | Anticipates versioned readers. This document describes the format when version == 1        |
+| type            | `2`          | An enumeration encoding the type of trace. Flight Data Recorder mode traces have type == 1 |
+| bitfield        | `4`          | Holds parameters that are not aligned to bytes. Further described below.                   |
+| cycle_frequency | `8`          | The frequency in hertz of the CPU oscillator used to measure duration of events in ticks.  |
+| buffer_size     | `8`          | The size in bytes of the data portion of the trace following the header.                   |
+| reserved        | `8`          | Reserved for future use.                                                                   |
 
 The bitfield parameter of the file header is composed of the following fields.
 
-+-------------------+----------------+-----------------------------------------+
-| Field             | Size (bits)    | Description                             |
-+===================+================+=========================================+
-| constant_tsc      | ``1``          | Whether the platform's timestamp        |
-|                   |                | counter used to record ticks between    |
-|                   |                | events ticks at a constant frequency    |
-|                   |                | despite CPU frequency changes.          |
-|                   |                | 0 == non-constant. 1 == constant.       |
-+-------------------+----------------+-----------------------------------------+
-| nonstop_tsc       | ``1``          | Whether the tsc continues to count      |
-|                   |                | despite whether the CPU is in a low     |
-|                   |                | power state. 0 == stop. 1 == non-stop.  |
-+-------------------+----------------+-----------------------------------------+
-| reserved          | ``30``         | Not meaningful.                         |
-+-------------------+----------------+-----------------------------------------+
-
-
-Data Section
-============
+| Field        | Size (bits) | Description                                                                                                                                                                 |
+| ------------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| constant_tsc | `1`         | Whether the platform's timestamp counter used to record ticks between events ticks at a constant frequency despite CPU frequency changes. 0 == non-constant. 1 == constant. |
+| nonstop_tsc  | `1`         | Whether the tsc continues to count despite whether the CPU is in a low power state. 0 == stop. 1 == non-stop.                                                               |
+| reserved     | `30`        | Not meaningful.                                                                                                                                                             |
+
+## Data Section
 
 Following the header in a trace is a data section with size matching the
 buffer_size field in the header.
@@ -88,20 +54,17 @@ The data section is a stream of elements of different types.
 
 There are a few categories of data in the sequence.
 
-- ``Function Records``: Function Records contain the timing of entry into and
+- `Function Records`: Function Records contain the timing of entry into and
   exit from function execution. Function Records have 8 bytes each.
-
-- ``Metadata Records``: Metadata records serve many purposes. Mostly, they
+- `Metadata Records`: Metadata records serve many purposes. Mostly, they
   capture information that may be too costly to record for each function, but
   that is required to contextualize the fine-grained timings. They also are used
   as markers for user-defined Event Data payloads. Metadata records have 16
   bytes each.
-
-- ``Event Data``: Free form data may be associated with events that are traced
+- `Event Data`: Free form data may be associated with events that are traced
   by the binary and encode data defined by a handler function. Event data is
   always preceded with a marker record which indicates how large it is.
-
-- ``Function Arguments``: The arguments to some functions are included in the
+- `Function Arguments`: The arguments to some functions are included in the
   trace. These are either pointer addresses or primitives that are read and
   logged independently of their types in a high level language. To the tracer,
   they are all numbers. Function Records that have attached arguments will
@@ -113,68 +76,41 @@ There are a few categories of data in the sequence.
 A reader of the memory format must maintain a state machine. The format makes no
 attempt to pad for alignment, and it is not seekable.
 
-
-Function Records
-----------------
+### Function Records
 
 Function Records have an 8-byte layout. This layout encodes information to
 reconstruct a call stack of instrumented function and their durations.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bits)  | Description                                   |
-+===============+==============+===============================================+
-| discriminant  | ``1``        | Indicates whether a reader should read a      |
-|               |              | Function or Metadata record. Set to ``0`` for |
-|               |              | Function records.                             |
-+---------------+--------------+-----------------------------------------------+
-| action        | ``3``        | Specifies whether the function is being       |
-|               |              | entered, exited, or is a non-standard entry   |
-|               |              | or exit produced by optimizations.            |
-+---------------+--------------+-----------------------------------------------+
-| function_id   | ``28``       | A numeric ID for the function. Resolved to a  |
-|               |              | name via the xray instrumentation map. The    |
-|               |              | instrumentation map is built by xray at       |
-|               |              | compile time into an object file and pairs    |
-|               |              | the function ids to addresses. It is used for |
-|               |              | patching and as a lookup into the binary's    |
-|               |              | symbols to obtain names.                      |
-+---------------+--------------+-----------------------------------------------+
-| tsc_delta     | ``32``       | The number of ticks of the timestamp counter  |
-|               |              | since a previous record recorded a delta or   |
-|               |              | other TSC resetting event.                    |
-+---------------+--------------+-----------------------------------------------+
+| Field        | Size (bits) | Description                                                                                                                                                                                                                                                                                  |
+| ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| discriminant | `1`         | Indicates whether a reader should read a Function or Metadata record. Set to `0` for Function records.                                                                                                                                                                                       |
+| action       | `3`         | Specifies whether the function is being entered, exited, or is a non-standard entry or exit produced by optimizations.                                                                                                                                                                       |
+| function_id  | `28`        | A numeric ID for the function. Resolved to a name via the xray instrumentation map. The instrumentation map is built by xray at compile time into an object file and pairs the function ids to addresses. It is used for patching and as a lookup into the binary's symbols to obtain names. |
+| tsc_delta    | `32`        | The number of ticks of the timestamp counter since a previous record recorded a delta or other TSC resetting event.                                                                                                                                                                          |
 
 On little-endian machines, the bitfields are ordered from least significant bit
 bit to most significant bit. A reader can read an 8-bit value and apply the mask
-``0x01`` for the discriminant. Similarly, they can read 32 bits and unsigned
-shift right by ``0x04`` to obtain the function_id field.
+`0x01` for the discriminant. Similarly, they can read 32 bits and unsigned
+shift right by `0x04` to obtain the function_id field.
 
 On big-endian machine, the bitfields are written in order from most significant
 bit to least significant bit. A reader would read an 8-bit value and unsigned
 shift right by 7 bits for the discriminant. The function_id field could be
-obtained by reading a 32-bit value and applying the mask ``0x0FFFFFFF``.
+obtained by reading a 32-bit value and applying the mask `0x0FFFFFFF`.
 
 Function action types are as follows.
 
-+---------------+--------------+-----------------------------------------------+
-| Type          | Number       | Description                                   |
-+===============+==============+===============================================+
-| Entry         | ``0``        | Typical function entry.                       |
-+---------------+--------------+-----------------------------------------------+
-| Exit          | ``1``        | Typical function exit.                        |
-+---------------+--------------+-----------------------------------------------+
-| Tail_Exit     | ``2``        | An exit from a function due to tail call      |
-|               |              | optimization.                                 |
-+---------------+--------------+-----------------------------------------------+
-| Entry_Args    | ``3``        | A function entry that records arguments.      |
-+---------------+--------------+-----------------------------------------------+
+| Type       | Number | Description                                            |
+| ---------- | ------ | ------------------------------------------------------ |
+| Entry      | `0`    | Typical function entry.                                |
+| Exit       | `1`    | Typical function exit.                                 |
+| Tail_Exit  | `2`    | An exit from a function due to tail call optimization. |
+| Entry_Args | `3`    | A function entry that records arguments.               |
 
 Entry_Args records do not contain the arguments themselves. Instead, metadata
 records for each of the logged args follow the function record in the stream.
 
-
-Metadata Records
-----------------
+### Metadata Records
 
 Interspersed throughout the buffer are 16-byte Metadata records. For typically
 instrumented binaries, they will be sparser than Function records, and they
@@ -187,81 +123,50 @@ The same bit field rules described for function records apply to the first byte
 of MetadataRecords. Within this byte, little endian machines use lsb to msb
 ordering and big endian machines use msb to lsb ordering.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size         | Description                                   |
-+===============+==============+===============================================+
-| discriminant  | ``1 bit``    | Indicates whether a reader should read a      |
-|               |              | Function or Metadata record. Set to ``1`` for |
-|               |              | Metadata records.                             |
-+---------------+--------------+-----------------------------------------------+
-| record_kind   | ``7 bits``   | The type of Metadata record.                  |
-+---------------+--------------+-----------------------------------------------+
-| data          | ``15 bytes`` | A data field used differently for each record |
-|               |              | type.                                         |
-+---------------+--------------+-----------------------------------------------+
+| Field        | Size       | Description                                                                                            |
+| ------------ | ---------- | ------------------------------------------------------------------------------------------------------ |
+| discriminant | `1 bit`    | Indicates whether a reader should read a Function or Metadata record. Set to `1` for Metadata records. |
+| record_kind  | `7 bits`   | The type of Metadata record.                                                                           |
+| data         | `15 bytes` | A data field used differently for each record type.                                                    |
 
 Here is a table of the enumerated record kinds.
 
-+--------+---------------------------+
-| Number | Type                      |
-+========+===========================+
-| 0      | NewBuffer                 |
-+--------+---------------------------+
-| 1      | EndOfBuffer               |
-+--------+---------------------------+
-| 2      | NewCPUId                  |
-+--------+---------------------------+
-| 3      | TSCWrap                   |
-+--------+---------------------------+
-| 4      | WallTimeMarker            |
-+--------+---------------------------+
-| 5      | CustomEventMarker         |
-+--------+---------------------------+
-| 6      | CallArgument              |
-+--------+---------------------------+
-
-
-NewBuffer Records
------------------
+| Number | Type              |
+| ------ | ----------------- |
+| 0      | NewBuffer         |
+| 1      | EndOfBuffer       |
+| 2      | NewCPUId          |
+| 3      | TSCWrap           |
+| 4      | WallTimeMarker    |
+| 5      | CustomEventMarker |
+| 6      | CallArgument      |
+
+### NewBuffer Records
 
 Each buffer begins with a NewBuffer record immediately after the header.
 It records the thread ID of the thread that the trace belongs to.
 
 Its data segment is as follows.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| thread_Id     | ``2``        | Thread ID for buffer.                         |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``13``       | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
+| Field     | Size (bytes) | Description           |
+| --------- | ------------ | --------------------- |
+| thread_Id | `2`          | Thread ID for buffer. |
+| reserved  | `13`         | Unused.               |
 
-
-WallClockTime Records
----------------------
+### WallClockTime Records
 
 Following the NewBuffer record, each buffer records an absolute time as a frame
 of reference for the durations recorded by timestamp counter deltas.
 
 Its data segment is as follows.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| seconds       | ``8``        | Seconds on absolute timescale. The starting   |
-|               |              | point is unspecified and depends on the       |
-|               |              | implementation and platform configured by the |
-|               |              | tracer.                                       |
-+---------------+--------------+-----------------------------------------------+
-| microseconds  | ``4``        | The microsecond component of the time.        |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``3``        | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
-
+| Field        | Size (bytes) | Description                                                                                                                               |
+| ------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
+| seconds      | `8`          | Seconds on absolute timescale. The starting point is unspecified and depends on the implementation and platform configured by the tracer. |
+| microseconds | `4`          | The microsecond component of the time.                                                                                                    |
+| reserved     | `3`          | Unused.                                                                                                                                   |
 
-NewCpuId Records
-----------------
+### NewCpuId Records
 
 Each function entry invokes a routine to determine what CPU is executing.
 Typically, this is done with readtscp, which reads the timestamp counter at the
@@ -272,19 +177,13 @@ first instrumented entry point, the tracer will output a NewCpuId record.
 
 Its data segment is as follows.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| cpu_id        | ``2``        | CPU Id.                                       |
-+---------------+--------------+-----------------------------------------------+
-| absolute_tsc  | ``8``        | The absolute value of the timestamp counter.  |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``5``        | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
-
+| Field        | Size (bytes) | Description                                  |
+| ------------ | ------------ | -------------------------------------------- |
+| cpu_id       | `2`          | CPU Id.                                      |
+| absolute_tsc | `8`          | The absolute value of the timestamp counter. |
+| reserved     | `5`          | Unused.                                      |
 
-TSCWrap Records
----------------
+### TSCWrap Records
 
 Since each function record uses a 32-bit value to represent the number of ticks
 of the timestamp counter since the last reference, it is possible for this value
@@ -295,17 +194,12 @@ timestamp counter record is written in the form of a TSCWrap record.
 
 Its data segment is as follows.
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| absolute_tsc  | ``8``        | Timestamp counter value.                      |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``7``        | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
+| Field        | Size (bytes) | Description              |
+| ------------ | ------------ | ------------------------ |
+| absolute_tsc | `8`          | Timestamp counter value. |
+| reserved     | `7`          | Unused.                  |
 
-
-CallArgument Records
---------------------
+### CallArgument Records
 
 Immediately following an Entry_Args type function record, there may be one or
 more CallArgument records that contain the traced function's parameter values.
@@ -315,17 +209,12 @@ order of the function parameters.
 
 CallArgument data segment:
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| argument      | ``8``        | Numeric argument (may be pointer address).    |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``7``        | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
-
+| Field    | Size (bytes) | Description                                |
+| -------- | ------------ | ------------------------------------------ |
+| argument | `8`          | Numeric argument (may be pointer address). |
+| reserved | `7`          | Unused.                                    |
 
-CustomEventMarker Records
--------------------------
+### CustomEventMarker Records
 
 XRay provides the feature of logging custom events. This may be leveraged to
 record tracing info for RPCs or similarly trace data that is application
@@ -337,27 +226,19 @@ CustomEventMarkers to indicate their presence and size.
 
 CustomEventMarker data segment:
 
-+---------------+--------------+-----------------------------------------------+
-| Field         | Size (bytes) | Description                                   |
-+===============+==============+===============================================+
-| event_size    | ``4``        | Size of preceded event.                       |
-+---------------+--------------+-----------------------------------------------+
-| absolute_tsc  | ``8``        | A timestamp counter of the event.             |
-+---------------+--------------+-----------------------------------------------+
-| reserved      | ``3``        | Unused.                                       |
-+---------------+--------------+-----------------------------------------------+
+| Field        | Size (bytes) | Description                       |
+| ------------ | ------------ | --------------------------------- |
+| event_size   | `4`          | Size of preceded event.           |
+| absolute_tsc | `8`          | A timestamp counter of the event. |
+| reserved     | `3`          | Unused.                           |
 
-
-EndOfBuffer Records
--------------------
+### EndOfBuffer Records
 
 An EndOfBuffer record type indicates that there is no more trace data in this
 buffer. The reader is expected to seek past the remaining buffer_size expressed
 before the start of buffer and look for either another header or EOF.
 
-
-Format Grammar and Invariants
-=============================
+## Format Grammar and Invariants
 
 Not all sequences of Metadata records and Function records are valid data. A
 sequence should be parsed as a state machine. The expectations for a valid
@@ -365,35 +246,26 @@ format can be expressed as a context free grammar.
 
 This is an attempt to explain the format with statements in EBNF format.
 
-- Format := Header ThreadBuffer* EOF
-
-- ThreadBuffer := NewBuffer WallClockTime NewCPUId BodySequence* End
-
+- Format := Header ThreadBuffer\* EOF
+- ThreadBuffer := NewBuffer WallClockTime NewCPUId BodySequence\* End
 - BodySequence := NewCPUId | TSCWrap | Function | CustomEvent
-
-- Function := (Function_Entry_Args CallArgument*) | Function_Other_Type
-
+- Function := (Function_Entry_Args CallArgument\*) | Function_Other_Type
 - CustomEvent := CustomEventMarker CustomEventUnstructuredMemory
-
 - End := EndOfBuffer RemainingBufferSizeToSkip
 
-
-Function Record Order
----------------------
+### Function Record Order
 
 There are a few clarifications that may help understand what is expected of
 Function records.
 
 - Functions with an Exit are expected to have a corresponding Entry or
   Entry_Args function record precede them in the trace.
-
 - Tail_Exit Function records record the Function ID of the function whose return
   address the program counter will take. In other words, the final function that
   would be popped off of the call stack if tail call optimization was not used.
-
 - Not all functions marked for instrumentation are necessarily in the trace. The
   tracer uses heuristics to preserve the trace for non-trivial functions.
-
 - Not every entry must have a traced Exit or Tail Exit. The buffer may run out
   of space or the program may request for the tracer to finalize toreturn the
   buffer before an instrumented function exits.
+
diff --git a/llvm/docs/YamlIO.md b/llvm/docs/YamlIO.md
index a5f7069ac1d40..77ca63550e0df 100644
--- a/llvm/docs/YamlIO.md
+++ b/llvm/docs/YamlIO.md
@@ -1,71 +1,63 @@
-=====================
-YAML I/O
-=====================
+# YAML I/O
 
+## Introduction to YAML
 
-Introduction to YAML
-====================
+YAML is a human-readable data serialization language. The full YAML language
+spec can be read at [yaml.org](http://www.yaml.org/spec/1.2/spec.html#Introduction). The simplest form of
+YAML is just "scalars", "mappings", and "sequences". A scalar is any number
+or string. The pound/hash symbol (`#`) begins a comment line. A mapping is
+a set of key-value pairs where the key ends with a colon. For example:
 
-YAML is a human-readable data serialization language.  The full YAML language
-spec can be read at `yaml.org
-<http://www.yaml.org/spec/1.2/spec.html#Introduction>`_.  The simplest form of
-YAML is just "scalars", "mappings", and "sequences".  A scalar is any number
-or string.  The pound/hash symbol (``#``) begins a comment line.   A mapping is
-a set of key-value pairs where the key ends with a colon.  For example:
+```yaml
+# a mapping
+name:      Tom
+hat-size:  7
+```
 
-.. code-block:: yaml
-
-     # a mapping
-     name:      Tom
-     hat-size:  7
-
-A sequence is a list of items where each item starts with a leading dash (``-``).
+A sequence is a list of items where each item starts with a leading dash (`-`).
 For example:
 
-.. code-block:: yaml
-
-     # a sequence
-     - x86
-     - x86_64
-     - PowerPC
+```yaml
+# a sequence
+- x86
+- x86_64
+- PowerPC
+```
 
-You can combine mappings and sequences by indenting.  For example a sequence
+You can combine mappings and sequences by indenting. For example a sequence
 of mappings in which one of the mapping values is itself a sequence:
 
-.. code-block:: yaml
-
-     # a sequence of mappings with one key's value being a sequence
-     - name:      Tom
-       cpus:
-        - x86
-        - x86_64
-     - name:      Bob
-       cpus:
-        - x86
-     - name:      Dan
-       cpus:
-        - PowerPC
-        - x86
+```yaml
+# a sequence of mappings with one key's value being a sequence
+- name:      Tom
+  cpus:
+   - x86
+   - x86_64
+- name:      Bob
+  cpus:
+   - x86
+- name:      Dan
+  cpus:
+   - PowerPC
+   - x86
+```
 
 Sometimes sequences are known to be short and the one entry per line is too
 verbose, so YAML offers an alternative syntax for sequences called a "Flow
 Sequence" in which you put comma separated sequence elements into square
-brackets.  The above example could then be simplified to:
-
-
-.. code-block:: yaml
-
-     # a sequence of mappings with one key's value being a flow sequence
-     - name:      Tom
-       cpus:      [ x86, x86_64 ]
-     - name:      Bob
-       cpus:      [ x86 ]
-     - name:      Dan
-       cpus:      [ PowerPC, x86 ]
+brackets. The above example could then be simplified to:
 
+```yaml
+# a sequence of mappings with one key's value being a flow sequence
+- name:      Tom
+  cpus:      [ x86, x86_64 ]
+- name:      Bob
+  cpus:      [ x86 ]
+- name:      Dan
+  cpus:      [ PowerPC, x86 ]
+```
 
-Introduction to YAML I/O
-========================
+## Introduction to YAML I/O
 
 The use of indenting makes the YAML easy for a human to read and understand,
 but having a program read and write YAML involves a lot of tedious details.
@@ -73,987 +65,952 @@ The YAML I/O library structures and simplifies reading and writing YAML
 documents.
 
 YAML I/O assumes you have some "native" data structures which you want to be
-able to dump as YAML and recreate from YAML.  The first step is to try
+able to dump as YAML and recreate from YAML. The first step is to try
 writing example YAML for your data structures. You may find after looking at
 possible YAML representations that a direct mapping of your data structures
-to YAML is not very readable.  Often, the fields are not in an order that
-a human would find readable.  Or the same information is replicated in multiple
+to YAML is not very readable. Often, the fields are not in an order that
+a human would find readable. Or the same information is replicated in multiple
 locations, making it hard for a human to write such YAML correctly.
 
 In relational database theory there is a design step called normalization in
-which you reorganize fields and tables.  The same considerations need to
-go into the design of your YAML encoding.  But, you may not want to change
-your existing native data structures.  Therefore, when writing out YAML,
+which you reorganize fields and tables. The same considerations need to
+go into the design of your YAML encoding. But, you may not want to change
+your existing native data structures. Therefore, when writing out YAML,
 there may be a normalization step, and when reading YAML there would be a
 corresponding denormalization step.
 
-YAML I/O uses a non-invasive, traits-based design.  YAML I/O defines some
-abstract base templates.  You specialize those templates on your data types.
-For instance, if you have an enumerated type ``FooBar`` you could specialize
-``ScalarEnumerationTraits`` on that type and define the ``enumeration()`` method:
+YAML I/O uses a non-invasive, traits-based design. YAML I/O defines some
+abstract base templates. You specialize those templates on your data types.
+For instance, if you have an enumerated type `FooBar` you could specialize
+`ScalarEnumerationTraits` on that type and define the `enumeration()` method:
 
-.. code-block:: c++
+```c++
+using llvm::yaml::ScalarEnumerationTraits;
+using llvm::yaml::IO;
 
-    using llvm::yaml::ScalarEnumerationTraits;
-    using llvm::yaml::IO;
+template <>
+struct ScalarEnumerationTraits<FooBar> {
+  static void enumeration(IO &io, FooBar &value) {
+  ...
+  }
+};
+```
 
-    template <>
-    struct ScalarEnumerationTraits<FooBar> {
-      static void enumeration(IO &io, FooBar &value) {
-      ...
-      }
-    };
-
-
-As with all YAML I/O template specializations, the ``ScalarEnumerationTraits`` is used for
+As with all YAML I/O template specializations, the `ScalarEnumerationTraits` is used for
 both reading and writing YAML. That is, the mapping between in-memory enum
 values and the YAML string representation is only in one place.
 This assures that the code for writing and parsing of YAML stays in sync.
 
 To specify YAML mappings, you define a specialization on
-``llvm::yaml::MappingTraits``.
+`llvm::yaml::MappingTraits`.
 If your native data structure happens to be a struct that is already normalized,
-then the specialization is simple.  For example:
-
-.. code-block:: c++
+then the specialization is simple. For example:
 
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
 
-    template <>
-    struct MappingTraits<Person> {
-      static void mapping(IO &io, Person &info) {
-        io.mapRequired("name",         info.name);
-        io.mapOptional("hat-size",     info.hatSize);
-      }
-    };
+template <>
+struct MappingTraits<Person> {
+  static void mapping(IO &io, Person &info) {
+    io.mapRequired("name",         info.name);
+    io.mapOptional("hat-size",     info.hatSize);
+  }
+};
+```
 
-
-A YAML sequence is automatically inferred if your data type has ``begin()``/``end()``
-iterators and a ``push_back()`` method.  Therefore any of the STL containers
-(such as ``std::vector<>``) will automatically translate to YAML sequences.
+A YAML sequence is automatically inferred if your data type has `begin()`/`end()`
+iterators and a `push_back()` method. Therefore any of the STL containers
+(such as `std::vector<>`) will automatically translate to YAML sequences.
 
 Once you have defined specializations for your data types, you can
 programmatically use YAML I/O to write a YAML document:
 
-.. code-block:: c++
-
-    using llvm::yaml::Output;
+```c++
+using llvm::yaml::Output;
 
-    Person tom;
-    tom.name = "Tom";
-    tom.hatSize = 8;
-    Person dan;
-    dan.name = "Dan";
-    dan.hatSize = 7;
-    std::vector<Person> persons;
-    persons.push_back(tom);
-    persons.push_back(dan);
+Person tom;
+tom.name = "Tom";
+tom.hatSize = 8;
+Person dan;
+dan.name = "Dan";
+dan.hatSize = 7;
+std::vector<Person> persons;
+persons.push_back(tom);
+persons.push_back(dan);
 
-    Output yout(llvm::outs());
-    yout << persons;
+Output yout(llvm::outs());
+yout << persons;
+```
 
 This would write the following:
 
-.. code-block:: yaml
-
-     - name:      Tom
-       hat-size:  8
-     - name:      Dan
-       hat-size:  7
+```yaml
+- name:      Tom
+  hat-size:  8
+- name:      Dan
+  hat-size:  7
+```
 
 And you can also read such YAML documents with the following code:
 
-.. code-block:: c++
-
-    using llvm::yaml::Input;
+```c++
+using llvm::yaml::Input;
 
-    typedef std::vector<Person> PersonList;
-    std::vector<PersonList> docs;
+typedef std::vector<Person> PersonList;
+std::vector<PersonList> docs;
 
-    Input yin(document.getBuffer());
-    yin >> docs;
+Input yin(document.getBuffer());
+yin >> docs;
 
-    if ( yin.error() )
-      return;
+if ( yin.error() )
+  return;
 
-    // Process read document
-    for ( PersonList &pl : docs ) {
-      for ( Person &person : pl ) {
-        cout << "name=" << person.name;
-      }
-    }
+// Process read document
+for ( PersonList &pl : docs ) {
+  for ( Person &person : pl ) {
+    cout << "name=" << person.name;
+  }
+}
+```
 
 One other feature of YAML is the ability to define multiple documents in a
-single file.  That is why reading YAML produces a vector of your document type.
-
-
+single file. That is why reading YAML produces a vector of your document type.
 
-Error Handling
-==============
+## Error Handling
 
 When parsing a YAML document, if the input does not match your schema (as
-expressed in your ``XxxTraits<>`` specializations).  YAML I/O
-will print out an error message and your Input object's ``error()`` method will
+expressed in your `XxxTraits<>` specializations). YAML I/O
+will print out an error message and your Input object's `error()` method will
 return true. For instance, the following document:
 
-.. code-block:: yaml
+```yaml
+- name:      Tom
+  shoe-size: 12
+- name:      Dan
+  hat-size:  7
+```
 
-     - name:      Tom
-       shoe-size: 12
-     - name:      Dan
-       hat-size:  7
-
-Has a key (shoe-size) that is not defined in the schema.  YAML I/O will
+Has a key (shoe-size) that is not defined in the schema. YAML I/O will
 automatically generate this error:
 
-.. code-block:: yaml
-
-    YAML:2:2: error: unknown key 'shoe-size'
-      shoe-size:       12
-      ^~~~~~~~~
+```yaml
+YAML:2:2: error: unknown key 'shoe-size'
+  shoe-size:       12
+  ^~~~~~~~~
+```
 
 Similar errors are produced for other input not conforming to the schema.
 
+## Scalars
 
-Scalars
-=======
-
-YAML scalars are just strings (i.e., not a sequence or mapping).  The YAML I/O
+YAML scalars are just strings (i.e., not a sequence or mapping). The YAML I/O
 library provides support for translating between YAML scalars and specific
 C++ types.
 
+### Built-in types
 
-Built-in types
---------------
 The following types have built-in support in YAML I/O:
 
-* ``bool``
-* ``float``
-* ``double``
-* ``StringRef``
-* ``std::string``
-* ``int64_t``
-* ``int32_t``
-* ``int16_t``
-* ``int8_t``
-* ``uint64_t``
-* ``uint32_t``
-* ``uint16_t``
-* ``uint8_t``
-
-That is, you can use those types in fields of ``MappingTraits`` or as the element type
-in a sequence.  When reading, YAML I/O will validate that the string found
+- `bool`
+- `float`
+- `double`
+- `StringRef`
+- `std::string`
+- `int64_t`
+- `int32_t`
+- `int16_t`
+- `int8_t`
+- `uint64_t`
+- `uint32_t`
+- `uint16_t`
+- `uint8_t`
+
+That is, you can use those types in fields of `MappingTraits` or as the element type
+in a sequence. When reading, YAML I/O will validate that the string found
 is convertible to that type and error out if not.
 
+### Unique types
 
-Unique types
-------------
 Given that YAML I/O is trait based, the selection of how to convert your data
-to YAML is based on the type of your data.  But in C++ type matching, typedefs
-do not generate unique type names.  That means if you have two typedefs of
-unsigned int, to YAML I/O both types look exactly like unsigned int.  To
+to YAML is based on the type of your data. But in C++ type matching, typedefs
+do not generate unique type names. That means if you have two typedefs of
+unsigned int, to YAML I/O both types look exactly like unsigned int. To
 facilitate making unique type names, YAML I/O provides a macro which is used
 like a typedef on built-in types, but expands to create a class with conversion
-operators to and from the base type.  For example:
+operators to and from the base type. For example:
 
-.. code-block:: c++
+```c++
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFooFlags)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyBarFlags)
+```
 
-    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFooFlags)
-    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyBarFlags)
-
-This generates two classes ``MyFooFlags`` and ``MyBarFlags`` which you can use in your
-native data structures instead of ``uint32_t``. They are implicitly
-converted to and from ``uint32_t``.  The point of creating these unique types
+This generates two classes `MyFooFlags` and `MyBarFlags` which you can use in your
+native data structures instead of `uint32_t`. They are implicitly
+converted to and from `uint32_t`. The point of creating these unique types
 is that you can now specify traits on them to get different YAML conversions.
 
-Hex types
----------
+### Hex types
+
 An example use of a unique type is that YAML I/O provides fixed-sized unsigned
 integers that are written with YAML I/O as hexadecimal instead of the decimal
 format used by the built-in integer types:
 
-* ``Hex64``
-* ``Hex32``
-* ``Hex16``
-* ``Hex8``
+- `Hex64`
+- `Hex32`
+- `Hex16`
+- `Hex8`
 
-You can use ``llvm::yaml::Hex32`` instead of ``uint32_t``. The only difference will
+You can use `llvm::yaml::Hex32` instead of `uint32_t`. The only difference will
 be that when YAML I/O writes out that type it will be formatted in hexadecimal.
 
+### ScalarEnumerationTraits
 
-ScalarEnumerationTraits
------------------------
 YAML I/O supports translating between in-memory enumerations and a set of string
-values in YAML documents. This is done by specializing ``ScalarEnumerationTraits<>``
-on your enumeration type and defining an ``enumeration()`` method.
+values in YAML documents. This is done by specializing `ScalarEnumerationTraits<>`
+on your enumeration type and defining an `enumeration()` method.
 For instance, suppose you had an enumeration of CPUs and a struct with it as
 a field:
 
-.. code-block:: c++
+```c++
+enum CPUs {
+  cpu_x86_64  = 5,
+  cpu_x86     = 7,
+  cpu_PowerPC = 8
+};
 
-    enum CPUs {
-      cpu_x86_64  = 5,
-      cpu_x86     = 7,
-      cpu_PowerPC = 8
-    };
-
-    struct Info {
-      CPUs      cpu;
-      uint32_t  flags;
-    };
+struct Info {
+  CPUs      cpu;
+  uint32_t  flags;
+};
+```
 
 To support reading and writing of this enumeration, you can define a
-``ScalarEnumerationTraits`` specialization on CPUs, which can then be used
+`ScalarEnumerationTraits` specialization on CPUs, which can then be used
 as a field type:
 
-.. code-block:: c++
-
-    using llvm::yaml::ScalarEnumerationTraits;
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
-
-    template <>
-    struct ScalarEnumerationTraits<CPUs> {
-      static void enumeration(IO &io, CPUs &value) {
-        io.enumCase(value, "x86_64",  cpu_x86_64);
-        io.enumCase(value, "x86",     cpu_x86);
-        io.enumCase(value, "PowerPC", cpu_PowerPC);
-      }
-    };
-
-    template <>
-    struct MappingTraits<Info> {
-      static void mapping(IO &io, Info &info) {
-        io.mapRequired("cpu",       info.cpu);
-        io.mapOptional("flags",     info.flags, 0);
-      }
-    };
+```c++
+using llvm::yaml::ScalarEnumerationTraits;
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
+
+template <>
+struct ScalarEnumerationTraits<CPUs> {
+  static void enumeration(IO &io, CPUs &value) {
+    io.enumCase(value, "x86_64",  cpu_x86_64);
+    io.enumCase(value, "x86",     cpu_x86);
+    io.enumCase(value, "PowerPC", cpu_PowerPC);
+  }
+};
+
+template <>
+struct MappingTraits<Info> {
+  static void mapping(IO &io, Info &info) {
+    io.mapRequired("cpu",       info.cpu);
+    io.mapOptional("flags",     info.flags, 0);
+  }
+};
+```
 
 When reading YAML, if the string found does not match any of the strings
-specified by ``enumCase()`` methods, an error is automatically generated.
+specified by `enumCase()` methods, an error is automatically generated.
 When writing YAML, if the value being written does not match any of the values
-specified by the ``enumCase()`` methods, a runtime assertion is triggered.
+specified by the `enumCase()` methods, a runtime assertion is triggered.
 
+### BitValue
 
-BitValue
---------
 Another common data structure in C++ is a field where each bit has a unique
-meaning.  This is often used in a "flags" field.  YAML I/O has support for
-converting such fields to a flow sequence.   For instance suppose you
+meaning. This is often used in a "flags" field. YAML I/O has support for
+converting such fields to a flow sequence. For instance suppose you
 had the following bit flags defined:
 
-.. code-block:: c++
-
-    enum {
-      flagsPointy = 1
-      flagsHollow = 2
-      flagsFlat   = 4
-      flagsRound  = 8
-    };
-
-    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFlags)
-
-To support reading and writing of ``MyFlags``, you specialize ``ScalarBitSetTraits<>``
-on ``MyFlags`` and provide the bit values and their names.
-
-.. code-block:: c++
-
-    using llvm::yaml::ScalarBitSetTraits;
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
-
-    template <>
-    struct ScalarBitSetTraits<MyFlags> {
-      static void bitset(IO &io, MyFlags &value) {
-        io.bitSetCase(value, "hollow",  flagHollow);
-        io.bitSetCase(value, "flat",    flagFlat);
-        io.bitSetCase(value, "round",   flagRound);
-        io.bitSetCase(value, "pointy",  flagPointy);
-      }
-    };
-
-    struct Info {
-      StringRef   name;
-      MyFlags     flags;
-    };
-
-    template <>
-    struct MappingTraits<Info> {
-      static void mapping(IO &io, Info& info) {
-        io.mapRequired("name",  info.name);
-        io.mapRequired("flags", info.flags);
-       }
-    };
+```c++
+enum {
+  flagsPointy = 1
+  flagsHollow = 2
+  flagsFlat   = 4
+  flagsRound  = 8
+};
+
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFlags)
+```
+
+To support reading and writing of `MyFlags`, you specialize `ScalarBitSetTraits<>`
+on `MyFlags` and provide the bit values and their names.
+
+```c++
+using llvm::yaml::ScalarBitSetTraits;
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
+
+template <>
+struct ScalarBitSetTraits<MyFlags> {
+  static void bitset(IO &io, MyFlags &value) {
+    io.bitSetCase(value, "hollow",  flagHollow);
+    io.bitSetCase(value, "flat",    flagFlat);
+    io.bitSetCase(value, "round",   flagRound);
+    io.bitSetCase(value, "pointy",  flagPointy);
+  }
+};
+
+struct Info {
+  StringRef   name;
+  MyFlags     flags;
+};
+
+template <>
+struct MappingTraits<Info> {
+  static void mapping(IO &io, Info& info) {
+    io.mapRequired("name",  info.name);
+    io.mapRequired("flags", info.flags);
+   }
+};
+```
 
 With the above, YAML I/O (when writing) will test mask each value in the
 bitset trait against the flags field, and each that matches will
-cause the corresponding string to be added to the flow sequence.  The opposite
+cause the corresponding string to be added to the flow sequence. The opposite
 is done when reading and any unknown string values will result in an error. With
 the above schema, a same valid YAML document is:
 
-.. code-block:: yaml
-
-    name:    Tom
-    flags:   [ pointy, flat ]
+```yaml
+name:    Tom
+flags:   [ pointy, flat ]
+```
 
 Sometimes a "flags" field might contain an enumeration part
 defined by a bit-mask.
 
-.. code-block:: c++
-
-    enum {
-      flagsFeatureA = 1,
-      flagsFeatureB = 2,
-      flagsFeatureC = 4,
+```c++
+enum {
+  flagsFeatureA = 1,
+  flagsFeatureB = 2,
+  flagsFeatureC = 4,
 
-      flagsCPUMask = 24,
+  flagsCPUMask = 24,
 
-      flagsCPU1 = 8,
-      flagsCPU2 = 16
-    };
+  flagsCPU1 = 8,
+  flagsCPU2 = 16
+};
+```
 
-To support reading and writing such fields, you need to use the ``maskedBitSet()``
+To support reading and writing such fields, you need to use the `maskedBitSet()`
 method and provide the bit values, their names and the enumeration mask.
 
-.. code-block:: c++
-
-    template <>
-    struct ScalarBitSetTraits<MyFlags> {
-      static void bitset(IO &io, MyFlags &value) {
-        io.bitSetCase(value, "featureA",  flagsFeatureA);
-        io.bitSetCase(value, "featureB",  flagsFeatureB);
-        io.bitSetCase(value, "featureC",  flagsFeatureC);
-        io.maskedBitSetCase(value, "CPU1",  flagsCPU1, flagsCPUMask);
-        io.maskedBitSetCase(value, "CPU2",  flagsCPU2, flagsCPUMask);
-      }
-    };
+```c++
+template <>
+struct ScalarBitSetTraits<MyFlags> {
+  static void bitset(IO &io, MyFlags &value) {
+    io.bitSetCase(value, "featureA",  flagsFeatureA);
+    io.bitSetCase(value, "featureB",  flagsFeatureB);
+    io.bitSetCase(value, "featureC",  flagsFeatureC);
+    io.maskedBitSetCase(value, "CPU1",  flagsCPU1, flagsCPUMask);
+    io.maskedBitSetCase(value, "CPU2",  flagsCPU2, flagsCPUMask);
+  }
+};
+```
 
 YAML I/O (when writing) will apply the enumeration mask to the flags field,
 and compare the result and values from the bitset. As in case of a regular
 bitset, each that matches will cause the corresponding string to be added
 to the flow sequence.
 
-Custom Scalar
--------------
+### Custom Scalar
+
 Sometimes, for readability, a scalar needs to be formatted in a custom way. For
 instance, your internal data structure may use an integer for time (seconds since
 some epoch), but in YAML it would be much nicer to express that integer in
-some time format (e.g., ``4-May-2012 10:30pm``).  YAML I/O has a way to support
-custom formatting and parsing of scalar types by specializing ``ScalarTraits<>`` on
-your data type.  When writing, YAML I/O will provide the native type and
-your specialization must create a temporary ``llvm::StringRef``.  When reading,
-YAML I/O will provide an ``llvm::StringRef`` of scalar and your specialization
-must convert that to your native data type.  An outline of a custom scalar type
+some time format (e.g., `4-May-2012 10:30pm`). YAML I/O has a way to support
+custom formatting and parsing of scalar types by specializing `ScalarTraits<>` on
+your data type. When writing, YAML I/O will provide the native type and
+your specialization must create a temporary `llvm::StringRef`. When reading,
+YAML I/O will provide an `llvm::StringRef` of scalar and your specialization
+must convert that to your native data type. An outline of a custom scalar type
 looks like:
 
-.. code-block:: c++
-
-    using llvm::yaml::ScalarTraits;
-    using llvm::yaml::IO;
-
-    template <>
-    struct ScalarTraits<MyCustomType> {
-      static void output(const MyCustomType &value, void*,
-                         llvm::raw_ostream &out) {
-        out << value;  // do custom formatting here
-      }
-      static StringRef input(StringRef scalar, void*, MyCustomType &value) {
-        // do custom parsing here.  Return the empty string on success,
-        // or an error message on failure.
-        return StringRef();
-      }
-      // Determine if this scalar needs quotes.
-      static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
-    };
-
-Block Scalars
--------------
+```c++
+using llvm::yaml::ScalarTraits;
+using llvm::yaml::IO;
+
+template <>
+struct ScalarTraits<MyCustomType> {
+  static void output(const MyCustomType &value, void*,
+                     llvm::raw_ostream &out) {
+    out << value;  // do custom formatting here
+  }
+  static StringRef input(StringRef scalar, void*, MyCustomType &value) {
+    // do custom parsing here.  Return the empty string on success,
+    // or an error message on failure.
+    return StringRef();
+  }
+  // Determine if this scalar needs quotes.
+  static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
+};
+```
+
+### Block Scalars
 
 YAML block scalars are string literals that are represented in YAML using the
 literal block notation, just like the example shown below:
 
-.. code-block:: yaml
-
-    text: |
-      First line
-      Second line
+```yaml
+text: |
+  First line
+  Second line
+```
 
 The YAML I/O library provides support for translating between YAML block scalars
-and specific C++ types by allowing you to specialize ``BlockScalarTraits<>`` on
+and specific C++ types by allowing you to specialize `BlockScalarTraits<>` on
 your data type. The library doesn't provide any built-in support for block
-scalar I/O for types like ``std::string`` and ``llvm::StringRef`` as they are already
+scalar I/O for types like `std::string` and `llvm::StringRef` as they are already
 supported by YAML I/O and use the ordinary scalar notation by default.
 
-``BlockScalarTraits`` specializations are very similar to the
-``ScalarTraits`` specialization - YAML I/O will provide the native type and your
-specialization must create a temporary ``llvm::StringRef`` when writing, and
-it will also provide an ``llvm::StringRef`` that has the value of that block scalar
+`BlockScalarTraits` specializations are very similar to the
+`ScalarTraits` specialization - YAML I/O will provide the native type and your
+specialization must create a temporary `llvm::StringRef` when writing, and
+it will also provide an `llvm::StringRef` that has the value of that block scalar
 and your specialization must convert that to your native data type when reading.
 An example of a custom type with an appropriate specialization of
-``BlockScalarTraits`` is shown below:
-
-.. code-block:: c++
-
-    using llvm::yaml::BlockScalarTraits;
-    using llvm::yaml::IO;
-
-    struct MyStringType {
-      std::string Str;
-    };
-
-    template <>
-    struct BlockScalarTraits<MyStringType> {
-      static void output(const MyStringType &Value, void *Ctxt,
-                         llvm::raw_ostream &OS) {
-        OS << Value.Str;
-      }
-
-      static StringRef input(StringRef Scalar, void *Ctxt,
-                             MyStringType &Value) {
-        Value.Str = Scalar.str();
-        return StringRef();
-      }
-    };
-
-
-
-Mappings
-========
-
-To be translated to or from a YAML mapping for your type ``T``, you must specialize
-``llvm::yaml::MappingTraits`` on ``T`` and implement the ``void mapping(IO &io, T&)``
+`BlockScalarTraits` is shown below:
+
+```c++
+using llvm::yaml::BlockScalarTraits;
+using llvm::yaml::IO;
+
+struct MyStringType {
+  std::string Str;
+};
+
+template <>
+struct BlockScalarTraits<MyStringType> {
+  static void output(const MyStringType &Value, void *Ctxt,
+                     llvm::raw_ostream &OS) {
+    OS << Value.Str;
+  }
+
+  static StringRef input(StringRef Scalar, void *Ctxt,
+                         MyStringType &Value) {
+    Value.Str = Scalar.str();
+    return StringRef();
+  }
+};
+```
+
+## Mappings
+
+To be translated to or from a YAML mapping for your type `T`, you must specialize
+`llvm::yaml::MappingTraits` on `T` and implement the `void mapping(IO &io, T&)`
 method. If your native data structures use pointers to a class everywhere,
-you can specialize on the class pointer.  Examples:
-
-.. code-block:: c++
-
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
-
-    // Example of struct Foo which is used by value
-    template <>
-    struct MappingTraits<Foo> {
-      static void mapping(IO &io, Foo &foo) {
-        io.mapOptional("size",      foo.size);
-      ...
-      }
-    };
-
-    // Example of struct Bar which is natively always a pointer
-    template <>
-    struct MappingTraits<Bar*> {
-      static void mapping(IO &io, Bar *&bar) {
-        io.mapOptional("size",    bar->size);
-      ...
-      }
-    };
+you can specialize on the class pointer. Examples:
+
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
+
+// Example of struct Foo which is used by value
+template <>
+struct MappingTraits<Foo> {
+  static void mapping(IO &io, Foo &foo) {
+    io.mapOptional("size",      foo.size);
+  ...
+  }
+};
+
+// Example of struct Bar which is natively always a pointer
+template <>
+struct MappingTraits<Bar*> {
+  static void mapping(IO &io, Bar *&bar) {
+    io.mapOptional("size",    bar->size);
+  ...
+  }
+};
+```
 
 There are circumstances where we want to allow the entire mapping to be
-read as an enumeration.  For example, say some configuration option
-started as an enumeration.  Then it got more complex so it is now a
-mapping.  But it is necessary to support the old configuration files.
-In that case, add a function ``enumInput`` like for
-``ScalarEnumerationTraits::enumeration``.  Examples:
-
-.. code-block:: c++
-
-    struct FooBarEnum {
-      int Foo;
-      int Bar;
-      bool operator==(const FooBarEnum &R) const {
-        return Foo == R.Foo && Bar == R.Bar;
-      }
-    };
-
-    template <> struct MappingTraits<FooBarEnum> {
-      static void enumInput(IO &io, FooBarEnum &Val) {
-        io.enumCase(Val, "OnlyFoo", FooBarEnum({1, 0}));
-        io.enumCase(Val, "OnlyBar", FooBarEnum({0, 1}));
-      }
-      static void mapping(IO &io, FooBarEnum &Val) {
-        io.mapOptional("Foo", Val.Foo);
-        io.mapOptional("Bar", Val.Bar);
-      }
-    };
-
-
-No Normalization
-----------------
-
-The ``mapping()`` method is responsible, if needed, for normalizing and
+read as an enumeration. For example, say some configuration option
+started as an enumeration. Then it got more complex so it is now a
+mapping. But it is necessary to support the old configuration files.
+In that case, add a function `enumInput` like for
+`ScalarEnumerationTraits::enumeration`. Examples:
+
+```c++
+struct FooBarEnum {
+  int Foo;
+  int Bar;
+  bool operator==(const FooBarEnum &R) const {
+    return Foo == R.Foo && Bar == R.Bar;
+  }
+};
+
+template <> struct MappingTraits<FooBarEnum> {
+  static void enumInput(IO &io, FooBarEnum &Val) {
+    io.enumCase(Val, "OnlyFoo", FooBarEnum({1, 0}));
+    io.enumCase(Val, "OnlyBar", FooBarEnum({0, 1}));
+  }
+  static void mapping(IO &io, FooBarEnum &Val) {
+    io.mapOptional("Foo", Val.Foo);
+    io.mapOptional("Bar", Val.Bar);
+  }
+};
+```
+
+### No Normalization
+
+The `mapping()` method is responsible, if needed, for normalizing and
 denormalizing. In a simple case where the native data structure requires no
-normalization, the mapping method just uses ``mapOptional()`` or ``mapRequired()`` to
-bind the struct's fields to YAML key names.  For example:
+normalization, the mapping method just uses `mapOptional()` or `mapRequired()` to
+bind the struct's fields to YAML key names. For example:
 
-.. code-block:: c++
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
 
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
+template <>
+struct MappingTraits<Person> {
+  static void mapping(IO &io, Person &info) {
+    io.mapRequired("name",         info.name);
+    io.mapOptional("hat-size",     info.hatSize);
+  }
+};
+```
 
-    template <>
-    struct MappingTraits<Person> {
-      static void mapping(IO &io, Person &info) {
-        io.mapRequired("name",         info.name);
-        io.mapOptional("hat-size",     info.hatSize);
-      }
-    };
+### Normalization
 
-
-Normalization
-----------------
-
-When [de]normalization is required, the ``mapping()`` method needs a way to access
+When [de]normalization is required, the `mapping()` method needs a way to access
 normalized values as fields. To help with this, there is
-a template ``MappingNormalization<>`` which you can then use to automatically
-do the normalization and denormalization.  The template is used to create
-a local variable in your ``mapping()`` method which contains the normalized keys.
+a template `MappingNormalization<>` which you can then use to automatically
+do the normalization and denormalization. The template is used to create
+a local variable in your `mapping()` method which contains the normalized keys.
 
 Suppose you have native data type
 Polar which specifies a position in polar coordinates (distance, angle):
 
-.. code-block:: c++
-
-    struct Polar {
-      float distance;
-      float angle;
-    };
+```c++
+struct Polar {
+  float distance;
+  float angle;
+};
+```
 
 but you've decided the normalized YAML form should be in x,y coordinates. That
 is, you want the yaml to look like:
 
-.. code-block:: yaml
+```yaml
+x:   10.3
+y:   -4.7
+```
 
-    x:   10.3
-    y:   -4.7
-
-You can support this by defining a ``MappingTraits`` that normalizes the polar
+You can support this by defining a `MappingTraits` that normalizes the polar
 coordinates to x,y coordinates when writing YAML and denormalizes x,y
 coordinates into polar when reading YAML.
 
-.. code-block:: c++
-
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
 
-    template <>
-    struct MappingTraits<Polar> {
+template <>
+struct MappingTraits<Polar> {
 
-      class NormalizedPolar {
-      public:
-        NormalizedPolar(IO &io)
-          : x(0.0), y(0.0) {
-        }
-        NormalizedPolar(IO &, Polar &polar)
-          : x(polar.distance * cos(polar.angle)),
-            y(polar.distance * sin(polar.angle)) {
-        }
-        Polar denormalize(IO &) {
-          return Polar(sqrt(x*x+y*y), arctan(x,y));
-        }
+  class NormalizedPolar {
+  public:
+    NormalizedPolar(IO &io)
+      : x(0.0), y(0.0) {
+    }
+    NormalizedPolar(IO &, Polar &polar)
+      : x(polar.distance * cos(polar.angle)),
+        y(polar.distance * sin(polar.angle)) {
+    }
+    Polar denormalize(IO &) {
+      return Polar(sqrt(x*x+y*y), arctan(x,y));
+    }
 
-        float        x;
-        float        y;
-      };
+    float        x;
+    float        y;
+  };
 
-      static void mapping(IO &io, Polar &polar) {
-        MappingNormalization<NormalizedPolar, Polar> keys(io, polar);
+  static void mapping(IO &io, Polar &polar) {
+    MappingNormalization<NormalizedPolar, Polar> keys(io, polar);
 
-        io.mapRequired("x",    keys->x);
-        io.mapRequired("y",    keys->y);
-      }
-    };
+    io.mapRequired("x",    keys->x);
+    io.mapRequired("y",    keys->y);
+  }
+};
+```
 
 When writing YAML, the local variable "keys" will be a stack allocated
-instance of ``NormalizedPolar``, constructed from the supplied polar object which
-initializes it x and y fields.  The ``mapRequired()`` methods then write out the x
+instance of `NormalizedPolar`, constructed from the supplied polar object which
+initializes it x and y fields. The `mapRequired()` methods then write out the x
 and y values as key/value pairs.
 
 When reading YAML, the local variable "keys" will be a stack allocated instance
-of ``NormalizedPolar``, constructed by the empty constructor.  The ``mapRequired()``
+of `NormalizedPolar`, constructed by the empty constructor. The `mapRequired()`
 methods will find the matching key in the YAML document and fill in the x and y
-fields of the ``NormalizedPolar`` object keys. At the end of the ``mapping()`` method
-when the local keys variable goes out of scope, the ``denormalize()`` method will
+fields of the `NormalizedPolar` object keys. At the end of the `mapping()` method
+when the local keys variable goes out of scope, the `denormalize()` method will
 automatically be called to convert the read values back to polar coordinates,
-and then assigned back to the second parameter to ``mapping()``.
+and then assigned back to the second parameter to `mapping()`.
 
 In some cases, the normalized class may be a subclass of the native type and
-could be returned by the ``denormalize()`` method, except that the temporary
-normalized instance is stack allocated.  In these cases, the utility template
-``MappingNormalizationHeap<>`` can be used instead.  It just like
-``MappingNormalization<>`` except that it heap allocates the normalized object
-when reading YAML.  It never destroys the normalized object.  The ``denormalize()``
-method can this return ``this``.
+could be returned by the `denormalize()` method, except that the temporary
+normalized instance is stack allocated. In these cases, the utility template
+`MappingNormalizationHeap<>` can be used instead. It just like
+`MappingNormalization<>` except that it heap allocates the normalized object
+when reading YAML. It never destroys the normalized object. The `denormalize()`
+method can this return `this`.
 
+### Default values
 
-Default values
---------------
-Within a ``mapping()`` method, calls to ``io.mapRequired()`` mean that that key is
+Within a `mapping()` method, calls to `io.mapRequired()` mean that that key is
 required to exist when parsing YAML documents; otherwise, YAML I/O will issue an
 error.
 
-On the other hand, keys registered with ``io.mapOptional()`` are allowed to not
-exist in the YAML document being read.  So what value is put in the field
+On the other hand, keys registered with `io.mapOptional()` are allowed to not
+exist in the YAML document being read. So what value is put in the field
 for those optional keys?
 There are two steps to how those optional fields are filled in. First, the
-second parameter to the ``mapping()`` method is a reference to a native class.  That
-native class must have a default constructor.  Whatever value the default
+second parameter to the `mapping()` method is a reference to a native class. That
+native class must have a default constructor. Whatever value the default
 constructor initially sets for an optional field will be that field's value.
-Second, the ``mapOptional()`` method has an optional third parameter.  If provided
-it is the value that ``mapOptional()`` should set that field to if the YAML document
+Second, the `mapOptional()` method has an optional third parameter. If provided
+it is the value that `mapOptional()` should set that field to if the YAML document
 does not have that key.
 
 There is one important difference between those two ways (default constructor
-and third parameter to ``mapOptional()``). When YAML I/O generates a YAML document,
-if the ``mapOptional()`` third parameter is used, if the actual value being written
-is the same as (using ``==``) the default value, then that key/value is not written.
-
+and third parameter to `mapOptional()`). When YAML I/O generates a YAML document,
+if the `mapOptional()` third parameter is used, if the actual value being written
+is the same as (using `==`) the default value, then that key/value is not written.
 
-Order of Keys
---------------
+### Order of Keys
 
 When writing out a YAML document, the keys are written in the order that the
-calls to ``mapRequired()``/``mapOptional()`` are made in the ``mapping()`` method. This
+calls to `mapRequired()`/`mapOptional()` are made in the `mapping()` method. This
 gives you a chance to write the fields in an order that a human reader of
-the YAML document would find natural.  This may be different that the order
+the YAML document would find natural. This may be different that the order
 of the fields in the native class.
 
 When reading in a YAML document, the keys in the document can be in any order,
-but they are processed in the order that the calls to ``mapRequired()``/``mapOptional()``
-are made in the ``mapping()`` method.  That enables some interesting
-functionality.  For instance, if the first field bound is the cpu and the second
+but they are processed in the order that the calls to `mapRequired()`/`mapOptional()`
+are made in the `mapping()` method. That enables some interesting
+functionality. For instance, if the first field bound is the cpu and the second
 field bound is flags, and the flags are cpu specific, you can programmatically
 switch how the flags are converted to and from YAML based on the cpu.
 This works for both reading and writing. For example:
 
-.. code-block:: c++
-
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
-
-    struct Info {
-      CPUs        cpu;
-      uint32_t    flags;
-    };
-
-    template <>
-    struct MappingTraits<Info> {
-      static void mapping(IO &io, Info &info) {
-        io.mapRequired("cpu",       info.cpu);
-        // flags must come after cpu for this to work when reading yaml
-        if ( info.cpu == cpu_x86_64 )
-          io.mapRequired("flags",  *(My86_64Flags*)info.flags);
-        else
-          io.mapRequired("flags",  *(My86Flags*)info.flags);
-     }
-    };
-
-
-Tags
-----
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
+
+struct Info {
+  CPUs        cpu;
+  uint32_t    flags;
+};
+
+template <>
+struct MappingTraits<Info> {
+  static void mapping(IO &io, Info &info) {
+    io.mapRequired("cpu",       info.cpu);
+    // flags must come after cpu for this to work when reading yaml
+    if ( info.cpu == cpu_x86_64 )
+      io.mapRequired("flags",  *(My86_64Flags*)info.flags);
+    else
+      io.mapRequired("flags",  *(My86Flags*)info.flags);
+ }
+};
+```
+
+### Tags
 
 The YAML syntax supports tags as a way to specify the type of a node before
-it is parsed. This allows dynamic types of nodes.  But the YAML I/O model uses
+it is parsed. This allows dynamic types of nodes. But the YAML I/O model uses
 static typing, so there are limits to how you can use tags with the YAML I/O
 model. Recently, we added support to YAML I/O for checking/setting the optional
 tag on a map. Using this functionality it is even possible to support different
 mappings, as long as they are convertible.
 
-To check a tag, inside your ``mapping()`` method you can use ``io.mapTag()`` to specify
-what the tag should be.  This will also add that tag when writing YAML.
+To check a tag, inside your `mapping()` method you can use `io.mapTag()` to specify
+what the tag should be. This will also add that tag when writing YAML.
 
-Validation
-----------
+### Validation
 
 Sometimes in a YAML map, each key/value pair is valid, but the combination is
-not.  This is similar to something having no syntax errors, but still having
-semantic errors.  To support semantic-level checking, YAML I/O allows
-an optional ``validate()`` method in a MappingTraits template specialization.
+not. This is similar to something having no syntax errors, but still having
+semantic errors. To support semantic-level checking, YAML I/O allows
+an optional `validate()` method in a MappingTraits template specialization.
 
-When parsing YAML, the ``validate()`` method is called *after* all key/values in
-the map have been processed. Any error message returned by the ``validate()``
+When parsing YAML, the `validate()` method is called *after* all key/values in
+the map have been processed. Any error message returned by the `validate()`
 method during input will be printed just like a syntax error would be printed.
-When writing YAML, the ``validate()`` method is called *before* the YAML
-key/values  are written.  Any error during output will trigger an ``assert()``
+When writing YAML, the `validate()` method is called *before* the YAML
+key/values are written. Any error during output will trigger an `assert()`
 because it is a programming error to have invalid struct values.
 
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
+
+struct Stuff {
+  ...
+};
+
+template <>
+struct MappingTraits<Stuff> {
+  static void mapping(IO &io, Stuff &stuff) {
+  ...
+  }
+  static std::string validate(IO &io, Stuff &stuff) {
+    // Look at all fields in 'stuff' and if there
+    // are any bad values return a string describing
+    // the error.  Otherwise return an empty string.
+    return std::string{};
+  }
+};
+```
+
+### Flow Mapping
 
-.. code-block:: c++
-
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
-
-    struct Stuff {
-      ...
-    };
-
-    template <>
-    struct MappingTraits<Stuff> {
-      static void mapping(IO &io, Stuff &stuff) {
-      ...
-      }
-      static std::string validate(IO &io, Stuff &stuff) {
-        // Look at all fields in 'stuff' and if there
-        // are any bad values return a string describing
-        // the error.  Otherwise return an empty string.
-        return std::string{};
-      }
-    };
-
-Flow Mapping
-------------
 A YAML "flow mapping" is a mapping that uses the inline notation
 (e.g { x: 1, y: 0 } ) when written to YAML. To specify that a type should be
 written in YAML using flow mapping, your MappingTraits specialization should
-add ``static constexpr bool flow = true;``. For instance:
-
-.. code-block:: c++
+add `static constexpr bool flow = true;`. For instance:
 
-    using llvm::yaml::MappingTraits;
-    using llvm::yaml::IO;
+```c++
+using llvm::yaml::MappingTraits;
+using llvm::yaml::IO;
 
-    struct Stuff {
-      ...
-    };
+struct Stuff {
+  ...
+};
 
-    template <>
-    struct MappingTraits<Stuff> {
-      static void mapping(IO &io, Stuff &stuff) {
-        ...
-      }
+template <>
+struct MappingTraits<Stuff> {
+  static void mapping(IO &io, Stuff &stuff) {
+    ...
+  }
 
-      static constexpr bool flow = true;
-    }
+  static constexpr bool flow = true;
+}
+```
 
-Flow mappings are subject to line wrapping according to the ``Output`` object
+Flow mappings are subject to line wrapping according to the `Output` object
 configuration.
 
-Sequence
-========
-
-To be translated to or from a YAML sequence for your type ``T``, you must specialize
-``llvm::yaml::SequenceTraits`` on ``T`` and implement two methods:
-``size_t size(IO &io, T&)`` and
-``T::value_type& element(IO &io, T&, size_t indx)``.  For example:
-
-.. code-block:: c++
-
-  template <>
-  struct SequenceTraits<MySeq> {
-    static size_t size(IO &io, MySeq &list) { ... }
-    static MySeqEl &element(IO &io, MySeq &list, size_t index) { ... }
-  };
-
-The ``size()`` method returns how many elements are currently in your sequence.
-The ``element()`` method returns a reference to the i'th element in the sequence.
-When parsing YAML, the ``element()`` method may be called with an index one bigger
-than the current size.  Your ``element()`` method should allocate space for one
+## Sequence
+
+To be translated to or from a YAML sequence for your type `T`, you must specialize
+`llvm::yaml::SequenceTraits` on `T` and implement two methods:
+`size_t size(IO &io, T&)` and
+`T::value_type& element(IO &io, T&, size_t indx)`. For example:
+
+```c++
+template <>
+struct SequenceTraits<MySeq> {
+  static size_t size(IO &io, MySeq &list) { ... }
+  static MySeqEl &element(IO &io, MySeq &list, size_t index) { ... }
+};
+```
+
+The `size()` method returns how many elements are currently in your sequence.
+The `element()` method returns a reference to the i'th element in the sequence.
+When parsing YAML, the `element()` method may be called with an index one bigger
+than the current size. Your `element()` method should allocate space for one
 more element (using default constructor if element is a C++ object) and return
 a reference to that new allocated space.
 
+### Flow Sequence
 
-Flow Sequence
--------------
 A YAML "flow sequence" is a sequence that when written to YAML it uses the
-inline notation (e.g., ``[ foo, bar ]`` ).  To specify that a sequence type should
+inline notation (e.g., `[ foo, bar ]` ). To specify that a sequence type should
 be written in YAML as a flow sequence, your SequenceTraits specialization should
-add ``static constexpr bool flow = true;``.  For instance:
-
-.. code-block:: c++
+add `static constexpr bool flow = true;`. For instance:
 
-  template <>
-  struct SequenceTraits<MyList> {
-    static size_t size(IO &io, MyList &list) { ... }
-    static MyListEl &element(IO &io, MyList &list, size_t index) { ... }
+```c++
+template <>
+struct SequenceTraits<MyList> {
+  static size_t size(IO &io, MyList &list) { ... }
+  static MyListEl &element(IO &io, MyList &list, size_t index) { ... }
 
-    // The existence of this member causes YAML I/O to use a flow sequence
-    static constexpr bool flow = true;
-  };
+  // The existence of this member causes YAML I/O to use a flow sequence
+  static constexpr bool flow = true;
+};
+```
 
-With the above, if you used ``MyList`` as the data type in your native data
+With the above, if you used `MyList` as the data type in your native data
 structures, then when converted to YAML, a flow sequence of integers
-will be used (e.g., ``[ 10, -3, 4 ]``).
+will be used (e.g., `[ 10, -3, 4 ]`).
 
 Flow sequences are subject to line wrapping according to the Output object
 configuration.
 
-Utility Macros
---------------
-Since a common source of sequences is ``std::vector<>``, YAML I/O provides macros:
-``LLVM_YAML_IS_SEQUENCE_VECTOR()`` and ``LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR()`` which
-can be used to easily specify ``SequenceTraits<>`` on a ``std::vector`` type.  YAML
-I/O does not partial specialize ``SequenceTraits`` on ``std::vector<>`` because that
-would force all vectors to be sequences.  An example use of the macros:
-
-.. code-block:: c++
-
-  std::vector<MyType1>;
-  std::vector<MyType2>;
-  LLVM_YAML_IS_SEQUENCE_VECTOR(MyType1)
-  LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyType2)
+### Utility Macros
 
+Since a common source of sequences is `std::vector<>`, YAML I/O provides macros:
+`LLVM_YAML_IS_SEQUENCE_VECTOR()` and `LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR()` which
+can be used to easily specify `SequenceTraits<>` on a `std::vector` type. YAML
+I/O does not partial specialize `SequenceTraits` on `std::vector<>` because that
+would force all vectors to be sequences. An example use of the macros:
 
+```c++
+std::vector<MyType1>;
+std::vector<MyType2>;
+LLVM_YAML_IS_SEQUENCE_VECTOR(MyType1)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyType2)
+```
 
-Document List
-=============
+## Document List
 
-YAML allows you to define multiple "documents" in a single YAML file.  Each
-new document starts with a left aligned ``---`` token.  The end of all documents
-is denoted with a left aligned ``...`` token.  Many users of YAML will never
-have need for multiple documents.  The top level node in their YAML schema
+YAML allows you to define multiple "documents" in a single YAML file. Each
+new document starts with a left aligned `---` token. The end of all documents
+is denoted with a left aligned `...` token. Many users of YAML will never
+have need for multiple documents. The top level node in their YAML schema
 will be a mapping or sequence. For those cases, the following is not needed.
 But for cases where you do want multiple documents, you can specify a
-trait for you document list type.  The trait has the same methods as
-``SequenceTraits`` but is named ``DocumentListTraits``.  For example:
+trait for you document list type. The trait has the same methods as
+`SequenceTraits` but is named `DocumentListTraits`. For example:
 
-.. code-block:: c++
-
-  template <>
-  struct DocumentListTraits<MyDocList> {
-    static size_t size(IO &io, MyDocList &list) { ... }
-    static MyDocType element(IO &io, MyDocList &list, size_t index) { ... }
-  };
+```c++
+template <>
+struct DocumentListTraits<MyDocList> {
+  static size_t size(IO &io, MyDocList &list) { ... }
+  static MyDocType element(IO &io, MyDocList &list, size_t index) { ... }
+};
+```
 
+## User Context Data
 
-User Context Data
-=================
-When an ``llvm::yaml::Input`` or ``llvm::yaml::Output`` object is created, its
-constructor takes an optional "context" parameter.  This is a pointer to
+When an `llvm::yaml::Input` or `llvm::yaml::Output` object is created, its
+constructor takes an optional "context" parameter. This is a pointer to
 whatever state information you might need.
 
 For instance, in a previous example we showed how the conversion type for a
 flags field could be determined at runtime based on the value of another field
 in the mapping. But what if an inner mapping needs to know some field value
-of an outer mapping?  That is where the "context" parameter comes in. You
-can set values in the context in the outer map's ``mapping()`` method and
-retrieve those values in the inner map's ``mapping()`` method.
+of an outer mapping? That is where the "context" parameter comes in. You
+can set values in the context in the outer map's `mapping()` method and
+retrieve those values in the inner map's `mapping()` method.
 
-The context value is just a ``void*``.  All your traits which use the context
+The context value is just a `void*`. All your traits which use the context
 and operate on your native data types, need to agree what the context value
-actually is.  It could be a pointer to an object or struct which your various
+actually is. It could be a pointer to an object or struct which your various
 traits use to share context sensitive information.
 
+## Output
 
-Output
-======
-
-The ``llvm::yaml::Output`` class is used to generate a YAML document from your
+The `llvm::yaml::Output` class is used to generate a YAML document from your
 in-memory data structures, using traits defined on your data types.
-To instantiate an ``Output`` object you need an ``llvm::raw_ostream``, an optional
+To instantiate an `Output` object you need an `llvm::raw_ostream`, an optional
 context pointer and an optional wrapping column:
 
-.. code-block:: c++
+```c++
+class Output : public IO {
+public:
+  Output(llvm::raw_ostream &, void *context = NULL, int WrapColumn = 70);
+```
 
-      class Output : public IO {
-      public:
-        Output(llvm::raw_ostream &, void *context = NULL, int WrapColumn = 70);
-
-Once you have an ``Output`` object, you can use the C++ stream operator on it
+Once you have an `Output` object, you can use the C++ stream operator on it
 to write your native data as YAML. One thing to recall is that a YAML file
-can contain multiple "documents".  If the top level data structure you are
-streaming as YAML is a mapping, scalar, or sequence, then ``Output`` assumes you
+can contain multiple "documents". If the top level data structure you are
+streaming as YAML is a mapping, scalar, or sequence, then `Output` assumes you
 are generating one document and wraps the mapping output
-with ``---`` and trailing ``...``.
+with `---` and trailing `...`.
 
-The ``WrapColumn`` parameter will cause the flow mappings and sequences to
+The `WrapColumn` parameter will cause the flow mappings and sequences to
 line-wrap when they go over the supplied column. Pass 0 to completely
 suppress the wrapping.
 
-.. code-block:: c++
-
-    using llvm::yaml::Output;
+```c++
+using llvm::yaml::Output;
 
-    void dumpMyMapDoc(const MyMapType &info) {
-      Output yout(llvm::outs());
-      yout << info;
-    }
+void dumpMyMapDoc(const MyMapType &info) {
+  Output yout(llvm::outs());
+  yout << info;
+}
+```
 
 The above could produce output like:
 
-.. code-block:: yaml
-
-     ---
-     name:      Tom
-     hat-size:  7
-     ...
+```yaml
+---
+name:      Tom
+hat-size:  7
+...
+```
 
 On the other hand, if the top level data structure you are streaming as YAML
-has a ``DocumentListTraits`` specialization, then Output walks through each element
-of your DocumentList and generates a ``---`` before the start of each element
-and ends with a ``...``.
+has a `DocumentListTraits` specialization, then Output walks through each element
+of your DocumentList and generates a `---` before the start of each element
+and ends with a `...`.
 
-.. code-block:: c++
+```c++
+using llvm::yaml::Output;
 
-    using llvm::yaml::Output;
-
-    void dumpMyMapDoc(const MyDocListType &docList) {
-      Output yout(llvm::outs());
-      yout << docList;
-    }
+void dumpMyMapDoc(const MyDocListType &docList) {
+  Output yout(llvm::outs());
+  yout << docList;
+}
+```
 
 The above could produce output like:
 
-.. code-block:: yaml
-
-     ---
-     name:      Tom
-     hat-size:  7
-     ---
-     name:      Tom
-     shoe-size:  11
-     ...
-
-Input
-=====
-
-The ``llvm::yaml::Input`` class is used to parse YAML document(s) into your native
-data structures. To instantiate an ``Input``
-object you need a ``StringRef`` to the entire YAML file, and optionally a context
+```yaml
+---
+name:      Tom
+hat-size:  7
+---
+name:      Tom
+shoe-size:  11
+...
+```
+
+## Input
+
+The `llvm::yaml::Input` class is used to parse YAML document(s) into your native
+data structures. To instantiate an `Input`
+object you need a `StringRef` to the entire YAML file, and optionally a context
 pointer:
 
-.. code-block:: c++
-
-      class Input : public IO {
-      public:
-        Input(StringRef inputContent, void *context=NULL);
-
-Once you have an ``Input`` object, you can use the C++ stream operator to read
-the document(s).  If you expect there might be multiple YAML documents in
-one file, you'll need to specialize ``DocumentListTraits`` on a list of your
-document type and stream in that document list type.  Otherwise, you can
-just stream in the document type.  Also, you can check if there was
-any syntax errors in the YAML by calling the ``error()`` method on the ``Input``
-object.  For example:
-
-.. code-block:: c++
+```c++
+class Input : public IO {
+public:
+  Input(StringRef inputContent, void *context=NULL);
+```
 
-     // Reading a single document
-     using llvm::yaml::Input;
+Once you have an `Input` object, you can use the C++ stream operator to read
+the document(s). If you expect there might be multiple YAML documents in
+one file, you'll need to specialize `DocumentListTraits` on a list of your
+document type and stream in that document list type. Otherwise, you can
+just stream in the document type. Also, you can check if there was
+any syntax errors in the YAML by calling the `error()` method on the `Input`
+object. For example:
 
-     Input yin(mb.getBuffer());
+```c++
+// Reading a single document
+using llvm::yaml::Input;
 
-     // Parse the YAML file
-     MyDocType theDoc;
-     yin >> theDoc;
+Input yin(mb.getBuffer());
 
-     // Check for error
-     if ( yin.error() )
-       return;
+// Parse the YAML file
+MyDocType theDoc;
+yin >> theDoc;
 
+// Check for error
+if ( yin.error() )
+  return;
+```
 
-.. code-block:: c++
+```c++
+// Reading multiple documents in one file
+using llvm::yaml::Input;
 
-     // Reading multiple documents in one file
-     using llvm::yaml::Input;
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDocType)
 
-     LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDocType)
+Input yin(mb.getBuffer());
 
-     Input yin(mb.getBuffer());
+// Parse the YAML file
+std::vector<MyDocType> theDocList;
+yin >> theDocList;
 
-     // Parse the YAML file
-     std::vector<MyDocType> theDocList;
-     yin >> theDocList;
+// Check for error
+if ( yin.error() )
+  return;
+```
 
-     // Check for error
-     if ( yin.error() )
-       return;

>From 8986fca36402189f212d34264b62a9c267abe996 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 11 Sep 2026 17:31:10 +0000
Subject: [PATCH 3/4] [LLVM][docs] Finish MyST migration for remaining docs
 (batch 11)

---
 llvm/docs/MarkedUpDisassembly.md              |   3 +-
 llvm/docs/MeetupGuidelines.md                 |   3 +-
 llvm/docs/MemoryModelRelaxationAnnotations.md |  15 +-
 llvm/docs/PCSectionsMetadata.md               |  26 +--
 llvm/docs/Projects.md                         | 185 +++++++++---------
 llvm/docs/Proposals/GitHubMove.md             |  92 ++++-----
 llvm/docs/Proposals/TestSuite.md              | 171 ++++++++--------
 llvm/docs/Proposals/VectorPredication.md      |  14 +-
 llvm/docs/QualGroup.md                        |  13 +-
 llvm/docs/ScudoHardenedAllocator.md           |   3 +-
 llvm/docs/Security.md                         |   9 +-
 llvm/docs/SecurityTransparencyReports.md      |  96 ++++-----
 llvm/docs/SegmentedStacks.md                  |   5 +-
 llvm/docs/StackMaps.md                        |  25 +--
 llvm/docs/Statepoints.md                      |  13 +-
 llvm/docs/SupportPolicy.md                    |  11 +-
 llvm/docs/TableGen/BackEnds.md                |   5 +-
 llvm/docs/TableGen/BackGuide.md               |  27 ++-
 llvm/docs/TableGen/ProgRef.md                 | 124 ++++++------
 llvm/docs/TransformMetadata.md                |  35 ++--
 llvm/docs/TypeMetadata.md                     |  41 ++--
 llvm/docs/VectorizationPlan.md                | 104 +++++-----
 llvm/docs/XRay.md                             |  27 +--
 llvm/docs/XRayExample.md                      |  11 +-
 llvm/docs/XRayFDRFormat.md                    |   9 +-
 25 files changed, 533 insertions(+), 534 deletions(-)

diff --git a/llvm/docs/MarkedUpDisassembly.md b/llvm/docs/MarkedUpDisassembly.md
index b3fc4da1c5527..ca19c1ad7cb7e 100644
--- a/llvm/docs/MarkedUpDisassembly.md
+++ b/llvm/docs/MarkedUpDisassembly.md
@@ -29,7 +29,7 @@ with the marked up annotations.
 
 ## Instruction Annotations
 
-(contextual-markups)=
+(contextual markups)=
 
 ### Contextual markups
 
@@ -74,4 +74,3 @@ The intended consumers of this information use the C API, therefore the new C
 API function for the disassembler will be added to provide an option to produce
 disassembled instructions with annotations, `LLVMSetDisasmOptions()` and the
 `LLVMDisassembler_Option_UseMarkup` option (see above).
-
diff --git a/llvm/docs/MeetupGuidelines.md b/llvm/docs/MeetupGuidelines.md
index 33fa2b4cd4668..e882c352e02ae 100644
--- a/llvm/docs/MeetupGuidelines.md
+++ b/llvm/docs/MeetupGuidelines.md
@@ -15,7 +15,7 @@ best for your specific situation.
 - We highly recommend that you join the official LLVM meetup organization. In
   addition to covering the cost of the meetup, all LLVM meetups are advertised
   together and easily found by potential attendees. Please contact
-  <mailto:tanyalattner at llvm.org> for more details.
+  [tanyalattner at llvm.org](mailto:tanyalattner at llvm.org) for more details.
 - Beware of cultural differences: what works well in one region may not work in
   other part of the world.
 - Do not be alone to organize the meetup. Try to work with a couple other
@@ -72,4 +72,3 @@ best for your specific situation.
   but the people who live in the city may not attend.
 - Make a poll, but beware that not every responder will join (we had ~20 votes
   on the poll, while only ~8 people attended).
-
diff --git a/llvm/docs/MemoryModelRelaxationAnnotations.md b/llvm/docs/MemoryModelRelaxationAnnotations.md
index 81fe32c85083f..fda7fcc0768be 100644
--- a/llvm/docs/MemoryModelRelaxationAnnotations.md
+++ b/llvm/docs/MemoryModelRelaxationAnnotations.md
@@ -47,13 +47,13 @@ tag
   `prefix:suffix` notation.
   For example:
 
-  ```{code-block}
+  :::{code-block}
   :caption: 'Example: Tags in Metadata'
 
   !0 = !{!"scope", !"workgroup"}  # scope:workgroup
   !1 = !{!"scope", !"device"}     # scope:device
   !2 = !{!"scope", !"system"}     # scope:system
-  ```
+  :::
 
   :::{note}
   The only semantics relevant to the optimizer is the
@@ -65,13 +65,13 @@ tag
   to specify all of the tags they belong to. Such a list
   is referred to as a "set of tags".
 
-  ```{code-block}
+  :::{code-block}
   :caption: 'Example: Set of Tags in Metadata'
 
   !0 = !{!"scope", !"workgroup"}
   !1 = !{!"sync-as", !"private"}
   !2 = !{!0, !2}
-  ```
+  :::
 
   :::{note}
   If an operation does not have MMRA metadata, it's treated as if
@@ -88,12 +88,12 @@ tag
   For the sake of readability in examples below,
   we use a (non-functional) short syntax to represent MMMRA metadata:
 
-  ```{code-block}
+  :::{code-block}
   :caption: Short Syntax Example
 
   store %ptr1 # foo:bar
   store %ptr1 !mmra !{!"foo", !"bar"}
-  ```
+  :::
 
   These two notations can be used in this document and are strictly
   equivalent. However, only the second version is functional.
@@ -112,7 +112,7 @@ compatibility
   correctness. In other words, the memory model cannot be relaxed further
   by deleting metadata from instructions.
 
-(happensbefore)=
+(HappensBefore)=
 
 ## The *happens-before* Relation
 
@@ -477,4 +477,3 @@ B: store release %ptr2  # foo:x, bar:y
 # No tags with "foo" or "bar" in A, so no tags added.
 U: store release %ptr3
 ```
-
diff --git a/llvm/docs/PCSectionsMetadata.md b/llvm/docs/PCSectionsMetadata.md
index 22b29f43af29a..d09c70a7c0e32 100644
--- a/llvm/docs/PCSectionsMetadata.md
+++ b/llvm/docs/PCSectionsMetadata.md
@@ -56,8 +56,8 @@ the entry size is just 32 bits.
 Optional encoding options can be passed in the first `MDString` operator:
 `<section>!<options>`. The following options are available:
 
-> - `C` -- Compress constant integers of size 2-8 bytes as ULEB128; this
->   includes the function size (but excludes the PC entry).
+- `C` -- Compress constant integers of size 2-8 bytes as ULEB128; this
+  includes the function size (but excludes the PC entry).
 
 For example, `foo!C` will emit into section `foo` with all constants
 encoded as ULEB128.
@@ -84,21 +84,24 @@ As with other LLVM IR metadata, there are no requirements for LLVM IR
 transformation passes to preserve `!pcsections` metadata, with the following
 exceptions:
 
-> - The `AtomicExpandPass` shall preserve `!pcsections` metadata
->   according to the below rules 1-4.
+- The `AtomicExpandPass` shall preserve `!pcsections` metadata
+  according to the below rules 1-4.
 
 When translating LLVM IR to MIR, the `!pcsections` metadata shall be copied
 from the source `Instruction` to the target `MachineInstr` (set with
 `MachineInstr::setPCSections()`). The instruction selectors and MIR
 optimization passes shall preserve PC sections metadata as follows:
 
-> 1. Replacements will preserve PC sections metadata of the replaced
->    instruction.
-> 2. Duplications will preserve PC sections metadata of the copied
->    instruction.
-> 3. Merging will preserve PC sections metadata of one of the two
->    instructions (no guarantee on which instruction's metadata is used).
-> 4. Deletions will lose PC sections metadata.
+1. Replacements will preserve PC sections metadata of the replaced
+   instruction.
+
+2. Duplications will preserve PC sections metadata of the copied
+   instruction.
+
+3. Merging will preserve PC sections metadata of one of the two
+   instructions (no guarantee on which instruction's metadata is used).
+
+4. Deletions will lose PC sections metadata.
 
 This is similar to debug info, and the `BuildMI()` helper provides a
 convenient way to propagate debug info and `!pcsections` metadata in the
@@ -110,4 +113,3 @@ Use cases for `!pcsections` metadata should either be fully tolerant to
 missing metadata, or the passes inserting `!pcsections` metadata should run
 *after* all LLVM IR optimization passes to preserve the metadata until being
 translated to MIR.
-
diff --git a/llvm/docs/Projects.md b/llvm/docs/Projects.md
index 0896364892227..a9e9c631a3430 100644
--- a/llvm/docs/Projects.md
+++ b/llvm/docs/Projects.md
@@ -44,38 +44,38 @@ Underneath your top level directory, you should have the following directories:
 
 **lib**
 
-> This subdirectory should contain all of your library source code. For each
-> library that you build, you will have one directory in **lib** that will
-> contain that library's source code.
->
-> Libraries can be object files, archives, or dynamic libraries. The **lib**
-> directory is just a convenient place for libraries as it places them all in
-> a directory from which they can be linked later.
+: This subdirectory should contain all of your library source code. For each
+  library that you build, you will have one directory in **lib** that will
+  contain that library's source code.
+
+  Libraries can be object files, archives, or dynamic libraries. The **lib**
+  directory is just a convenient place for libraries as it places them all in
+  a directory from which they can be linked later.
 
 **include**
 
-> This subdirectory should contain any header files that are global to your
-> project. By global, we mean that they are used by more than one library or
-> executable of your project.
->
-> By placing your header files in **include**, they will be found
-> automatically by the LLVM build system. For example, if you have a file
-> **include/jazz/note.h**, then your source files can include it simply with
-> **#include "jazz/note.h"**.
+: This subdirectory should contain any header files that are global to your
+  project. By global, we mean that they are used by more than one library or
+  executable of your project.
+
+  By placing your header files in **include**, they will be found
+  automatically by the LLVM build system. For example, if you have a file
+  **include/jazz/note.h**, then your source files can include it simply with
+  **#include "jazz/note.h"**.
 
 **tools**
 
-> This subdirectory should contain all of your source code for executables.
-> For each program that you build, you will have one directory in **tools**
-> that will contain that program's source code.
+: This subdirectory should contain all of your source code for executables.
+  For each program that you build, you will have one directory in **tools**
+  that will contain that program's source code.
 
 **test**
 
-> This subdirectory should contain tests that verify that your code works
-> correctly. Automated tests are especially useful.
->
-> Currently, the LLVM build system provides basic support for tests. The LLVM
-> system provides the following:
+: This subdirectory should contain tests that verify that your code works
+  correctly. Automated tests are especially useful.
+
+  Currently, the LLVM build system provides basic support for tests. The LLVM
+  system provides the following:
 
 - LLVM contains regression tests in `llvm/test`. These tests are run by the
   {doc}`Lit <CommandGuide/lit>` testing tool. This test procedure uses `RUN`
@@ -105,101 +105,101 @@ do:
 
 `LEVEL`
 
-> This variable is the relative path from this `Makefile` to the top
-> directory of your project's source code. For example, if your source code
-> is in `/tmp/src`, then the `Makefile` in `/tmp/src/jump/high`
-> would set `LEVEL` to `"../.."`.
+: This variable is the relative path from this `Makefile` to the top
+  directory of your project's source code. For example, if your source code
+  is in `/tmp/src`, then the `Makefile` in `/tmp/src/jump/high`
+  would set `LEVEL` to `"../.."`.
 
 ### Variables for Building Subdirectories
 
 `DIRS`
 
-> This is a space separated list of subdirectories that should be built. They
-> will be built, one at a time, in the order specified.
+: This is a space separated list of subdirectories that should be built. They
+  will be built, one at a time, in the order specified.
 
 `PARALLEL_DIRS`
 
-> This is a list of directories that can be built in parallel. These will be
-> built after the directories in DIRS have been built.
+: This is a list of directories that can be built in parallel. These will be
+  built after the directories in DIRS have been built.
 
 `OPTIONAL_DIRS`
 
-> This is a list of directories that can be built if they exist, but will not
-> cause an error if they do not exist. They are built serially in the order
-> in which they are listed.
+: This is a list of directories that can be built if they exist, but will not
+  cause an error if they do not exist. They are built serially in the order
+  in which they are listed.
 
 ### Variables for Building Libraries
 
 `LIBRARYNAME`
 
-> This variable contains the base name of the library that will be built. For
-> example, to build a library named `libsample.a`, `LIBRARYNAME` should
-> be set to `sample`.
+: This variable contains the base name of the library that will be built. For
+  example, to build a library named `libsample.a`, `LIBRARYNAME` should
+  be set to `sample`.
 
 `BUILD_ARCHIVE`
 
-> By default, a library is a `.o` file that is linked directly into a
-> program. To build an archive (also known as a static library), set the
-> `BUILD_ARCHIVE` variable.
+: By default, a library is a `.o` file that is linked directly into a
+  program. To build an archive (also known as a static library), set the
+  `BUILD_ARCHIVE` variable.
 
 `SHARED_LIBRARY`
 
-> If `SHARED_LIBRARY` is defined in your Makefile, a shared (or dynamic)
-> library will be built.
+: If `SHARED_LIBRARY` is defined in your Makefile, a shared (or dynamic)
+  library will be built.
 
 ### Variables for Building Programs
 
 `TOOLNAME`
 
-> This variable contains the name of the program that will be built. For
-> example, to build an executable named `sample`, `TOOLNAME` should be set
-> to `sample`.
+: This variable contains the name of the program that will be built. For
+  example, to build an executable named `sample`, `TOOLNAME` should be set
+  to `sample`.
 
 `USEDLIBS`
 
-> This variable holds a space separated list of libraries that should be
-> linked into the program. These libraries must be libraries that come from
-> your **lib** directory. The libraries must be specified without their
-> `lib` prefix. For example, to link `libsample.a`, you would set
-> `USEDLIBS` to `sample.a`.
->
-> Note that this works only for statically linked libraries.
+: This variable holds a space separated list of libraries that should be
+  linked into the program. These libraries must be libraries that come from
+  your **lib** directory. The libraries must be specified without their
+  `lib` prefix. For example, to link `libsample.a`, you would set
+  `USEDLIBS` to `sample.a`.
+
+  Note that this works only for statically linked libraries.
 
 `LLVMLIBS`
 
-> This variable holds a space separated list of libraries that should be
-> linked into the program. These libraries must be LLVM libraries. The
-> libraries must be specified without their `lib` prefix. For example, to
-> link with a driver that performs an IR transformation you might set
-> `LLVMLIBS` to this minimal set of libraries `LLVMSupport.a LLVMCore.a
-> LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a
-> LLVMScalarOpts.a LLVMTarget.a`.
->
-> Note that this works only for statically linked libraries. LLVM is split
-> into a large number of static libraries, and the list of libraries you
-> require may be much longer than the list above. To see a full list of
-> libraries use: `llvm-config --libs all`. Using `LINK_COMPONENTS` as
-> described below, obviates the need to set `LLVMLIBS`.
+: This variable holds a space separated list of libraries that should be
+  linked into the program. These libraries must be LLVM libraries. The
+  libraries must be specified without their `lib` prefix. For example, to
+  link with a driver that performs an IR transformation you might set
+  `LLVMLIBS` to this minimal set of libraries `LLVMSupport.a LLVMCore.a
+  LLVMBitReader.a LLVMAsmParser.a LLVMAnalysis.a LLVMTransformUtils.a
+  LLVMScalarOpts.a LLVMTarget.a`.
+
+  Note that this works only for statically linked libraries. LLVM is split
+  into a large number of static libraries, and the list of libraries you
+  require may be much longer than the list above. To see a full list of
+  libraries use: `llvm-config --libs all`. Using `LINK_COMPONENTS` as
+  described below, obviates the need to set `LLVMLIBS`.
 
 `LINK_COMPONENTS`
 
-> This variable holds a space separated list of components that the LLVM
-> `Makefiles` pass to the `llvm-config` tool to generate a link line for
-> the program. For example, to link with all LLVM libraries use
-> `LINK_COMPONENTS = all`.
+: This variable holds a space separated list of components that the LLVM
+  `Makefiles` pass to the `llvm-config` tool to generate a link line for
+  the program. For example, to link with all LLVM libraries use
+  `LINK_COMPONENTS = all`.
 
 `LIBS`
 
-> To link dynamic libraries, add `-l<library base name>` to the `LIBS`
-> variable. The LLVM build system will look in the same places for dynamic
-> libraries as it does for static libraries.
->
-> For example, to link `libsample.so`, you would have the following line in
-> your `Makefile`:
->
-> > ```makefile
-> > LIBS += -lsample
-> > ```
+: To link dynamic libraries, add `-l<library base name>` to the `LIBS`
+  variable. The LLVM build system will look in the same places for dynamic
+  libraries as it does for static libraries.
+
+  For example, to link `libsample.so`, you would have the following line in
+  your `Makefile`:
+
+  ```makefile
+  LIBS += -lsample
+  ```
 
 Note that `LIBS` must occur in the Makefile after the inclusion of
 `Makefile.common`.
@@ -208,13 +208,13 @@ Note that `LIBS` must occur in the Makefile after the inclusion of
 
 `CFLAGS` & `CPPFLAGS`
 
-> This variable can be used to add options to the C and C++ compiler,
-> respectively. It is typically used to add options that tell the compiler
-> the location of additional directories to search for header files.
->
-> It is highly suggested that you append to `CFLAGS` and `CPPFLAGS` as
-> opposed to overwriting them. The LLVM `Makefiles` may already have
-> useful options in them that you may not want to overwrite.
+: This variable can be used to add options to the C and C++ compiler,
+  respectively. It is typically used to add options that tell the compiler
+  the location of additional directories to search for header files.
+
+  It is highly suggested that you append to `CFLAGS` and `CPPFLAGS` as
+  opposed to overwriting them. The LLVM `Makefiles` may already have
+  useful options in them that you may not want to overwrite.
 
 ## Placement of Object Code
 
@@ -223,19 +223,18 @@ you do a `Debug`, `Release`, or `Profile` build.
 
 Libraries
 
-> All libraries (static and dynamic) will be stored in
-> `PROJ_OBJ_ROOT/<type>/lib`, where *type* is `Debug`, `Release`, or
-> `Profile` for a debug, optimized, or profiled build, respectively.
+: All libraries (static and dynamic) will be stored in
+  `PROJ_OBJ_ROOT/<type>/lib`, where *type* is `Debug`, `Release`, or
+  `Profile` for a debug, optimized, or profiled build, respectively.
 
 Executables
 
-> All executables will be stored in `PROJ_OBJ_ROOT/<type>/bin`, where *type*
-> is `Debug`, `Release`, or `Profile` for a debug, optimized, or
-> profiled build, respectively.
+: All executables will be stored in `PROJ_OBJ_ROOT/<type>/bin`, where *type*
+  is `Debug`, `Release`, or `Profile` for a debug, optimized, or
+  profiled build, respectively.
 
 ## Further Help
 
 If you have any questions or need any help creating an LLVM project, the LLVM
 team would be more than happy to help. You can always post your questions to
 the [Discourse forums](https://discourse.llvm.org).
-
diff --git a/llvm/docs/Proposals/GitHubMove.md b/llvm/docs/Proposals/GitHubMove.md
index 100e38c24b8fb..dc49131b1ee05 100644
--- a/llvm/docs/Proposals/GitHubMove.md
+++ b/llvm/docs/Proposals/GitHubMove.md
@@ -1,3 +1,8 @@
+---
+myst:
+  footnote_transition: false
+---
+
 # Moving LLVM Projects to GitHub
 
 ## Current Status
@@ -98,14 +103,14 @@ past discussions about Git:
 
 - "The 'branch' I most care about is mainline, and losing the ability to say
   'fixed in r1234' (with some sort of monotonically increasing number) would
-  be a tragic loss." [^cite_lattnerrevnum]
+  be a tragic loss." [^lattnerrevnum]
 - "I like those results sorted by time and the chronology should be obvious, but
   timestamps are incredibly cumbersome and make it difficult to verify that a
-  given checkout matches a given set of results." [^cite_trickrevnum]
+  given checkout matches a given set of results." [^trickrevnum]
 - "There is still the major regression with unreadable version numbers.
   Given the amount of Bugzilla traffic with 'Fixed in...', that's a
-  non-trivial issue." [^cite_jsonnrevnum]
-- "Sequential IDs are important for LNT and llvmlab bisection tool." [^cite_matthewsrevnum].
+  non-trivial issue." [^jsonnrevnum]
+- "Sequential IDs are important for LNT and llvmlab bisection tool." [^matthewsrevnum].
 
 However, Git can emulate this increasing revision number:
 `git rev-list --count <commit-hash>`. This identifier is unique only
@@ -128,7 +133,7 @@ policy. We must rely on the community to avoid pushing merge commits.
 GitHub offers a feature called `Status Checks`: a branch protected by
 `status checks` requires commits to be explicitly allowed before the push can happen.
 We could supply a pre-push hook on the client side that would run and check the
-history, before allowing the commit being pushed [^cite_statuschecks].
+history, before allowing the commit being pushed [^statuschecks].
 However this solution would be somewhat fragile (how do you update a script
 installed on every developer machine?) and prevents SVN access to the
 repository.
@@ -156,7 +161,7 @@ email format unchanged besides the commit URL.
    provide infrastructure testing.
 5. Update Phabricator to pick up commits from the GitHub repository.
 6. LNT and llvmlab have to be updated: they rely on unique monotonically
-   increasing integer across branch [^cite_matthewsrevnum].
+   increasing integer across branch [^matthewsrevnum].
 7. Instruct downstream integrators to pick up commits from the GitHub
    repository.
 8. Review and prepare an update for the LLVM documentation.
@@ -194,24 +199,24 @@ For example, www/ and test-suite/ are not part of the monorepo.
 Putting all sub-projects in a single checkout makes cross-project refactoring
 naturally simple:
 
-> - New sub-projects can be trivially split out for better reuse and/or layering
->   (e.g., to allow libSupport and/or LIT to be used by runtimes without adding a
->   dependency on LLVM).
-> - Changing an API in LLVM and upgrading the sub-projects will always be done in
->   a single commit, designing away a common source of temporary build breakage.
-> - Moving code across sub-project (during refactoring for instance) in a single
->   commit enables accurate `git blame` when tracking code change history.
-> - Tooling based on `git grep` works natively across sub-projects, allowing to
->   easier find refactoring opportunities across projects (for example reusing a
->   datastructure initially in LLDB by moving it into libSupport).
-> - Having all the sources present encourages maintaining the other sub-projects
->   when changing API.
+- New sub-projects can be trivially split out for better reuse and/or layering
+  (e.g., to allow libSupport and/or LIT to be used by runtimes without adding a
+  dependency on LLVM).
+- Changing an API in LLVM and upgrading the sub-projects will always be done in
+  a single commit, designing away a common source of temporary build breakage.
+- Moving code across sub-project (during refactoring for instance) in a single
+  commit enables accurate `git blame` when tracking code change history.
+- Tooling based on `git grep` works natively across sub-projects, allowing to
+  easier find refactoring opportunities across projects (for example reusing a
+  datastructure initially in LLDB by moving it into libSupport).
+- Having all the sources present encourages maintaining the other sub-projects
+  when changing API.
 
 Finally, the monorepo maintains the property of the existing SVN repository that
 the sub-projects move synchronously, and a single revision number (or commit
 hash) identifies the state of the development across all projects.
 
-(build-single-project)=
+(build_single_project)=
 
 #### Building a single sub-project
 
@@ -249,28 +254,28 @@ so it's not clear if this is something that will be supported going forward.
 
 ### Monorepo Drawbacks
 
-> - Using the monolithic repository may add overhead for those contributing to a
->   standalone sub-project, particularly on runtimes like libcxx and compiler-rt
->   that don't rely on LLVM; currently, a fresh clone of libcxx is only 15MB (vs.
->   1GB for the monorepo), and the commit rate of LLVM may cause more frequent
->   `git push` collisions when upstreaming. Affected contributors may be able to
->   use the SVN bridge or the single-subproject Git mirrors. However, it's
->   undecided if these projects will continue to be maintained.
-> - Using the monolithic repository may add overhead for those *integrating* a
->   standalone sub-project, even if they aren't contributing to it, due to the
->   same disk space concern as the point above. The availability of the
->   sub-project Git mirrors would addresses this.
-> - Preservation of the existing read/write SVN-based workflows relies on the
->   GitHub SVN bridge, which is an extra dependency. Maintaining this locks us
->   into GitHub and could restrict future workflow changes.
+- Using the monolithic repository may add overhead for those contributing to a
+  standalone sub-project, particularly on runtimes like libcxx and compiler-rt
+  that don't rely on LLVM; currently, a fresh clone of libcxx is only 15MB (vs.
+  1GB for the monorepo), and the commit rate of LLVM may cause more frequent
+  `git push` collisions when upstreaming. Affected contributors may be able to
+  use the SVN bridge or the single-subproject Git mirrors. However, it's
+  undecided if these projects will continue to be maintained.
+- Using the monolithic repository may add overhead for those *integrating* a
+  standalone sub-project, even if they aren't contributing to it, due to the
+  same disk space concern as the point above. The availability of the
+  sub-project Git mirrors would addresses this.
+- Preservation of the existing read/write SVN-based workflows relies on the
+  GitHub SVN bridge, which is an extra dependency. Maintaining this locks us
+  into GitHub and could restrict future workflow changes.
 
 #### Workflows
 
-> - {ref}`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`.
-> - {ref}`Checkout/Clone Multiple Projects, with Commit Access <workflow-monocheckout-multicommit>`.
-> - {ref}`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`.
-> - {ref}`Branching/Stashing/Updating for Local Development or Experiments <workflow-mono-branching>`.
-> - {ref}`Bisecting <workflow-mono-bisecting>`.
+- {ref}`Checkout/Clone a Single Project, without Commit Access <workflow-checkout-commit>`.
+- {ref}`Checkout/Clone Multiple Projects, with Commit Access <workflow-monocheckout-multicommit>`.
+- {ref}`Commit an API Change in LLVM and Update the Sub-projects <workflow-cross-repo-commit>`.
+- {ref}`Branching/Stashing/Updating for Local Development or Experiments <workflow-mono-branching>`.
+- {ref}`Bisecting <workflow-mono-bisecting>`.
 
 ## Workflow Before/After
 
@@ -1074,13 +1079,12 @@ happy hacking!
 
 ## References
 
-[^cite_lattnerrevnum]: Chris Lattner, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041739.html>
-
-[^cite_trickrevnum]: Andrew Trick, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041721.html>
+[^lattnerrevnum]: Chris Lattner, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041739.html>
 
-[^cite_jsonnrevnum]: Joerg Sonnenberger, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041688.html>
+[^trickrevnum]: Andrew Trick, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041721.html>
 
-[^cite_matthewsrevnum]: Chris Matthews, <http://lists.llvm.org/pipermail/cfe-dev/2016-July/049886.html>
+[^jsonnrevnum]: Joerg Sonnenberger, <http://lists.llvm.org/pipermail/llvm-dev/2011-July/041688.html>
 
-[^cite_statuschecks]: GitHub status-checks, <https://help.github.com/articles/about-required-status-checks/>
+[^matthewsrevnum]: Chris Matthews, <http://lists.llvm.org/pipermail/cfe-dev/2016-July/049886.html>
 
+[^statuschecks]: GitHub status-checks, <https://help.github.com/articles/about-required-status-checks/>
diff --git a/llvm/docs/Proposals/TestSuite.md b/llvm/docs/Proposals/TestSuite.md
index e606312049d54..eef4095703909 100644
--- a/llvm/docs/Proposals/TestSuite.md
+++ b/llvm/docs/Proposals/TestSuite.md
@@ -11,12 +11,14 @@ Most probably, the reason why the programs below have not been added to
 the test-suite yet is that nobody has found time to do it. But there
 might be other issues as well, such as
 
-> - Licensing (Support can still be added as external module,
->   : like for the SPEC benchmarks)
-> - Language (in particular, there is no official LLVM frontend
->   : for FORTRAN yet)
-> - Parallelism (currently, all programs in test-suite use
->   : one thread only)
+- Licensing (Support can still be added as external module,
+  like for the SPEC benchmarks)
+
+- Language (in particular, there is no official LLVM frontend
+  for FORTRAN yet)
+
+- Parallelism (currently, all programs in test-suite use
+  one thread only)
 
 ## Benchmarks
 
@@ -34,33 +36,33 @@ Note that CMake's Ninja generator has difficulties with Fortran. See the
 [CMake documentation](https://cmake.org/cmake/help/v3.13/generator/Ninja.html#fortran-support)
 for details.
 
-> - 503.bwaves_r/603.bwaves_s
-> - 507.cactuBSSN_r
-> - 521.wrf_r/621.wrf_s
-> - 527.cam4_r/627.cam4_s
-> - 628.pop2_s
-> - 548.exchange2_r/648.exchange2_s
-> - 549.fotonik3d_r/649.fotonik3d_s
-> - 554.roms_r/654.roms_s
+- 503.bwaves_r/603.bwaves_s
+- 507.cactuBSSN_r
+- 521.wrf_r/621.wrf_s
+- 527.cam4_r/627.cam4_s
+- 628.pop2_s
+- 548.exchange2_r/648.exchange2_s
+- 549.fotonik3d_r/649.fotonik3d_s
+- 554.roms_r/654.roms_s
 
 ### SPEC OMP2012
 
 <https://www.spec.org/omp2012/>
 
-> - 350.md
-> - 351.bwaves
-> - 352.nab
-> - 357.bt331
-> - 358.botsalgn
-> - 359.botsspar
-> - 360.ilbdc
-> - 362.fma3d
-> - 363.swim
-> - 367.imagick
-> - 370.mgrid331
-> - 371.applu331
-> - 372.smithwa
-> - 376.kdtree
+- 350.md
+- 351.bwaves
+- 352.nab
+- 357.bt331
+- 358.botsalgn
+- 359.botsspar
+- 360.ilbdc
+- 362.fma3d
+- 363.swim
+- 367.imagick
+- 370.mgrid331
+- 371.applu331
+- 372.smithwa
+- 376.kdtree
 
 ### OpenCV
 
@@ -109,21 +111,21 @@ and is itself a collection of benchmark suites
 Rodinia has already been partially included in
 MultiSource/Benchmarks/Rodinia. Benchmarks still missing are:
 
-> - streamcluster
-> - particlefilter
-> - nw
-> - nn
-> - myocyte
-> - mummergpu
-> - lud
-> - leukocyte
-> - lavaMD
-> - kmeans
-> - hotspot3D
-> - heartwall
-> - cfd
-> - bfs
-> - b+tree
+- streamcluster
+- particlefilter
+- nw
+- nn
+- myocyte
+- mummergpu
+- lud
+- leukocyte
+- lavaMD
+- kmeans
+- hotspot3D
+- heartwall
+- cfd
+- bfs
+- b+tree
 
 ### vecmathlib tests harness
 
@@ -185,23 +187,23 @@ Many of its programs have already been integrated in
 MultiSource/Benchmarks/DOE-ProxyApps-C and
 MultiSource/Benchmarks/DOE-ProxyApps-C++.
 
-> - Nekbone
-> - QMCPack
-> - LAMMPS
-> - Kripke
-> - Quicksilver
-> - PENNANT
-> - Big Data Analytic Suite
-> - Deep Learning Suite
-> - Stream
-> - Stride
-> - ML/DL micro-benchmark
-> - Pynamic
-> - ACME
-> - VPIC
-> - Laghos
-> - Parallel Integer Sort
-> - Havoq
+- Nekbone
+- QMCPack
+- LAMMPS
+- Kripke
+- Quicksilver
+- PENNANT
+- Big Data Analytic Suite
+- Deep Learning Suite
+- Stream
+- Stride
+- ML/DL micro-benchmark
+- Pynamic
+- ACME
+- VPIC
+- Laghos
+- Parallel Integer Sort
+- Havoq
 
 ### NWChem
 
@@ -258,45 +260,44 @@ into the test-suite repository.
 
 #### Resampling
 
-> - Bilinear
-> - Bicubic
-> - Lanczos
+- Bilinear
+- Bicubic
+- Lanczos
 
 #### Dither
 
-> - Threshold
-> - Random
-> - Halftone
-> - Bayer
-> - Floyd-Steinberg
-> - Jarvis
-> - Stucki
-> - Burkes
-> - Sierra
-> - Atkinson
-> - Gradient-based
+- Threshold
+- Random
+- Halftone
+- Bayer
+- Floyd-Steinberg
+- Jarvis
+- Stucki
+- Burkes
+- Sierra
+- Atkinson
+- Gradient-based
 
 #### Feature detection
 
-> - Harris
-> - Histogram of Oriented Gradients
+- Harris
+- Histogram of Oriented Gradients
 
 #### Color conversion
 
-> - RGB to grayscale
-> - HSL to RGB
+- RGB to grayscale
+- HSL to RGB
 
 ### Graph
 
 #### Search Algorithms
 
-> - Breadth-First-Search
-> - Depth-First-Search
-> - Dijkstra's algorithm
-> - A-Star
+- Breadth-First-Search
+- Depth-First-Search
+- Dijkstra's algorithm
+- A-Star
 
 #### Spanning Tree
 
-> - Kruskal's algorithm
-> - Prim's algorithm
-
+- Kruskal's algorithm
+- Prim's algorithm
diff --git a/llvm/docs/Proposals/VectorPredication.md b/llvm/docs/Proposals/VectorPredication.md
index db0456c0c1d3a..5f90e24cf36ac 100644
--- a/llvm/docs/Proposals/VectorPredication.md
+++ b/llvm/docs/Proposals/VectorPredication.md
@@ -1,3 +1,8 @@
+---
+myst:
+  footnote_transition: false
+---
+
 # Vector Predication Roadmap
 
 ## Motivation
@@ -7,12 +12,12 @@ specifically for vector instructions with a mask and/or an explicit vector
 length. LLVM currently has no target-independent means to model predicated
 vector instructions for modern SIMD ISAs such as AVX512, ARM SVE, the RISC-V V
 extension and NEC SX-Aurora. Only some predicated vector operations, such as
-masked loads and stores, are available through intrinsics [^cite_maskedir].
+masked loads and stores, are available through intrinsics [^maskedir].
 
 The Vector Predication (VP) extensions is a concrete RFC and prototype
 implementation to achieve native vector predication in LLVM. The VP prototype
 and all related discussions can be found in the VP patch on Phabricator
-[^cite_vprfc].
+[^vprfc].
 
 ## Roadmap
 
@@ -67,9 +72,8 @@ Result: Native vector predication in IR.
 
 ## References
 
-[^cite_maskedir]: `llvm.masked.*` intrinsics,
+[^maskedir]: `llvm.masked.*` intrinsics,
     <https://llvm.org/docs/LangRef.html#masked-vector-load-and-store-intrinsics>
 
-[^cite_vprfc]: RFC: Prototype & Roadmap for vector predication in LLVM,
+[^vprfc]: RFC: Prototype & Roadmap for vector predication in LLVM,
     <https://reviews.llvm.org/D57504>
-
diff --git a/llvm/docs/QualGroup.md b/llvm/docs/QualGroup.md
index f3b2c17b27183..902c184f7034e 100644
--- a/llvm/docs/QualGroup.md
+++ b/llvm/docs/QualGroup.md
@@ -124,18 +124,18 @@ Membership in the LLVM Qualification Group is intended for individuals with rele
 
 **Individual Contributors**
 
-> - Experience in software/tool qualification (e.g., reliability, quality, safety, security); OR
-> - Active involvement in LLVM-related qualification efforts; OR
-> - Significant LLVM contributions related to qualification in the past year (code, discussion, resolving related challenges).
+- Experience in software/tool qualification (e.g., reliability, quality, safety, security); OR
+- Active involvement in LLVM-related qualification efforts; OR
+- Significant LLVM contributions related to qualification in the past year (code, discussion, resolving related challenges).
 
 **Researchers**
 
-> - Active research, publication, or development of methodologies, frameworks, or tools aimed at improving LLVM quality and reliability.
+- Active research, publication, or development of methodologies, frameworks, or tools aimed at improving LLVM quality and reliability.
 
 **Vendor Contacts**
 
-> - Represent organizations building or using LLVM-based tools in safety-critical environments; OR
-> - Require involvement due to organizational role in qualification or compliance.
+- Represent organizations building or using LLVM-based tools in safety-critical environments; OR
+- Require involvement due to organizational role in qualification or compliance.
 
 ### Nomination Process
 
@@ -342,4 +342,3 @@ For more information or to get involved:
 
 - Refer to our initial [RFC: Proposal to Establish a Safety Group in LLVM](https://discourse.llvm.org/t/rfc-proposal-to-establish-a-safety-group-in-llvm/86916) on the LLVM Discourse forum.
 - Join the conversation on the LLVM Community Discord in the [#fusa-qual-wg](https://discord.com/channels/636084430946959380/1389362444169773117) channel.
-
diff --git a/llvm/docs/ScudoHardenedAllocator.md b/llvm/docs/ScudoHardenedAllocator.md
index a1982c978ef0b..36b2869791fcc 100644
--- a/llvm/docs/ScudoHardenedAllocator.md
+++ b/llvm/docs/ScudoHardenedAllocator.md
@@ -249,7 +249,7 @@ The following "string" options are available:
 ```
 
 Additional flags can be specified, for example if Scudo if compiled with
-[GWP-ASan](https://llvm.org/docs/GwpAsan.html) support.
+{doc}`GWP-ASan <GwpAsan>` support.
 
 The following "mallopt" options are available (options are defined in
 `include/scudo/interface.h`):
@@ -336,4 +336,3 @@ Here is a list of the current error messages and their potential cause:
 
 Several other error messages relate to parameter checking on the libc allocation
 APIs and are fairly straightforward to understand.
-
diff --git a/llvm/docs/Security.md b/llvm/docs/Security.md
index 108532838faad..582a6a92f0612 100644
--- a/llvm/docs/Security.md
+++ b/llvm/docs/Security.md
@@ -26,7 +26,7 @@ We aim to acknowledge your report within two business days since you first reach
 
 The members of the group represent a wide cross-section of the community, and
 meet the criteria for inclusion below. The list is in the format
-`* ${full_name} (${affiliation}) [${github_username}]`. If a github
+{title-reference}`* ${full_name} (${affiliation}) [${github_username}]`. If a github
 username for an individual isn't available, the brackets will be empty.
 
 - Abhay Kanhere (Apple) [@AbhayKanhere]
@@ -94,7 +94,7 @@ If a nomination for LLVM Security Response Group membership is supported by a ma
 
 ### Accepting membership
 
-Before new LLVM Security Response Group membership is finalized, the successful nominee should accept membership and agree to abide by this security policy, particularly [Privileges and Responsibilities of LLVM Security Response Group Members] below.
+Before new LLVM Security Response Group membership is finalized, the successful nominee should accept membership and agree to abide by this security policy, particularly [Privileges and Responsibilities of LLVM Security Response Group Members](#privileges-and-responsibilities-of-llvm-security-response-group-members) below.
 
 ### Keeping Membership Current
 
@@ -114,7 +114,7 @@ The transparency reports are published at {doc}`SecurityTransparencyReports`.
 
 ### Access
 
-LLVM Security Response Group members will be subscribed to a private [Discussion Medium]. It will be used for technical discussions of security issues, as well as process discussions about matters such as disclosure timelines and group membership. Members have access to all security issues.
+LLVM Security Response Group members will be subscribed to a private [Discussion Medium](#discussion-medium). It will be used for technical discussions of security issues, as well as process discussions about matters such as disclosure timelines and group membership. Members have access to all security issues.
 
 ### Confidentiality
 
@@ -199,7 +199,7 @@ as security-sensitive but need significant work to get to the stage where that's
 manageable. The LLVM community will need to decide whether it wants to invest in
 making these parts of the code securable, and maintain these security properties
 over time. In all cases the LLVM Security Response Group
-[should be consulted][security-group-discussion-medium], since they'll be
+{ref}`should be consulted <security-group-discussion-medium>`, since they'll be
 responding to security issues filed against these parts of the codebase.
 
 The security-sensitive parts of the LLVM Project currently are the following:
@@ -253,4 +253,3 @@ in the report, as well as update this document through the above process.
 [llvm/llvm-security-repo]: https://github.com/llvm/llvm-security-repo/security
 [mitre]: https://cve.mitre.org
 [report a vulnerability]: https://github.com/llvm/llvm-security-repo/security/advisories/new
-
diff --git a/llvm/docs/SecurityTransparencyReports.md b/llvm/docs/SecurityTransparencyReports.md
index 6cdb1fd2fbddb..5a0ba8552eaf1 100644
--- a/llvm/docs/SecurityTransparencyReports.md
+++ b/llvm/docs/SecurityTransparencyReports.md
@@ -1,9 +1,10 @@
 ---
-substitutions:
-  br: |-
-    ```{raw} html
-    <br/>
-    ```
+myst:
+  substitutions:
+    br: |-
+      ```{raw} html
+      <br/>
+      ```
 ---
 
 # LLVM Security Group Transparency Reports
@@ -107,44 +108,52 @@ that were received earlier, but were disclosed in 2023.
 
 9 of these were judged to be security issues:
 
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=36> reports the presence of
->   .git folder in <https://llvm.org/.git>. Redirect:
->   <https://issuetracker.google.com/issues/42410029> archive:
->   <https://github.com/llvm/llvm-project/issues/131841>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=66> reports the presence of a
->   GitHub Personal Access token in a DockerHub imaage. Redirect
->   <https://issuetracker.google.com/issues/42410060> archive:
->   <https://github.com/llvm/llvm-project/issues/131846>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=42> reports a potential gap
->   in the Armv8.1-m BTI protection, involving a combination of large switch statements
->   and \_\_builtin_unreachable() in the default case. Redirect:
->   <https://issuetracker.google.com/issues/42410035> archive:
->   <https://github.com/llvm/llvm-project/issues/131848>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=43> reports a dependency
->   on an old version of xml2js with a CVE filed against it. Redirect:
->   <https://issuetracker.google.com/issues/42410036> archive:
->   <https://github.com/llvm/llvm-project/issues/131849>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=45> reports a number of
->   dependencies that have had vulnerabilities reported against them. Redirect:
->   <https://issuetracker.google.com/issues/42410038> archive:
->   <https://github.com/llvm/llvm-project/issues/131851>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=46> is related to
->   issue 43. Redirect <https://issuetracker.google.com/issues/42410039> archive:
->   <https://github.com/llvm/llvm-project/issues/131852>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=48> reports a buffer overflow in
->   std::format from -fexperimental-library. Redirect:
->   https://issuetracker.google.com/issues/42410041 archive:
->   https://github.com/llvm/llvm-project/issues/131856
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=54> reports a memory leak in
->   basic_string move assignment when built with libc++ versions \<=6.0 and run against
->   newer libc++ shared/dylibs. Redirect:
->   <https://issuetracker.google.com/issues/42410047> archive:
->   <https://github.com/llvm/llvm-project/issues/131857>
-> - <https://bugs.chromium.org/p/llvm/issues/detail?id=56> reports an out
->   of bounds buffer store introduced by LLVM backends, that regressed
->   due to a procedural oversight. Redirect
->   <https://issuetracker.google.com/issues/42410049> archive:
->   <https://github.com/llvm/llvm-project/issues/131858>
+- https://bugs.chromium.org/p/llvm/issues/detail?id=36 reports the presence of
+  .git folder in https://llvm.org/.git. Redirect:
+  https://issuetracker.google.com/issues/42410029 archive:
+  https://github.com/llvm/llvm-project/issues/131841
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=66 reports the presence of a
+  GitHub Personal Access token in a DockerHub imaage. Redirect
+  https://issuetracker.google.com/issues/42410060 archive:
+  https://github.com/llvm/llvm-project/issues/131846
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=42 reports a potential gap
+  in the Armv8.1-m BTI protection, involving a combination of large switch statements
+  and __builtin_unreachable() in the default case. Redirect:
+  https://issuetracker.google.com/issues/42410035 archive:
+  https://github.com/llvm/llvm-project/issues/131848
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=43 reports a dependency
+  on an old version of xml2js with a CVE filed against it. Redirect:
+  https://issuetracker.google.com/issues/42410036 archive:
+  https://github.com/llvm/llvm-project/issues/131849
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=45 reports a number of
+  dependencies that have had vulnerabilities reported against them. Redirect:
+  https://issuetracker.google.com/issues/42410038 archive:
+  https://github.com/llvm/llvm-project/issues/131851
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=46 is related to
+  issue 43. Redirect https://issuetracker.google.com/issues/42410039 archive:
+  https://github.com/llvm/llvm-project/issues/131852
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=48 reports a buffer overflow in
+  std::format from -fexperimental-library. Redirect:
+  https://issuetracker.google.com/issues/42410041 archive:
+  https://github.com/llvm/llvm-project/issues/131856
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=54 reports a memory leak in
+  basic_string move assignment when built with libc++ versions <=6.0 and run against
+  newer libc++ shared/dylibs. Redirect:
+  https://issuetracker.google.com/issues/42410047 archive:
+  https://github.com/llvm/llvm-project/issues/131857
+
+- https://bugs.chromium.org/p/llvm/issues/detail?id=56 reports an out
+  of bounds buffer store introduced by LLVM backends, that regressed
+  due to a procedural oversight. Redirect
+  https://issuetracker.google.com/issues/42410049 archive:
+  https://github.com/llvm/llvm-project/issues/131858
 
 No dedicated LLVM releases were made for any of the above issues.
 
@@ -455,4 +464,3 @@ were not related to the LLVM project. The subject lines for these were:
 3. “I was recently hacked... maybe you folks might know the dev?”
 4. “ASP.NETconfiguration: Creating Debug Binary in `[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows`”
 5. “ASP.NETconfiguration: Creating Debug Binary in `[![Labelling new pull requests](https://github.com/llvm/llvm-project/actions/workflows/new-prs.yml/badge.svg?event=create)](https://github.com/llvm/llvm-project/actions/workflows`”
-
diff --git a/llvm/docs/SegmentedStacks.md b/llvm/docs/SegmentedStacks.md
index a23541379612d..a11592d325163 100644
--- a/llvm/docs/SegmentedStacks.md
+++ b/llvm/docs/SegmentedStacks.md
@@ -14,7 +14,7 @@ The runtime functionality is [already there in libgcc](http://gcc.gnu.org/wiki/S
 
 ## Implementation Details
 
-(allocating-stacklets)=
+(allocating stacklets)=
 
 ### Allocating Stacklets
 
@@ -53,7 +53,7 @@ second return, which returns control to the correct caller.
 
 ### Variable Sized Allocas
 
-The section on [allocating stacklets] automatically assumes that every stack
+The section on {ref}`allocating stacklets <allocating stacklets>` automatically assumes that every stack
 frame will be of fixed size. However, LLVM allows the use of the `llvm.alloca`
 intrinsic to allocate dynamically sized blocks of memory on the stack. When
 faced with such a variable-sized alloca, code is generated to:
@@ -65,4 +65,3 @@ faced with such a variable-sized alloca, code is generated to:
 
 The memory allocated from the heap is linked into a list in the current
 stacklet, and freed along with the same. This prevents a memory leak.
-
diff --git a/llvm/docs/StackMaps.md b/llvm/docs/StackMaps.md
index 2d07a0aaa2c3c..652b23a6750df 100644
--- a/llvm/docs/StackMaps.md
+++ b/llvm/docs/StackMaps.md
@@ -44,10 +44,10 @@ releases is not guaranteed.
 
 The stack map functionality described in this document is separate
 from the functionality described in
-{ref}`stack-map`. `GCFunctionMetadata` provides the location of
-pointers into a collected heap captured by the `GCRoot` intrinsic,
+{ref}`stack-map`. *GCFunctionMetadata* provides the location of
+pointers into a collected heap captured by the *GCRoot* intrinsic,
 which can also be considered a "stack map". Unlike the stack maps
-defined above, the `GCFunctionMetadata` stack map interface does not
+defined above, the *GCFunctionMetadata* stack map interface does not
 provide a way to associate live register values of arbitrary type with
 an instruction address, nor does it specify a format for the resulting
 stack map. The stack maps described here could potentially provide
@@ -341,17 +341,13 @@ StkMapRecord[NumRecords] {
 The first byte of each location encodes a type that indicates how to
 interpret the `RegNum` and `Offset` fields as follows:
 
-```{eval-rst}
-======== ========== =================== ===========================
-Encoding Type       Value               Description
--------- ---------- ------------------- ---------------------------
-0x1      Register   Reg                 Value in a register
-0x2      Direct     Reg + Offset        Frame index value
-0x3      Indirect   [Reg + Offset]      Spilled value
-0x4      Constant   Offset              Small constant
-0x5      ConstIndex Constants[Offset]   Large constant
-======== ========== =================== ===========================
-```
+| Encoding | Type       | Value             | Description         |
+| -------- | ---------- | ----------------- | ------------------- |
+| 0x1      | Register   | Reg               | Value in a register |
+| 0x2      | Direct     | Reg + Offset      | Frame index value   |
+| 0x3      | Indirect   | [Reg + Offset]    | Spilled value       |
+| 0x4      | Constant   | Offset            | Small constant      |
+| 0x5      | ConstIndex | Constants[Offset] | Large constant      |
 
 In the common case, a value is available in a register, and the
 `Offset` field will be zero. Values spilled to the stack are encoded
@@ -492,4 +488,3 @@ Support for StackMap generation and the related intrinsics requires
 some code for each backend. Today, only a subset of LLVM's backends
 are supported. The currently supported architectures are X86_64,
 PowerPC, AArch64 and SystemZ.
-
diff --git a/llvm/docs/Statepoints.md b/llvm/docs/Statepoints.md
index 5a39f643e0f00..6d24effc7b54d 100644
--- a/llvm/docs/Statepoints.md
+++ b/llvm/docs/Statepoints.md
@@ -321,7 +321,7 @@ lowering both the base and derived pointer operands are required to be live
 over the associated call safepoint even if the base is otherwise unused
 afterwards.
 
-(gc-transition-args)=
+(gc_transition_args)=
 
 ### GC Transitions
 
@@ -419,7 +419,7 @@ This special section is encoded per the
 The general expectation is that a JIT compiler will parse and discard this
 format; it is not particularly memory efficient. If you need an alternate
 format (e.g. for an ahead of time compiler), see discussion under
-\:ref: `open work items <OpenWork>` below.
+{ref}`open work items <OpenWork>` below.
 
 Each statepoint generates the following Locations:
 
@@ -510,7 +510,7 @@ experimenting with the current version.
 
 ## Utility Passes for Safepoint Insertion
 
-(rewritestatepointsforgc)=
+(RewriteStatepointsForGC)=
 
 ### RewriteStatepointsForGC
 
@@ -587,7 +587,7 @@ In practice, RewriteStatepointsForGC should be run much later in the pass
 pipeline, after most optimization is already done. This helps to improve
 the quality of the generated code when compiled with garbage collection support.
 
-(rewritestatepointsforgc-intrinsic-lowering)=
+(RewriteStatepointsForGC_intrinsic_lowering)=
 
 ### RewriteStatepointsForGC intrinsic lowering
 
@@ -633,7 +633,7 @@ declare void @__llvm_memcpy_element_unordered_atomic_safepoint_1(
   i64 %length)
 ```
 
-(placesafepoints)=
+(PlaceSafepoints)=
 
 ### PlaceSafepoints
 
@@ -701,7 +701,7 @@ here.
 Support for statepoint generation requires some code for each backend.
 Today, only Aarch64 and X86_64 are supported.
 
-(openwork)=
+(OpenWork)=
 
 ## Limitations and Half Baked Ideas
 
@@ -757,4 +757,3 @@ for [Statepoint] in the summary field. When filing new bugs, please
 use this tag so that interested parties see the newly filed bug. As
 with most LLVM features, design discussions take place on the [Discourse forums](https://discourse.llvm.org) and patches
 should be sent to [llvm-commits](http://lists.llvm.org/mailman/listinfo/llvm-commits) for review.
-
diff --git a/llvm/docs/SupportPolicy.md b/llvm/docs/SupportPolicy.md
index 3f22b36ea15db..7e052bee3da2a 100644
--- a/llvm/docs/SupportPolicy.md
+++ b/llvm/docs/SupportPolicy.md
@@ -169,11 +169,11 @@ burden on maintaining other components (core or peripheral).
 There are multiple types of issues that might trigger a request for deprecation,
 including (but not limited to):
 
-> - Changes in a component consistently break other areas of the project.
-> - Components go broken for long periods of time (weeks or more).
-> - Clearly superior alternatives are in use and maintenance is painful.
-> - Builds and tests are harder / take longer, increasing the cost of
->   maintenance, overtaking the perceived benefits.
+- Changes in a component consistently break other areas of the project.
+- Components go broken for long periods of time (weeks or more).
+- Clearly superior alternatives are in use and maintenance is painful.
+- Builds and tests are harder / take longer, increasing the cost of
+  maintenance, overtaking the perceived benefits.
 
 If the maintenance cost is higher than it is acceptable by the majority of
 developers, it means that either the sub-community is too small (and the extra
@@ -229,4 +229,3 @@ overall maintenance costs to a minimum and will need to show steps to mitigate
 all of the issues that were listed as reasons for its original removal.
 
 Failing on those again, will lead to become a candidate for removal yet again.
-
diff --git a/llvm/docs/TableGen/BackEnds.md b/llvm/docs/TableGen/BackEnds.md
index 47b7be492332f..03df57b33cb27 100644
--- a/llvm/docs/TableGen/BackEnds.md
+++ b/llvm/docs/TableGen/BackEnds.md
@@ -221,7 +221,7 @@ from TableGen records. The ARM and AArch64 targets use this backend to generate
 tables of system registers; the AMDGPU target uses it to generate meta-data
 about complex image and memory buffer instructions.
 
-See [SearchableTables Reference] for a detailed description.
+See [SearchableTables Reference](#searchabletables-reference) for a detailed description.
 
 ### CTags
 
@@ -1068,7 +1068,7 @@ function. This class provides three fields.
 - `GenericTable Table`. The name of the table that is to receive another
   lookup function.
 - `list<string> Key`. The list of fields that make up the secondary key.
-- `bit EarlyOut`. See the third example in [Generic Tables].
+- `bit EarlyOut`. See the third example in [Generic Tables](#generic-tables).
 
 Here is an example of a secondary key added to the `CTable` above. The
 generated function looks up entries based on the `Name` and `Kind` fields.
@@ -1124,4 +1124,3 @@ const CEntry *lookupCEntryByName(StringRef Name, unsigned Kind) {
   return &CTable[Idx->_index];
 }
 ```
-
diff --git a/llvm/docs/TableGen/BackGuide.md b/llvm/docs/TableGen/BackGuide.md
index 1e232c1cbeb28..bc1ce3c82c583 100644
--- a/llvm/docs/TableGen/BackGuide.md
+++ b/llvm/docs/TableGen/BackGuide.md
@@ -1,9 +1,7 @@
 # TableGen Backend Developer's Guide
 
-```{eval-rst}
-.. sectnum::
-
-```
+:::{sectnum}
+:::
 
 ## Introduction
 
@@ -46,7 +44,7 @@ is usually abbreviated `RK`.
 
 There are two maps in the recordkeeper, one for classes and one for records
 (the latter often referred to as *defs*). Each map maps the class or record
-name to an instance of the `Record` class (see [Record]), which contains
+name to an instance of the `Record` class (see [Record](#record)), which contains
 all the information about that class or record.
 
 In addition to the two maps, the `RecordKeeper` instance contains:
@@ -73,10 +71,10 @@ classes and one for the records. The primary data members of a record are
 the record name, the vector of field names and their values, and the vector of
 superclasses of the record.
 
-The record name is stored as a pointer to an `Init` (see [Init]), which
+The record name is stored as a pointer to an `Init` (see [Init](#init)), which
 is a class whose instances hold TableGen values (sometimes referred to as
 *initializers*). The field names and values are stored in a vector of
-`RecordVal` instances (see [RecordVal]), each of which contains both the
+`RecordVal` instances (see [RecordVal](#recordval)), each of which contains both the
 field name and its value. The superclass vector contains a sequence of
 pairs, with each pair including the superclass record and its source
 file location.
@@ -86,7 +84,7 @@ In addition to those members, a `Record` instance contains:
 - A vector of source file locations that includes the record definition
   itself, plus the locations of any multiclasses involved in its definition.
 - For a class record, a vector of the class's template arguments.
-- An instance of `DefInit` (see [DefInit]) corresponding to this record.
+- An instance of `DefInit` (see [DefInit](#definit)) corresponding to this record.
 - A unique record ID.
 - A boolean that specifies whether this is a class definition.
 - A boolean that specifies whether this is an anonymous record.
@@ -99,7 +97,7 @@ The `Record` class provides many useful functions.
   superclasses.
 - Functions to get a particular field value by specifying its name in various
   forms and returning its value in various forms
-  (see [Getting Record Names and Fields]).
+  (see [Getting Record Names and Fields](#getting-record-names-and-fields)).
 - Boolean functions to check the various attributes of the record.
 
 A `Record` instance can be printed to an output stream with the `<<`
@@ -117,7 +115,7 @@ In addition to those primary members, the `RecordVal` has other data members.
 
 - The source file location of the field definition.
 - The type of the field, stored as an instance
-  of the `RecTy` class (see [RecTy]).
+  of the `RecTy` class (see [RecTy](#recty)).
 
 The `RecordVal` class provides some useful functions.
 
@@ -127,7 +125,7 @@ The `RecordVal` class provides some useful functions.
 - A function to get the source file location.
 
 Note that field values are more easily obtained directly from the `Record`
-instance (see [Record]).
+instance (see [Record](#record)).
 
 A `RecordVal` instance can be printed to an output stream with the `<<`
 operator.
@@ -480,7 +478,7 @@ for (Record *AttrRec : AttrRecords) {
 
 ## Getting Record Names and Fields
 
-As described above (see [Record]), there are multiple functions that
+As described above (see [Record](#record)), there are multiple functions that
 return the name of a record. One particularly useful one is
 `getNameInitAsString()`, which returns the name as a `std::string`.
 
@@ -610,10 +608,10 @@ Each of these five functions is overloaded four times.
   source file locations is typically taken from a `Record` instance.
 - `PrintError(const Record *Rec, const Twine &Msg)`:
   Prints the message followed by the source line associated with the
-  specified record (see [Record]).
+  specified record (see [Record](#record)).
 - `PrintError(const RecordVal *RecVal, const Twine &Msg)`:
   Prints the message followed by the source line associated with the
-  specified record field (see [RecordVal]).
+  specified record field (see [RecordVal](#recordval)).
 
 Using these functions, the goal is to produce the most specific error report
 possible.
@@ -760,4 +758,3 @@ The backend has been divided into four phases and timed separately.
 
 If you want to instrument a backend, refer to the backend `DAGISelEmitter.cpp`
 and search for `Records.startTimer`.
-
diff --git a/llvm/docs/TableGen/ProgRef.md b/llvm/docs/TableGen/ProgRef.md
index 4c2c802fc9fe5..ff8a271ab24a6 100644
--- a/llvm/docs/TableGen/ProgRef.md
+++ b/llvm/docs/TableGen/ProgRef.md
@@ -1,9 +1,7 @@
 # TableGen Programmer's Reference
 
-```{eval-rst}
-.. sectnum::
-
-```
+:::{sectnum}
+:::
 
 ## Introduction
 
@@ -103,23 +101,23 @@ multiple concrete records all at once. A multiclass can inherit from other
 multiclasses, which means that the multiclass inherits all the definitions
 from its parent multiclasses.
 
-[Appendix C: Sample Record] illustrates a complex record in the Intel X86
+[Appendix C: Sample Record](#appendix-c-sample-record) illustrates a complex record in the Intel X86
 target and the simple way in which it is defined.
 
 ## Source Files
 
 TableGen source files are plain ASCII text files. The files can contain
-statements, comments, and blank lines (see [Lexical Analysis]). The standard file
+statements, comments, and blank lines (see [Lexical Analysis](#lexical-analysis)). The standard file
 extension for TableGen files is `.td`.
 
 TableGen files can grow quite large, so there is an include mechanism that
 allows one file to include the content of another file (see [Include
-Files][include files]). This allows large files to be broken up into smaller ones, and
+Files](#include-files)). This allows large files to be broken up into smaller ones, and
 also provides a simple library mechanism where multiple source files can
 include the same library file.
 
 TableGen supports a simple preprocessor that can be used to conditionalize
-portions of `.td` files. See [Preprocessing Facilities] for more
+portions of `.td` files. See [Preprocessing Facilities](#preprocessing-facilities) for more
 information.
 
 ## Lexical Analysis
@@ -132,7 +130,7 @@ implied whitespace between tokens.
 
 TableGen supports BCPL-style comments (`// ...`) and nestable C-style
 comments (`/* ... */`).
-TableGen also provides simple [Preprocessing Facilities].
+TableGen also provides simple [Preprocessing Facilities](#preprocessing-facilities).
 
 Formfeed characters may be used freely in files to produce page breaks when
 the file is printed for review.
@@ -237,7 +235,7 @@ syntax compared to other bang operators, so it is defined separately:
    CondOperator: !cond
 ```
 
-See [Appendix A: Bang Operators] for a description of each bang operator.
+See [Appendix A: Bang Operators](#appendix-a-bang-operators) for a description of each bang operator.
 
 ### Include files
 
@@ -321,7 +319,7 @@ wide range of records conveniently and compactly.
   another `dag` object, allowing an arbitrary tree of nodes and edges.
   As an example, DAGs are used to represent code patterns for use by
   the code generator instruction selection algorithms. See [Directed
-  acyclic graphs (DAGs)][directed acyclic graphs (dags)] for more details;
+  acyclic graphs (DAGs)](#directed-acyclic-graphs-dags) for more details;
 
 {token}`ClassID`
 
@@ -451,7 +449,7 @@ sometimes not when the value is the empty list (`[]`).
 
 This represents a DAG initializer (note the parentheses). The first
 {token}`DagArg` is called the "operator" of the DAG and must be a record.
-See [Directed acyclic graphs (DAGs)] for more details.
+See [Directed acyclic graphs (DAGs)](#directed-acyclic-graphs-dags) for more details.
 
 ```{eval-rst}
 .. productionlist::
@@ -474,7 +472,7 @@ sense after reading the remainder of this guide.
   ```
 
 - The implicit template argument `NAME` in a `class` or `multiclass`
-  definition (see [NAME]).
+  definition (see [NAME](#name)).
 
 - A field local to a `class`, such as the use of `Bar` in:
 
@@ -533,11 +531,11 @@ sense after reading the remainder of this guide.
 
 This form creates a new anonymous record definition (as would be created by an
 unnamed `def` inheriting from the given class with the given template
-arguments; see [def]) and the value is that record. A field of the record can be
-obtained using a suffix; see [Suffixed Values].
+arguments; see [def](#def)) and the value is that record. A field of the record can be
+obtained using a suffix; see [Suffixed Values](#suffixed-values).
 
 Invoking a class in this manner can provide a simple subroutine facility.
-See [Using Classes as Subroutines] for more information.
+See [Using Classes as Subroutines](#using-classes-as-subroutines) for more information.
 
 ```{eval-rst}
 .. productionlist::
@@ -551,9 +549,9 @@ simple values. Except in the case of `!cond`, a bang operator takes a list
 of arguments enclosed in parentheses and performs some function on those
 arguments, producing a value for that bang operator. The `!cond` operator
 takes a list of pairs of arguments separated by colons. See [Appendix A:
-Bang Operators][appendix a: bang operators] for a description of each bang operator.
+Bang Operators](#appendix-a-bang-operators) for a description of each bang operator.
 
-The `Type` is only accepted for certain bang operators, and must not be
+The *Type* is only accepted for certain bang operators, and must not be
 `code`.
 
 ### Suffixed values
@@ -573,13 +571,13 @@ primary value. Here are the possible suffixes for some primary *value*.
 
 *value*`[i]`
 
-: The final value is element `i` of the list *value* (note the brackets).
+: The final value is element *i* of the list *value* (note the brackets).
   In other words, the brackets act as a subscripting operator on the list.
   This is the case only when a single element is specified.
 
 *value*`[i,]`
 
-: The final value is a list that contains a single element `i` of the list.
+: The final value is a list that contains a single element *i* of the list.
   In short, a list slice with a single element.
 
 *value*`[4...7,17,2...3,4]`
@@ -592,8 +590,8 @@ primary value. Here are the possible suffixes for some primary *value*.
   *value*`[i,m...n,j,ls]`
 
   : Each element may be an expression (variables, bang operators).
-    The type of `m` and `n` should be `int`.
-    The type of `i`, `j`, and `ls` should be either `int` or `list<int>`.
+    The type of *m* and *n* should be *int*.
+    The type of *i*, *j*, and *ls* should be either *int* or *list\<int>*.
 
 *value*`.`*field*
 
@@ -621,7 +619,7 @@ left-hand-side operand is treated normally.
 Values can have a trailing paste operator, in which case the left-hand-side
 operand is concatenated to an empty string.
 
-[Appendix B: Paste Operator Examples] presents examples of the behavior of
+[Appendix B: Paste Operator Examples](#appendix-b-paste-operator-examples) presents examples of the behavior of
 the paste operator.
 
 ## Statements
@@ -683,14 +681,14 @@ forward declaration. Note that records derived from a forward-declared
 class will inherit no fields from it, because those records are built when
 their declarations are parsed, and thus before the class is finally defined.
 
-(name)=
+(NAME)=
 
 Every class has an implicit template argument named `NAME` (uppercase),
 which is bound to the name of the {token}`Def` or {token}`Defm` inheriting
 from the class. If the class is inherited by an anonymous record, the name
 is unspecified but globally unique.
 
-See [Examples: classes and records] for examples.
+See [Examples: classes and records](#examples-classes-and-records) for examples.
 
 #### Record Bodies
 
@@ -788,7 +786,7 @@ The `defvar` form defines a variable whose value can be used in other
 value expressions within the body. The variable is not a field: it does not
 become a field of the class or record being defined. Variables are provided
 to hold temporary values while processing the body. See [Defvar in a Record
-Body][defvar in a record body] for more details.
+Body](#defvar-in-a-record-body) for more details.
 
 When class `C2` inherits from class `C1`, it acquires all the field
 definitions of `C1`. As those definitions are merged into class `C2`, any
@@ -841,9 +839,9 @@ The DAG `(ops rec1)` is passed as a template argument to class `A`. Notice
 that the DAG includes `rec1`, the record being defined.
 
 The steps taken to create a new record are somewhat complex. See [How
-records are built][how records are built].
+records are built](#how-records-are-built).
 
-See [Examples: classes and records] for examples.
+See [Examples: classes and records](#examples-classes-and-records) for examples.
 
 ### Examples: classes and records
 
@@ -1051,7 +1049,7 @@ contains a series of statements that define records, using {token}`Def` and
 The {token}`If` and {token}`Assert` statements can also be used.
 
 Also as with regular classes, the multiclass has the implicit template
-argument `NAME` (see [NAME]). When a named (non-anonymous) record is
+argument `NAME` (see [NAME](#name)). When a named (non-anonymous) record is
 defined in a multiclass and the record's name does not include a use of the
 template argument `NAME`, such a use is automatically *prepended*
 to the name. That is, the following are equivalent inside a multiclass:
@@ -1067,7 +1065,7 @@ definition. Each `def` statement in the multiclass produces a record. As
 with top-level `def` statements, these definitions can inherit from
 multiple parent classes.
 
-See [Examples: multiclasses and defms] for examples.
+See [Examples: multiclasses and defms](#examples-multiclasses-and-defms) for examples.
 
 ### `defm` --- invoke multiclasses to define multiple records
 
@@ -1119,7 +1117,7 @@ defm Foo        : SomeMultiClass<...>;
 defm NAME # Foo : SomeMultiClass<...>;
 ```
 
-See [Examples: multiclasses and defms] for examples.
+See [Examples: multiclasses and defms](#examples-multiclasses-and-defms) for examples.
 
 ### Examples: multiclasses and defms
 
@@ -1348,7 +1346,7 @@ The identifier on the left of the `=` is defined to be a type name
 whose actual type is given by the type expression on the right of the `=`.
 
 Currently, only primitive types and type aliases are supported to be the source
-type and `deftype` statements can only appear at the top level.
+type and *deftype* statements can only appear at the top level.
 
 ### `defvar` --- define a variable
 
@@ -1375,7 +1373,7 @@ defvar i = !add(i, 1);
 ```
 
 Variables can also be defined with `defvar` in a record body. See
-[Defvar in a Record Body] for more details.
+[Defvar in a Record Body](#defvar-in-a-record-body) for more details.
 
 ### `foreach` --- iterate over a sequence of statements
 
@@ -1419,7 +1417,7 @@ A `dump` statement prints the input string to standard error
 output. It is intended for debugging purposes.
 
 - At top level, the message is printed immediately.
-- Within a record/class/multiclass, `dump` gets evaluated at each
+- Within a record/class/multiclass, *dump* gets evaluated at each
   instantiation point of the containing record.
 
 ```{eval-rst}
@@ -1428,7 +1426,7 @@ output. It is intended for debugging purposes.
 ```
 
 The {token}`Value` is an arbitrary string expression.
-For example, it can be used in combination with `!repr` to investigate
+For example, it can be used in combination with *!repr* to investigate
 the values passed to a multiclass:
 
 ```text
@@ -1462,7 +1460,7 @@ the usual way: in a case like `if v1 then if v2 then {...} else {...}`, the
 
 The {token}`IfBody` of the then and else arms of the `if` establish an
 inner scope. Any `defvar` variables defined in the bodies go out of scope
-when the bodies are finished (see [Defvar in a Record Body] for more details).
+when the bodies are finished (see [Defvar in a Record Body](#defvar-in-a-record-body) for more details).
 
 The `if` statement can also be used in a record {token}`Body`.
 
@@ -1579,24 +1577,29 @@ defvar i = !add(i, 1)
 The following steps are taken by TableGen when a record is built. Classes are simply
 abstract records and so go through the same steps.
 
-1. Build the record name ({token}`NameValue`) and create an empty record.
-2. Parse the parent classes in the {token}`ParentClassList` from left to
+```{eval-rst}
+1. Build the record name (:token:`NameValue`) and create an empty record.
+
+2. Parse the parent classes in the :token:`ParentClassList` from left to
    right, visiting each parent class's ancestor classes from top to bottom.
 
-> 1. Add the fields from the parent class to the record.
-> 2. Substitute the template arguments into those fields.
-> 3. Add the parent class to the record's list of inherited classes.
+  a. Add the fields from the parent class to the record.
+  b. Substitute the template arguments into those fields.
+  c. Add the parent class to the record's list of inherited classes.
 
-3. Apply any top-level `let` bindings to the record. Recall that top-level
+3. Apply any top-level ``let`` bindings to the record. Recall that top-level
    bindings only apply to inherited fields.
+
 4. Parse the body of the record.
 
-> - Add any fields to the record.
-> - Modify the values of fields according to local `let` statements.
-> - Define any `defvar` variables.
+  * Add any fields to the record.
+  * Modify the values of fields according to local ``let`` statements.
+  * Define any ``defvar`` variables.
 
 5. Make a pass over all the fields to resolve any inter-field references.
+
 6. Add the record to the final record list.
+```
 
 Because references between fields are resolved (step 5) after `let` bindings are
 applied (step 3), the `let` statement has unusual power. For example:
@@ -1639,7 +1642,7 @@ def rec2 {      // C
 
 ## Using Classes as Subroutines
 
-As described in [Simple values], a class can be invoked in an expression
+As described in [Simple values](#simple-values), a class can be invoked in an expression
 and passed template arguments. This causes TableGen to create a new anonymous
 record inheriting from that class. As usual, the record receives all the
 fields defined in the class.
@@ -1850,14 +1853,14 @@ and non-0 as true.
 
 `!filter(`*var*`,` *list*`,` *predicate*`)`
 
-> This operator creates a new `list` by filtering the elements in
-> *list*. To perform the filtering, TableGen binds the variable *var* to each
-> element and then evaluates the *predicate* expression, which presumably
-> refers to *var*. The predicate must
-> produce a boolean value (`bit`, `bits`, or `int`). The value is
-> interpreted as with `!if`:
-> if the value is 0, the element is not included in the new list. If the value
-> is anything else, the element is included.
+: This operator creates a new `list` by filtering the elements in
+  *list*. To perform the filtering, TableGen binds the variable *var* to each
+  element and then evaluates the *predicate* expression, which presumably
+  refers to *var*. The predicate must
+  produce a boolean value (`bit`, `bits`, or `int`). The value is
+  interpreted as with `!if`:
+  if the value is 0, the element is not included in the new list. If the value
+  is anything else, the element is included.
 
 `!find(`*string1*`,` *string2*\[`,` *start*\]`)`
 
@@ -2067,10 +2070,10 @@ and non-0 as true.
   For example:
 
   - `!range(4)` is equivalent to `!range(0, 4, 1)` and the result is
-    `[0, 1, 2, 3]`.
+    *[0, 1, 2, 3]*.
   - `!range(1, 4)` is equivalent to `!range(1, 4, 1)` and the result is
-    `[1, 2, 3]`.
-  - The result of `!range(0, 4, 2)` is `[0, 2]`.
+    *[1, 2, 3]*.
+  - The result of `!range(0, 4, 2)` is *[0, 2]*.
   - The results of `!range(0, 4, -1)` and `!range(4, 0, 1)` are empty.
 
 `!range(`*list*`)`
@@ -2129,11 +2132,9 @@ and non-0 as true.
 
   For example, to sort a list of records by their `Name` field:
 
+  ```text
+  list<Thing> sorted = !sort(t, Things, t.Name);
   ```
-  .. code-block:: text
-  ```
-
-  > list\<Thing> sorted = !sort(t, Things, t.Name);
 
 `!sra(`*a*`,` *count*`)`
 
@@ -2407,4 +2408,3 @@ from all the parent classes; for example, `IsIndirectBranch` is inherited
 from the `Instruction` class.
 
 [python's]: http://docs.python.org/py3k/reference/introduction.html#notation
-
diff --git a/llvm/docs/TransformMetadata.md b/llvm/docs/TransformMetadata.md
index 302a35944db72..588e8bb3546c6 100644
--- a/llvm/docs/TransformMetadata.md
+++ b/llvm/docs/TransformMetadata.md
@@ -390,7 +390,7 @@ if (rtc) {
 ```
 
 The runtime condition (`rtc`) checks that the array `A` and the
-element `B[0]` do not alias.
+element {title-reference}`B[0]` do not alias.
 
 Currently, this transformation does not support followup-attributes.
 
@@ -407,28 +407,28 @@ to change. The default optimization pipeline (anything higher than
 
 When using the legacy pass manager:
 
-> - LoopInterchange (if enabled)
-> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
-> - VersioningLICM (if enabled)
-> - LoopDistribute
-> - LoopVectorizer
-> - LoopUnrollAndJam (if enabled)
-> - LoopUnroll (partial and runtime unrolling)
+- LoopInterchange (if enabled)
+- SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+- VersioningLICM (if enabled)
+- LoopDistribute
+- LoopVectorizer
+- LoopUnrollAndJam (if enabled)
+- LoopUnroll (partial and runtime unrolling)
 
 When using the legacy pass manager with LTO:
 
-> - LoopInterchange (if enabled)
-> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
-> - LoopVectorizer
-> - LoopUnroll (partial and runtime unrolling)
+- LoopInterchange (if enabled)
+- SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+- LoopVectorizer
+- LoopUnroll (partial and runtime unrolling)
 
 When using the new pass manager:
 
-> - SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
-> - LoopDistribute
-> - LoopVectorizer
-> - LoopUnrollAndJam (if enabled)
-> - LoopUnroll (partial and runtime unrolling)
+- SimpleLoopUnroll/LoopFullUnroll (only performs full unrolling)
+- LoopDistribute
+- LoopVectorizer
+- LoopUnrollAndJam (if enabled)
+- LoopUnroll (partial and runtime unrolling)
 
 ## Leftover Transformations
 
@@ -455,4 +455,3 @@ case.
 
 Future versions of LLVM may fix this by executing transformations using
 a dynamic ordering.
-
diff --git a/llvm/docs/TypeMetadata.md b/llvm/docs/TypeMetadata.md
index 8626fd39598d0..c286cccd99020 100644
--- a/llvm/docs/TypeMetadata.md
+++ b/llvm/docs/TypeMetadata.md
@@ -56,15 +56,14 @@ struct D : A, C {
 
 The virtual table objects for A, B, C and D look like this (under the Itanium ABI):
 
-```{eval-rst}
-.. csv-table:: Virtual Table Layout for A, B, C, D
-  :header: Class, 0, 1, 2, 3, 4, 5, 6
+:::{csv-table} Virtual Table Layout for A, B, C, D
+:header: Class, 0, 1, 2, 3, 4, 5, 6
 
-  A, A::offset-to-top, &A::rtti, &A::f
-  B, B::offset-to-top, &B::rtti, &B::f, &B::g
-  C, C::offset-to-top, &C::rtti, &C::h
-  D, D::offset-to-top, &D::rtti, &D::f, &D::h, D::offset-to-top, &D::rtti, thunk for &D::h
-```
+A, A::offset-to-top, &A::rtti, &A::f
+B, B::offset-to-top, &B::rtti, &B::f, &B::g
+C, C::offset-to-top, &C::rtti, &C::h
+D, D::offset-to-top, &D::rtti, &D::f, &D::h, D::offset-to-top, &D::rtti, thunk for &D::h
+:::
 
 When an object of type A is constructed, the address of `&A::f` in A's
 virtual table object is stored in the object's vtable pointer. In ABI parlance
@@ -84,18 +83,17 @@ shown below. The following table shows the name of a class, the offset of an
 address point within that class's vtable and the name of one of the classes
 with which that address point is compatible.
 
-```{eval-rst}
-.. csv-table:: Type Offsets for A, B, C, D
-  :header: VTable for, Offset, Compatible Class
-
-  A, 16, A
-  B, 16, A
-   ,   , B
-  C, 16, C
-  D, 16, A
-   ,   , D
-   , 48, C
-```
+:::{csv-table} Type Offsets for A, B, C, D
+:header: VTable for, Offset, Compatible Class
+
+A, 16, A
+B, 16, A
+ ,   , B
+C, 16, C
+D, 16, A
+ ,   , D
+ , 48, C
+:::
 
 The next step is to encode this compatibility information into the IR. The way
 this is done is to create type metadata named after each of the compatible
@@ -156,6 +154,8 @@ as the former will be the jump table entry if a jump table is necessary.
 The [GlobalLayoutBuilder][globallayoutbuilder] class is responsible for laying out the globals
 efficiently to minimize the sizes of the underlying bitsets.
 
+**Example:**
+
 ```
 target datalayout = "e-p:32:32"
 
@@ -284,4 +284,3 @@ normal loads.
 [control flow integrity]: https://clang.llvm.org/docs/ControlFlowIntegrity.html
 [control flow integrity design document]: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html
 [globallayoutbuilder]: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
-
diff --git a/llvm/docs/VectorizationPlan.md b/llvm/docs/VectorizationPlan.md
index 6df336f3c28e6..560f9080a95d9 100644
--- a/llvm/docs/VectorizationPlan.md
+++ b/llvm/docs/VectorizationPlan.md
@@ -1,9 +1,14 @@
+---
+myst:
+  footnote_transition: false
+---
+
 # Vectorization Plan
 
 ## Abstract
 
 The vectorization transformation can be rather complicated, involving several
-potential alternatives, especially for outer-loops [^footnote-1] but also possibly for
+potential alternatives, especially for outer-loops [^1] but also possibly for
 innermost loops. These alternatives may have significant performance impact,
 both positive and negative. A cost model is therefore employed to identify the
 best alternative, including the alternative of avoiding any transformation
@@ -20,7 +25,7 @@ VPlan is currently used to drive code-generation in LoopVectorize. VPlans are
 constructed after all cost-based and most legality-related decisions have been
 taken. As def-use chains between recipes are now fully modeled in VPlan,
 VPlan-based analyses and transformations are used to simplify and modularize
-the vectorization process [^footnote-10]. Those include transformations to
+the vectorization process [^10]. Those include transformations to
 
 1. Legalize the initial VPlan, e.g. by introducing specialized recipes for
    reductions and interleave groups.
@@ -104,8 +109,8 @@ The design of VPlan follows several high-level guidelines:
    3. Combinations of the above, including nested vectorization: vectorizing
       both an inner loop and an outer-loop at the same time (each with its own
       VF and UF), mixed vectorization: vectorizing a loop with SLP patterns
-      inside [^footnote-4], (re)vectorizing input IR containing vector code.
-   4. Function vectorization [^footnote-2].
+      inside [^4], (re)vectorizing input IR containing vector code.
+   4. Function vectorization [^2].
 
 4. Support multiple candidates efficiently. In particular, similar candidates
    related to a range of possible VF's and UF's must be represented efficiently.
@@ -131,39 +136,44 @@ The design of VPlan follows several high-level guidelines:
 
 The low-level design of VPlan comprises of the following classes.
 
-```{eval-rst}
+LoopVectorizationPlanner
+: A LoopVectorizationPlanner is designed to handle the vectorization of a loop
+  or a loop nest. It can construct, optimize and discard one or more VPlans,
+  each VPlan modelling a distinct way to vectorize the loop or the loop nest.
+  Once the best VPlan is determined, including the best VF and UF, this VPlan
+  drives the generation of output IR.
 
-:VPlan:
-  A model of a vectorized candidate for a given input IR loop or loop nest. This
+VPlan
+: A model of a vectorized candidate for a given input IR loop or loop nest. This
   candidate is represented using a Hierarchical CFG. VPlan supports estimating
   the cost and driving the generation of the output IR code it represents.
 
-:Hierarchical CFG:
-  A control-flow graph whose nodes are basic-blocks or Hierarchical CFG's. The
-  Hierarchical CFG data structure is similar to the Tile Tree [5]_, where
+Hierarchical CFG
+: A control-flow graph whose nodes are basic-blocks or Hierarchical CFG's. The
+  Hierarchical CFG data structure is similar to the Tile Tree [^5], where
   cross-Tile edges are lifted to connect Tiles instead of the original
-  basic-blocks as in Sharir [6]_, promoting the Tile encapsulation. The terms
-  Region and Block are used rather than Tile [5]_ to avoid confusion with loop
+  basic-blocks as in Sharir [^6], promoting the Tile encapsulation. The terms
+  Region and Block are used rather than Tile [^5] to avoid confusion with loop
   tiling.
 
-:VPBlockBase:
-  The building block of the Hierarchical CFG. A pure-virtual base-class of
+VPBlockBase
+: The building block of the Hierarchical CFG. A pure-virtual base-class of
   VPBasicBlock and VPRegionBlock, see below. VPBlockBase models the hierarchical
   control-flow relations with other VPBlocks. Note that in contrast to the IR
   BasicBlock, a VPBlockBase models its control-flow successors and predecessors
   directly, rather than through a Terminator branch or through predecessor
   branches that "use" the VPBlockBase.
 
-:VPBasicBlock:
-  VPBasicBlock is a subclass of VPBlockBase, and serves as the leaves of the
+VPBasicBlock
+: VPBasicBlock is a subclass of VPBlockBase, and serves as the leaves of the
   Hierarchical CFG. It represents a sequence of output IR instructions that will
   appear consecutively in an output IR basic-block. The instructions of this
   basic-block originate from one or more VPBasicBlocks. VPBasicBlock holds a
   sequence of zero or more VPRecipes that model the cost and generation of the
   output IR instructions.
 
-:VPRegionBlock:
-  VPRegionBlock is a subclass of VPBlockBase. It models a collection of
+VPRegionBlock
+: VPRegionBlock is a subclass of VPBlockBase. It models a collection of
   VPBasicBlocks and VPRegionBlocks which form a SESE subgraph of the output IR
   CFG. A VPRegionBlock may indicate that its contents are to be replicated a
   constant number of times when output IR is generated, effectively representing
@@ -171,46 +181,39 @@ The low-level design of VPlan comprises of the following classes.
   to support scalarized and predicated instructions with a single model for
   multiple candidate VF's and UF's.
 
-:VPRecipeBase:
-  A pure-virtual base class modeling a sequence of one or more output IR
+VPRecipeBase
+: A pure-virtual base class modeling a sequence of one or more output IR
   instructions, possibly based on one or more input IR instructions. These
   input IR instructions are referred to as "Ingredients" of the Recipe. A Recipe
   may specify how its ingredients are to be transformed to produce the output IR
   instructions; e.g., cloned once, replicated multiple times or widened
   according to selected VF.
 
-:VPValue:
-  The base of VPlan's def-use relations class hierarchy. When instantiated, it
+VPValue
+: The base of VPlan's def-use relations class hierarchy. When instantiated, it
   models a constant or a live-in Value in VPlan. It has users, which are of type
   VPUser, but no operands.
 
-:VPUser:
-  A VPUser represents an entity that uses a number of VPValues as operands.
+VPUser
+: A VPUser represents an entity that uses a number of VPValues as operands.
   VPUser is similar in some aspects to LLVM's User class.
 
-:VPDef:
-  A VPDef represents an entity that defines zero, one or multiple VPValues.
+VPDef
+: A VPDef represents an entity that defines zero, one or multiple VPValues.
   It is used to model the fact that recipes in VPlan can define multiple
   VPValues.
 
-:VPInstruction:
-  A VPInstruction is a recipe characterized by a single opcode and optional
+VPInstruction
+: A VPInstruction is a recipe characterized by a single opcode and optional
   flags, free of ingredients or other meta-data. VPInstructions also extend
   LLVM IR's opcodes with idiomatic operations that enrich the Vectorizer's
   semantics.
 
-:VPTransformState:
-  Stores information used for generating output IR, passed from
+VPTransformState
+: Stores information used for generating output IR, passed from
   LoopVectorizationPlanner to its selected VPlan for execution, and used to pass
   additional information down to VPBlocks and VPRecipes.
 
-The Planning Process and VPlan Roadmap
-======================================
-
-Transforming the Loop Vectorizer to use VPlan follows a staged approach. First,
-VPlan was only used to record the final vectorization decisions, and to execute
-```
-
 ## The Planning Process and VPlan Roadmap
 
 Transforming the Loop Vectorizer to use VPlan follows a staged approach. First,
@@ -246,43 +249,42 @@ idiom groups having synergistic cost.
 ### Related LLVM components
 
 1. SLP Vectorizer: one can compare the VPlan model with LLVM's existing SLP
-   tree, where TSLP [^footnote-3] adds Plan Step 2.b.
+   tree, where TSLP [^3] adds Plan Step 2.b.
 2. RegionInfo: one can compare VPlan's H-CFG with the Region Analysis as used by
-   Polly [^footnote-7].
+   Polly [^7].
 3. Loop Vectorizer: the Vectorization Plan aims to upgrade the infrastructure of
-   the Loop Vectorizer and extend it to handle outer loops [^footnote-8], [^footnote-9].
+   the Loop Vectorizer and extend it to handle outer loops [^8], [^9].
 
 ### References
 
-[^footnote-1]: "Outer-loop vectorization: revisited for short SIMD architectures", Dorit
+[^1]: "Outer-loop vectorization: revisited for short SIMD architectures", Dorit
     Nuzman and Ayal Zaks, PACT 2008.
 
-[^footnote-2]: "Proposal for function vectorization and loop vectorization with function
+[^2]: "Proposal for function vectorization and loop vectorization with function
     calls", Xinmin Tian, \[[cfe-dev](http://lists.llvm.org/pipermail/cfe-dev/2016-March/047732.html)\].,
     March 2, 2016.
     See also [review](https://reviews.llvm.org/D22792).
 
-[^footnote-3]: "Throttling Automatic Vectorization: When Less is More", Vasileios
+[^3]: "Throttling Automatic Vectorization: When Less is More", Vasileios
     Porpodas and Tim Jones, PACT 2015 and LLVM Developers' Meeting 2015.
 
-[^footnote-4]: "Exploiting mixed SIMD parallelism by reducing data reorganization
+[^4]: "Exploiting mixed SIMD parallelism by reducing data reorganization
     overhead", Hao Zhou and Jingling Xue, CGO 2016.
 
-[^footnote-5]: "Register Allocation via Hierarchical Graph Coloring", David Callahan and
+[^5]: "Register Allocation via Hierarchical Graph Coloring", David Callahan and
     Brian Koblenz, PLDI 1991
 
-[^footnote-6]: "Structural analysis: A new approach to flow analysis in optimizing
+[^6]: "Structural analysis: A new approach to flow analysis in optimizing
     compilers", M. Sharir, Journal of Computer Languages, Jan. 1980
 
-[^footnote-7]: "Enabling Polyhedral Optimizations in LLVM", Tobias Grosser, Diploma
+[^7]: "Enabling Polyhedral Optimizations in LLVM", Tobias Grosser, Diploma
     thesis, 2011.
 
-[^footnote-8]: "Introducing VPlan to the Loop Vectorizer", Gil Rapaport and Ayal Zaks,
+[^8]: "Introducing VPlan to the Loop Vectorizer", Gil Rapaport and Ayal Zaks,
     European LLVM Developers' Meeting 2017.
 
-[^footnote-9]: "Extending LoopVectorizer: OpenMP4.5 SIMD and Outer Loop
+[^9]: "Extending LoopVectorizer: OpenMP4.5 SIMD and Outer Loop
     Auto-Vectorization", Intel Vectorizer Team, LLVM Developers' Meeting 2016.
 
-[^footnote-10]: "VPlan: Status Update and Future Roadmap", Ayal Zaks and Florian Hahn,
+[^10]: "VPlan: Status Update and Future Roadmap", Ayal Zaks and Florian Hahn,
     LLVM Developers' Meeting 2023, <https://www.youtube.com/watch?v=SzGP4PgMuLE>
-
diff --git a/llvm/docs/XRay.md b/llvm/docs/XRay.md
index 6a306e067a891..6744d3a7195ab 100644
--- a/llvm/docs/XRay.md
+++ b/llvm/docs/XRay.md
@@ -1,9 +1,9 @@
----
-Version: 1 as of 2016-11-08
----
-
 # XRay Instrumentation
 
+```{eval-rst}
+:Version: 1 as of 2016-11-08
+```
+
 ## Introduction
 
 XRay is a function call tracing system which combines compiler-inserted
@@ -80,10 +80,10 @@ void alt_never_instrumented() __attribute__((xray_never_instrument));
 ```
 
 When linking a binary, you can either manually link in the [XRay Runtime
-Library][xray runtime library] or use `clang` to link it in automatically with the
+Library](#xray-runtime-library) or use `clang` to link it in automatically with the
 `-fxray-instrument` flag. Alternatively, you can statically link-in the XRay
 runtime library from compiler-rt -- those archive files will take the name of
-`libclang_rt.xray-{arch}` where `{arch}` is the mnemonic supported by clang
+{title-reference}`libclang_rt.xray-{arch}` where {title-reference}`{arch}` is the mnemonic supported by clang
 (x86_64, arm7, etc.).
 
 ### LLVM Function Attribute
@@ -240,7 +240,7 @@ variable. Programmatic configuration can be done by calling
 selected/installed.
 
 When the buffers are flushed to disk, the result is a binary trace format
-described by [XRay FDR format](XRayFDRFormat.html)
+described by {doc}`XRay FDR format <XRayFDRFormat>`
 
 When FDR mode is on, it will keep writing and recycling memory buffers until
 the logging implementation is finalized -- at which point it can be flushed and
@@ -274,9 +274,11 @@ format. All the trace analysis tools (and the trace reading library) will
 support all versions of the FDR mode format as we add more functionality and
 record types in the future.
 
-> **NOTE:** We do not promise perpetual support for when we update the log
-> versions we support going forward. Deprecation of the formats will be
-> announced and discussed on the developers mailing list.
+:::{note}
+We do not promise perpetual support for when we update the log
+versions we support going forward. Deprecation of the formats will be
+announced and discussed on the developers mailing list.
+:::
 
 ### Trace Analysis Tools
 
@@ -292,7 +294,7 @@ supports the following subcommands:
 - `convert`: Converts an XRay log file from one format to another. We can
   convert from binary XRay traces (both basic and FDR mode) to YAML,
   [flame-graph](https://github.com/brendangregg/FlameGraph) friendly text
-  formats, as well as `Chrome Trace Viewer (catapult)
+  formats, as well as {title-reference}`Chrome Trace Viewer (catapult)
   <https://github.com/catapult-project/catapult>` formats.
 - `graph`: Generates a DOT graph of the function call relationships between
   functions found in an XRay trace.
@@ -360,7 +362,6 @@ the XRay instrumentation system.
 We're looking forward to contributions to port XRay to more architectures and
 operating systems.
 
-% References...
+<!-- References... -->
 
 [xray whitepaper]: http://research.google.com/pubs/pub45287.html
-
diff --git a/llvm/docs/XRayExample.md b/llvm/docs/XRayExample.md
index dc2d591eda85e..e1393049bfbac 100644
--- a/llvm/docs/XRayExample.md
+++ b/llvm/docs/XRayExample.md
@@ -7,7 +7,7 @@ compiling some sample LLVM IR generated by Clang.
 ## Building with XRay
 
 To debug an application with XRay instrumentation, we need to build it with a
-Clang that supports the `-fxray-instrument` option. See [XRay](XRay.html)
+Clang that supports the `-fxray-instrument` option. See {doc}`XRay`
 for more technical details of how XRay works for background information.
 
 In our example, we need to add `-fxray-instrument` to the list of flags
@@ -321,8 +321,7 @@ llvm-xray tool, please feel free to propose them on the llvm-dev@ mailing list.
 The following are some ideas to inspire you in getting involved and potentially
 making things better.
 
-> - Implement a query/filtering library that allows for finding patterns in the
->   XRay traces.
-> - Collecting function call stacks and how often they're encountered in the
->   XRay trace.
-
+- Implement a query/filtering library that allows for finding patterns in the
+  XRay traces.
+- Collecting function call stacks and how often they're encountered in the
+  XRay trace.
diff --git a/llvm/docs/XRayFDRFormat.md b/llvm/docs/XRayFDRFormat.md
index 19005b5a4aca7..766329a03d905 100644
--- a/llvm/docs/XRayFDRFormat.md
+++ b/llvm/docs/XRayFDRFormat.md
@@ -1,9 +1,9 @@
----
-Version: 1 as of 2017-07-20
----
-
 # XRay Flight Data Recorder Trace Format
 
+```{eval-rst}
+:Version: 1 as of 2017-07-20
+```
+
 ## Introduction
 
 When gathering XRay traces in Flight Data Recorder mode, each thread of an
@@ -268,4 +268,3 @@ Function records.
 - Not every entry must have a traced Exit or Tail Exit. The buffer may run out
   of space or the program may request for the tracer to finalize toreturn the
   buffer before an instrumented function exits.
-

>From 32a0ee2afeb665d12b7dd4ef9a59cf3792ac3055 Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Sat, 12 Sep 2026 00:08:59 +0000
Subject: [PATCH 4/4] [LLVM][docs] Convert remaining batch 11 tables to MyST

---
 llvm/docs/QualGroup.md              |  82 ++++++-----
 llvm/docs/ScudoHardenedAllocator.md | 207 +++++++++++++++-------------
 llvm/docs/TypeMetadata.md           |  44 +++---
 3 files changed, 169 insertions(+), 164 deletions(-)

diff --git a/llvm/docs/QualGroup.md b/llvm/docs/QualGroup.md
index 902c184f7034e..366a24ee95ccd 100644
--- a/llvm/docs/QualGroup.md
+++ b/llvm/docs/QualGroup.md
@@ -40,48 +40,46 @@ The members of the LLVM Qualification Group represent a diverse cross-section of
 They meet the criteria for inclusion described in the sub-sections below and are identified as [active contributors](#contribution-principles).
 Knowing their handles help us keep track of who’s who across platforms, coordinate activities, and recognize contributions.
 
-```{eval-rst}
-.. list-table::
-   :widths: 20 20 20 20 20
-   :header-rows: 1
-
-   * - Name
-     - Affiliation
-     - Discourse handle
-     - Discord handle
-     - GitHub handle
-   * - Carlos Andrés Ramírez
-     - Woven by Toyota
-     - CarlosAndresRamirez
-     - carlos\_andres\_ramirez
-     - CarlosAndresRamirez
-   * - Oscar Slotosch
-     - Validas
-     - slotosch
-     - oscarslotosch_66740
-     - slotosch
-   * - Petter Berntsson
-     - Arm Limited
-     - petbernt
-     - petbernt
-     - petbernt
-   * - Wendi Urribarri
-     - Woven by Toyota
-     - uwendi
-     - uwendi
-     - uwendi
-   * - YoungJun Lee
-     - NSHC
-     - YoungJunLee
-     - YoungJunLee
-     - IamYJLee
-   * - Zaky Hermawan
-     - (No affiliation)
-     - ZakyHermawan
-     - quarkz99
-     - zakyHermawan
-
-```
+:::{list-table}
+:widths: 20 20 20 20 20
+:header-rows: 1
+
+* - Name
+  - Affiliation
+  - Discourse handle
+  - Discord handle
+  - GitHub handle
+* - Carlos Andrés Ramírez
+  - Woven by Toyota
+  - CarlosAndresRamirez
+  - carlos_andres_ramirez
+  - CarlosAndresRamirez
+* - Oscar Slotosch
+  - Validas
+  - slotosch
+  - oscarslotosch_66740
+  - slotosch
+* - Petter Berntsson
+  - Arm Limited
+  - petbernt
+  - petbernt
+  - petbernt
+* - Wendi Urribarri
+  - Woven by Toyota
+  - uwendi
+  - uwendi
+  - uwendi
+* - YoungJun Lee
+  - NSHC
+  - YoungJunLee
+  - YoungJunLee
+  - IamYJLee
+* - Zaky Hermawan
+  - (No affiliation)
+  - ZakyHermawan
+  - quarkz99
+  - zakyHermawan
+:::
 
 Organizations are limited to three representatives within the group to maintain diversity.
 
diff --git a/llvm/docs/ScudoHardenedAllocator.md b/llvm/docs/ScudoHardenedAllocator.md
index 36b2869791fcc..fa79e0296b488 100644
--- a/llvm/docs/ScudoHardenedAllocator.md
+++ b/llvm/docs/ScudoHardenedAllocator.md
@@ -188,65 +188,76 @@ extern "C" const char *__scudo_default_options() {
 
 The following "string" options are available:
 
-```{eval-rst}
-+---------------------------------+----------------+-------------------------------------------------+
-| Option                          | Default        | Description                                     |
-+---------------------------------+----------------+-------------------------------------------------+
-| quarantine_size_kb              | 0              | The size (in Kb) of quarantine used to delay    |
-|                                 |                | the actual deallocation of chunks. Lower value  |
-|                                 |                | may reduce memory usage but decrease the        |
-|                                 |                | effectiveness of the mitigation; a negative     |
-|                                 |                | value will fallback to the defaults. Setting    |
-|                                 |                | *both* this and thread_local_quarantine_size_kb |
-|                                 |                | to zero will disable the quarantine entirely.   |
-+---------------------------------+----------------+-------------------------------------------------+
-| quarantine_max_chunk_size       | 0              | Size (in bytes) up to which chunks can be       |
-|                                 |                | quarantined.                                    |
-+---------------------------------+----------------+-------------------------------------------------+
-| thread_local_quarantine_size_kb | 0              | The size (in Kb) of per-thread cache use to     |
-|                                 |                | offload the global quarantine. Lower value may  |
-|                                 |                | reduce memory usage but might increase          |
-|                                 |                | contention on the global quarantine. Setting    |
-|                                 |                | *both* this and quarantine_size_kb to zero will |
-|                                 |                | disable the quarantine entirely.                |
-+---------------------------------+----------------+-------------------------------------------------+
-| dealloc_type_mismatch           | false          | Whether or not we report errors on              |
-|                                 |                | malloc/delete, new/free, new/delete[], etc.     |
-+---------------------------------+----------------+-------------------------------------------------+
-| delete_size_mismatch            | true           | Whether or not we report errors on mismatch     |
-|                                 |                | between sizes of new and delete.                |
-+---------------------------------+----------------+-------------------------------------------------+
-| zero_contents                   | false          | Whether or not we zero chunk contents on        |
-|                                 |                | allocation.                                     |
-+---------------------------------+----------------+-------------------------------------------------+
-| pattern_fill_contents           | false          | Whether or not we fill chunk contents with a    |
-|                                 |                | byte pattern on allocation.                     |
-+---------------------------------+----------------+-------------------------------------------------+
-| may_return_null                 | true           | Whether or not a non-fatal failure can return a |
-|                                 |                | NULL pointer (as opposed to terminating).       |
-+---------------------------------+----------------+-------------------------------------------------+
-| release_to_os_interval_ms       | 5000           | The minimum interval (in ms) at which a release |
-|                                 |                | can be attempted (a negative value disables     |
-|                                 |                | reclaiming).                                    |
-+---------------------------------+----------------+-------------------------------------------------+
-| allocation_ring_buffer_size     | 32768          | If stack trace collection is requested, how     |
-|                                 |                | many previous allocations to keep in the        |
-|                                 |                | allocation ring buffer.                         |
-|                                 |                |                                                 |
-|                                 |                | This buffer is used to provide allocation and   |
-|                                 |                | deallocation stack traces for MTE fault         |
-|                                 |                | reports. The larger the buffer, the more        |
-|                                 |                | unrelated allocations can happen between        |
-|                                 |                | (de)allocation and the fault.                   |
-|                                 |                | If your sync-mode MTE faults do not have        |
-|                                 |                | (de)allocation stack traces, try increasing the |
-|                                 |                | buffer size.                                    |
-|                                 |                |                                                 |
-|                                 |                | Stack trace collection can be requested using   |
-|                                 |                | the scudo_malloc_set_track_allocation_stacks    |
-|                                 |                | function.                                       |
-+---------------------------------+----------------+-------------------------------------------------+
-```
+:::{list-table}
+
+* - Option
+  - Default
+  - Description
+* - quarantine_size_kb
+  - 0
+  - The size (in Kb) of quarantine used to delay
+    the actual deallocation of chunks. Lower value
+    may reduce memory usage but decrease the
+    effectiveness of the mitigation; a negative
+    value will fallback to the defaults. Setting
+    *both* this and thread_local_quarantine_size_kb
+    to zero will disable the quarantine entirely.
+* - quarantine_max_chunk_size
+  - 0
+  - Size (in bytes) up to which chunks can be
+    quarantined.
+* - thread_local_quarantine_size_kb
+  - 0
+  - The size (in Kb) of per-thread cache use to
+    offload the global quarantine. Lower value may
+    reduce memory usage but might increase
+    contention on the global quarantine. Setting
+    *both* this and quarantine_size_kb to zero will
+    disable the quarantine entirely.
+* - dealloc_type_mismatch
+  - false
+  - Whether or not we report errors on
+    malloc/delete, new/free, new/delete[], etc.
+* - delete_size_mismatch
+  - true
+  - Whether or not we report errors on mismatch
+    between sizes of new and delete.
+* - zero_contents
+  - false
+  - Whether or not we zero chunk contents on
+    allocation.
+* - pattern_fill_contents
+  - false
+  - Whether or not we fill chunk contents with a
+    byte pattern on allocation.
+* - may_return_null
+  - true
+  - Whether or not a non-fatal failure can return a
+    NULL pointer (as opposed to terminating).
+* - release_to_os_interval_ms
+  - 5000
+  - The minimum interval (in ms) at which a release
+    can be attempted (a negative value disables
+    reclaiming).
+* - allocation_ring_buffer_size
+  - 32768
+  - If stack trace collection is requested, how
+    many previous allocations to keep in the
+    allocation ring buffer.
+
+    This buffer is used to provide allocation and
+    deallocation stack traces for MTE fault
+    reports. The larger the buffer, the more
+    unrelated allocations can happen between
+    (de)allocation and the fault.
+    If your sync-mode MTE faults do not have
+    (de)allocation stack traces, try increasing the
+    buffer size.
+
+    Stack trace collection can be requested using
+    the scudo_malloc_set_track_allocation_stacks
+    function.
+:::
 
 Additional flags can be specified, for example if Scudo if compiled with
 {doc}`GWP-ASan <GwpAsan>` support.
@@ -254,45 +265,45 @@ Additional flags can be specified, for example if Scudo if compiled with
 The following "mallopt" options are available (options are defined in
 `include/scudo/interface.h`):
 
-```{eval-rst}
-+---------------------------+-------------------------------------------------------+
-| Option                    | Description                                           |
-+---------------------------+-------------------------------------------------------+
-| M_DECAY_TIME              | Sets the release interval option to the specified     |
-|                           | value (Android only allows 0 or 1 to respectively set |
-|                           | the interval to the minimum and maximum value as      |
-|                           | specified at compile time).                           |
-+---------------------------+-------------------------------------------------------+
-| M_PURGE                   | Forces immediate memory reclaiming but does not       |
-|                           | reclaim everything. For smaller size classes, there   |
-|                           | is still some memory that is not reclaimed due to the |
-|                           | extra time it takes and the small amount of memory    |
-|                           | that can be reclaimed.                                |
-|                           | The value is ignored.                                 |
-+---------------------------+-------------------------------------------------------+
-| M_PURGE_ALL               | Same as M_PURGE but will force release all possible   |
-|                           | memory regardless of how long it takes.               |
-|                           | The value is ignored.                                 |
-+---------------------------+-------------------------------------------------------+
-| M_MEMTAG_TUNING           | Tunes the allocator's choice of memory tags to make   |
-|                           | it more likely that a certain class of memory errors  |
-|                           | will be detected. The value argument should be one of |
-|                           | the enumerators of ``scudo_memtag_tuning``.           |
-+---------------------------+-------------------------------------------------------+
-| M_THREAD_DISABLE_MEM_INIT | Tunes the per-thread memory initialization, 0 being   |
-|                           | the normal behavior, 1 disabling the automatic heap   |
-|                           | initialization.                                       |
-+---------------------------+-------------------------------------------------------+
-| M_CACHE_COUNT_MAX         | Set the maximum number of entries than can be cached  |
-|                           | in the Secondary cache.                               |
-+---------------------------+-------------------------------------------------------+
-| M_CACHE_SIZE_MAX          | Sets the maximum size of entries that can be cached   |
-|                           | in the Secondary cache.                               |
-+---------------------------+-------------------------------------------------------+
-| M_TSDS_COUNT_MAX          | Increases the maximum number of TSDs that can be used |
-|                           | up to the limit specified at compile time.            |
-+---------------------------+-------------------------------------------------------+
-```
+:::{list-table}
+
+* - Option
+  - Description
+* - M_DECAY_TIME
+  - Sets the release interval option to the specified
+    value (Android only allows 0 or 1 to respectively set
+    the interval to the minimum and maximum value as
+    specified at compile time).
+* - M_PURGE
+  - Forces immediate memory reclaiming but does not
+    reclaim everything. For smaller size classes, there
+    is still some memory that is not reclaimed due to the
+    extra time it takes and the small amount of memory
+    that can be reclaimed.
+    The value is ignored.
+* - M_PURGE_ALL
+  - Same as M_PURGE but will force release all possible
+    memory regardless of how long it takes.
+    The value is ignored.
+* - M_MEMTAG_TUNING
+  - Tunes the allocator's choice of memory tags to make
+    it more likely that a certain class of memory errors
+    will be detected. The value argument should be one of
+    the enumerators of `scudo_memtag_tuning`.
+* - M_THREAD_DISABLE_MEM_INIT
+  - Tunes the per-thread memory initialization, 0 being
+    the normal behavior, 1 disabling the automatic heap
+    initialization.
+* - M_CACHE_COUNT_MAX
+  - Set the maximum number of entries than can be cached
+    in the Secondary cache.
+* - M_CACHE_SIZE_MAX
+  - Sets the maximum size of entries that can be cached
+    in the Secondary cache.
+* - M_TSDS_COUNT_MAX
+  - Increases the maximum number of TSDs that can be used
+    up to the limit specified at compile time.
+:::
 
 ## Error Types
 
diff --git a/llvm/docs/TypeMetadata.md b/llvm/docs/TypeMetadata.md
index c286cccd99020..7ebd026138313 100644
--- a/llvm/docs/TypeMetadata.md
+++ b/llvm/docs/TypeMetadata.md
@@ -248,30 +248,26 @@ from classes with hidden visibility), then this optimisation would be valid.
 This concept is represented in IR by the `!vcall_visibility` metadata
 attached to vtable objects, with the following values:
 
-```{eval-rst}
-.. list-table::
-   :header-rows: 1
-   :widths: 10 90
-
-   * - Value
-     - Behavior
-
-   * - 0 (or omitted)
-     - **Public**
-           Virtual function calls using this vtable could be made from external
-           code.
-
-   * - 1
-     - **Linkage Unit**
-           All virtual function calls which might use this vtable are in the
-           current LTO unit, meaning they will be in the current module once
-           LTO linking has been performed.
-
-   * - 2
-     - **Translation Unit**
-           All virtual function calls which might use this vtable are in the
-           current module.
-```
+:::{list-table}
+:header-rows: 1
+:widths: 10 90
+
+* - Value
+  - Behavior
+* - 0 (or omitted)
+  - **Public**
+    : Virtual function calls using this vtable could be made from external
+      code.
+* - 1
+  - **Linkage Unit**
+    : All virtual function calls which might use this vtable are in the
+      current LTO unit, meaning they will be in the current module once
+      LTO linking has been performed.
+* - 2
+  - **Translation Unit**
+    : All virtual function calls which might use this vtable are in the
+      current module.
+:::
 
 In addition, all function pointer loads from a vtable marked with the
 `!vcall_visibility` metadata (with a non-zero value) must be done using the



More information about the llvm-branch-commits mailing list