aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-05-18 12:55:35 +0200
committerRon Evans <[email protected]>2024-05-24 19:12:26 +0200
commit81ce7fb738142361afba119f1f531cf6ffddc6d1 (patch)
tree68559a44ba49457b5ef9a5f2381fab1eae0276ff /compiler
parentc2776dcf78125abb86e3e7b4a110bb0d07386d09 (diff)
downloadtinygo-81ce7fb738142361afba119f1f531cf6ffddc6d1.tar.gz
tinygo-81ce7fb738142361afba119f1f531cf6ffddc6d1.zip
LLVM 18 support
Diffstat (limited to 'compiler')
-rw-r--r--compiler/asserts.go4
-rw-r--r--compiler/intrinsics.go10
-rw-r--r--compiler/llvm.go8
-rw-r--r--compiler/llvmutil/llvm.go13
-rw-r--r--compiler/testdata/channel.ll4
-rw-r--r--compiler/testdata/defer-cortex-m-qemu.ll6
-rw-r--r--compiler/testdata/gc.ll18
-rw-r--r--compiler/testdata/slice.ll4
-rw-r--r--compiler/testdata/zeromap.ll8
9 files changed, 51 insertions, 24 deletions
diff --git a/compiler/asserts.go b/compiler/asserts.go
index 0fb112e0b..035fda616 100644
--- a/compiler/asserts.go
+++ b/compiler/asserts.go
@@ -135,7 +135,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
// Calculate (^uintptr(0)) >> 1, which is the max value that fits in an
// uintptr if uintptrs were signed.
- maxBufSize := llvm.ConstLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false))
+ maxBufSize := b.CreateLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false), "")
if elementSize > maxBufSize.ZExtValue() {
b.addError(pos, fmt.Sprintf("channel element type is too big (%v bytes)", elementSize))
return
@@ -150,7 +150,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
// Make sure maxBufSize has the same type as bufSize.
if maxBufSize.Type() != bufSize.Type() {
- maxBufSize = llvm.ConstZExt(maxBufSize, bufSize.Type())
+ maxBufSize = b.CreateZExt(maxBufSize, bufSize.Type(), "")
}
// Do the check for a too large (or negative) buffer size.
diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go
index c1d05348b..3c7edd7c9 100644
--- a/compiler/intrinsics.go
+++ b/compiler/intrinsics.go
@@ -23,6 +23,8 @@ func (b *builder) defineIntrinsicFunction() {
b.createMemoryCopyImpl()
case name == "runtime.memzero":
b.createMemoryZeroImpl()
+ case name == "runtime.stacksave":
+ b.createStackSaveImpl()
case name == "runtime.KeepAlive":
b.createKeepAliveImpl()
case strings.HasPrefix(name, "runtime/volatile.Load"):
@@ -77,6 +79,14 @@ func (b *builder) createMemoryZeroImpl() {
b.CreateRetVoid()
}
+// createStackSaveImpl creates a call to llvm.stacksave.p0 to read the current
+// stack pointer.
+func (b *builder) createStackSaveImpl() {
+ b.createFunctionStart(true)
+ sp := b.readStackPointer()
+ b.CreateRet(sp)
+}
+
// Return the llvm.memset.p0.i8 function declaration.
func (c *compilerContext) getMemsetFunc() llvm.Value {
fnName := "llvm.memset.p0.i" + strconv.Itoa(c.uintptrType.IntTypeWidth())
diff --git a/compiler/llvm.go b/compiler/llvm.go
index 968d28b88..d693f6ed7 100644
--- a/compiler/llvm.go
+++ b/compiler/llvm.go
@@ -451,10 +451,14 @@ func (c *compilerContext) isThumb() bool {
// readStackPointer emits a LLVM intrinsic call that returns the current stack
// pointer as an *i8.
func (b *builder) readStackPointer() llvm.Value {
- stacksave := b.mod.NamedFunction("llvm.stacksave")
+ name := "llvm.stacksave.p0"
+ if llvmutil.Version() < 18 {
+ name = "llvm.stacksave" // backwards compatibility with LLVM 17 and below
+ }
+ stacksave := b.mod.NamedFunction(name)
if stacksave.IsNil() {
fnType := llvm.FunctionType(b.dataPtrType, nil, false)
- stacksave = llvm.AddFunction(b.mod, "llvm.stacksave", fnType)
+ stacksave = llvm.AddFunction(b.mod, name, fnType)
}
return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "")
}
diff --git a/compiler/llvmutil/llvm.go b/compiler/llvmutil/llvm.go
index d4ceee3fb..48fddffbe 100644
--- a/compiler/llvmutil/llvm.go
+++ b/compiler/llvmutil/llvm.go
@@ -8,6 +8,9 @@
package llvmutil
import (
+ "strconv"
+ "strings"
+
"tinygo.org/x/go-llvm"
)
@@ -203,3 +206,13 @@ func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
used.SetInitializer(usedInitializer)
used.SetLinkage(llvm.AppendingLinkage)
}
+
+// Return the LLVM major version.
+func Version() int {
+ majorStr := strings.Split(llvm.Version, ".")[0]
+ major, err := strconv.Atoi(majorStr)
+ if err != nil {
+ panic("unexpected error while parsing LLVM version: " + err.Error()) // should not happen
+ }
+ return major
+}
diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll
index be769e859..65e18dea8 100644
--- a/compiler/testdata/channel.ll
+++ b/compiler/testdata/channel.ll
@@ -81,11 +81,11 @@ entry:
%select.send.value = alloca i32, align 4
store i32 1, ptr %select.send.value, align 4
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
- store ptr %ch1, ptr %select.states.alloca, align 8
+ store ptr %ch1, ptr %select.states.alloca, align 4
%select.states.alloca.repack1 = getelementptr inbounds %runtime.chanSelectState, ptr %select.states.alloca, i32 0, i32 1
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
%0 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1
- store ptr %ch2, ptr %0, align 8
+ store ptr %ch2, ptr %0, align 4
%.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1, i32 1
store ptr null, ptr %.repack3, align 4
%select.result = call { i32, i1 } @runtime.tryChanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr undef) #4
diff --git a/compiler/testdata/defer-cortex-m-qemu.ll b/compiler/testdata/defer-cortex-m-qemu.ll
index 32697ccd5..52a3bfbab 100644
--- a/compiler/testdata/defer-cortex-m-qemu.ll
+++ b/compiler/testdata/defer-cortex-m-qemu.ll
@@ -25,7 +25,7 @@ entry:
%deferPtr = alloca ptr, align 4
store ptr null, ptr %deferPtr, align 4
%deferframe.buf = alloca %runtime.deferFrame, align 4
- %0 = call ptr @llvm.stacksave()
+ %0 = call ptr @llvm.stacksave.p0()
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
store i32 0, ptr %defer.alloca, align 4
%defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
@@ -113,7 +113,7 @@ rundefers.end3: ; preds = %rundefers.loophead6
}
; Function Attrs: nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave() #3
+declare ptr @llvm.stacksave.p0() #3
declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2
@@ -136,7 +136,7 @@ entry:
%deferPtr = alloca ptr, align 4
store ptr null, ptr %deferPtr, align 4
%deferframe.buf = alloca %runtime.deferFrame, align 4
- %0 = call ptr @llvm.stacksave()
+ %0 = call ptr @llvm.stacksave.p0()
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
store i32 0, ptr %defer.alloca, align 4
%defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll
index de638dad2..a696ee409 100644
--- a/compiler/testdata/gc.ll
+++ b/compiler/testdata/gc.ll
@@ -16,9 +16,9 @@ target triple = "wasm32-unknown-wasi"
@main.struct2 = hidden global ptr null, align 4
@main.struct3 = hidden global ptr null, align 4
@main.struct4 = hidden global ptr null, align 4
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 8
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 8
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 8
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 4
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 4
[email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 4
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
@@ -104,19 +104,19 @@ entry:
%stackalloc = alloca i8, align 1
%makeslice = call dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
- store ptr %makeslice, ptr @main.slice1, align 8
+ store ptr %makeslice, ptr @main.slice1, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
- store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 4
%makeslice1 = call dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
- store ptr %makeslice1, ptr @main.slice2, align 8
+ store ptr %makeslice1, ptr @main.slice2, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
- store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 4
%makeslice3 = call dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
- store ptr %makeslice3, ptr @main.slice3, align 8
+ store ptr %makeslice3, ptr @main.slice3, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
- store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 4
ret void
}
diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll
index bc0198741..29d5ed8a4 100644
--- a/compiler/testdata/slice.ll
+++ b/compiler/testdata/slice.ll
@@ -122,7 +122,7 @@ entry:
br i1 %slice.maxcap, label %slice.throw, label %slice.next
slice.next: ; preds = %entry
- %makeslice.cap = shl i32 %len, 1
+ %makeslice.cap = shl nuw i32 %len, 1
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
@@ -164,7 +164,7 @@ entry:
br i1 %slice.maxcap, label %slice.throw, label %slice.next
slice.next: ; preds = %entry
- %makeslice.cap = shl i32 %len, 2
+ %makeslice.cap = shl nuw i32 %len, 2
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
diff --git a/compiler/testdata/zeromap.ll b/compiler/testdata/zeromap.ll
index 510010dbe..4ad263130 100644
--- a/compiler/testdata/zeromap.ll
+++ b/compiler/testdata/zeromap.ll
@@ -26,7 +26,7 @@ entry:
%2 = insertvalue %main.hasPadding %1, i1 %s.b2, 2
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
- store %main.hasPadding %2, ptr %hashmap.key, align 8
+ store %main.hasPadding %2, ptr %hashmap.key, align 4
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
@@ -59,7 +59,7 @@ entry:
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
store i32 5, ptr %hashmap.value, align 4
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
- store %main.hasPadding %2, ptr %hashmap.key, align 8
+ store %main.hasPadding %2, ptr %hashmap.key, align 4
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
@@ -80,7 +80,7 @@ entry:
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
- store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
+ store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
@@ -108,7 +108,7 @@ entry:
store i32 5, ptr %hashmap.value, align 4
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
- store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
+ store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4