[Mlir-commits] [mlir] 31d1ae7 - [mlir][doc] Fix links and references in documentation of Tutorials

Markus Böck llvmlistbot at llvm.org
Tue May 25 11:18:58 PDT 2021

Author: Markus Böck
Date: 2021-05-25T20:18:50+02:00
New Revision: 31d1ae79752da75503a4f1deb3ef2fd0b7868682

URL: https://github.com/llvm/llvm-project/commit/31d1ae79752da75503a4f1deb3ef2fd0b7868682
DIFF: https://github.com/llvm/llvm-project/commit/31d1ae79752da75503a4f1deb3ef2fd0b7868682.diff

LOG: [mlir][doc] Fix links and references in documentation of Tutorials

This patch is the third in a series of patches fixing markdown links and references inside the mlir documentation.

This patch addresses all broken references to other markdown files and sections inside the Tutorials folder.

Differential Revision: https://reviews.llvm.org/D103017




diff  --git a/mlir/docs/Tutorials/CreatingADialect.md b/mlir/docs/Tutorials/CreatingADialect.md
index 9a1c0fa339afb..3f39cfcec840a 100644
--- a/mlir/docs/Tutorials/CreatingADialect.md
+++ b/mlir/docs/Tutorials/CreatingADialect.md
@@ -10,7 +10,7 @@ Public dialects are typically separated into at least 3 directories:
 * mlir/test/Dialect/Foo           (for tests)
 Along with other public headers, the 'include' directory contains a
-TableGen file in the [ODS format](OpDefinitions.md), describing the
+TableGen file in the [ODS format](../OpDefinitions.md), describing the
 operations in the dialect.  This is used to generate operation
 declarations (FooOps.h.inc) and definitions (FooOps.cpp.inc) and
 operation interface declarations (FooOpsInterfaces.h.inc) and
