llvm

package module
v0.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2022 License: 0BSD, Unlicense Imports: 3 Imported by: 0

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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Example

func Example()

Types

This section is empty.

Directories

Path Synopsis
asm
Package asm implements a parser for LLVM IR assembly files.
Package asm implements a parser for LLVM IR assembly files.
cmd
internal
enc
Package enc implements encoding of identifiers for LLVM IR assembly.
Package enc implements encoding of identifiers for LLVM IR assembly.
gep
Package gep computes the result type of getelementptr instructions and constant expressions.
Package gep computes the result type of getelementptr instructions and constant expressions.
natsort
Package natsort implements natural sort.
Package natsort implements natural sort.
osutil
Package osutil implements OS utility functions.
Package osutil implements OS utility functions.
ir
Package ir declares the types used to represent LLVM IR modules.
Package ir declares the types used to represent LLVM IR modules.
constant
Package constant implements values representing immutable LLVM IR constants.
Package constant implements values representing immutable LLVM IR constants.
enum
Package enum defines enumerate types of LLVM IR.
Package enum defines enumerate types of LLVM IR.
metadata
Package metadata provides access to LLVM IR metadata.
Package metadata provides access to LLVM IR metadata.
types
Package types declares the data types of LLVM IR.
Package types declares the data types of LLVM IR.
value
Package value provides a definition of LLVM IR values.
Package value provides a definition of LLVM IR values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL