mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 02:57:46 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 730da698a3 | |||
| 073862ee92 | |||
| c820d83ae2 |
@@ -108,7 +108,7 @@ jobs:
|
|||||||
- image: golang:1.25-bullseye
|
- image: golang:1.25-bullseye
|
||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "21"
|
llvm: "20"
|
||||||
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, 21]
|
version: [16, 17, 18, 19, 20]
|
||||||
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 == 21
|
if: matrix.version == 20
|
||||||
run: go install
|
run: go install
|
||||||
- name: Check binary
|
- name: Check binary
|
||||||
if: matrix.version == 21
|
if: matrix.version == 20
|
||||||
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-21 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 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-21-dev \
|
llvm-20-dev \
|
||||||
clang-21 \
|
clang-20 \
|
||||||
libclang-21-dev \
|
libclang-20-dev \
|
||||||
lld-21
|
lld-20
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ 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 && llvm20
|
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
|
||||||
|
|
||||||
package cgo
|
package cgo
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
//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,7 +84,6 @@ 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
|
||||||
@@ -136,13 +135,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-9
@@ -139,7 +139,8 @@ 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).
|
||||||
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
nocapture := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
||||||
|
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +153,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.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
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.
|
||||||
@@ -174,25 +175,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.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
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.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
case "runtime.stringFromBytes":
|
case "runtime.stringFromBytes":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
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.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
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.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
||||||
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" {
|
||||||
@@ -227,9 +228,11 @@ 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, c.nocaptureAttr)
|
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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-20250916101410-63740cfada08
|
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74
|
||||||
)
|
)
|
||||||
|
|
||||||
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-20250916101410-63740cfada08 h1:vvEVYF4Qb38C25U8Ae/1QUWlCSp4pIE0PR+/BwNPvBU=
|
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
// runtime instead of at compile time. But we need to
|
// runtime instead of at compile time. But we need to
|
||||||
// revert any changes made by the call first.
|
// revert any changes made by the call first.
|
||||||
if r.debug {
|
if r.debug {
|
||||||
fmt.Fprintln(os.Stderr, indent+"!! revert because of error:", callErr.Err)
|
fmt.Fprintln(os.Stderr, indent+"!! revert because of error:", callErr.Error())
|
||||||
}
|
}
|
||||||
callMem.revert()
|
callMem.revert()
|
||||||
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
|
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ const (
|
|||||||
P09 Pin = 9
|
P09 Pin = 9
|
||||||
P10 Pin = 10
|
P10 Pin = 10
|
||||||
P11 Pin = 11
|
P11 Pin = 11
|
||||||
P12 Pin = 12
|
P12 Pin = 12 // peripherals: I2C0 SDA
|
||||||
P13 Pin = 13
|
P13 Pin = 13 // peripherals: I2C0 SCL
|
||||||
P14 Pin = 14
|
P14 Pin = 14
|
||||||
P15 Pin = 15
|
P15 Pin = 15
|
||||||
P16 Pin = 16
|
P16 Pin = 16
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ func (b *B) ReportAllocs() {
|
|||||||
|
|
||||||
// runN runs a single benchmark for the specified number of iterations.
|
// runN runs a single benchmark for the specified number of iterations.
|
||||||
func (b *B) runN(n int) {
|
func (b *B) runN(n int) {
|
||||||
|
b.runCleanup() // start fresh in the next iteration
|
||||||
b.N = n
|
b.N = n
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
@@ -457,6 +458,7 @@ func (b *B) Run(name string, f func(b *B)) bool {
|
|||||||
// Only process sub-benchmarks, if any.
|
// Only process sub-benchmarks, if any.
|
||||||
sub.hasSub = true
|
sub.hasSub = true
|
||||||
}
|
}
|
||||||
|
defer sub.runCleanup() // make sure all cleanups are run, even when panicking
|
||||||
if sub.run1() {
|
if sub.run1() {
|
||||||
sub.run()
|
sub.run()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user