all: remove support for LLVM 11 and LLVM 12

This removes a lot of backwards compatibility cruft and makes it
possible to start using features that need LLVM 13 or newer.
For example:

  * https://github.com/tinygo-org/tinygo/pull/2637
  * https://github.com/tinygo-org/tinygo/pull/2830
Этот коммит содержится в:
Ayke van Laethem 2022-05-05 14:52:20 +02:00 коммит произвёл Ron Evans
родитель 5afb63df60
коммит 5c23f6fb6c
17 изменённых файлов: 18 добавлений и 166 удалений

Просмотреть файл

@ -102,21 +102,16 @@ commands:
- run: make fmt-check - run: make fmt-check
jobs: jobs:
test-llvm11-go116: test-llvm13-go116:
docker: docker:
- image: circleci/golang:1.16-buster - image: circleci/golang:1.16-buster
steps: steps:
- test-linux: - test-linux:
llvm: "11" llvm: "13"
test-llvm12-go117:
docker:
- image: circleci/golang:1.17-buster
steps:
- test-linux:
llvm: "12"
workflows: workflows:
test-all: test-all:
jobs: jobs:
- test-llvm11-go116 # This tests our lowest supported versions of Go and LLVM, to make sure at
- test-llvm12-go117 # least the smoke tests still pass.
- test-llvm13-go116

Просмотреть файл

@ -935,17 +935,6 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
return errors.New("verification failure after LLVM optimization passes") return errors.New("verification failure after LLVM optimization passes")
} }
// LLVM 11 by default tries to emit tail calls (even with the target feature
// disabled) unless it is explicitly disabled with a function attribute.
// This is a problem, as it tries to emit them and prints an error when it
// can't with this feature disabled.
// Because as of september 2020 tail calls are not yet widely supported,
// they need to be disabled until they are widely supported (at which point
// the +tail-call target feautre can be set).
if strings.HasPrefix(config.Triple(), "wasm") {
transform.DisableTailCalls(mod)
}
return nil return nil
} }

Просмотреть файл

