SkillAgentSearch skills...

Godbolt.nvim

Simple godbolt-like functionality for vim

Install / Use

/learn @lanza/Godbolt.nvim
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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.

asciicast

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++ compilation
  • swiftc for 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-llvm when using compile_commands.json
  • output = "asm": Uses assembly output (default for clang)
  • output = "auto": No injection, uses compile_commands.json flags as-is
  • Default for :Godbolt command: "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:

  • .ll files: Use custom pass lists or O-levels
  • .c/.cpp files: 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 cursor
  • o - Toggle fold/unfold for groups (▸ → ▾)
  • q - Quit the pipeline viewer
  • g[ - Jump to first pass
  • g] - Jump to last pass

In the before/after panes:

  • ]p / [p or Tab / Shift-Tab - Next/Previous pass
  • Standard diff commands (]c, [c for next/previous diff)

Pipeline Viewer Features:

  • Smart Grouping: Function/CGSCC passes are grouped together
    • Groups display as ▸ [F] PassName (N functions) when folded
    • Press o or Enter to unfold and see individual functions
    • Module passes ([M]) automatically close all open groups
    • Interleaved passes are correctly merged into groups
  • Auto-Unfold Navigation: Tab automatically 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

View on GitHub
GitHub Stars7
CategoryDevelopment
Updated2mo ago
Forks0

Languages

Lua

Security Score

70/100

Audited on Jan 22, 2026

No findings