Compare commits

...
Sign in to create a new pull request.

35 commits

Author SHA1 Message Date
Maxwell G
da069d072e Rebuild for golang 1.25.2 2025-10-11 21:17:25 -05:00
Alejandro Sáez
faf08a188d rebuild 2025-10-10 15:13:25 +02:00
Elliott Sales de Andrade
20e209e6d0 Update to latest version (#2389619) 2025-08-25 03:25:16 -04:00
Maxwell G
1ba82360fb Rebuild for golang-1.25.0 2025-08-15 18:42:25 -05:00
Elliott Sales de Andrade
8526125e83 Backport support for Go 1.25 2025-08-08 19:35:38 -04:00
Elliott Sales de Andrade
dc10663dd3 Update build to use LLVM 19 2025-08-02 20:20:56 -04:00
Elliott Sales de Andrade
98fdc4179f Update to latest version (#2266297) 2025-08-02 20:20:51 -04:00
Elliott Sales de Andrade
4bdd7c5cf3 Remove older patches
- QEMU is no longer broken for the cases we need.
- The optional package suggestion was never fully implemented, so drop
  it for now.
2025-08-02 04:56:46 -04:00
Elliott Sales de Andrade
5f84d1ac7a Update to 0.34.0 2025-08-02 04:56:46 -04:00
Elliott Sales de Andrade
36b6b72c3d Update to 0.33.0 2025-08-02 04:56:46 -04:00
Elliott Sales de Andrade
b460c7c931 Improve build with non-default LLVM/Clang 2025-08-02 04:56:46 -04:00
Fedora Release Engineering
716d8be332 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-25 19:20:17 +00:00
Fedora Release Engineering
cc972cf7e5 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-19 12:52:48 +00:00
Elliott Sales de Andrade
16bb42b116 Switch to SPDX licenses 2024-10-28 01:22:53 -04:00
Miroslav Suchý
70df58fba1 convert license to SPDX
This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4
2024-09-04 22:24:17 +02:00
Fedora Release Engineering
62cfc868a2 Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-20 07:30:20 +00:00
Maxwell G
2fb69c2ae8
Rebuild for golang 1.22.0 2024-02-11 23:40:19 +00:00
Fedora Release Engineering
6bea1c34db Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-27 06:16:52 +00:00
Elliott Sales de Andrade
1539b445c8 Allow an older version of golang.org/x/tools
The requirement is really only on 0.9, as that changed some internals.
2023-11-05 00:56:46 -04:00
Elliott Sales de Andrade
9a6e0539c2 Upload compiler-rt 17 sources
[skip changelog]
2023-09-25 04:26:22 -04:00
Elliott Sales de Andrade
000c23720d Backport support for LLVM17 2023-09-25 04:23:42 -04:00
Elliott Sales de Andrade
fa5e9eb979 Update to latest version (#2240155) 2023-09-25 04:19:31 -04:00
Elliott Sales de Andrade
81c66e60d6 Remove release-specific sources
This makes it difficult to build an srpm on a different release.
2023-09-25 04:08:52 -04:00
Elliott Sales de Andrade
1eb5a805d6 Skip a broken test
[skip changelog]
2023-09-03 04:10:56 -04:00
Elliott Sales de Andrade
96c5d0d6c6 Backport patch for golang.org/x/tools 0.12.0
Also, drop some older unused patches.
2023-08-28 20:38:00 -04:00
Elliott Sales de Andrade
4d6d12da79 Upload sources and fix dependency
[skip changelog]
2023-08-27 21:03:15 -04:00
Elliott Sales de Andrade
5c81169782 Updte to latest version (#2214119) 2023-08-27 20:51:46 -04:00
Elliott Sales de Andrade
8180175230 Update to latest version (#2214119) 2023-08-07 21:07:57 -04:00
Elliott Sales de Andrade
b2c23a4f26 Remove outdated arch checks
i686 and armv7hl were removed as possible build architectures some time
ago.
2023-08-07 21:05:05 -04:00
Fedora Release Engineering
0539d75995 Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-22 16:22:44 +00:00
Elliott Sales de Andrade
694d1924a1 Upload sources
[skip changelog]
2023-04-16 16:45:29 -04:00
Elliott Sales de Andrade
b3b8eb54cc Add support for LLVM 16 2023-04-16 16:40:31 -04:00
Elliott Sales de Andrade
35a3896d93 Update to latest version (#2169260) 2023-02-25 20:42:30 -05:00
Elliott Sales de Andrade
9b16b76e2f Backport compatibility for Go 1.20 2023-01-23 03:45:52 -05:00
Fedora Release Engineering
a9b7fbae8f Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-21 05:06:19 +00:00
28 changed files with 653 additions and 7936 deletions

37
.gitignore vendored
View file

@ -1,38 +1,19 @@
/tinygo-*.tar.gz
/avr-*.tar.gz
/cmsis-*.tar.gz
/cmsis-*-clean.tar.xz
/cmsis_svd-*.tar.gz
/cmsis_svd-*-clean.tar.xz
/cmsis_svd_data-*.tar.gz
/cmsis_svd_data-*-clean.tar.xz
/compiler-rt-*.src.tar.xz
/compiler-rt-*.src.tar.xz.sig
/macos-minimal-sdk-*.tar.gz
/mingw64-*.tar.gz
/musl-*.tar.gz
/musl-*.tar.gz.asc
/net-*.tar.gz
/nrfx-*.tar.gz
/picolibc-*.tar.gz
/wasi-libc-*.tar.gz
/tinygo-0.6.0.tar.gz
/tinygo-0.7.0.tar.gz
/tinygo-0.7.1.tar.gz
/tinygo-0.8.0.tar.gz
/tinygo-0.9.0.tar.gz
/tinygo-0.10.0.tar.gz
/tinygo-0.11.0.tar.gz
/tinygo-0.12.0.tar.gz
/tinygo-0.13.0.tar.gz
/tinygo-0.13.1.tar.gz
/tinygo-0.14.0.tar.gz
/tinygo-0.14.1.tar.gz
/tinygo-0.15.0.tar.gz
/tinygo-0.16.0.tar.gz
/tinygo-0.17.0.tar.gz
/tinygo-0.18.0.tar.gz
/tinygo-0.19.0.tar.gz
/tinygo-0.20.0.tar.gz
/tinygo-0.21.0.tar.gz
/musl-1.2.2.tar.gz
/musl-1.2.2.tar.gz.asc
/tinygo-0.22.0.tar.gz
/musl-1.2.0.tar.gz
/musl-1.2.0.tar.gz.asc
/tinygo-0.23.0.tar.gz
/macos-minimal-sdk-ebb736fda2bec7cea38dcda807518b835a539525.tar.gz
/tinygo-0.25.0.tar.gz
/tinygo-0.26.0.tar.gz
/bdwgc-1166f11f7dee08d7ad369296b24cf8c9582f8789.tar.gz

View file

@ -1,38 +1,50 @@
From 6b50974a6d4972b755a35d40d87e5bdf9c97d925 Mon Sep 17 00:00:00 2001
From fdd5322026e4b7b2e7fe6a80628b7239b4c4eb99 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Tue, 15 Dec 2020 05:06:04 -0500
Subject: [PATCH 01/18] Skip WASI tests.
Subject: [PATCH 1/5] Skip WASI tests.
We do not have wasmtime available.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
main_test.go | 5 -----
1 file changed, 5 deletions(-)
main_test.go | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/main_test.go b/main_test.go
index 9ddbe52f..79ae2cf2 100644
index b07d6aaa..ae0a4482 100644
--- a/main_test.go
+++ b/main_test.go
@@ -154,10 +154,6 @@ func TestBuild(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasm", sema), tests, t)
@@ -188,22 +188,6 @@ func TestBuild(t *testing.T) {
runTest("gc.go", optionsBoehm, t, nil, nil)
})
})
- t.Run("WASI", func(t *testing.T) {
- t.Run("WASIp1", func(t *testing.T) {
- t.Parallel()
- runPlatTests(optionsFromTarget("wasi", sema), tests, t)
- runPlatTests(optionsFromTarget("wasip1", sema), tests, t)
-
- // Test with -gc=boehm.
- t.Run("gc.go-boehm", func(t *testing.T) {
- t.Parallel()
- optionsBoehm := optionsFromTarget("wasip1", sema)
- optionsBoehm.GC = "boehm"
- runTest("gc.go", optionsBoehm, t, nil, nil)
- })
- })
- t.Run("WASIp2", func(t *testing.T) {
- t.Parallel()
- runPlatTests(optionsFromTarget("wasip2", sema), tests, t)
- })
}
}
@@ -413,7 +409,6 @@ func TestTest(t *testing.T) {
if runtime.GOOS == "linux" {
@@ -925,7 +909,6 @@ func TestTest(t *testing.T) {
// Node/Wasmtime
targ{"WASM", optionsFromTarget("wasm", sema)},
- targ{"WASI", optionsFromTarget("wasi", sema)},
- targ{"WASI", optionsFromTarget("wasip1", sema)},
)
}
for _, targ := range targs {
--
2.36.1
2.50.0

View file

@ -0,0 +1,58 @@
From f650ab16b5a3badf48922f77683ceaf791c82d64 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Wed, 28 Feb 2024 04:26:40 -0500
Subject: [PATCH 2/5] Skip tests that require Go module mode
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
errors_test.go | 2 +-
main_test.go | 2 +-
testdata/errors/loader-invaliddep.go | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/errors_test.go b/errors_test.go
index 871dc4c0..3d0bb162 100644
--- a/errors_test.go
+++ b/errors_test.go
@@ -37,7 +37,7 @@ func TestErrors(t *testing.T) {
{name: "loader-importcycle"},
{name: "loader-invaliddep"},
{name: "loader-invalidpackage"},
- {name: "loader-nopackage"},
+ // {name: "loader-nopackage"},
{name: "optimizer"},
{name: "syntax"},
{name: "types"},
diff --git a/main_test.go b/main_test.go
index ae0a4482..ca052821 100644
--- a/main_test.go
+++ b/main_test.go
@@ -78,7 +78,6 @@ func TestBuild(t *testing.T) {
"json.go",
"map.go",
"math.go",
- "oldgo/",
"print.go",
"reflect.go",
"signal.go",
@@ -1031,6 +1030,7 @@ func ioLogger(t *testing.T, wg *sync.WaitGroup) io.WriteCloser {
}
func TestGetListOfPackages(t *testing.T) {
+ t.Skip("Not available in non-module mode")
opts := optionsFromTarget("", sema)
tests := []struct {
pkgs []string
diff --git a/testdata/errors/loader-invaliddep.go b/testdata/errors/loader-invaliddep.go
index 05c2f2d5..719a617b 100644
--- a/testdata/errors/loader-invaliddep.go
+++ b/testdata/errors/loader-invaliddep.go
@@ -5,4 +5,4 @@ import _ "github.com/tinygo-org/tinygo/testdata/errors/invaliddep"
func main() {
}
-// ERROR: invaliddep{{[\\/]}}invaliddep.go:1:1: expected 'package', found ppackage
+// ERROR: {{.*}}invaliddep{{[\\/]}}invaliddep.go:1:1: expected 'package', found ppackage
--
2.50.0

View file

@ -1,122 +0,0 @@
From 76c575659d42187b0c4c15d4f5978c4368800da7 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 2 Jan 2022 05:47:18 -0500
Subject: [PATCH 02/18] Use system mingw64 headers and crt
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/mingw-w64.go | 68 ++++---------------------------------------
compileopts/config.go | 7 ++---
2 files changed, 7 insertions(+), 68 deletions(-)
diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go
index 27fefee0..d233068d 100644
--- a/builder/mingw-w64.go
+++ b/builder/mingw-w64.go
@@ -1,31 +1,11 @@
package builder
import (
- "io"
- "os"
- "path/filepath"
- "strings"
-
- "github.com/tinygo-org/tinygo/goenv"
+ "fmt"
)
var MinGW = Library{
- name: "mingw-w64",
- makeHeaders: func(target, includeDir string) error {
- // copy _mingw.h
- srcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "mingw-w64")
- outf, err := os.Create(includeDir + "/_mingw.h")
- if err != nil {
- return err
- }
- defer outf.Close()
- inf, err := os.Open(srcDir + "/mingw-w64-headers/crt/_mingw.h.in")
- if err != nil {
- return err
- }
- _, err = io.Copy(outf, inf)
- return err
- },
+ name: "mingw-w64",
sourceDir: func() string { return "" }, // unused
cflags: func(target, headerPath string) []string {
// No flags necessary because there are no files to compile.
@@ -45,47 +25,9 @@ var MinGW = Library{
// compile these files.
func makeMinGWExtraLibs(tmpdir string) []*compileJob {
var jobs []*compileJob
- root := goenv.Get("TINYGOROOT")
- // Normally all the api-ms-win-crt-*.def files are all compiled to a single
- // .lib file. But to simplify things, we're going to leave them as separate
- // files.
- for _, name := range []string{
- "kernel32.def.in",
- "api-ms-win-crt-conio-l1-1-0.def",
- "api-ms-win-crt-convert-l1-1-0.def",
- "api-ms-win-crt-environment-l1-1-0.def",
- "api-ms-win-crt-filesystem-l1-1-0.def",
- "api-ms-win-crt-heap-l1-1-0.def",
- "api-ms-win-crt-locale-l1-1-0.def",
- "api-ms-win-crt-math-l1-1-0.def.in",
- "api-ms-win-crt-multibyte-l1-1-0.def",
- "api-ms-win-crt-private-l1-1-0.def.in",
- "api-ms-win-crt-process-l1-1-0.def",
- "api-ms-win-crt-runtime-l1-1-0.def.in",
- "api-ms-win-crt-stdio-l1-1-0.def",
- "api-ms-win-crt-string-l1-1-0.def",
- "api-ms-win-crt-time-l1-1-0.def",
- "api-ms-win-crt-utility-l1-1-0.def",
- } {
- outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
- inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
- job := &compileJob{
- description: "create lib file " + inpath,
- result: outpath,
- run: func(job *compileJob) error {
- defpath := inpath
- if strings.HasSuffix(inpath, ".in") {
- // .in files need to be preprocessed by a preprocessor (-E)
- // first.
- defpath = outpath + ".def"
- err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/")
- if err != nil {
- return err
- }
- }
- return link("ld.lld", "-m", "i386pep", "-o", outpath, defpath)
- },
- }
+ for _, name := range []string{"kernel32", "ucrt"} {
+ outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name)
+ job := dummyCompileJob(outpath)
jobs = append(jobs, job)
}
return jobs
diff --git a/compileopts/config.go b/compileopts/config.go
index ebfc5082..cd49283d 100644
--- a/compileopts/config.go
+++ b/compileopts/config.go
@@ -304,12 +304,9 @@ func (c *Config) CFlags() []string {
root := goenv.Get("TINYGOROOT")
cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot")
case "mingw-w64":
- root := goenv.Get("TINYGOROOT")
- path, _ := c.LibcPath("mingw-w64")
cflags = append(cflags,
- "--sysroot="+path,
- "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
- "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
+ "--sysroot=/usr/x86_64-w64-mingw32/sys-root",
+ "-isystem", "/usr/x86_64-w64-mingw32/sys-root/mingw/include",
"-D_UCRT",
)
case "":
--
2.36.1

View file

@ -0,0 +1,126 @@
From d516beb86673a9b80ca75c41e8fb7cba7e3f126f Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 27 Oct 2024 23:33:18 -0400
Subject: [PATCH 3/5] Set LLVM search paths for Fedora
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
cgo/libclang_config_llvm15.go | 4 ++--
cgo/libclang_config_llvm16.go | 4 ++--
cgo/libclang_config_llvm17.go | 4 ++--
cgo/libclang_config_llvm18.go | 4 ++--
cgo/libclang_config_llvm19.go | 4 ++--
cgo/libclang_config_llvm20.go | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/cgo/libclang_config_llvm15.go b/cgo/libclang_config_llvm15.go
index edb1128d..0dc87193 100644
--- a/cgo/libclang_config_llvm15.go
+++ b/cgo/libclang_config_llvm15.go
@@ -3,11 +3,11 @@
package cgo
/*
-#cgo linux CFLAGS: -I/usr/lib/llvm-15/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm15/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@15/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@15/include
#cgo freebsd CFLAGS: -I/usr/local/llvm15/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm15/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm15/lib -lclang
diff --git a/cgo/libclang_config_llvm16.go b/cgo/libclang_config_llvm16.go
index ee354e21..4c338678 100644
--- a/cgo/libclang_config_llvm16.go
+++ b/cgo/libclang_config_llvm16.go
@@ -9,11 +9,11 @@ package cgo
// ln -sf ../../x86_64-linux-gnu/libclang-16.so.1 /usr/lib/llvm-16/lib/libclang.so
/*
-#cgo linux CFLAGS: -I/usr/lib/llvm-16/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm16/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@16/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@16/include
#cgo freebsd CFLAGS: -I/usr/local/llvm16/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-16/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm16/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@16/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@16/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm16/lib -lclang
diff --git a/cgo/libclang_config_llvm17.go b/cgo/libclang_config_llvm17.go
index 6395d8a3..609b0758 100644
--- a/cgo/libclang_config_llvm17.go
+++ b/cgo/libclang_config_llvm17.go
@@ -3,11 +3,11 @@
package cgo
/*
-#cgo linux CFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -I/usr/lib/llvm-17/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm17/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@17/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@17/include
#cgo freebsd CFLAGS: -I/usr/local/llvm17/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-17/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm17/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@17/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@17/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm17/lib -lclang
diff --git a/cgo/libclang_config_llvm18.go b/cgo/libclang_config_llvm18.go
index da181291..76f23129 100644
--- a/cgo/libclang_config_llvm18.go
+++ b/cgo/libclang_config_llvm18.go
@@ -3,11 +3,11 @@
package cgo
/*
-#cgo linux CFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -I/usr/lib/llvm-18/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm18/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@18/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@18/include
#cgo freebsd CFLAGS: -I/usr/local/llvm18/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm18/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm18/lib -lclang
diff --git a/cgo/libclang_config_llvm19.go b/cgo/libclang_config_llvm19.go
index 11a64e72..94c95bcb 100644
--- a/cgo/libclang_config_llvm19.go
+++ b/cgo/libclang_config_llvm19.go
@@ -3,11 +3,11 @@
package cgo
/*
-#cgo linux CFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -I/usr/lib/llvm-19/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm19/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@19/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@19/include
#cgo freebsd CFLAGS: -I/usr/local/llvm19/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm19/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@19/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lclang
diff --git a/cgo/libclang_config_llvm20.go b/cgo/libclang_config_llvm20.go
index faa2e54d..947558d6 100644
--- a/cgo/libclang_config_llvm20.go
+++ b/cgo/libclang_config_llvm20.go
@@ -3,11 +3,11 @@
package cgo
/*
-#cgo linux CFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -I/usr/lib/llvm-20/include
+#cgo linux CFLAGS: -I/usr/lib64/llvm20/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@20/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@20/include
#cgo freebsd CFLAGS: -I/usr/local/llvm20/include
-#cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lclang
+#cgo linux LDFLAGS: -L/usr/lib64/llvm20/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lclang
--
2.50.0

View file

@ -1,64 +0,0 @@
From 2a2e35e4565e8ea7f7ac2d34cb9da24000bb6474 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Mon, 3 Jan 2022 22:39:31 -0500
Subject: [PATCH 03/18] Skip some cross Linux tests where qemu is broken
The upstream issues will hopefully be fixed soon:
- https://gitlab.com/qemu-project/qemu/-/issues/447
- https://gitlab.com/qemu-project/qemu/-/issues/690
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
main_test.go | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/main_test.go b/main_test.go
index 79ae2cf2..9359ef0c 100644
--- a/main_test.go
+++ b/main_test.go
@@ -252,6 +252,20 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
}
func emuCheck(t *testing.T, options compileopts.Options) {
+ // Skip running the test executable due to bugs in qemu.
+ // https://gitlab.com/qemu-project/qemu/-/issues/447
+ // https://gitlab.com/qemu-project/qemu/-/issues/690
+ switch runtime.GOARCH {
+ case "arm64":
+ if options.GOARCH == "386" || options.GOARCH == "arm" {
+ t.Skipf("qemu is broken for this host/target architecture combination")
+ }
+ case "386":
+ if options.GOARCH == "arm" {
+ t.Skipf("qemu is broken for this host/target architecture combination")
+ }
+ }
+
// Check if the emulator is installed.
spec, err := compileopts.LoadTarget(&options)
if err != nil {
@@ -341,6 +355,20 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
return
}
+ // Skip running the test executable due to bugs in qemu.
+ // https://gitlab.com/qemu-project/qemu/-/issues/447
+ // https://gitlab.com/qemu-project/qemu/-/issues/690
+ switch runtime.GOARCH {
+ case "arm64":
+ if options.GOARCH == "386" || options.GOARCH == "arm" {
+ return
+ }
+ case "386":
+ if options.GOARCH == "arm" {
+ return
+ }
+ }
+
// putchar() prints CRLF, convert it to LF.
actual := bytes.Replace(stdout.Bytes(), []byte{'\r', '\n'}, []byte{'\n'}, -1)
expected = bytes.Replace(expected, []byte{'\r', '\n'}, []byte{'\n'}, -1) // for Windows
--
2.36.1

View file

@ -0,0 +1,33 @@
From d83874e6ab92ee4142cc7672da226a9091f7211a Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Tue, 31 Dec 2024 02:00:17 -0500
Subject: [PATCH 4/5] Normalize expected path for chdir tests
The expected path comes from a simple string concatenation in shell, but
`os.Getwd` appears to have the normalized working directory, so this can
fail if any parent directory is a symlink.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
tests/testing/chdir/chdir.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/testing/chdir/chdir.go b/tests/testing/chdir/chdir.go
index 75281c21..660b25ac 100644
--- a/tests/testing/chdir/chdir.go
+++ b/tests/testing/chdir/chdir.go
@@ -20,6 +20,11 @@ func main() {
}
if runtime.GOOS == "windows" {
cwd = filepath.ToSlash(cwd)
+ } else {
+ expectDir, err = filepath.EvalSymlinks(expectDir)
+ if err != nil {
+ log.Fatal(err)
+ }
}
if cwd != expectDir {
log.Fatalf("expected:\"%v\" != os.Getwd():\"%v\"", expectDir, cwd)
--
2.50.0

View file

@ -1,78 +0,0 @@
From 3f935d679870de924aa65d78c23ecdcb483ab4a3 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 6 Feb 2022 03:49:16 -0500
Subject: [PATCH 04/18] Suggest optional packages to install if missing
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/jobs.go | 17 +++++++++++++++++
builder/mingw-w64.go | 2 +-
builder/tools.go | 6 +++++-
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/builder/jobs.go b/builder/jobs.go
index 3d510974..d24a4165 100644
--- a/builder/jobs.go
+++ b/builder/jobs.go
@@ -7,6 +7,7 @@ import (
"container/heap"
"errors"
"fmt"
+ "os"
"runtime"
"sort"
"strings"
@@ -37,6 +38,22 @@ type compileJob struct {
duration time.Duration // how long it took to run this job (only set after finishing)
}
+// checkIfPackagedFileExistsJob returns a new *compileJob that checks if a file
+// exists. If the file does not exist, the job will fail with an error
+// suggesting to install the named system packageToInstall.
+func checkIfPackagedFileExistsJob(fileName, packageToInstall string) *compileJob {
+ return &compileJob{
+ description: fmt.Sprintf("check if %v exists", fileName),
+ result: fileName,
+ run: func(*compileJob) (err error) {
+ if _, err := os.Stat(fileName); errors.Is(err, os.ErrNotExist) {
+ return fmt.Errorf("%v does not exist; please install %v via dnf", fileName, packageToInstall)
+ }
+ return nil
+ },
+ }
+}
+
// dummyCompileJob returns a new *compileJob that produces an output without
// doing anything. This can be useful where a *compileJob producing an output is
// expected but nothing needs to be done, for example for a load from a cache.
diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go
index d233068d..d2539f6e 100644
--- a/builder/mingw-w64.go
+++ b/builder/mingw-w64.go
@@ -27,7 +27,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob {
var jobs []*compileJob
for _, name := range []string{"kernel32", "ucrt"} {
outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name)
- job := dummyCompileJob(outpath)
+ job := checkIfPackagedFileExistsJob(outpath, "mingw64-crt and mingw64-headers")
jobs = append(jobs, job)
}
return jobs
diff --git a/builder/tools.go b/builder/tools.go
index 53d89bf0..e55719b2 100644
--- a/builder/tools.go
+++ b/builder/tools.go
@@ -46,5 +46,9 @@ func link(linker string, flags ...string) error {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = goenv.Get("TINYGOROOT")
- return cmd.Run()
+ err := cmd.Run()
+ if linker == "avr-gcc" && errors.Is(err, exec.ErrNotFound) {
+ return errors.New("avr-gcc not found; please install avr-gcc and avr-libc via dnf")
+ }
+ return err
}
--
2.36.1

View file

@ -1,30 +0,0 @@
From 41cbdf1cfe50f24b49beb615f0924ea3255c7e7d Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 8 May 2022 04:18:05 -0400
Subject: [PATCH 05/18] Skip TestDirFS on 32-bit systems
Because Seek is not fully implemented there.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
src/os/os_anyos_test.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/os/os_anyos_test.go b/src/os/os_anyos_test.go
index dd255fb4..5dc0d860 100644
--- a/src/os/os_anyos_test.go
+++ b/src/os/os_anyos_test.go
@@ -277,6 +277,10 @@ func TestDirFS(t *testing.T) {
t.Log("TODO: implement Readdir for Windows")
return
}
+ if runtime.GOARCH == "386" || runtime.GOARCH == "arm" {
+ t.Log("TODO: implement seek for 386 and arm")
+ return
+ }
if isWASI {
t.Log("TODO: allow foo/bar/. as synonym for path foo/bar on wasi?")
return
--
2.36.1

View file

@ -0,0 +1,44 @@
From 9c8cef8d589dfbd2d913010a1211d8a49279c986 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sat, 2 Aug 2025 18:30:43 -0400
Subject: [PATCH 5/5] Skip x86 tests on ARM
They are currently broken:
https://github.com/tinygo-org/tinygo/issues/4969
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
main_test.go | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/main_test.go b/main_test.go
index ca052821..13a40997 100644
--- a/main_test.go
+++ b/main_test.go
@@ -192,7 +192,10 @@ func TestBuild(t *testing.T) {
if runtime.GOOS == "linux" {
for name, osArch := range supportedLinuxArches {
options := optionsFromOSARCH(osArch, sema)
- if options.GOARCH != runtime.GOARCH { // Native architecture already run above.
+ if options.GOARCH == "386" && runtime.GOARCH == "arm64" {
+ // This is currently broken running in qemu.
+ // https://github.com/tinygo-org/tinygo/issues/4969
+ } else if options.GOARCH != runtime.GOARCH { // Native architecture already run above.
t.Run(name, func(t *testing.T) {
runPlatTests(options, tests, t)
})
@@ -895,7 +898,10 @@ func TestTest(t *testing.T) {
if runtime.GOOS == "linux" {
for name, osArch := range supportedLinuxArches {
options := optionsFromOSARCH(osArch, sema)
- if options.GOARCH != runtime.GOARCH { // Native architecture already run above.
+ if options.GOARCH == "386" && runtime.GOARCH == "arm64" {
+ // This is currently broken running in qemu.
+ // https://github.com/tinygo-org/tinygo/issues/4969
+ } else if options.GOARCH != runtime.GOARCH { // Native architecture already run above.
targs = append(targs, targ{name, options})
}
}
--
2.50.0

View file

@ -1,44 +0,0 @@
From a44f31de099aaf6768af2102919f1a8c221ce6f4 Mon Sep 17 00:00:00 2001
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date: Sun, 8 May 2022 18:39:26 -0400
Subject: [PATCH 06/18] Skip broken tests on i686
* compress/flate runs out of memory
* testing/fstest uses Seek, which is not implemented there
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
Makefile | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 99f67c29..1ef11d29 100644
--- a/Makefile
+++ b/Makefile
@@ -338,15 +338,21 @@ endif
# Additional standard library packages that pass tests on individual platforms
TEST_PACKAGES_LINUX := \
archive/zip \
- compress/flate \
compress/lzw \
crypto/hmac \
debug/dwarf \
debug/plan9obj \
io/ioutil \
strconv \
- testing/fstest \
text/template/parse
+ifneq ($(shell getconf LONG_BIT),32)
+# Some tests are skipped on 32-bit because:
+# compress/flate runs out of memory
+# testing/fstest uses Seek, which is not implemented there
+TEST_PACKAGES_LINUX += \
+ compress/flate \
+ testing/fstest
+endif
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
--
2.36.1

View file

@ -1,265 +0,0 @@
From e8f07384a0f5a61351a62931d3fb69bf6c451c1b Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Sun, 16 Oct 2022 00:44:38 +0200
Subject: [PATCH 07/18] wasm: fix GC scanning of allocas
Scanning of allocas was entirely broken on WebAssembly. The code
intended to do this was never run. There were also no tests.
Looking into this further, I found that it is actually not really
necessary to do that: the C stack can be scanned conservatively and in
fact this was already done for goroutine stacks (because they live on
the heap and are always referenced). It wasn't done for the system stack
however.
With these fixes, I believe code should be both faster *and* more
correct.
I found this in my work to get opaque pointers supported in LLVM 15,
because the code that was never reached now finally got run and was
actually quite buggy.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
src/runtime/arch_tinygowasm.go | 3 +++
src/runtime/asm_tinygowasm.S | 10 ++++++++++
src/runtime/gc_stack_portable.go | 34 +++++++++++++++++++++-----------
targets/wasi.json | 3 +++
targets/wasm.json | 3 +++
transform/gc.go | 30 ++++++++--------------------
transform/llvm.go | 28 ++++++++------------------
7 files changed, 57 insertions(+), 54 deletions(-)
create mode 100644 src/runtime/asm_tinygowasm.S
diff --git a/src/runtime/arch_tinygowasm.go b/src/runtime/arch_tinygowasm.go
index 597b2489..f1893d91 100644
--- a/src/runtime/arch_tinygowasm.go
+++ b/src/runtime/arch_tinygowasm.go
@@ -58,6 +58,8 @@ var (
globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol))
+
+ stackTop = uintptr(unsafe.Pointer(&globalsStartSymbol))
)
func align(ptr uintptr) uintptr {
@@ -67,6 +69,7 @@ func align(ptr uintptr) uintptr {
return (ptr + heapAlign - 1) &^ (heapAlign - 1)
}
+//export tinygo_getCurrentStackPointer
func getCurrentStackPointer() uintptr
// growHeap tries to grow the heap size. It returns true if it succeeds, false
diff --git a/src/runtime/asm_tinygowasm.S b/src/runtime/asm_tinygowasm.S
new file mode 100644
index 00000000..3278a7f6
--- /dev/null
+++ b/src/runtime/asm_tinygowasm.S
@@ -0,0 +1,10 @@
+.globaltype __stack_pointer, i32
+
+.global tinygo_getCurrentStackPointer
+.hidden tinygo_getCurrentStackPointer
+.type tinygo_getCurrentStackPointer,@function
+tinygo_getCurrentStackPointer: // func getCurrentStackPointer() uintptr
+ .functype tinygo_getCurrentStackPointer() -> (i32)
+ global.get __stack_pointer
+ return
+ end_function
diff --git a/src/runtime/gc_stack_portable.go b/src/runtime/gc_stack_portable.go
index 6ffc35d4..6802de02 100644
--- a/src/runtime/gc_stack_portable.go
+++ b/src/runtime/gc_stack_portable.go
@@ -4,6 +4,7 @@
package runtime
import (
+ "internal/task"
"unsafe"
)
@@ -17,19 +18,28 @@ type stackChainObject struct {
// markStack marks all root pointers found on the stack.
//
-// This implementation is conservative and relies on the compiler inserting code
-// to manually push/pop stack objects that are stored in a linked list starting
-// with stackChainStart. Manually keeping track of stack values is _much_ more
-// expensive than letting the compiler do it and it inhibits a few important
-// optimizations, but it has the big advantage of being portable to basically
-// any ISA, including WebAssembly.
+// - Goroutine stacks are heap allocated and always reachable in some way
+// (for example through internal/task.currentTask) so they will always be
+// scanned.
+// - The system stack (aka startup stack) is not heap allocated, so even
+// though it may be referenced it will not be scanned by default.
+//
+// Therefore, we only need to scan the system stack.
+// It is relatively easy to scan the system stack while we're on it: we can
+// simply read __stack_pointer and __global_base and scan the area inbetween.
+// Unfortunately, it's hard to get the system stack pointer while we're on a
+// goroutine stack. But when we're on a goroutine stack, the system stack is in
+// the scheduler which means there shouldn't be anything on the system stack
+// anyway.
+// ...I hope this assumption holds, otherwise we will need to store the system
+// stack in a global or something.
+//
+// The compiler also inserts code to store all globals in a chain via
+// stackChainStart. Luckily we don't need to scan these, as these globals are
+// stored on the goroutine stack and are therefore already getting scanned.
func markStack() {
- stackObject := stackChainStart
- for stackObject != nil {
- start := uintptr(unsafe.Pointer(stackObject)) + unsafe.Sizeof(uintptr(0))*2
- end := start + stackObject.numSlots*unsafe.Alignof(uintptr(0))
- markRoots(start, end)
- stackObject = stackObject.parent
+ if task.OnSystemStack() {
+ markRoots(getCurrentStackPointer(), stackTop)
}
}
diff --git a/targets/wasi.json b/targets/wasi.json
index e710b4bb..6cec6be4 100644
--- a/targets/wasi.json
+++ b/targets/wasi.json
@@ -18,6 +18,9 @@
"--stack-first",
"--no-demangle"
],
+ "extra-files": [
+ "src/runtime/asm_tinygowasm.S"
+ ],
"emulator": "wasmtime {}",
"wasm-abi": "generic"
}
diff --git a/targets/wasm.json b/targets/wasm.json
index 2bcada5f..26494cc4 100644
--- a/targets/wasm.json
+++ b/targets/wasm.json
@@ -19,6 +19,9 @@
"--stack-first",
"--no-demangle"
],
+ "extra-files": [
+ "src/runtime/asm_tinygowasm.S"
+ ],
"emulator": "node {root}/targets/wasm_exec.js {}",
"wasm-abi": "js"
}
diff --git a/transform/gc.go b/transform/gc.go
index eb3520aa..87dc6e88 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -139,7 +139,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
}
// Determine what to do with each call.
- var allocas, pointers []llvm.Value
+ var pointers []llvm.Value
for _, call := range calls {
ptr := call.Operand(0)
call.EraseFromParentAsInstruction()
@@ -189,16 +189,15 @@ func MakeGCStackSlots(mod llvm.Module) bool {
// be optimized if needed.
}
- if !ptr.IsAAllocaInst().IsNil() {
- if typeHasPointers(ptr.Type().ElementType()) {
- allocas = append(allocas, ptr)
- }
- } else {
- pointers = append(pointers, ptr)
+ if ptr := stripPointerCasts(ptr); !ptr.IsAAllocaInst().IsNil() {
+ // Allocas don't need to be tracked because they are allocated
+ // on the C stack which is scanned separately.
+ continue
}
+ pointers = append(pointers, ptr)
}
- if len(allocas) == 0 && len(pointers) == 0 {
+ if len(pointers) == 0 {
// This function does not need to keep track of stack pointers.
continue
}
@@ -208,9 +207,6 @@ func MakeGCStackSlots(mod llvm.Module) bool {
stackChainStartType, // Pointer to parent frame.
uintptrType, // Number of elements in this frame.
}
- for _, alloca := range allocas {
- fields = append(fields, alloca.Type().ElementType())
- }
for _, ptr := range pointers {
fields = append(fields, ptr.Type())
}
@@ -235,16 +231,6 @@ func MakeGCStackSlots(mod llvm.Module) bool {
stackObjectCast := builder.CreateBitCast(stackObject, stackChainStartType, "")
builder.CreateStore(stackObjectCast, stackChainStart)
- // Replace all independent allocas with GEPs in the stack object.
- for i, alloca := range allocas {
- gep := builder.CreateGEP(stackObject, []llvm.Value{
- llvm.ConstInt(ctx.Int32Type(), 0, false),
- llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false),
- }, "")
- alloca.ReplaceAllUsesWith(gep)
- alloca.EraseFromParentAsInstruction()
- }
-
// Do a store to the stack object after each new pointer that is created.
pointerStores := make(map[llvm.Value]struct{})
for i, ptr := range pointers {
@@ -260,7 +246,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
// Extract a pointer to the appropriate section of the stack object.
gep := builder.CreateGEP(stackObject, []llvm.Value{
llvm.ConstInt(ctx.Int32Type(), 0, false),
- llvm.ConstInt(ctx.Int32Type(), uint64(2+len(allocas)+i), false),
+ llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false),
}, "")
// Store the pointer into the stack slot.
diff --git a/transform/llvm.go b/transform/llvm.go
index 90b7a7c7..32ee9560 100644
--- a/transform/llvm.go
+++ b/transform/llvm.go
@@ -75,26 +75,14 @@ func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) ll
return global
}
-// typeHasPointers returns whether this type is a pointer or contains pointers.
-// If the type is an aggregate type, it will check whether there is a pointer
-// inside.
-func typeHasPointers(t llvm.Type) bool {
- switch t.TypeKind() {
- case llvm.PointerTypeKind:
- return true
- case llvm.StructTypeKind:
- for _, subType := range t.StructElementTypes() {
- if typeHasPointers(subType) {
- return true
- }
+// stripPointerCasts strips instruction pointer casts (getelementptr and
+// bitcast) and returns the original value without the casts.
+func stripPointerCasts(value llvm.Value) llvm.Value {
+ if !value.IsAInstruction().IsNil() {
+ switch value.InstructionOpcode() {
+ case llvm.GetElementPtr, llvm.BitCast:
+ return stripPointerCasts(value.Operand(0))
}
- return false
- case llvm.ArrayTypeKind:
- if typeHasPointers(t.ElementType()) {
- return true
- }
- return false
- default:
- return false
}
+ return value
}
--
2.36.1

View file

@ -1,52 +0,0 @@
From 9e64a63d49100e550fad97b390bb01489ed6ca44 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Tue, 20 Sep 2022 23:59:22 +0200
Subject: [PATCH 08/18] compiler: return a FunctionType (not a PointerType) in
getRawFuncType
This is necessary for opaque pointer support (in LLVM 15).
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
compiler/func.go | 4 ++--
compiler/interface.go | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/compiler/func.go b/compiler/func.go
index 75656cb7..a8b2874e 100644
--- a/compiler/func.go
+++ b/compiler/func.go
@@ -62,7 +62,7 @@ func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (f
funcPtr = bitcast.Operand(0)
return
}
- llvmSig := b.getRawFuncType(sig)
+ llvmSig := llvm.PointerType(b.getRawFuncType(sig), b.funcPtrAddrSpace)
funcPtr = b.CreateBitCast(bitcast, llvmSig, "")
return
}
@@ -117,7 +117,7 @@ func (c *compilerContext) getRawFuncType(typ *types.Signature) llvm.Type {
paramTypes = append(paramTypes, c.i8ptrType) // context
// Make a func type out of the signature.
- return llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), c.funcPtrAddrSpace)
+ return llvm.FunctionType(returnType, paramTypes, false)
}
// parseMakeClosure makes a function value (with context) from the given
diff --git a/compiler/interface.go b/compiler/interface.go
index c59a9ade..b0ea71e3 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -465,7 +465,7 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
paramTuple = append(paramTuple, sig.Params().At(i))
}
paramTuple = append(paramTuple, types.NewVar(token.NoPos, nil, "$typecode", types.Typ[types.Uintptr]))
- llvmFnType := c.getRawFuncType(types.NewSignature(sig.Recv(), types.NewTuple(paramTuple...), sig.Results(), false)).ElementType()
+ llvmFnType := c.getRawFuncType(types.NewSignature(sig.Recv(), types.NewTuple(paramTuple...), sig.Results(), false))
llvmFn = llvm.AddFunction(c.mod, fnName, llvmFnType)
c.addStandardDeclaredAttributes(llvmFn)
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("tinygo-invoke", c.getMethodSignatureName(instr.Method)))
--
2.36.1

View file

@ -1,993 +0,0 @@
From 8138d69793c00829df45501c35975055ad52d151 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Wed, 21 Sep 2022 00:37:01 +0200
Subject: [PATCH 09/18] all: add type parameter to CreateCall
This uses LLVMBuildCall2 in the background, which is the replacement for
the deprecated LLVMBuildCall function.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/build.go | 2 +-
compiler/alias.go | 2 +-
compiler/atomic.go | 4 ++--
compiler/calls.go | 14 +++++++-------
compiler/compiler.go | 25 ++++++++++++++++---------
compiler/defer.go | 16 ++++++++++------
compiler/func.go | 8 +++++---
compiler/goroutine.go | 33 ++++++++++++++++++---------------
compiler/inlineasm.go | 16 ++++++++--------
compiler/interface.go | 17 ++++++++---------
compiler/interrupt.go | 4 ++--
compiler/intrinsics.go | 6 +++---
compiler/llvm.go | 2 +-
compiler/llvmutil/llvm.go | 24 ++++++++++++++----------
compiler/llvmutil/wordpack.go | 4 ++--
compiler/symbol.go | 6 +++---
compiler/syscall.go | 14 +++++++-------
go.mod | 2 +-
go.sum | 4 ++--
interp/interp.go | 2 +-
interp/interpreter.go | 2 +-
transform/interface-lowering.go | 7 ++++---
transform/interrupt.go | 2 +-
transform/panic.go | 2 +-
transform/rtcalls.go | 2 +-
transform/wasm-abi.go | 6 +++---
26 files changed, 123 insertions(+), 103 deletions(-)
diff --git a/builder/build.go b/builder/build.go
index 2008c897..28385044 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -523,7 +523,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
if pkgInit.IsNil() {
panic("init not found for " + pkg.Pkg.Path())
}
- irbuilder.CreateCall(pkgInit, []llvm.Value{llvm.Undef(i8ptrType)}, "")
+ irbuilder.CreateCall(pkgInit.GlobalValueType(), pkgInit, []llvm.Value{llvm.Undef(i8ptrType)}, "")
}
irbuilder.CreateRetVoid()
diff --git a/compiler/alias.go b/compiler/alias.go
index 9e88e3c6..b16cbce8 100644
--- a/compiler/alias.go
+++ b/compiler/alias.go
@@ -52,7 +52,7 @@ func (b *builder) createAlias(alias llvm.Value) {
b.CreateUnreachable()
return
}
- result := b.CreateCall(alias, b.llvmFn.Params(), "")
+ result := b.CreateCall(alias.GlobalValueType(), alias, b.llvmFn.Params(), "")
if result.Type().TypeKind() == llvm.VoidTypeKind {
b.CreateRetVoid()
} else {
diff --git a/compiler/atomic.go b/compiler/atomic.go
index f12c6d11..6ba3849c 100644
--- a/compiler/atomic.go
+++ b/compiler/atomic.go
@@ -25,7 +25,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
if fn.IsNil() {
fn = llvm.AddFunction(b.mod, name, llvm.FunctionType(vType, []llvm.Type{ptr.Type(), vType}, false))
}
- oldVal := b.createCall(fn, []llvm.Value{ptr, val}, "")
+ oldVal := b.createCall(fn.GlobalValueType(), fn, []llvm.Value{ptr, val}, "")
// Return the new value, not the original value returned.
return b.CreateAdd(oldVal, val, "")
}
@@ -78,7 +78,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
if fn.IsNil() {
fn = llvm.AddFunction(b.mod, name, llvm.FunctionType(vType, []llvm.Type{ptr.Type(), vType, b.uintptrType}, false))
}
- b.createCall(fn, []llvm.Value{ptr, val, llvm.ConstInt(b.uintptrType, 5, false)}, "")
+ b.createCall(fn.GlobalValueType(), fn, []llvm.Value{ptr, val, llvm.ConstInt(b.uintptrType, 5, false)}, "")
return llvm.Value{}
}
store := b.CreateStore(val, ptr)
diff --git a/compiler/calls.go b/compiler/calls.go
index aeca518a..b38d770f 100644
--- a/compiler/calls.go
+++ b/compiler/calls.go
@@ -37,15 +37,15 @@ const (
// createRuntimeInvoke instead.
func (b *builder) createRuntimeCallCommon(fnName string, args []llvm.Value, name string, isInvoke bool) llvm.Value {
fn := b.program.ImportedPackage("runtime").Members[fnName].(*ssa.Function)
- llvmFn := b.getFunction(fn)
+ fnType, llvmFn := b.getFunction(fn)
if llvmFn.IsNil() {
panic("trying to call non-existent function: " + fn.RelString(nil))
}
args = append(args, llvm.Undef(b.i8ptrType)) // unused context parameter
if isInvoke {
- return b.createInvoke(llvmFn, args, name)
+ return b.createInvoke(fnType, llvmFn, args, name)
}
- return b.createCall(llvmFn, args, name)
+ return b.createCall(fnType, llvmFn, args, name)
}
// createRuntimeCall creates a new call to runtime.<fnName> with the given
@@ -65,22 +65,22 @@ func (b *builder) createRuntimeInvoke(fnName string, args []llvm.Value, name str
// createCall creates a call to the given function with the arguments possibly
// expanded.
-func (b *builder) createCall(fn llvm.Value, args []llvm.Value, name string) llvm.Value {
+func (b *builder) createCall(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value {
expanded := make([]llvm.Value, 0, len(args))
for _, arg := range args {
fragments := b.expandFormalParam(arg)
expanded = append(expanded, fragments...)
}
- return b.CreateCall(fn, expanded, name)
+ return b.CreateCall(fnType, fn, expanded, name)
}
// createInvoke is like createCall but continues execution at the landing pad if
// the call resulted in a panic.
-func (b *builder) createInvoke(fn llvm.Value, args []llvm.Value, name string) llvm.Value {
+func (b *builder) createInvoke(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value {
if b.hasDeferFrame() {
b.createInvokeCheckpoint()
}
- return b.createCall(fn, args, name)
+ return b.createCall(fnType, fn, args, name)
}
// Expand an argument type to a list that can be used in a function call
diff --git a/compiler/compiler.go b/compiler/compiler.go
index bbaf6432..b64fddcc 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -131,6 +131,7 @@ type builder struct {
*compilerContext
llvm.Builder
fn *ssa.Function
+ llvmFnType llvm.Type
llvmFn llvm.Value
info functionInfo
locals map[ssa.Value]llvm.Value // local variables
@@ -155,11 +156,13 @@ type builder struct {
}
func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *builder {
+ fnType, fn := c.getFunction(f)
return &builder{
compilerContext: c,
Builder: irbuilder,
fn: f,
- llvmFn: c.getFunction(f),
+ llvmFnType: fnType,
+ llvmFn: fn,
info: c.getFunctionInfo(f),
locals: make(map[ssa.Value]llvm.Value),
dilocals: make(map[*types.Var]llvm.Metadata),
@@ -711,7 +714,8 @@ func (b *builder) getLocalVariable(variable *types.Var) llvm.Metadata {
// DISubprogram metadata node.
func (c *compilerContext) attachDebugInfo(f *ssa.Function) llvm.Metadata {
pos := c.program.Fset.Position(f.Syntax().Pos())
- return c.attachDebugInfoRaw(f, c.getFunction(f), "", pos.Filename, pos.Line)
+ _, fn := c.getFunction(f)
+ return c.attachDebugInfoRaw(f, fn, "", pos.Filename, pos.Line)
}
// attachDebugInfo adds debug info to a function declaration. It returns the
@@ -1654,6 +1658,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
// Try to call the function directly for trivially static calls.
var callee, context llvm.Value
+ var calleeType llvm.Type
exported := false
if fn := instr.StaticCallee(); fn != nil {
// Direct function call, either to a named or anonymous (directly
@@ -1684,7 +1689,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
return b.createInterruptGlobal(instr)
}
- callee = b.getFunction(fn)
+ calleeType, callee = b.getFunction(fn)
info := b.getFunctionInfo(fn)
if callee.IsNil() {
return llvm.Value{}, b.makeError(instr.Pos(), "undefined function: "+info.linkName)
@@ -1698,8 +1703,8 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
// Eventually we might be able to eliminate this special case
// entirely. For details, see:
// https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c/60521
- fnType := llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false)
- callee = llvm.ConstBitCast(callee, llvm.PointerType(fnType, b.funcPtrAddrSpace))
+ calleeType = llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false)
+ callee = llvm.ConstBitCast(callee, llvm.PointerType(calleeType, b.funcPtrAddrSpace))
}
case *ssa.MakeClosure:
// A call on a func value, but the callee is trivial to find. For
@@ -1726,13 +1731,14 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
params = append([]llvm.Value{value}, params...)
params = append(params, typecode)
callee = b.getInvokeFunction(instr)
+ calleeType = callee.GlobalValueType()
context = llvm.Undef(b.i8ptrType)
} else {
// Function pointer.
value := b.getValue(instr.Value)
// This is a func value, which cannot be called directly. We have to
// extract the function pointer and context first from the func value.
- callee, context = b.decodeFuncValue(value, instr.Value.Type().Underlying().(*types.Signature))
+ calleeType, callee, context = b.decodeFuncValue(value, instr.Value.Type().Underlying().(*types.Signature))
b.createNilCheck(instr.Value, callee, "fpcall")
}
@@ -1742,7 +1748,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
params = append(params, context)
}
- return b.createInvoke(callee, params, ""), nil
+ return b.createInvoke(calleeType, callee, params, ""), nil
}
// getValue returns the LLVM value of a constant, function value, global, or
@@ -1756,7 +1762,8 @@ func (b *builder) getValue(expr ssa.Value) llvm.Value {
b.addError(expr.Pos(), "cannot use an exported function as value: "+expr.String())
return llvm.Undef(b.getLLVMType(expr.Type()))
}
- return b.createFuncValue(b.getFunction(expr), llvm.Undef(b.i8ptrType), expr.Signature)
+ _, fn := b.getFunction(expr)
+ return b.createFuncValue(fn, llvm.Undef(b.i8ptrType), expr.Signature)
case *ssa.Global:
value := b.getGlobal(expr)
if value.IsNil() {
@@ -3080,7 +3087,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
// Instead of a load from the global, create a bitcast of the
// function pointer itself.
name := strings.TrimSuffix(unop.X.(*ssa.Global).Name(), "$funcaddr")
- fn := b.getFunction(b.fn.Pkg.Members[name].(*ssa.Function))
+ _, fn := b.getFunction(b.fn.Pkg.Members[name].(*ssa.Function))
if fn.IsNil() {
return llvm.Value{}, b.makeError(unop.Pos(), "cgo function not found: "+name)
}
diff --git a/compiler/defer.go b/compiler/defer.go
index 75c1be3d..e82370fa 100644
--- a/compiler/defer.go
+++ b/compiler/defer.go
@@ -201,7 +201,7 @@ li a0, 0
}
asmType := llvm.FunctionType(resultType, []llvm.Type{b.deferFrame.Type()}, false)
asm := llvm.InlineAsm(asmType, asmString, constraints, false, false, 0, false)
- result := b.CreateCall(asm, []llvm.Value{b.deferFrame}, "setjmp")
+ result := b.CreateCall(asmType, asm, []llvm.Value{b.deferFrame}, "setjmp")
result.AddCallSiteAttribute(-1, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0))
isZero := b.CreateICmp(llvm.IntEQ, result, llvm.ConstInt(resultType, 0, false), "setjmp.result")
continueBB := b.insertBasicBlock("")
@@ -492,6 +492,7 @@ func (b *builder) createRunDefers() {
}
var fnPtr llvm.Value
+ var fnType llvm.Type
if !callback.IsInvoke() {
// Isolate the func value.
@@ -499,8 +500,8 @@ func (b *builder) createRunDefers() {
forwardParams = forwardParams[1:]
//Get function pointer and context
- fp, context := b.decodeFuncValue(funcValue, callback.Signature())
- fnPtr = fp
+ var context llvm.Value
+ fnType, fnPtr, context = b.decodeFuncValue(funcValue, callback.Signature())
//Pass context
forwardParams = append(forwardParams, context)
@@ -509,6 +510,7 @@ func (b *builder) createRunDefers() {
// parameters.
forwardParams = append(forwardParams[1:], forwardParams[0])
fnPtr = b.getInvokeFunction(callback)
+ fnType = fnPtr.GlobalValueType()
// Add the context parameter. An interface call cannot also be a
// closure but we have to supply the parameter anyway for platforms
@@ -516,7 +518,7 @@ func (b *builder) createRunDefers() {
forwardParams = append(forwardParams, llvm.Undef(b.i8ptrType))
}
- b.createCall(fnPtr, forwardParams, "")
+ b.createCall(fnType, fnPtr, forwardParams, "")
case *ssa.Function:
// Direct call.
@@ -547,7 +549,8 @@ func (b *builder) createRunDefers() {
}
// Call real function.
- b.createInvoke(b.getFunction(callback), forwardParams, "")
+ fnType, fn := b.getFunction(callback)
+ b.createInvoke(fnType, fn, forwardParams, "")
case *ssa.MakeClosure:
// Get the real defer struct type and cast to it.
@@ -571,7 +574,8 @@ func (b *builder) createRunDefers() {
}
// Call deferred function.
- b.createCall(b.getFunction(fn), forwardParams, "")
+ fnType, llvmFn := b.getFunction(fn)
+ b.createCall(fnType, llvmFn, forwardParams, "")
case *ssa.Builtin:
db := b.deferBuiltinFuncs[callback]
diff --git a/compiler/func.go b/compiler/func.go
index a8b2874e..c6a8802d 100644
--- a/compiler/func.go
+++ b/compiler/func.go
@@ -55,14 +55,15 @@ func (b *builder) extractFuncContext(funcValue llvm.Value) llvm.Value {
// decodeFuncValue extracts the context and the function pointer from this func
// value. This may be an expensive operation.
-func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcPtr, context llvm.Value) {
+func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcType llvm.Type, funcPtr, context llvm.Value) {
context = b.CreateExtractValue(funcValue, 0, "")
bitcast := b.CreateExtractValue(funcValue, 1, "")
if !bitcast.IsAConstantExpr().IsNil() && bitcast.Opcode() == llvm.BitCast {
funcPtr = bitcast.Operand(0)
return
}
- llvmSig := llvm.PointerType(b.getRawFuncType(sig), b.funcPtrAddrSpace)
+ funcType = b.getRawFuncType(sig)
+ llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace)
funcPtr = b.CreateBitCast(bitcast, llvmSig, "")
return
}
@@ -141,5 +142,6 @@ func (b *builder) parseMakeClosure(expr *ssa.MakeClosure) (llvm.Value, error) {
context := b.emitPointerPack(boundVars)
// Create the closure.
- return b.createFuncValue(b.getFunction(f), context, f.Signature), nil
+ _, fn := b.getFunction(f)
+ return b.createFuncValue(fn, context, f.Signature), nil
}
diff --git a/compiler/goroutine.go b/compiler/goroutine.go
index 8d76c89f..ba8ec0f4 100644
--- a/compiler/goroutine.go
+++ b/compiler/goroutine.go
@@ -22,6 +22,7 @@ func (b *builder) createGo(instr *ssa.Go) {
var prefix string
var funcPtr llvm.Value
+ var funcPtrType llvm.Type
hasContext := false
if callee := instr.Call.StaticCallee(); callee != nil {
// Static callee is known. This makes it easier to start a new
@@ -42,7 +43,7 @@ func (b *builder) createGo(instr *ssa.Go) {
params = append(params, context) // context parameter
hasContext = true
}
- funcPtr = b.getFunction(callee)
+ funcPtrType, funcPtr = b.getFunction(callee)
} else if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok {
// We cheat. None of the builtins do any long or blocking operation, so
// we might as well run these builtins right away without the program
@@ -80,6 +81,7 @@ func (b *builder) createGo(instr *ssa.Go) {
itfTypeCode := b.CreateExtractValue(itf, 0, "")
itfValue := b.CreateExtractValue(itf, 1, "")
funcPtr = b.getInvokeFunction(&instr.Call)
+ funcPtrType = funcPtr.GlobalValueType()
params = append([]llvm.Value{itfValue}, params...) // start with receiver
params = append(params, itfTypeCode) // end with typecode
} else {
@@ -89,7 +91,7 @@ func (b *builder) createGo(instr *ssa.Go) {
// * The function context, for closures.
// * The function pointer (for tasks).
var context llvm.Value
- funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value), instr.Call.Value.Type().Underlying().(*types.Signature))
+ funcPtrType, funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value), instr.Call.Value.Type().Underlying().(*types.Signature))
params = append(params, context, funcPtr)
hasContext = true
prefix = b.fn.RelString(nil)
@@ -97,14 +99,14 @@ func (b *builder) createGo(instr *ssa.Go) {
paramBundle := b.emitPointerPack(params)
var stackSize llvm.Value
- callee := b.createGoroutineStartWrapper(funcPtr, prefix, hasContext, instr.Pos())
+ callee := b.createGoroutineStartWrapper(funcPtrType, funcPtr, prefix, hasContext, instr.Pos())
if b.AutomaticStackSize {
// The stack size is not known until after linking. Call a dummy
// function that will be replaced with a load from a special ELF
// section that contains the stack size (and is modified after
// linking).
- stackSizeFn := b.getFunction(b.program.ImportedPackage("internal/task").Members["getGoroutineStackSize"].(*ssa.Function))
- stackSize = b.createCall(stackSizeFn, []llvm.Value{callee, llvm.Undef(b.i8ptrType)}, "stacksize")
+ stackSizeFnType, stackSizeFn := b.getFunction(b.program.ImportedPackage("internal/task").Members["getGoroutineStackSize"].(*ssa.Function))
+ stackSize = b.createCall(stackSizeFnType, stackSizeFn, []llvm.Value{callee, llvm.Undef(b.i8ptrType)}, "stacksize")
} else {
// The stack size is fixed at compile time. By emitting it here as a
// constant, it can be optimized.
@@ -113,8 +115,8 @@ func (b *builder) createGo(instr *ssa.Go) {
}
stackSize = llvm.ConstInt(b.uintptrType, b.DefaultStackSize, false)
}
- start := b.getFunction(b.program.ImportedPackage("internal/task").Members["start"].(*ssa.Function))
- b.createCall(start, []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.i8ptrType)}, "")
+ fnType, start := b.getFunction(b.program.ImportedPackage("internal/task").Members["start"].(*ssa.Function))
+ b.createCall(fnType, start, []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.i8ptrType)}, "")
}
// createGoroutineStartWrapper creates a wrapper for the task-based
@@ -140,15 +142,16 @@ func (b *builder) createGo(instr *ssa.Go) {
// to last parameter of the function) is used for this wrapper. If hasContext is
// false, the parameter bundle is assumed to have no context parameter and undef
// is passed instead.
-func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix string, hasContext bool, pos token.Pos) llvm.Value {
+func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.Value, prefix string, hasContext bool, pos token.Pos) llvm.Value {
var wrapper llvm.Value
builder := c.ctx.NewBuilder()
defer builder.Dispose()
var deadlock llvm.Value
+ var deadlockType llvm.Type
if c.Scheduler == "asyncify" {
- deadlock = c.getFunction(c.program.ImportedPackage("runtime").Members["deadlock"].(*ssa.Function))
+ deadlockType, deadlock = c.getFunction(c.program.ImportedPackage("runtime").Members["deadlock"].(*ssa.Function))
}
if !fn.IsAFunction().IsNil() {
@@ -192,7 +195,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
}
// Create the list of params for the call.
- paramTypes := fn.Type().ElementType().ParamTypes()
+ paramTypes := fnType.ParamTypes()
if !hasContext {
paramTypes = paramTypes[:len(paramTypes)-1] // strip context parameter
}
@@ -202,10 +205,10 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
}
// Create the call.
- builder.CreateCall(fn, params, "")
+ builder.CreateCall(fnType, fn, params, "")
if c.Scheduler == "asyncify" {
- builder.CreateCall(deadlock, []llvm.Value{
+ builder.CreateCall(deadlockType, deadlock, []llvm.Value{
llvm.Undef(c.i8ptrType),
}, "")
}
@@ -261,7 +264,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
}
// Get the list of parameters, with the extra parameters at the end.
- paramTypes := fn.Type().ElementType().ParamTypes()
+ paramTypes := fnType.ParamTypes()
paramTypes = append(paramTypes, fn.Type()) // the last element is the function pointer
params := llvmutil.EmitPointerUnpack(builder, c.mod, wrapper.Param(0), paramTypes)
@@ -270,10 +273,10 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
params = params[:len(params)-1]
// Create the call.
- builder.CreateCall(fnPtr, params, "")
+ builder.CreateCall(fnType, fnPtr, params, "")
if c.Scheduler == "asyncify" {
- builder.CreateCall(deadlock, []llvm.Value{
+ builder.CreateCall(deadlockType, deadlock, []llvm.Value{
llvm.Undef(c.i8ptrType),
}, "")
}
diff --git a/compiler/inlineasm.go b/compiler/inlineasm.go
index 27b0492b..2afb0a16 100644
--- a/compiler/inlineasm.go
+++ b/compiler/inlineasm.go
@@ -25,7 +25,7 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{}, false)
asm := constant.StringVal(args[0].(*ssa.Const).Value)
target := llvm.InlineAsm(fnType, asm, "", true, false, 0, false)
- return b.CreateCall(target, nil, ""), nil
+ return b.CreateCall(fnType, target, nil, ""), nil
}
// This is a compiler builtin, which allows assembly to be called in a flexible
@@ -120,7 +120,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error)
}
fnType := llvm.FunctionType(outputType, argTypes, false)
target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0, false)
- result := b.CreateCall(target, args, "")
+ result := b.CreateCall(fnType, target, args, "")
if hasOutput {
return result, nil
} else {
@@ -163,7 +163,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
constraints += ",~{r1},~{r2},~{r3}"
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false)
- return b.CreateCall(target, llvmArgs, ""), nil
+ return b.CreateCall(fnType, target, llvmArgs, ""), nil
}
// This is a compiler builtin which emits an inline SVCall instruction. It can
@@ -201,7 +201,7 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
constraints += ",~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7}"
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false)
- return b.CreateCall(target, llvmArgs, ""), nil
+ return b.CreateCall(fnType, target, llvmArgs, ""), nil
}
// This is a compiler builtin which emits CSR instructions. It can be one of:
@@ -226,24 +226,24 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) {
fnType := llvm.FunctionType(b.uintptrType, nil, false)
asm := fmt.Sprintf("csrr $0, %d", csr)
target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0, false)
- return b.CreateCall(target, nil, ""), nil
+ return b.CreateCall(fnType, target, nil, ""), nil
case "Set":
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.uintptrType}, false)
asm := fmt.Sprintf("csrw %d, $0", csr)
target := llvm.InlineAsm(fnType, asm, "r", true, false, 0, false)
- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
case "SetBits":
// Note: it may be possible to optimize this to csrrsi in many cases.
fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false)
asm := fmt.Sprintf("csrrs $0, %d, $1", csr)
target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false)
- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
case "ClearBits":
// Note: it may be possible to optimize this to csrrci in many cases.
fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false)
asm := fmt.Sprintf("csrrc $0, %d, $1", csr)
target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false)
- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
default:
return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name)
}
diff --git a/compiler/interface.go b/compiler/interface.go
index b0ea71e3..72f8952d 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -254,12 +254,12 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value {
method := ms.At(i)
signatureGlobal := c.getMethodSignature(method.Obj().(*types.Func))
fn := c.program.MethodValue(method)
- llvmFn := c.getFunction(fn)
+ llvmFnType, llvmFn := c.getFunction(fn)
if llvmFn.IsNil() {
// compiler error, so panic
panic("cannot find function: " + c.getFunctionInfo(fn).linkName)
}
- wrapper := c.getInterfaceInvokeWrapper(fn, llvmFn)
+ wrapper := c.getInterfaceInvokeWrapper(fn, llvmFnType, llvmFn)
methodInfo := llvm.ConstNamedStruct(interfaceMethodInfoType, []llvm.Value{
signatureGlobal,
llvm.ConstPtrToInt(wrapper, c.uintptrType),
@@ -361,7 +361,7 @@ func (b *builder) createTypeAssert(expr *ssa.TypeAssert) llvm.Value {
// implements each method of the interface. See:
// https://research.swtch.com/interfaces
fn := b.getInterfaceImplementsFunc(expr.AssertedType)
- commaOk = b.CreateCall(fn, []llvm.Value{actualTypeNum}, "")
+ commaOk = b.CreateCall(fn.GlobalValueType(), fn, []llvm.Value{actualTypeNum}, "")
} else {
globalName := "reflect/types.typeid:" + getTypeCodeName(expr.AssertedType)
@@ -480,7 +480,7 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value {
// value, dereferences or unpacks it if necessary, and calls the real method.
// If the method to wrap has a pointer receiver, no wrapping is necessary and
// the function is returned directly.
-func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llvm.Value) llvm.Value {
+func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFnType llvm.Type, llvmFn llvm.Value) llvm.Value {
wrapperName := llvmFn.Name() + "$invoke"
wrapper := c.mod.NamedFunction(wrapperName)
if !wrapper.IsNil() {
@@ -505,9 +505,8 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv
}
// create wrapper function
- fnType := llvmFn.Type().ElementType()
- paramTypes := append([]llvm.Type{c.i8ptrType}, fnType.ParamTypes()[len(expandedReceiverType):]...)
- wrapFnType := llvm.FunctionType(fnType.ReturnType(), paramTypes, false)
+ paramTypes := append([]llvm.Type{c.i8ptrType}, llvmFnType.ParamTypes()[len(expandedReceiverType):]...)
+ wrapFnType := llvm.FunctionType(llvmFnType.ReturnType(), paramTypes, false)
wrapper = llvm.AddFunction(c.mod, wrapperName, wrapFnType)
c.addStandardAttributes(wrapper)
@@ -535,10 +534,10 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv
receiverValue := b.emitPointerUnpack(wrapper.Param(0), []llvm.Type{receiverType})[0]
params := append(b.expandFormalParam(receiverValue), wrapper.Params()[1:]...)
if llvmFn.Type().ElementType().ReturnType().TypeKind() == llvm.VoidTypeKind {
- b.CreateCall(llvmFn, params, "")
+ b.CreateCall(llvmFnType, llvmFn, params, "")
b.CreateRetVoid()
} else {
- ret := b.CreateCall(llvmFn, params, "ret")
+ ret := b.CreateCall(llvmFnType, llvmFn, params, "ret")
b.CreateRet(ret)
}
diff --git a/compiler/interrupt.go b/compiler/interrupt.go
index bcd407cd..45c7d074 100644
--- a/compiler/interrupt.go
+++ b/compiler/interrupt.go
@@ -36,7 +36,7 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
// Fall back to a generic error.
return llvm.Value{}, b.makeError(instr.Pos(), "interrupt function must be constant")
}
- funcRawPtr, funcContext := b.decodeFuncValue(funcValue, nil)
+ _, funcRawPtr, funcContext := b.decodeFuncValue(funcValue, nil)
funcPtr := llvm.ConstPtrToInt(funcRawPtr, b.uintptrType)
// Create a new global of type runtime/interrupt.handle. Globals of this
@@ -85,7 +85,7 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
useFnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{interrupt.Type()}, false)
useFn = llvm.AddFunction(b.mod, "runtime/interrupt.use", useFnType)
}
- b.CreateCall(useFn, []llvm.Value{interrupt}, "")
+ b.CreateCall(useFn.GlobalValueType(), useFn, []llvm.Value{interrupt}, "")
}
return interrupt, nil
diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go
index 0203d441..9fedfbd6 100644
--- a/compiler/intrinsics.go
+++ b/compiler/intrinsics.go
@@ -55,7 +55,7 @@ func (b *builder) createMemoryCopyImpl() {
params = append(params, b.getValue(param))
}
params = append(params, llvm.ConstInt(b.ctx.Int1Type(), 0, false))
- b.CreateCall(llvmFn, params, "")
+ b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "")
b.CreateRetVoid()
}
@@ -76,7 +76,7 @@ func (b *builder) createMemoryZeroImpl() {
b.getValue(b.fn.Params[1]),
llvm.ConstInt(b.ctx.Int1Type(), 0, false),
}
- b.CreateCall(llvmFn, params, "")
+ b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "")
b.CreateRetVoid()
}
@@ -119,6 +119,6 @@ func (b *builder) defineMathOp() {
for i, param := range b.fn.Params {
args[i] = b.getValue(param)
}
- result := b.CreateCall(llvmFn, args, "")
+ result := b.CreateCall(llvmFn.GlobalValueType(), llvmFn, args, "")
b.CreateRet(result)
}
diff --git a/compiler/llvm.go b/compiler/llvm.go
index 0d2ba9da..9540bcc6 100644
--- a/compiler/llvm.go
+++ b/compiler/llvm.go
@@ -312,5 +312,5 @@ func (b *builder) readStackPointer() llvm.Value {
fnType := llvm.FunctionType(b.i8ptrType, nil, false)
stacksave = llvm.AddFunction(b.mod, "llvm.stacksave", fnType)
}
- return b.CreateCall(stacksave, nil, "")
+ return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "")
}
diff --git a/compiler/llvmutil/llvm.go b/compiler/llvmutil/llvm.go
index 74404a3e..e73b68da 100644
--- a/compiler/llvmutil/llvm.go
+++ b/compiler/llvmutil/llvm.go
@@ -39,7 +39,8 @@ func CreateTemporaryAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type, n
alloca = CreateEntryBlockAlloca(builder, t, name)
bitcast = builder.CreateBitCast(alloca, i8ptrType, name+".bitcast")
size = llvm.ConstInt(ctx.Int64Type(), targetData.TypeAllocSize(t), false)
- builder.CreateCall(getLifetimeStartFunc(mod), []llvm.Value{size, bitcast}, "")
+ fnType, fn := getLifetimeStartFunc(mod)
+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "")
return
}
@@ -54,13 +55,15 @@ func CreateInstructionAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type,
builder.SetInsertPointBefore(inst)
bitcast := builder.CreateBitCast(alloca, i8ptrType, name+".bitcast")
size := llvm.ConstInt(ctx.Int64Type(), targetData.TypeAllocSize(t), false)
- builder.CreateCall(getLifetimeStartFunc(mod), []llvm.Value{size, bitcast}, "")
+ fnType, fn := getLifetimeStartFunc(mod)
+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "")
if next := llvm.NextInstruction(inst); !next.IsNil() {
builder.SetInsertPointBefore(next)
} else {
builder.SetInsertPointAtEnd(inst.InstructionParent())
}
- builder.CreateCall(getLifetimeEndFunc(mod), []llvm.Value{size, bitcast}, "")
+ fnType, fn = getLifetimeEndFunc(mod)
+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "")
return alloca
}
@@ -68,33 +71,34 @@ func CreateInstructionAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type,
// llvm.lifetime.end intrinsic. It is commonly used together with
// createTemporaryAlloca.
func EmitLifetimeEnd(builder llvm.Builder, mod llvm.Module, ptr, size llvm.Value) {
- builder.CreateCall(getLifetimeEndFunc(mod), []llvm.Value{size, ptr}, "")
+ fnType, fn := getLifetimeEndFunc(mod)
+ builder.CreateCall(fnType, fn, []llvm.Value{size, ptr}, "")
}
// getLifetimeStartFunc returns the llvm.lifetime.start intrinsic and creates it
// first if it doesn't exist yet.
-func getLifetimeStartFunc(mod llvm.Module) llvm.Value {
+func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) {
fn := mod.NamedFunction("llvm.lifetime.start.p0i8")
ctx := mod.Context()
i8ptrType := llvm.PointerType(ctx.Int8Type(), 0)
+ fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
if fn.IsNil() {
- fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
fn = llvm.AddFunction(mod, "llvm.lifetime.start.p0i8", fnType)
}
- return fn
+ return fnType, fn
}
// getLifetimeEndFunc returns the llvm.lifetime.end intrinsic and creates it
// first if it doesn't exist yet.
-func getLifetimeEndFunc(mod llvm.Module) llvm.Value {
+func getLifetimeEndFunc(mod llvm.Module) (llvm.Type, llvm.Value) {
fn := mod.NamedFunction("llvm.lifetime.end.p0i8")
ctx := mod.Context()
i8ptrType := llvm.PointerType(ctx.Int8Type(), 0)
+ fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
if fn.IsNil() {
- fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false)
fn = llvm.AddFunction(mod, "llvm.lifetime.end.p0i8", fnType)
}
- return fn
+ return fnType, fn
}
// SplitBasicBlock splits a LLVM basic block into two parts. All instructions
diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go
index 41d4c581..73b1e27e 100644
--- a/compiler/llvmutil/wordpack.go
+++ b/compiler/llvmutil/wordpack.go
@@ -95,14 +95,14 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs
// Packed data is bigger than a pointer, so allocate it on the heap.
sizeValue := llvm.ConstInt(uintptrType, size, false)
alloc := mod.NamedFunction("runtime.alloc")
- packedHeapAlloc := builder.CreateCall(alloc, []llvm.Value{
+ packedHeapAlloc := builder.CreateCall(alloc.GlobalValueType(), alloc, []llvm.Value{
sizeValue,
llvm.ConstNull(i8ptrType),
llvm.Undef(i8ptrType), // unused context parameter
}, "")
if needsStackObjects {
trackPointer := mod.NamedFunction("runtime.trackPointer")
- builder.CreateCall(trackPointer, []llvm.Value{
+ builder.CreateCall(trackPointer.GlobalValueType(), trackPointer, []llvm.Value{
packedHeapAlloc,
llvm.Undef(i8ptrType), // unused context parameter
}, "")
diff --git a/compiler/symbol.go b/compiler/symbol.go
index c4ce6f21..83fe050b 100644
--- a/compiler/symbol.go
+++ b/compiler/symbol.go
@@ -53,11 +53,11 @@ const (
// getFunction returns the LLVM function for the given *ssa.Function, creating
// it if needed. It can later be filled with compilerContext.createFunction().
-func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
+func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) {
info := c.getFunctionInfo(fn)
llvmFn := c.mod.NamedFunction(info.linkName)
if !llvmFn.IsNil() {
- return llvmFn
+ return llvmFn.GlobalValueType(), llvmFn
}
var retType llvm.Type
@@ -202,7 +202,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
llvmFn.SetUnnamedAddr(true)
}
- return llvmFn
+ return fnType, llvmFn
}
// getFunctionInfo returns information about a function that is not directly
diff --git a/compiler/syscall.go b/compiler/syscall.go
index 0c5f1246..66baf826 100644
--- a/compiler/syscall.go
+++ b/compiler/syscall.go
@@ -44,7 +44,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
constraints += ",~{rcx},~{r11}"
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel, false)
- return b.CreateCall(target, args, ""), nil
+ return b.CreateCall(fnType, target, args, ""), nil
case b.GOARCH == "386" && b.GOOS == "linux":
// Sources:
// syscall(2) man page
@@ -70,7 +70,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
}
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel, false)
- return b.CreateCall(target, args, ""), nil
+ return b.CreateCall(fnType, target, args, ""), nil
case b.GOARCH == "arm" && b.GOOS == "linux":
// Implement the EABI system call convention for Linux.
// Source: syscall(2) man page.
@@ -102,7 +102,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
}
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false)
- return b.CreateCall(target, args, ""), nil
+ return b.CreateCall(fnType, target, args, ""), nil
case b.GOARCH == "arm64" && b.GOOS == "linux":
// Source: syscall(2) man page.
args := []llvm.Value{}
@@ -134,7 +134,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
constraints += ",~{x16},~{x17}" // scratch registers
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false)
- return b.CreateCall(target, args, ""), nil
+ return b.CreateCall(fnType, target, args, ""), nil
default:
return llvm.Value{}, b.makeError(call.Pos(), "unknown GOOS/GOARCH for syscall: "+b.GOOS+"/"+b.GOARCH)
}
@@ -205,9 +205,9 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
// Note that SetLastError/GetLastError could be replaced with direct
// access to the thread control block, which is probably smaller and
// faster. The Go runtime does this in assembly.
- b.CreateCall(setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "")
- syscallResult := b.CreateCall(fnPtr, params, "")
- errResult := b.CreateCall(getLastError, nil, "err")
+ b.CreateCall(setLastError.GlobalValueType(), setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "")
+ syscallResult := b.CreateCall(llvmType, fnPtr, params, "")
+ errResult := b.CreateCall(getLastError.GlobalValueType(), getLastError, nil, "err")
if b.uintptrType != b.ctx.Int32Type() {
errResult = b.CreateZExt(errResult, b.uintptrType, "err.uintptr")
}
diff --git a/go.mod b/go.mod
index fdf686d4..4af10427 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11
gopkg.in/yaml.v2 v2.4.0
- tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7
+ tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636
)
require (
diff --git a/go.sum b/go.sum
index 3fc9cac1..401de3be 100644
--- a/go.sum
+++ b/go.sum
@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc=
-tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 h1:JxtI6P/lyWHAcs/4QJWeWIbh4HntxPFONMVWvx7wf8Y=
+tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
diff --git a/interp/interp.go b/interp/interp.go
index a1f5f507..856f08b1 100644
--- a/interp/interp.go
+++ b/interp/interp.go
@@ -127,7 +127,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
// Create a call to the package initializer (which was
// previously deleted).
i8undef := llvm.Undef(r.i8ptrType)
- r.builder.CreateCall(fn, []llvm.Value{i8undef}, "")
+ r.builder.CreateCall(fn.GlobalValueType(), fn, []llvm.Value{i8undef}, "")
// Make sure that any globals touched by the package
// initializer, won't be accessed by later package initializers.
err := r.markExternalLoad(fn)
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 7cee14bf..4a4553f8 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -977,7 +977,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me
}
}
}
- result = r.builder.CreateCall(llvmFn, args, inst.name)
+ result = r.builder.CreateCall(inst.llvmInst.CalledFunctionType(), llvmFn, args, inst.name)
case llvm.Load:
err := mem.markExternalLoad(operands[0])
if err != nil {
diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go
index 7a01c2ea..f5b29e30 100644
--- a/transform/interface-lowering.go
+++ b/transform/interface-lowering.go
@@ -493,12 +493,13 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte
paramTypes = append(paramTypes, param.Type())
}
calledFunctionType := function.Type()
- sig := llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), calledFunctionType.PointerAddressSpace())
+ functionType := llvm.FunctionType(returnType, paramTypes, false)
+ sig := llvm.PointerType(functionType, calledFunctionType.PointerAddressSpace())
if sig != function.Type() {
function = p.builder.CreateBitCast(function, sig, "")
}
- retval := p.builder.CreateCall(function, append([]llvm.Value{receiver}, params...), "")
+ retval := p.builder.CreateCall(functionType, function, append([]llvm.Value{receiver}, params...), "")
if retval.Type().TypeKind() == llvm.VoidTypeKind {
p.builder.CreateRetVoid()
} else {
@@ -518,7 +519,7 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte
// importantly, it avoids undefined behavior when accidentally calling a
// method on a nil interface.
nilPanic := p.mod.NamedFunction("runtime.nilPanic")
- p.builder.CreateCall(nilPanic, []llvm.Value{
+ p.builder.CreateCall(nilPanic.GlobalValueType(), nilPanic, []llvm.Value{
llvm.Undef(llvm.PointerType(p.ctx.Int8Type(), 0)),
}, "")
p.builder.CreateUnreachable()
diff --git a/transform/interrupt.go b/transform/interrupt.go
index 3ffe7048..2c301be0 100644
--- a/transform/interrupt.go
+++ b/transform/interrupt.go
@@ -91,7 +91,7 @@ func LowerInterrupts(mod llvm.Module) []error {
initializer := handler.Initializer()
context := llvm.ConstExtractValue(initializer, []uint32{0})
funcPtr := llvm.ConstExtractValue(initializer, []uint32{1}).Operand(0)
- builder.CreateCall(funcPtr, []llvm.Value{
+ builder.CreateCall(funcPtr.GlobalValueType(), funcPtr, []llvm.Value{
num,
context,
}, "")
diff --git a/transform/panic.go b/transform/panic.go
index e8e9a1fe..dee3bae0 100644
--- a/transform/panic.go
+++ b/transform/panic.go
@@ -27,7 +27,7 @@ func ReplacePanicsWithTrap(mod llvm.Module) {
panic("expected use of a panic function to be a call")
}
builder.SetInsertPointBefore(use)
- builder.CreateCall(trap, nil, "")
+ builder.CreateCall(trap.GlobalValueType(), trap, nil, "")
}
}
}
diff --git a/transform/rtcalls.go b/transform/rtcalls.go
index 2edfd655..2f17f815 100644
--- a/transform/rtcalls.go
+++ b/transform/rtcalls.go
@@ -165,7 +165,7 @@ func OptimizeReflectImplements(mod llvm.Module) {
// Replace Implements call with the type assert call.
builder.SetInsertPointBefore(call)
- implements := builder.CreateCall(typeAssertFunction, []llvm.Value{
+ implements := builder.CreateCall(typeAssertFunction.GlobalValueType(), typeAssertFunction, []llvm.Value{
builder.CreatePtrToInt(call.Operand(0), uintptrType, ""), // typecode to check
}, "")
call.ReplaceAllUsesWith(implements)
diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go
index aeba713d..aedad71d 100644
--- a/transform/wasm-abi.go
+++ b/transform/wasm-abi.go
@@ -124,12 +124,12 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
// Pass a stack-allocated pointer as the first parameter
// where the return value should be stored, instead of using
// the regular return value.
- builder.CreateCall(externalFn, callParams, callName)
+ builder.CreateCall(externalFnType, externalFn, callParams, callName)
returnValue := builder.CreateLoad(retvalAlloca, "retval")
call.ReplaceAllUsesWith(returnValue)
call.EraseFromParentAsInstruction()
} else {
- newCall := builder.CreateCall(externalFn, callParams, callName)
+ newCall := builder.CreateCall(externalFnType, externalFn, callParams, callName)
call.ReplaceAllUsesWith(newCall)
call.EraseFromParentAsInstruction()
}
@@ -156,7 +156,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
}
callParams = append(callParams, paramValue)
}
- retval := builder.CreateCall(fn, callParams, "")
+ retval := builder.CreateCall(fn.GlobalValueType(), fn, callParams, "")
if retval.Type().TypeKind() == llvm.VoidTypeKind {
builder.CreateRetVoid()
} else {
--
2.36.1

View file

@ -1,377 +0,0 @@
From 65a18179d8ff911ba43a3a28ffb2f36c262cff5e Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Wed, 21 Sep 2022 13:55:32 +0200
Subject: [PATCH 10/18] all: add type parameter to CreateLoad
This is needed for LLVM 15.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
compiler/atomic.go | 2 +-
compiler/channel.go | 8 ++++----
compiler/compiler.go | 13 +++++++------
compiler/defer.go | 19 +++++++++++--------
compiler/llvmutil/wordpack.go | 4 ++--
compiler/map.go | 6 +++---
compiler/volatile.go | 5 ++++-
go.mod | 2 +-
go.sum | 4 ++--
interp/interpreter.go | 2 +-
transform/gc.go | 2 +-
transform/stacksize.go | 13 +++++++++----
transform/wasm-abi.go | 4 ++--
13 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/compiler/atomic.go b/compiler/atomic.go
index 6ba3849c..73761be4 100644
--- a/compiler/atomic.go
+++ b/compiler/atomic.go
@@ -56,7 +56,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
return swapped
case "LoadInt32", "LoadInt64", "LoadUint32", "LoadUint64", "LoadUintptr", "LoadPointer":
ptr := b.getValue(b.fn.Params[0])
- val := b.CreateLoad(ptr, "")
+ val := b.CreateLoad(b.getLLVMType(b.fn.Signature.Results().At(0).Type()), ptr, "")
val.SetOrdering(llvm.AtomicOrderingSequentiallyConsistent)
val.SetAlignment(b.targetData.PrefTypeAlignment(val.Type())) // required
return val
diff --git a/compiler/channel.go b/compiler/channel.go
index a9886e10..5c3b6c59 100644
--- a/compiler/channel.go
+++ b/compiler/channel.go
@@ -84,7 +84,7 @@ func (b *builder) createChanRecv(unop *ssa.UnOp) llvm.Value {
if isZeroSize {
received = llvm.ConstNull(valueType)
} else {
- received = b.CreateLoad(valueAlloca, "chan.received")
+ received = b.CreateLoad(valueType, valueAlloca, "chan.received")
b.emitLifetimeEnd(valueAllocaCast, valueAllocaSize)
}
b.emitLifetimeEnd(channelBlockedListAllocaCast, channelBlockedListAllocaSize)
@@ -264,8 +264,8 @@ func (b *builder) getChanSelectResult(expr *ssa.Extract) llvm.Value {
// receive can proceed at a time) so we'll get that alloca, bitcast
// it to the correct type, and dereference it.
recvbuf := b.selectRecvBuf[expr.Tuple.(*ssa.Select)]
- typ := llvm.PointerType(b.getLLVMType(expr.Type()), 0)
- ptr := b.CreateBitCast(recvbuf, typ, "")
- return b.CreateLoad(ptr, "")
+ typ := b.getLLVMType(expr.Type())
+ ptr := b.CreateBitCast(recvbuf, llvm.PointerType(typ, 0), "")
+ return b.CreateLoad(typ, ptr, "")
}
}
diff --git a/compiler/compiler.go b/compiler/compiler.go
index b64fddcc..7ab2fe4e 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -1931,11 +1931,12 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
// Can't load directly from array (as index is non-constant), so have to
// do it using an alloca+gep+load.
- alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(array.Type(), "index.alloca")
+ arrayType := array.Type()
+ alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(arrayType, "index.alloca")
b.CreateStore(array, alloca)
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
ptr := b.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep")
- result := b.CreateLoad(ptr, "index.load")
+ result := b.CreateLoad(arrayType.ElementType(), ptr, "index.load")
b.emitLifetimeEnd(allocaPtr, allocaSize)
return result, nil
case *ssa.IndexAddr:
@@ -2012,7 +2013,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
// Lookup byte
buf := b.CreateExtractValue(value, 0, "")
bufPtr := b.CreateInBoundsGEP(buf, []llvm.Value{index}, "")
- return b.CreateLoad(bufPtr, ""), nil
+ return b.CreateLoad(b.ctx.Int8Type(), bufPtr, ""), nil
case *types.Map:
valueType := expr.Type()
if expr.CommaOk {
@@ -3076,10 +3077,10 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
return llvm.Value{}, b.makeError(unop.Pos(), "todo: unknown type for negate: "+unop.X.Type().Underlying().String())
}
case token.MUL: // *x, dereference pointer
- unop.X.Type().Underlying().(*types.Pointer).Elem()
+ valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem())
if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 {
// zero-length data
- return llvm.ConstNull(x.Type().ElementType()), nil
+ return llvm.ConstNull(valueType), nil
} else if strings.HasSuffix(unop.X.String(), "$funcaddr") {
// CGo function pointer. The cgo part has rewritten CGo function
// pointers as stub global variables of the form:
@@ -3094,7 +3095,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
return b.CreateBitCast(fn, b.i8ptrType, ""), nil
} else {
b.createNilCheck(unop.X, x, "deref")
- load := b.CreateLoad(x, "")
+ load := b.CreateLoad(valueType, x, "")
return load, nil
}
case token.XOR: // ^x, toggle all bits in integer
diff --git a/compiler/defer.go b/compiler/defer.go
index e82370fa..1f892e5b 100644
--- a/compiler/defer.go
+++ b/compiler/defer.go
@@ -249,7 +249,8 @@ func isInLoop(start *ssa.BasicBlock) bool {
func (b *builder) createDefer(instr *ssa.Defer) {
// The pointer to the previous defer struct, which we will replace to
// make a linked list.
- next := b.CreateLoad(b.deferPtr, "defer.next")
+ deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)
+ next := b.CreateLoad(deferType, b.deferPtr, "defer.next")
var values []llvm.Value
valueTypes := []llvm.Type{b.uintptrType, next.Type()}
@@ -406,6 +407,8 @@ func (b *builder) createDefer(instr *ssa.Defer) {
// createRunDefers emits code to run all deferred functions.
func (b *builder) createRunDefers() {
+ deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)
+
// Add a loop like the following:
// for stack != nil {
// _stack := stack
@@ -431,7 +434,7 @@ func (b *builder) createRunDefers() {
// Create loop head:
// for stack != nil {
b.SetInsertPointAtEnd(loophead)
- deferData := b.CreateLoad(b.deferPtr, "")
+ deferData := b.CreateLoad(deferType, b.deferPtr, "")
stackIsNil := b.CreateICmp(llvm.IntEQ, deferData, llvm.ConstPointerNull(deferData.Type()), "stackIsNil")
b.CreateCondBr(stackIsNil, end, loop)
@@ -444,13 +447,13 @@ func (b *builder) createRunDefers() {
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 1, false), // .next field
}, "stack.next.gep")
- nextStack := b.CreateLoad(nextStackGEP, "stack.next")
+ nextStack := b.CreateLoad(deferType, nextStackGEP, "stack.next")
b.CreateStore(nextStack, b.deferPtr)
gep := b.CreateInBoundsGEP(deferData, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 0, false), // .callback field
}, "callback.gep")
- callback := b.CreateLoad(gep, "callback")
+ callback := b.CreateLoad(b.uintptrType, gep, "callback")
sw := b.CreateSwitch(callback, unreachable, len(b.allDeferFuncs))
for i, callback := range b.allDeferFuncs {
@@ -487,7 +490,7 @@ func (b *builder) createRunDefers() {
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 2; i < len(valueTypes); i++ {
gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep")
- forwardParam := b.CreateLoad(gep, "param")
+ forwardParam := b.CreateLoad(valueTypes[i], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -536,7 +539,7 @@ func (b *builder) createRunDefers() {
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := range getParams(callback.Signature) {
gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
- forwardParam := b.CreateLoad(gep, "param")
+ forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -569,7 +572,7 @@ func (b *builder) createRunDefers() {
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 2; i < len(valueTypes); i++ {
gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "")
- forwardParam := b.CreateLoad(gep, "param")
+ forwardParam := b.CreateLoad(valueTypes[i], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -596,7 +599,7 @@ func (b *builder) createRunDefers() {
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 0; i < params.Len(); i++ {
gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
- forwardParam := b.CreateLoad(gep, "param")
+ forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param")
argValues = append(argValues, forwardParam)
}
diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go
index 73b1e27e..97b86045 100644
--- a/compiler/llvmutil/wordpack.go
+++ b/compiler/llvmutil/wordpack.go
@@ -63,7 +63,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs
}
// Load value (the *i8) from the alloca.
- result := builder.CreateLoad(packedAlloc, "")
+ result := builder.CreateLoad(i8ptrType, packedAlloc, "")
// End the lifetime of the alloca, to help the optimizer.
packedPtr := builder.CreateBitCast(packedAlloc, i8ptrType, "")
@@ -171,7 +171,7 @@ func EmitPointerUnpack(builder llvm.Builder, mod llvm.Module, ptr llvm.Value, va
llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
}
gep := builder.CreateInBoundsGEP(packedAlloc, indices, "")
- values[i] = builder.CreateLoad(gep, "")
+ values[i] = builder.CreateLoad(valueType, gep, "")
}
if !packedRawAlloc.IsNil() {
allocPtr := builder.CreateBitCast(packedRawAlloc, i8ptrType, "")
diff --git a/compiler/map.go b/compiler/map.go
index 57a7033a..7655ec70 100644
--- a/compiler/map.go
+++ b/compiler/map.go
@@ -106,7 +106,7 @@ func (b *builder) createMapLookup(keyType, valueType types.Type, m, key llvm.Val
// Load the resulting value from the hashmap. The value is set to the zero
// value if the key doesn't exist in the hashmap.
- mapValue := b.CreateLoad(mapValueAlloca, "")
+ mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "")
b.emitLifetimeEnd(mapValuePtr, mapValueAllocaSize)
if commaOk {
@@ -217,8 +217,8 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv
mapKeyAlloca, mapKeyPtr, mapKeySize := b.createTemporaryAlloca(llvmStoredKeyType, "range.key")
mapValueAlloca, mapValuePtr, mapValueSize := b.createTemporaryAlloca(llvmValueType, "range.value")
ok := b.createRuntimeCall("hashmapNext", []llvm.Value{llvmRangeVal, it, mapKeyPtr, mapValuePtr}, "range.next")
- mapKey := b.CreateLoad(mapKeyAlloca, "")
- mapValue := b.CreateLoad(mapValueAlloca, "")
+ mapKey := b.CreateLoad(llvmStoredKeyType, mapKeyAlloca, "")
+ mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "")
if isKeyStoredAsInterface {
// The key is stored as an interface but it isn't of interface type.
diff --git a/compiler/volatile.go b/compiler/volatile.go
index 143eff28..3d3a67fa 100644
--- a/compiler/volatile.go
+++ b/compiler/volatile.go
@@ -1,5 +1,7 @@
package compiler
+import "go/types"
+
// This file implements volatile loads/stores in runtime/volatile.LoadT and
// runtime/volatile.StoreT as compiler builtins.
@@ -9,7 +11,8 @@ func (b *builder) createVolatileLoad() {
b.createFunctionStart(true)
addr := b.getValue(b.fn.Params[0])
b.createNilCheck(b.fn.Params[0], addr, "deref")
- val := b.CreateLoad(addr, "")
+ valType := b.getLLVMType(b.fn.Params[0].Type().(*types.Pointer).Elem())
+ val := b.CreateLoad(valType, addr, "")
val.SetVolatile(true)
b.CreateRet(val)
}
diff --git a/go.mod b/go.mod
index 4af10427..26707a96 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11
gopkg.in/yaml.v2 v2.4.0
- tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636
+ tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6
)
require (
diff --git a/go.sum b/go.sum
index 401de3be..e5c734cd 100644
--- a/go.sum
+++ b/go.sum
@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 h1:JxtI6P/lyWHAcs/4QJWeWIbh4HntxPFONMVWvx7wf8Y=
-tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 h1:bJYUpmJrVm7Uluxh80qSivfeU3d9D4JNg5oJ+h9U+xc=
+tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 4a4553f8..2c7fd8c3 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -983,7 +983,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me
if err != nil {
return r.errorAt(inst, err)
}
- result = r.builder.CreateLoad(operands[0], inst.name)
+ result = r.builder.CreateLoad(inst.llvmInst.Type(), operands[0], inst.name)
if inst.llvmInst.IsVolatile() {
result.SetVolatile(true)
}
diff --git a/transform/gc.go b/transform/gc.go
index 87dc6e88..7a4e99ac 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -222,7 +222,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
builder.CreateStore(initialStackObject, stackObject)
// Update stack start.
- parent := builder.CreateLoad(stackChainStart, "")
+ parent := builder.CreateLoad(stackChainStartType, stackChainStart, "")
gep := builder.CreateGEP(stackObject, []llvm.Value{
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), 0, false),
diff --git a/transform/stacksize.go b/transform/stacksize.go
index 7be49238..f1a3c93d 100644
--- a/transform/stacksize.go
+++ b/transform/stacksize.go
@@ -34,6 +34,11 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string
return nil
}
+ ctx := mod.Context()
+ targetData := llvm.NewTargetData(mod.DataLayout())
+ defer targetData.Dispose()
+ uintptrType := ctx.IntType(targetData.PointerSize() * 8)
+
// Create the new global with stack sizes, that will be put in a new section
// just for itself.
stackSizesGlobalType := llvm.ArrayType(functions[0].Type(), len(functions))
@@ -50,16 +55,16 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string
appendToUsedGlobals(mod, append([]llvm.Value{stackSizesGlobal}, functionValues...)...)
// Replace the calls with loads from the new global with stack sizes.
- irbuilder := mod.Context().NewBuilder()
+ irbuilder := ctx.NewBuilder()
defer irbuilder.Dispose()
for i, function := range functions {
for _, use := range functionMap[function] {
ptr := llvm.ConstGEP(stackSizesGlobal, []llvm.Value{
- llvm.ConstInt(mod.Context().Int32Type(), 0, false),
- llvm.ConstInt(mod.Context().Int32Type(), uint64(i), false),
+ llvm.ConstInt(ctx.Int32Type(), 0, false),
+ llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
})
irbuilder.SetInsertPointBefore(use)
- stacksize := irbuilder.CreateLoad(ptr, "stacksize")
+ stacksize := irbuilder.CreateLoad(uintptrType, ptr, "stacksize")
use.ReplaceAllUsesWith(stacksize)
use.EraseFromParentAsInstruction()
}
diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go
index aedad71d..064e38f4 100644
--- a/transform/wasm-abi.go
+++ b/transform/wasm-abi.go
@@ -125,7 +125,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
// where the return value should be stored, instead of using
// the regular return value.
builder.CreateCall(externalFnType, externalFn, callParams, callName)
- returnValue := builder.CreateLoad(retvalAlloca, "retval")
+ returnValue := builder.CreateLoad(int64Type, retvalAlloca, "retval")
call.ReplaceAllUsesWith(returnValue)
call.EraseFromParentAsInstruction()
} else {
@@ -152,7 +152,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
for i, origParam := range fn.Params() {
paramValue := externalFn.Param(i)
if origParam.Type() == int64Type {
- paramValue = builder.CreateLoad(paramValue, "i64")
+ paramValue = builder.CreateLoad(int64Type, paramValue, "i64")
}
callParams = append(callParams, paramValue)
}
--
2.36.1

View file

@ -1,565 +0,0 @@
From dd4f1c594ef0fadb59fa418f1049542f86237800 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Wed, 21 Sep 2022 17:00:09 +0200
Subject: [PATCH 11/18] all: add type parameter to *GEP calls
This is necessary for LLVM 15.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/build.go | 2 +-
compiler/channel.go | 8 +++---
compiler/compiler.go | 46 ++++++++++++++++++++---------------
compiler/defer.go | 19 ++++++++-------
compiler/interface.go | 16 ++++++------
compiler/llvm.go | 6 ++---
compiler/llvmutil/wordpack.go | 6 ++---
go.mod | 2 +-
go.sum | 4 +--
interp/memory.go | 4 +--
transform/gc.go | 4 +--
transform/llvm.go | 10 ++++----
transform/stacksize.go | 2 +-
13 files changed, 69 insertions(+), 60 deletions(-)
diff --git a/builder/build.go b/builder/build.go
index 28385044..7a7dd9ac 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -1153,7 +1153,7 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro
// Create the string value, which is a {ptr, len} pair.
zero := llvm.ConstInt(mod.Context().Int32Type(), 0, false)
- ptr := llvm.ConstGEP(buf, []llvm.Value{zero, zero})
+ ptr := llvm.ConstGEP(bufInitializer.Type(), buf, []llvm.Value{zero, zero})
if ptr.Type() != elementTypes[0] {
return fmt.Errorf("%s: not a string", globalName)
}
diff --git a/compiler/channel.go b/compiler/channel.go
index 5c3b6c59..81f84565 100644
--- a/compiler/channel.go
+++ b/compiler/channel.go
@@ -173,7 +173,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
allocaType := llvm.ArrayType(b.ctx.Int8Type(), int(recvbufSize))
recvbufAlloca, _, _ := b.createTemporaryAlloca(allocaType, "select.recvbuf.alloca")
recvbufAlloca.SetAlignment(recvbufAlign)
- recvbuf = b.CreateGEP(recvbufAlloca, []llvm.Value{
+ recvbuf = b.CreateGEP(allocaType, recvbufAlloca, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
}, "select.recvbuf")
@@ -184,13 +184,13 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
statesAlloca, statesI8, statesSize := b.createTemporaryAlloca(statesAllocaType, "select.states.alloca")
for i, state := range selectStates {
// Set each slice element to the appropriate channel.
- gep := b.CreateGEP(statesAlloca, []llvm.Value{
+ gep := b.CreateGEP(statesAllocaType, statesAlloca, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false),
}, "")
b.CreateStore(state, gep)
}
- statesPtr := b.CreateGEP(statesAlloca, []llvm.Value{
+ statesPtr := b.CreateGEP(statesAllocaType, statesAlloca, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
}, "select.states")
@@ -204,7 +204,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
chBlockAllocaType := llvm.ArrayType(b.getLLVMRuntimeType("channelBlockedList"), len(selectStates))
chBlockAlloca, chBlockAllocaPtr, chBlockSize := b.createTemporaryAlloca(chBlockAllocaType, "select.block.alloca")
chBlockLen := llvm.ConstInt(b.uintptrType, uint64(len(selectStates)), false)
- chBlockPtr := b.CreateGEP(chBlockAlloca, []llvm.Value{
+ chBlockPtr := b.CreateGEP(chBlockAllocaType, chBlockAlloca, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
}, "select.block")
diff --git a/compiler/compiler.go b/compiler/compiler.go
index 7ab2fe4e..c93b2e56 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -918,7 +918,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
bufferGlobal.SetInitializer(bufferValue)
bufferGlobal.SetLinkage(llvm.InternalLinkage)
bufferGlobal.SetAlignment(1)
- slicePtr := llvm.ConstInBoundsGEP(bufferGlobal, []llvm.Value{
+ slicePtr := llvm.ConstInBoundsGEP(bufferValue.Type(), bufferGlobal, []llvm.Value{
llvm.ConstInt(c.uintptrType, 0, false),
llvm.ConstInt(c.uintptrType, 0, false),
})
@@ -990,7 +990,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
// Create the slice object itself.
// Because embed.FS refers to it as *[]embed.file instead of a plain
// []embed.file, we have to store this as a global.
- slicePtr := llvm.ConstInBoundsGEP(sliceDataGlobal, []llvm.Value{
+ slicePtr := llvm.ConstInBoundsGEP(sliceDataInitializer.Type(), sliceDataGlobal, []llvm.Value{
llvm.ConstInt(c.uintptrType, 0, false),
llvm.ConstInt(c.uintptrType, 0, false),
})
@@ -1018,11 +1018,11 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
func (c *compilerContext) getEmbedFileString(file *loader.EmbedFile) llvm.Value {
dataGlobalName := "embed/file_" + file.Hash
dataGlobal := c.mod.NamedGlobal(dataGlobalName)
+ dataGlobalType := llvm.ArrayType(c.ctx.Int8Type(), int(file.Size))
if dataGlobal.IsNil() {
- dataGlobalType := llvm.ArrayType(c.ctx.Int8Type(), int(file.Size))
dataGlobal = llvm.AddGlobal(c.mod, dataGlobalType, dataGlobalName)
}
- strPtr := llvm.ConstInBoundsGEP(dataGlobal, []llvm.Value{
+ strPtr := llvm.ConstInBoundsGEP(dataGlobalType, dataGlobal, []llvm.Value{
llvm.ConstInt(c.uintptrType, 0, false),
llvm.ConstInt(c.uintptrType, 0, false),
})
@@ -1601,7 +1601,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
// Note: the pointer is always of type *i8.
ptr := argValues[0]
len := argValues[1]
- return b.CreateGEP(ptr, []llvm.Value{len}, ""), nil
+ return b.CreateGEP(b.ctx.Int8Type(), ptr, []llvm.Value{len}, ""), nil
case "Alignof": // unsafe.Alignof
align := b.targetData.ABITypeAlignment(argValues[0].Type())
return llvm.ConstInt(b.uintptrType, uint64(align), false), nil
@@ -1911,7 +1911,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), uint64(expr.Field), false),
}
- return b.CreateInBoundsGEP(val, indices, ""), nil
+ elementType := b.getLLVMType(expr.X.Type().Underlying().(*types.Pointer).Elem())
+ return b.CreateInBoundsGEP(elementType, val, indices, ""), nil
case *ssa.Function:
panic("function is not an expression")
case *ssa.Global:
@@ -1935,7 +1936,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(arrayType, "index.alloca")
b.CreateStore(array, alloca)
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
- ptr := b.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep")
+ ptr := b.CreateInBoundsGEP(arrayType, alloca, []llvm.Value{zero, index}, "index.gep")
result := b.CreateLoad(arrayType.ElementType(), ptr, "index.load")
b.emitLifetimeEnd(allocaPtr, allocaSize)
return result, nil
@@ -1945,13 +1946,15 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
// Get buffer pointer and length
var bufptr, buflen llvm.Value
+ var bufType llvm.Type
switch ptrTyp := expr.X.Type().Underlying().(type) {
case *types.Pointer:
- typ := expr.X.Type().Underlying().(*types.Pointer).Elem().Underlying()
+ typ := ptrTyp.Elem().Underlying()
switch typ := typ.(type) {
case *types.Array:
bufptr = val
buflen = llvm.ConstInt(b.uintptrType, uint64(typ.Len()), false)
+ bufType = b.getLLVMType(typ)
// Check for nil pointer before calculating the address, from
// the spec:
// > For an operand x of type T, the address operation &x
@@ -1965,6 +1968,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
case *types.Slice:
bufptr = b.CreateExtractValue(val, 0, "indexaddr.ptr")
buflen = b.CreateExtractValue(val, 1, "indexaddr.len")
+ bufType = b.getLLVMType(ptrTyp.Elem())
default:
return llvm.Value{}, b.makeError(expr.Pos(), "todo: indexaddr: "+ptrTyp.String())
}
@@ -1982,9 +1986,9 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
index,
}
- return b.CreateInBoundsGEP(bufptr, indices, ""), nil
+ return b.CreateInBoundsGEP(bufType, bufptr, indices, ""), nil
case *types.Slice:
- return b.CreateInBoundsGEP(bufptr, []llvm.Value{index}, ""), nil
+ return b.CreateInBoundsGEP(bufType, bufptr, []llvm.Value{index}, ""), nil
default:
panic("unreachable")
}
@@ -2012,8 +2016,9 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
// Lookup byte
buf := b.CreateExtractValue(value, 0, "")
- bufPtr := b.CreateInBoundsGEP(buf, []llvm.Value{index}, "")
- return b.CreateLoad(b.ctx.Int8Type(), bufPtr, ""), nil
+ bufElemType := b.ctx.Int8Type()
+ bufPtr := b.CreateInBoundsGEP(bufElemType, buf, []llvm.Value{index}, "")
+ return b.CreateLoad(bufElemType, bufPtr, ""), nil
case *types.Map:
valueType := expr.Type()
if expr.CommaOk {
@@ -2146,7 +2151,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
switch typ := expr.X.Type().Underlying().(type) {
case *types.Pointer: // pointer to array
// slice an array
- length := typ.Elem().Underlying().(*types.Array).Len()
+ arrayType := typ.Elem().Underlying().(*types.Array)
+ length := arrayType.Len()
llvmLen := llvm.ConstInt(b.uintptrType, uint64(length), false)
if high.IsNil() {
high = llvmLen
@@ -2175,7 +2181,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
}
sliceLen := b.CreateSub(high, low, "slice.len")
- slicePtr := b.CreateInBoundsGEP(value, indices, "slice.ptr")
+ slicePtr := b.CreateInBoundsGEP(b.getLLVMType(arrayType), value, indices, "slice.ptr")
sliceCap := b.CreateSub(max, low, "slice.cap")
slice := b.ctx.ConstStruct([]llvm.Value{
@@ -2214,7 +2220,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
max = b.CreateTrunc(max, b.uintptrType, "")
}
- newPtr := b.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "")
+ ptrElemType := b.getLLVMType(typ.Elem())
+ newPtr := b.CreateInBoundsGEP(ptrElemType, oldPtr, []llvm.Value{low}, "")
newLen := b.CreateSub(high, low, "")
newCap := b.CreateSub(max, low, "")
slice := b.ctx.ConstStruct([]llvm.Value{
@@ -2254,7 +2261,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
high = b.CreateTrunc(high, b.uintptrType, "")
}
- newPtr := b.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "")
+ newPtr := b.CreateInBoundsGEP(b.ctx.Int8Type(), oldPtr, []llvm.Value{low}, "")
newLen := b.CreateSub(high, low, "")
str := llvm.Undef(b.getLLVMRuntimeType("_string"))
str = b.CreateInsertValue(str, newPtr, 0, "")
@@ -2717,14 +2724,15 @@ func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value {
var strPtr llvm.Value
if str != "" {
objname := c.pkg.Path() + "$string"
- global := llvm.AddGlobal(c.mod, llvm.ArrayType(c.ctx.Int8Type(), len(str)), objname)
+ globalType := llvm.ArrayType(c.ctx.Int8Type(), len(str))
+ global := llvm.AddGlobal(c.mod, globalType, objname)
global.SetInitializer(c.ctx.ConstString(str, false))
global.SetLinkage(llvm.InternalLinkage)
global.SetGlobalConstant(true)
global.SetUnnamedAddr(true)
global.SetAlignment(1)
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
- strPtr = llvm.ConstInBoundsGEP(global, []llvm.Value{zero, zero})
+ strPtr = llvm.ConstInBoundsGEP(globalType, global, []llvm.Value{zero, zero})
} else {
strPtr = llvm.ConstNull(c.i8ptrType)
}
@@ -2844,7 +2852,7 @@ func (b *builder) createConvert(typeFrom, typeTo types.Type, value llvm.Value, p
// create a GEP that is not in bounds. However, we're
// talking about unsafe code here so the programmer has to
// be careful anyway.
- return b.CreateInBoundsGEP(origptr, []llvm.Value{index}, ""), nil
+ return b.CreateInBoundsGEP(b.ctx.Int8Type(), origptr, []llvm.Value{index}, ""), nil
}
}
}
diff --git a/compiler/defer.go b/compiler/defer.go
index 1f892e5b..27e90331 100644
--- a/compiler/defer.go
+++ b/compiler/defer.go
@@ -407,7 +407,8 @@ func (b *builder) createDefer(instr *ssa.Defer) {
// createRunDefers emits code to run all deferred functions.
func (b *builder) createRunDefers() {
- deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)
+ deferType := b.getLLVMRuntimeType("_defer")
+ deferPtrType := llvm.PointerType(deferType, 0)
// Add a loop like the following:
// for stack != nil {
@@ -434,7 +435,7 @@ func (b *builder) createRunDefers() {
// Create loop head:
// for stack != nil {
b.SetInsertPointAtEnd(loophead)
- deferData := b.CreateLoad(deferType, b.deferPtr, "")
+ deferData := b.CreateLoad(deferPtrType, b.deferPtr, "")
stackIsNil := b.CreateICmp(llvm.IntEQ, deferData, llvm.ConstPointerNull(deferData.Type()), "stackIsNil")
b.CreateCondBr(stackIsNil, end, loop)
@@ -443,13 +444,13 @@ func (b *builder) createRunDefers() {
// stack = stack.next
// switch stack.callback {
b.SetInsertPointAtEnd(loop)
- nextStackGEP := b.CreateInBoundsGEP(deferData, []llvm.Value{
+ nextStackGEP := b.CreateInBoundsGEP(deferType, deferData, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 1, false), // .next field
}, "stack.next.gep")
- nextStack := b.CreateLoad(deferType, nextStackGEP, "stack.next")
+ nextStack := b.CreateLoad(deferPtrType, nextStackGEP, "stack.next")
b.CreateStore(nextStack, b.deferPtr)
- gep := b.CreateInBoundsGEP(deferData, []llvm.Value{
+ gep := b.CreateInBoundsGEP(deferType, deferData, []llvm.Value{
llvm.ConstInt(b.ctx.Int32Type(), 0, false),
llvm.ConstInt(b.ctx.Int32Type(), 0, false), // .callback field
}, "callback.gep")
@@ -489,7 +490,7 @@ func (b *builder) createRunDefers() {
forwardParams := []llvm.Value{}
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 2; i < len(valueTypes); i++ {
- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep")
+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep")
forwardParam := b.CreateLoad(valueTypes[i], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -538,7 +539,7 @@ func (b *builder) createRunDefers() {
forwardParams := []llvm.Value{}
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := range getParams(callback.Signature) {
- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -571,7 +572,7 @@ func (b *builder) createRunDefers() {
forwardParams := []llvm.Value{}
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 2; i < len(valueTypes); i++ {
- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "")
+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "")
forwardParam := b.CreateLoad(valueTypes[i], gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
@@ -598,7 +599,7 @@ func (b *builder) createRunDefers() {
var argValues []llvm.Value
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 0; i < params.Len(); i++ {
- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param")
argValues = append(argValues, forwardParam)
}
diff --git a/compiler/interface.go b/compiler/interface.go
index 72f8952d..acb474f5 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -122,19 +122,19 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value {
for i := 0; i < typ.NumFields(); i++ {
fieldGlobalValue := llvm.ConstNull(runtimeStructField)
fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0})
- fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type())
+ fieldNameType, fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type())
fieldName.SetLinkage(llvm.PrivateLinkage)
fieldName.SetUnnamedAddr(true)
- fieldName = llvm.ConstGEP(fieldName, []llvm.Value{
+ fieldName = llvm.ConstGEP(fieldNameType, fieldName, []llvm.Value{
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
})
fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldName, []uint32{1})
if typ.Tag(i) != "" {
- fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type())
+ fieldTagType, fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type())
fieldTag.SetLinkage(llvm.PrivateLinkage)
fieldTag.SetUnnamedAddr(true)
- fieldTag = llvm.ConstGEP(fieldTag, []llvm.Value{
+ fieldTag = llvm.ConstGEP(fieldTagType, fieldTag, []llvm.Value{
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
})
@@ -239,7 +239,7 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value {
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
if !global.IsNil() {
// the method set already exists
- return llvm.ConstGEP(global, []llvm.Value{zero, zero})
+ return llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{zero, zero})
}
ms := c.program.MethodSets.MethodSet(typ)
@@ -272,7 +272,7 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value {
global.SetInitializer(value)
global.SetGlobalConstant(true)
global.SetLinkage(llvm.LinkOnceODRLinkage)
- return llvm.ConstGEP(global, []llvm.Value{zero, zero})
+ return llvm.ConstGEP(arrayType, global, []llvm.Value{zero, zero})
}
// getInterfaceMethodSet returns a global variable with the method set of the
@@ -288,7 +288,7 @@ func (c *compilerContext) getInterfaceMethodSet(typ types.Type) llvm.Value {
zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
if !global.IsNil() {
// method set already exist, return it
- return llvm.ConstGEP(global, []llvm.Value{zero, zero})
+ return llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{zero, zero})
}
// Every method is a *i8 reference indicating the signature of this method.
@@ -303,7 +303,7 @@ func (c *compilerContext) getInterfaceMethodSet(typ types.Type) llvm.Value {
global.SetInitializer(value)
global.SetGlobalConstant(true)
global.SetLinkage(llvm.LinkOnceODRLinkage)
- return llvm.ConstGEP(global, []llvm.Value{zero, zero})
+ return llvm.ConstGEP(value.Type(), global, []llvm.Value{zero, zero})
}
// getMethodSignatureName returns a unique name (that can be used as the name of
diff --git a/compiler/llvm.go b/compiler/llvm.go
index 9540bcc6..686d4d2b 100644
--- a/compiler/llvm.go
+++ b/compiler/llvm.go
@@ -61,10 +61,10 @@ func (b *builder) emitPointerUnpack(ptr llvm.Value, valueTypes []llvm.Type) []ll
}
// makeGlobalArray creates a new LLVM global with the given name and integers as
-// contents, and returns the global.
+// contents, and returns the global and initializer type.
// Note that it is left with the default linkage etc., you should set
// linkage/constant/etc properties yourself.
-func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType llvm.Type) llvm.Value {
+func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType llvm.Type) (llvm.Type, llvm.Value) {
globalType := llvm.ArrayType(elementType, len(buf))
global := llvm.AddGlobal(c.mod, globalType, name)
value := llvm.Undef(globalType)
@@ -73,7 +73,7 @@ func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType l
value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)})
}
global.SetInitializer(value)
- return global
+ return globalType, global
}
// createObjectLayout returns a LLVM value (of type i8*) that describes where
diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go
index 97b86045..2a4607c8 100644
--- a/compiler/llvmutil/wordpack.go
+++ b/compiler/llvmutil/wordpack.go
@@ -58,7 +58,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
}
- gep := builder.CreateInBoundsGEP(packedAllocCast, indices, "")
+ gep := builder.CreateInBoundsGEP(packedType, packedAllocCast, indices, "")
builder.CreateStore(value, gep)
}
@@ -115,7 +115,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
}
- gep := builder.CreateInBoundsGEP(packedAlloc, indices, "")
+ gep := builder.CreateInBoundsGEP(packedType, packedAlloc, indices, "")
builder.CreateStore(value, gep)
}
@@ -170,7 +170,7 @@ func EmitPointerUnpack(builder llvm.Builder, mod llvm.Module, ptr llvm.Value, va
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
}
- gep := builder.CreateInBoundsGEP(packedAlloc, indices, "")
+ gep := builder.CreateInBoundsGEP(packedType, packedAlloc, indices, "")
values[i] = builder.CreateLoad(valueType, gep, "")
}
if !packedRawAlloc.IsNil() {
diff --git a/go.mod b/go.mod
index 26707a96..feb4e0d6 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11
gopkg.in/yaml.v2 v2.4.0
- tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6
+ tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634
)
require (
diff --git a/go.sum b/go.sum
index e5c734cd..907364f9 100644
--- a/go.sum
+++ b/go.sum
@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 h1:bJYUpmJrVm7Uluxh80qSivfeU3d9D4JNg5oJ+h9U+xc=
-tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 h1:hihbmHkJjalV4kGshoCF03P/G4IjoXcNAbzLblXLa/M=
+tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
diff --git a/interp/memory.go b/interp/memory.go
index 3a16b875..2fa6f5cb 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -646,8 +646,8 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
if llvmValue.Type() != mem.r.i8ptrType {
llvmValue = llvm.ConstBitCast(llvmValue, mem.r.i8ptrType)
}
- llvmValue = llvm.ConstInBoundsGEP(llvmValue, []llvm.Value{
- llvm.ConstInt(llvmValue.Type().Context().Int32Type(), uint64(v.offset()), false),
+ llvmValue = llvm.ConstInBoundsGEP(mem.r.mod.Context().Int8Type(), llvmValue, []llvm.Value{
+ llvm.ConstInt(mem.r.mod.Context().Int32Type(), uint64(v.offset()), false),
})
}
diff --git a/transform/gc.go b/transform/gc.go
index 7a4e99ac..3870a6b6 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -223,7 +223,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
// Update stack start.
parent := builder.CreateLoad(stackChainStartType, stackChainStart, "")
- gep := builder.CreateGEP(stackObject, []llvm.Value{
+ gep := builder.CreateGEP(stackObjectType, stackObject, []llvm.Value{
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), 0, false),
}, "")
@@ -244,7 +244,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
builder.SetInsertPointBefore(insertionPoint)
// Extract a pointer to the appropriate section of the stack object.
- gep := builder.CreateGEP(stackObject, []llvm.Value{
+ gep := builder.CreateGEP(stackObjectType, stackObject, []llvm.Value{
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false),
}, "")
diff --git a/transform/llvm.go b/transform/llvm.go
index 32ee9560..6716dd63 100644
--- a/transform/llvm.go
+++ b/transform/llvm.go
@@ -31,10 +31,10 @@ func hasUses(value llvm.Value) bool {
}
// makeGlobalArray creates a new LLVM global with the given name and integers as
-// contents, and returns the global.
+// contents, and returns the global and initializer type.
// Note that it is left with the default linkage etc., you should set
// linkage/constant/etc properties yourself.
-func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) llvm.Value {
+func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) (llvm.Type, llvm.Value) {
buf := reflect.ValueOf(bufItf)
globalType := llvm.ArrayType(elementType, buf.Len())
global := llvm.AddGlobal(mod, globalType, name)
@@ -44,7 +44,7 @@ func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementTy
value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)})
}
global.SetInitializer(value)
- return global
+ return globalType, global
}
// getGlobalBytes returns the slice contained in the array of the provided
@@ -64,8 +64,8 @@ func getGlobalBytes(global llvm.Value) []byte {
// function used for creating reflection sidetables, for example.
func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) llvm.Value {
oldGlobal := mod.NamedGlobal(name)
- global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType())
- gep := llvm.ConstGEP(global, []llvm.Value{
+ globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType())
+ gep := llvm.ConstGEP(globalType, global, []llvm.Value{
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
})
diff --git a/transform/stacksize.go b/transform/stacksize.go
index f1a3c93d..169f1454 100644
--- a/transform/stacksize.go
+++ b/transform/stacksize.go
@@ -59,7 +59,7 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string
defer irbuilder.Dispose()
for i, function := range functions {
for _, use := range functionMap[function] {
- ptr := llvm.ConstGEP(stackSizesGlobal, []llvm.Value{
+ ptr := llvm.ConstGEP(stackSizesGlobalType, stackSizesGlobal, []llvm.Value{
llvm.ConstInt(ctx.Int32Type(), 0, false),
llvm.ConstInt(ctx.Int32Type(), uint64(i), false),
})
--
2.36.1

View file

@ -1,578 +0,0 @@
From 6053c1c8528c63a669d070550bacd43f2f6a68e1 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Tue, 20 Sep 2022 23:26:49 +0200
Subject: [PATCH 12/18] all: replace llvm.Const* calls with builder.Create*
calls
A number of llvm.Const* functions (in particular extractvalue and
insertvalue) were removed in LLVM 15, so we have to use a builder
instead. This builder will create the same constant values, it simply
uses a different API.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
compiler/asserts.go | 2 +-
compiler/compiler.go | 23 ++++++++++++++++-------
compiler/interface.go | 20 ++++++++++----------
compiler/interrupt.go | 8 +++++---
compiler/llvm.go | 2 +-
interp/interpreter.go | 13 +++++++------
interp/memory.go | 8 ++++----
transform/gc.go | 2 +-
transform/interface-lowering.go | 14 +++++++-------
transform/interrupt.go | 7 ++++---
transform/llvm.go | 16 +++++++++-------
transform/reflect.go | 32 +++++++++++++++++++-------------
transform/rtcalls.go | 4 ++--
13 files changed, 86 insertions(+), 65 deletions(-)
diff --git a/compiler/asserts.go b/compiler/asserts.go
index 8d9efdde..2a5265e9 100644
--- a/compiler/asserts.go
+++ b/compiler/asserts.go
@@ -145,7 +145,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
}
// Make the maxBufSize actually the maximum allowed value (in number of
// elements in the channel buffer).
- maxBufSize = llvm.ConstUDiv(maxBufSize, llvm.ConstInt(b.uintptrType, elementSize, false))
+ maxBufSize = b.CreateUDiv(maxBufSize, llvm.ConstInt(b.uintptrType, elementSize, false), "")
// Make sure maxBufSize has the same type as bufSize.
if maxBufSize.Type() != bufSize.Type() {
diff --git a/compiler/compiler.go b/compiler/compiler.go
index c93b2e56..3d29628c 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -63,6 +63,7 @@ type compilerContext struct {
DumpSSA bool
mod llvm.Module
ctx llvm.Context
+ builder llvm.Builder // only used for constant operations
dibuilder *llvm.DIBuilder
cu llvm.Metadata
difiles map[string]llvm.Metadata
@@ -98,6 +99,7 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
}
c.ctx = llvm.NewContext()
+ c.builder = c.ctx.NewBuilder()
c.mod = c.ctx.NewModule(moduleName)
c.mod.SetTarget(config.Triple)
c.mod.SetDataLayout(c.targetData.String())
@@ -126,6 +128,12 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
return c
}
+// Dispose everything related to the context, _except_ for the IR module (and
+// the associated context).
+func (c *compilerContext) dispose() {
+ c.builder.Dispose()
+}
+
// builder contains all information relevant to build a single function.
type builder struct {
*compilerContext
@@ -256,6 +264,7 @@ func Sizes(machine llvm.TargetMachine) types.Sizes {
// CompilePackage compiles a single package to a LLVM module.
func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, machine llvm.TargetMachine, config *Config, dumpSSA bool) (llvm.Module, []error) {
c := newCompilerContext(moduleName, machine, config, dumpSSA)
+ defer c.dispose()
c.packageDir = pkg.OriginalDir()
c.embedGlobals = pkg.EmbedGlobals
c.pkg = pkg.Pkg
@@ -972,10 +981,10 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
for _, file := range allFiles {
fileStruct := llvm.ConstNull(embedFileStructType)
name := c.createConst(ssa.NewConst(constant.MakeString(file.Name), types.Typ[types.String]))
- fileStruct = llvm.ConstInsertValue(fileStruct, name, []uint32{0}) // "name" field
+ fileStruct = c.builder.CreateInsertValue(fileStruct, name, 0, "") // "name" field
if file.Hash != "" {
data := c.getEmbedFileString(file)
- fileStruct = llvm.ConstInsertValue(fileStruct, data, []uint32{1}) // "data" field
+ fileStruct = c.builder.CreateInsertValue(fileStruct, data, 1, "") // "data" field
}
fileStructs = append(fileStructs, fileStruct)
}
@@ -1006,7 +1015,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
// Define the embed.FS struct. It has only one field: the files (as a
// *[]embed.file).
globalInitializer := llvm.ConstNull(c.getLLVMType(member.Type().(*types.Pointer).Elem()))
- globalInitializer = llvm.ConstInsertValue(globalInitializer, sliceGlobal, []uint32{0})
+ globalInitializer = c.builder.CreateInsertValue(globalInitializer, sliceGlobal, 0, "")
global.SetInitializer(globalInitializer)
global.SetVisibility(llvm.HiddenVisibility)
global.SetAlignment(c.targetData.ABITypeAlignment(globalInitializer.Type()))
@@ -2757,15 +2766,15 @@ func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value {
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32]))
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32]))
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false))
- cplx = llvm.ConstInsertValue(cplx, r, []uint32{0})
- cplx = llvm.ConstInsertValue(cplx, i, []uint32{1})
+ cplx = c.builder.CreateInsertValue(cplx, r, 0, "")
+ cplx = c.builder.CreateInsertValue(cplx, i, 1, "")
return cplx
} else if typ.Kind() == types.Complex128 {
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64]))
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64]))
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false))
- cplx = llvm.ConstInsertValue(cplx, r, []uint32{0})
- cplx = llvm.ConstInsertValue(cplx, i, []uint32{1})
+ cplx = c.builder.CreateInsertValue(cplx, r, 0, "")
+ cplx = c.builder.CreateInsertValue(cplx, i, 1, "")
return cplx
} else {
panic("unknown constant of basic type: " + expr.String())
diff --git a/compiler/interface.go b/compiler/interface.go
index acb474f5..106c327a 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -88,20 +88,20 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
}
globalValue := llvm.ConstNull(global.Type().ElementType())
if !references.IsNil() {
- globalValue = llvm.ConstInsertValue(globalValue, references, []uint32{0})
+ globalValue = c.builder.CreateInsertValue(globalValue, references, 0, "")
}
if length != 0 {
lengthValue := llvm.ConstInt(c.uintptrType, uint64(length), false)
- globalValue = llvm.ConstInsertValue(globalValue, lengthValue, []uint32{1})
+ globalValue = c.builder.CreateInsertValue(globalValue, lengthValue, 1, "")
}
if !methodSet.IsNil() {
- globalValue = llvm.ConstInsertValue(globalValue, methodSet, []uint32{2})
+ globalValue = c.builder.CreateInsertValue(globalValue, methodSet, 2, "")
}
if !ptrTo.IsNil() {
- globalValue = llvm.ConstInsertValue(globalValue, ptrTo, []uint32{3})
+ globalValue = c.builder.CreateInsertValue(globalValue, ptrTo, 3, "")
}
if !typeAssert.IsNil() {
- globalValue = llvm.ConstInsertValue(globalValue, typeAssert, []uint32{4})
+ globalValue = c.builder.CreateInsertValue(globalValue, typeAssert, 4, "")
}
global.SetInitializer(globalValue)
global.SetLinkage(llvm.LinkOnceODRLinkage)
@@ -121,7 +121,7 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value {
structGlobalValue := llvm.ConstNull(structGlobalType)
for i := 0; i < typ.NumFields(); i++ {
fieldGlobalValue := llvm.ConstNull(runtimeStructField)
- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0})
+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), 0, "")
fieldNameType, fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type())
fieldName.SetLinkage(llvm.PrivateLinkage)
fieldName.SetUnnamedAddr(true)
@@ -129,7 +129,7 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value {
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
})
- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldName, []uint32{1})
+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldName, 1, "")
if typ.Tag(i) != "" {
fieldTagType, fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type())
fieldTag.SetLinkage(llvm.PrivateLinkage)
@@ -138,13 +138,13 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value {
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
llvm.ConstInt(c.ctx.Int32Type(), 0, false),
})
- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldTag, []uint32{2})
+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldTag, 2, "")
}
if typ.Field(i).Embedded() {
fieldEmbedded := llvm.ConstInt(c.ctx.Int1Type(), 1, false)
- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldEmbedded, []uint32{3})
+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldEmbedded, 3, "")
}
- structGlobalValue = llvm.ConstInsertValue(structGlobalValue, fieldGlobalValue, []uint32{uint32(i)})
+ structGlobalValue = c.builder.CreateInsertValue(structGlobalValue, fieldGlobalValue, i, "")
}
structGlobal.SetInitializer(structGlobalValue)
structGlobal.SetUnnamedAddr(true)
diff --git a/compiler/interrupt.go b/compiler/interrupt.go
index 45c7d074..c1f7d69f 100644
--- a/compiler/interrupt.go
+++ b/compiler/interrupt.go
@@ -49,9 +49,11 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
global.SetGlobalConstant(true)
global.SetUnnamedAddr(true)
initializer := llvm.ConstNull(globalLLVMType)
- initializer = llvm.ConstInsertValue(initializer, funcContext, []uint32{0})
- initializer = llvm.ConstInsertValue(initializer, funcPtr, []uint32{1})
- initializer = llvm.ConstInsertValue(initializer, llvm.ConstInt(b.intType, uint64(id.Int64()), true), []uint32{2, 0})
+ initializer = b.CreateInsertValue(initializer, funcContext, 0, "")
+ initializer = b.CreateInsertValue(initializer, funcPtr, 1, "")
+ initializer = b.CreateInsertValue(initializer, llvm.ConstNamedStruct(globalLLVMType.StructElementTypes()[2], []llvm.Value{
+ llvm.ConstInt(b.intType, uint64(id.Int64()), true),
+ }), 2, "")
global.SetInitializer(initializer)
// Add debug info to the interrupt global.
diff --git a/compiler/llvm.go b/compiler/llvm.go
index 686d4d2b..8b80869b 100644
--- a/compiler/llvm.go
+++ b/compiler/llvm.go
@@ -70,7 +70,7 @@ func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType l
value := llvm.Undef(globalType)
for i := 0; i < len(buf); i++ {
ch := uint64(buf[i])
- value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)})
+ value = c.builder.CreateInsertValue(value, llvm.ConstInt(elementType, ch, false), i, "")
}
global.SetInitializer(value)
return globalType, global
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 2c7fd8c3..d029aa33 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -408,7 +408,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
// Elem() is only valid for certain type classes.
switch class {
case "chan", "pointer", "slice", "array":
- elementType := llvm.ConstExtractValue(typecodeID.Initializer(), []uint32{0})
+ elementType := r.builder.CreateExtractValue(typecodeID.Initializer(), 0, "")
uintptrType := r.mod.Context().IntType(int(mem.r.pointerSize) * 8)
locals[inst.localIndex] = r.getValue(llvm.ConstPtrToInt(elementType, uintptrType))
default:
@@ -461,8 +461,8 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
// easier checking in the next step.
concreteTypeMethods := map[string]struct{}{}
for i := 0; i < methodSet.Type().ArrayLength(); i++ {
- methodInfo := llvm.ConstExtractValue(methodSet, []uint32{uint32(i)})
- name := llvm.ConstExtractValue(methodInfo, []uint32{0}).Name()
+ methodInfo := r.builder.CreateExtractValue(methodSet, i, "")
+ name := r.builder.CreateExtractValue(methodInfo, 0, "").Name()
concreteTypeMethods[name] = struct{}{}
}
@@ -496,7 +496,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
typecodeID := typecodeIDBitCast.Operand(0).Initializer()
// Load the method set, which is part of the typecodeID object.
- methodSet := llvm.ConstExtractValue(typecodeID, []uint32{2}).Operand(0).Initializer()
+ methodSet := r.builder.CreateExtractValue(typecodeID, 2, "").Operand(0).Initializer()
// We don't need to load the interface method set.
@@ -511,9 +511,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
numMethods := methodSet.Type().ArrayLength()
var method llvm.Value
for i := 0; i < numMethods; i++ {
- methodSignature := llvm.ConstExtractValue(methodSet, []uint32{uint32(i), 0})
+ methodSignatureAgg := r.builder.CreateExtractValue(methodSet, i, "")
+ methodSignature := r.builder.CreateExtractValue(methodSignatureAgg, 0, "")
if methodSignature == signature {
- method = llvm.ConstExtractValue(methodSet, []uint32{uint32(i), 1}).Operand(0)
+ method = r.builder.CreateExtractValue(methodSignatureAgg, 1, "").Operand(0)
}
}
if method.IsNil() {
diff --git a/interp/memory.go b/interp/memory.go
index 2fa6f5cb..583f9355 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -215,7 +215,7 @@ func (mv *memoryView) markExternal(llvmValue llvm.Value, mark uint8) error {
case llvm.StructTypeKind:
numElements := llvmType.StructElementTypesCount()
for i := 0; i < numElements; i++ {
- element := llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)})
+ element := mv.r.builder.CreateExtractValue(llvmValue, i, "")
err := mv.markExternal(element, mark)
if err != nil {
return err
@@ -224,7 +224,7 @@ func (mv *memoryView) markExternal(llvmValue llvm.Value, mark uint8) error {
case llvm.ArrayTypeKind:
numElements := llvmType.ArrayLength()
for i := 0; i < numElements; i++ {
- element := llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)})
+ element := mv.r.builder.CreateExtractValue(llvmValue, i, "")
err := mv.markExternal(element, mark)
if err != nil {
return err
@@ -1074,7 +1074,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) {
field := rawValue{
buf: v.buf[offset:],
}
- field.set(llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}), r)
+ field.set(r.builder.CreateExtractValue(llvmValue, i, ""), r)
}
case llvm.ArrayTypeKind:
numElements := llvmType.ArrayLength()
@@ -1085,7 +1085,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) {
field := rawValue{
buf: v.buf[offset:],
}
- field.set(llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}), r)
+ field.set(r.builder.CreateExtractValue(llvmValue, i, ""), r)
}
case llvm.DoubleTypeKind:
f, _ := llvmValue.DoubleValue()
diff --git a/transform/gc.go b/transform/gc.go
index 3870a6b6..514fb1bf 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -218,7 +218,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
initialStackObject := llvm.ConstNull(stackObjectType)
numSlots := (targetData.TypeAllocSize(stackObjectType) - uint64(targetData.PointerSize())*2) / uint64(targetData.ABITypeAlignment(uintptrType))
numSlotsValue := llvm.ConstInt(uintptrType, numSlots, false)
- initialStackObject = llvm.ConstInsertValue(initialStackObject, numSlotsValue, []uint32{1})
+ initialStackObject = builder.CreateInsertValue(initialStackObject, numSlotsValue, 1, "")
builder.CreateStore(initialStackObject, stackObject)
// Update stack start.
diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go
index f5b29e30..f28443dc 100644
--- a/transform/interface-lowering.go
+++ b/transform/interface-lowering.go
@@ -154,7 +154,7 @@ func (p *lowerInterfacesPass) run() error {
if initializer.IsNil() {
continue
}
- methodSet := llvm.ConstExtractValue(initializer, []uint32{2})
+ methodSet := p.builder.CreateExtractValue(initializer, 2, "")
p.addTypeMethods(t, methodSet)
}
}
@@ -288,9 +288,9 @@ func (p *lowerInterfacesPass) run() error {
zeroUintptr := llvm.ConstNull(p.uintptrType)
for _, t := range p.types {
initializer := t.typecode.Initializer()
- methodSet := llvm.ConstExtractValue(initializer, []uint32{2})
- initializer = llvm.ConstInsertValue(initializer, llvm.ConstNull(methodSet.Type()), []uint32{2})
- initializer = llvm.ConstInsertValue(initializer, zeroUintptr, []uint32{4})
+ methodSet := p.builder.CreateExtractValue(initializer, 2, "")
+ initializer = p.builder.CreateInsertValue(initializer, llvm.ConstNull(methodSet.Type()), 2, "")
+ initializer = p.builder.CreateInsertValue(initializer, zeroUintptr, 4, "")
t.typecode.SetInitializer(initializer)
}
@@ -311,10 +311,10 @@ func (p *lowerInterfacesPass) addTypeMethods(t *typeInfo, methodSet llvm.Value)
t.methodSet = methodSet
set := methodSet.Initializer() // get value from global
for i := 0; i < set.Type().ArrayLength(); i++ {
- methodData := llvm.ConstExtractValue(set, []uint32{uint32(i)})
- signatureGlobal := llvm.ConstExtractValue(methodData, []uint32{0})
+ methodData := p.builder.CreateExtractValue(set, i, "")
+ signatureGlobal := p.builder.CreateExtractValue(methodData, 0, "")
signatureName := signatureGlobal.Name()
- function := llvm.ConstExtractValue(methodData, []uint32{1}).Operand(0)
+ function := p.builder.CreateExtractValue(methodData, 1, "").Operand(0)
signature := p.getSignature(signatureName)
method := &methodInfo{
function: function,
diff --git a/transform/interrupt.go b/transform/interrupt.go
index 2c301be0..b15ff8a9 100644
--- a/transform/interrupt.go
+++ b/transform/interrupt.go
@@ -44,7 +44,8 @@ func LowerInterrupts(mod llvm.Module) []error {
// Get the interrupt number from the initializer
initializer := global.Initializer()
- num := llvm.ConstExtractValue(initializer, []uint32{2, 0}).SExtValue()
+ interrupt := builder.CreateExtractValue(initializer, 2, "")
+ num := builder.CreateExtractValue(interrupt, 0, "").SExtValue()
pkg := packageFromInterruptHandle(global)
handles, exists := handleMap[num]
@@ -89,8 +90,8 @@ func LowerInterrupts(mod llvm.Module) []error {
builder.SetInsertPointBefore(call)
for _, handler := range handlers {
initializer := handler.Initializer()
- context := llvm.ConstExtractValue(initializer, []uint32{0})
- funcPtr := llvm.ConstExtractValue(initializer, []uint32{1}).Operand(0)
+ context := builder.CreateExtractValue(initializer, 0, "")
+ funcPtr := builder.CreateExtractValue(initializer, 1, "").Operand(0)
builder.CreateCall(funcPtr.GlobalValueType(), funcPtr, []llvm.Value{
num,
context,
diff --git a/transform/llvm.go b/transform/llvm.go
index 6716dd63..17968f8a 100644
--- a/transform/llvm.go
+++ b/transform/llvm.go
@@ -36,25 +36,27 @@ func hasUses(value llvm.Value) bool {
// linkage/constant/etc properties yourself.
func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) (llvm.Type, llvm.Value) {
buf := reflect.ValueOf(bufItf)
- globalType := llvm.ArrayType(elementType, buf.Len())
- global := llvm.AddGlobal(mod, globalType, name)
- value := llvm.Undef(globalType)
+ var values []llvm.Value
for i := 0; i < buf.Len(); i++ {
ch := buf.Index(i).Uint()
- value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)})
+ values = append(values, llvm.ConstInt(elementType, ch, false))
}
+ value := llvm.ConstArray(elementType, values)
+ global := llvm.AddGlobal(mod, value.Type(), name)
global.SetInitializer(value)
- return globalType, global
+ return value.Type(), global
}
// getGlobalBytes returns the slice contained in the array of the provided
// global. It can recover the bytes originally created using makeGlobalArray, if
// makeGlobalArray was given a byte slice.
-func getGlobalBytes(global llvm.Value) []byte {
+//
+// The builder parameter is only used for constant operations.
+func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte {
value := global.Initializer()
buf := make([]byte, value.Type().ArrayLength())
for i := range buf {
- buf[i] = byte(llvm.ConstExtractValue(value, []uint32{uint32(i)}).ZExtValue())
+ buf[i] = byte(builder.CreateExtractValue(value, i, "").ZExtValue())
}
return buf
}
diff --git a/transform/reflect.go b/transform/reflect.go
index fd70ccb7..68beba9b 100644
--- a/transform/reflect.go
+++ b/transform/reflect.go
@@ -76,6 +76,10 @@ var nonBasicTypes = map[string]int64{
// typeCodeAssignmentState keeps some global state around for type code
// assignments, used to assign one unique type code to each Go type.
type typeCodeAssignmentState struct {
+ // Builder used purely for constant operations (because LLVM 15 removed many
+ // llvm.Const* functions).
+ builder llvm.Builder
+
// An integer that's incremented each time it's used to give unique IDs to
// type codes that are not yet fully supported otherwise by the reflect
// package (or are simply unused in the compiled program).
@@ -165,6 +169,7 @@ func LowerReflect(mod llvm.Module) {
defer targetData.Dispose()
uintptrType := mod.Context().IntType(targetData.PointerSize() * 8)
state := typeCodeAssignmentState{
+ builder: mod.Context().NewBuilder(),
fallbackIndex: 1,
uintptrLen: targetData.PointerSize() * 8,
namedBasicTypes: make(map[string]int),
@@ -177,6 +182,7 @@ func LowerReflect(mod llvm.Module) {
needsStructNamesSidetable: len(getUses(mod.NamedGlobal("reflect.structNamesSidetable"))) != 0,
needsArrayTypesSidetable: len(getUses(mod.NamedGlobal("reflect.arrayTypesSidetable"))) != 0,
}
+ defer state.builder.Dispose()
for _, t := range types {
num := state.getTypeCodeNum(t.typecode)
if num.BitLen() > state.uintptrLen || !num.IsUint64() {
@@ -238,7 +244,7 @@ func LowerReflect(mod llvm.Module) {
// It also cleans up the IR for testing.
for _, typ := range types {
initializer := typ.typecode.Initializer()
- references := llvm.ConstExtractValue(initializer, []uint32{0})
+ references := state.builder.CreateExtractValue(initializer, 0, "")
typ.typecode.SetInitializer(llvm.ConstNull(initializer.Type()))
if strings.HasPrefix(typ.name, "reflect/types.type:struct:") {
// Structs have a 'references' field that is not a typecode but
@@ -260,7 +266,7 @@ func (state *typeCodeAssignmentState) getTypeCodeNum(typecode llvm.Value) *big.I
name := ""
if class == "named" {
name = value
- typecode = llvm.ConstExtractValue(typecode.Initializer(), []uint32{0})
+ typecode = state.builder.CreateExtractValue(typecode.Initializer(), 0, "")
class, value = getClassAndValueFromTypeCode(typecode)
}
if class == "basic" {
@@ -344,7 +350,7 @@ func (state *typeCodeAssignmentState) getNonBasicTypeCode(class string, typecode
switch class {
case "chan", "pointer", "slice":
// Prefix-style type kinds. The upper bits contain the element type.
- sub := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0})
+ sub := state.builder.CreateExtractValue(typecode.Initializer(), 0, "")
return state.getTypeCodeNum(sub)
case "array":
// An array is basically a pair of (typecode, length) stored in a
@@ -416,7 +422,7 @@ func (state *typeCodeAssignmentState) getArrayTypeNum(typecode llvm.Value) int {
return num
}
- elemTypeCode := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0})
+ elemTypeCode := state.builder.CreateExtractValue(typecode.Initializer(), 0, "")
elemTypeNum := state.getTypeCodeNum(elemTypeCode)
if elemTypeNum.BitLen() > state.uintptrLen || !elemTypeNum.IsUint64() {
// TODO: make this a regular error
@@ -424,7 +430,7 @@ func (state *typeCodeAssignmentState) getArrayTypeNum(typecode llvm.Value) int {
}
// The array side table is a sequence of {element type, array length}.
- arrayLength := llvm.ConstExtractValue(typecode.Initializer(), []uint32{1}).ZExtValue()
+ arrayLength := state.builder.CreateExtractValue(typecode.Initializer(), 1, "").ZExtValue()
buf := makeVarint(elemTypeNum.Uint64())
buf = append(buf, makeVarint(arrayLength)...)
@@ -454,7 +460,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
// Get the fields this struct type contains.
// The struct number will be the start index of
- structTypeGlobal := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0}).Operand(0).Initializer()
+ structTypeGlobal := state.builder.CreateExtractValue(typecode.Initializer(), 0, "").Operand(0).Initializer()
numFields := structTypeGlobal.Type().ArrayLength()
// The first data that is stored in the struct sidetable is the number of
@@ -471,28 +477,28 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
// the sidetable bigger.
for i := 0; i < numFields; i++ {
// Collect some information about this field.
- field := llvm.ConstExtractValue(structTypeGlobal, []uint32{uint32(i)})
+ field := state.builder.CreateExtractValue(structTypeGlobal, i, "")
- nameGlobal := llvm.ConstExtractValue(field, []uint32{1})
+ nameGlobal := state.builder.CreateExtractValue(field, 1, "")
if nameGlobal == llvm.ConstPointerNull(nameGlobal.Type()) {
panic("compiler: no name for this struct field")
}
- fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0))
+ fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0), state.builder)
fieldNameNumber := state.getStructNameNumber(fieldNameBytes)
// See whether this struct field has an associated tag, and if so,
// store that tag in the tags sidetable.
- tagGlobal := llvm.ConstExtractValue(field, []uint32{2})
+ tagGlobal := state.builder.CreateExtractValue(field, 2, "")
hasTag := false
tagNumber := 0
if tagGlobal != llvm.ConstPointerNull(tagGlobal.Type()) {
hasTag = true
- tagBytes := getGlobalBytes(tagGlobal.Operand(0))
+ tagBytes := getGlobalBytes(tagGlobal.Operand(0), state.builder)
tagNumber = state.getStructNameNumber(tagBytes)
}
// The 'embedded' or 'anonymous' flag for this field.
- embedded := llvm.ConstExtractValue(field, []uint32{3}).ZExtValue() != 0
+ embedded := state.builder.CreateExtractValue(field, 3, "").ZExtValue() != 0
// The first byte in the struct types sidetable is a flags byte with
// two bits in it.
@@ -510,7 +516,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int
// Get the type number and add it to the buffer.
// All fields have a type, so include it directly here.
- typeNum := state.getTypeCodeNum(llvm.ConstExtractValue(field, []uint32{0}))
+ typeNum := state.getTypeCodeNum(state.builder.CreateExtractValue(field, 0, ""))
if typeNum.BitLen() > state.uintptrLen || !typeNum.IsUint64() {
// TODO: make this a regular error
panic("struct field has a type code that is too big")
diff --git a/transform/rtcalls.go b/transform/rtcalls.go
index 2f17f815..d70bc626 100644
--- a/transform/rtcalls.go
+++ b/transform/rtcalls.go
@@ -149,7 +149,7 @@ func OptimizeReflectImplements(mod llvm.Module) {
interfaceType := interfaceTypeBitCast.Operand(0)
if strings.HasPrefix(interfaceType.Name(), "reflect/types.type:named:") {
// Get the underlying type.
- interfaceType = llvm.ConstExtractValue(interfaceType.Initializer(), []uint32{0})
+ interfaceType = builder.CreateExtractValue(interfaceType.Initializer(), 0, "")
}
if !strings.HasPrefix(interfaceType.Name(), "reflect/types.type:interface:") {
// This is an error. The Type passed to Implements should be of
@@ -161,7 +161,7 @@ func OptimizeReflectImplements(mod llvm.Module) {
// Interface is unknown at compile time. This can't be optimized.
continue
}
- typeAssertFunction := llvm.ConstExtractValue(interfaceType.Initializer(), []uint32{4}).Operand(0)
+ typeAssertFunction := builder.CreateExtractValue(interfaceType.Initializer(), 4, "").Operand(0)
// Replace Implements call with the type assert call.
builder.SetInsertPointBefore(call)
--
2.36.1

View file

@ -1,79 +0,0 @@
From 1004deaafd70d4eb94196977c20a5b1a17cded81 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Thu, 22 Sep 2022 01:06:40 +0200
Subject: [PATCH 13/18] interp: change object.llvmType to the initializer type
Previously it was a pointer type, which won't work with opaque pointers.
Instead, use the global initializer type instead.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
go.mod | 2 +-
go.sum | 4 ++--
interp/interpreter.go | 2 +-
interp/memory.go | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/go.mod b/go.mod
index feb4e0d6..a50f1174 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11
gopkg.in/yaml.v2 v2.4.0
- tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634
+ tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec
)
require (
diff --git a/go.sum b/go.sum
index 907364f9..4af03408 100644
--- a/go.sum
+++ b/go.sum
@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 h1:hihbmHkJjalV4kGshoCF03P/G4IjoXcNAbzLblXLa/M=
-tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec h1:FYtAFrw/YQPc644uNN65dW50FrEuVNaPBf70x23ApY4=
+tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
diff --git a/interp/interpreter.go b/interp/interpreter.go
index d029aa33..8c783a70 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -637,7 +637,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
// Create the new object.
size := operands[0].(literalValue).value.(uint64)
alloca := object{
- llvmType: inst.llvmInst.Type(),
+ llvmType: inst.llvmInst.AllocatedType(),
globalName: r.pkgName + "$alloca",
buffer: newRawValue(uint32(size)),
size: uint32(size),
diff --git a/interp/memory.go b/interp/memory.go
index 583f9355..6a537bad 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -37,7 +37,7 @@ import (
// ability to roll back interpreting a function.
type object struct {
llvmGlobal llvm.Value
- llvmType llvm.Type // must match llvmGlobal.Type() if both are set, may be unset if llvmGlobal is set
+ llvmType llvm.Type // must match llvmGlobal.GlobalValueType() if both are set, may be unset if llvmGlobal is set
llvmLayoutType llvm.Type // LLVM type based on runtime.alloc layout parameter, if available
globalName string // name, if not yet created (not guaranteed to be the final name)
buffer value // buffer with value as given by interp, nil if external
@@ -594,7 +594,7 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val
var globalType llvm.Type
if !obj.llvmType.IsNil() {
// The exact type is known.
- globalType = obj.llvmType.ElementType()
+ globalType = obj.llvmType
} else { // !obj.llvmLayoutType.IsNil()
// The exact type isn't known, but the object layout is known.
globalType = obj.llvmLayoutType
--
2.36.1

View file

@ -1,586 +0,0 @@
From 0cdaa0f6db40e372db24d945b557d03b97ff92e9 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Thu, 22 Sep 2022 13:33:00 +0200
Subject: [PATCH 14/18] all: remove pointer ElementType calls
This is needed for opaque pointers, which are enabled by default in
LLVM 15.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/build.go | 4 +--
compiler/asserts.go | 4 +--
compiler/calls.go | 58 ++++++++++++++-------------------
compiler/compiler.go | 15 +++++----
compiler/func.go | 2 +-
compiler/interface.go | 4 +--
compiler/ircheck/check.go | 5 +--
compiler/symbol.go | 15 ++-------
interp/compiler.go | 21 ++++++++----
interp/interp.go | 10 +++---
interp/interpreter.go | 2 +-
interp/memory.go | 23 +++++++------
transform/allocs.go | 2 +-
transform/gc.go | 4 +--
transform/interface-lowering.go | 2 +-
transform/llvm.go | 2 +-
transform/wasm-abi.go | 2 +-
17 files changed, 82 insertions(+), 93 deletions(-)
diff --git a/builder/build.go b/builder/build.go
index 7a7dd9ac..488ee823 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -418,7 +418,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
return errors.New("global not found: " + globalName)
}
name := global.Name()
- newGlobal := llvm.AddGlobal(mod, global.Type().ElementType(), name+".tmp")
+ newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp")
global.ReplaceAllUsesWith(newGlobal)
global.EraseFromParentAsGlobal()
newGlobal.SetName(name)
@@ -1134,7 +1134,7 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro
// A strin is a {ptr, len} pair. We need these types to build the
// initializer.
- initializerType := global.Type().ElementType()
+ initializerType := global.GlobalValueType()
if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" {
return fmt.Errorf("%s: not a string", globalName)
}
diff --git a/compiler/asserts.go b/compiler/asserts.go
index 2a5265e9..ba482494 100644
--- a/compiler/asserts.go
+++ b/compiler/asserts.go
@@ -91,7 +91,7 @@ func (b *builder) createSliceToArrayPointerCheck(sliceLen llvm.Value, arrayLen i
// createUnsafeSliceCheck inserts a runtime check used for unsafe.Slice. This
// function must panic if the ptr/len parameters are invalid.
-func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Basic) {
+func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, elementType llvm.Type, lenType *types.Basic) {
// From the documentation of unsafe.Slice:
// > At run time, if len is negative, or if ptr is nil and len is not
// > zero, a run-time panic occurs.
@@ -105,7 +105,7 @@ func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Bas
// Determine the maximum slice size, and therefore the maximum value of the
// len parameter.
- maxSize := b.maxSliceSize(ptr.Type().ElementType())
+ maxSize := b.maxSliceSize(elementType)
maxSizeValue := llvm.ConstInt(len.Type(), maxSize, false)
// Do the check. By using unsigned greater than for the length check, signed
diff --git a/compiler/calls.go b/compiler/calls.go
index b38d770f..b122f0c8 100644
--- a/compiler/calls.go
+++ b/compiler/calls.go
@@ -20,7 +20,7 @@ const maxFieldsPerParam = 3
type paramInfo struct {
llvmType llvm.Type
name string // name, possibly with suffixes for e.g. struct fields
- flags paramFlags
+ elemSize uint64 // size of pointer element type, or 0 if this isn't a pointer
}
// paramFlags identifies parameter attributes for flags. Most importantly, it
@@ -96,13 +96,7 @@ func (c *compilerContext) expandFormalParamType(t llvm.Type, name string, goType
// failed to expand this parameter: too many fields
}
// TODO: split small arrays
- return []paramInfo{
- {
- llvmType: t,
- name: name,
- flags: getTypeFlags(goType),
- },
- }
+ return []paramInfo{c.getParamInfo(t, name, goType)}
}
// expandFormalParamOffsets returns a list of offsets from the start of an
@@ -152,7 +146,6 @@ func (b *builder) expandFormalParam(v llvm.Value) []llvm.Value {
// Try to flatten a struct type to a list of types. Returns a 1-element slice
// with the passed in type if this is not possible.
func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType types.Type) []paramInfo {
- typeFlags := getTypeFlags(goType)
switch t.TypeKind() {
case llvm.StructTypeKind:
var paramInfos []paramInfo
@@ -183,40 +176,37 @@ func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType
}
}
subInfos := c.flattenAggregateType(subfield, name+"."+suffix, extractSubfield(goType, i))
- for i := range subInfos {
- subInfos[i].flags |= typeFlags
- }
paramInfos = append(paramInfos, subInfos...)
}
return paramInfos
default:
- return []paramInfo{
- {
- llvmType: t,
- name: name,
- flags: typeFlags,
- },
- }
+ return []paramInfo{c.getParamInfo(t, name, goType)}
}
}
-// getTypeFlags returns the type flags for a given type. It will not recurse
-// into sub-types (such as in structs).
-func getTypeFlags(t types.Type) paramFlags {
- if t == nil {
- return 0
+// getParamInfo collects information about a parameter. For example, if this
+// parameter is pointer-like, it will also store the element type for the
+// dereferenceable_or_null attribute.
+func (c *compilerContext) getParamInfo(t llvm.Type, name string, goType types.Type) paramInfo {
+ info := paramInfo{
+ llvmType: t,
+ name: name,
}
- switch t.Underlying().(type) {
- case *types.Pointer:
- // Pointers in Go must either point to an object or be nil.
- return paramIsDeferenceableOrNull
- case *types.Chan, *types.Map:
- // Channels and maps are implemented as pointers pointing to some
- // object, and follow the same rules as *types.Pointer.
- return paramIsDeferenceableOrNull
- default:
- return 0
+ if goType != nil {
+ switch underlying := goType.Underlying().(type) {
+ case *types.Pointer:
+ // Pointers in Go must either point to an object or be nil.
+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMType(underlying.Elem()))
+ case *types.Chan:
+ // Channels are implemented simply as a *runtime.channel.
+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("channel"))
+ case *types.Map:
+ // Maps are similar to channels: they are implemented as a
+ // *runtime.hashmap.
+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("hashmap"))
+ }
}
+ return info
}
// extractSubfield extracts a field from a struct, or returns null if this is
diff --git a/compiler/compiler.go b/compiler/compiler.go
index 3d29628c..fc47c29c 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -862,7 +862,7 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
if files, ok := c.embedGlobals[member.Name()]; ok {
c.createEmbedGlobal(member, global, files)
} else if !info.extern {
- global.SetInitializer(llvm.ConstNull(global.Type().ElementType()))
+ global.SetInitializer(llvm.ConstNull(global.GlobalValueType()))
global.SetVisibility(llvm.HiddenVisibility)
if info.section != "" {
global.SetSection(info.section)
@@ -1405,7 +1405,7 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
b.CreateRet(b.getValue(instr.Results[0]))
} else {
// Multiple return values. Put them all in a struct.
- retVal := llvm.ConstNull(b.llvmFn.Type().ElementType().ReturnType())
+ retVal := llvm.ConstNull(b.llvmFn.GlobalValueType().ReturnType())
for i, result := range instr.Results {
val := b.getValue(result)
retVal = b.CreateInsertValue(retVal, val, i, "")
@@ -1444,7 +1444,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
elemsBuf := b.CreateExtractValue(elems, 0, "append.elemsBuf")
elemsPtr := b.CreateBitCast(elemsBuf, b.i8ptrType, "append.srcPtr")
elemsLen := b.CreateExtractValue(elems, 1, "append.elemsLen")
- elemType := srcBuf.Type().ElementType()
+ elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem())
elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false)
result := b.createRuntimeCall("sliceAppend", []llvm.Value{srcPtr, elemsPtr, srcLen, srcCap, elemsLen, elemSize}, "append.new")
newPtr := b.CreateExtractValue(result, 0, "append.newPtr")
@@ -1497,7 +1497,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
srcLen := b.CreateExtractValue(src, 1, "copy.srcLen")
dstBuf := b.CreateExtractValue(dst, 0, "copy.dstArray")
srcBuf := b.CreateExtractValue(src, 0, "copy.srcArray")
- elemType := dstBuf.Type().ElementType()
+ elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem())
dstBuf = b.CreateBitCast(dstBuf, b.i8ptrType, "copy.dstPtr")
srcBuf = b.CreateBitCast(srcBuf, b.i8ptrType, "copy.srcPtr")
elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false)
@@ -1637,7 +1637,8 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
b.uintptrType,
b.uintptrType,
}, false))
- b.createUnsafeSliceCheck(ptr, len, argTypes[1].Underlying().(*types.Basic))
+ elementType := b.getLLVMType(argTypes[0].Underlying().(*types.Pointer).Elem())
+ b.createUnsafeSliceCheck(ptr, len, elementType, argTypes[1].Underlying().(*types.Basic))
if len.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() {
// Too small, zero-extend len.
len = b.CreateZExt(len, b.uintptrType, "")
@@ -1712,7 +1713,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
// Eventually we might be able to eliminate this special case
// entirely. For details, see:
// https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c/60521
- calleeType = llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false)
+ calleeType = llvm.FunctionType(callee.GlobalValueType().ReturnType(), nil, false)
callee = llvm.ConstBitCast(callee, llvm.PointerType(calleeType, b.funcPtrAddrSpace))
}
case *ssa.MakeClosure:
@@ -3095,7 +3096,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
}
case token.MUL: // *x, dereference pointer
valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem())
- if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 {
+ if b.targetData.TypeAllocSize(valueType) == 0 {
// zero-length data
return llvm.ConstNull(valueType), nil
} else if strings.HasSuffix(unop.X.String(), "$funcaddr") {
diff --git a/compiler/func.go b/compiler/func.go
index c6a8802d..4203fdf7 100644
--- a/compiler/func.go
+++ b/compiler/func.go
@@ -73,7 +73,7 @@ func (c *compilerContext) getFuncType(typ *types.Signature) llvm.Type {
return c.ctx.StructType([]llvm.Type{c.i8ptrType, c.rawVoidFuncType}, false)
}
-// getRawFuncType returns a LLVM function pointer type for a given signature.
+// getRawFuncType returns a LLVM function type for a given signature.
func (c *compilerContext) getRawFuncType(typ *types.Signature) llvm.Type {
// Get the return type.
var returnType llvm.Type
diff --git a/compiler/interface.go b/compiler/interface.go
index 106c327a..2007b7d7 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -86,7 +86,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
if _, ok := typ.Underlying().(*types.Pointer); !ok {
ptrTo = c.getTypeCode(types.NewPointer(typ))
}
- globalValue := llvm.ConstNull(global.Type().ElementType())
+ globalValue := llvm.ConstNull(global.GlobalValueType())
if !references.IsNil() {
globalValue = c.builder.CreateInsertValue(globalValue, references, 0, "")
}
@@ -533,7 +533,7 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFnType
receiverValue := b.emitPointerUnpack(wrapper.Param(0), []llvm.Type{receiverType})[0]
params := append(b.expandFormalParam(receiverValue), wrapper.Params()[1:]...)
- if llvmFn.Type().ElementType().ReturnType().TypeKind() == llvm.VoidTypeKind {
+ if llvmFnType.ReturnType().TypeKind() == llvm.VoidTypeKind {
b.CreateCall(llvmFnType, llvmFn, params, "")
b.CreateRetVoid()
} else {
diff --git a/compiler/ircheck/check.go b/compiler/ircheck/check.go
index 30c6ee17..e2b7ed51 100644
--- a/compiler/ircheck/check.go
+++ b/compiler/ircheck/check.go
@@ -70,10 +70,7 @@ func (c *checker) checkType(t llvm.Type, checked map[llvm.Type]struct{}, special
return fmt.Errorf("failed to verify element type of array type %s: %s", t.String(), err.Error())
}
case llvm.PointerTypeKind:
- // check underlying type
- if err := c.checkType(t.ElementType(), checked, specials); err != nil {
- return fmt.Errorf("failed to verify underlying type of pointer type %s: %s", t.String(), err.Error())
- }
+ // Pointers can't be checked in an opaque pointer world.
case llvm.VectorTypeKind:
// check element type
if err := c.checkType(t.ElementType(), checked, specials); err != nil {
diff --git a/compiler/symbol.go b/compiler/symbol.go
index 83fe050b..01b3fc37 100644
--- a/compiler/symbol.go
+++ b/compiler/symbol.go
@@ -83,7 +83,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
// Add an extra parameter as the function context. This context is used in
// closures and bound methods, but should be optimized away when not used.
if !info.exported {
- paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", flags: 0})
+ paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", elemSize: 0})
}
var paramTypes []llvm.Type
@@ -112,17 +112,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
dereferenceableOrNullKind := llvm.AttributeKindID("dereferenceable_or_null")
for i, info := range paramInfos {
- if info.flags&paramIsDeferenceableOrNull == 0 {
- continue
- }
- if info.llvmType.TypeKind() == llvm.PointerTypeKind {
- el := info.llvmType.ElementType()
- size := c.targetData.TypeAllocSize(el)
- if size == 0 {
- // dereferenceable_or_null(0) appears to be illegal in LLVM.
- continue
- }
- dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, size)
+ if info.elemSize != 0 {
+ dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, info.elemSize)
llvmFn.AddAttributeAtIndex(i+1, dereferenceableOrNull)
}
}
diff --git a/interp/compiler.go b/interp/compiler.go
index 20723c64..ffef69e5 100644
--- a/interp/compiler.go
+++ b/interp/compiler.go
@@ -209,7 +209,7 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
case llvm.Alloca:
// Alloca allocates stack space for local variables.
numElements := r.getValue(inst.llvmInst.Operand(0)).(literalValue).value.(uint32)
- elementSize := r.targetData.TypeAllocSize(inst.llvmInst.Type().ElementType())
+ elementSize := r.targetData.TypeAllocSize(inst.llvmInst.AllocatedType())
inst.operands = []value{
literalValue{elementSize * uint64(numElements)},
}
@@ -218,17 +218,17 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
inst.name = llvmInst.Name()
ptr := llvmInst.Operand(0)
n := llvmInst.OperandsCount()
- elementType := ptr.Type().ElementType()
+ elementType := llvmInst.GEPSourceElementType()
// gep: [source ptr, dest value size, pairs of indices...]
inst.operands = []value{
r.getValue(ptr),
- literalValue{r.targetData.TypeAllocSize(llvmInst.Type().ElementType())},
r.getValue(llvmInst.Operand(1)),
literalValue{r.targetData.TypeAllocSize(elementType)},
}
for i := 2; i < n; i++ {
operand := r.getValue(llvmInst.Operand(i))
- if elementType.TypeKind() == llvm.StructTypeKind {
+ switch elementType.TypeKind() {
+ case llvm.StructTypeKind:
index := operand.(literalValue).value.(uint32)
elementOffset := r.targetData.ElementOffset(elementType, int(index))
// Encode operands in a special way. The elementOffset
@@ -242,12 +242,15 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
// runtime.
inst.operands = append(inst.operands, literalValue{elementOffset}, literalValue{^uint64(index)})
elementType = elementType.StructElementTypes()[index]
- } else {
+ case llvm.ArrayTypeKind:
elementType = elementType.ElementType()
elementSize := r.targetData.TypeAllocSize(elementType)
elementSizeOperand := literalValue{elementSize}
// Add operand * elementSizeOperand bytes to the pointer.
inst.operands = append(inst.operands, operand, elementSizeOperand)
+ default:
+ // This should be unreachable.
+ panic("unknown type: " + elementType.String())
}
}
case llvm.BitCast, llvm.IntToPtr, llvm.PtrToInt:
@@ -267,10 +270,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
case llvm.StructTypeKind:
offset += r.targetData.ElementOffset(indexingType, int(index))
indexingType = indexingType.StructElementTypes()[index]
- default: // ArrayTypeKind
+ case llvm.ArrayTypeKind:
indexingType = indexingType.ElementType()
elementSize := r.targetData.TypeAllocSize(indexingType)
offset += elementSize * uint64(index)
+ default:
+ panic("unknown type kind") // unreachable
}
}
size := r.targetData.TypeAllocSize(inst.llvmInst.Type())
@@ -290,10 +295,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
case llvm.StructTypeKind:
offset += r.targetData.ElementOffset(indexingType, int(index))
indexingType = indexingType.StructElementTypes()[index]
- default: // ArrayTypeKind
+ case llvm.ArrayTypeKind:
indexingType = indexingType.ElementType()
elementSize := r.targetData.TypeAllocSize(indexingType)
offset += elementSize * uint64(index)
+ default:
+ panic("unknown type kind") // unreachable
}
}
// insertvalue [agg, elt, byteOffset]
diff --git a/interp/interp.go b/interp/interp.go
index 856f08b1..7833dfe9 100644
--- a/interp/interp.go
+++ b/interp/interp.go
@@ -156,7 +156,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
if obj.constant {
continue // constant buffers can't have been modified
}
- initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem)
+ initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem)
if err == errInvalidPtrToIntSize {
// This can happen when a previous interp run did not have the
// correct LLVM type for a global and made something up. In that
@@ -190,7 +190,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
if err != nil {
return err
}
- if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() {
+ if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() {
panic("initializer type mismatch")
}
obj.llvmGlobal.SetInitializer(initializer)
@@ -213,7 +213,7 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error {
r.pkgName = initName[:len(initName)-len(".init")]
// Create new function with the interp result.
- newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.Type().ElementType())
+ newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.GlobalValueType())
newFn.SetLinkage(fn.Linkage())
newFn.SetVisibility(fn.Visibility())
entry := mod.Context().AddBasicBlock(newFn, "entry")
@@ -263,11 +263,11 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error {
if obj.constant {
continue // constant, so can't have been modified
}
- initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem)
+ initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem)
if err != nil {
return err
}
- if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() {
+ if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() {
panic("initializer type mismatch")
}
obj.llvmGlobal.SetInitializer(initializer)
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 8c783a70..c438b4b6 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -655,7 +655,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
// GetElementPtr does pointer arithmetic, changing the offset of the
// pointer into the underlying object.
var offset uint64
- for i := 2; i < len(operands); i += 2 {
+ for i := 1; i < len(operands); i += 2 {
index := operands[i].Uint()
elementSize := operands[i+1].Uint()
if int64(elementSize) < 0 {
diff --git a/interp/memory.go b/interp/memory.go
index 6a537bad..82ab716d 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -808,14 +808,17 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
if err != nil {
return llvm.Value{}, err
}
- elementType := field.Type().ElementType()
- if elementType.TypeKind() == llvm.StructTypeKind {
- // There are some special pointer types that should be used as a
- // ptrtoint, so that they can be used in certain optimizations.
- name := elementType.StructName()
- if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" {
- uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
- field = llvm.ConstPtrToInt(field, uintptrType)
+ if !field.IsAGlobalVariable().IsNil() {
+ elementType := field.GlobalValueType()
+ if elementType.TypeKind() == llvm.StructTypeKind {
+ // There are some special pointer types that should be used
+ // as a ptrtoint, so that they can be used in certain
+ // optimizations.
+ name := elementType.StructName()
+ if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" {
+ uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
+ field = llvm.ConstPtrToInt(field, uintptrType)
+ }
}
}
structFields = append(structFields, field)
@@ -998,7 +1001,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) {
ptr := llvmValue.Operand(0)
index := llvmValue.Operand(1)
numOperands := llvmValue.OperandsCount()
- elementType := ptr.Type().ElementType()
+ elementType := llvmValue.GEPSourceElementType()
totalOffset := r.targetData.TypeAllocSize(elementType) * index.ZExtValue()
for i := 2; i < numOperands; i++ {
indexValue := llvmValue.Operand(i)
@@ -1173,7 +1176,7 @@ func (r *runner) getValue(llvmValue llvm.Value) value {
r.globals[llvmValue] = index
r.objects = append(r.objects, obj)
if !llvmValue.IsAGlobalVariable().IsNil() {
- obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.Type().ElementType()))
+ obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.GlobalValueType()))
if initializer := llvmValue.Initializer(); !initializer.IsNil() {
obj.buffer = r.getValue(initializer)
obj.constant = llvmValue.IsGlobalConstant()
diff --git a/transform/allocs.go b/transform/allocs.go
index af7c70b2..5be7df2d 100644
--- a/transform/allocs.go
+++ b/transform/allocs.go
@@ -124,7 +124,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
alloca.SetAlignment(alignment)
// Zero the allocation inside the block where the value was originally allocated.
- zero := llvm.ConstNull(alloca.Type().ElementType())
+ zero := llvm.ConstNull(alloca.AllocatedType())
builder.SetInsertPointBefore(bitcast)
store := builder.CreateStore(zero, alloca)
store.SetAlignment(alignment)
diff --git a/transform/gc.go b/transform/gc.go
index 514fb1bf..e2d23987 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -18,7 +18,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
stackChainStart := mod.NamedGlobal("runtime.stackChainStart")
if !stackChainStart.IsNil() {
stackChainStart.SetLinkage(llvm.InternalLinkage)
- stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.Type().ElementType()))
+ stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.GlobalValueType()))
stackChainStart.SetGlobalConstant(true)
}
return false
@@ -96,7 +96,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
return false
}
stackChainStart.SetLinkage(llvm.InternalLinkage)
- stackChainStartType := stackChainStart.Type().ElementType()
+ stackChainStartType := stackChainStart.GlobalValueType()
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStartType))
// Iterate until runtime.trackPointer has no uses left.
diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go
index f28443dc..9e2ffa90 100644
--- a/transform/interface-lowering.go
+++ b/transform/interface-lowering.go
@@ -423,7 +423,7 @@ func (p *lowerInterfacesPass) defineInterfaceImplementsFunc(fn llvm.Value, itf *
func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *interfaceInfo, signature *signatureInfo) {
context := fn.LastParam()
actualType := llvm.PrevParam(context)
- returnType := fn.Type().ElementType().ReturnType()
+ returnType := fn.GlobalValueType().ReturnType()
context.SetName("context")
actualType.SetName("actualType")
fn.SetLinkage(llvm.InternalLinkage)
diff --git a/transform/llvm.go b/transform/llvm.go
index 17968f8a..7042b32d 100644
--- a/transform/llvm.go
+++ b/transform/llvm.go
@@ -66,7 +66,7 @@ func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte {
// function used for creating reflection sidetables, for example.
func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) llvm.Value {
oldGlobal := mod.NamedGlobal(name)
- globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType())
+ globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.GlobalValueType())
gep := llvm.ConstGEP(globalType, global, []llvm.Value{
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go
index 064e38f4..83a16d85 100644
--- a/transform/wasm-abi.go
+++ b/transform/wasm-abi.go
@@ -50,7 +50,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
paramTypes := []llvm.Type{}
// Check return type for 64-bit integer.
- fnType := fn.Type().ElementType()
+ fnType := fn.GlobalValueType()
returnType := fnType.ReturnType()
if returnType == int64Type {
hasInt64 = true
--
2.36.1

View file

@ -1,31 +0,0 @@
From 6bf7aa1623b6d7d9a269df876453af22b1c54c2d Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Wed, 12 Oct 2022 21:46:50 +0200
Subject: [PATCH 15/18] transform: fix memory corruption issues
There was a bug in the wasm ABI lowering pass (found using
AddressSanitizer on LLVM 15) that resulted in a rather subtle memory
corruption. This commit fixes this issues.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
transform/wasm-abi.go | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go
index 83a16d85..08122a3e 100644
--- a/transform/wasm-abi.go
+++ b/transform/wasm-abi.go
@@ -88,8 +88,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
// Update all users to call the external function.
// The old $i64wrapper function could be removed, but it may as well
// be left in place.
- for use := fn.FirstUse(); !use.IsNil(); use = use.NextUse() {
- call := use.User()
+ for _, call := range getUses(fn) {
entryBlockBuilder.SetInsertPointBefore(call.InstructionParent().Parent().EntryBasicBlock().FirstInstruction())
builder.SetInsertPointBefore(call)
callParams := []llvm.Value{}
--
2.36.1

View file

@ -1,193 +0,0 @@
From 003963ddc796960ce498361409a9d121366b1c42 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Wed, 12 Oct 2022 22:05:38 +0000
Subject: [PATCH 16/18] riscv: add "target-abi" metadata flag
This flag is necessary in LLVM 15 because it appears that LLVM 15 has
changed the default target ABI from lp64 to lp64d. This results in a
linker failure. Setting the "target-abi" forces the RISC-V backend to
use the intended target ABI.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/build.go | 1 +
builder/library.go | 7 +++++--
compileopts/config.go | 13 +++++++++++++
compileopts/target.go | 1 +
compiler/compiler.go | 13 +++++++++++++
compiler/compiler_test.go | 1 +
targets/riscv32.json | 4 ++--
targets/riscv64.json | 4 ++--
8 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/builder/build.go b/builder/build.go
index 488ee823..4818185f 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -170,6 +170,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
Triple: config.Triple(),
CPU: config.CPU(),
Features: config.Features(),
+ ABI: config.ABI(),
GOOS: config.GOOS(),
GOARCH: config.GOARCH(),
CodeModel: config.CodeModel(),
diff --git a/builder/library.go b/builder/library.go
index 385f1610..87822d15 100644
--- a/builder/library.go
+++ b/builder/library.go
@@ -155,6 +155,9 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
args = append(args, "-mcpu="+cpu)
}
}
+ if config.ABI() != "" {
+ args = append(args, "-mabi="+config.ABI())
+ }
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
if strings.Split(target, "-")[2] == "linux" {
args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
@@ -170,10 +173,10 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
args = append(args, "-mdouble=64")
}
if strings.HasPrefix(target, "riscv32-") {
- args = append(args, "-march=rv32imac", "-mabi=ilp32", "-fforce-enable-int128")
+ args = append(args, "-march=rv32imac", "-fforce-enable-int128")
}
if strings.HasPrefix(target, "riscv64-") {
- args = append(args, "-march=rv64gc", "-mabi=lp64")
+ args = append(args, "-march=rv64gc")
}
if strings.HasPrefix(target, "xtensa") {
// Hack to work around an issue in the Xtensa port:
diff --git a/compileopts/config.go b/compileopts/config.go
index cd49283d..80ea8cff 100644
--- a/compileopts/config.go
+++ b/compileopts/config.go
@@ -47,6 +47,12 @@ func (c *Config) Features() string {
return c.Target.Features + "," + c.Options.LLVMFeatures
}
+// ABI returns the -mabi= flag for this target (like -mabi=lp64). A zero-length
+// string is returned if the target doesn't specify an ABI.
+func (c *Config) ABI() string {
+ return c.Target.ABI
+}
+
// GOOS returns the GOOS of the target. This might not always be the actual OS:
// for example, bare-metal targets will usually pretend to be linux to get the
// standard library to compile.
@@ -230,6 +236,9 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) {
if c.CPU() != "" {
archname += "-" + c.CPU()
}
+ if c.ABI() != "" {
+ archname += "-" + c.ABI()
+ }
// Try to load a precompiled library.
precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name)
@@ -335,6 +344,10 @@ func (c *Config) CFlags() []string {
cflags = append(cflags, "-mcpu="+c.Target.CPU)
}
}
+ // Set the -mabi flag, if needed.
+ if c.ABI() != "" {
+ cflags = append(cflags, "-mabi="+c.ABI())
+ }
return cflags
}
diff --git a/compileopts/target.go b/compileopts/target.go
index 865b8afe..c26c870e 100644
--- a/compileopts/target.go
+++ b/compileopts/target.go
@@ -26,6 +26,7 @@ type TargetSpec struct {
Inherits []string `json:"inherits"`
Triple string `json:"llvm-target"`
CPU string `json:"cpu"`
+ ABI string `json:"target-abi"` // rougly equivalent to -mabi= flag
Features string `json:"features"`
GOOS string `json:"goos"`
GOARCH string `json:"goarch"`
diff --git a/compiler/compiler.go b/compiler/compiler.go
index fc47c29c..8b6e8661 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -41,6 +41,7 @@ type Config struct {
Triple string
CPU string
Features string
+ ABI string
GOOS string
GOARCH string
CodeModel string
@@ -321,6 +322,18 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
c.dibuilder.Destroy()
}
+ // Add the "target-abi" flag, which is necessary on RISC-V otherwise it will
+ // pick one that doesn't match the -mabi Clang flag.
+ if c.ABI != "" {
+ c.mod.AddNamedMetadataOperand("llvm.module.flags",
+ c.ctx.MDNode([]llvm.Metadata{
+ llvm.ConstInt(c.ctx.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch
+ c.ctx.MDString("target-abi"),
+ c.ctx.MDString(c.ABI),
+ }),
+ )
+ }
+
return c.mod, c.diagnostics
}
diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go
index 2ed26921..a5cd9c6b 100644
--- a/compiler/compiler_test.go
+++ b/compiler/compiler_test.go
@@ -73,6 +73,7 @@ func TestCompiler(t *testing.T) {
compilerConfig := &Config{
Triple: config.Triple(),
Features: config.Features(),
+ ABI: config.ABI(),
GOOS: config.GOOS(),
GOARCH: config.GOARCH(),
CodeModel: config.CodeModel(),
diff --git a/targets/riscv32.json b/targets/riscv32.json
index c3c8dff5..a2878089 100644
--- a/targets/riscv32.json
+++ b/targets/riscv32.json
@@ -1,12 +1,12 @@
{
"inherits": ["riscv"],
"llvm-target": "riscv32-unknown-none",
+ "target-abi": "ilp32",
"build-tags": ["tinygo.riscv32"],
"scheduler": "tasks",
"default-stack-size": 2048,
"cflags": [
- "-march=rv32imac",
- "-mabi=ilp32"
+ "-march=rv32imac"
],
"ldflags": [
"-melf32lriscv"
diff --git a/targets/riscv64.json b/targets/riscv64.json
index c2378e97..fc45c91c 100644
--- a/targets/riscv64.json
+++ b/targets/riscv64.json
@@ -1,10 +1,10 @@
{
"inherits": ["riscv"],
"llvm-target": "riscv64-unknown-none",
+ "target-abi": "lp64",
"build-tags": ["tinygo.riscv64"],
"cflags": [
- "-march=rv64gc",
- "-mabi=lp64"
+ "-march=rv64gc"
],
"ldflags": [
"-melf64lriscv"
--
2.36.1

View file

@ -1,195 +0,0 @@
From 76f42a3fac44ac6d07c53b10ddadb683ca019684 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Tue, 18 Oct 2022 23:16:36 +0000
Subject: [PATCH 17/18] interp: add support for constant icmp instructions
These instructions sometimes pop up in LLVM 15, but they never occured
in LLVM 14. Implementing them is relatively straightforward: simply
generalize the code that already exists for llvm.ICmp interpreting.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
interp/interpreter.go | 84 +++++++++++++++++---------------
interp/memory.go | 11 +++++
interp/testdata/consteval.ll | 15 ++++++
interp/testdata/consteval.out.ll | 1 +
4 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/interp/interpreter.go b/interp/interpreter.go
index c438b4b6..83fd2cd9 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -723,46 +723,9 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
locals[inst.localIndex] = newagg
case llvm.ICmp:
predicate := llvm.IntPredicate(operands[2].(literalValue).value.(uint8))
- var result bool
lhs := operands[0]
rhs := operands[1]
- switch predicate {
- case llvm.IntEQ, llvm.IntNE:
- lhsPointer, lhsErr := lhs.asPointer(r)
- rhsPointer, rhsErr := rhs.asPointer(r)
- if (lhsErr == nil) != (rhsErr == nil) {
- // Fast path: only one is a pointer, so they can't be equal.
- result = false
- } else if lhsErr == nil {
- // Both must be nil, so both are pointers.
- // Compare them directly.
- result = lhsPointer.equal(rhsPointer)
- } else {
- // Fall back to generic comparison.
- result = lhs.asRawValue(r).equal(rhs.asRawValue(r))
- }
- if predicate == llvm.IntNE {
- result = !result
- }
- case llvm.IntUGT:
- result = lhs.Uint() > rhs.Uint()
- case llvm.IntUGE:
- result = lhs.Uint() >= rhs.Uint()
- case llvm.IntULT:
- result = lhs.Uint() < rhs.Uint()
- case llvm.IntULE:
- result = lhs.Uint() <= rhs.Uint()
- case llvm.IntSGT:
- result = lhs.Int() > rhs.Int()
- case llvm.IntSGE:
- result = lhs.Int() >= rhs.Int()
- case llvm.IntSLT:
- result = lhs.Int() < rhs.Int()
- case llvm.IntSLE:
- result = lhs.Int() <= rhs.Int()
- default:
- return nil, mem, r.errorAt(inst, errors.New("interp: unsupported icmp"))
- }
+ result := r.interpretICmp(lhs, rhs, predicate)
if result {
locals[inst.localIndex] = literalValue{uint8(1)}
} else {
@@ -948,6 +911,51 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
return nil, mem, r.errorAt(bb.instructions[len(bb.instructions)-1], errors.New("interp: reached end of basic block without terminator"))
}
+// Interpret an icmp instruction. Doesn't have side effects, only returns the
+// output of the comparison.
+func (r *runner) interpretICmp(lhs, rhs value, predicate llvm.IntPredicate) bool {
+ switch predicate {
+ case llvm.IntEQ, llvm.IntNE:
+ var result bool
+ lhsPointer, lhsErr := lhs.asPointer(r)
+ rhsPointer, rhsErr := rhs.asPointer(r)
+ if (lhsErr == nil) != (rhsErr == nil) {
+ // Fast path: only one is a pointer, so they can't be equal.
+ result = false
+ } else if lhsErr == nil {
+ // Both must be nil, so both are pointers.
+ // Compare them directly.
+ result = lhsPointer.equal(rhsPointer)
+ } else {
+ // Fall back to generic comparison.
+ result = lhs.asRawValue(r).equal(rhs.asRawValue(r))
+ }
+ if predicate == llvm.IntNE {
+ result = !result
+ }
+ return result
+ case llvm.IntUGT:
+ return lhs.Uint() > rhs.Uint()
+ case llvm.IntUGE:
+ return lhs.Uint() >= rhs.Uint()
+ case llvm.IntULT:
+ return lhs.Uint() < rhs.Uint()
+ case llvm.IntULE:
+ return lhs.Uint() <= rhs.Uint()
+ case llvm.IntSGT:
+ return lhs.Int() > rhs.Int()
+ case llvm.IntSGE:
+ return lhs.Int() >= rhs.Int()
+ case llvm.IntSLT:
+ return lhs.Int() < rhs.Int()
+ case llvm.IntSLE:
+ return lhs.Int() <= rhs.Int()
+ default:
+ // _should_ be unreachable, until LLVM adds new icmp operands (unlikely)
+ panic("interp: unsupported icmp")
+ }
+}
+
func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, mem *memoryView, indent string) *Error {
numOperands := inst.llvmInst.OperandsCount()
operands := make([]llvm.Value, numOperands)
diff --git a/interp/memory.go b/interp/memory.go
index 82ab716d..248825f6 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -1031,6 +1031,17 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) {
for i := uint32(0); i < ptrSize; i++ {
v.buf[i] = ptrValue.pointer
}
+ case llvm.ICmp:
+ size := r.targetData.TypeAllocSize(llvmValue.Operand(0).Type())
+ lhs := newRawValue(uint32(size))
+ rhs := newRawValue(uint32(size))
+ lhs.set(llvmValue.Operand(0), r)
+ rhs.set(llvmValue.Operand(1), r)
+ if r.interpretICmp(lhs, rhs, llvmValue.IntPredicate()) {
+ v.buf[0] = 1 // result is true
+ } else {
+ v.buf[0] = 0 // result is false
+ }
default:
llvmValue.Dump()
println()
diff --git a/interp/testdata/consteval.ll b/interp/testdata/consteval.ll
index 9afb9ff7..d0c0e3b6 100644
--- a/interp/testdata/consteval.ll
+++ b/interp/testdata/consteval.ll
@@ -3,6 +3,7 @@ target triple = "x86_64--linux"
@intToPtrResult = global i8 0
@ptrToIntResult = global i8 0
+@icmpResult = global i8 0
@someArray = internal global {i16, i8, i8} zeroinitializer
@someArrayPointer = global i8* zeroinitializer
@@ -15,6 +16,7 @@ define internal void @main.init() {
call void @testIntToPtr()
call void @testPtrToInt()
call void @testConstGEP()
+ call void @testICmp()
ret void
}
@@ -48,3 +50,16 @@ define internal void @testConstGEP() {
store i8* getelementptr inbounds (i8, i8* bitcast ({i16, i8, i8}* @someArray to i8*), i32 2), i8** @someArrayPointer
ret void
}
+
+define internal void @testICmp() {
+ br i1 icmp eq (i64 ptrtoint (i8* @ptrToIntResult to i64), i64 0), label %equal, label %unequal
+equal:
+ ; should not be reached
+ store i8 1, i8* @icmpResult
+ ret void
+unequal:
+ ; should be reached
+ store i8 2, i8* @icmpResult
+ ret void
+ ret void
+}
diff --git a/interp/testdata/consteval.out.ll b/interp/testdata/consteval.out.ll
index 5fac449e..08d74c85 100644
--- a/interp/testdata/consteval.out.ll
+++ b/interp/testdata/consteval.out.ll
@@ -3,6 +3,7 @@ target triple = "x86_64--linux"
@intToPtrResult = local_unnamed_addr global i8 2
@ptrToIntResult = local_unnamed_addr global i8 2
+@icmpResult = local_unnamed_addr global i8 2
@someArray = internal global { i16, i8, i8 } zeroinitializer
@someArrayPointer = local_unnamed_addr global i8* getelementptr inbounds ({ i16, i8, i8 }, { i16, i8, i8 }* @someArray, i64 0, i32 1)
--
2.36.1

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
#!/bin/bash -e
CMSIS_VERSION=9fe411cef1cef5de58e5957b89760759de44e393
CMSIS_SVD_VERSION=df75ff974c76a911fc2815e29807f5ecaae06fc2
CMSIS_SVD_DATA_VERSION=05a9562ec59b87945a8d7177a4b08b7aa2f2fd58
if [ -e "cmsis-${CMSIS_VERSION}-clean.tar.xz" ]; then
echo "Not downloading cmsis-${CMSIS_VERSION}-clean.tar.xz again!"
else
# The license for this tarball is complicated, but the headers are under a
# simple BSD license, so we only package them.
# The license for this tarball is complicated, but the headers are under the
# BSD-3-Clause license, so we only package them.
wget -nc https://github.com/ARM-software/CMSIS/archive/${CMSIS_VERSION}/cmsis-${CMSIS_VERSION}.tar.gz
tar xf cmsis-${CMSIS_VERSION}.tar.gz
tar cJf cmsis-${CMSIS_VERSION}-clean.tar.xz \
@ -16,24 +16,52 @@ tar cJf cmsis-${CMSIS_VERSION}-clean.tar.xz \
rm -r CMSIS-${CMSIS_VERSION}/
fi
if [ -e "cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz" ]; then
echo "Not downloading cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz again!"
if [ -e "cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz" ]; then
echo "Not downloading cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz again!"
else
# This is basically a "collection of random stuff" from various vendors, under
# various licenses. Some licenses are non-free and some are actively hostile,
# but we only need a rather small portion under a good license.
#wget https://github.com/posborne/cmsis-svd/archive/${CMSIS_SVD_VERSION}/cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz
wget -nc https://github.com/tinygo-org/cmsis-svd/archive/${CMSIS_SVD_VERSION}/cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz
tar xf cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz
tar cJf cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz \
cmsis-svd-${CMSIS_SVD_VERSION}/data/Atmel/ \
cmsis-svd-${CMSIS_SVD_VERSION}/data/Espressif/ \
cmsis-svd-${CMSIS_SVD_VERSION}/data/Espressif-Community/ \
cmsis-svd-${CMSIS_SVD_VERSION}/data/Kendryte-Community/ \
cmsis-svd-${CMSIS_SVD_VERSION}/data/SiFive-Community/ \
cmsis-svd-${CMSIS_SVD_VERSION}/data/NXP/M* \
cmsis-svd-${CMSIS_SVD_VERSION}/data/RaspberryPi/ \
# This has a weird license, so we cannot include it.
# cmsis-svd-${CMSIS_SVD_VERSION}/data/STMicro/
rm -r cmsis-svd-${CMSIS_SVD_VERSION}/
# but we only need a rather small portion under a good license:
# - Atmel: Apache-2.0 AND BSD-Source-Code
# - Espressif: Apache-2.0
# - Espressif-Community: Apache-2.0 OR MIT
# - Kendryte-Community: ISC
# - Nordic: BSD-3-Clause
# - NXP/L*: Proprietary, so not included.
# - NXP/Q*: Unknown, so not included.
# - NXP/M*: BSD-3-Clause
# - RaspberryPi: BSD-3-Clause
# - Renesas: Proprietary
# - SiFive-Community: ISC AND (Apache-2.0 OR MIT)
# - STMicro: Apache-2.0 AND Proprietary, so only a subset included.
# These directories are not used by TinyGo, so are not kept:
# - ARM_SAMPLE: BSD-3-Clause
# - Allwinner-Community: Apache-2.0 OR MIT
# - ArteryTek: BSD-3-Clause
# - Cypress: Apache-2.0
# - Freescale: Proprietary
# - Fujitsu: Proprietary
# - GigaDevice: Apache-2.0
# - Holtek: Proprietary
# - Infineon: Proprietary
# - Nuvoton: Unknown
# - SiliconLabs: Zlib
# - Spansion: Proprietary
# - TexasInstruments: Proprietary
# - Toshiba: Unknown
wget -nc https://github.com/cmsis-svd/cmsis-svd-data/archive/${CMSIS_SVD_DATA_VERSION}/cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}.tar.gz
tar xf cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}.tar.gz
mapfile -t clean_stmicro < <(grep -Rl '^ *SPDX-License-Identifier: Apache-2.0$' \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/STMicro/*.svd)
tar cJf cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Atmel/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Espressif/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Espressif-Community/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Kendryte-Community/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Nordic/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/NXP/M* \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/RaspberryPi/ \
cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/SiFive-Community/ \
"${clean_stmicro[@]}"
rm -r cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/
fi

View file

@ -0,0 +1,38 @@
>From e5adcd97b5196e29991b524237381a0202a60659 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sun, 9 Feb 2025 10:07:19 -0500
Subject: [PATCH] iconv: fix erroneous input validation in EUC-KR decoder
as a result of incorrect bounds checking on the lead byte being
decoded, certain invalid inputs which should produce an encoding
error, such as "\xc8\x41", instead produced out-of-bounds loads from
the ksc table.
in a worst case, the loaded value may not be a valid unicode scalar
value, in which case, if the output encoding was UTF-8, wctomb would
return (size_t)-1, causing an overflow in the output pointer and
remaining buffer size which could clobber memory outside of the output
buffer.
bug report was submitted in private by Nick Wellnhofer on account of
potential security implications.
---
src/locale/iconv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index 9605c8e9..008c93f0 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
if (c >= 93 || d >= 94) {
c += (0xa1-0x81);
d += 0xa1;
- if (c >= 93 || c>=0xc6-0x81 && d>0x52)
+ if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
goto ilseq;
if (d-'A'<26) d = d-'A';
else if (d-'a'<26) d = d-'a'+26;
--
2.21.0

View file

@ -0,0 +1,38 @@
>From c47ad25ea3b484e10326f933e927c0bc8cded3da Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Wed, 12 Feb 2025 17:06:30 -0500
Subject: [PATCH] iconv: harden UTF-8 output code path against input decoder
bugs
the UTF-8 output code was written assuming an invariant that iconv's
decoders only emit valid Unicode Scalar Values which wctomb can encode
successfully, thereby always returning a value between 1 and 4.
if this invariant is not satisfied, wctomb returns (size_t)-1, and the
subsequent adjustments to the output buffer pointer and remaining
output byte count overflow, moving the output position backwards,
potentially past the beginning of the buffer, without storing any
bytes.
---
src/locale/iconv.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index 008c93f0..52178950 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
if (*outb < k) goto toobig;
memcpy(*out, tmp, k);
} else k = wctomb_utf8(*out, c);
+ /* This failure condition should be unreachable, but
+ * is included to prevent decoder bugs from translating
+ * into advancement outside the output buffer range. */
+ if (k>4) goto ilseq;
*out += k;
*outb -= k;
break;
--
2.21.0

21
sources
View file

@ -1,12 +1,15 @@
SHA512 (tinygo-0.26.0.tar.gz) = 7b95f6b4356545b806207092fa315863446227e3f90d05abad1f231b381d402b00654e11ab79472c32d5572ea7183bdd4e5ee34190a13e3aefa668ebcd1042b4
SHA512 (tinygo-0.39.0.tar.gz) = ab9dbe6bfac56470d3703617bd0da152b044e84ced1bfcfb7e7bf6ba8880d07dfac267dca7356ace18bd3ed392ed7031b6cb4a2535ad5f956ab5912ecefe3807
SHA512 (avr-6624554c02b237b23dc17d53e992bf54033fc228.tar.gz) = 1aa157bd761db38f8680614fa1cf47d7009508f65291b7eaaa5aba1ae76d35103f68a42947b7269a170d2f1cf8fb09941a5d74070fe6d204b68dd15a9ad2ed29
SHA512 (bdwgc-1166f11f7dee08d7ad369296b24cf8c9582f8789.tar.gz) = 030d5a9a0931915a76b1ec270e7208199cf40973ac6c8141c02e34f118f965bedcadff3bb36481b0e45703df8eb2750d20809f3fde367fd5efed5f8a44ccab32
SHA512 (cmsis-9fe411cef1cef5de58e5957b89760759de44e393-clean.tar.xz) = f131fc241f61982c49f334eb502c2f13da61eb7bdaa641ee84a8de30c4d576b735b8aadeafd7d75351473a2df6a42de6a236ecc5dcc616ee6cfcc07af29446f9
SHA512 (cmsis_svd-df75ff974c76a911fc2815e29807f5ecaae06fc2-clean.tar.xz) = 8abbc6f366aed9571a74a4b6e7065ed2d6a59e0495c3745681d9a654d61edd136319788741f7afc781211adb64ed1faeafe9d6acc6be5a16d9ee48e98c5ddeb1
SHA512 (compiler-rt-15.0.0.src.tar.xz) = 25763e581c90923260b7c3a03e220feb4cabb2757e418c4940db0eeb6a17f65b35db0c93d3c1e526adad2f6dc93595bec6d99b1bfb4a1bd13a14a0db5301e6cf
SHA512 (compiler-rt-15.0.0.src.tar.xz.sig) = 94f39d2e30372ccea4db96c3dd4005a5b44c2bf5d22fa0aaf45b86673ef7d3460884689f97bc96470db2d546042fb01fe3ca41bf22b6323abe0cd785b85d76ef
SHA512 (macos-minimal-sdk-ebb736fda2bec7cea38dcda807518b835a539525.tar.gz) = 2f97d5826c79116c851e1efde74faf806de56ac8acc5509d1ab7690d0edf88f6e227b273d2c5ef7d894a8ada2e316e285ef4e58d74ca0c6f91584653154eae10
SHA512 (musl-1.2.0.tar.gz) = 58bd88189a6002356728cea1c6f6605a893fe54f7687595879add4eab283c8692c3b031eb9457ad00d1edd082cfe62fcc0eb5eb1d3bf4f1d749c0efa2a95fec1
SHA512 (musl-1.2.0.tar.gz.asc) = 1639d1f39f3c587011cc6e1ae44774d20d306f4d18fb394bfa86c40f52af53a882ebd5326553b589a1c5316494b77658dc3310c0187836dfd1fd023ccfedaaf0
SHA512 (cmsis_svd_data-05a9562ec59b87945a8d7177a4b08b7aa2f2fd58-clean.tar.xz) = e8ba9d74fb148dfa8b3ba140d307b243fb38378f69544529455eea5df57d4276b7177d3549228f8acadc4e72c94506456e78025d9b16d606b322fda8ab38327d
SHA512 (compiler-rt-19.1.7.src.tar.xz) = e2e8e6a094525b84184e9e4a4c1a727de518d4ef1a91370515f0c955719dc946fd60e7fabd10f52ab1905ef6d4a86084b8ddfb9b45de838aa1c5ddf3c042748b
SHA512 (compiler-rt-19.1.7.src.tar.xz.sig) = 48550377345331bfa0015d2c5bb6e063507a76e950f8f349a8e6877d35428a11d86bd617ea7a048f1584a42c58da924ef523d622b54ce4ca94eaa12ce290b49c
SHA512 (macos-minimal-sdk-e7c72156eac3ebf29c34cc2faa71efcb1296663f.tar.gz) = 44638fa9786e88327eb5a2f5cf06c8f09149f21b2592802bdd2db04cbdf4dfbee1bc9296af1b7745c4e30ac97f26a714e19168b742526a8a1b4f8ce23d8fa789
SHA512 (mingw64-8526cb618269440a94810b94b77f8bd48c5c3396.tar.gz) = 723d1ac22d8026f31b59d39328f711f36976798445a82daddcdc9fa6ab4346a5030e9c2efc84ef009439b8f021c5c7c120cfa083a7912a5b0212ac6852c005a7
SHA512 (musl-1.2.3.tar.gz) = 9332f713d3eb7de4369bc0327d99252275ee52abf523ee34b894b24a387f67579787f7c72a46cf652e090cffdb0bc3719a4e7b84dca66890b6a37f12e8ad089c
SHA512 (musl-1.2.3.tar.gz.asc) = 01a857dbc3981c90244d4d1d883efe51986652ca5734a741c9d1a4d06c5a22831e85520ac67212268b70c22049317a8f39b3219be182e7e67741add428ac5bc6
SHA512 (net-c134160ae47d38b468b1c5ade43e78ad5a1e616d.tar.gz) = 449149af6bca15fa0fe1a9a8b37b3cab3bf83b177dd78d760fcca561bbacb415d6c7f0a355edf8d0de1b934d13fbce9d307c2a4410f1ff1c3bfe71b28e76b228
SHA512 (nrfx-d779b49fc59c7a165e7da1d7cd7d57b28a059f16.tar.gz) = 31c7fc6fd88d4a74e5739b29659cb717a4629480d17d84e491d61c36c435aba16d38ef63d1036e508666a17eeaac5f11a5ff83211f88410f30cc2e152146ee83
SHA512 (picolibc-f68b8204f797d6b3bfbc7c4da4d257961fbc8770.tar.gz) = fa58a7ddcb1a40239a220ca701a83895804b9ddc837652fa18e9aed2603bba2825df2074e2fa4fbf8649bb9a21308e877850273ec9d421795e2ae549f331ab13
SHA512 (wasi-libc-30094b6ed05f19cee102115215863d185f2db4f0.tar.gz) = 17492263fd5dca422f19e0ff8533e1f440e3b7516dc24ef0d16fdc44832cc63ec288c9e930f63b47fb71497144fed55cc313acc74339d067b8d4f5c7c683df0f
SHA512 (picolibc-b92edfda8ac6853772d87cadaeeeaa21b78609b6.tar.gz) = 9fb60d81bd98c96264c81e95cab6622ccacb34da285f7f3c137bd3cd8bc6e87cbc065a2e9d9fdfc7b93eec52f33bbfa70b6d0abc1a30551ebec1af351344cc39
SHA512 (wasi-libc-wasi-sdk-20.tar.gz) = e264240dc7dbcf6398c8ca09bc108298f4a8aa955af22de5a3015fbcde81cb09dd83cd48349090082d5de0e8a3dbcf746c7b14657c67657b3f2f1ab28bb9cf05

View file

@ -1,27 +1,30 @@
# Generated by go2rpm 1
%bcond_without check
%bcond check 1
# I'm not sure what this is for, as no tests seem to use it, and it introduces
# some weird license that needs review.
%bcond wasi_cli 0
%global __brp_strip_lto %{nil}
%global __brp_strip_static_archive %{nil}
# https://github.com/tinygo-org/tinygo
%global goipath github.com/tinygo-org/tinygo
Version: 0.26.0
Version: 0.39.0
%global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393
%global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228
%if %{fedora} > 36
%global clang_llvm_version 15
%else
%global clang_llvm_version 14
%endif
%global cmsis_svd_commit df75ff974c76a911fc2815e29807f5ecaae06fc2
%global compiler_rt_version %{clang_llvm_version}.0.0
%global macos_minsdk_commit ebb736fda2bec7cea38dcda807518b835a539525
%global musl_version 1.2.0
%global nrfx_commit d779b49fc59c7a165e7da1d7cd7d57b28a059f16
%global picolibc_commit f68b8204f797d6b3bfbc7c4da4d257961fbc8770
%global wasi_libc_commit 30094b6ed05f19cee102115215863d185f2db4f0
%global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393
%global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228
%global bdwgc_commit 1166f11f7dee08d7ad369296b24cf8c9582f8789
%global clang_llvm_version 19
%global cmsis_svd_data_commit 05a9562ec59b87945a8d7177a4b08b7aa2f2fd58
%global compiler_rt_version %{clang_llvm_version}.1.7
%global macos_minsdk_commit e7c72156eac3ebf29c34cc2faa71efcb1296663f
%global mingw64_commit 8526cb618269440a94810b94b77f8bd48c5c3396
%global musl_version 1.2.3
%global net_commit c134160ae47d38b468b1c5ade43e78ad5a1e616d
%global nrfx_commit d779b49fc59c7a165e7da1d7cd7d57b28a059f16
%global picolibc_commit b92edfda8ac6853772d87cadaeeeaa21b78609b6
%global wasi_libc_version 20
%global wasi_libc_tag wasi-sdk-%{wasi_libc_version}
%global wasi_cli_version 0.2.0
# No longer matching regular Go's /usr/share/gocode because it also provides
# pre-compiled binaries, and symlinks to arch-specific clang headers.
@ -33,31 +36,35 @@ Version: 0.26.0
Go compiler for small places. Microcontrollers, WebAssembly, and command-line
tools. Based on LLVM.}
#global godocs CHANGELOG.md BUILDING.md CONTRIBUTING.md README.md
#global golicenses LICENSE LICENSE.TXT
#global gosupfiles lib/CMSIS/CMSIS/Include/*.h lib/compiler-rt/lib/builtins/*/*.S lib/nrfx/mdk/*.{ld,S} src/examples/wasm/*/*.js targets/*.{js,json,ld,S}
Name: tinygo
Release: %autorelease
Summary: Go compiler for small places
# Main files: BSD
# CMSIS: BSD (subsetted)
# avr-mcu: ASL 2.0 (packs) and MIT (Rust code, unused by this package)
# cmsis-svd: ASL 2.0 and BSD and ISC and MIT (subsetted)
# compiler-rt: NCSA or MIT
# macos-minimal-sdk: APSL 2.0 and BSD and ISC and Public Domain
# Main files: BSD-3-Clause
# builder/cc1as.*: Apache-2.0 WITH LLVM-exception
# corpus_test.go: MIT
# CMSIS: BSD-3-Clause (subsetted)
# avr-mcu: Apache-2.0 (packs) AND MIT (Rust code, unused by this package)
# cmsis-svd: Apache-2.0 AND (Apache-2.0 OR MIT) AND BSD-3-Clause AND BSD-Source-Code AND ISC AND MIT (subsetted)
# compiler-rt: Apache-2.0 WITH LLVM-exception OR NCSA OR MIT
# macos-minimal-sdk: APSL-2.0 AND BSD-2-Clause AND BSD-3-Clause AND BSD-4-Clause AND BSD-4-Clause-UC AND ISC AND LicenseRef-Fedora-Public-Domain
# musl: MIT
# nrfx: BSD and ASL 2.0
# picolibc: BSD and ISC and MIT and GPLv2 (testing code only, unused by this package)
# wasi-libc: BSD and CC0 and ISC and MIT and Public Domain
License: BSD and APSL 2.0 and ASL 2.0 and CC0 and ISC and MIT and (NCSA or MIT) and Public Domain
# net: BSD-2-Clause
# nrfx: BSD-3-Clause AND Apache-2.0
# picolibc: BSD-2-Clause AND BSD-2-Clause-FreeBSD AND BSD-3-Clause AND ISC AND SMLNJ AND Spencer-94 AND GPLv2 (testing code only, unused by this package)
# wasi-libc: Apache-2.0 WITH LLVM-exception AND Apache-2.0 AND MIT AND BSD-2-Clause AND CC0-1.0 (dlmalloc implementation, unused by this package)
License: %{shrink: BSD-3-Clause AND Apache-2.0 WITH LLVM-exception AND BSD-2-Clause AND MIT AND
Apache-2.0 AND
(Apache-2.0 OR MIT) AND BSD-Source-Code AND ISC AND
(Apache-2.0 WITH LLVM-exception OR NCSA OR MIT) AND
APSL-2.0 AND BSD-2-Clause AND BSD-4-Clause AND BSD-4-Clause-UC AND LicenseRef-Fedora-Public-Domain AND
BSD-2-Clause-FreeBSD AND SMLNJ AND Spencer-94}
URL: %{gourl}
Source0: %{gosource}
Source1: clean_tarballs.sh
Source2: cmsis-%{CMSIS_commit}-clean.tar.xz
Source3: https://github.com/avr-rust/avr-mcu/archive/%{avr_commit}/avr-%{avr_commit}.tar.gz
Source4: cmsis_svd-%{cmsis_svd_commit}-clean.tar.xz
Source4: cmsis_svd_data-%{cmsis_svd_data_commit}-clean.tar.xz
Source50: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}/compiler-rt-%{compiler_rt_version}.src.tar.xz
Source51: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}/compiler-rt-%{compiler_rt_version}.src.tar.xz.sig
Source52: https://src.fedoraproject.org/rpms/compiler-rt/raw/f8e98d51f0c3fdbaa9ce5d99816930e4fcbe504b/f/release-keys.asc#/compiler-rt-release-keys.asc
@ -67,76 +74,71 @@ Source62: https://musl.libc.org/musl.pub
Source7: https://github.com/aykevl/macos-minimal-sdk/archive/%{macos_minsdk_commit}/macos-minimal-sdk-%{macos_minsdk_commit}.tar.gz
Source8: https://github.com/NordicSemiconductor/nrfx/archive/%{nrfx_commit}/nrfx-%{nrfx_commit}.tar.gz
Source9: https://github.com/keith-packard/picolibc/archive/%{picolibc_commit}/picolibc-%{picolibc_commit}.tar.gz
Source10: https://github.com/WebAssembly/wasi-libc/archive/%{wasi_libc_commit}/wasi-libc-%{wasi_libc_commit}.tar.gz
Source10: https://github.com/WebAssembly/wasi-libc/archive/%{wasi_libc_tag}/wasi-libc-%{wasi_libc_tag}.tar.gz
Source11: https://github.com/mingw-w64/mingw-w64/archive/%{mingw64_commit}/mingw64-%{mingw64_commit}.tar.gz
Source12: https://github.com/tinygo-org/net/archive/%{net_commit}/net-%{net_commit}.tar.gz
%if %{with wasi_cli}
Source13: https://github.com/WebAssembly/wasi-cli/archive/v%{wasi_cli_version}/wasi-cli-%{wasi_cli_version}.tar.gz
%endif
Source14: https://github.com/ivmai/bdwgc/archive/%{bdwgc_commit}/bdwgc-%{bdwgc_commit}.tar.gz
#
# Unnumbered patches are applied to the main source tree.
# Patches that are 1X00-1X99 are applied to the subdirectory for source X.
#
# We don't have wasmtime to run these.
Patch0001: 0001-Skip-WASI-tests.patch
# Unbundling things
Patch0002: 0002-Use-system-mingw64-headers-and-crt.patch
# Skip testing some things where qemu is broken:
# https://gitlab.com/qemu-project/qemu/-/issues/447
# https://gitlab.com/qemu-project/qemu/-/issues/690
Patch0003: 0003-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch
# Add Fedora specific dnf instructions
Patch0004: 0004-Suggest-optional-packages-to-install-if-missing.patch
Patch: 0001-Skip-WASI-tests.patch
# We set GO111MODULE=off during tests, so can't run a few of them.
Patch: 0002-Skip-tests-that-require-Go-module-mode.patch
# Better search paths for non-default LLVM.
Patch: 0003-Set-LLVM-search-paths-for-Fedora.patch
#https://github.com/tinygo-org/tinygo/pull/4677
Patch: 0004-Normalize-expected-path-for-chdir-tests.patch
# https://github.com/tinygo-org/tinygo/issues/4969
Patch: 0005-Skip-x86-tests-on-ARM.patch
# https://github.com/tinygo-org/tinygo/pull/2840
Patch0005: 0005-Skip-TestDirFS-on-32-bit-systems.patch
Patch0006: 0006-Skip-broken-tests-on-i686.patch
# Backport patches for LLVM 15 support
# https://github.com/tinygo-org/tinygo/pull/3230
Patch0007: 0007-wasm-fix-GC-scanning-of-allocas.patch
# https://github.com/tinygo-org/tinygo/pull/3189
Patch0008: 0008-compiler-return-a-FunctionType-not-a-PointerType-in-.patch
Patch0009: 0009-all-add-type-parameter-to-CreateCall.patch
Patch0010: 0010-all-add-type-parameter-to-CreateLoad.patch
Patch0011: 0011-all-add-type-parameter-to-GEP-calls.patch
Patch0012: 0012-all-replace-llvm.Const-calls-with-builder.Create-cal.patch
Patch0013: 0013-interp-change-object.llvmType-to-the-initializer-typ.patch
Patch0014: 0014-all-remove-pointer-ElementType-calls.patch
Patch0015: 0015-transform-fix-memory-corruption-issues.patch
Patch0016: 0016-riscv-add-target-abi-metadata-flag.patch
Patch0017: 0017-interp-add-support-for-constant-icmp-instructions.patch
Patch0018: 0018-ci-add-support-for-LLVM-15.patch
# Fix CVE-2025-26519 in musl.
Patch1600: https://www.openwall.com/lists/musl/2025/02/13/1/1#/musl-cve-2025-26519-1.patch
Patch1601: https://www.openwall.com/lists/musl/2025/02/13/1/2#/musl-cve-2025-26519-2.patch
# Not supported upstream yet.
ExcludeArch: armv7hl ppc64le s390x
ExcludeArch: ppc64le s390x
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
ExcludeArch: %{ix86}
BuildRequires: (clang-devel >= %{clang_llvm_version} with clang-devel < %{lua: print(tonumber(rpm.expand('%{clang_llvm_version}')) + 1)})
BuildRequires: clang-devel(major) = %{clang_llvm_version}
BuildRequires: golang(github.com/aykevl/go-wasm)
BuildRequires: golang(github.com/blakesmith/ar)
%ifnarch %{ix86}
BuildRequires: chromium
BuildRequires: golang(github.com/chromedp/chromedp) >= 0.7.6
BuildRequires: golang(github.com/chromedp/cdproto/cdp)
%endif
BuildRequires: golang(github.com/gofrs/flock) >= 0.8.1
BuildRequires: golang(github.com/google/shlex)
BuildRequires: golang(github.com/inhies/go-bytesize)
BuildRequires: golang(github.com/marcinbor85/gohex)
BuildRequires: golang(github.com/mattn/go-colorable) >= 0.1.8
BuildRequires: golang(github.com/mattn/go-colorable) >= 0.1.13
BuildRequires: golang(github.com/mattn/go-tty) >= 0.0.4
BuildRequires: golang(go.bug.st/serial) >= 1.3.5
BuildRequires: golang(github.com/tetratelabs/wazero) >= 1.6
BuildRequires: golang(golang.org/x/net/http/httpguts) >= 0.35
BuildRequires: golang(github.com/sigurn/crc16)
BuildRequires: golang(go.bug.st/serial) >= 1.6.0
BuildRequires: golang(golang.org/x/tools/go/ast/astutil)
BuildRequires: golang(golang.org/x/tools/go/ssa) >= 0.1.11
BuildRequires: golang(golang.org/x/tools/go/ssa) >= 0.30
BuildRequires: golang(gopkg.in/yaml.v2) >= 2.4.0
BuildRequires: golang(tinygo.org/x/go-llvm)
BuildRequires: golang-tests
BuildRequires: llvm-devel(major) = %{clang_llvm_version}
BuildRequires: make
BuildRequires: avr-gcc
BuildRequires: avr-libc
BuildRequires: binaryen >= 102
BuildRequires: binaryen >= 116
# We don't have glibc for arm, so skip these.
#BuildRequires: gcc-arm-linux-gnu
#BuildRequires: gcc-aarch64-linux-gnu
BuildRequires: lld
BuildRequires: mingw64-crt
BuildRequires: mingw64-headers
BuildRequires: nodejs
BuildRequires: lld(major) = %{clang_llvm_version}
# BuildRequires: mingw64-crt
# BuildRequires: mingw64-headers
BuildRequires: nodejs >= 18
BuildRequires: qemu-system-arm-core
BuildRequires: qemu-system-riscv-core
BuildRequires: qemu-user
@ -144,46 +146,53 @@ BuildRequires: qemu-user
# For GPG signature verification
BuildRequires: gnupg2
Requires: clang
Requires: clang(major) = %{clang_llvm_version}
Requires: golang
Requires: lld
Recommends: avr-gcc
Recommends: avr-libc
Requires: lld(major) = %{clang_llvm_version}
# Add this when LLVM supports ESP natively.
# Recommends: esptool
Recommends: mingw64-crt
Recommends: mingw64-headers
# Recommends: mingw64-crt
# Recommends: mingw64-headers
Recommends: qemu-system-arm-core
Recommends: qemu-system-riscv-core
Recommends: qemu-user
# Make note of bundled libc's
Provides: bundled(bdwgc) = %{bdwgc_commit}
Provides: bundled(gc) = %{bdwgc_commit}
Provides: bundled(compiler-rt) = %{compiler_rt_version}
Provides: bundled(musl) = %{musl_version}
Provides: bundled(picolibc) = %{picolibc_commit}
Provides: bundled(wasi-libc) = %{wasi_libc_commit}
Provides: bundled(wasi-libc) = %{wasi_libc_version}
%description
%{common_description}
#gopkg
%prep
%goprep
%autopatch -p1
%autopatch -q -p1 -M 999
tar -C lib -xf %{SOURCE2}
rmdir lib/CMSIS
mv lib/CMSIS-%{CMSIS_commit} lib/CMSIS
pushd lib/CMSIS
%autopatch -q -p1 -m 1200 -M 1299
popd
tar -C lib -xf %{SOURCE3}
rmdir lib/avr
mv lib/avr-mcu-%{avr_commit} lib/avr
pushd lib/avr
%autopatch -q -p1 -m 1300 -M 1399
popd
tar -C lib -xf %{SOURCE4}
rmdir lib/cmsis-svd
mv lib/cmsis-svd-%{cmsis_svd_commit} lib/cmsis-svd
mv lib/cmsis-svd-data-%{cmsis_svd_data_commit} lib/cmsis-svd
pushd lib/cmsis-svd
%autopatch -q -p1 -m 1400 -M 1499
popd
# Verify *before* actually unpacking!
%{gpgverify} --keyring='%{SOURCE52}' --signature='%{SOURCE51}' --data='%{SOURCE50}'
@ -191,61 +200,93 @@ tar -C lib -xf %{SOURCE50}
mv lib/compiler-rt-%{compiler_rt_version}.src/lib/builtins lib/compiler-rt-builtins
mv lib/compiler-rt-%{compiler_rt_version}.src/README.txt lib/compiler-rt-builtins/
mv lib/compiler-rt-%{compiler_rt_version}.src/LICENSE.TXT lib/compiler-rt-builtins/
pushd lib/compiler-rt-builtins
%autopatch -q -p1 -m 1500 -M 1599
popd
# Verify *before* actually unpacking!
%{gpgverify} --keyring='%{SOURCE62}' --signature='%{SOURCE61}' --data='%{SOURCE60}'
tar -C lib -xf %{SOURCE60}
rmdir lib/musl
mv lib/musl-%{musl_version} lib/musl
pushd lib/musl
%autopatch -q -p1 -m 1600 -M 1699
popd
tar -C lib -xf %{SOURCE7}
rmdir lib/macos-minimal-sdk
mv lib/macos-minimal-sdk-%{macos_minsdk_commit} lib/macos-minimal-sdk
pushd lib/macos-minimal-sdk
%autopatch -q -p1 -m 1700 -M 1799
popd
tar -C lib -xf %{SOURCE8}
rmdir lib/nrfx
mv lib/nrfx-%{nrfx_commit} lib/nrfx
rm lib/nrfx/.gitignore
chmod -x lib/nrfx/doc/generate_html_doc.sh
pushd lib/nrfx
%autopatch -q -p1 -m 1800 -M 1899
popd
tar -C lib -xf %{SOURCE9}
rmdir lib/picolibc
mv lib/picolibc-%{picolibc_commit} lib/picolibc
pushd lib/picolibc
%autopatch -q -p1 -m 1900 -M 1999
popd
tar -C lib -xf %{SOURCE10}
rmdir lib/wasi-libc
mv lib/wasi-libc-%{wasi_libc_commit} lib/wasi-libc
mv lib/wasi-libc-%{wasi_libc_tag} lib/wasi-libc
pushd lib/wasi-libc
%autopatch -q -p1 -m 11000 -M 11099
popd
# This test is too slow and pretty much freezes.
%ifarch %{ix86}
sed -i -e 's!archive/zip!$(nil)!' Makefile
tar -C lib -xf %{SOURCE11}
rmdir lib/mingw-w64
mv lib/mingw-w64-%{mingw64_commit} lib/mingw-w64
pushd lib/mingw-w64
%autopatch -q -p1 -m 11100 -M 11199
popd
tar -C src -xf %{SOURCE12}
rmdir src/net
mv src/net-%{net_commit} src/net
pushd src/net
%autopatch -q -p1 -m 11200 -M 11299
popd
%if %{with wasi_cli}
tar -C lib -xf %{SOURCE13}
rmdir lib/wasi-cli
mv lib/wasi-cli-%{wasi_cli_version} lib/wasi-cli
pushd lib/wasi-cli
%autopatch -q -p1 -m 11300 -M 11399
popd
%endif
tar -C lib -xf %{SOURCE14}
rmdir lib/bdwgc
mv lib/bdwgc-%{bdwgc_commit} lib/bdwgc
pushd lib/bdwgc
%autopatch -q -p1 -m 11400 -M 11499
popd
%build
# Use only GOBUILDTAGS when https://pagure.io/go-rpm-macros/pull-request/34 is
# merged and released.
export BUILDTAGS="llvm%{clang_llvm_version}" LDFLAGS="-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=%{tinygoroot} "
export GO_BUILDTAGS="llvm%{clang_llvm_version}" GO_LDFLAGS="-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=%{tinygoroot} "
%gobuild -o %{gobuilddir}/bin/tinygo %{goipath}
GO111MODULE=off %make_build gen-device STM32=0
for target in thumbv6m-unknown-unknown-eabi-cortex-m0 thumbv6m-unknown-unknown-eabi-cortex-m0plus thumbv7em-unknown-unknown-eabi-cortex-m4; do
mkdir -p ${target}
for libc in compiler-rt picolibc; do
TINYGOROOT=$PWD \
%{gobuilddir}/bin/tinygo \
build-library -target=${target#*eabi-} -o ${target}/${libc} ${libc}
chmod -R a+rX ${target}/${libc}
done
done
%make_build wasi-libc CLANG=clang-%{clang_llvm_version} LLVM_AR=llvm-ar LLVM_NM=llvm-nm
GO111MODULE=off %make_build gen-device RENESAS=0 STM32=0
%install
#gopkginstall
install -vdm 0755 %{buildroot}%{_bindir}
install -vpm 0755 %{gobuilddir}/bin/* %{buildroot}%{_bindir}/
install -vdm 0755 %{buildroot}%{tinygoroot}
install -vdm 0755 %{buildroot}%{tinygoroot}/lib
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/bdwgc
cp -rp lib/bdwgc/* %{buildroot}%{tinygoroot}/lib/bdwgc
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/CMSIS
install -vpm 0644 lib/CMSIS/README.md %{buildroot}%{tinygoroot}/lib/CMSIS/
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/CMSIS/CMSIS/Include
@ -253,6 +294,25 @@ install -vpm 0644 lib/CMSIS/CMSIS/Include/* %{buildroot}%{tinygoroot}/lib/CMSIS/
cp -rp lib/compiler-rt-builtins %{buildroot}%{tinygoroot}/lib
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/macos-minimal-sdk
cp -rp lib/macos-minimal-sdk/* %{buildroot}%{tinygoroot}/lib/macos-minimal-sdk
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
cp -rp lib/mingw-w64/mingw-w64-crt/def-include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
cp -rp lib/mingw-w64/mingw-w64-crt/gdtoa %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
cp -rp lib/mingw-w64/mingw-w64-crt/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
cp -rp lib/mingw-w64/mingw-w64-crt/misc %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
cp -rp lib/mingw-w64/mingw-w64-crt/stdio %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/crt
cp -rp lib/mingw-w64/mingw-w64-crt/crt/pseudo-reloc.c %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/crt
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/math
cp -rp lib/mingw-w64/mingw-w64-crt/math/x86 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/math
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common
cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/api-ms-win-crt-* %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common
cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/advapi32.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common
cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/kernel32.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common
cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/msvcrt.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers/defaults
cp -rp lib/mingw-w64/mingw-w64-headers/crt/ %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers
cp -rp lib/mingw-w64/mingw-w64-headers/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers
cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers/defaults
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl
cp -rp lib/musl/COPYRIGHT %{buildroot}%{tinygoroot}/lib/musl
cp -rp lib/musl/include %{buildroot}%{tinygoroot}/lib/musl
@ -261,28 +321,79 @@ cp -rp lib/musl/arch/aarch64 %{buildroot}%{tinygoroot}/lib/musl/arch
cp -rp lib/musl/arch/arm %{buildroot}%{tinygoroot}/lib/musl/arch
cp -rp lib/musl/arch/generic %{buildroot}%{tinygoroot}/lib/musl/arch
cp -rp lib/musl/arch/i386 %{buildroot}%{tinygoroot}/lib/musl/arch
cp -rp lib/musl/arch/mips %{buildroot}%{tinygoroot}/lib/musl/arch
cp -rp lib/musl/arch/x86_64 %{buildroot}%{tinygoroot}/lib/musl/arch
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl/crt
cp -rp lib/musl/crt/crt1.c %{buildroot}%{tinygoroot}/lib/musl/crt
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/conf %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/ctype %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/env %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/errno %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/exit %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/fcntl %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/include %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/internal %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/legacy %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/linux %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/locale %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/malloc %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/mman %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/math %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/misc %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/multibyte %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/sched %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/signal %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/stdio %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/stdlib %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/string %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/thread %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/time %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/unistd %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/musl/src/process %{buildroot}%{tinygoroot}/lib/musl/src
cp -rp lib/nrfx %{buildroot}%{tinygoroot}/lib/
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc
cp -rp lib/wasi-libc/sysroot %{buildroot}%{tinygoroot}/lib/wasi-libc/
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/dlmalloc
cp -rp lib/wasi-libc/dlmalloc/src %{buildroot}%{tinygoroot}/lib/wasi-libc/dlmalloc
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half
cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half
cp -rp lib/wasi-libc/libc-bottom-half/headers %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half
cp -rp lib/wasi-libc/libc-bottom-half/sources %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half
cp -rp lib/wasi-libc/libc-top-half/headers %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half
cp -rp lib/wasi-libc/libc-top-half/sources %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl
cp -rp lib/wasi-libc/libc-top-half/musl/include %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch
cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch
cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/conf %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/dirent %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/env %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/errno %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/exit %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/fcntl %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/fenv %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/include %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/internal %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/legacy %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/locale %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/math %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/misc %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/multibyte %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/network %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/stat %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/stdio %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/stdlib %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/string %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/thread %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/time %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
cp -rp lib/wasi-libc/libc-top-half/musl/src/unistd %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src
%if %{with wasi_cli}
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-cli
cp -rp lib/wasi-cli/wit %{buildroot}%{tinygoroot}/lib/wasi-cli/wit
%endif
install -vdm 0755 %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc
cp -rp lib/picolibc/newlib/libc/ctype %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc
chmod -x %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc/ctype/{mkcaseconv,mkcategories,mkunidata}
@ -296,20 +407,13 @@ install -vdm 0755 %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm
cp -rp lib/picolibc/newlib/libm/common %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm
cp -rp lib/picolibc/newlib/libm/math %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm
cp -rp lib/picolibc-stdio.c %{buildroot}%{tinygoroot}/lib
install -vdm 0755 %{buildroot}%{tinygoroot}/pkg
for target in thumbv6m-unknown-unknown-eabi-cortex-m0 thumbv6m-unknown-unknown-eabi-cortex-m0plus thumbv7em-unknown-unknown-eabi-cortex-m4; do
install -vdm 0755 %{buildroot}%{tinygoroot}/pkg/${target}
for libc in compiler-rt picolibc; do
cp -rp ${target}/${libc} %{buildroot}%{tinygoroot}/pkg/${target}/
done
done
cp -rp src %{buildroot}%{tinygoroot}/
rm %{buildroot}%{tinygoroot}/src/examples/wasm/.gitignore
cp -rp targets %{buildroot}%{tinygoroot}/
%if %{with check}
%global gotestflags %gocompilerflags -v -tags="llvm%{clang_llvm_version}"
%global gotestflags %gocompilerflags -v -tags="llvm%{clang_llvm_version}" -timeout 30m
%check
export TINYGOROOT=%{buildroot}%{tinygoroot}
export GOPATH=%{buildroot}%{tinygoroot}:%{gopath}
@ -318,17 +422,11 @@ export GO111MODULE=off
export XDG_CACHE_HOME="${PWD}/$(mktemp -d tinygo.XXXXXX)"
%gocheck -v -t src -t tests
( cd _build/src/%{goipath} && GOPATH=%{currentgosourcedir}/_build:$GOPATH make smoketest STM32=0 XTENSA=0 )
%ifnarch %{ix86} aarch64
%ifnarch aarch64
make wasmtest
%endif
# Ignoring errors due to CGo issue:
# https://github.com/tinygo-org/tinygo/issues/3057
%ifarch %{ix86}
make tinygo-test-fast
%else
make tinygo-test
%endif
%endif
%files
@ -336,6 +434,8 @@ make tinygo-test
%license LICENSE
%{_bindir}/tinygo
%{tinygoroot}
%doc %{tinygoroot}/lib/bdwgc/README.md
%license %{tinygoroot}/lib/bdwgc/LICENSE
%doc %{tinygoroot}/lib/CMSIS/README.md
%license %{tinygoroot}/lib/compiler-rt-builtins/LICENSE.TXT
%doc %{tinygoroot}/lib/compiler-rt-builtins/README.txt
@ -343,8 +443,6 @@ make tinygo-test
%doc %{tinygoroot}/lib/nrfx/README.md
%license %{tinygoroot}/lib/musl/COPYRIGHT
#gopkgfiles
%changelog
%autochangelog