MCPcopy Create free account
hub / github.com/llir/llvm

github.com/llir/llvm @v0.3.6

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.3.6 ↗ · + Follow
1,999 symbols 5,508 edges 186 files ⚖ custom 1,795 documented · 90% 1 cross-repo links updated 20mo agov0.3.6 · 2022-08-03★ 1,27418 open issues

Browse by type

Functions 1,729 Types & classes 270
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

llvm

Build Status Coverage Status Go Report Card go.dev reference

Library for interacting with LLVM IR in pure Go.

Introduction

Installation

go get -u github.com/llir/llvm/...

Versions

Map between llir/llvm tagged releases and LLVM release versions.

Users

Usage

Input example - Parse LLVM IR assembly

Example usage in GoDoc.

// This example parses an LLVM IR assembly file and pretty-prints the data types
// of the parsed module to standard output.
package main

import (
    "log"

    "github.com/kr/pretty"
    "github.com/llir/llvm/asm"
)

func main() {
    // Parse the LLVM IR assembly file `foo.ll`.
    m, err := asm.ParseFile("foo.ll")
    if err != nil {
        log.Fatalf("%+v", err)
    }
    // Pretty-print the data types of the parsed LLVM IR module.
    pretty.Println(m)
}

Output example - Produce LLVM IR assembly

Example usage in GoDoc.

// This example produces LLVM IR code equivalent to the following C code, which
// implements a pseudo-random number generator.
//
//    int abs(int x);
//
//    int seed = 0;
//
//    // ref: https://en.wikipedia.org/wiki/Linear_congruential_generator
//    //    a = 0x15A4E35
//    //    c = 1
//    int rand(void) {
//       seed = seed*0x15A4E35 + 1;
//       return abs(seed);
//    }
package main

import (
    "fmt"

    "github.com/llir/llvm/ir"
    "github.com/llir/llvm/ir/constant"
    "github.com/llir/llvm/ir/types"
)

func main() {
    // Create convenience types and constants.
    i32 := types.I32
    zero := constant.NewInt(i32, 0)
    a := constant.NewInt(i32, 0x15A4E35) // multiplier of the PRNG.
    c := constant.NewInt(i32, 1)         // increment of the PRNG.

    // Create a new LLVM IR module.
    m := ir.NewModule()

    // Create an external function declaration and append it to the module.
    //
    //    int abs(int x);
    abs := m.NewFunc("abs", i32, ir.NewParam("x", i32))

    // Create a global variable definition and append it to the module.
    //
    //    int seed = 0;
    seed := m.NewGlobalDef("seed", zero)

    // Create a function definition and append it to the module.
    //
    //    int rand(void) { ... }
    rand := m.NewFunc("rand", i32)

    // Create an unnamed entry basic block and append it to the `rand` function.
    entry := rand.NewBlock("")

    // Create instructions and append them to the entry basic block.
    tmp1 := entry.NewLoad(i32, seed)
    tmp2 := entry.NewMul(tmp1, a)
    tmp3 := entry.NewAdd(tmp2, c)
    entry.NewStore(tmp3, seed)
    tmp4 := entry.NewCall(abs, tmp3)
    entry.NewRet(tmp4)

    // Print the LLVM IR assembly of the module.
    fmt.Println(m)
}

Analysis example - Process LLVM IR

Example usage in GoDoc.

// This example program analyses an LLVM IR module to produce a callgraph in
// Graphviz DOT format.
package main

import (
    "fmt"
    "strings"

    "github.com/llir/llvm/asm"
    "github.com/llir/llvm/ir"
)

func main() {
    // Parse LLVM IR assembly file.
    m, err := asm.ParseFile("foo.ll")
    if err != nil {
        panic(err)
    }
    // Produce callgraph of module.
    callgraph := genCallgraph(m)
    // Output callgraph in Graphviz DOT format.
    fmt.Println(callgraph)
}

// genCallgraph returns the callgraph in Graphviz DOT format of the given LLVM
// IR module.
func genCallgraph(m *ir.Module) string {
    buf := &strings.Builder{}
    buf.WriteString("digraph {\n")
    // For each function of the module.
    for _, f := range m.Funcs {
        // Add caller node.
        caller := f.Ident()
        fmt.Fprintf(buf, "\t%q\n", caller)
        // For each basic block of the function.
        for _, block := range f.Blocks {
            // For each non-branching instruction of the basic block.
            for _, inst := range block.Insts {
                // Type switch on instruction to find call instructions.
                switch inst := inst.(type) {
                case *ir.InstCall:
                    callee := inst.Callee.Ident()
                    // Add edges from caller to callee.
                    fmt.Fprintf(buf, "\t%q -> %q\n", caller, callee)
                }
            }
            // Terminator of basic block.
            switch term := block.Term.(type) {
            case *ir.TermRet:
                // do something.
                _ = term
            }
        }
    }
    buf.WriteString("}")
    return buf.String()
}

License

The llir/llvm project is dual-licensed to the public domain and under a zero-clause BSD license. You may choose either license to govern your use of llir/llvm.

Extension points exported contracts — how you extend this code

browse all types & interfaces →

Core symbols most depended-on inside this repo

browse all functions →

Shape

Method 1,316
Function 413
Struct 206
TypeAlias 41
Interface 23

Languages

Go100%

Modules by API surface

ir/metadata/specialized_metadata.go140 symbols
ir/types/types.go99 symbols
ir/constant/sumtype.go96 symbols
ir/sumtype.go81 symbols
ir/inst_conversion.go78 symbols
ir/terminator.go73 symbols
ir/inst_binary.go72 symbols
ir/helper.go72 symbols
ir/inst_other.go67 symbols
ir/constant/expr_conversion.go65 symbols
ir/constant/expr_binary.go60 symbols
asm/specialized_metadata.go44 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add llvm \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page