mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
all: initial support for LLVM 21
This commit is contained in:
@@ -108,7 +108,7 @@ jobs:
|
|||||||
- image: golang:1.25-bullseye
|
- image: golang:1.25-bullseye
|
||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "20"
|
llvm: "21"
|
||||||
resource_class: large
|
resource_class: large
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: [16, 17, 18, 19, 20]
|
version: [16, 17, 18, 19, 20, 21]
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
@@ -141,8 +141,8 @@ jobs:
|
|||||||
- name: Check binary
|
- name: Check binary
|
||||||
run: tinygo version
|
run: tinygo version
|
||||||
- name: Build TinyGo (default LLVM)
|
- name: Build TinyGo (default LLVM)
|
||||||
if: matrix.version == 20
|
if: matrix.version == 21
|
||||||
run: go install
|
run: go install
|
||||||
- name: Check binary
|
- name: Check binary
|
||||||
if: matrix.version == 20
|
if: matrix.version == 21
|
||||||
run: tinygo version
|
run: tinygo version
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
# still works after checking out the dev branch (that is, when going from LLVM
|
# still works after checking out the dev branch (that is, when going from LLVM
|
||||||
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
||||||
|
|
||||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-21 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends -y \
|
sudo apt-get install --no-install-recommends -y \
|
||||||
llvm-20-dev \
|
llvm-21-dev \
|
||||||
clang-20 \
|
clang-21 \
|
||||||
libclang-20-dev \
|
libclang-21-dev \
|
||||||
lld-20
|
lld-21
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
// Hide a warning in LLVM 21 that doesn't apply to us (appears to be a side
|
||||||
|
// effect of how CGo processes C header files).
|
||||||
|
#cgo CFLAGS: -Wno-deprecated-declarations
|
||||||
|
|
||||||
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
|
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
|
||||||
#include <llvm/Config/llvm-config.h>
|
#include <llvm/Config/llvm-config.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
|
//go:build !byollvm && llvm20
|
||||||
|
|
||||||
package cgo
|
package cgo
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20
|
||||||
|
|
||||||
|
package cgo
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo linux CFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -I/usr/lib/llvm-21/include
|
||||||
|
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@21/include
|
||||||
|
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@21/include
|
||||||
|
#cgo freebsd CFLAGS: -I/usr/local/llvm21/include
|
||||||
|
#cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lclang
|
||||||
|
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -lclang
|
||||||
|
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -lclang
|
||||||
|
#cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lclang
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
@@ -84,6 +84,7 @@ type compilerContext struct {
|
|||||||
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
|
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
|
||||||
funcPtrAddrSpace int
|
funcPtrAddrSpace int
|
||||||
uintptrType llvm.Type
|
uintptrType llvm.Type
|
||||||
|
nocaptureAttr llvm.Attribute
|
||||||
program *ssa.Program
|
program *ssa.Program
|
||||||
diagnostics []error
|
diagnostics []error
|
||||||
functionInfos map[*ssa.Function]functionInfo
|
functionInfos map[*ssa.Function]functionInfo
|
||||||
@@ -135,6 +136,13 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
|
|||||||
c.funcPtrType = dummyFunc.Type()
|
c.funcPtrType = dummyFunc.Type()
|
||||||
dummyFunc.EraseFromParentAsFunction()
|
dummyFunc.EraseFromParentAsFunction()
|
||||||
|
|
||||||
|
// The attribute "nocapture" changed to "captures(none)" in LLVM 21.
|
||||||
|
if llvmutil.Version() < 21 {
|
||||||
|
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
||||||
|
} else {
|
||||||
|
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("captures"), 0)
|
||||||
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-12
@@ -139,8 +139,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
// not.
|
// not.
|
||||||
// (It may be safe to add the nocapture parameter to the context
|
// (It may be safe to add the nocapture parameter to the context
|
||||||
// parameter, but I'd like to stay on the safe side here).
|
// parameter, but I'd like to stay on the safe side here).
|
||||||
nocapture := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +152,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
// Mark it as noreturn so LLVM can optimize away code.
|
// Mark it as noreturn so LLVM can optimize away code.
|
||||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
||||||
case "internal/abi.NoEscape":
|
case "internal/abi.NoEscape":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
case "runtime.alloc":
|
case "runtime.alloc":
|
||||||
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
||||||
// returns values that are never null and never alias to an existing value.
|
// 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)
|
|||||||
case "runtime.sliceAppend":
|
case "runtime.sliceAppend":
|
||||||
// Appending a slice will only read the to-be-appended slice, it won't
|
// Appending a slice will only read the to-be-appended slice, it won't
|
||||||
// be modified.
|
// be modified.
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.sliceCopy":
|
case "runtime.sliceCopy":
|
||||||
// Copying a slice won't capture any of the parameters.
|
// Copying a slice won't capture any of the parameters.
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||||
case "runtime.stringFromBytes":
|
case "runtime.stringFromBytes":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.stringFromRunes":
|
case "runtime.stringFromRunes":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.trackPointer":
|
case "runtime.trackPointer":
|
||||||
// This function is necessary for tracking pointers on the stack in a
|
// This function is necessary for tracking pointers on the stack in a
|
||||||
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
||||||
// that the only thing we'll do is read the pointer.
|
// that the only thing we'll do is read the pointer.
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
||||||
if strings.Split(c.Triple, "-")[0] == "avr" {
|
if strings.Split(c.Triple, "-")[0] == "avr" {
|
||||||
@@ -228,11 +227,9 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
|
|
||||||
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
|
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
|
||||||
}
|
}
|
||||||
nocaptureKind := llvm.AttributeKindID("nocapture")
|
|
||||||
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
|
|
||||||
for i, typ := range paramTypes {
|
for i, typ := range paramTypes {
|
||||||
if typ.TypeKind() == llvm.PointerTypeKind {
|
if typ.TypeKind() == llvm.PointerTypeKind {
|
||||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ require (
|
|||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.30.0
|
||||||
golang.org/x/tools v0.30.0
|
golang.org/x/tools v0.30.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -58,5 +58,5 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8=
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08 h1:vvEVYF4Qb38C25U8Ae/1QUWlCSp4pIE0PR+/BwNPvBU=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||||
|
|||||||
Reference in New Issue
Block a user