diff options
author | Ayke van Laethem <[email protected]> | 2024-05-18 12:55:35 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2024-05-24 19:12:26 +0200 |
commit | 81ce7fb738142361afba119f1f531cf6ffddc6d1 (patch) | |
tree | 68559a44ba49457b5ef9a5f2381fab1eae0276ff /compiler | |
parent | c2776dcf78125abb86e3e7b4a110bb0d07386d09 (diff) | |
download | tinygo-81ce7fb738142361afba119f1f531cf6ffddc6d1.tar.gz tinygo-81ce7fb738142361afba119f1f531cf6ffddc6d1.zip |
LLVM 18 support
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/asserts.go | 4 | ||||
-rw-r--r-- | compiler/intrinsics.go | 10 | ||||
-rw-r--r-- | compiler/llvm.go | 8 | ||||
-rw-r--r-- | compiler/llvmutil/llvm.go | 13 | ||||
-rw-r--r-- | compiler/testdata/channel.ll | 4 | ||||
-rw-r--r-- | compiler/testdata/defer-cortex-m-qemu.ll | 6 | ||||
-rw-r--r-- | compiler/testdata/gc.ll | 18 | ||||
-rw-r--r-- | compiler/testdata/slice.ll | 4 | ||||
-rw-r--r-- | compiler/testdata/zeromap.ll | 8 |
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 |