Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
llvm: [14, 15, 16, 17, 18, 19, 20]
llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -20,7 +20,6 @@ jobs:
go-version: '1.22'
# Optional step when a LLVM version is very new.
- name: Update Homebrew
if: matrix.llvm == 20
run: brew update
- name: Install LLVM
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }}
Expand All @@ -35,7 +34,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
llvm: [14, 15, 16, 17, 18, 19, 20]
llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -56,3 +55,26 @@ jobs:
if: matrix.llvm == 20
run:
go test -v
test-linux-fedora:
# Fedora uses different paths than other systems, so testing it separately.
runs-on: ubuntu-24.04
strategy:
matrix:
llvm: [19, 20, 21]
container: fedora:43
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies (default LLVM)
if: matrix.llvm == 21
run: dnf install --assumeyes g++ golang llvm-devel
- name: Install dependencies (older LLVM)
if: matrix.llvm != 21
run: dnf install --assumeyes g++ golang llvm${{ matrix.llvm }}-devel
- name: Test LLVM ${{ matrix.llvm }}
run:
go test -v -tags=llvm${{ matrix.llvm }}
- name: Test default LLVM
if: matrix.llvm == 20
run:
go test -v
47 changes: 47 additions & 0 deletions captures_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package llvm

import (
"strconv"
"strings"
"testing"
)

// TestCapturesAttribute checks that the 'captures' parameter attribute
// (which replaced the boolean 'nocapture' enum attribute starting with
// LLVM 21) round-trips through the generic enum-attribute API, and that a
// value of 0 corresponds to CaptureInfo::none(), i.e. captures(none).
func TestCapturesAttribute(t *testing.T) {
majorVersion, _ := strconv.Atoi(strings.SplitN(Version, ".", 2)[0])
if majorVersion < 21 {
t.Skip("not llvm 21")
}

ctx := NewContext()
mod := ctx.NewModule("")
defer mod.Dispose()

ptrType := PointerType(ctx.Int8Type(), 0)
ftyp := FunctionType(ctx.VoidType(), []Type{ptrType}, false)
fn := AddFunction(mod, "foo", ftyp)

kind := AttributeKindID("captures")
if kind == 0 {
t.Fatal("captures kind id not found")
}

attr := ctx.CreateEnumAttribute(kind, 0)
fn.AddAttributeAtIndex(1, attr)

got := fn.GetEnumAttributeAtIndex(1, kind)
if got.IsNil() {
t.Fatal("expected captures attribute on param 1, got nil")
}
if val := got.GetEnumValue(); val != 0 {
t.Errorf("expected captures value 0 (none), got %d", val)
}

text := mod.String()
if !strings.Contains(text, "captures(none)") {
t.Errorf("expected 'captures(none)' in output, got:\n%s", text)
}
}
23 changes: 21 additions & 2 deletions executionengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package llvm
#include <stdlib.h>
*/
import "C"
import "unsafe"
import "errors"
import (
"errors"
"unsafe"
)

func LinkInMCJIT() { C.LLVMLinkInMCJIT() }
func LinkInInterpreter() { C.LLVMLinkInInterpreter() }
Expand Down Expand Up @@ -110,6 +112,17 @@ func NewInterpreter(m Module) (ee ExecutionEngine, err error) {
return
}

func NewJITCompiler(m Module, optLevel int) (ee ExecutionEngine, err error) {
var cmsg *C.char
fail := C.LLVMCreateJITCompilerForModule(&ee.C, m.C, C.uint(optLevel), &cmsg)
if fail != 0 {
ee.C = nil
err = errors.New(C.GoString(cmsg))
C.LLVMDisposeMessage(cmsg)
}
return
}

func NewMCJITCompilerOptions() MCJITCompilerOptions {
var options C.struct_LLVMMCJITCompilerOptions
C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})))
Expand Down Expand Up @@ -159,6 +172,12 @@ func (ee ExecutionEngine) FindFunction(name string) (f Value) {
return
}

func (ee ExecutionEngine) GetFunctionAddress(name string) uint64 {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
return uint64(C.LLVMGetFunctionAddress(ee.C, cname))
}

func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer {
return C.LLVMRecompileAndRelinkFunction(ee.C, f.C)
}
Expand Down
25 changes: 12 additions & 13 deletions ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ type (
ComdatSelectionKind C.LLVMComdatSelectionKind
IntPredicate C.LLVMIntPredicate
FloatPredicate C.LLVMRealPredicate
LandingPadClause C.LLVMLandingPadClauseTy
InlineAsmDialect C.LLVMInlineAsmDialect
)

Expand Down Expand Up @@ -344,15 +343,6 @@ const (
FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue
)

//-------------------------------------------------------------------------
// llvm.LandingPadClause
//-------------------------------------------------------------------------

const (
LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch
LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter
)

//-------------------------------------------------------------------------
// llvm.InlineAsmDialect
//-------------------------------------------------------------------------
Expand Down Expand Up @@ -802,6 +792,18 @@ func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsi
func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) }
func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) }

// Operations on terminator instructions (br, switch, etc). Unlike operands,
// the number and meaning of successors has been stable across LLVM versions,
// making these a safe, version-independent way to enumerate the destination
// blocks of a switch instruction: successor 0 is the default destination,
// and successors 1..N-1 correspond to case 0..N-2 (see GetSwitchCaseValue for
// the matching case value).
func (v Value) SuccessorsCount() int { return int(C.LLVMGetNumSuccessors(v.C)) }
func (v Value) Successor(i int) (bb BasicBlock) {
bb.C = C.LLVMGetSuccessor(v.C, C.unsigned(i))
return
}

// Operations on constants of any type
func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return }
func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return }
Expand Down Expand Up @@ -928,9 +930,6 @@ func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.
func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return }
func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return }
func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return }
func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return }
func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return }
func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return }
func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return }

func ConstGEP(t Type, v Value, indices []Value) (rv Value) {
Expand Down
1 change: 0 additions & 1 deletion ir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ func TestAttributes(t *testing.T) {
"nest",
"noalias",
"nobuiltin",
"nocapture",
"noduplicate",
"noimplicitfloat",
"noinline",
Expand Down
15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm14.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm15.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm16.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm17.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm18.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm19.go

This file was deleted.

15 changes: 0 additions & 15 deletions llvm_config_darwin_llvm20.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm14.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm15.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm16.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm17.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm18.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm19.go

This file was deleted.

10 changes: 0 additions & 10 deletions llvm_config_linux_llvm20.go

This file was deleted.

Loading
Loading