@@ -23,7 +23,7 @@ FooOpsInterfaces.h.inc.
 The 'Transforms' directory contains rewrite rules for the dialect,
 typically described in TableGen file using the [DDR
 Note that dialect names should not generally be suffixed with “Ops”,
 although some files pertaining only to the operations of a dialect (e.g.

diff  --git a/mlir/docs/Tutorials/DefiningAttributesAndTypes.md b/mlir/docs/Tutorials/DefiningAttributesAndTypes.md
index 4afafe718b545..30d6a6e9412e8 100644
--- a/mlir/docs/Tutorials/DefiningAttributesAndTypes.md
+++ b/mlir/docs/Tutorials/DefiningAttributesAndTypes.md
@@ -1,11 +1,11 @@
 # Defining Dialect Attributes and Types
 This document is a quickstart to defining dialect specific extensions to the
-[attribute](LangRef.md#attributes) and [type](LangRef.md#type-system) systems in
+[attribute](../LangRef.md/#attributes) and [type](../LangRef.md/#type-system) systems in
 MLIR. The main part of this tutorial focuses on defining types, but the
 instructions are nearly identical for defining attributes.
-See [MLIR specification](LangRef.md) for more information about MLIR, the
+See [MLIR specification](../LangRef.md) for more information about MLIR, the
 structure of the IR, operations, etc.
 ## Types
@@ -25,13 +25,13 @@ So before defining the derived `Type`, it's important to know which of the two
 classes of `Type` we are defining:
 Some types are _singleton_ in nature, meaning they have no parameters and only
-ever have one instance, like the [`index` type](../Dialects/Builtin.md#indextype).
+ever have one instance, like the [`index` type](../Dialects/Builtin.md/#indextype).
 Other types are _parametric_, and contain additional information that
diff erentiates 
diff erent instances of the same `Type`. For example the
-[`integer` type](../Dialects/Builtin.md#integertype) contains a bitwidth, with `i8` and
+[`integer` type](../Dialects/Builtin.md/#integertype) contains a bitwidth, with `i8` and
 `i16` representing 
diff erent instances of
-[`integer` type](../Dialects/Builtin.md#integertype). _Parametric_ may also contain a
+[`integer` type](../Dialects/Builtin.md/#integertype). _Parametric_ may also contain a
 mutable component, which can be used, for example, to construct self-referring
 recursive types. The mutable component _cannot_ be used to 
diff erentiate
 instances of a type class, so usually such types contain other parametric
@@ -319,7 +319,7 @@ public:
 Once the dialect types have been defined, they must then be registered with a
 `Dialect`. This is done via a similar mechanism to
-[operations](LangRef.md#operations), with the `addTypes` method. The one
+[operations](../LangRef.md/#operations), with the `addTypes` method. The one
diff erence with operations, is that when a type is registered the
 definition of its storage class must be visible.
@@ -351,7 +351,7 @@ public:
 These methods take an instance of a high-level parser or printer that allows for
 easily implementing the necessary functionality. As described in the
-[MLIR language reference](../../LangRef.md#dialect-types), dialect types are
+[MLIR language reference](../LangRef.md/#dialect-types), dialect types are
 generally represented as: `! dialect-namespace < type-data >`, with a pretty
 form available under certain circumstances. The responsibility of our parser and
 printer is to provide the `type-data` bits.

diff  --git a/mlir/docs/Tutorials/QuickstartRewrites.md b/mlir/docs/Tutorials/QuickstartRewrites.md
index 54e67214a4735..2de24e8343bb5 100644
--- a/mlir/docs/Tutorials/QuickstartRewrites.md
+++ b/mlir/docs/Tutorials/QuickstartRewrites.md
@@ -6,10 +6,10 @@ patterns, as well as defining the rewrite using a graph walker (note: using
 patterns and the rewrite engine is preferred, showing the walker is for
 demonstration purposes).
-See [MLIR specification](LangRef.md) for more information about MLIR, the
+See [MLIR specification](../LangRef.md) for more information about MLIR, the
 structure of the IR, operations, etc. See
-[Table-driven Operation Definition](OpDefinitions.md) and
-[Declarative Rewrite Rule](DeclarativeRewrites.md) for the detailed explanation
+[Table-driven Operation Definition](../OpDefinitions.md) and
+[Declarative Rewrite Rule](../DeclarativeRewrites.md) for the detailed explanation
 of all available mechanisms for defining operations and rewrites in a
 table-driven manner.

diff  --git a/mlir/docs/Tutorials/Toy/Ch-2.md b/mlir/docs/Tutorials/Toy/Ch-2.md
index 8386804da8c62..2c0389e09d7e0 100644
--- a/mlir/docs/Tutorials/Toy/Ch-2.md
+++ b/mlir/docs/Tutorials/Toy/Ch-2.md
@@ -29,10 +29,10 @@ pre-defined instructions (*operations* in MLIR terminology) or types.
 MLIR is designed to be a completely extensible infrastructure; there is no
 closed set of attributes (think: constant metadata), operations, or types. MLIR
 supports this extensibility with the concept of
-[Dialects](../../LangRef.md#dialects). Dialects provide a grouping mechanism for
+[Dialects](../../LangRef.md/#dialects). Dialects provide a grouping mechanism for
 abstraction under a unique `namespace`.
-In MLIR, [`Operations`](../../LangRef.md#operations) are the core unit of
+In MLIR, [`Operations`](../../LangRef.md/#operations) are the core unit of
 abstraction and computation, similar in many ways to LLVM instructions.
 Operations can have application-specific semantics and can be used to represent
 all of the core IR structures in LLVM: instructions, globals (like functions),
@@ -49,7 +49,7 @@ Let's break down the anatomy of this MLIR operation:
 -   `%t_tensor`
     *   The name given to the result defined by this operation (which includes
-        [a prefixed sigil to avoid collisions](../../LangRef.md#identifiers-and-keywords)).
+        [a prefixed sigil to avoid collisions](../../LangRef.md/#identifiers-and-keywords)).
         An operation may define zero or more results (in the context of Toy, we
         will limit ourselves to single-result operations), which are SSA values.
         The name is used during parsing but is not persistent (e.g., it is not
@@ -90,13 +90,13 @@ about and manipulated generically. These concepts are:
 -   A name for the operation.
 -   A list of SSA operand values.
--   A list of [attributes](../../LangRef.md#attributes).
--   A list of [types](../../LangRef.md#type-system) for result values.
--   A [source location](../../Diagnostics.md#source-locations) for debugging
+-   A list of [attributes](../../LangRef.md/#attributes).
+-   A list of [types](../../LangRef.md/#type-system) for result values.
+-   A [source location](../../Diagnostics.md/#source-locations) for debugging
--   A list of successors [blocks](../../LangRef.md#blocks) (for branches,
+-   A list of successors [blocks](../../LangRef.md/#blocks) (for branches,
--   A list of [regions](../../LangRef.md#regions) (for structural operations
+-   A list of [regions](../../LangRef.md/#regions) (for structural operations
     like functions).
 In MLIR, every operation has a mandatory source location associated with it.
@@ -118,7 +118,7 @@ compiler passes - does not include locations in the output by default. The
 MLIR is designed to allow all IR elements, such as attributes, operations, and
 types, to be customized. At the same time, IR elements can always be reduced to
 the above fundamental concepts. This allows MLIR to parse, represent, and
-[round-trip](../../../getting_started/Glossary.md#round-trip) IR for *any*
+[round-trip](../../../getting_started/Glossary.md/#round-trip) IR for *any*
 operation. For example, we could place our Toy operation from above into an
 `.mlir` file and round-trip through *mlir-opt* without registering any dialect:
@@ -240,10 +240,10 @@ operation. This operation will represent a constant value in the Toy language.
 This operation takes zero operands, a
-[dense elements](../../LangRef.md#dense-elements-attribute) attribute named
+[dense elements](../../Dialects/Builtin.md/#denseintorfpelementsattr) attribute named
 `value` to represent the constant value, and returns a single result of
-[TensorType](../../LangRef.md#tensor-type). An operation class inherits from the
+[RankedTensorType](../../Dialects/Builtin.md/#rankedtensortype). An operation class 
+inherits from the [CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
 `mlir::Op` class which also takes some optional [*traits*](../../Traits.md) to
 customize its behavior. `Traits` are a mechanism with which we can inject
 additional behavior into an Operation, such as additional accessors,
@@ -378,7 +378,7 @@ operation.
 We define a toy operation by inheriting from our base 'Toy_Op' class above. Here
 we provide the mnemonic and a list of traits for the operation. The
-[mnemonic](../../OpDefinitions.md#operation-name) here matches the one given in
+[mnemonic](../../OpDefinitions.md/#operation-name) here matches the one given in
 `ConstantOp::getOperationName` without the dialect prefix; `toy.`. Missing here
 from our C++ definition are the `ZeroOperands` and `OneResult` traits; these
 will be automatically inferred based upon the `arguments` and `results` fields
@@ -404,8 +404,8 @@ implementation is incredibly useful when getting started with TableGen.
 #### Defining Arguments and Results
 With the shell of the operation defined, we can now provide the
-[inputs](../../OpDefinitions.md#operation-arguments) and
-[outputs](../../OpDefinitions.md#operation-results) to our operation. The
+[inputs](../../OpDefinitions.md/#operation-arguments) and
+[outputs](../../OpDefinitions.md/#operation-results) to our operation. The
 inputs, or arguments, to an operation may be attributes or types for SSA operand
 values. The results correspond to a set of types for the values produced by the
@@ -430,7 +430,7 @@ ConstantOp::value()`.
 The next step after defining the operation is to document it. Operations may
-[`summary` and `description`](../../OpDefinitions.md#operation-documentation)
+[`summary` and `description`](../../OpDefinitions.md/#operation-documentation)
 fields to describe the semantics of the operation. This information is useful
 for users of the dialect and can even be used to auto-generate Markdown
@@ -468,7 +468,7 @@ necessary verification logic based upon the constraints we have given. This
 means that we don't need to verify the structure of the return type, or even the
 input attribute `value`. In many cases, additional verification is not even
 necessary for ODS operations. To add additional verification logic, an operation
-can override the [`verifier`](../../OpDefinitions.md#custom-verifier-code)
+can override the [`verifier`](../../OpDefinitions.md/#custom-verifier-code)
 field. The `verifier` field allows for defining a C++ code blob that will be run
 as part of `ConstantOp::verify`. This blob can assume that all of the other
 invariants of the operation have already been verified:
@@ -508,7 +508,7 @@ def ConstantOp : Toy_Op<"constant"> {
 The final missing component here from our original C++ example are the `build`
 methods. ODS can generate some simple build methods automatically, and in this
 case it will generate our first build method for us. For the rest, we define the
-[`builders`](../../OpDefinitions.md#custom-builder-methods) field. This field
+[`builders`](../../OpDefinitions.md/#custom-builder-methods) field. This field
 takes a list of `OpBuilder` objects that take a string corresponding to a list
 of C++ parameters, as well as an optional code block that can be used to specify
 the implementation inline.
@@ -580,7 +580,7 @@ One thing to notice here is that all of our Toy operations are printed using the
 generic assembly format. This format is the one shown when breaking down
 `toy.transpose` at the beginning of this chapter. MLIR allows for operations to
 define their own custom assembly format, either
-[declaratively](../../OpDefinitions.md#declarative-assembly-format) or
+[declaratively](../../OpDefinitions.md/#declarative-assembly-format) or
 imperatively via C++. Defining a custom assembly format allows for tailoring the
 generated IR into something a bit more readable by removing a lot of the fluff
 that is required by the generic format. Let's walk through an example of an
@@ -655,7 +655,7 @@ static mlir::ParseResult parsePrintOp(mlir::OpAsmParser &parser,
 With the C++ implementation defined, let's see how this can be mapped to the
-[declarative format](../../OpDefinitions.md#declarative-assembly-format). The
+[declarative format](../../OpDefinitions.md/#declarative-assembly-format). The
 declarative format is largely composed of three 
diff erent components:
 *   Directives
@@ -681,7 +681,7 @@ def PrintOp : Toy_Op<"print"> {
-The [declarative format](../../OpDefinitions.md#declarative-assembly-format) has
+The [declarative format](../../OpDefinitions.md/#declarative-assembly-format) has
 many more interesting features, so be sure to check it out before implementing a
 custom format in C++. After beautifying the format of a few of our operations we
 now get a much more readable:

diff  --git a/mlir/docs/Tutorials/Toy/Ch-3.md b/mlir/docs/Tutorials/Toy/Ch-3.md
index abdb419f534fa..b3d1c0006bf75 100644
--- a/mlir/docs/Tutorials/Toy/Ch-3.md
+++ b/mlir/docs/Tutorials/Toy/Ch-3.md
@@ -108,7 +108,7 @@ The implementation of this rewriter is in `ToyCombine.cpp`. The
 [canonicalization pass](../../Canonicalization.md) applies transformations
 defined by operations in a greedy, iterative manner. To ensure that the
 canonicalization pass applies our new transform, we set
-[hasCanonicalizer = 1](../../OpDefinitions.md#hascanonicalizer) and register the
+[hasCanonicalizer = 1](../../OpDefinitions.md/#hascanonicalizer) and register the
 pattern with the canonicalization framework.

diff  --git a/mlir/docs/Tutorials/Toy/Ch-4.md b/mlir/docs/Tutorials/Toy/Ch-4.md
index 938e44289280a..76102d2a222d6 100644
--- a/mlir/docs/Tutorials/Toy/Ch-4.md
+++ b/mlir/docs/Tutorials/Toy/Ch-4.md
@@ -50,7 +50,7 @@ hook into.
 The first thing we need to do is to define the constraints on inlining
 operations in the Toy dialect. This information is provided through a
-[dialect interface](../../Interfaces.md#dialect-interfaces). This is essentially
+[dialect interface](../../Interfaces.md/#dialect-interfaces). This is essentially
 a class containing a set of virtual hooks which the dialect can override.
 In this case, the interface is `DialectInlinerInterface`.
@@ -106,7 +106,7 @@ void ToyDialect::initialize() {
 Next, we need to provide a way for the inliner to know that `toy.generic_call`
 represents a call to a function. MLIR provides an
-[operation interface](../../Interfaces.md#operation-interfaces) that can be used
+[operation interface](../../Interfaces.md/#attributeoperationtype-interfaces) that can be used
 to mark an operation as being "call-like". Unlike dialect interfaces, operation
 interfaces provide a more refined granularity of information that is specific
 and core to a single operation. The interface that we will be adding here is the
@@ -284,7 +284,7 @@ can define an operation interface that can be specified on operations that need
 to have their result shapes inferred.
 Similarly to operations, we can also
-[define operation interfaces](../../OpDefinitions.md#operation-interfaces) using
+[define operation interfaces](../../Interfaces.md/#attributeoperationtype-interfaces) using
 the operation definition specification (ODS) framework.
 The interface is defined by inheriting from `OpInterface`, which takes the name
@@ -305,7 +305,7 @@ Next, we define the interface methods that the operations will need to provide.
 An interface method is comprised of: a description; a C++ return type in string
 form; a method name in string form; and a few optional components, depending on
 the need. See the
-[ODS documentation](../../OpDefinitions.md#operation-interfaces) for more
+[ODS documentation](../../Interfaces.md/#attributeoperationtype-interfaces) for more
@@ -342,7 +342,7 @@ void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
 At this point, each of the necessary Toy operations provide a mechanism by which
 to infer their output shapes. The ShapeInferencePass is a FunctionPass: it will
 run on each Function in isolation. MLIR also supports general
-[OperationPasses](../../PassManagement.md#operation-pass) that run on any isolated
+[OperationPasses](../../PassManagement.md/#operation-pass) that run on any isolated
 operation (i.e. other function-like operations), but here our module only
 contains functions, so there is no need to generalize to all operations.

diff  --git a/mlir/docs/Tutorials/Toy/Ch-5.md b/mlir/docs/Tutorials/Toy/Ch-5.md
index ef95fa4bb4e5b..3eecd9473a083 100644
--- a/mlir/docs/Tutorials/Toy/Ch-5.md
+++ b/mlir/docs/Tutorials/Toy/Ch-5.md
@@ -15,34 +15,35 @@ part of the program and is limited: it doesn't support representing our
 `Affine` for the computation heavy part of Toy, and in the
 [next chapter](Ch-6.md) directly target the `LLVM IR` dialect for lowering
 `print`. As part of this lowering, we will be lowering from the
-[TensorType](../../LangRef.md#tensor-type) that `Toy` operates on to the
-[MemRefType](../../LangRef.md#memref-type) that is indexed via an affine
-loop-nest. Tensors represent an abstract value-typed sequence of data, meaning
-that they don't live in any memory. MemRefs, on the other hand, represent lower
-level buffer access, as they are concrete references to a region of memory.
+[TensorType](../../Dialects/Builtin.md/#rankedtensortype) that `Toy` 
+operates on to the [MemRefType](../../Dialects/Builtin.md/#memreftype) that is 
+indexed via an affine loop-nest. Tensors represent an abstract value-typed 
+sequence of data, meaning that they don't live in any memory. MemRefs, on the
+other hand, represent lower level buffer access, as they are concrete 
+references to a region of memory.
 # Dialect Conversions
 MLIR has many 
diff erent dialects, so it is important to have a unified framework
-for [converting](../../../getting_started/Glossary.md#conversion) between them. This is where the
+for [converting](../../../getting_started/Glossary.md/#conversion) between them. This is where the
 `DialectConversion` framework comes into play. This framework allows for
 transforming a set of *illegal* operations to a set of *legal* ones. To use this
 framework, we need to provide two things (and an optional third):
-*   A [Conversion Target](../../DialectConversion.md#conversion-target)
+*   A [Conversion Target](../../DialectConversion.md/#conversion-target)
     -   This is the formal specification of what operations or dialects are
         legal for the conversion. Operations that aren't legal will require
         rewrite patterns to perform
-        [legalization](../../../getting_started/Glossary.md#legalization).
+        [legalization](../../../getting_started/Glossary.md/#legalization).
 *   A set of
-    [Rewrite Patterns](../../DialectConversion.md#rewrite-pattern-specification)
+    [Rewrite Patterns](../../DialectConversion.md/#rewrite-pattern-specification)
     -   This is the set of [patterns](../QuickstartRewrites.md) used to
         convert *illegal* operations into a set of zero or more *legal* ones.
-*   Optionally, a [Type Converter](../../DialectConversion.md#type-conversion).
+*   Optionally, a [Type Converter](../../DialectConversion.md/#type-conversion).
     -   If provided, this is used to convert the types of block arguments. We
         won't be needing this for our conversion.
@@ -96,9 +97,9 @@ additional `operands` parameter containing operands that have been
 remapped/replaced. This is used when dealing with type conversions, as the
 pattern will want to operate on values of the new type but match against the
 old. For our lowering, this invariant will be useful as it translates from the
-[TensorType](../../LangRef.md#tensor-type) currently being operated on to the
-[MemRefType](../../LangRef.md#memref-type). Let's look at a snippet of lowering
-the `toy.transpose` operation:
+[TensorType](../../Dialects/Builtin.md/#rankedtensortype) currently 
+being operated on to the [MemRefType](../../Dialects/Builtin.md/#memreftype).
+Let's look at a snippet of lowering the `toy.transpose` operation:
 /// Lower the `toy.transpose` operation to an affine loop nest.

diff  --git a/mlir/docs/Tutorials/Toy/Ch-6.md b/mlir/docs/Tutorials/Toy/Ch-6.md
index 9c5d838c447c1..2c7390cb7c87e 100644
--- a/mlir/docs/Tutorials/Toy/Ch-6.md
+++ b/mlir/docs/Tutorials/Toy/Ch-6.md
@@ -16,7 +16,7 @@ lowered all but one of the `toy` operations, with the last being `toy.print`.
 Before going over the conversion to LLVM, let's lower the `toy.print` operation.
 We will lower this operation to a non-affine loop nest that invokes `printf` for
 each element. Note that, because the dialect conversion framework supports
-[transitive lowering](../../../getting_started/Glossary.md#transitive-lowering), we don't need to
+[transitive lowering](../../../getting_started/Glossary.md/#transitive-lowering), we don't need to
 directly emit operations in the LLVM dialect. By transitive lowering, we mean
 that the conversion framework may apply multiple patterns to fully legalize an
 operation. In this example, we are generating a structured loop nest instead of
@@ -87,7 +87,7 @@ used for lowering. At this point in the compilation process, we have a
 combination of `toy`, `affine`, and `std` operations. Luckily, the `std` and
 `affine` dialects already provide the set of patterns needed to transform them
 into LLVM dialect. These patterns allow for lowering the IR in multiple stages
-by relying on [transitive lowering](../../../getting_started/Glossary.md#transitive-lowering).
+by relying on [transitive lowering](../../../getting_started/Glossary.md/#transitive-lowering).
   mlir::RewritePatternSet patterns(&getContext());
@@ -318,7 +318,7 @@ $ echo 'def main() { print([[1, 2], [3, 4]]); }' | ./bin/toyc-ch6 -emit=jit
 You can also play with `-emit=mlir`, `-emit=mlir-affine`, `-emit=mlir-llvm`, and
 `-emit=llvm` to compare the various levels of IR involved. Also try options like
-[`--print-ir-after-all`](../../PassManagement.md#ir-printing) to track the
+[`--print-ir-after-all`](../../PassManagement.md/#ir-printing) to track the
 evolution of the IR throughout the pipeline.
 The example code used throughout this section can be found in 

diff  --git a/mlir/docs/Tutorials/Toy/Ch-7.md b/mlir/docs/Tutorials/Toy/Ch-7.md
index 8dcf47e969e3b..0a99ac2fae88d 100644
--- a/mlir/docs/Tutorials/Toy/Ch-7.md
+++ b/mlir/docs/Tutorials/Toy/Ch-7.md
@@ -62,7 +62,7 @@ representation.
 #### Defining the Type Class
-As mentioned in [chapter 2](Ch-2.md), [`Type`](../../LangRef.md#type-system)
+As mentioned in [chapter 2](Ch-2.md), [`Type`](../../LangRef.md/#type-system)
 objects in MLIR are value-typed and rely on having an internal storage object
 that holds the actual data for the type. The `Type` class in itself acts as a
 simple wrapper around an internal `TypeStorage` object that is uniqued within an
@@ -72,7 +72,7 @@ constructing and uniquing an instance of a storage class.
 When defining a new `Type` that contains parametric data (e.g. the `struct`
 type, which requires additional information to hold the element types), we will
 need to provide a derived storage class. The `singleton` types that don't have
-any additional data (e.g. the [`index` type](../../Dialects/Builtin.md#indextype)) don't
+any additional data (e.g. the [`index` type](../../Dialects/Builtin.md/#indextype)) don't
 require a storage class and use the default `TypeStorage`.
 ##### Defining the Storage Class
@@ -235,7 +235,7 @@ These methods take an instance of a high-level parser or printer that allows for
 easily implementing the necessary functionality. Before going into the
 implementation, let's think about the syntax that we want for the `struct` type
 in the printed IR. As described in the
-[MLIR language reference](../../LangRef.md#dialect-types), dialect types are
+[MLIR language reference](../../LangRef.md/#dialect-types), dialect types are
 generally represented as: `! dialect-namespace < type-data >`, with a pretty
 form available under certain circumstances. The responsibility of our `Toy`
 parser and printer is to provide the `type-data` bits. We will define our
@@ -359,7 +359,7 @@ that will provide more specific handling of `structs`.
 ##### `toy.struct_constant`
 This new operation materializes a constant value for a struct. In our current
-modeling, we just use an [array attribute](../../LangRef.md#array-attribute)
+modeling, we just use an [array attribute](../../Dialects/Builtin.md/#arrayattr)
 that contains a set of constant values for each of the `struct` elements.

diff  --git a/mlir/docs/Tutorials/Toy/_index.md b/mlir/docs/Tutorials/Toy/_index.md
index 696bb37d19c4e..c93eae3fa52f7 100644
--- a/mlir/docs/Tutorials/Toy/_index.md
+++ b/mlir/docs/Tutorials/Toy/_index.md
@@ -2,7 +2,7 @@
 This tutorial runs through the implementation of a basic toy language on top of
 MLIR. The goal of this tutorial is to introduce the concepts of MLIR; in
-particular, how [dialects](../../LangRef.md#dialects) can help easily support
+particular, how [dialects](../../LangRef.md/#dialects) can help easily support
 language specific constructs and transformations while still offering an easy
 path to lower to LLVM or other codegen infrastructure. This tutorial is based on
 the model of the
@@ -13,7 +13,7 @@ from the 2020 LLVM Dev Conference ([slides](https://llvm.org/devmtg/2020-09/slid
 This tutorial assumes you have cloned and built MLIR; if you have not yet done
 so, see
-[Getting started with MLIR](https://mlir.llvm.org/getting_started/).
+[Getting started with MLIR](../../../getting_started/).
 This tutorial is divided in the following chapters:

diff  --git a/mlir/docs/Tutorials/UnderstandingTheIRStructure.md b/mlir/docs/Tutorials/UnderstandingTheIRStructure.md
index 3b32d6a409715..41f5c7ee41189 100644
--- a/mlir/docs/Tutorials/UnderstandingTheIRStructure.md
+++ b/mlir/docs/Tutorials/UnderstandingTheIRStructure.md
@@ -1,11 +1,11 @@
 # Understanding the IR Structure
 The MLIR Language Reference describes the
-[High Level Structure](../LangRef/#high-level-structure), this document
+[High Level Structure](../LangRef.md/#high-level-structure), this document
 illustrates this structure through examples, and introduces at the same time the
 C++ APIs involved in manipulating it.
-We will implement a [pass](../PassManagement/#operation-pass) that traverses any
+We will implement a [pass](../PassManagement.md/#operation-pass) that traverses any
 MLIR input and prints the entity inside the IR. A pass (or in general almost any
 piece of IR) is always rooted with an operation. Most of the time the top-level
 operation is a `ModuleOp`, the MLIR `PassManager` is actually limited to
@@ -217,7 +217,7 @@ does not satisfy a criteria:
 Another relationship in the IR is the one that links a `Value` with its users.
 As defined in the
-[language reference](https://mlir.llvm.org/docs/LangRef/#high-level-structure),
+[language reference](../LangRef.md/#high-level-structure),
 each Value is either a `BlockArgument` or the result of exactly one `Operation`
 (an `Operation` can have multiple results, each of them is a separate `Value`).
 The users of a `Value` are `Operation`s, through their arguments: each


More information about the Mlir-commits mailing list