Skip to content

Commit 3ff74f8

Browse files
committed
all: initial support for LLVM 21
1 parent 109e076 commit 3ff74f8

File tree

11 files changed

+53
-29
lines changed

11 files changed

+53
-29
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
- image: golang:1.25-bullseye
109109
steps:
110110
- test-linux:
111-
llvm: "20"
111+
llvm: "21"
112112
resource_class: large
113113

114114
workflows:

.github/workflows/build-macos.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ jobs:
117117
runs-on: macos-latest
118118
strategy:
119119
matrix:
120-
version: [16, 17, 18, 19, 20]
120+
version: [16, 17, 18, 19, 20, 21]
121121
steps:
122122
- name: Set up Homebrew
123123
uses: Homebrew/actions/setup-homebrew@master
@@ -141,8 +141,8 @@ jobs:
141141
- name: Check binary
142142
run: tinygo version
143143
- name: Build TinyGo (default LLVM)
144-
if: matrix.version == 20
144+
if: matrix.version == 21
145145
run: go install
146146
- name: Check binary
147-
if: matrix.version == 20
147+
if: matrix.version == 21
148148
run: tinygo version

.github/workflows/sizediff-install-pkgs.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
# still works after checking out the dev branch (that is, when going from LLVM
33
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
44

5-
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm.list
5+
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-21 main' | sudo tee /etc/apt/sources.list.d/llvm.list
66
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
77
sudo apt-get update
88
sudo apt-get install --no-install-recommends -y \
9-
llvm-20-dev \
10-
clang-20 \
11-
libclang-20-dev \
12-
lld-20
9+
llvm-21-dev \
10+
clang-21 \
11+
libclang-21-dev \
12+
lld-21

cgo/libclang.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ import (
2121
)
2222

2323
/*
24+
// Hide a warning in LLVM 21 that doesn't apply to us (appears to be a side
25+
// effect of how CGo processes C header files).
26+
#cgo CFLAGS: -Wno-deprecated-declarations
27+
2428
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
2529
#include <llvm/Config/llvm-config.h>
2630
#include <stdlib.h>

cgo/libclang_config_llvm20.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
1+
//go:build !byollvm && llvm20
22

33
package cgo
44

cgo/libclang_config_llvm21.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20
2+
3+
package cgo
4+
5+
/*
6+
#cgo linux CFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -I/usr/lib/llvm-21/include
7+
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@21/include
8+
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@21/include
9+
#cgo freebsd CFLAGS: -I/usr/local/llvm21/include
10+
#cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lclang
11+
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -lclang
12+
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -lclang
13+
#cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lclang
14+
*/
15+
import "C"

compiler/compiler.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type compilerContext struct {
8484
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
8585
funcPtrAddrSpace int
8686
uintptrType llvm.Type
87+
nocaptureAttr llvm.Attribute
8788
program *ssa.Program
8889
diagnostics []error
8990
functionInfos map[*ssa.Function]functionInfo
@@ -135,6 +136,13 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
135136
c.funcPtrType = dummyFunc.Type()
136137
dummyFunc.EraseFromParentAsFunction()
137138

139+
// The attribute "nocapture" changed to "captures(none)" in LLVM 21.
140+
if llvmutil.Version() < 21 {
141+
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
142+
} else {
143+
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("captures"), 0)
144+
}
145+
138146
return c
139147
}
140148

compiler/symbol.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
139139
// not.
140140
// (It may be safe to add the nocapture parameter to the context
141141
// parameter, but I'd like to stay on the safe side here).
142-
nocapture := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
143-
llvmFn.AddAttributeAtIndex(i+1, nocapture)
142+
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
144143
}
145144
}
146145

@@ -153,7 +152,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
153152
// Mark it as noreturn so LLVM can optimize away code.
154153
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
155154
case "internal/abi.NoEscape":
156-
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
155+
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
157156
case "runtime.alloc":
158157
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
159158
// returns values that are never null and never alias to an existing value.
@@ -175,25 +174,25 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
175174
case "runtime.sliceAppend":
176175
// Appending a slice will only read the to-be-appended slice, it won't
177176
// be modified.
178-
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
177+
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
179178
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
180179
case "runtime.sliceCopy":
181180
// Copying a slice won't capture any of the parameters.
182181
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
183-
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
182+
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
184183
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
185-
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
184+
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
186185
case "runtime.stringFromBytes":
187-
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
186+
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
188187
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
189188
case "runtime.stringFromRunes":
190-
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
189+
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
191190
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
192191
case "runtime.trackPointer":
193192
// This function is necessary for tracking pointers on the stack in a
194193
// portable way (see gc_stack_portable.go). Indicate to the optimizer
195194
// that the only thing we'll do is read the pointer.
196-
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
195+
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
197196
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
198197
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
199198
if strings.Split(c.Triple, "-")[0] == "avr" {
@@ -228,11 +227,9 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
228227

229228
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
230229
}
231-
nocaptureKind := llvm.AttributeKindID("nocapture")
232-
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
233230
for i, typ := range paramTypes {
234231
if typ.TypeKind() == llvm.PointerTypeKind {
235-
llvmFn.AddAttributeAtIndex(i+1, nocapture)
232+
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
236233
}
237234
}
238235
}

flake.nix

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@
4848
buildInputs = [
4949
# These dependencies are required for building tinygo (go install).
5050
go
51-
llvmPackages_20.llvm
52-
llvmPackages_20.libclang
51+
llvmPackages_21.llvm
52+
llvmPackages_21.libclang
5353
# Additional dependencies needed at runtime, for building and/or
5454
# flashing.
55-
llvmPackages_20.lld
55+
llvmPackages_21.lld
5656
avrdude
5757
binaryen
5858
# Additional dependencies needed for on-chip debugging.
@@ -68,7 +68,7 @@
6868
export MD5SUM=md5sum
6969
7070
# Ugly hack to make the Clang resources directory available.
71-
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_20.clang.cc.lib}/lib/clang/20\" -tags=llvm20"
71+
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_21.clang.cc.lib}/lib/clang/21\""
7272
'';
7373
};
7474
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ require (
1818
golang.org/x/sys v0.30.0
1919
golang.org/x/tools v0.30.0
2020
gopkg.in/yaml.v2 v2.4.0
21-
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74
21+
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08
2222
)
2323

2424
require (

0 commit comments

Comments
 (0)