From 9102ca6b1e94f6a62c413765807826682d62e9e9 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Mon, 5 Aug 2024 20:13:31 +0800 Subject: [PATCH] ssa: workaround for LLVM attribute compilation errors --- cl/compile_test.go | 24 +++++++++--------------- ssa/package.go | 36 +++++++++++++++++++++++++++++++++++- ssa/ssa_test.go | 36 +++++++++++++++--------------------- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/cl/compile_test.go b/cl/compile_test.go index 14be500c..b1942b80 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -140,7 +140,7 @@ source_filename = "foo" @"foo.init$guard" = global i1 false, align 1 -define ptr @foo.GenInts() #0 { +define ptr @foo.GenInts() presplitcoroutine { entry: %promise = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) @@ -207,36 +207,30 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: read) -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 +declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) ; Function Attrs: nounwind -declare i1 @llvm.coro.alloc(token) #2 +declare i1 @llvm.coro.alloc(token) ; Function Attrs: nounwind memory(none) -declare i64 @llvm.coro.size.i64() #3 +declare i64 @llvm.coro.size.i64() ; Function Attrs: nounwind -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 +declare ptr @llvm.coro.begin(token, ptr writeonly) ; Function Attrs: nounwind memory(argmem: read) -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #4 +declare ptr @llvm.coro.free(token, ptr nocapture readonly) ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1, token) #2 +declare i1 @llvm.coro.end(ptr, i1, token) ; Function Attrs: cold noreturn nounwind memory(inaccessiblemem: write) -declare void @llvm.trap() #5 +declare void @llvm.trap() declare void @"github.com/goplus/llgo/x/async.(*Promise).setValue[int]"(ptr, i64) ; Function Attrs: nounwind -declare i8 @llvm.coro.suspend(token, i1) #2 +declare i8 @llvm.coro.suspend(token, i1) -attributes #0 = { "presplitcoroutine" } -attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } -attributes #2 = { nounwind } -attributes #3 = { nounwind memory(none) } -attributes #4 = { nounwind memory(argmem: read) } -attributes #5 = { cold noreturn nounwind memory(inaccessiblemem: write) } `) } diff --git a/ssa/package.go b/ssa/package.go index 79a2acad..0c1ed75e 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -19,8 +19,10 @@ package ssa import ( "go/token" "go/types" + "regexp" "runtime" "strconv" + "strings" "unsafe" "github.com/goplus/llgo/ssa/abi" @@ -699,9 +701,41 @@ func (p Package) Path() string { return p.abi.Pkg } +// Find presplitcoroutine attribute and replace attribute tag with it +// e.g. attributes #0 = { noinline nounwind readnone "presplitcoroutine" } +// replace #0 with presplitcoroutine +// and also remove all other attributes +func removeLLVMAttributes(ll string) string { + attrRe := regexp.MustCompile(`^attributes (#\d+) = {[^}]*}$`) + attrRe2 := regexp.MustCompile(`(\) #\d+ {|\) #\d+)$`) + lines := strings.Split(ll, "\n") + newLines := make([]string, 0, len(lines)) + presplitcoroutine := "" + for _, line := range lines { + if m := attrRe.FindStringSubmatch(line); m != nil { + if strings.Contains(line, "\"presplitcoroutine\"") { + presplitcoroutine = " " + m[1] + " " + } + } else { + newLines = append(newLines, line) + } + } + + for i, line := range newLines { + if presplitcoroutine != "" { + line = strings.Replace(line, presplitcoroutine, " presplitcoroutine ", 1) + } + line = attrRe2.ReplaceAllString(line, ")") + newLines[i] = line + } + + return strings.Join(newLines, "\n") +} + // String returns a string representation of the package. func (p Package) String() string { - return p.mod.String() + // TODO(lijie): workaround for compiling errors of LLVM attributes + return removeLLVMAttributes(p.mod.String()) } // SetPatch sets a patch function. diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 05ac2dfd..3e5c1762 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -610,9 +610,8 @@ _llgo_0: } ; Function Attrs: cold noreturn nounwind memory(inaccessiblemem: write) -declare void @llvm.trap() #0 +declare void @llvm.trap() -attributes #0 = { cold noreturn nounwind memory(inaccessiblemem: write) } `) } @@ -710,57 +709,52 @@ _llgo_3: ; No predecessors! } ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: read) -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #0 +declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) ; Function Attrs: nounwind memory(none) -declare i32 @llvm.coro.size.i32() #1 +declare i32 @llvm.coro.size.i32() ; Function Attrs: nounwind memory(none) -declare i64 @llvm.coro.size.i64() #1 +declare i64 @llvm.coro.size.i64() ; Function Attrs: nounwind memory(none) -declare i32 @llvm.coro.align.i32() #1 +declare i32 @llvm.coro.align.i32() ; Function Attrs: nounwind memory(none) -declare i64 @llvm.coro.align.i64() #1 +declare i64 @llvm.coro.align.i64() ; Function Attrs: nounwind -declare i1 @llvm.coro.alloc(token) #2 +declare i1 @llvm.coro.alloc(token) ; Function Attrs: nounwind -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 +declare ptr @llvm.coro.begin(token, ptr writeonly) ; Function Attrs: nounwind memory(argmem: read) -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #3 +declare ptr @llvm.coro.free(token, ptr nocapture readonly) ; Function Attrs: nounwind -declare i1 @llvm.coro.end(ptr, i1, token) #2 +declare i1 @llvm.coro.end(ptr, i1, token) declare void @llvm.coro.resume(ptr) ; Function Attrs: nounwind memory(argmem: readwrite) -declare i1 @llvm.coro.done(ptr nocapture readonly) #4 +declare i1 @llvm.coro.done(ptr nocapture readonly) declare void @llvm.coro.destroy(ptr) ; Function Attrs: nounwind memory(none) -declare ptr @llvm.coro.promise(ptr nocapture, i32, i1) #1 +declare ptr @llvm.coro.promise(ptr nocapture, i32, i1) ; Function Attrs: nounwind memory(none) -declare ptr @llvm.coro.noop() #1 +declare ptr @llvm.coro.noop() ; Function Attrs: nounwind memory(none) -declare ptr @llvm.coro.frame() #1 +declare ptr @llvm.coro.frame() declare void @setValue(i64) ; Function Attrs: nounwind -declare i8 @llvm.coro.suspend(token, i1) #2 +declare i8 @llvm.coro.suspend(token, i1) -attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } -attributes #1 = { nounwind memory(none) } -attributes #2 = { nounwind } -attributes #3 = { nounwind memory(argmem: read) } -attributes #4 = { nounwind memory(argmem: readwrite) } `) }