LLVM IR can be difficult to read, especially for large compilations. Internally, we have been using a visualizer tool that provides interactive views of IR, CFG, various analyses, and pass pipelines. This is useful for debugging, analysis of optimization passes (why something happens or doesn’t), looking for optimization opportunities, and interactive exploration (what happens when I run pass X here? And then pass Y on the result, etc.)
We want to upstream the capabilities of our internal IR visualizer as part of the LLVM VS Code extension. LLVM currently provides a minimal extension. We’d like to integrate selected visualization features into it. To enable communication between VS Code and LLVM, we plan to introduce an LSP server for LLVM IR.
The enhanced extension will support the following:
-
Provide common LSP functionality (navigation, reference tracking, etc.)
-
Display the CFG and IR side by side with cross-navigation
-
Run any optimization pass or analysis on the given IR and display the results
-
Run a custom optimization pipeline on the given IR
-
Support large compilations
- E.g. do lazy evaluation of IRs at different pipeline stages. Doing print-after-all for large compilations can take a really long time.
-
Run entirely offline and locally
LSP
We plan to use LSP as a protocol to enable interaction between the VS Code extension and LLVM. LSP provides a lot of useful functionality “out-of-the-box” - navigation between symbols, tracking value uses, etc. Additionally, we can use LSP to run custom commands for the extension. For example, we are going to use it to request SVG files of the CFG from LLVM.
An alternative approach would be to invoke LLVM tools (e.g., opt) directly with command-line arguments. This is how our internal visualizer interacts with LLVM. It works for simple requests, but has limitations for more complicated queries. This approach requires exposing all the necessary functionality via a command-line interface. This gets cumbersome for complicated queries, such as inspecting what a specific analysis understands about an SSA value at a given instruction.
Integration Plan
-
LSP server for LLVM IR
-
Add support for tracking source location for LLVM IR constructions (Values, BasicBlocks, Functions). This is a prerequisite for many of the LSP features.
-
Add a simple LSP server as a new tool in LLVM
-
Support some basic LSP commands
-
Add a custom command to generate a CFG for a given IR
-
Add a custom command to run an arbitrary opt pass for a given IR
-
-
-
Extend the existing LLVM VS Code extension
-
Connect to the LSP server and enable some basic LSP functionality
-
Introduce a command to request the CFG from the LSP server
-
Introduce cross-navigation between the CFG and IR
-
Introduce a command to run a custom opt pass/opt pipeline
-
Highlight changes between optimization passes
-
Future work
Value Analysis
-
Show where a value originates and how it propagates through the IR.
-
Support interactive queries on a specific SSA value (e.g., which passes modified it, what analyses know about it).
Graph Visualization
-
Add dominator tree (DT) visualization similar to the existing CFG view.
-
Provide simplified CFG/DT views that omit instruction detail (block-only visualization).
-
Show visual diffs in the CFG view between optimization passes (e.g., added/removed edges or blocks).
Demo
The initial prototype of the proposed LSP server and the extended VS Code extension can be found here: GitHub - JanJecmen/llvm-project at vscode-irviz
The LSP server is located in llvm/tools/llvm-lsp
and the VS Code extension in llvm/utils/vscode/llvm
.
Easiest way to run the extension is to open src/extension.ts
in VS Code and press F5. The compile target for the LSP server is llvm-lsp-server
.