@ -26,7 +26,7 @@ func TestClangAttributes(t *testing.T) {
"cortex-m0", "cortex-m0",
"cortex-m0plus", "cortex-m0plus",
"cortex-m3", "cortex-m3",
//"cortex-m33", // TODO: broken in LLVM 11, fixed in https://reviews.llvm.org/D90305 "cortex-m33",
"cortex-m4", "cortex-m4",
"cortex-m7", "cortex-m7",
"esp32c3", "esp32c3",

Просмотреть файл

@ -6,7 +6,6 @@ import (
"github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv" "github.com/tinygo-org/tinygo/goenv"
"tinygo.org/x/go-llvm"
) )
// Create a job that builds a Darwin libSystem.dylib stub library. This library // Create a job that builds a Darwin libSystem.dylib stub library. This library
@ -39,12 +38,8 @@ func makeDarwinLibSystemJob(config *compileopts.Config, tmpdir string) *compileJ
// Link object file to dynamic library. // Link object file to dynamic library.
platformVersion := strings.TrimPrefix(strings.Split(config.Triple(), "-")[2], "macosx") platformVersion := strings.TrimPrefix(strings.Split(config.Triple(), "-")[2], "macosx")
flavor := "darwin"
if strings.Split(llvm.Version, ".")[0] < "13" {
flavor = "darwinnew" // needed on LLVM 12 and below
}
flags = []string{ flags = []string{
"-flavor", flavor, "-flavor", "darwin",
"-demangle", "-demangle",
"-dynamic", "-dynamic",
"-dylib", "-dylib",

Просмотреть файл

@ -54,7 +54,7 @@ func RunTool(tool string, args ...string) error {
ok = C.tinygo_clang_driver(C.int(len(args)), (**C.char)(buf)) ok = C.tinygo_clang_driver(C.int(len(args)), (**C.char)(buf))
case "ld.lld": case "ld.lld":
switch linker { switch linker {
case "darwin", "darwinnew": // darwinnew is only needed for LLVM 12 and below case "darwin":
ok = C.tinygo_link_macho(C.int(len(args)), (**C.char)(buf)) ok = C.tinygo_link_macho(C.int(len(args)), (**C.char)(buf))
case "elf": case "elf":
ok = C.tinygo_link_elf(C.int(len(args)), (**C.char)(buf)) ok = C.tinygo_link_elf(C.int(len(args)), (**C.char)(buf))

Просмотреть файл

@ -1,16 +0,0 @@
//go:build !byollvm && llvm11
// +build !byollvm,llvm11
package cgo
/*
#cgo linux CFLAGS: -I/usr/lib/llvm-11/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@11/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@11/include
#cgo freebsd CFLAGS: -I/usr/local/llvm11/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-11/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@11/lib -lclang -lffi
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@11/lib -lclang -lffi
#cgo freebsd LDFLAGS: -L/usr/local/llvm11/lib -lclang
*/
import "C"

Просмотреть файл

@ -1,16 +0,0 @@
//go:build !byollvm && llvm12
// +build !byollvm,llvm12
package cgo
/*
#cgo linux CFLAGS: -I/usr/lib/llvm-12/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@12/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@12/include
#cgo freebsd CFLAGS: -I/usr/local/llvm12/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-12/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@12/lib -lclang -lffi
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@12/lib -lclang -lffi
#cgo freebsd LDFLAGS: -L/usr/local/llvm12/lib -lclang
*/
import "C"

Просмотреть файл

@ -1,5 +1,5 @@
//go:build !byollvm && !llvm11 && !llvm12 && !llvm14 //go:build !byollvm && !llvm14
// +build !byollvm,!llvm11,!llvm12,!llvm14 // +build !byollvm,!llvm14
package cgo package cgo

Просмотреть файл

@ -12,11 +12,9 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"strconv"
"strings" "strings"
"github.com/tinygo-org/tinygo/goenv" "github.com/tinygo-org/tinygo/goenv"
"tinygo.org/x/go-llvm"
) )
// Target specification for a given target. Used for bare metal targets. // Target specification for a given target. Used for bare metal targets.
@ -266,12 +264,8 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
spec.Libc = "darwin-libSystem" spec.Libc = "darwin-libSystem"
arch := strings.Split(triple, "-")[0] arch := strings.Split(triple, "-")[0]
platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx") platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx")
flavor := "darwin"
if strings.Split(llvm.Version, ".")[0] < "13" {
flavor = "darwinnew" // needed on LLVM 12 and below
}
spec.LDFlags = append(spec.LDFlags, spec.LDFlags = append(spec.LDFlags,
"-flavor", flavor, "-flavor", "darwin",
"-dead_strip", "-dead_strip",
"-arch", arch, "-arch", arch,
"-platform_version", "macos", platformVersion, platformVersion, "-platform_version", "macos", platformVersion, platformVersion,
@ -296,13 +290,8 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
"--image-base", "0x400000", "--image-base", "0x400000",
"--gc-sections", "--gc-sections",
"--no-insert-timestamp", "--no-insert-timestamp",
"--no-dynamicbase",
) )
llvmMajor, _ := strconv.Atoi(strings.Split(llvm.Version, ".")[0])
if llvmMajor >= 12 {
// This flag was added in LLVM 12. At the same time, LLVM 12
// switched the default from --dynamicbase to --no-dynamicbase.
spec.LDFlags = append(spec.LDFlags, "--no-dynamicbase")
}
} else { } else {
spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie
} }

Просмотреть файл

