| # MLIR : Language Server Protocol | |
| [TOC] | |
| This document describes the tools and utilities related to supporting | |
| [LSP](https://microsoft.github.io/language-server-protocol/) IDE language | |
| extensions for various MLIR-related languages. An LSP language extension is | |
| generally comprised of two components; a language client and a language server. | |
| A language client is a piece of code that interacts with the IDE that you are | |
| using, such as VSCode. A language server acts as the backend for queries that | |
| the client may want to perform, such as "Find Definition", "Find References", | |
| etc. | |
| ## MLIR LSP Language Server : `mlir-lsp-server` | |
| MLIR provides an implementation of an LSP language server for `.mlir` text files | |
| in the form of the `mlir-lsp-server` tool. This tool interacts with the MLIR C++ | |
| API to support rich language queries, such as "Find Definition". | |
| ### Supporting custom dialects | |
| `mlir-lsp-server`, like many other MLIR based tools, relies on having the | |
| appropriate dialects registered to be able to parse in the custom assembly | |
| formats used in the textual .mlir files. The `mlir-lsp-server` found within the | |
| main MLIR repository provides support for all of the upstream MLIR dialects. | |
| Downstream and out-of-tree users will need to provide a custom | |
| `mlir-lsp-server` executable that registers the entities that they are | |
| interested in. The implementation of `mlir-lsp-server` is provided as a library, | |
| making it easy for downstream users to register their dialect and simply | |
| call into the main implementation. A simple example is shown below: | |
| ```c++ | |
| #include "mlir/Tools/mlir-lsp-server/MlirLspServerMain.h" | |
| int main(int argc, char **argv) { | |
| mlir::DialectRegistry registry; | |
| registerMyDialects(registry); | |
| return mlir::failed(mlir::MlirLspServerMain(argc, argv, registry)); | |
| } | |
| ``` | |
| See the [Editor Plugins](#editor-plugins) section below for details on how to | |
| setup support in a few known LSP clients, such as vscode. | |
| ### Features | |
| This section details a few of the features that the MLIR language server | |
| provides. The screenshots are shown in [VSCode](https://code.visualstudio.com/), | |
| but the exact feature set available will depend on your editor client. | |
| [mlir features]: # | |
| #### Diagnostics | |
| The language server actively runs verification on the IR as you type, showing | |
| any generated diagnostics in-place. | |
|  | |
| ##### Automatically insert `expected-` diagnostic checks | |
| MLIR provides | |
| [infrastructure](https://mlir.llvm.org/docs/Diagnostics/#sourcemgr-diagnostic-verifier-handler) | |
| for checking expected diagnostics, which is heavily utilized when defining IR | |
| parsing and verification. The language server provides code actions for | |
| automatically inserting the checks for diagnostics it knows about. | |
|  | |
| #### Code completion | |
| The language server provides suggestions as you type, offering completions for | |
| dialect constructs (such as attributes, operations, and types), block names, SSA | |
| value names, keywords, and more. | |
|  | |
| #### Cross-references | |
| Cross references allow for navigating the use/def chains of SSA values (i.e. | |
| operation results and block arguments), [Symbols](../SymbolsAndSymbolTables.md), | |
| and Blocks. | |
| ##### Find definition | |
| Jump to the definition of the IR entity under the cursor. A few examples are | |
| shown below: | |
| - SSA Values | |
|  | |
| - Symbol References | |
|  | |
| The definition of an operation will also take into account the source location | |
| attached, allowing for navigating into the source file that generated the | |
| operation. | |
|  | |
| ##### Find references | |
| Show all references of the IR entity under the cursor. | |
|  | |
| #### Hover | |
| Hover over an IR entity to see more information about it. The exact information | |
| displayed is dependent on the type of IR entity under the cursor. For example, | |
| hovering over an `Operation` may show its generic format. | |
|  | |
| #### Navigation | |
| The language server will also inform the editor about the structure of symbol | |
| tables within the IR. This allows for jumping directly to the definition of a | |
| symbol, such as a `func.func`, within the file. | |
|  | |
| #### Bytecode Editing and Inspection | |
| The language server provides support for interacting with MLIR bytecode files, | |
| enabling IDEs to transparently view and edit bytecode files in the same way | |
| as textual `.mlir` files. | |
|  | |
| ## PDLL LSP Language Server : `mlir-pdll-lsp-server` | |
| MLIR provides an implementation of an LSP language server for `.pdll` text files | |
| in the form of the `mlir-pdll-lsp-server` tool. This tool interacts with the | |
| PDLL C++ API to support rich language queries, such as code completion and "Find | |
| Definition". | |
| ### Compilation Database | |
| Similarly to | |
| [`clangd`](https://clang.llvm.org/docs/JSONCompilationDatabase.html), and | |
| language servers for various other programming languages, the PDLL language | |
| server relies on a compilation database to provide build-system information for | |
| `.pdll` files. This information includes, for example, the include directories | |
| available for that file. This database allows for the server to interact with | |
| `.pdll` files using the same configuration as when building. | |
| #### Format | |
| A PDLL compilation database is a YAML file, conventionally named | |
| `pdll_compile_commands.yml`, that contains a set of `FileInfo` documents | |
| providing information for individiual `.pdll` files. | |
| Example: | |
| ```yaml | |
| --- !FileInfo: | |
| filepath: "/home/user/llvm/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.pdll" | |
| includes: "/home/user/llvm/mlir/lib/Dialect/Arith/IR;/home/user/llvm/mlir/include" | |
| ``` | |
| - filepath: <string> - Absolute file path of the file. | |
| - includes: <string> - Semi-colon delimited list of absolute include | |
| directories. | |
| #### Build System Integration | |
| Per convention, PDLL compilation databases should be named | |
| `pdll_compile_commands.yml` and placed at the top of the build directory. When | |
| using CMake and `mlir_pdll`, a compilation database is generally automatically | |
| built and placed in the appropriate location. | |
| ### Features | |
| This section details a few of the features that the PDLL language server | |
| provides. The screenshots are shown in [VSCode](https://code.visualstudio.com/), | |
| but the exact feature set available will depend on your editor client. | |
| [pdll features]: # | |
| #### Diagnostics | |
| The language server actively runs verification as you type, showing any | |
| generated diagnostics in-place. | |
|  | |
| #### Code completion and signature help | |
| The language server provides suggestions as you type based on what constraints, | |
| rewrites, dialects, operations, etc are available in this context. The server | |
| also provides information about the structure of constraint and rewrite calls, | |
| operations, and more as you fill them in. | |
|  | |
| #### Cross-references | |
| Cross references allow for navigating the code base. | |
| ##### Find definition | |
| Jump to the definition of a symbol under the cursor: | |
|  | |
| If ODS information is available, we can also jump to the definition of operation | |
| names and more: | |
|  | |
| ##### Find references | |
| Show all references of the symbol under the cursor. | |
|  | |
| #### Hover | |
| Hover over a symbol to see more information about it, such as its type, | |
| documentation, and more. | |
|  | |
| If ODS information is available, we can also show information directly from the | |
| operation definitions: | |
|  | |
| #### Navigation | |
| The language server will also inform the editor about the structure of symbols | |
| within the IR. | |
|  | |
| #### View intermediate output | |
| The language server provides support for introspecting various intermediate | |
| stages of compilation, such as the AST, the `.mlir` containing the generated | |
| PDL, and the generated C++ glue. This is a custom LSP extension, and is not | |
| necessarily provided by all IDE clients. | |
|  | |
| #### Inlay hints | |
| The language server provides additional information inline with the source code. | |
| Editors usually render this using read-only virtual text snippets interspersed | |
| with code. Hints may be shown for: | |
| - types of local variables | |
| - names of operand and result groups | |
| - constraint and rewrite arguments | |
|  | |
| ## TableGen LSP Language Server : `tblgen-lsp-server` | |
| MLIR provides an implementation of an LSP language server for `.td` text files | |
| in the form of the `tblgen-lsp-server` tool. This tool interacts with the | |
| TableGen C++ API to support rich language queries, such as "Find Definition". | |
| ### Compilation Database | |
| Similarly to | |
| [`clangd`](https://clang.llvm.org/docs/JSONCompilationDatabase.html), and | |
| language servers for various other programming languages, the TableGen language | |
| server relies on a compilation database to provide build-system information for | |
| `.td` files. This information includes, for example, the include directories | |
| available for that file. This database allows for the server to interact with | |
| `.td` files using the same configuration as when building. | |
| #### Format | |
| A TableGen compilation database is a YAML file, conventionally named | |
| `tablegen_compile_commands.yml`, that contains a set of `FileInfo` documents | |
| providing information for individiual `.td` files. | |
| Example: | |
| ```yaml | |
| --- !FileInfo: | |
| filepath: "/home/user/llvm/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td" | |
| includes: "/home/user/llvm/mlir/lib/Dialect/Arith/IR;/home/user/llvm/mlir/include" | |
| ``` | |
| - filepath: <string> - Absolute file path of the file. | |
| - includes: <string> - Semi-colon delimited list of absolute include | |
| directories. | |
| #### Build System Integration | |
| Per convention, TableGen compilation databases should be named | |
| `tablegen_compile_commands.yml` and placed at the top of the build directory. | |
| When using CMake and `mlir_tablegen`, a compilation database is generally | |
| automatically built and placed in the appropriate location. | |
| ### Features | |
| This section details a few of the features that the TableGen language server | |
| provides. The screenshots are shown in [VSCode](https://code.visualstudio.com/), | |
| but the exact feature set available will depend on your editor client. | |
| [tablegen features]: # | |
| #### Diagnostics | |
| The language server actively runs verification as you type, showing any | |
| generated diagnostics in-place. | |
|  | |
| #### Cross-references | |
| Cross references allow for navigating the code base. | |
| ##### Find definition | |
| Jump to the definition of a symbol under the cursor: | |
|  | |
| ##### Find references | |
| Show all references of the symbol under the cursor. | |
|  | |
| #### Hover | |
| Hover over a symbol to see more information about it, such as its type, | |
| documentation, and more. | |
|  | |
| Hovering over an overridden field will also show you information such as | |
| documentation from the base value: | |
|  | |
| ## Language Server Design | |
| The design of the various language servers provided by MLIR are effectively the | |
| same, and are largely comprised of three different components: | |
| - Communication and Transport (via JSON-RPC) | |
| - Language Server Protocol | |
| - Language-Specific Server | |
|  | |
| ### Communication and Transport | |
| The language server, such as `mlir-lsp-server`, communicates with the language | |
| client via JSON-RPC over stdin/stdout. In the code, this is the `JSONTransport` | |
| class. This class knows nothing about the Language Server Protocol, it only | |
| knows that JSON-RPC messages are coming in and JSON-RPC messages are going out. | |
| The handling of incoming and outgoing LSP messages is left to the | |
| `MessageHandler` class. This class routes incoming messages to handlers in the | |
| `Language Server Protocol` layer for interpretation, and packages outgoing | |
| messages for transport. This class also has limited knowledge of the LSP, and | |
| only has information about the three main classes of messages: notifications, | |
| calls, and replies. | |
| ### Language Server Protocol | |
| `LSPServer` handles the interpretation of the finer LSP details. This class | |
| registers handlers for LSP messages and then forwards to the | |
| [`Language-Specific Server`](#language-specific-server) for processing. The | |
| intent of this component is to hold all of the necessary glue when communicating | |
| from the LSP world to the language-specific world (e.g. MLIR, PDLL, etc.). In | |
| most cases, the LSP message handlers simply forward directly to the | |
| `Language-Specific Server`. In some cases, however, the impedance mismatch | |
| between the two requires more complicated glue code. | |
| ### Language-Specific Server | |
| The language specific server, such as `MLIRServer` or `PDLLServer`, provides the | |
| internal implementation of all of LSP queries for a specific language. These are | |
| the classes that directly interacts with the C++ API for the language, including | |
| parsing text files, interpreting definition/reference information, etc. | |
| ## Editor Plugins | |
| LSP Language plugins are available for many popular editors, and in principle | |
| the language servers provided by MLIR should work with any of them, though | |
| feature sets and interfaces may vary. Below are a set of plugins that are known | |
| to work: | |
| ### Visual Studio Code | |
| The [MLIR extension](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-mlir) | |
| provides language IDE features for [MLIR](https://mlir.llvm.org/) related | |
| languages: [MLIR](#mlir---mlir-textual-assembly-format), | |
| [PDLL](#pdll---mlir-pdll-pattern-files), and [TableGen](#td---tablegen-files) | |
| #### `.mlir` - MLIR textual assembly format: | |
| The MLIR extension adds language support for the | |
| [MLIR textual assembly format](https://mlir.llvm.org/docs/LangRef/): | |
| ##### Features | |
| - Syntax highlighting for `.mlir` files and `mlir` markdown blocks | |
| - go-to-definition and cross references | |
| - Detailed information when hovering over IR entities | |
| - Outline and navigation of symbols and symbol tables | |
| - Code completion | |
| - Live parser and verifier diagnostics | |
| [mlir-vscode features]: # | |
| ##### Setup | |
| ###### `mlir-lsp-server` | |
| The various `.mlir` language features require the | |
| [`mlir-lsp-server` language server](https://mlir.llvm.org/docs/Tools/MLIRLSP/#mlir-lsp-language-server--mlir-lsp-server). | |
| If `mlir-lsp-server` is not found within your workspace path, you must specify | |
| the path of the server via the `mlir.server_path` setting. The path of the | |
| server may be absolute or relative within your workspace. | |
| #### `.pdll` - MLIR PDLL pattern files: | |
| The MLIR extension adds language support for the | |
| [PDLL pattern language](https://mlir.llvm.org/docs/PDLL/). | |
| ##### Features | |
| - Syntax highlighting for `.pdll` files and `pdll` markdown blocks | |
| - go-to-definition and cross references | |
| - Types and documentation on hover | |
| - Code completion and signature help | |
| - View intermediate AST, MLIR, or C++ output | |
| [pdll-vscode features]: # | |
| ##### Setup | |
| ###### `mlir-pdll-lsp-server` | |
| The various `.pdll` language features require the | |
| [`mlir-pdll-lsp-server` language server](https://mlir.llvm.org/docs/Tools/MLIRLSP/#pdll-lsp-language-server--mlir-pdll-lsp-server). | |
| If `mlir-pdll-lsp-server` is not found within your workspace path, you must | |
| specify the path of the server via the `mlir.pdll_server_path` setting. The path | |
| of the server may be absolute or relative within your workspace. | |
| ###### Project setup | |
| To properly understand and interact with `.pdll` files, the language server must | |
| understand how the project is built (compile flags). | |
| [`pdll_compile_commands.yml` files](https://mlir.llvm.org/docs/Tools/MLIRLSP/#compilation-database) | |
| related to your project should be provided to ensure files are properly | |
| processed. These files can usually be generated by the build system, and the | |
| server will attempt to find them within your `build/` directory. If not | |
| available in or a unique location, additional `pdll_compile_commands.yml` files | |
| may be specified via the `mlir.pdll_compilation_databases` setting. The paths of | |
| these databases may be absolute or relative within your workspace. | |
| #### `.td` - TableGen files: | |
| The MLIR extension adds language support for the | |
| [TableGen language](https://llvm.org/docs/TableGen/ProgRef.html). | |
| ##### Features | |
| - Syntax highlighting for `.td` files and `tablegen` markdown blocks | |
| - go-to-definition and cross references | |
| - Types and documentation on hover | |
| [tablegen-vscode features]: # | |
| ##### Setup | |
| ###### `tblgen-lsp-server` | |
| The various `.td` language features require the | |
| [`tblgen-lsp-server` language server](https://mlir.llvm.org/docs/Tools/MLIRLSP/#tablegen-lsp-language-server--tblgen-lsp-server). | |
| If `tblgen-lsp-server` is not found within your workspace path, you must specify | |
| the path of the server via the `mlir.tablegen_server_path` setting. The path of | |
| the server may be absolute or relative within your workspace. | |
| ###### Project setup | |
| To properly understand and interact with `.td` files, the language server must | |
| understand how the project is built (compile flags). | |
| [`tablegen_compile_commands.yml` files](https://mlir.llvm.org/docs/Tools/MLIRLSP/#compilation-database-1) | |
| related to your project should be provided to ensure files are properly | |
| processed. These files can usually be generated by the build system, and the | |
| server will attempt to find them within your `build/` directory. If not | |
| available in or a unique location, additional `tablegen_compile_commands.yml` | |
| files may be specified via the `mlir.tablegen_compilation_databases` setting. | |
| The paths of these databases may be absolute or relative within your workspace. | |
| #### Contributing | |
| This extension is actively developed within the | |
| [LLVM monorepo](https://github.com/llvm/llvm-project), at | |
| [`mlir/utils/vscode`](https://github.com/llvm/llvm-project/tree/main/mlir/utils/vscode). | |
| As such, contributions should follow the | |
| [normal LLVM guidelines](https://llvm.org/docs/Contributing.html), with code | |
| reviews sent to | |
| [GitHub](https://llvm.org/docs/Contributing.html#how-to-submit-a-patch). | |
| When developing or deploying this extension within the LLVM monorepo, a few | |
| extra setup steps are required: | |
| - Copy `mlir/utils/textmate/mlir.json` to the extension directory and rename to | |
| `grammar.json`. | |
| - Copy `llvm/utils/textmate/tablegen.json` to the extension directory and rename | |
| to `tablegen-grammar.json`. | |
| - Copy | |
| `https://mlir.llvm.org//LogoAssets/logo/PNG/full_color/mlir-identity-03.png` | |
| to the extension directory and rename to `icon.png`. | |
| Please follow the existing code style when contributing to the extension, we | |
| recommend to run `npm run format` before sending a patch. |