Godbolt.nvim
Simple godbolt-like functionality for vim
Install / Use
/learn @lanza/Godbolt.nvimREADME
godbolt.nvim
A powerful Neovim plugin that brings Compiler Explorer (godbolt.org) functionality directly into your editor. Compile your code to assembly, LLVM IR, or other intermediate representations in a split window, with bidirectional line mapping and LLVM optimization pipeline visualization.
Features
- Multi-format output: Assembly, LLVM IR, ClangIR, AST dumps, and object files
- Bidirectional line mapping: Click on source code to highlight corresponding assembly/IR, and vice versa
- LLVM pipeline viewer: Step through optimization passes for both C/C++ files and LLVM IR
- Link-Time Optimization (LTO): Compile and link multiple files with whole-program optimization
- LTO pipeline visualization: Watch cross-module optimizations in action (70+ passes)
- Multi-language support: C, C++, Swift, and LLVM IR
- Per-file compiler arguments: Use comments to specify flags per file
- Automatic output detection: Intelligently detects output type from compiler flags
- Clean output: Separates warnings/errors from the main output buffer
Quick Start
-- 1. Install the plugin using your package manager
{
'lanza/godbolt.nvim',
config = function()
require('godbolt').setup()
end,
}
-- 2. Open a C/C++ file and run
:Godbolt -O2
-- 3. To see LLVM optimization passes (C/C++ files):
:GodboltPipeline O2
-- 4. For multi-file Link-Time Optimization:
:GodboltLTO main.c utils.c
:GodboltLTOPipeline main.c utils.c -O2
-- Or for .ll files with custom passes:
:!clang -S -emit-llvm -O0 -Xclang -disable-O0-optnone % -o %:r.ll
:edit %:r.ll
:GodboltPipeline mem2reg,instcombine
Installation
Using lazy.nvim:
{
'lanza/godbolt.nvim',
config = function()
require('godbolt').setup({
-- Your configuration here (see Configuration section below)
})
end,
}
Using packer.nvim:
use {
'lanza/godbolt.nvim',
config = function()
require('godbolt').setup()
end
}
Requirements:
- Neovim 0.7+
clang/clang++for C/C++ compilationswiftcfor Swift compilation (optional)opt(LLVM optimizer) for LLVM IR optimization and pipeline viewer (optional)
Lua API
All commands have corresponding Lua functions that accept an options table for programmatic control:
local gb = require('godbolt')
-- Basic compilation with output preference
gb.godbolt("", { output = "llvm" }) -- Force LLVM IR output
gb.godbolt("", { output = "asm" }) -- Force assembly output
gb.godbolt("", { output = "auto" }) -- Auto-detect (default)
-- LTO functions (always output LLVM IR)
gb.godbolt_lto(nil, "", { output = "llvm" }) -- Auto-detect files
gb.godbolt_lto({"main.c", "util.c"}, "-O2", { output = "llvm" })
gb.godbolt_lto_pipeline(nil, "-O2", { output = "llvm" })
gb.godbolt_lto_compare(nil, "-O3", { output = "llvm" })
Output Preference Behavior:
output = "llvm": Auto-injects-emit-llvmwhen using compile_commands.jsonoutput = "asm": Uses assembly output (default for clang)output = "auto": No injection, uses compile_commands.json flags as-is- Default for
:Godboltcommand:"llvm"(most useful for code inspection) - Default for LTO commands:
"llvm"(LTO always outputs LLVM IR)
When output = "llvm" is set and compile_commands.json is used, the plugin will automatically add -emit-llvm to the compiler flags unless you explicitly specify -emit-* or -S in your arguments.
Configuration
Configure the plugin in your init.lua:
require('godbolt').setup({
-- Compiler paths (optional, uses these defaults)
clang = 'clang',
swiftc = 'swiftc',
opt = 'opt',
-- Default compiler arguments
cpp_args = '-std=c++20',
c_args = '-std=c17',
swift_args = '',
ll_args = '',
-- Window configuration (optional)
-- window_cmd = 'split' -- instead of default 'vertical botright new'
-- Line mapping configuration (Godbolt-style source-to-assembly mapping)
line_mapping = {
enabled = true, -- Enable automatic line mapping
auto_scroll = false, -- Auto-scroll windows when cursor moves (only scrolls if off-screen)
throttle_ms = 150, -- Throttle cursor updates (ms) for performance
silent_on_failure = false, -- Show error messages if debug info is missing
show_compilation_cmd = true, -- Show compilation command when debug info fails
},
-- Display configuration
display = {
strip_debug_metadata = true, -- Hide debug metadata (!123 = !{...}) in LLVM IR
annotate_variables = true, -- Show variable names as comments (e.g., "; %5 = x")
},
-- Pipeline viewer configuration
pipeline = {
enabled = true, -- Enable pipeline viewer
show_stats = true, -- Show instruction and basic block statistics
start_at_final = false, -- Start at first pass instead of final result
filter_unchanged = false, -- Filter out passes that don't change the IR
-- Optimization remarks configuration (OFF by default)
remarks = false, -- Set to true to enable all categories
-- OR granular control:
-- remarks = {
-- pass = true, -- ✓ Show successful optimizations
-- missed = true, -- ✗ Show missed opportunities
-- analysis = false, -- ℹ Show detailed analysis (verbose)
-- filter = "inline", -- Regex filter for which passes (default: "inline")
-- },
},
})
All fields are optional and will use sensible defaults if not specified.
Commands
Basic Compilation
:Godbolt [compiler-args]
Compiles the current file to assembly/IR in a new split window.
Auto-Detection from compile_commands.json:
If you run :Godbolt without arguments, it will automatically use compiler flags from compile_commands.json for the current file if found:
" Auto-detect compiler flags from compile_commands.json
:Godbolt
" Or manually specify flags (overrides compile_commands.json)
:Godbolt -O3 -march=native
The plugin extracts flags like -O2, -std=c++20, -I, -D from your build system configuration and applies them automatically.
Examples:
:Godbolt " Auto-detect flags or basic compilation
:Godbolt -O3 " With optimization
:Godbolt -O2 -march=native
:Godbolt -emit-llvm " Output LLVM IR instead of assembly
:Godbolt -emit-cir " Output ClangIR (MLIR)
Pipeline Viewer
:GodboltPipeline [passes]
Runs LLVM optimization passes and opens an interactive 3-pane viewer showing each pass's transformations.
Supported file types:
.llfiles: Use custom pass lists or O-levels.c/.cppfiles: Use O-levels only (O0, O1, O2, O3)
Examples:
" For C/C++ files - view frontend optimization passes
:GodboltPipeline O2 " Use O2 optimization level
:GodboltPipeline O3 " Use O3 optimization level
" For .ll files - use custom passes or O-levels
:GodboltPipeline " Use default O2 pipeline
:GodboltPipeline O3 " Use O3 optimization level
:GodboltPipeline mem2reg,instcombine " Run specific passes
" Workflow for custom passes on C/C++ code:
" 1. First compile to LLVM IR with O0
:Godbolt -emit-llvm -O0 -Xclang -disable-O0-optnone
" 2. Then run custom passes on the .ll file
:edit %:r.ll
:GodboltPipeline mem2reg,sroa,instcombine
Note: For C/C++ files, custom pass lists are not supported due to clang's compilation model. Compile to .ll first if you need custom passes.
Pass Scope Indicators:
The pipeline viewer shows scope indicators for each pass:
- [M] - Module pass: operates on the entire module (all functions, globals)
- [F] - Function pass: operates on a single function
- [C] - CGSCC pass: operates on a call graph strongly-connected component
Module passes show the full module before/after, while function passes show only the specific function being optimized.
Pipeline Navigation Commands:
:NextPass- Navigate to the next optimization pass:PrevPass- Navigate to the previous optimization pass:GotoPass [N]- Jump to pass number N (or show picker if N omitted):FirstPass- Jump to the first pass:LastPass- Jump to the last pass
Keybindings in Pipeline Viewer:
In the pass list pane:
j/k- Navigate through all visible lines (modules, group headers, function entries)Tab/Shift-Tab- Jump to next/previous changed pass (auto-unfolds groups)Enter- Select and view the pass/function under cursoro- Toggle fold/unfold for groups (▸ → ▾)q- Quit the pipeline viewerg[- Jump to first passg]- Jump to last pass
In the before/after panes:
]p/[porTab/Shift-Tab- Next/Previous pass- Standard diff commands (
]c,[cfor next/previous diff)
Pipeline Viewer Features:
- Smart Grouping: Function/CGSCC passes are grouped together
- Groups display as
▸ [F] PassName (N functions)when folded - Press
oorEnterto unfold and see individual functions - Module passes (
[M]) automatically close all open groups - Interleaved passes are correctly merged into groups
- Groups display as
- Auto-Unfold Navigation:
Tabautomatically unfolds groups when navigating to changed passes - Sorted Functions: Within each group, changed functions appear first
- Visual Indicators:
>marks the currently selected pass/function●marks the selected function entry within an unfolded group- Changed passes/functions are highlighted in color
- Unchanged passes/functions are grayed out
- All Groups Start Folded: Even groups with 1000+ functions start folded for usability
Optimization Remarks (Optional)
LLVM optimization remarks provide detailed information about optimization decisions made by the compiler. This is useful for und