@ -52,30 +52,6 @@ func (b *builder) createAtomicOp(call *ssa.CallCommon) (llvm.Value, bool) {
ptr := b.getValue(call.Args[0]) ptr := b.getValue(call.Args[0])
old := b.getValue(call.Args[1]) old := b.getValue(call.Args[1])
newVal := b.getValue(call.Args[2]) newVal := b.getValue(call.Args[2])
if strings.HasSuffix(name, "64") {
if strings.HasPrefix(b.Triple, "thumb") {
// Work around a bug in LLVM, at least LLVM 11:
// https://reviews.llvm.org/D95891
// Check for thumbv6m, thumbv7, thumbv7em, and perhaps others.
// See also: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
compareAndSwap := b.mod.NamedFunction("__sync_val_compare_and_swap_8")
if compareAndSwap.IsNil() {
// Declare the function if it isn't already declared.
i64Type := b.ctx.Int64Type()
fnType := llvm.FunctionType(i64Type, []llvm.Type{llvm.PointerType(i64Type, 0), i64Type, i64Type}, false)
compareAndSwap = llvm.AddFunction(b.mod, "__sync_val_compare_and_swap_8", fnType)
}
actualOldValue := b.CreateCall(compareAndSwap, []llvm.Value{ptr, old, newVal}, "")
// The __sync_val_compare_and_swap_8 function returns the old
// value. However, we shouldn't return the old value, we should
// return whether the compare/exchange was successful. This is
// easily done by comparing the returned (actual) old value with
// the expected old value passed to
// __sync_val_compare_and_swap_8.
swapped := b.CreateICmp(llvm.IntEQ, old, actualOldValue, "")
return swapped, true
}
}
tuple := b.CreateAtomicCmpXchg(ptr, old, newVal, llvm.AtomicOrderingSequentiallyConsistent, llvm.AtomicOrderingSequentiallyConsistent, true) tuple := b.CreateAtomicCmpXchg(ptr, old, newVal, llvm.AtomicOrderingSequentiallyConsistent, llvm.AtomicOrderingSequentiallyConsistent, true)
swapped := b.CreateExtractValue(tuple, 1, "") swapped := b.CreateExtractValue(tuple, 1, "")
return swapped, true return swapped, true

Просмотреть файл

@ -28,18 +28,11 @@ type testCase struct {
func TestCompiler(t *testing.T) { func TestCompiler(t *testing.T) {
t.Parallel() t.Parallel()
// Check LLVM version. // Determine LLVM version.
llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0]) llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0])
if err != nil { if err != nil {
t.Fatal("could not parse LLVM version:", llvm.Version) t.Fatal("could not parse LLVM version:", llvm.Version)
} }
if llvmMajor < 11 {
// It is likely this version needs to be bumped in the future.
// The goal is to at least test the LLVM version that's used by default
// in TinyGo and (if possible without too many workarounds) also some
// previous versions.
t.Skip("compiler tests require LLVM 11 or above, got LLVM ", llvm.Version)
}
// Determine Go minor version (e.g. 16 in go1.16.3). // Determine Go minor version (e.g. 16 in go1.16.3).
_, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) _, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT"))
@ -221,11 +214,6 @@ func filterIrrelevantIRLines(lines []string) []string {
if strings.HasPrefix(line, "source_filename = ") { if strings.HasPrefix(line, "source_filename = ") {
continue continue
} }
if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") {
// Ignore attribute groups. These may change between LLVM versions.
// Right now test outputs are for LLVM 12 and higher.
continue
}
if llvmVersion < 14 && strings.HasPrefix(line, "target datalayout = ") { if llvmVersion < 14 && strings.HasPrefix(line, "target datalayout = ") {
// The datalayout string may vary betewen LLVM versions. // The datalayout string may vary betewen LLVM versions.
// Right now test outputs are for LLVM 14 and higher. // Right now test outputs are for LLVM 14 and higher.

Просмотреть файл

@ -233,14 +233,6 @@ func setHeapEnd(newHeapEnd uintptr) {
// This function can be called again when the heap size increases. The caller is // This function can be called again when the heap size increases. The caller is
// responsible for copying the metadata to the new location. // responsible for copying the metadata to the new location.
func calculateHeapAddresses() { func calculateHeapAddresses() {
if GOARCH == "wasm" {
// This is a workaround for a bug in wasm-ld: wasm-ld doesn't always
// align __heap_base and when this memory is shared through an API, it
// might result in unaligned memory. For details, see:
// https://reviews.llvm.org/D106499
// It should be removed once we switch to LLVM 13, where this is fixed.
heapStart = align(heapStart)
}
totalSize := heapEnd - heapStart totalSize := heapEnd - heapStart
// Allocate some memory to keep 2 bits of information about every block. // Allocate some memory to keep 2 bits of information about every block.

Просмотреть файл

@ -4,21 +4,10 @@
package runtime package runtime
import "unsafe"
// markGlobals marks all globals, which are reachable by definition. // markGlobals marks all globals, which are reachable by definition.
// //
// This implementation marks all globals conservatively and assumes it can use // This implementation marks all globals conservatively and assumes it can use
// linker-defined symbols for the start and end of the .data section. // linker-defined symbols for the start and end of the .data section.
func markGlobals() { func markGlobals() {
end := globalsEnd markRoots(globalsStart, globalsEnd)
if GOARCH == "wasm" {
// This is a workaround for a bug in wasm-ld: wasm-ld doesn't always
// align __heap_base and when this memory is shared through an API, it
// might result in unaligned memory. For details, see:
// https://reviews.llvm.org/D106499
// It should be removed once we switch to LLVM 13, where this is fixed.
end = end &^ (unsafe.Alignof(end) - 1)
}
markRoots(globalsStart, end)
} }

Просмотреть файл

@ -67,12 +67,7 @@ func SetFinalizer(obj interface{}, finalizer interface{}) {
func initHeap() { func initHeap() {
// preinit() may have moved heapStart; reset heapptr // preinit() may have moved heapStart; reset heapptr
ptr := heapStart heapptr = heapStart
if GOARCH == "wasm" {
// llvm11 and llvm12 do not correctly align the heap on wasm
ptr = align(ptr)
}
heapptr = ptr
} }
// setHeapEnd sets a new (larger) heapEnd pointer. // setHeapEnd sets a new (larger) heapEnd pointer.

Просмотреть файл

@ -1,4 +1,6 @@
{ {
"inherits": ["cortex-m"], "inherits": ["cortex-m"],
"llvm-target": "thumbv7m-unknown-unknown-eabi" "llvm-target": "thumbv8m.main-unknown-unknown-eabi",
"cpu": "cortex-m33",
"features": "+armv8-m.main,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
} }

Просмотреть файл

@ -18,17 +18,3 @@ func ApplyFunctionSections(mod llvm.Module) {
llvmFn = llvm.NextFunction(llvmFn) llvmFn = llvm.NextFunction(llvmFn)
} }
} }
// DisableTailCalls adds the "disable-tail-calls"="true" function attribute to
// all functions. This may be necessary, in particular to avoid an error with
// WebAssembly in LLVM 11.
func DisableTailCalls(mod llvm.Module) {
attribute := mod.Context().CreateStringAttribute("disable-tail-calls", "true")
llvmFn := mod.FirstFunction()
for !llvmFn.IsNil() {
if !llvmFn.IsDeclaration() {
llvmFn.AddFunctionAttr(attribute)
}
llvmFn = llvm.NextFunction(llvmFn)
}
}

Просмотреть файл

@ -9,7 +9,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"testing" "testing"
@ -101,12 +100,6 @@ func fuzzyEqualIR(s1, s2 string) bool {
// stripped out. // stripped out.
func filterIrrelevantIRLines(lines []string) []string { func filterIrrelevantIRLines(lines []string) []string {
var out []string var out []string
llvmVersion, err := strconv.Atoi(strings.Split(llvm.Version, ".")[0])
if err != nil {
// Note: this should never happen and if it does, it will always happen
// for a particular build because llvm.Version is a constant.
panic(err)
}
for _, line := range lines { for _, line := range lines {
line = strings.Split(line, ";")[0] // strip out comments/info line = strings.Split(line, ";")[0] // strip out comments/info
line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments
@ -116,11 +109,6 @@ func filterIrrelevantIRLines(lines []string) []string {
if strings.HasPrefix(line, "source_filename = ") { if strings.HasPrefix(line, "source_filename = ") {
continue continue
} }
if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") {
// Ignore attribute groups. These may change between LLVM versions.
// Right now test outputs are for LLVM 12.
continue
}
out = append(out, line) out = append(out, line)
} }
return out return out