Compare commits

...

49 Commits

Author SHA1 Message Date
xushiwei
ed19a6960e Merge pull request #273 from xushiwei/q
cl/blocks
2024-06-05 15:20:08 +08:00
xushiwei
11b4de63ee llgo_autogen.lla 2024-06-05 15:14:34 +08:00
xushiwei
b9d1d52ab3 gentests 2024-06-05 15:10:35 +08:00
xushiwei
fe548e580d use cl/blocks 2024-06-05 15:08:05 +08:00
xushiwei
fd7d2765c8 findLoop: reach 2024-06-05 15:02:11 +08:00
xushiwei
a226a70383 findLoop: mark fdel 2024-06-05 14:14:12 +08:00
xushiwei
519e69a7f8 cl/blocks 2024-06-05 13:48:11 +08:00
xushiwei
3d599f8044 Merge pull request #271 from goplus/dependabot/go_modules/golang.org/x/tools-0.22.0
build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
2024-06-05 10:05:43 +08:00
dependabot[bot]
bbf0393008 build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-05 00:52:06 +00:00
xushiwei
f1a4af013a Merge pull request #270 from xushiwei/q
llgo/ssa: NoArgsNoRet
2024-06-04 20:03:49 +08:00
xushiwei
05af9f9810 llgo/ssa: NoArgsNoRet 2024-06-04 20:02:45 +08:00
xushiwei
f68aada9f8 Merge pull request #269 from cpunion/link-args
build: support pkg-config and link args
2024-06-04 19:22:48 +08:00
Li Jie
52d60d9623 build: support pkg-config and link args 2024-06-04 16:35:17 +08:00
xushiwei
2ddf8a44bc Merge pull request #268 from visualfc/cast
cl: fix cl/_testrt/cast
2024-06-04 15:43:53 +08:00
visualfc
281fbc2bee cl: fix cl/_testrt/cast 2024-06-04 15:27:49 +08:00
xushiwei
c174568081 Merge pull request #266 from xushiwei/q
c/sqlite
2024-06-04 12:55:30 +08:00
xushiwei
f4a519c824 c/sqlite 2024-06-04 12:48:49 +08:00
xushiwei
62e4e2f716 Merge pull request #258 from visualfc/invoke
ssa: MakeInterface check abi.KindDirectIface
2024-06-04 10:35:38 +08:00
visualfc
193e6dfc93 ssa: ChangeInterface 2024-06-03 16:03:05 +08:00
visualfc
7596658e6c ssa: MakeInterface check abi.KindDirectIface 2024-06-03 11:47:16 +08:00
xushiwei
73d6bd8400 Merge pull request #264 from xushiwei/q
llgo/ssa getDefer fix: move to function start
2024-06-03 09:58:55 +08:00
xushiwei
922fabd935 llgo/ssa getDefer fix: move to function start 2024-06-03 09:56:39 +08:00
xushiwei
2f3d267439 Merge pull request #263 from xushiwei/q
llgo/ssa: DeferAlways/DeferInCond/DeferInLoop
2024-06-03 08:46:24 +08:00
xushiwei
bdaf7ff30b Merge remote-tracking branch 'gop/main' into q 2024-06-03 08:43:34 +08:00
xushiwei
cfca98512a llgo/ssa: DeferAlways/DeferInCond/DeferInLoop 2024-06-03 02:43:04 +08:00
xushiwei
23d9e86c46 Merge pull request #262 from xushiwei/q
README: defer
2024-06-03 01:43:43 +08:00
xushiwei
6ac6fb0192 README: defer 2024-06-03 01:43:17 +08:00
xushiwei
aaa36b9d3b Merge pull request #261 from xushiwei/q
defer support; llgo/ssa: IfThen/RunDefers/EndBuild
2024-06-03 01:35:33 +08:00
xushiwei
2c799a8ccf deferInit bugfix 2024-06-03 01:32:25 +08:00
xushiwei
56a5a7d72e defer refactor 2024-06-03 01:06:01 +08:00
xushiwei
410f9dd759 llgo/ssa: EndBuild 2024-06-02 21:54:51 +08:00
xushiwei
ba45217756 llgo/ssa: RunDefers 2024-06-02 15:24:42 +08:00
xushiwei
5a5929048d defer support; llgo/ssa: IfThen 2024-06-02 14:29:35 +08:00
xushiwei
bfc3c7fbf9 Merge pull request #257 from xushiwei/q
llgo/ssa: Builtin
2024-06-01 17:33:01 +08:00
xushiwei
e151bd4cd1 TestUserdefExpr 2024-06-01 17:30:37 +08:00
xushiwei
bfe68520f4 logCall: ignore vkBuiltin 2024-06-01 17:26:42 +08:00
xushiwei
45734c0b5c llgo/ssa: Builtin 2024-06-01 17:18:17 +08:00
xushiwei
d689062fc3 Merge pull request #256 from xushiwei/q
README: goroutine
2024-06-01 16:17:24 +08:00
xushiwei
881574ed39 README: goroutine 2024-06-01 16:14:26 +08:00
xushiwei
0bd5aa873b Merge pull request #255 from xushiwei/q
goroutine support; llgo/ssa: memory (malloc/free)
2024-06-01 16:09:31 +08:00
xushiwei
51f3ac2376 _testgo: goroutine 2024-06-01 16:04:35 +08:00
xushiwei
e5802853c0 goroutine support; llgo/ssa: memory (malloc/free) 2024-06-01 15:52:54 +08:00
xushiwei
edb5e36916 Merge pull request #254 from xushiwei/q
c/pthread
2024-05-31 20:07:00 +08:00
xushiwei
33ba94e784 c/pthread 2024-05-31 20:02:59 +08:00
xushiwei
9c969e0026 Merge pull request #252 from visualfc/fnnamed
ssa: fix llvm named in func
2024-05-31 16:26:25 +08:00
visualfc
858622a98d move eface demo to cl/_testrt 2024-05-31 15:53:52 +08:00
visualfc
c673489461 ssa: fix llvm named in func 2024-05-31 14:22:17 +08:00
xushiwei
53a39b6947 Merge pull request #251 from xushiwei/q
llgo/ssa: Do Call/Go/Defer
2024-05-31 12:06:09 +08:00
xushiwei
8f82d86a5d llgo/ssa: Do Call/Go/Defer 2024-05-31 12:01:11 +08:00
62 changed files with 4907 additions and 1672 deletions

View File

@@ -172,10 +172,9 @@ Common Go syntax is already supported. Except for the following, which needs to
* map (Very limited support) * map (Very limited support)
* panic (Limited support) * panic (Limited support)
* recover (Not supported yet) * recover (Not supported yet)
* defer (Not supported yet) * defer (Limited: defer in loops is not supported)
* gc (Not supported yet) * gc (Not supported yet)
* chan (Not supported yet) * chan (Not supported yet)
* goroutine (Not supported yet)
* generics (Not supported yet) * generics (Not supported yet)
Here are some examples related to Go syntax: Here are some examples related to Go syntax:
@@ -183,6 +182,8 @@ Here are some examples related to Go syntax:
* [concat](_demo/concat/concat.go): define a variadic function * [concat](_demo/concat/concat.go): define a variadic function
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function) * [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
* [errors](_demo/errors/errors.go): demo to implement error interface * [errors](_demo/errors/errors.go): demo to implement error interface
* [defer](_demo/defer/defer.go): defer demo
* [goroutine](_demo/goroutine/goroutine.go): goroutine demo
## Go packages support ## Go packages support

17
_demo/defer/defer.go Normal file
View File

@@ -0,0 +1,17 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
}
defer println("bye")
}

View File

@@ -0,0 +1,12 @@
package main
func main() {
done := false
go func() {
println("Hello, goroutine")
done = true
}()
for !done {
print(".")
}
}

25
_demo/thread/thd.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/pthread"
)
var key pthread.Key
func main() {
key.Create(nil)
key.Set(c.Pointer(c.Str("main value\n")))
var thd pthread.Thread
pthread.Create(&thd, nil, func(arg c.Pointer) c.Pointer {
key.Set(c.Pointer(c.Str("thread value\n")))
c.Printf(c.Str("Hello, thread\nTLS: %s"), key.Get())
return c.Pointer(c.Str("Back to main\n"))
}, nil)
var retval c.Pointer
pthread.Join(thd, &retval)
c.Printf(c.Str("%sTLS: %s"), retval, key.Get())
}

12
c/c.go
View File

@@ -63,6 +63,9 @@ func Unreachable()
//go:linkname Malloc C.malloc //go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer func Malloc(size uintptr) Pointer
//go:linkname Free C.free
func Free(ptr Pointer)
//go:linkname Memcpy C.memcpy //go:linkname Memcpy C.memcpy
func Memcpy(dst, src Pointer, n uintptr) Pointer func Memcpy(dst, src Pointer, n uintptr) Pointer
@@ -115,11 +118,20 @@ func Fwrite(data Pointer, size, count uintptr, fp FilePtr) uintptr
//go:linkname Fputc C.fputc //go:linkname Fputc C.fputc
func Fputc(c Int, fp FilePtr) Int func Fputc(c Int, fp FilePtr) Int
//go:linkname Fputs C.fputs
func Fputs(s *Char, fp FilePtr) Int
//go:linkname Fflush C.fflush
func Fflush(fp FilePtr) Int
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname Time C.time //go:linkname Time C.time
func Time(*int32) int32 func Time(*int32) int32
//go:linkname Usleep C.usleep
func Usleep(useconds Uint) Int
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type Option struct { type Option struct {

160
c/pthread/pthread.go Normal file
View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pthread
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
func __noop__() c.Int {
return 0
}
// -----------------------------------------------------------------------------
type aThread struct {
Unused [8]byte
}
// Thread represents a POSIX thread.
type Thread = *aThread
// The pthread_create() function starts a new thread in the calling
// process. The new thread starts execution by invoking
// start_routine(); arg is passed as the sole argument of
// start_routine().
//
// The new thread terminates in one of the following ways:
//
// - It calls pthread_exit(3), specifying an exit status value that
// is available to another thread in the same process that calls
// pthread_join(3).
//
// - It returns from start_routine(). This is equivalent to
// calling pthread_exit(3) with the value supplied in the return
// statement.
//
// - It is canceled (see pthread_cancel(3)).
//
// - Any of the threads in the process calls exit(3), or the main
// thread performs a return from main(). This causes the
// termination of all threads in the process.
//
// On success, pthread_create() returns 0; on error, it returns an
// error number, and the contents of *thread are undefined.
//
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
//
//go:linkname Create C.pthread_create
func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
// The pthread_join() function waits for the thread specified by
// thread to terminate. If that thread has already terminated, then
// pthread_join() returns immediately. The thread specified by
// thread must be joinable.
//
// If retval is not NULL, then pthread_join() copies the exit status
// of the target thread (i.e., the value that the target thread
// supplied to pthread_exit(3)) into the location pointed to by
// retval. If the target thread was canceled, then PTHREAD_CANCELED
// is placed in the location pointed to by retval.
//
// If multiple threads simultaneously try to join with the same
// thread, the results are undefined. If the thread calling
// pthread_join() is canceled, then the target thread will remain
// joinable (i.e., it will not be detached).
//
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
//
//go:linkname Join C.pthread_join
func Join(thread Thread, retval *c.Pointer) c.Int
// The pthread_exit() function terminates the calling thread and
// returns a value via retval that (if the thread is joinable) is
// available to another thread in the same process that calls
// pthread_join(3).
//
// See https://man7.org/linux/man-pages/man3/pthread_exit.3.html
//
//go:linkname Exit C.pthread_exit
func Exit(retval c.Pointer)
// The pthread_cancel() function sends a cancelation request to the
// thread thread.
//
// See https://man7.org/linux/man-pages/man3/pthread_cancel.3.html
//
//go:linkname Cancel C.pthread_cancel
func Cancel(thread Thread) c.Int
// -----------------------------------------------------------------------------
// Attr represents a POSIX thread attributes.
type Attr struct {
Detached byte
SsSp *c.Char
SsSize uintptr
}
// llgo:link (*Attr).Init C.pthread_attr_init
func (attr *Attr) Init() c.Int { return 0 }
// llgo:link (*Attr).Destroy C.pthread_attr_destroy
func (attr *Attr) Destroy() c.Int { return 0 }
// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate
func (attr *Attr) GetDetached(detached *c.Int) c.Int { return 0 }
// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate
func (attr *Attr) SetDetached(detached c.Int) c.Int { return 0 }
// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize
func (attr *Attr) GetStackSize(stackSize *uintptr) c.Int { return 0 }
// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize
func (attr *Attr) SetStackSize(stackSize uintptr) c.Int { return 0 }
// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr
func (attr *Attr) GetStackAddr(stackAddr *c.Pointer) c.Int { return 0 }
// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr
func (attr *Attr) SetStackAddr(stackAddr c.Pointer) c.Int { return 0 }
// -----------------------------------------------------------------------------
// Thread Local Storage
type Key c.Uint
// llgo:link (*Key).Create C.pthread_key_create
func (key *Key) Create(destructor func(c.Pointer)) c.Int { return 0 }
// llgo:link Key.Delete C.pthread_key_delete
func (key Key) Delete() c.Int { return 0 }
// llgo:link Key.Get C.pthread_getspecific
func (key Key) Get() c.Pointer { return nil }
// llgo:link Key.Set C.pthread_setspecific
func (key Key) Set(value c.Pointer) c.Int { return __noop__() }
// -----------------------------------------------------------------------------

Binary file not shown.

View File

@@ -5,6 +5,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%main.stringStruct = type { ptr, i64 } %main.stringStruct = type { ptr, i64 }
%main.slice = type { ptr, i64, i64 } %main.slice = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@@ -85,7 +86,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
store i64 0, ptr @main.minhexdigits, align 4 store i64 0, ptr @main.minhexdigits, align 4
br label %_llgo_2 br label %_llgo_2
@@ -120,272 +121,352 @@ _llgo_0:
call void @main.prinfsub(double 1.001000e+02) call void @main.prinfsub(double 1.001000e+02)
call void @main.printnl() call void @main.printnl()
%6 = load ptr, ptr @_llgo_float32, align 8 %6 = load ptr, ptr @_llgo_float32, align 8
%7 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %6, i32 0, i32 6
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, i32 0, i32 0 %8 = load i8, ptr %7, align 1
store ptr %6, ptr %8, align 8 %9 = or i8 %8, 32
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, i32 0, i32 1 store i8 %9, ptr %7, align 1
store ptr inttoptr (i32 1315859240 to ptr), ptr %9, align 8 %10 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%10 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, align 8 %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 0
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.eface" %10) store ptr %6, ptr %11, align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1
store ptr inttoptr (i32 1315859240 to ptr), ptr %12, align 8
%13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.eface" %13)
call void @main.printnl() call void @main.printnl()
%11 = load ptr, ptr @_llgo_float64, align 8 %14 = load ptr, ptr @_llgo_float64, align 8
%12 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %14, i32 0, i32 6
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 0 %16 = load i8, ptr %15, align 1
store ptr %11, ptr %13, align 8 %17 = or i8 %16, 32
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 1 store i8 %17, ptr %15, align 1
store ptr inttoptr (i64 4746175415993761792 to ptr), ptr %14, align 8 %18 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%15 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, align 8 %19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 0
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.eface" %15) store ptr %14, ptr %19, align 8
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 1
store ptr inttoptr (i64 4746175415993761792 to ptr), ptr %20, align 8
%21 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, align 8
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.eface" %21)
call void @main.printnl() call void @main.printnl()
br i1 true, label %_llgo_3, label %_llgo_2 br i1 true, label %_llgo_3, label %_llgo_2
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %22 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %16, i64 0 %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, i64 0
%18 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %24 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 0 %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 0
store ptr @2, ptr %19, align 8 store ptr @2, ptr %25, align 8
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 1 %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 1
store i64 10, ptr %20, align 4 store i64 10, ptr %26, align 4
%21 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %18, align 8 %27 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %24, align 8
%22 = load ptr, ptr @_llgo_string, align 8 %28 = load ptr, ptr @_llgo_string, align 8
%23 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %29 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %21, ptr %23, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %27, ptr %29, align 8
%24 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %24, i32 0, i32 0
store ptr %22, ptr %25, align 8
%26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %24, i32 0, i32 1
store ptr %23, ptr %26, align 8
%27 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %24, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %27, ptr %17, align 8
%28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %16, i64 1
%29 = load ptr, ptr @_llgo_bool, align 8
%30 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %30 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 0 %31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 0
store ptr %29, ptr %31, align 8 store ptr %28, ptr %31, align 8
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 1 %32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 1
store ptr inttoptr (i64 -1 to ptr), ptr %32, align 8 store ptr %29, ptr %32, align 8
%33 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, align 8 %33 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %33, ptr %28, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %33, ptr %23, align 8
%34 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 %34 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, i64 1
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %34, i32 0, i32 0 %35 = load ptr, ptr @_llgo_bool, align 8
store ptr %16, ptr %35, align 8 %36 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %35, i32 0, i32 6
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %34, i32 0, i32 1 %37 = load i8, ptr %36, align 1
store i64 2, ptr %36, align 4 %38 = or i8 %37, 32
%37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %34, i32 0, i32 2 store i8 %38, ptr %36, align 1
store i64 2, ptr %37, align 4 %39 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%38 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %34, align 8 %40 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, i32 0, i32 0
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %38) store ptr %35, ptr %40, align 8
%41 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, i32 0, i32 1
store ptr inttoptr (i64 -1 to ptr), ptr %41, align 8
%42 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %42, ptr %34, align 8
%43 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%44 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 0
store ptr %22, ptr %44, align 8
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 1
store i64 2, ptr %45, align 4
%46 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 2
store i64 2, ptr %46, align 4
%47 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, align 8
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %47)
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_3, %_llgo_0
%39 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48) %48 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
%40 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, i64 0 %49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, i64 0
%41 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %50 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %41, i32 0, i32 0 %51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %50, i32 0, i32 0
store ptr @3, ptr %42, align 8 store ptr @3, ptr %51, align 8
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %41, i32 0, i32 1 %52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %50, i32 0, i32 1
store i64 8, ptr %43, align 4 store i64 8, ptr %52, align 4
%44 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %41, align 8 %53 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %50, align 8
%45 = load ptr, ptr @_llgo_string, align 8 %54 = load ptr, ptr @_llgo_string, align 8
%46 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %55 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %44, ptr %46, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %53, ptr %55, align 8
%47 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %56 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%48 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %47, i32 0, i32 0 %57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %56, i32 0, i32 0
store ptr %45, ptr %48, align 8 store ptr %54, ptr %57, align 8
%49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %47, i32 0, i32 1 %58 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %56, i32 0, i32 1
store ptr %46, ptr %49, align 8 store ptr %55, ptr %58, align 8
%50 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %47, align 8 %59 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %56, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %50, ptr %40, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %59, ptr %49, align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, i64 1 %60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, i64 1
%52 = load ptr, ptr @_llgo_bool, align 8 %61 = load ptr, ptr @_llgo_bool, align 8
%53 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %62 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %61, i32 0, i32 6
%54 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, i32 0, i32 0 %63 = load i8, ptr %62, align 1
store ptr %52, ptr %54, align 8 %64 = or i8 %63, 32
%55 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, i32 0, i32 1 store i8 %64, ptr %62, align 1
store ptr inttoptr (i64 -1 to ptr), ptr %55, align 8 %65 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%56 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, align 8 %66 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %65, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %56, ptr %51, align 8 store ptr %61, ptr %66, align 8
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %39, i64 2 %67 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %65, i32 0, i32 1
%58 = load ptr, ptr @_llgo_bool, align 8 store ptr inttoptr (i64 -1 to ptr), ptr %67, align 8
%59 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %68 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %65, align 8
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %59, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %68, ptr %60, align 8
store ptr %58, ptr %60, align 8 %69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, i64 2
%61 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %59, i32 0, i32 1
store ptr inttoptr (i64 -1 to ptr), ptr %61, align 8
%62 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %59, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %62, ptr %57, align 8
%63 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%64 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %63, i32 0, i32 0
store ptr %39, ptr %64, align 8
%65 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %63, i32 0, i32 1
store i64 3, ptr %65, align 4
%66 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %63, i32 0, i32 2
store i64 3, ptr %66, align 4
%67 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %63, align 8
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %67)
%68 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 256)
%69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 0
%70 = load ptr, ptr @_llgo_bool, align 8 %70 = load ptr, ptr @_llgo_bool, align 8
%71 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %71 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %70, i32 0, i32 6
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %71, i32 0, i32 0 %72 = load i8, ptr %71, align 1
store ptr %70, ptr %72, align 8 %73 = or i8 %72, 32
%73 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %71, i32 0, i32 1 store i8 %73, ptr %71, align 1
store ptr inttoptr (i64 -1 to ptr), ptr %73, align 8 %74 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%74 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %71, align 8 %75 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %74, ptr %69, align 8 store ptr %70, ptr %75, align 8
%75 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 1 %76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 1
%76 = load ptr, ptr @_llgo_bool, align 8 store ptr inttoptr (i64 -1 to ptr), ptr %76, align 8
%77 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %77 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, align 8
%78 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %77, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %77, ptr %69, align 8
store ptr %76, ptr %78, align 8 %78 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %77, i32 0, i32 1 %79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %78, i32 0, i32 0
store ptr null, ptr %79, align 8 store ptr %48, ptr %79, align 8
%80 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %77, align 8 %80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %78, i32 0, i32 1
store %"github.com/goplus/llgo/internal/runtime.eface" %80, ptr %75, align 8 store i64 3, ptr %80, align 4
%81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 2 %81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %78, i32 0, i32 2
%82 = load ptr, ptr @_llgo_int32, align 8 store i64 3, ptr %81, align 4
%83 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %82 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %78, align 8
%84 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i32 0, i32 0 call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %82)
store ptr %82, ptr %84, align 8 %83 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 256)
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i32 0, i32 1 %84 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 0
store ptr inttoptr (i64 97 to ptr), ptr %85, align 8 %85 = load ptr, ptr @_llgo_bool, align 8
%86 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, align 8 %86 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %85, i32 0, i32 6
store %"github.com/goplus/llgo/internal/runtime.eface" %86, ptr %81, align 8 %87 = load i8, ptr %86, align 1
%87 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 3 %88 = or i8 %87, 32
%88 = load ptr, ptr @_llgo_int32, align 8 store i8 %88, ptr %86, align 1
%89 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %89 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, i32 0, i32 0 %90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, i32 0, i32 0
store ptr %88, ptr %90, align 8 store ptr %85, ptr %90, align 8
%91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, i32 0, i32 1 %91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, i32 0, i32 1
store ptr inttoptr (i64 65 to ptr), ptr %91, align 8 store ptr inttoptr (i64 -1 to ptr), ptr %91, align 8
%92 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, align 8 %92 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %89, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %92, ptr %87, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %92, ptr %84, align 8
%93 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 4 %93 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 1
%94 = load ptr, ptr @_llgo_int32, align 8 %94 = load ptr, ptr @_llgo_bool, align 8
%95 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %95 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %94, i32 0, i32 6
%96 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %95, i32 0, i32 0 %96 = load i8, ptr %95, align 1
store ptr %94, ptr %96, align 8 %97 = or i8 %96, 32
%97 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %95, i32 0, i32 1 store i8 %97, ptr %95, align 1
store ptr inttoptr (i64 20013 to ptr), ptr %97, align 8 %98 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%98 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %95, align 8 %99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %98, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %98, ptr %93, align 8 store ptr %94, ptr %99, align 8
%99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 5 %100 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %98, i32 0, i32 1
%100 = load ptr, ptr @_llgo_int8, align 8 store ptr null, ptr %100, align 8
%101 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %101 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %98, align 8
%102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %101, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %101, ptr %93, align 8
store ptr %100, ptr %102, align 8 %102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 2
%103 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %101, i32 0, i32 1 %103 = load ptr, ptr @_llgo_int32, align 8
store ptr inttoptr (i64 1 to ptr), ptr %103, align 8 %104 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %103, i32 0, i32 6
%104 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %101, align 8 %105 = load i8, ptr %104, align 1
store %"github.com/goplus/llgo/internal/runtime.eface" %104, ptr %99, align 8 %106 = or i8 %105, 32
%105 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 6 store i8 %106, ptr %104, align 1
%106 = load ptr, ptr @_llgo_int16, align 8
%107 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %107 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 0 %108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 0
store ptr %106, ptr %108, align 8 store ptr %103, ptr %108, align 8
%109 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 1 %109 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 1
store ptr inttoptr (i64 2 to ptr), ptr %109, align 8 store ptr inttoptr (i64 97 to ptr), ptr %109, align 8
%110 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, align 8 %110 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %110, ptr %105, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %110, ptr %102, align 8
%111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 7 %111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 3
%112 = load ptr, ptr @_llgo_int32, align 8 %112 = load ptr, ptr @_llgo_int32, align 8
%113 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %113 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %112, i32 0, i32 6
%114 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, i32 0, i32 0 %114 = load i8, ptr %113, align 1
store ptr %112, ptr %114, align 8 %115 = or i8 %114, 32
%115 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, i32 0, i32 1 store i8 %115, ptr %113, align 1
store ptr inttoptr (i64 3 to ptr), ptr %115, align 8 %116 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%116 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, align 8 %117 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %116, ptr %111, align 8 store ptr %112, ptr %117, align 8
%117 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 8 %118 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, i32 0, i32 1
%118 = load ptr, ptr @_llgo_int64, align 8 store ptr inttoptr (i64 65 to ptr), ptr %118, align 8
%119 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %119 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, align 8
%120 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %119, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %119, ptr %111, align 8
store ptr %118, ptr %120, align 8 %120 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 4
%121 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %119, i32 0, i32 1 %121 = load ptr, ptr @_llgo_int32, align 8
store ptr inttoptr (i64 4 to ptr), ptr %121, align 8 %122 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %121, i32 0, i32 6
%122 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %119, align 8 %123 = load i8, ptr %122, align 1
store %"github.com/goplus/llgo/internal/runtime.eface" %122, ptr %117, align 8 %124 = or i8 %123, 32
%123 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 9 store i8 %124, ptr %122, align 1
%124 = load ptr, ptr @_llgo_int, align 8
%125 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %125 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%126 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 0 %126 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 0
store ptr %124, ptr %126, align 8 store ptr %121, ptr %126, align 8
%127 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 1 %127 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 1
store ptr inttoptr (i64 5 to ptr), ptr %127, align 8 store ptr inttoptr (i64 20013 to ptr), ptr %127, align 8
%128 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, align 8 %128 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %128, ptr %123, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %128, ptr %120, align 8
%129 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 10 %129 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 5
%130 = load ptr, ptr @_llgo_uint8, align 8 %130 = load ptr, ptr @_llgo_int8, align 8
%131 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %131 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %130, i32 0, i32 6
%132 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %131, i32 0, i32 0 %132 = load i8, ptr %131, align 1
store ptr %130, ptr %132, align 8 %133 = or i8 %132, 32
%133 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %131, i32 0, i32 1 store i8 %133, ptr %131, align 1
store ptr inttoptr (i64 1 to ptr), ptr %133, align 8 %134 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%134 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %131, align 8 %135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %134, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %134, ptr %129, align 8 store ptr %130, ptr %135, align 8
%135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 11 %136 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %134, i32 0, i32 1
%136 = load ptr, ptr @_llgo_uint16, align 8 store ptr inttoptr (i64 1 to ptr), ptr %136, align 8
%137 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %137 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %134, align 8
%138 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %137, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %137, ptr %129, align 8
store ptr %136, ptr %138, align 8 %138 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 6
%139 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %137, i32 0, i32 1 %139 = load ptr, ptr @_llgo_int16, align 8
store ptr inttoptr (i64 2 to ptr), ptr %139, align 8 %140 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %139, i32 0, i32 6
%140 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %137, align 8 %141 = load i8, ptr %140, align 1
store %"github.com/goplus/llgo/internal/runtime.eface" %140, ptr %135, align 8 %142 = or i8 %141, 32
%141 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 12 store i8 %142, ptr %140, align 1
%142 = load ptr, ptr @_llgo_uint32, align 8
%143 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %143 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%144 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, i32 0, i32 0 %144 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, i32 0, i32 0
store ptr %142, ptr %144, align 8 store ptr %139, ptr %144, align 8
%145 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, i32 0, i32 1 %145 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, i32 0, i32 1
store ptr inttoptr (i64 3 to ptr), ptr %145, align 8 store ptr inttoptr (i64 2 to ptr), ptr %145, align 8
%146 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, align 8 %146 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %143, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %146, ptr %141, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %146, ptr %138, align 8
%147 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 13 %147 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 7
%148 = load ptr, ptr @_llgo_uint64, align 8 %148 = load ptr, ptr @_llgo_int32, align 8
%149 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %149 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %148, i32 0, i32 6
%150 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %149, i32 0, i32 0 %150 = load i8, ptr %149, align 1
store ptr %148, ptr %150, align 8 %151 = or i8 %150, 32
%151 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %149, i32 0, i32 1 store i8 %151, ptr %149, align 1
store ptr inttoptr (i64 4 to ptr), ptr %151, align 8 %152 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%152 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %149, align 8 %153 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %152, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %152, ptr %147, align 8 store ptr %148, ptr %153, align 8
%153 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 14 %154 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %152, i32 0, i32 1
%154 = load ptr, ptr @_llgo_uintptr, align 8 store ptr inttoptr (i64 3 to ptr), ptr %154, align 8
%155 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %155 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %152, align 8
%156 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %155, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %155, ptr %147, align 8
store ptr %154, ptr %156, align 8 %156 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 8
%157 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %155, i32 0, i32 1 %157 = load ptr, ptr @_llgo_int64, align 8
store ptr inttoptr (i64 5 to ptr), ptr %157, align 8 %158 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %157, i32 0, i32 6
%158 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %155, align 8 %159 = load i8, ptr %158, align 1
store %"github.com/goplus/llgo/internal/runtime.eface" %158, ptr %153, align 8 %160 = or i8 %159, 32
%159 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i64 15 store i8 %160, ptr %158, align 1
%160 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %161 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%161 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %160, i32 0, i32 0 %162 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %161, i32 0, i32 0
store ptr @4, ptr %161, align 8 store ptr %157, ptr %162, align 8
%162 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %160, i32 0, i32 1 %163 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %161, i32 0, i32 1
store i64 4, ptr %162, align 4 store ptr inttoptr (i64 4 to ptr), ptr %163, align 8
%163 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %160, align 8 %164 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %161, align 8
%164 = load ptr, ptr @_llgo_string, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %164, ptr %156, align 8
%165 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %165 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 9
store %"github.com/goplus/llgo/internal/runtime.String" %163, ptr %165, align 8 %166 = load ptr, ptr @_llgo_int, align 8
%166 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %167 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %166, i32 0, i32 6
%167 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %166, i32 0, i32 0 %168 = load i8, ptr %167, align 1
store ptr %164, ptr %167, align 8 %169 = or i8 %168, 32
%168 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %166, i32 0, i32 1 store i8 %169, ptr %167, align 1
store ptr %165, ptr %168, align 8 %170 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%169 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %166, align 8 %171 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %170, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %169, ptr %159, align 8 store ptr %166, ptr %171, align 8
%170 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 %172 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %170, i32 0, i32 1
%171 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %170, i32 0, i32 0 store ptr inttoptr (i64 5 to ptr), ptr %172, align 8
store ptr %68, ptr %171, align 8 %173 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %170, align 8
%172 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %170, i32 0, i32 1 store %"github.com/goplus/llgo/internal/runtime.eface" %173, ptr %165, align 8
store i64 16, ptr %172, align 4 %174 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 10
%173 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %170, i32 0, i32 2 %175 = load ptr, ptr @_llgo_uint8, align 8
store i64 16, ptr %173, align 4 %176 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %175, i32 0, i32 6
%174 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %170, align 8 %177 = load i8, ptr %176, align 1
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %174) %178 = or i8 %177, 32
store i8 %178, ptr %176, align 1
%179 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%180 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %179, i32 0, i32 0
store ptr %175, ptr %180, align 8
%181 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %179, i32 0, i32 1
store ptr inttoptr (i64 1 to ptr), ptr %181, align 8
%182 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %179, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %182, ptr %174, align 8
%183 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 11
%184 = load ptr, ptr @_llgo_uint16, align 8
%185 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %184, i32 0, i32 6
%186 = load i8, ptr %185, align 1
%187 = or i8 %186, 32
store i8 %187, ptr %185, align 1
%188 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%189 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %188, i32 0, i32 0
store ptr %184, ptr %189, align 8
%190 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %188, i32 0, i32 1
store ptr inttoptr (i64 2 to ptr), ptr %190, align 8
%191 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %188, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %191, ptr %183, align 8
%192 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 12
%193 = load ptr, ptr @_llgo_uint32, align 8
%194 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %193, i32 0, i32 6
%195 = load i8, ptr %194, align 1
%196 = or i8 %195, 32
store i8 %196, ptr %194, align 1
%197 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%198 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %197, i32 0, i32 0
store ptr %193, ptr %198, align 8
%199 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %197, i32 0, i32 1
store ptr inttoptr (i64 3 to ptr), ptr %199, align 8
%200 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %197, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %200, ptr %192, align 8
%201 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 13
%202 = load ptr, ptr @_llgo_uint64, align 8
%203 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %202, i32 0, i32 6
%204 = load i8, ptr %203, align 1
%205 = or i8 %204, 32
store i8 %205, ptr %203, align 1
%206 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%207 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %206, i32 0, i32 0
store ptr %202, ptr %207, align 8
%208 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %206, i32 0, i32 1
store ptr inttoptr (i64 4 to ptr), ptr %208, align 8
%209 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %206, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %209, ptr %201, align 8
%210 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 14
%211 = load ptr, ptr @_llgo_uintptr, align 8
%212 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %211, i32 0, i32 6
%213 = load i8, ptr %212, align 1
%214 = or i8 %213, 32
store i8 %214, ptr %212, align 1
%215 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%216 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %215, i32 0, i32 0
store ptr %211, ptr %216, align 8
%217 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %215, i32 0, i32 1
store ptr inttoptr (i64 5 to ptr), ptr %217, align 8
%218 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %215, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %218, ptr %210, align 8
%219 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i64 15
%220 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%221 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %220, i32 0, i32 0
store ptr @4, ptr %221, align 8
%222 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %220, i32 0, i32 1
store i64 4, ptr %222, align 4
%223 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %220, align 8
%224 = load ptr, ptr @_llgo_string, align 8
%225 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %223, ptr %225, align 8
%226 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%227 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %226, i32 0, i32 0
store ptr %224, ptr %227, align 8
%228 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %226, i32 0, i32 1
store ptr %225, ptr %228, align 8
%229 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %226, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %229, ptr %219, align 8
%230 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%231 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %230, i32 0, i32 0
store ptr %83, ptr %231, align 8
%232 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %230, i32 0, i32 1
store i64 16, ptr %232, align 4
%233 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %230, i32 0, i32 2
store i64 16, ptr %233, align 4
%234 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %230, align 8
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %234)
ret i32 0 ret i32 0
_llgo_3: ; preds = %_llgo_0 _llgo_3: ; preds = %_llgo_0
@@ -1370,7 +1451,7 @@ _llgo_1: ; preds = %_llgo_3
%7 = icmp ult i64 %9, 10 %7 = icmp ult i64 %9, 10
br i1 %7, label %_llgo_2, label %_llgo_4 br i1 %7, label %_llgo_2, label %_llgo_4
_llgo_2: ; preds = %_llgo_3, %_llgo_1 _llgo_2: ; preds = %_llgo_1, %_llgo_3
%8 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %10, i64 100, i64 100) %8 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %10, i64 100, i64 100)
call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %8) call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %8)
ret void ret void
@@ -1412,7 +1493,7 @@ declare i32 @printf(ptr, ...)
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_float32, align 8 %0 = load ptr, ptr @_llgo_float32, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

View File

@@ -53,7 +53,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0 %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
store ptr @0, ptr %3, align 8 store ptr @1, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
store i64 7, ptr %4, align 4 store i64 7, ptr %4, align 4
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8 %5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
@@ -79,7 +79,7 @@ _llgo_3: ; preds = %_llgo_1, %_llgo_0
%15 = phi i64 [ 0, %_llgo_0 ], [ %11, %_llgo_1 ] %15 = phi i64 [ 0, %_llgo_0 ], [ %11, %_llgo_1 ]
%16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0 %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0
store ptr @1, ptr %17, align 8 store ptr @0, ptr %17, align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1 %18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1
store i64 7, ptr %18, align 4 store i64 7, ptr %18, align 4
%19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8 %19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8

View File

@@ -2,8 +2,9 @@
source_filename = "main" source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@@ -19,7 +20,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -35,40 +36,52 @@ _llgo_0:
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 0 %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 0
%4 = load ptr, ptr @_llgo_int, align 8 %4 = load ptr, ptr @_llgo_int, align 8
%5 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %4, i32 0, i32 6
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %5, i32 0, i32 0 %6 = load i8, ptr %5, align 1
store ptr %4, ptr %6, align 8 %7 = or i8 %6, 32
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %5, i32 0, i32 1 store i8 %7, ptr %5, align 1
store ptr inttoptr (i64 1 to ptr), ptr %7, align 8 %8 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%8 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %5, align 8 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %8, ptr %3, align 8 store ptr %4, ptr %9, align 8
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 1 %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 1
%10 = load ptr, ptr @_llgo_int, align 8 store ptr inttoptr (i64 1 to ptr), ptr %10, align 8
%11 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %11 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.eface" %11, ptr %3, align 8
store ptr %10, ptr %12, align 8 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 1
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, i32 0, i32 1 %13 = load ptr, ptr @_llgo_int, align 8
store ptr inttoptr (i64 2 to ptr), ptr %13, align 8 %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %13, i32 0, i32 6
%14 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, align 8 %15 = load i8, ptr %14, align 1
store %"github.com/goplus/llgo/internal/runtime.eface" %14, ptr %9, align 8 %16 = or i8 %15, 32
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 2 store i8 %16, ptr %14, align 1
%16 = load ptr, ptr @_llgo_int, align 8
%17 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %17 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, i32 0, i32 0 %18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, i32 0, i32 0
store ptr %16, ptr %18, align 8 store ptr %13, ptr %18, align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, i32 0, i32 1 %19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, i32 0, i32 1
store ptr inttoptr (i64 3 to ptr), ptr %19, align 8 store ptr inttoptr (i64 2 to ptr), ptr %19, align 8
%20 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, align 8 %20 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %17, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %20, ptr %15, align 8 store %"github.com/goplus/llgo/internal/runtime.eface" %20, ptr %12, align 8
%21 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 %21 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %2, i64 2
%22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %21, i32 0, i32 0 %22 = load ptr, ptr @_llgo_int, align 8
store ptr %2, ptr %22, align 8 %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %22, i32 0, i32 6
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %21, i32 0, i32 1 %24 = load i8, ptr %23, align 1
store i64 3, ptr %23, align 4 %25 = or i8 %24, 32
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %21, i32 0, i32 2 store i8 %25, ptr %23, align 1
store i64 3, ptr %24, align 4 %26 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%25 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %21, align 8 %27 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %26, i32 0, i32 0
call void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %25) store ptr %22, ptr %27, align 8
%28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %26, i32 0, i32 1
store ptr inttoptr (i64 3 to ptr), ptr %28, align 8
%29 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %26, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %29, ptr %21, align 8
%30 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %30, i32 0, i32 0
store ptr %2, ptr %31, align 8
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %30, i32 0, i32 1
store i64 3, ptr %32, align 4
%33 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %30, i32 0, i32 2
store i64 3, ptr %33, align 4
%34 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %30, align 8
call void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %34)
ret i32 0 ret i32 0
} }
@@ -118,7 +131,7 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_int, align 8 %0 = load ptr, ptr @_llgo_int, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

20
cl/_testdefer/loop/in.go Normal file
View File

@@ -0,0 +1,20 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
for i := 0; i < 3; i++ {
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
return
}
}
defer println("bye")
}

View File

@@ -0,0 +1,7 @@
0: always
1: cond
4: loop
2: loop
5: loop
3: cond
6: cond

View File

@@ -0,0 +1,18 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
return
}
defer println("bye")
}

View File

@@ -0,0 +1,4 @@
0: always
1: cond
2: cond
3: cond

52
cl/_testdefer/print/in.go Normal file
View File

@@ -0,0 +1,52 @@
package main
func f() float64 {
return 1.0
}
func main() {
var v = f()
const n = 7 // digits printed
var buf [n + 7]byte
buf[0] = '+'
e := 0 // exp
if v == 0 {
if 1/v < 0 {
buf[0] = '-'
}
} else {
if v < 0 {
v = -v
buf[0] = '-'
}
// normalize
for v >= 10 {
e++
v /= 10
}
for v < 1 {
e--
v *= 10
}
// round
h := 5.0
for i := 0; i < n; i++ {
h /= 10
}
v += h
if v >= 10 {
e++
v /= 10
}
}
// format +d.dddd+edd
for i := 0; i < n; i++ {
s := int(v)
buf[i+2] = byte(s + '0')
v -= float64(s)
v *= 10
}
}

View File

@@ -0,0 +1,18 @@
0: always
1: cond
3: cond
4: cond
5: cond
7: loop
6: loop
10: loop
8: loop
9: cond
13: loop
11: loop
12: cond
14: cond
2: cond
17: loop
15: loop
16: always

View File

@@ -0,0 +1,17 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
}
defer println("bye")
}

View File

@@ -0,0 +1,5 @@
0: always
1: cond
2: cond
4: cond
3: always

18
cl/_testgo/defer/in.go Normal file
View File

@@ -0,0 +1,18 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
return
}
defer println("bye")
}

188
cl/_testgo/defer/out.ll Normal file
View File

@@ -0,0 +1,188 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.Defer" = type { { ptr, ptr }, i64, ptr, i64 }
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@__llgo_defer = linkonce global ptr null
@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@2 = private unnamed_addr constant [4 x i8] c"bye\00", align 1
@3 = private unnamed_addr constant [6 x i8] c"world\00", align 1
@4 = private unnamed_addr constant [3 x i8] c"hi\00", align 1
define i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1
%2 = icmp sgt i64 %1, 2
ret i1 %2
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$after"()
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
%2 = load ptr, ptr @__llgo_defer, align 8
%3 = call ptr @pthread_getspecific(ptr %2)
%4 = alloca i8, i64 40, align 1
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 0
store ptr null, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 1
store i64 0, ptr %6, align 4
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 2
store ptr %3, ptr %7, align 8
%8 = call i32 @pthread_setspecific(ptr %2, ptr %4)
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 1
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 3
%11 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 0
store ptr @0, ptr %12, align 8
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 1
store i64 5, ptr %13, align 4
%14 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %11, align 8
%15 = call i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %14)
br i1 %15, label %_llgo_2, label %_llgo_3
_llgo_1: ; No predecessors!
ret i32 0
_llgo_2: ; preds = %_llgo_0
%16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0
store ptr @1, ptr %17, align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1
store i64 5, ptr %18, align 4
%19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8
%20 = load i64, ptr %9, align 4
%21 = or i64 %20, 1
store i64 %21, ptr %9, align 4
%22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0
store ptr @2, ptr %23, align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
store i64 3, ptr %24, align 4
%25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
%26 = load i64, ptr %9, align 4
%27 = or i64 %26, 2
store i64 %27, ptr %9, align 4
store i64 0, ptr %10, align 4
br label %_llgo_4
_llgo_3: ; preds = %_llgo_0
%28 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 0
store ptr @3, ptr %29, align 8
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 1
store i64 5, ptr %30, align 4
%31 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %28, align 8
%32 = load i64, ptr %9, align 4
%33 = or i64 %32, 4
store i64 %33, ptr %9, align 4
store i64 1, ptr %10, align 4
br label %_llgo_4
_llgo_4: ; preds = %_llgo_3, %_llgo_2
%34 = load i64, ptr %9, align 4
%35 = and i64 %34, 4
%36 = icmp ne i64 %35, 0
br i1 %36, label %_llgo_7, label %_llgo_8
_llgo_5: ; preds = %_llgo_12
ret i32 0
_llgo_6: ; preds = %_llgo_12
ret i32 0
_llgo_7: ; preds = %_llgo_4
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %31)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
br label %_llgo_8
_llgo_8: ; preds = %_llgo_7, %_llgo_4
%37 = and i64 %34, 2
%38 = icmp ne i64 %37, 0
br i1 %38, label %_llgo_9, label %_llgo_10
_llgo_9: ; preds = %_llgo_8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %25)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
br label %_llgo_10
_llgo_10: ; preds = %_llgo_9, %_llgo_8
%39 = and i64 %34, 1
%40 = icmp ne i64 %39, 0
br i1 %40, label %_llgo_11, label %_llgo_12
_llgo_11: ; preds = %_llgo_10
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %19)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
br label %_llgo_12
_llgo_12: ; preds = %_llgo_11, %_llgo_10
call void @"main.main$1"()
%41 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, align 8
%42 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %41, 2
%43 = call i32 @pthread_setspecific(ptr %2, ptr %42)
%44 = load i64, ptr %10, align 4
switch i64 %44, label %_llgo_5 [
i64 1, label %_llgo_6
]
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
define void @"main.main$1"() {
_llgo_0:
%0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0
store ptr @4, ptr %1, align 8
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1
store i64 2, ptr %2, align 4
%3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %3)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret void
}
declare ptr @pthread_getspecific(i32)
declare i32 @pthread_setspecific(i32, ptr)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
define void @"main.init$after"() {
_llgo_0:
%0 = load ptr, ptr @__llgo_defer, align 8
%1 = icmp eq ptr %0, null
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
declare i32 @pthread_key_create(ptr, ptr)

View File

@@ -1,613 +0,0 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
%main.eface = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 }
@"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@_llgo_bool = linkonce global ptr null
@_llgo_int = linkonce global ptr null
@_llgo_int8 = linkonce global ptr null
@_llgo_int16 = linkonce global ptr null
@_llgo_int32 = linkonce global ptr null
@_llgo_int64 = linkonce global ptr null
@_llgo_uint = linkonce global ptr null
@_llgo_uint8 = linkonce global ptr null
@_llgo_uint16 = linkonce global ptr null
@_llgo_uint32 = linkonce global ptr null
@_llgo_uint64 = linkonce global ptr null
@_llgo_uintptr = linkonce global ptr null
@_llgo_float32 = linkonce global ptr null
@_llgo_float64 = linkonce global ptr null
@"[10]_llgo_int" = linkonce global ptr null
@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null
@"*_llgo_int" = linkonce global ptr null
@"[]_llgo_int" = linkonce global ptr null
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@_llgo_string = linkonce global ptr null
@"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM" = global ptr null
@2 = private unnamed_addr constant [2 x i8] c"x\00", align 1
@3 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@4 = private unnamed_addr constant [2 x i8] c"y\00", align 1
@5 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@6 = private unnamed_addr constant [2 x i8] c"z\00", align 1
@7 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@8 = private unnamed_addr constant [5 x i8] c"main\00", align 1
define void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.eface" %0, ptr %1, align 8
%2 = getelementptr inbounds %main.eface, ptr %1, i32 0, i32 0
%3 = load ptr, ptr %2, align 8
%4 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 0
store ptr @0, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
store i64 0, ptr %6, align 4
%7 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %4, align 8
call void @main.dumpTyp(ptr %3, %"github.com/goplus/llgo/internal/runtime.String" %7)
ret void
}
define void @main.dumpTyp(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %1)
%2 = call i64 @"github.com/goplus/llgo/internal/abi.(*Type).Kind"(ptr %0)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 0
%4 = load i64, ptr %3, align 4
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 1
%6 = load i64, ptr %5, align 4
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 2
%8 = load i32, ptr %7, align 4
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 3
%10 = load i8, ptr %9, align 1
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 4
%12 = load i8, ptr %11, align 1
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %2)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %6)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%13 = zext i32 %8 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %13)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%14 = zext i8 %10 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %14)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%15 = zext i8 %12 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %15)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret void
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
call void @"github.com/goplus/llgo/internal/abi.init"()
call void @"main.init$abi"()
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = load ptr, ptr @_llgo_bool, align 8
%3 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, i32 0, i32 0
store ptr %2, ptr %4, align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, i32 0, i32 1
store ptr inttoptr (i64 -1 to ptr), ptr %5, align 8
%6 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %6)
%7 = load ptr, ptr @_llgo_int, align 8
%8 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 0
store ptr %7, ptr %9, align 8
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 1
store ptr null, ptr %10, align 8
%11 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %11)
%12 = load ptr, ptr @_llgo_int8, align 8
%13 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, i32 0, i32 0
store ptr %12, ptr %14, align 8
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, i32 0, i32 1
store ptr null, ptr %15, align 8
%16 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %16)
%17 = load ptr, ptr @_llgo_int16, align 8
%18 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 0
store ptr %17, ptr %19, align 8
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, i32 0, i32 1
store ptr null, ptr %20, align 8
%21 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %18, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %21)
%22 = load ptr, ptr @_llgo_int32, align 8
%23 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %23, i32 0, i32 0
store ptr %22, ptr %24, align 8
%25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %23, i32 0, i32 1
store ptr null, ptr %25, align 8
%26 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %23, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %26)
%27 = load ptr, ptr @_llgo_int64, align 8
%28 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, i32 0, i32 0
store ptr %27, ptr %29, align 8
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, i32 0, i32 1
store ptr null, ptr %30, align 8
%31 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %28, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %31)
%32 = load ptr, ptr @_llgo_uint, align 8
%33 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%34 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %33, i32 0, i32 0
store ptr %32, ptr %34, align 8
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %33, i32 0, i32 1
store ptr null, ptr %35, align 8
%36 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %33, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %36)
%37 = load ptr, ptr @_llgo_uint8, align 8
%38 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, i32 0, i32 0
store ptr %37, ptr %39, align 8
%40 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, i32 0, i32 1
store ptr null, ptr %40, align 8
%41 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %41)
%42 = load ptr, ptr @_llgo_uint16, align 8
%43 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%44 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %43, i32 0, i32 0
store ptr %42, ptr %44, align 8
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %43, i32 0, i32 1
store ptr null, ptr %45, align 8
%46 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %43, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %46)
%47 = load ptr, ptr @_llgo_uint32, align 8
%48 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, i32 0, i32 0
store ptr %47, ptr %49, align 8
%50 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, i32 0, i32 1
store ptr null, ptr %50, align 8
%51 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %48, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %51)
%52 = load ptr, ptr @_llgo_uint64, align 8
%53 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%54 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, i32 0, i32 0
store ptr %52, ptr %54, align 8
%55 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, i32 0, i32 1
store ptr null, ptr %55, align 8
%56 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %53, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %56)
%57 = load ptr, ptr @_llgo_uintptr, align 8
%58 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%59 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %58, i32 0, i32 0
store ptr %57, ptr %59, align 8
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %58, i32 0, i32 1
store ptr null, ptr %60, align 8
%61 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %58, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %61)
%62 = load ptr, ptr @_llgo_float32, align 8
%63 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%64 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %63, i32 0, i32 0
store ptr %62, ptr %64, align 8
%65 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %63, i32 0, i32 1
store ptr null, ptr %65, align 8
%66 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %63, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %66)
%67 = load ptr, ptr @_llgo_float64, align 8
%68 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i32 0, i32 0
store ptr %67, ptr %69, align 8
%70 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, i32 0, i32 1
store ptr null, ptr %70, align 8
%71 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %71)
%72 = load ptr, ptr @"[10]_llgo_int", align 8
%73 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 80)
store [10 x i64] zeroinitializer, ptr %73, align 4
%74 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%75 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 0
store ptr %72, ptr %75, align 8
%76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 1
store ptr %73, ptr %76, align 8
%77 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %77)
%78 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%79 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, i32 0, i32 0
store ptr %78, ptr %80, align 8
%81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, i32 0, i32 1
store ptr @"main.main$1", ptr %81, align 8
%82 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %82)
%83 = load ptr, ptr @"*_llgo_int", align 8
%84 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, i32 0, i32 0
store ptr %83, ptr %85, align 8
%86 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, i32 0, i32 1
store ptr null, ptr %86, align 8
%87 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %87)
%88 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0)
%89 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 0
store ptr %88, ptr %90, align 8
%91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 1
store i64 0, ptr %91, align 4
%92 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 2
store i64 0, ptr %92, align 4
%93 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, align 8
%94 = load ptr, ptr @"[]_llgo_int", align 8
%95 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
store %"github.com/goplus/llgo/internal/runtime.Slice" %93, ptr %95, align 8
%96 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%97 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, i32 0, i32 0
store ptr %94, ptr %97, align 8
%98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, i32 0, i32 1
store ptr %95, ptr %98, align 8
%99 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %99)
%100 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%101 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %100, i32 0, i32 0
store ptr @1, ptr %101, align 8
%102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %100, i32 0, i32 1
store i64 5, ptr %102, align 4
%103 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %100, align 8
%104 = load ptr, ptr @_llgo_string, align 8
%105 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %103, ptr %105, align 8
%106 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%107 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, i32 0, i32 0
store ptr %104, ptr %107, align 8
%108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, i32 0, i32 1
store ptr %105, ptr %108, align 8
%109 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %109)
%110 = load ptr, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8
%111 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
store { i8, i64, i64 } zeroinitializer, ptr %111, align 4
%112 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%113 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, i32 0, i32 0
store ptr %110, ptr %113, align 8
%114 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, i32 0, i32 1
store ptr %111, ptr %114, align 8
%115 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %115)
ret i32 0
}
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare i64 @"github.com/goplus/llgo/internal/abi.(*Type).Kind"(ptr)
declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare void @"github.com/goplus/llgo/internal/abi.init"()
declare void @"github.com/goplus/llgo/internal/runtime.init"()
define void @"main.init$abi"() {
_llgo_0:
%0 = load ptr, ptr @_llgo_bool, align 8
%1 = icmp eq ptr %0, null
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
store ptr %2, ptr @_llgo_bool, align 8
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
%3 = load ptr, ptr @_llgo_int, align 8
%4 = icmp eq ptr %3, null
br i1 %4, label %_llgo_3, label %_llgo_4
_llgo_3: ; preds = %_llgo_2
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
store ptr %5, ptr @_llgo_int, align 8
br label %_llgo_4
_llgo_4: ; preds = %_llgo_3, %_llgo_2
%6 = load ptr, ptr @_llgo_int8, align 8
%7 = icmp eq ptr %6, null
br i1 %7, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
store ptr %8, ptr @_llgo_int8, align 8
br label %_llgo_6
_llgo_6: ; preds = %_llgo_5, %_llgo_4
%9 = load ptr, ptr @_llgo_int16, align 8
%10 = icmp eq ptr %9, null
br i1 %10, label %_llgo_7, label %_llgo_8
_llgo_7: ; preds = %_llgo_6
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
store ptr %11, ptr @_llgo_int16, align 8
br label %_llgo_8
_llgo_8: ; preds = %_llgo_7, %_llgo_6
%12 = load ptr, ptr @_llgo_int32, align 8
%13 = icmp eq ptr %12, null
br i1 %13, label %_llgo_9, label %_llgo_10
_llgo_9: ; preds = %_llgo_8
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
store ptr %14, ptr @_llgo_int32, align 8
br label %_llgo_10
_llgo_10: ; preds = %_llgo_9, %_llgo_8
%15 = load ptr, ptr @_llgo_int64, align 8
%16 = icmp eq ptr %15, null
br i1 %16, label %_llgo_11, label %_llgo_12
_llgo_11: ; preds = %_llgo_10
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
store ptr %17, ptr @_llgo_int64, align 8
br label %_llgo_12
_llgo_12: ; preds = %_llgo_11, %_llgo_10
%18 = load ptr, ptr @_llgo_uint, align 8
%19 = icmp eq ptr %18, null
br i1 %19, label %_llgo_13, label %_llgo_14
_llgo_13: ; preds = %_llgo_12
%20 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
store ptr %20, ptr @_llgo_uint, align 8
br label %_llgo_14
_llgo_14: ; preds = %_llgo_13, %_llgo_12
%21 = load ptr, ptr @_llgo_uint8, align 8
%22 = icmp eq ptr %21, null
br i1 %22, label %_llgo_15, label %_llgo_16
_llgo_15: ; preds = %_llgo_14
%23 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
store ptr %23, ptr @_llgo_uint8, align 8
br label %_llgo_16
_llgo_16: ; preds = %_llgo_15, %_llgo_14
%24 = load ptr, ptr @_llgo_uint16, align 8
%25 = icmp eq ptr %24, null
br i1 %25, label %_llgo_17, label %_llgo_18
_llgo_17: ; preds = %_llgo_16
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
store ptr %26, ptr @_llgo_uint16, align 8
br label %_llgo_18
_llgo_18: ; preds = %_llgo_17, %_llgo_16
%27 = load ptr, ptr @_llgo_uint32, align 8
%28 = icmp eq ptr %27, null
br i1 %28, label %_llgo_19, label %_llgo_20
_llgo_19: ; preds = %_llgo_18
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
store ptr %29, ptr @_llgo_uint32, align 8
br label %_llgo_20
_llgo_20: ; preds = %_llgo_19, %_llgo_18
%30 = load ptr, ptr @_llgo_uint64, align 8
%31 = icmp eq ptr %30, null
br i1 %31, label %_llgo_21, label %_llgo_22
_llgo_21: ; preds = %_llgo_20
%32 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
store ptr %32, ptr @_llgo_uint64, align 8
br label %_llgo_22
_llgo_22: ; preds = %_llgo_21, %_llgo_20
%33 = load ptr, ptr @_llgo_uintptr, align 8
%34 = icmp eq ptr %33, null
br i1 %34, label %_llgo_23, label %_llgo_24
_llgo_23: ; preds = %_llgo_22
%35 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
store ptr %35, ptr @_llgo_uintptr, align 8
br label %_llgo_24
_llgo_24: ; preds = %_llgo_23, %_llgo_22
%36 = load ptr, ptr @_llgo_float32, align 8
%37 = icmp eq ptr %36, null
br i1 %37, label %_llgo_25, label %_llgo_26
_llgo_25: ; preds = %_llgo_24
%38 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
store ptr %38, ptr @_llgo_float32, align 8
br label %_llgo_26
_llgo_26: ; preds = %_llgo_25, %_llgo_24
%39 = load ptr, ptr @_llgo_float64, align 8
%40 = icmp eq ptr %39, null
br i1 %40, label %_llgo_27, label %_llgo_28
_llgo_27: ; preds = %_llgo_26
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
store ptr %41, ptr @_llgo_float64, align 8
br label %_llgo_28
_llgo_28: ; preds = %_llgo_27, %_llgo_26
%42 = load ptr, ptr @_llgo_int, align 8
%43 = load ptr, ptr @"[10]_llgo_int", align 8
%44 = icmp eq ptr %43, null
br i1 %44, label %_llgo_29, label %_llgo_30
_llgo_29: ; preds = %_llgo_28
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.ArrayOf"(i64 10, ptr %42)
store ptr %45, ptr @"[10]_llgo_int", align 8
br label %_llgo_30
_llgo_30: ; preds = %_llgo_29, %_llgo_28
%46 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%47 = icmp eq ptr %46, null
br i1 %47, label %_llgo_31, label %_llgo_32
_llgo_31: ; preds = %_llgo_30
%48 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%49 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%50 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 0
store ptr %48, ptr %50, align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 1
store i64 0, ptr %51, align 4
%52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 2
store i64 0, ptr %52, align 4
%53 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, align 8
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%55 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 0
store ptr %54, ptr %56, align 8
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 1
store i64 0, ptr %57, align 4
%58 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 2
store i64 0, ptr %58, align 4
%59 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, align 8
%60 = call ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice" %53, %"github.com/goplus/llgo/internal/runtime.Slice" %59, i1 false)
store ptr %60, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
br label %_llgo_32
_llgo_32: ; preds = %_llgo_31, %_llgo_30
%61 = load ptr, ptr @_llgo_int, align 8
%62 = load ptr, ptr @"*_llgo_int", align 8
%63 = icmp eq ptr %62, null
br i1 %63, label %_llgo_33, label %_llgo_34
_llgo_33: ; preds = %_llgo_32
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %61)
store ptr %64, ptr @"*_llgo_int", align 8
br label %_llgo_34
_llgo_34: ; preds = %_llgo_33, %_llgo_32
%65 = load ptr, ptr @_llgo_int, align 8
%66 = load ptr, ptr @"[]_llgo_int", align 8
%67 = icmp eq ptr %66, null
br i1 %67, label %_llgo_35, label %_llgo_36
_llgo_35: ; preds = %_llgo_34
%68 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceOf"(ptr %65)
store ptr %68, ptr @"[]_llgo_int", align 8
br label %_llgo_36
_llgo_36: ; preds = %_llgo_35, %_llgo_34
%69 = load ptr, ptr @_llgo_string, align 8
%70 = icmp eq ptr %69, null
br i1 %70, label %_llgo_37, label %_llgo_38
_llgo_37: ; preds = %_llgo_36
%71 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
store ptr %71, ptr @_llgo_string, align 8
br label %_llgo_38
_llgo_38: ; preds = %_llgo_37, %_llgo_36
%72 = load ptr, ptr @_llgo_int8, align 8
%73 = load ptr, ptr @_llgo_int, align 8
%74 = load ptr, ptr @_llgo_int, align 8
%75 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %75, i32 0, i32 0
store ptr @2, ptr %76, align 8
%77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %75, i32 0, i32 1
store i64 1, ptr %77, align 4
%78 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %75, align 8
%79 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %79, i32 0, i32 0
store ptr @3, ptr %80, align 8
%81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %79, i32 0, i32 1
store i64 0, ptr %81, align 4
%82 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %79, align 8
%83 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %78, ptr %72, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %82, i1 false)
%84 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %84, i32 0, i32 0
store ptr @4, ptr %85, align 8
%86 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %84, i32 0, i32 1
store i64 1, ptr %86, align 4
%87 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %84, align 8
%88 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%89 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %88, i32 0, i32 0
store ptr @5, ptr %89, align 8
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %88, i32 0, i32 1
store i64 0, ptr %90, align 4
%91 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %88, align 8
%92 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %87, ptr %73, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %91, i1 false)
%93 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%94 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %93, i32 0, i32 0
store ptr @6, ptr %94, align 8
%95 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %93, i32 0, i32 1
store i64 1, ptr %95, align 4
%96 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %93, align 8
%97 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 0
store ptr @7, ptr %98, align 8
%99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 1
store i64 0, ptr %99, align 4
%100 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %97, align 8
%101 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %96, ptr %74, i64 16, %"github.com/goplus/llgo/internal/runtime.String" %100, i1 false)
%102 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%103 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %102, i32 0, i32 0
store ptr @8, ptr %103, align 8
%104 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %102, i32 0, i32 1
store i64 4, ptr %104, align 4
%105 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %102, align 8
%106 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 168)
%107 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 0
store %"github.com/goplus/llgo/internal/abi.StructField" %83, ptr %107, align 8
%108 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 1
store %"github.com/goplus/llgo/internal/abi.StructField" %92, ptr %108, align 8
%109 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 2
store %"github.com/goplus/llgo/internal/abi.StructField" %101, ptr %109, align 8
%110 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 0
store ptr %106, ptr %111, align 8
%112 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 1
store i64 3, ptr %112, align 4
%113 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 2
store i64 3, ptr %113, align 4
%114 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, align 8
%115 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %105, i64 24, %"github.com/goplus/llgo/internal/runtime.Slice" %114)
store ptr %115, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.ArrayOf"(i64, ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
define void @"main.main$1"() {
_llgo_0:
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice", i1)
declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceOf"(ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String", i64, %"github.com/goplus/llgo/internal/runtime.Slice")
declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1)

View File

@@ -60,7 +60,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -82,15 +82,15 @@ _llgo_0:
%6 = call %"github.com/goplus/llgo/internal/runtime.iface" @main.New(%"github.com/goplus/llgo/internal/runtime.String" %5) %6 = call %"github.com/goplus/llgo/internal/runtime.iface" @main.New(%"github.com/goplus/llgo/internal/runtime.String" %5)
call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %6) call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %6)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%7 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %6, 0 %7 = call ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface" %6)
%8 = getelementptr ptr, ptr %7, i64 3 %8 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %6, 0
%9 = load ptr, ptr %8, align 8 %9 = getelementptr ptr, ptr %8, i64 3
%10 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %6, 1 %10 = load ptr, ptr %9, align 8
%11 = alloca { ptr, ptr }, align 8 %11 = alloca { ptr, ptr }, align 8
%12 = getelementptr inbounds { ptr, ptr }, ptr %11, i32 0, i32 0 %12 = getelementptr inbounds { ptr, ptr }, ptr %11, i32 0, i32 0
store ptr %9, ptr %12, align 8 store ptr %10, ptr %12, align 8
%13 = getelementptr inbounds { ptr, ptr }, ptr %11, i32 0, i32 1 %13 = getelementptr inbounds { ptr, ptr }, ptr %11, i32 0, i32 1
store ptr %10, ptr %13, align 8 store ptr %7, ptr %13, align 8
%14 = load { ptr, ptr }, ptr %11, align 8 %14 = load { ptr, ptr }, ptr %11, align 8
%15 = extractvalue { ptr, ptr } %14, 1 %15 = extractvalue { ptr, ptr } %14, 1
%16 = extractvalue { ptr, ptr } %14, 0 %16 = extractvalue { ptr, ptr } %14, 0
@@ -102,7 +102,7 @@ _llgo_0:
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 25, i64 0, i64 1) %0 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 25, i64 0, i64 1)
store ptr %0, ptr @_llgo_main.errorString, align 8 store ptr %0, ptr @_llgo_main.errorString, align 8
@@ -300,4 +300,6 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface")
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")

View File

@@ -0,0 +1,12 @@
package main
func main() {
done := false
go func(s string) {
println(s)
done = true
}("Hello, goroutine")
for !done {
print(".")
}
}

111
cl/_testgo/goroutine/out.ll Normal file
View File

@@ -0,0 +1,111 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [17 x i8] c"Hello, goroutine\00", align 1
@1 = private unnamed_addr constant [2 x i8] c".\00", align 1
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 1)
store i1 false, ptr %2, align 1
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%4 = getelementptr inbounds { ptr }, ptr %3, i32 0, i32 0
store ptr %2, ptr %4, align 8
%5 = alloca { ptr, ptr }, align 8
%6 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 0
store ptr @"main.main$1", ptr %6, align 8
%7 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 1
store ptr %3, ptr %7, align 8
%8 = load { ptr, ptr }, ptr %5, align 8
%9 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %9, i32 0, i32 0
store ptr @0, ptr %10, align 8
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %9, i32 0, i32 1
store i64 16, ptr %11, align 4
%12 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %9, align 8
%13 = call ptr @malloc(i64 32)
%14 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %13, i32 0, i32 0
store { ptr, ptr } %8, ptr %14, align 8
%15 = getelementptr inbounds { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %13, i32 0, i32 1
store %"github.com/goplus/llgo/internal/runtime.String" %12, ptr %15, align 8
%16 = alloca i8, i64 8, align 1
%17 = call i32 @pthread_create(ptr %16, ptr null, ptr @"main._llgo_routine$1", ptr %13)
br label %_llgo_3
_llgo_1: ; preds = %_llgo_3
%18 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 0
store ptr @1, ptr %19, align 8
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %18, i32 0, i32 1
store i64 1, ptr %20, align 4
%21 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %18, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %21)
br label %_llgo_3
_llgo_2: ; preds = %_llgo_3
ret i32 0
_llgo_3: ; preds = %_llgo_1, %_llgo_0
%22 = load i1, ptr %2, align 1
br i1 %22, label %_llgo_2, label %_llgo_1
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define void @"main.main$1"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %1)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%2 = load { ptr }, ptr %0, align 8
%3 = extractvalue { ptr } %2, 0
store i1 true, ptr %3, align 1
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
declare ptr @malloc(i64)
define ptr @"main._llgo_routine$1"(ptr %0) {
_llgo_0:
%1 = load { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" }, ptr %0, align 8
%2 = extractvalue { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" } %1, 0
%3 = extractvalue { { ptr, ptr }, %"github.com/goplus/llgo/internal/runtime.String" } %1, 1
%4 = extractvalue { ptr, ptr } %2, 1
%5 = extractvalue { ptr, ptr } %2, 0
call void %5(ptr %4, %"github.com/goplus/llgo/internal/runtime.String" %3)
call void @free(ptr %0)
ret ptr null
}
declare void @free(ptr)
declare i32 @pthread_create(ptr, ptr, ptr, ptr)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)

67
cl/_testgo/invoke/in.go Normal file
View File

@@ -0,0 +1,67 @@
package main
type T struct {
s string
}
func (t T) Invoke() int {
println("invoke", t.s)
return 0
}
func (t *T) Method() {}
type T1 int
func (t T1) Invoke() int {
println("invoke1", t)
return 1
}
type T2 float64
func (t T2) Invoke() int {
println("invoke2", t)
return 2
}
type T3 int8
func (t *T3) Invoke() int {
println("invoke3", *t)
return 3
}
type I interface {
Invoke() int
}
func main() {
var t = T{"hello"}
var t1 = T1(100)
var t2 = T2(100.1)
var t3 = T3(127)
invoke(t)
invoke(&t)
invoke(t1)
invoke(&t1)
invoke(t2)
invoke(&t2)
invoke(&t3)
var m M
var i I = m
println(i, m)
m = &t
invoke(m)
// panic
invoke(nil)
}
func invoke(i I) {
println(i.Invoke())
}
type M interface {
Invoke() int
Method()
}

973
cl/_testgo/invoke/out.ll Normal file
View File

@@ -0,0 +1,973 @@
; ModuleID = 'main'
source_filename = "main"
%main.T = type { %"github.com/goplus/llgo/internal/runtime.String" }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/abi.Method" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, ptr, ptr }
%"github.com/goplus/llgo/internal/abi.Imethod" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr }
@"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"invoke\00", align 1
@1 = private unnamed_addr constant [8 x i8] c"invoke1\00", align 1
@2 = private unnamed_addr constant [8 x i8] c"invoke2\00", align 1
@3 = private unnamed_addr constant [8 x i8] c"invoke3\00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@4 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@_llgo_main.T = linkonce global ptr null
@"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ" = global ptr null
@_llgo_string = linkonce global ptr null
@5 = private unnamed_addr constant [2 x i8] c"s\00", align 1
@6 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@7 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@8 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA" = linkonce global ptr null
@_llgo_int = linkonce global ptr null
@9 = private unnamed_addr constant [7 x i8] c"Method\00", align 1
@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null
@10 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@11 = private unnamed_addr constant [7 x i8] c"main.T\00", align 1
@"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0" = linkonce global ptr null
@12 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@13 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@14 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@"*_llgo_main.T" = linkonce global ptr null
@_llgo_main.T1 = linkonce global ptr null
@15 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@16 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@17 = private unnamed_addr constant [8 x i8] c"main.T1\00", align 1
@"*_llgo_main.T1" = linkonce global ptr null
@_llgo_main.T2 = linkonce global ptr null
@_llgo_float64 = linkonce global ptr null
@18 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@19 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@20 = private unnamed_addr constant [8 x i8] c"main.T2\00", align 1
@"*_llgo_main.T2" = linkonce global ptr null
@"*_llgo_main.T3" = linkonce global ptr null
@_llgo_main.T3 = linkonce global ptr null
@_llgo_int8 = linkonce global ptr null
@21 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@22 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@23 = private unnamed_addr constant [8 x i8] c"main.T3\00", align 1
@"_llgo_iface$jwmSdgh1zvY_TDIgLzCkvkbiyrdwl9N806DH0JGcyMI" = linkonce global ptr null
@24 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@25 = private unnamed_addr constant [7 x i8] c"Method\00", align 1
@26 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@27 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
define i64 @main.T.Invoke(%main.T %0) {
_llgo_0:
%1 = alloca %main.T, align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 16)
store %main.T %0, ptr %2, align 8
%3 = getelementptr inbounds %main.T, ptr %2, i32 0, i32 0
%4 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %3, align 8
%5 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 0
store ptr @0, ptr %6, align 8
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1
store i64 6, ptr %7, align 4
%8 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %5, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %8)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i64 0
}
define i64 @"main.(*T).Invoke"(ptr %0) {
_llgo_0:
%1 = load %main.T, ptr %0, align 8
%2 = call i64 @main.T.Invoke(%main.T %1)
ret i64 %2
}
define void @"main.(*T).Method"(ptr %0) {
_llgo_0:
ret void
}
define i64 @main.T1.Invoke(i64 %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 0
store ptr @1, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1
store i64 7, ptr %3, align 4
%4 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %1, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %0)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i64 1
}
define i64 @"main.(*T1).Invoke"(ptr %0) {
_llgo_0:
%1 = load i64, ptr %0, align 4
%2 = call i64 @main.T1.Invoke(i64 %1)
ret i64 %2
}
define i64 @main.T2.Invoke(double %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 0
store ptr @2, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1
store i64 7, ptr %3, align 4
%4 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %1, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %0)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i64 2
}
define i64 @"main.(*T2).Invoke"(ptr %0) {
_llgo_0:
%1 = load double, ptr %0, align 8
%2 = call i64 @main.T2.Invoke(double %1)
ret i64 %2
}
define i64 @"main.(*T3).Invoke"(ptr %0) {
_llgo_0:
%1 = load i8, ptr %0, align 1
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
store ptr @3, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
store i64 7, ptr %4, align 4
%5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %5)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%6 = sext i8 %1 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %6)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i64 3
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$after"()
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface" %0)
%2 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %0, 0
%3 = getelementptr ptr, ptr %2, i64 3
%4 = load ptr, ptr %3, align 8
%5 = alloca { ptr, ptr }, align 8
%6 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 0
store ptr %4, ptr %6, align 8
%7 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 1
store ptr %1, ptr %7, align 8
%8 = load { ptr, ptr }, ptr %5, align 8
%9 = extractvalue { ptr, ptr } %8, 1
%10 = extractvalue { ptr, ptr } %8, 0
%11 = call i64 %10(ptr %9)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %11)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%3 = getelementptr inbounds %main.T, ptr %2, i32 0, i32 0
%4 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 0
store ptr @4, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
store i64 5, ptr %6, align 4
%7 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %4, align 8
store %"github.com/goplus/llgo/internal/runtime.String" %7, ptr %3, align 8
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
store i64 100, ptr %8, align 4
%9 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
store double 1.001000e+02, ptr %9, align 8
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 1)
store i8 127, ptr %10, align 1
%11 = load %main.T, ptr %2, align 8
%12 = load ptr, ptr @_llgo_main.T, align 8
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %main.T %11, ptr %13, align 8
%14 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %14, ptr %12)
%16 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %16, i32 0, i32 0
store ptr %15, ptr %17, align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %16, i32 0, i32 1
store ptr %13, ptr %18, align 8
%19 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %16, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %19)
%20 = load ptr, ptr @"*_llgo_main.T", align 8
%21 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %21, ptr %20)
%23 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %23, i32 0, i32 0
store ptr %22, ptr %24, align 8
%25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %23, i32 0, i32 1
store ptr %2, ptr %25, align 8
%26 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %23, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %26)
%27 = load i64, ptr %8, align 4
%28 = load ptr, ptr @_llgo_main.T1, align 8
%29 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %28, i32 0, i32 6
%30 = load i8, ptr %29, align 1
%31 = or i8 %30, 32
store i8 %31, ptr %29, align 1
%32 = inttoptr i64 %27 to ptr
%33 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%34 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %33, ptr %28)
%35 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, i32 0, i32 0
store ptr %34, ptr %36, align 8
%37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, i32 0, i32 1
store ptr %32, ptr %37, align 8
%38 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %35, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %38)
%39 = load ptr, ptr @"*_llgo_main.T1", align 8
%40 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %40, ptr %39)
%42 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %42, i32 0, i32 0
store ptr %41, ptr %43, align 8
%44 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %42, i32 0, i32 1
store ptr %8, ptr %44, align 8
%45 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %42, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %45)
%46 = load double, ptr %9, align 8
%47 = load ptr, ptr @_llgo_main.T2, align 8
%48 = bitcast double %46 to i64
%49 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %47, i32 0, i32 6
%50 = load i8, ptr %49, align 1
%51 = or i8 %50, 32
store i8 %51, ptr %49, align 1
%52 = inttoptr i64 %48 to ptr
%53 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %53, ptr %47)
%55 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %55, i32 0, i32 0
store ptr %54, ptr %56, align 8
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %55, i32 0, i32 1
store ptr %52, ptr %57, align 8
%58 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %55, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %58)
%59 = load ptr, ptr @"*_llgo_main.T2", align 8
%60 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%61 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %60, ptr %59)
%62 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%63 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %62, i32 0, i32 0
store ptr %61, ptr %63, align 8
%64 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %62, i32 0, i32 1
store ptr %9, ptr %64, align 8
%65 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %62, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %65)
%66 = load ptr, ptr @"*_llgo_main.T3", align 8
%67 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%68 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %67, ptr %66)
%69 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%70 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %69, i32 0, i32 0
store ptr %68, ptr %70, align 8
%71 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %69, i32 0, i32 1
store ptr %10, ptr %71, align 8
%72 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %69, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %72)
%73 = call ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
%74 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%75 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %74, ptr %73)
%76 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %76, i32 0, i32 0
store ptr %75, ptr %77, align 8
%78 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %76, i32 0, i32 1
store ptr null, ptr %78, align 8
%79 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %76, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %79)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%80 = load ptr, ptr @"*_llgo_main.T", align 8
%81 = load ptr, ptr @"_llgo_iface$jwmSdgh1zvY_TDIgLzCkvkbiyrdwl9N806DH0JGcyMI", align 8
%82 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %81, ptr %80)
%83 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%84 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %83, i32 0, i32 0
store ptr %82, ptr %84, align 8
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %83, i32 0, i32 1
store ptr %2, ptr %85, align 8
%86 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %83, align 8
%87 = call ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface" %86)
%88 = extractvalue %"github.com/goplus/llgo/internal/runtime.iface" %86, 1
%89 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%90 = call ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr %89, ptr %87)
%91 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%92 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %91, i32 0, i32 0
store ptr %90, ptr %92, align 8
%93 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %91, i32 0, i32 1
store ptr %88, ptr %93, align 8
%94 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %91, align 8
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" %94)
call void @main.invoke(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)
ret i32 0
}
declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double)
declare ptr @"github.com/goplus/llgo/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/internal/runtime.iface")
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define void @"main.init$after"() {
_llgo_0:
%0 = load ptr, ptr @_llgo_main.T, align 8
%1 = icmp eq ptr %0, null
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 25, i64 1, i64 2)
store ptr %2, ptr @_llgo_main.T, align 8
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
%3 = load ptr, ptr @_llgo_string, align 8
%4 = icmp eq ptr %3, null
br i1 %4, label %_llgo_3, label %_llgo_4
_llgo_3: ; preds = %_llgo_2
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
store ptr %5, ptr @_llgo_string, align 8
br label %_llgo_4
_llgo_4: ; preds = %_llgo_3, %_llgo_2
%6 = load ptr, ptr @_llgo_string, align 8
%7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0
store ptr @5, ptr %8, align 8
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1
store i64 1, ptr %9, align 4
%10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8
%11 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 0
store ptr @6, ptr %12, align 8
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %11, i32 0, i32 1
store i64 0, ptr %13, align 4
%14 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %11, align 8
%15 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %10, ptr %6, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %14, i1 false)
%16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0
store ptr @7, ptr %17, align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1
store i64 4, ptr %18, align 4
%19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8
%20 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 56)
%21 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %20, i64 0
store %"github.com/goplus/llgo/internal/abi.StructField" %15, ptr %21, align 8
%22 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %22, i32 0, i32 0
store ptr %20, ptr %23, align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %22, i32 0, i32 1
store i64 1, ptr %24, align 4
%25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %22, i32 0, i32 2
store i64 1, ptr %25, align 4
%26 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %22, align 8
%27 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %19, i64 16, %"github.com/goplus/llgo/internal/runtime.Slice" %26)
store ptr %27, ptr @"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ", align 8
%28 = load ptr, ptr @"main.struct$QTufDJA9wEDzuzgkA-ZSrLqW-B6lWN8O25mTSglAoLQ", align 8
br i1 %1, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4
%29 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 0
store ptr @8, ptr %30, align 8
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 1
store i64 6, ptr %31, align 4
%32 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %29, align 8
%33 = load ptr, ptr @_llgo_int, align 8
%34 = icmp eq ptr %33, null
br i1 %34, label %_llgo_7, label %_llgo_8
_llgo_6: ; preds = %_llgo_12, %_llgo_4
%35 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%36 = load ptr, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
%37 = icmp eq ptr %36, null
br i1 %37, label %_llgo_13, label %_llgo_14
_llgo_7: ; preds = %_llgo_5
%38 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
store ptr %38, ptr @_llgo_int, align 8
br label %_llgo_8
_llgo_8: ; preds = %_llgo_7, %_llgo_5
%39 = load ptr, ptr @_llgo_int, align 8
%40 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%41 = icmp eq ptr %40, null
br i1 %41, label %_llgo_9, label %_llgo_10
_llgo_9: ; preds = %_llgo_8
%42 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%43 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%44 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 0
store ptr %42, ptr %44, align 8
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 1
store i64 0, ptr %45, align 4
%46 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, i32 0, i32 2
store i64 0, ptr %46, align 4
%47 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %43, align 8
%48 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%49 = getelementptr ptr, ptr %48, i64 0
store ptr %39, ptr %49, align 8
%50 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 0
store ptr %48, ptr %51, align 8
%52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 1
store i64 1, ptr %52, align 4
%53 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, i32 0, i32 2
store i64 1, ptr %53, align 4
%54 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %50, align 8
%55 = call ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice" %47, %"github.com/goplus/llgo/internal/runtime.Slice" %54, i1 false)
store ptr %55, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
br label %_llgo_10
_llgo_10: ; preds = %_llgo_9, %_llgo_8
%56 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%57 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%58 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %57, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %32, ptr %58, align 8
%59 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %57, i32 0, i32 1
store ptr %56, ptr %59, align 8
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %57, i32 0, i32 2
store ptr @"main.(*T).Invoke", ptr %60, align 8
%61 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %57, i32 0, i32 3
store ptr @"main.(*T).Invoke", ptr %61, align 8
%62 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %57, align 8
%63 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%64 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %32, ptr %64, align 8
%65 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 1
store ptr %56, ptr %65, align 8
%66 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 2
store ptr @"main.(*T).Invoke", ptr %66, align 8
%67 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %63, i32 0, i32 3
store ptr @main.T.Invoke, ptr %67, align 8
%68 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %63, align 8
%69 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%70 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %69, i32 0, i32 0
store ptr @9, ptr %70, align 8
%71 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %69, i32 0, i32 1
store i64 6, ptr %71, align 4
%72 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %69, align 8
%73 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%74 = icmp eq ptr %73, null
br i1 %74, label %_llgo_11, label %_llgo_12
_llgo_11: ; preds = %_llgo_10
%75 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%76 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %76, i32 0, i32 0
store ptr %75, ptr %77, align 8
%78 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %76, i32 0, i32 1
store i64 0, ptr %78, align 4
%79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %76, i32 0, i32 2
store i64 0, ptr %79, align 4
%80 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %76, align 8
%81 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%82 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%83 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %82, i32 0, i32 0
store ptr %81, ptr %83, align 8
%84 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %82, i32 0, i32 1
store i64 0, ptr %84, align 4
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %82, i32 0, i32 2
store i64 0, ptr %85, align 4
%86 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %82, align 8
%87 = call ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice" %80, %"github.com/goplus/llgo/internal/runtime.Slice" %86, i1 false)
store ptr %87, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
br label %_llgo_12
_llgo_12: ; preds = %_llgo_11, %_llgo_10
%88 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%89 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %89, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %72, ptr %90, align 8
%91 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %89, i32 0, i32 1
store ptr %88, ptr %91, align 8
%92 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %89, i32 0, i32 2
store ptr @"main.(*T).Method", ptr %92, align 8
%93 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %89, i32 0, i32 3
store ptr @"main.(*T).Method", ptr %93, align 8
%94 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %89, align 8
%95 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%96 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %95, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %68, ptr %96, align 8
%97 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %97, i32 0, i32 0
store ptr %95, ptr %98, align 8
%99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %97, i32 0, i32 1
store i64 1, ptr %99, align 4
%100 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %97, i32 0, i32 2
store i64 1, ptr %100, align 4
%101 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %97, align 8
%102 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 80)
%103 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %102, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %62, ptr %103, align 8
%104 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %102, i64 1
store %"github.com/goplus/llgo/internal/abi.Method" %94, ptr %104, align 8
%105 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%106 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %105, i32 0, i32 0
store ptr %102, ptr %106, align 8
%107 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %105, i32 0, i32 1
store i64 2, ptr %107, align 4
%108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %105, i32 0, i32 2
store i64 2, ptr %108, align 4
%109 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %105, align 8
%110 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %110, i32 0, i32 0
store ptr @10, ptr %111, align 8
%112 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %110, i32 0, i32 1
store i64 4, ptr %112, align 4
%113 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %110, align 8
%114 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%115 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %114, i32 0, i32 0
store ptr @11, ptr %115, align 8
%116 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %114, i32 0, i32 1
store i64 6, ptr %116, align 4
%117 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %114, align 8
call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %2, %"github.com/goplus/llgo/internal/runtime.String" %113, %"github.com/goplus/llgo/internal/runtime.String" %117, ptr %28, %"github.com/goplus/llgo/internal/runtime.Slice" %101, %"github.com/goplus/llgo/internal/runtime.Slice" %109)
br label %_llgo_6
_llgo_13: ; preds = %_llgo_6
%118 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%119 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %118, i32 0, i32 0
store ptr @12, ptr %119, align 8
%120 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %118, i32 0, i32 1
store i64 6, ptr %120, align 4
%121 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %118, align 8
%122 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8
%123 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %122, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %121, ptr %123, align 8
%124 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %122, i32 0, i32 1
store ptr %35, ptr %124, align 8
%125 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %122, align 8
%126 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
%127 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %126, i64 0
store %"github.com/goplus/llgo/internal/abi.Imethod" %125, ptr %127, align 8
%128 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%129 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %128, i32 0, i32 0
store ptr %126, ptr %129, align 8
%130 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %128, i32 0, i32 1
store i64 1, ptr %130, align 4
%131 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %128, i32 0, i32 2
store i64 1, ptr %131, align 4
%132 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %128, align 8
%133 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %133, i32 0, i32 0
store ptr @13, ptr %134, align 8
%135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %133, i32 0, i32 1
store i64 4, ptr %135, align 4
%136 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %133, align 8
%137 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%138 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %137, i32 0, i32 0
store ptr @14, ptr %138, align 8
%139 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %137, i32 0, i32 1
store i64 0, ptr %139, align 4
%140 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %137, align 8
%141 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %136, %"github.com/goplus/llgo/internal/runtime.String" %140, %"github.com/goplus/llgo/internal/runtime.Slice" %132)
store ptr %141, ptr @"_llgo_iface$uRUteI7wmSy7y7ODhGzk0FdDaxGKMhVSSu6HZEv9aa0", align 8
br label %_llgo_14
_llgo_14: ; preds = %_llgo_13, %_llgo_6
%142 = load ptr, ptr @_llgo_main.T, align 8
%143 = load ptr, ptr @"*_llgo_main.T", align 8
%144 = icmp eq ptr %143, null
br i1 %144, label %_llgo_15, label %_llgo_16
_llgo_15: ; preds = %_llgo_14
%145 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %142)
store ptr %145, ptr @"*_llgo_main.T", align 8
br label %_llgo_16
_llgo_16: ; preds = %_llgo_15, %_llgo_14
%146 = load ptr, ptr @_llgo_main.T1, align 8
%147 = icmp eq ptr %146, null
br i1 %147, label %_llgo_17, label %_llgo_18
_llgo_17: ; preds = %_llgo_16
%148 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 2, i64 1, i64 1)
store ptr %148, ptr @_llgo_main.T1, align 8
br label %_llgo_18
_llgo_18: ; preds = %_llgo_17, %_llgo_16
%149 = load ptr, ptr @_llgo_int, align 8
br i1 %147, label %_llgo_19, label %_llgo_20
_llgo_19: ; preds = %_llgo_18
%150 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%151 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %150, i32 0, i32 0
store ptr @15, ptr %151, align 8
%152 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %150, i32 0, i32 1
store i64 6, ptr %152, align 4
%153 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %150, align 8
%154 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%155 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%156 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %155, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %153, ptr %156, align 8
%157 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %155, i32 0, i32 1
store ptr %154, ptr %157, align 8
%158 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %155, i32 0, i32 2
store ptr @"main.(*T1).Invoke", ptr %158, align 8
%159 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %155, i32 0, i32 3
store ptr @"main.(*T1).Invoke", ptr %159, align 8
%160 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %155, align 8
%161 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%162 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %161, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %153, ptr %162, align 8
%163 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %161, i32 0, i32 1
store ptr %154, ptr %163, align 8
%164 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %161, i32 0, i32 2
store ptr @"main.(*T1).Invoke", ptr %164, align 8
%165 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %161, i32 0, i32 3
store ptr @main.T1.Invoke, ptr %165, align 8
%166 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %161, align 8
%167 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%168 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %167, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %166, ptr %168, align 8
%169 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%170 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %169, i32 0, i32 0
store ptr %167, ptr %170, align 8
%171 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %169, i32 0, i32 1
store i64 1, ptr %171, align 4
%172 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %169, i32 0, i32 2
store i64 1, ptr %172, align 4
%173 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %169, align 8
%174 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%175 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %174, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %160, ptr %175, align 8
%176 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%177 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %176, i32 0, i32 0
store ptr %174, ptr %177, align 8
%178 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %176, i32 0, i32 1
store i64 1, ptr %178, align 4
%179 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %176, i32 0, i32 2
store i64 1, ptr %179, align 4
%180 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %176, align 8
%181 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%182 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %181, i32 0, i32 0
store ptr @16, ptr %182, align 8
%183 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %181, i32 0, i32 1
store i64 4, ptr %183, align 4
%184 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %181, align 8
%185 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%186 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %185, i32 0, i32 0
store ptr @17, ptr %186, align 8
%187 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %185, i32 0, i32 1
store i64 7, ptr %187, align 4
%188 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %185, align 8
call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %148, %"github.com/goplus/llgo/internal/runtime.String" %184, %"github.com/goplus/llgo/internal/runtime.String" %188, ptr %149, %"github.com/goplus/llgo/internal/runtime.Slice" %173, %"github.com/goplus/llgo/internal/runtime.Slice" %180)
br label %_llgo_20
_llgo_20: ; preds = %_llgo_19, %_llgo_18
%189 = load ptr, ptr @_llgo_main.T1, align 8
%190 = load ptr, ptr @"*_llgo_main.T1", align 8
%191 = icmp eq ptr %190, null
br i1 %191, label %_llgo_21, label %_llgo_22
_llgo_21: ; preds = %_llgo_20
%192 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %189)
store ptr %192, ptr @"*_llgo_main.T1", align 8
br label %_llgo_22
_llgo_22: ; preds = %_llgo_21, %_llgo_20
%193 = load ptr, ptr @_llgo_main.T2, align 8
%194 = icmp eq ptr %193, null
br i1 %194, label %_llgo_23, label %_llgo_24
_llgo_23: ; preds = %_llgo_22
%195 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 14, i64 1, i64 1)
store ptr %195, ptr @_llgo_main.T2, align 8
br label %_llgo_24
_llgo_24: ; preds = %_llgo_23, %_llgo_22
%196 = load ptr, ptr @_llgo_float64, align 8
%197 = icmp eq ptr %196, null
br i1 %197, label %_llgo_25, label %_llgo_26
_llgo_25: ; preds = %_llgo_24
%198 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
store ptr %198, ptr @_llgo_float64, align 8
br label %_llgo_26
_llgo_26: ; preds = %_llgo_25, %_llgo_24
%199 = load ptr, ptr @_llgo_float64, align 8
br i1 %194, label %_llgo_27, label %_llgo_28
_llgo_27: ; preds = %_llgo_26
%200 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%201 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %200, i32 0, i32 0
store ptr @18, ptr %201, align 8
%202 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %200, i32 0, i32 1
store i64 6, ptr %202, align 4
%203 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %200, align 8
%204 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%205 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%206 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %205, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %203, ptr %206, align 8
%207 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %205, i32 0, i32 1
store ptr %204, ptr %207, align 8
%208 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %205, i32 0, i32 2
store ptr @"main.(*T2).Invoke", ptr %208, align 8
%209 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %205, i32 0, i32 3
store ptr @"main.(*T2).Invoke", ptr %209, align 8
%210 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %205, align 8
%211 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%212 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %211, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %203, ptr %212, align 8
%213 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %211, i32 0, i32 1
store ptr %204, ptr %213, align 8
%214 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %211, i32 0, i32 2
store ptr @"main.(*T2).Invoke", ptr %214, align 8
%215 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %211, i32 0, i32 3
store ptr @main.T2.Invoke, ptr %215, align 8
%216 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %211, align 8
%217 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%218 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %217, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %216, ptr %218, align 8
%219 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%220 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %219, i32 0, i32 0
store ptr %217, ptr %220, align 8
%221 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %219, i32 0, i32 1
store i64 1, ptr %221, align 4
%222 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %219, i32 0, i32 2
store i64 1, ptr %222, align 4
%223 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %219, align 8
%224 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%225 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %224, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %210, ptr %225, align 8
%226 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%227 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %226, i32 0, i32 0
store ptr %224, ptr %227, align 8
%228 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %226, i32 0, i32 1
store i64 1, ptr %228, align 4
%229 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %226, i32 0, i32 2
store i64 1, ptr %229, align 4
%230 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %226, align 8
%231 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%232 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 0
store ptr @19, ptr %232, align 8
%233 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 1
store i64 4, ptr %233, align 4
%234 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %231, align 8
%235 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%236 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 0
store ptr @20, ptr %236, align 8
%237 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 1
store i64 7, ptr %237, align 4
%238 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %235, align 8
call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %195, %"github.com/goplus/llgo/internal/runtime.String" %234, %"github.com/goplus/llgo/internal/runtime.String" %238, ptr %199, %"github.com/goplus/llgo/internal/runtime.Slice" %223, %"github.com/goplus/llgo/internal/runtime.Slice" %230)
br label %_llgo_28
_llgo_28: ; preds = %_llgo_27, %_llgo_26
%239 = load ptr, ptr @_llgo_main.T2, align 8
%240 = load ptr, ptr @"*_llgo_main.T2", align 8
%241 = icmp eq ptr %240, null
br i1 %241, label %_llgo_29, label %_llgo_30
_llgo_29: ; preds = %_llgo_28
%242 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %239)
store ptr %242, ptr @"*_llgo_main.T2", align 8
br label %_llgo_30
_llgo_30: ; preds = %_llgo_29, %_llgo_28
%243 = load ptr, ptr @_llgo_main.T3, align 8
%244 = icmp eq ptr %243, null
br i1 %244, label %_llgo_31, label %_llgo_32
_llgo_31: ; preds = %_llgo_30
%245 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 3, i64 0, i64 1)
store ptr %245, ptr @_llgo_main.T3, align 8
br label %_llgo_32
_llgo_32: ; preds = %_llgo_31, %_llgo_30
%246 = load ptr, ptr @_llgo_int8, align 8
%247 = icmp eq ptr %246, null
br i1 %247, label %_llgo_33, label %_llgo_34
_llgo_33: ; preds = %_llgo_32
%248 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
store ptr %248, ptr @_llgo_int8, align 8
br label %_llgo_34
_llgo_34: ; preds = %_llgo_33, %_llgo_32
%249 = load ptr, ptr @_llgo_int8, align 8
br i1 %244, label %_llgo_35, label %_llgo_36
_llgo_35: ; preds = %_llgo_34
%250 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%251 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 0
store ptr @21, ptr %251, align 8
%252 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 1
store i64 6, ptr %252, align 4
%253 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %250, align 8
%254 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%255 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%256 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %255, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %253, ptr %256, align 8
%257 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %255, i32 0, i32 1
store ptr %254, ptr %257, align 8
%258 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %255, i32 0, i32 2
store ptr @"main.(*T3).Invoke", ptr %258, align 8
%259 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %255, i32 0, i32 3
store ptr @"main.(*T3).Invoke", ptr %259, align 8
%260 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %255, align 8
%261 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%262 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %261, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %260, ptr %262, align 8
%263 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%264 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %263, i32 0, i32 0
store ptr %261, ptr %264, align 8
%265 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %263, i32 0, i32 1
store i64 1, ptr %265, align 4
%266 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %263, i32 0, i32 2
store i64 1, ptr %266, align 4
%267 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %263, align 8
%268 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%269 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %268, i32 0, i32 0
store ptr @22, ptr %269, align 8
%270 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %268, i32 0, i32 1
store i64 4, ptr %270, align 4
%271 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %268, align 8
%272 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%273 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %272, i32 0, i32 0
store ptr @23, ptr %273, align 8
%274 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %272, i32 0, i32 1
store i64 7, ptr %274, align 4
%275 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %272, align 8
call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %245, %"github.com/goplus/llgo/internal/runtime.String" %271, %"github.com/goplus/llgo/internal/runtime.String" %275, ptr %249, { ptr, i64, i64 } zeroinitializer, %"github.com/goplus/llgo/internal/runtime.Slice" %267)
br label %_llgo_36
_llgo_36: ; preds = %_llgo_35, %_llgo_34
%276 = load ptr, ptr @_llgo_main.T3, align 8
%277 = load ptr, ptr @"*_llgo_main.T3", align 8
%278 = icmp eq ptr %277, null
br i1 %278, label %_llgo_37, label %_llgo_38
_llgo_37: ; preds = %_llgo_36
%279 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %276)
store ptr %279, ptr @"*_llgo_main.T3", align 8
br label %_llgo_38
_llgo_38: ; preds = %_llgo_37, %_llgo_36
%280 = load ptr, ptr @"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA", align 8
%281 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%282 = load ptr, ptr @"_llgo_iface$jwmSdgh1zvY_TDIgLzCkvkbiyrdwl9N806DH0JGcyMI", align 8
%283 = icmp eq ptr %282, null
br i1 %283, label %_llgo_39, label %_llgo_40
_llgo_39: ; preds = %_llgo_38
%284 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%285 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %284, i32 0, i32 0
store ptr @24, ptr %285, align 8
%286 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %284, i32 0, i32 1
store i64 6, ptr %286, align 4
%287 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %284, align 8
%288 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8
%289 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %288, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %287, ptr %289, align 8
%290 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %288, i32 0, i32 1
store ptr %280, ptr %290, align 8
%291 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %288, align 8
%292 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%293 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %292, i32 0, i32 0
store ptr @25, ptr %293, align 8
%294 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %292, i32 0, i32 1
store i64 6, ptr %294, align 4
%295 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %292, align 8
%296 = alloca %"github.com/goplus/llgo/internal/abi.Imethod", align 8
%297 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %296, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %295, ptr %297, align 8
%298 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Imethod", ptr %296, i32 0, i32 1
store ptr %281, ptr %298, align 8
%299 = load %"github.com/goplus/llgo/internal/abi.Imethod", ptr %296, align 8
%300 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 48)
%301 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %300, i64 0
store %"github.com/goplus/llgo/internal/abi.Imethod" %291, ptr %301, align 8
%302 = getelementptr %"github.com/goplus/llgo/internal/abi.Imethod", ptr %300, i64 1
store %"github.com/goplus/llgo/internal/abi.Imethod" %299, ptr %302, align 8
%303 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%304 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %303, i32 0, i32 0
store ptr %300, ptr %304, align 8
%305 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %303, i32 0, i32 1
store i64 2, ptr %305, align 4
%306 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %303, i32 0, i32 2
store i64 2, ptr %306, align 4
%307 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %303, align 8
%308 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%309 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %308, i32 0, i32 0
store ptr @26, ptr %309, align 8
%310 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %308, i32 0, i32 1
store i64 4, ptr %310, align 4
%311 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %308, align 8
%312 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%313 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %312, i32 0, i32 0
store ptr @27, ptr %313, align 8
%314 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %312, i32 0, i32 1
store i64 0, ptr %314, align 4
%315 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %312, align 8
%316 = call ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String" %311, %"github.com/goplus/llgo/internal/runtime.String" %315, %"github.com/goplus/llgo/internal/runtime.Slice" %307)
store ptr %316, ptr @"_llgo_iface$jwmSdgh1zvY_TDIgLzCkvkbiyrdwl9N806DH0JGcyMI", align 8
br label %_llgo_40
_llgo_40: ; preds = %_llgo_39, %_llgo_38
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64, i64, i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String", i64, %"github.com/goplus/llgo/internal/runtime.Slice")
declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1)
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr, %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", ptr, %"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice", i1)
declare ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr, ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface")
declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface")

5
cl/_testgo/print/in.go Normal file
View File

@@ -0,0 +1,5 @@
package main
func main() {
println('.', byte('.'))
}

40
cl/_testgo/print/out.ll Normal file
View File

@@ -0,0 +1,40 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 46)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 46)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i32 0
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)

View File

@@ -2,6 +2,7 @@
source_filename = "main" source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 } %"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
@@ -14,11 +15,11 @@ source_filename = "main"
@2 = private unnamed_addr constant [5 x i8] c"main\00", align 1 @2 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@3 = private unnamed_addr constant [12 x i8] c"Foo: not ok\00", align 1
@"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk" = linkonce global ptr null @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk" = linkonce global ptr null
@3 = private unnamed_addr constant [2 x i8] c"V\00", align 1 @4 = private unnamed_addr constant [2 x i8] c"V\00", align 1
@4 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 @5 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@5 = private unnamed_addr constant [5 x i8] c"main\00", align 1 @6 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@6 = private unnamed_addr constant [12 x i8] c"Foo: not ok\00", align 1
@7 = private unnamed_addr constant [12 x i8] c"Bar: not ok\00", align 1 @7 = private unnamed_addr constant [12 x i8] c"Bar: not ok\00", align 1
@8 = private unnamed_addr constant [10 x i8] c"F: not ok\00", align 1 @8 = private unnamed_addr constant [10 x i8] c"F: not ok\00", align 1
@@ -31,14 +32,18 @@ _llgo_0:
%3 = load { i64 }, ptr %1, align 4 %3 = load { i64 }, ptr %1, align 4
%4 = load ptr, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8 %4 = load ptr, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8
%5 = extractvalue { i64 } %3, 0 %5 = extractvalue { i64 } %3, 0
%6 = inttoptr i64 %5 to ptr %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %4, i32 0, i32 6
%7 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %7 = load i8, ptr %6, align 1
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, i32 0, i32 0 %8 = or i8 %7, 32
store ptr %4, ptr %8, align 8 store i8 %8, ptr %6, align 1
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, i32 0, i32 1 %9 = inttoptr i64 %5 to ptr
store ptr %6, ptr %9, align 8 %10 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%10 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %7, align 8 %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 0
ret %"github.com/goplus/llgo/internal/runtime.eface" %10 store ptr %4, ptr %11, align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1
store ptr %9, ptr %12, align 8
%13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8
ret %"github.com/goplus/llgo/internal/runtime.eface" %13
} }
define void @main.init() { define void @main.init() {
@@ -49,7 +54,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"github.com/goplus/llgo/cl/internal/foo.init"() call void @"github.com/goplus/llgo/cl/internal/foo.init"()
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -89,7 +94,7 @@ _llgo_2: ; preds = %_llgo_3, %_llgo_1
_llgo_3: ; preds = %_llgo_12 _llgo_3: ; preds = %_llgo_12
%16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %16 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0 %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0
store ptr @6, ptr %17, align 8 store ptr @3, ptr %17, align 8
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1 %18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1
store i64 11, ptr %18, align 4 store i64 11, ptr %18, align 4
%19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8 %19 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8
@@ -241,7 +246,7 @@ _llgo_18: ; preds = %_llgo_17, %_llgo_16
declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64) declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64)
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_int, align 8 %0 = load ptr, ptr @_llgo_int, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null
@@ -294,20 +299,20 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
_llgo_3: ; preds = %_llgo_2 _llgo_3: ; preds = %_llgo_2
%28 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %28 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 0 %29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 0
store ptr @3, ptr %29, align 8 store ptr @4, ptr %29, align 8
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 1 %30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %28, i32 0, i32 1
store i64 1, ptr %30, align 4 store i64 1, ptr %30, align 4
%31 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %28, align 8 %31 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %28, align 8
%32 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %32 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%33 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %32, i32 0, i32 0 %33 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %32, i32 0, i32 0
store ptr @4, ptr %33, align 8 store ptr @5, ptr %33, align 8
%34 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %32, i32 0, i32 1 %34 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %32, i32 0, i32 1
store i64 0, ptr %34, align 4 store i64 0, ptr %34, align 4
%35 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %32, align 8 %35 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %32, align 8
%36 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %31, ptr %25, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %35, i1 false) %36 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %31, ptr %25, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %35, i1 false)
%37 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %37 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%38 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %37, i32 0, i32 0 %38 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %37, i32 0, i32 0
store ptr @5, ptr %38, align 8 store ptr @6, ptr %38, align 8
%39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %37, i32 0, i32 1 %39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %37, i32 0, i32 1
store i64 4, ptr %39, align 4 store i64 4, ptr %39, align 4
%40 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %37, align 8 %40 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %37, align 8
@@ -346,8 +351,8 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.Bar"()
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.Bar"()
declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.F"() declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.F"()

View File

@@ -117,7 +117,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"github.com/goplus/llgo/cl/internal/foo.init"() call void @"github.com/goplus/llgo/cl/internal/foo.init"()
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -185,7 +185,7 @@ _llgo_0:
ret i32 0 ret i32 0
} }
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Foo", align 8 %0 = load ptr, ptr @"_llgo_github.com/goplus/llgo/cl/internal/foo.Foo", align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

View File

@@ -3,6 +3,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@"*_llgo_int8" = linkonce global ptr null @"*_llgo_int8" = linkonce global ptr null
@@ -68,7 +69,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -90,18 +91,22 @@ _llgo_0:
%6 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, align 8 %6 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, align 8
%7 = call ptr @main.hi(%"github.com/goplus/llgo/internal/runtime.eface" %6) %7 = call ptr @main.hi(%"github.com/goplus/llgo/internal/runtime.eface" %6)
%8 = load ptr, ptr @_llgo_int, align 8 %8 = load ptr, ptr @_llgo_int, align 8
%9 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %8, i32 0, i32 6
%10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 0 %10 = load i8, ptr %9, align 1
store ptr %8, ptr %10, align 8 %11 = or i8 %10, 32
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 1 store i8 %11, ptr %9, align 1
store ptr inttoptr (i64 100 to ptr), ptr %11, align 8 %12 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%12 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, align 8 %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 0
%13 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.eface" %12) store ptr %8, ptr %13, align 8
%14 = call i32 (ptr, ...) @printf(ptr @2, ptr %7, i64 %13) %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, i32 0, i32 1
store ptr inttoptr (i64 100 to ptr), ptr %14, align 8
%15 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %12, align 8
%16 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.eface" %15)
%17 = call i32 (ptr, ...) @printf(ptr @2, ptr %7, i64 %16)
ret i32 0 ret i32 0
} }
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_int8, align 8 %0 = load ptr, ptr @_llgo_int8, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

View File

@@ -3,6 +3,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
@main.a = global ptr null @main.a = global ptr null
@@ -86,7 +87,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
store i64 9223372036854775807, ptr @main.a, align 4 store i64 9223372036854775807, ptr @main.a, align 4
store i64 -9223372036854775808, ptr @main.b, align 4 store i64 -9223372036854775808, ptr @main.b, align 4
store i64 -1, ptr @main.n, align 4 store i64 -1, ptr @main.n, align 4
@@ -326,15 +327,19 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%123 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) %123 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%124 = load ptr, ptr @_llgo_int, align 8 %124 = load ptr, ptr @_llgo_int, align 8
%125 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %125 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %124, i32 0, i32 6
%126 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 0 %126 = load i8, ptr %125, align 1
store ptr %124, ptr %126, align 8 %127 = or i8 %126, 32
%127 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, i32 0, i32 1 store i8 %127, ptr %125, align 1
store ptr inttoptr (i64 100 to ptr), ptr %127, align 8 %128 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%128 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %125, align 8 %129 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %128, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.eface" %128, ptr %123, align 8 store ptr %124, ptr %129, align 8
%129 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %123, align 8 %130 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %128, i32 0, i32 1
%130 = ptrtoint ptr %123 to i64 store ptr inttoptr (i64 100 to ptr), ptr %130, align 8
%131 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %128, align 8
store %"github.com/goplus/llgo/internal/runtime.eface" %131, ptr %123, align 8
%132 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %123, align 8
%133 = ptrtoint ptr %123 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 true) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 true)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 0) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 0)
@@ -351,276 +356,276 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double 1.005000e+02) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double 1.005000e+02)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintEface"(%"github.com/goplus/llgo/internal/runtime.eface" %129) call void @"github.com/goplus/llgo/internal/runtime.PrintEface"(%"github.com/goplus/llgo/internal/runtime.eface" %132)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %123) call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %123)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %130) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %133)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%131 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3) %134 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3)
%132 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) %135 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
%133 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 %136 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 0 %137 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %136, i32 0, i32 0
store ptr %131, ptr %134, align 8 store ptr %134, ptr %137, align 8
%135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 1 %138 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %136, i32 0, i32 1
store i64 3, ptr %135, align 4 store i64 3, ptr %138, align 4
%136 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 2 %139 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %136, i32 0, i32 2
store i64 3, ptr %136, align 4 store i64 3, ptr %139, align 4
%137 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, align 8 %140 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %136, align 8
%138 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %122, 0 %141 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %122, 0
%139 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %122, 1 %142 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %122, 1
%140 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCopy"(%"github.com/goplus/llgo/internal/runtime.Slice" %137, ptr %138, i64 %139, i64 1) %143 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCopy"(%"github.com/goplus/llgo/internal/runtime.Slice" %140, ptr %141, i64 %142, i64 1)
store i64 %140, ptr %132, align 4 store i64 %143, ptr %135, align 4
%141 = load i64, ptr %132, align 4 %144 = load i64, ptr %135, align 4
%142 = getelementptr inbounds i8, ptr %131, i64 0 %145 = getelementptr inbounds i8, ptr %134, i64 0
%143 = load i8, ptr %142, align 1 %146 = load i8, ptr %145, align 1
%144 = getelementptr inbounds i8, ptr %131, i64 1 %147 = getelementptr inbounds i8, ptr %134, i64 1
%145 = load i8, ptr %144, align 1 %148 = load i8, ptr %147, align 1
%146 = getelementptr inbounds i8, ptr %131, i64 2 %149 = getelementptr inbounds i8, ptr %134, i64 2
%147 = load i8, ptr %146, align 1 %150 = load i8, ptr %149, align 1
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %141) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %144)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%148 = zext i8 %143 to i64 %151 = zext i8 %146 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %148) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %151)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%149 = zext i8 %145 to i64 %152 = zext i8 %148 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %149) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %152)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%150 = zext i8 %147 to i64 %153 = zext i8 %150 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %150) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %153)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%151 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %131, i64 1, i64 3, i64 1, i64 3, i64 3) %154 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %134, i64 1, i64 3, i64 1, i64 3, i64 3)
%152 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %155 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%153 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %152, i32 0, i32 0 %156 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %155, i32 0, i32 0
store ptr @5, ptr %153, align 8 store ptr @5, ptr %156, align 8
%154 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %152, i32 0, i32 1 %157 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %155, i32 0, i32 1
store i64 4, ptr %154, align 4 store i64 4, ptr %157, align 4
%155 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %152, align 8 %158 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %155, align 8
%156 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %155, 0 %159 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %158, 0
%157 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %155, 1 %160 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %158, 1
%158 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCopy"(%"github.com/goplus/llgo/internal/runtime.Slice" %151, ptr %156, i64 %157, i64 1) %161 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCopy"(%"github.com/goplus/llgo/internal/runtime.Slice" %154, ptr %159, i64 %160, i64 1)
store i64 %158, ptr %132, align 4 store i64 %161, ptr %135, align 4
%159 = load i64, ptr %132, align 4 %162 = load i64, ptr %135, align 4
%160 = getelementptr inbounds i8, ptr %131, i64 0 %163 = getelementptr inbounds i8, ptr %134, i64 0
%161 = load i8, ptr %160, align 1 %164 = load i8, ptr %163, align 1
%162 = getelementptr inbounds i8, ptr %131, i64 1 %165 = getelementptr inbounds i8, ptr %134, i64 1
%163 = load i8, ptr %162, align 1 %166 = load i8, ptr %165, align 1
%164 = getelementptr inbounds i8, ptr %131, i64 2 %167 = getelementptr inbounds i8, ptr %134, i64 2
%165 = load i8, ptr %164, align 1 %168 = load i8, ptr %167, align 1
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %159) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %162)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%166 = zext i8 %161 to i64 %169 = zext i8 %164 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %166) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %169)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%167 = zext i8 %163 to i64 %170 = zext i8 %166 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %167) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %170)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%168 = zext i8 %165 to i64 %171 = zext i8 %168 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %168) call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %171)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%169 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %172 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%170 = getelementptr inbounds { ptr }, ptr %169, i32 0, i32 0 %173 = getelementptr inbounds { ptr }, ptr %172, i32 0, i32 0
store ptr %132, ptr %170, align 8 store ptr %135, ptr %173, align 8
%171 = alloca { ptr, ptr }, align 8 %174 = alloca { ptr, ptr }, align 8
%172 = getelementptr inbounds { ptr, ptr }, ptr %171, i32 0, i32 0 %175 = getelementptr inbounds { ptr, ptr }, ptr %174, i32 0, i32 0
store ptr @"main.main$2", ptr %172, align 8 store ptr @"main.main$2", ptr %175, align 8
%173 = getelementptr inbounds { ptr, ptr }, ptr %171, i32 0, i32 1 %176 = getelementptr inbounds { ptr, ptr }, ptr %174, i32 0, i32 1
store ptr %169, ptr %173, align 8 store ptr %172, ptr %176, align 8
%174 = load { ptr, ptr }, ptr %171, align 8 %177 = load { ptr, ptr }, ptr %174, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @main.demo) call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @main.demo)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @main.demo) call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @main.demo)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @"main.main$1") call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr @"main.main$1")
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%175 = extractvalue { ptr, ptr } %174, 0 %178 = extractvalue { ptr, ptr } %177, 0
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %175) call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %178)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%176 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %179 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%177 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %176, i32 0, i32 0 %180 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %179, i32 0, i32 0
store ptr @6, ptr %177, align 8 store ptr @6, ptr %180, align 8
%178 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %176, i32 0, i32 1 %181 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %179, i32 0, i32 1
store i64 7, ptr %178, align 4 store i64 7, ptr %181, align 4
%179 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %176, align 8 %182 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %179, align 8
%180 = call ptr @"github.com/goplus/llgo/internal/runtime.NewStringIter"(%"github.com/goplus/llgo/internal/runtime.String" %179) %183 = call ptr @"github.com/goplus/llgo/internal/runtime.NewStringIter"(%"github.com/goplus/llgo/internal/runtime.String" %182)
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
%181 = call { i1, i64, i32 } @"github.com/goplus/llgo/internal/runtime.StringIterNext"(ptr %180) %184 = call { i1, i64, i32 } @"github.com/goplus/llgo/internal/runtime.StringIterNext"(ptr %183)
%182 = extractvalue { i1, i64, i32 } %181, 0 %185 = extractvalue { i1, i64, i32 } %184, 0
br i1 %182, label %_llgo_2, label %_llgo_3 br i1 %185, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%183 = extractvalue { i1, i64, i32 } %181, 1 %186 = extractvalue { i1, i64, i32 } %184, 1
%184 = extractvalue { i1, i64, i32 } %181, 2 %187 = extractvalue { i1, i64, i32 } %184, 2
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %183) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %186)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%185 = sext i32 %184 to i64 %188 = sext i32 %187 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %185) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %188)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
%186 = call double @main.Inf(i64 1) %189 = call double @main.Inf(i64 1)
%187 = call double @main.Inf(i64 -1) %190 = call double @main.Inf(i64 -1)
%188 = call double @main.NaN() %191 = call double @main.NaN()
%189 = call double @main.NaN() %192 = call double @main.NaN()
%190 = call i1 @main.IsNaN(double %189) %193 = call i1 @main.IsNaN(double %192)
%191 = call i1 @main.IsNaN(double 1.000000e+00) %194 = call i1 @main.IsNaN(double 1.000000e+00)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %186) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %189)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %187) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %190)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %188) call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double %191)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %190) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %193)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %191) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %194)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%192 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %195 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%193 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %192, i32 0, i32 0 %196 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %195, i32 0, i32 0
store ptr @7, ptr %193, align 8 store ptr @7, ptr %196, align 8
%194 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %192, i32 0, i32 1 %197 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %195, i32 0, i32 1
store i64 7, ptr %194, align 4 store i64 7, ptr %197, align 4
%195 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %192, align 8 %198 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %195, align 8
%196 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToBytes"(%"github.com/goplus/llgo/internal/runtime.String" %195) %199 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToBytes"(%"github.com/goplus/llgo/internal/runtime.String" %198)
%197 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %200 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%198 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %197, i32 0, i32 0 %201 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %200, i32 0, i32 0
store ptr @8, ptr %198, align 8 store ptr @8, ptr %201, align 8
%199 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %197, i32 0, i32 1 %202 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %200, i32 0, i32 1
store i64 7, ptr %199, align 4 store i64 7, ptr %202, align 4
%200 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %197, align 8 %203 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %200, align 8
%201 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToRunes"(%"github.com/goplus/llgo/internal/runtime.String" %200) %204 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.StringToRunes"(%"github.com/goplus/llgo/internal/runtime.String" %203)
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %196) call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %199)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %201) call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %204)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%202 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromBytes"(%"github.com/goplus/llgo/internal/runtime.Slice" %196) %205 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromBytes"(%"github.com/goplus/llgo/internal/runtime.Slice" %199)
%203 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRunes"(%"github.com/goplus/llgo/internal/runtime.Slice" %201) %206 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRunes"(%"github.com/goplus/llgo/internal/runtime.Slice" %204)
%204 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %196, 0 %207 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %199, 0
%205 = getelementptr inbounds i8, ptr %204, i64 3 %208 = getelementptr inbounds i8, ptr %207, i64 3
%206 = load i8, ptr %205, align 1 %209 = load i8, ptr %208, align 1
%207 = sext i8 %206 to i32 %210 = sext i8 %209 to i32
%208 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %207) %211 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %210)
%209 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %201, 0 %212 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %204, 0
%210 = getelementptr inbounds i32, ptr %209, i64 0 %213 = getelementptr inbounds i32, ptr %212, i64 0
%211 = load i32, ptr %210, align 4 %214 = load i32, ptr %213, align 4
%212 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %211) %215 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringFromRune"(i32 %214)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %202) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %205)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %203) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %206)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %208) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %211)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %212) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %215)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%213 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %216 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%214 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %213, i32 0, i32 0 %217 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %216, i32 0, i32 0
store ptr @9, ptr %214, align 8 store ptr @9, ptr %217, align 8
%215 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %213, i32 0, i32 1 %218 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %216, i32 0, i32 1
store i64 3, ptr %215, align 4 store i64 3, ptr %218, align 4
%216 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %213, align 8 %219 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %216, align 8
%217 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %220 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%218 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %217, i32 0, i32 0 %221 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %220, i32 0, i32 0
store ptr @10, ptr %218, align 8 store ptr @10, ptr %221, align 8
%219 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %217, i32 0, i32 1 %222 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %220, i32 0, i32 1
store i64 3, ptr %219, align 4 store i64 3, ptr %222, align 4
%220 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %217, align 8 %223 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %220, align 8
%221 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %216, %"github.com/goplus/llgo/internal/runtime.String" %220) %224 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %219, %"github.com/goplus/llgo/internal/runtime.String" %223)
%222 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %225 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%223 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %222, i32 0, i32 0 %226 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %225, i32 0, i32 0
store ptr @11, ptr %223, align 8 store ptr @11, ptr %226, align 8
%224 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %222, i32 0, i32 1 %227 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %225, i32 0, i32 1
store i64 3, ptr %224, align 4 store i64 3, ptr %227, align 4
%225 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %222, align 8 %228 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %225, align 8
%226 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %229 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%227 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %226, i32 0, i32 0 %230 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %229, i32 0, i32 0
store ptr @12, ptr %227, align 8 store ptr @12, ptr %230, align 8
%228 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %226, i32 0, i32 1 %231 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %229, i32 0, i32 1
store i64 3, ptr %228, align 4 store i64 3, ptr %231, align 4
%229 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %226, align 8 %232 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %229, align 8
%230 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %225, %"github.com/goplus/llgo/internal/runtime.String" %229) %233 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %228, %"github.com/goplus/llgo/internal/runtime.String" %232)
%231 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %234 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%232 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 0 %235 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %234, i32 0, i32 0
store ptr @13, ptr %232, align 8 store ptr @13, ptr %235, align 8
%233 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %231, i32 0, i32 1 %236 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %234, i32 0, i32 1
store i64 3, ptr %233, align 4 store i64 3, ptr %236, align 4
%234 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %231, align 8 %237 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %234, align 8
%235 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %238 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%236 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 0 %239 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %238, i32 0, i32 0
store ptr @14, ptr %236, align 8 store ptr @14, ptr %239, align 8
%237 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %235, i32 0, i32 1 %240 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %238, i32 0, i32 1
store i64 3, ptr %237, align 4 store i64 3, ptr %240, align 4
%238 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %235, align 8 %241 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %238, align 8
%239 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %234, %"github.com/goplus/llgo/internal/runtime.String" %238) %242 = call i1 @"github.com/goplus/llgo/internal/runtime.StringEqual"(%"github.com/goplus/llgo/internal/runtime.String" %237, %"github.com/goplus/llgo/internal/runtime.String" %241)
%240 = xor i1 %239, true %243 = xor i1 %242, true
%241 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %244 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%242 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %241, i32 0, i32 0 %245 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %244, i32 0, i32 0
store ptr @15, ptr %242, align 8 store ptr @15, ptr %245, align 8
%243 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %241, i32 0, i32 1 %246 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %244, i32 0, i32 1
store i64 3, ptr %243, align 4 store i64 3, ptr %246, align 4
%244 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %241, align 8 %247 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %244, align 8
%245 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %248 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%246 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %245, i32 0, i32 0 %249 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %248, i32 0, i32 0
store ptr @16, ptr %246, align 8 store ptr @16, ptr %249, align 8
%247 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %245, i32 0, i32 1 %250 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %248, i32 0, i32 1
store i64 3, ptr %247, align 4 store i64 3, ptr %250, align 4
%248 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %245, align 8 %251 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %248, align 8
%249 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %244, %"github.com/goplus/llgo/internal/runtime.String" %248) %252 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %247, %"github.com/goplus/llgo/internal/runtime.String" %251)
%250 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %253 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%251 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 0 %254 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %253, i32 0, i32 0
store ptr @17, ptr %251, align 8 store ptr @17, ptr %254, align 8
%252 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %250, i32 0, i32 1 %255 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %253, i32 0, i32 1
store i64 3, ptr %252, align 4 store i64 3, ptr %255, align 4
%253 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %250, align 8 %256 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %253, align 8
%254 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %257 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%255 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %254, i32 0, i32 0 %258 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %257, i32 0, i32 0
store ptr @18, ptr %255, align 8 store ptr @18, ptr %258, align 8
%256 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %254, i32 0, i32 1 %259 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %257, i32 0, i32 1
store i64 3, ptr %256, align 4 store i64 3, ptr %259, align 4
%257 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %254, align 8 %260 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %257, align 8
%258 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %257, %"github.com/goplus/llgo/internal/runtime.String" %253) %261 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %260, %"github.com/goplus/llgo/internal/runtime.String" %256)
%259 = xor i1 %258, true %262 = xor i1 %261, true
%260 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %263 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%261 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %260, i32 0, i32 0 %264 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %263, i32 0, i32 0
store ptr @19, ptr %261, align 8 store ptr @19, ptr %264, align 8
%262 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %260, i32 0, i32 1 %265 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %263, i32 0, i32 1
store i64 3, ptr %262, align 4 store i64 3, ptr %265, align 4
%263 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %260, align 8 %266 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %263, align 8
%264 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %267 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%265 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %264, i32 0, i32 0 %268 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %267, i32 0, i32 0
store ptr @20, ptr %265, align 8 store ptr @20, ptr %268, align 8
%266 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %264, i32 0, i32 1 %269 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %267, i32 0, i32 1
store i64 3, ptr %266, align 4 store i64 3, ptr %269, align 4
%267 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %264, align 8 %270 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %267, align 8
%268 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %267, %"github.com/goplus/llgo/internal/runtime.String" %263) %271 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %270, %"github.com/goplus/llgo/internal/runtime.String" %266)
%269 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %272 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%270 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %269, i32 0, i32 0 %273 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %272, i32 0, i32 0
store ptr @21, ptr %270, align 8 store ptr @21, ptr %273, align 8
%271 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %269, i32 0, i32 1 %274 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %272, i32 0, i32 1
store i64 3, ptr %271, align 4 store i64 3, ptr %274, align 4
%272 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %269, align 8 %275 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %272, align 8
%273 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %276 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%274 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %273, i32 0, i32 0 %277 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %276, i32 0, i32 0
store ptr @22, ptr %274, align 8 store ptr @22, ptr %277, align 8
%275 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %273, i32 0, i32 1 %278 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %276, i32 0, i32 1
store i64 3, ptr %275, align 4 store i64 3, ptr %278, align 4
%276 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %273, align 8 %279 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %276, align 8
%277 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %272, %"github.com/goplus/llgo/internal/runtime.String" %276) %280 = call i1 @"github.com/goplus/llgo/internal/runtime.StringLess"(%"github.com/goplus/llgo/internal/runtime.String" %275, %"github.com/goplus/llgo/internal/runtime.String" %279)
%278 = xor i1 %277, true %281 = xor i1 %280, true
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %221) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %224)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %230) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %233)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %240) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %243)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %249) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %252)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %259) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %262)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %268) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %271)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %278) call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %281)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i32 0 ret i32 0
} }
@@ -643,7 +648,7 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64)
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_int, align 8 %0 = load ptr, ptr @_llgo_int, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

View File

@@ -34,10 +34,7 @@ func main() {
cvt32Fto32(0, 0) cvt32Fto32(0, 0)
cvt32Fto32(1.5, 1) cvt32Fto32(1.5, 1)
cvt32Fto32(1147483647.1, 1147483648) cvt32Fto32(1147483647.1, 1147483648)
cvt32Fto32(2147483647.1, -2147483648)
cvt32Fto32(4147483647.1, -2147483648)
cvt32Fto32(-2147483648.1, -2147483648) cvt32Fto32(-2147483648.1, -2147483648)
cvt32Fto32(-2147482648.1, -2147482624)
// MaxUint32 = 1<<32 - 1 // 4294967295 // MaxUint32 = 1<<32 - 1 // 4294967295
cvt32Fto32U(0, 0) cvt32Fto32U(0, 0)

View File

@@ -401,7 +401,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -439,10 +439,7 @@ _llgo_0:
call void @main.cvt32Fto32(float 0.000000e+00, i32 0) call void @main.cvt32Fto32(float 0.000000e+00, i32 0)
call void @main.cvt32Fto32(float 1.500000e+00, i32 1) call void @main.cvt32Fto32(float 1.500000e+00, i32 1)
call void @main.cvt32Fto32(float 0x41D1194D80000000, i32 1147483648) call void @main.cvt32Fto32(float 0x41D1194D80000000, i32 1147483648)
call void @main.cvt32Fto32(float 0x41E0000000000000, i32 -2147483648)
call void @main.cvt32Fto32(float 0x41EEE6B280000000, i32 -2147483648)
call void @main.cvt32Fto32(float 0xC1E0000000000000, i32 -2147483648) call void @main.cvt32Fto32(float 0xC1E0000000000000, i32 -2147483648)
call void @main.cvt32Fto32(float 0xC1DFFFFF00000000, i32 -2147482624)
call void @main.cvt32Fto32U(float 0.000000e+00, i32 0) call void @main.cvt32Fto32U(float 0.000000e+00, i32 0)
call void @main.cvt32Fto32U(float 1.500000e+00, i32 1) call void @main.cvt32Fto32U(float 1.500000e+00, i32 1)
call void @main.cvt32Fto32U(float 0x41F0000000000000, i32 0) call void @main.cvt32Fto32U(float 0x41F0000000000000, i32 0)
@@ -472,7 +469,7 @@ _llgo_0:
ret i32 0 ret i32 0
} }
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_string, align 8 %0 = load ptr, ptr @_llgo_string, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

View File

@@ -6,6 +6,12 @@ import (
"github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/abi"
) )
type T string
func (t *T) Invoke() {
println("invoke")
}
type eface struct { type eface struct {
_type *abi.Type _type *abi.Type
data unsafe.Pointer data unsafe.Pointer
@@ -36,6 +42,8 @@ func main() {
y int y int
z int z int
}{}) }{})
var t T
dump(t)
} }
func dump(v any) { func dump(v any) {
@@ -45,5 +53,19 @@ func dump(v any) {
func dumpTyp(t *abi.Type, sep string) { func dumpTyp(t *abi.Type, sep string) {
print(sep) print(sep)
println(t.Kind(), t.Size_, t.PtrBytes, t.Hash, t.TFlag, t.Align_) println(t.Kind(), t.Size_, t.PtrBytes, t.Hash, t.TFlag, t.Align_, t.PtrToThis_, t.Uncommon())
if t.Elem() != nil {
dumpTyp(t.Elem(), sep+"\telem: ")
}
if t.Uncommon() != nil {
dumpUncommon(t.Uncommon(), sep+"\tuncomm: ")
if t.PtrToThis_ != nil {
dumpUncommon(t.PtrToThis_.Uncommon(), sep+"\tuncomm: ")
}
}
}
func dumpUncommon(u *abi.UncommonType, sep string) {
print(sep)
println(u.PkgPath_, u.Mcount, u.Xcount)
} }

857
cl/_testrt/eface/out.ll Normal file
View File

@@ -0,0 +1,857 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.eface" = type { ptr, ptr }
%main.eface = type { ptr, ptr }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/internal/runtime.String", ptr }
%"github.com/goplus/llgo/internal/abi.UncommonType" = type { %"github.com/goplus/llgo/internal/runtime.String", i16, i16, i32 }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/abi.StructField" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1 }
%"github.com/goplus/llgo/internal/abi.Method" = type { %"github.com/goplus/llgo/internal/runtime.String", ptr, ptr, ptr }
@"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"invoke\00", align 1
@1 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@2 = private unnamed_addr constant [8 x i8] c"\09elem: \00", align 1
@3 = private unnamed_addr constant [10 x i8] c"\09uncomm: \00", align 1
@4 = private unnamed_addr constant [10 x i8] c"\09uncomm: \00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@_llgo_bool = linkonce global ptr null
@_llgo_int = linkonce global ptr null
@_llgo_int8 = linkonce global ptr null
@_llgo_int16 = linkonce global ptr null
@_llgo_int32 = linkonce global ptr null
@_llgo_int64 = linkonce global ptr null
@_llgo_uint = linkonce global ptr null
@_llgo_uint8 = linkonce global ptr null
@_llgo_uint16 = linkonce global ptr null
@_llgo_uint32 = linkonce global ptr null
@_llgo_uint64 = linkonce global ptr null
@_llgo_uintptr = linkonce global ptr null
@_llgo_float32 = linkonce global ptr null
@_llgo_float64 = linkonce global ptr null
@"[10]_llgo_int" = linkonce global ptr null
@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = linkonce global ptr null
@"*_llgo_int" = linkonce global ptr null
@"[]_llgo_int" = linkonce global ptr null
@5 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@_llgo_string = linkonce global ptr null
@"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM" = global ptr null
@6 = private unnamed_addr constant [2 x i8] c"x\00", align 1
@7 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@8 = private unnamed_addr constant [2 x i8] c"y\00", align 1
@9 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@10 = private unnamed_addr constant [2 x i8] c"z\00", align 1
@11 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@12 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@13 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@_llgo_main.T = linkonce global ptr null
@14 = private unnamed_addr constant [7 x i8] c"Invoke\00", align 1
@15 = private unnamed_addr constant [5 x i8] c"main\00", align 1
@16 = private unnamed_addr constant [7 x i8] c"main.T\00", align 1
define void @"main.(*T).Invoke"(ptr %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 0
store ptr @0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1
store i64 6, ptr %3, align 4
%4 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %1, align 8
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret void
}
define void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.eface" %0, ptr %1, align 8
%2 = getelementptr inbounds %main.eface, ptr %1, i32 0, i32 0
%3 = load ptr, ptr %2, align 8
%4 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 0
store ptr @1, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
store i64 0, ptr %6, align 4
%7 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %4, align 8
call void @main.dumpTyp(ptr %3, %"github.com/goplus/llgo/internal/runtime.String" %7)
ret void
}
define void @main.dumpTyp(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %1)
%2 = call i64 @"github.com/goplus/llgo/internal/abi.(*Type).Kind"(ptr %0)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 0
%4 = load i64, ptr %3, align 4
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 1
%6 = load i64, ptr %5, align 4
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 2
%8 = load i32, ptr %7, align 4
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 3
%10 = load i8, ptr %9, align 1
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 4
%12 = load i8, ptr %11, align 1
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 10
%14 = load ptr, ptr %13, align 8
%15 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Uncommon"(ptr %0)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %2)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %4)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %6)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%16 = zext i32 %8 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %16)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%17 = zext i8 %10 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %17)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%18 = zext i8 %12 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %18)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %14)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %15)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%19 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Elem"(ptr %0)
%20 = icmp ne ptr %19, null
br i1 %20, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%21 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Elem"(ptr %0)
%22 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 0
store ptr @2, ptr %23, align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %22, i32 0, i32 1
store i64 7, ptr %24, align 4
%25 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %22, align 8
%26 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %1, %"github.com/goplus/llgo/internal/runtime.String" %25)
call void @main.dumpTyp(ptr %21, %"github.com/goplus/llgo/internal/runtime.String" %26)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
%27 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Uncommon"(ptr %0)
%28 = icmp ne ptr %27, null
br i1 %28, label %_llgo_3, label %_llgo_4
_llgo_3: ; preds = %_llgo_2
%29 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Uncommon"(ptr %0)
%30 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %30, i32 0, i32 0
store ptr @3, ptr %31, align 8
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %30, i32 0, i32 1
store i64 9, ptr %32, align 4
%33 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %30, align 8
%34 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %1, %"github.com/goplus/llgo/internal/runtime.String" %33)
call void @main.dumpUncommon(ptr %29, %"github.com/goplus/llgo/internal/runtime.String" %34)
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 10
%36 = load ptr, ptr %35, align 8
%37 = icmp ne ptr %36, null
br i1 %37, label %_llgo_5, label %_llgo_4
_llgo_4: ; preds = %_llgo_5, %_llgo_3, %_llgo_2
ret void
_llgo_5: ; preds = %_llgo_3
%38 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 10
%39 = load ptr, ptr %38, align 8
%40 = call ptr @"github.com/goplus/llgo/internal/abi.(*Type).Uncommon"(ptr %39)
%41 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %41, i32 0, i32 0
store ptr @4, ptr %42, align 8
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %41, i32 0, i32 1
store i64 9, ptr %43, align 4
%44 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %41, align 8
%45 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %1, %"github.com/goplus/llgo/internal/runtime.String" %44)
call void @main.dumpUncommon(ptr %40, %"github.com/goplus/llgo/internal/runtime.String" %45)
br label %_llgo_4
}
define void @main.dumpUncommon(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %1)
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.UncommonType", ptr %0, i32 0, i32 0
%3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.UncommonType", ptr %0, i32 0, i32 1
%5 = load i16, ptr %4, align 2
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.UncommonType", ptr %0, i32 0, i32 2
%7 = load i16, ptr %6, align 2
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %3)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%8 = zext i16 %5 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %8)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 32)
%9 = zext i16 %7 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %9)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret void
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
call void @"github.com/goplus/llgo/internal/abi.init"()
call void @"main.init$after"()
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = load ptr, ptr @_llgo_bool, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %2, i32 0, i32 6
%4 = load i8, ptr %3, align 1
%5 = or i8 %4, 32
store i8 %5, ptr %3, align 1
%6 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 0
store ptr %2, ptr %7, align 8
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, i32 0, i32 1
store ptr inttoptr (i64 -1 to ptr), ptr %8, align 8
%9 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %6, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %9)
%10 = load ptr, ptr @_llgo_int, align 8
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %10, i32 0, i32 6
%12 = load i8, ptr %11, align 1
%13 = or i8 %12, 32
store i8 %13, ptr %11, align 1
%14 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %14, i32 0, i32 0
store ptr %10, ptr %15, align 8
%16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %14, i32 0, i32 1
store ptr null, ptr %16, align 8
%17 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %14, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %17)
%18 = load ptr, ptr @_llgo_int8, align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %18, i32 0, i32 6
%20 = load i8, ptr %19, align 1
%21 = or i8 %20, 32
store i8 %21, ptr %19, align 1
%22 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, i32 0, i32 0
store ptr %18, ptr %23, align 8
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, i32 0, i32 1
store ptr null, ptr %24, align 8
%25 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %25)
%26 = load ptr, ptr @_llgo_int16, align 8
%27 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %26, i32 0, i32 6
%28 = load i8, ptr %27, align 1
%29 = or i8 %28, 32
store i8 %29, ptr %27, align 1
%30 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 0
store ptr %26, ptr %31, align 8
%32 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, i32 0, i32 1
store ptr null, ptr %32, align 8
%33 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %30, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %33)
%34 = load ptr, ptr @_llgo_int32, align 8
%35 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %34, i32 0, i32 6
%36 = load i8, ptr %35, align 1
%37 = or i8 %36, 32
store i8 %37, ptr %35, align 1
%38 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, i32 0, i32 0
store ptr %34, ptr %39, align 8
%40 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, i32 0, i32 1
store ptr null, ptr %40, align 8
%41 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %38, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %41)
%42 = load ptr, ptr @_llgo_int64, align 8
%43 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %42, i32 0, i32 6
%44 = load i8, ptr %43, align 1
%45 = or i8 %44, 32
store i8 %45, ptr %43, align 1
%46 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%47 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %46, i32 0, i32 0
store ptr %42, ptr %47, align 8
%48 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %46, i32 0, i32 1
store ptr null, ptr %48, align 8
%49 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %46, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %49)
%50 = load ptr, ptr @_llgo_uint, align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %50, i32 0, i32 6
%52 = load i8, ptr %51, align 1
%53 = or i8 %52, 32
store i8 %53, ptr %51, align 1
%54 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%55 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %54, i32 0, i32 0
store ptr %50, ptr %55, align 8
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %54, i32 0, i32 1
store ptr null, ptr %56, align 8
%57 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %54, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %57)
%58 = load ptr, ptr @_llgo_uint8, align 8
%59 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %58, i32 0, i32 6
%60 = load i8, ptr %59, align 1
%61 = or i8 %60, 32
store i8 %61, ptr %59, align 1
%62 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%63 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %62, i32 0, i32 0
store ptr %58, ptr %63, align 8
%64 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %62, i32 0, i32 1
store ptr null, ptr %64, align 8
%65 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %62, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %65)
%66 = load ptr, ptr @_llgo_uint16, align 8
%67 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %66, i32 0, i32 6
%68 = load i8, ptr %67, align 1
%69 = or i8 %68, 32
store i8 %69, ptr %67, align 1
%70 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%71 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %70, i32 0, i32 0
store ptr %66, ptr %71, align 8
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %70, i32 0, i32 1
store ptr null, ptr %72, align 8
%73 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %70, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %73)
%74 = load ptr, ptr @_llgo_uint32, align 8
%75 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %74, i32 0, i32 6
%76 = load i8, ptr %75, align 1
%77 = or i8 %76, 32
store i8 %77, ptr %75, align 1
%78 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%79 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %78, i32 0, i32 0
store ptr %74, ptr %79, align 8
%80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %78, i32 0, i32 1
store ptr null, ptr %80, align 8
%81 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %78, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %81)
%82 = load ptr, ptr @_llgo_uint64, align 8
%83 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %82, i32 0, i32 6
%84 = load i8, ptr %83, align 1
%85 = or i8 %84, 32
store i8 %85, ptr %83, align 1
%86 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%87 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %86, i32 0, i32 0
store ptr %82, ptr %87, align 8
%88 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %86, i32 0, i32 1
store ptr null, ptr %88, align 8
%89 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %86, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %89)
%90 = load ptr, ptr @_llgo_uintptr, align 8
%91 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %90, i32 0, i32 6
%92 = load i8, ptr %91, align 1
%93 = or i8 %92, 32
store i8 %93, ptr %91, align 1
%94 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%95 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %94, i32 0, i32 0
store ptr %90, ptr %95, align 8
%96 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %94, i32 0, i32 1
store ptr null, ptr %96, align 8
%97 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %94, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %97)
%98 = load ptr, ptr @_llgo_float32, align 8
%99 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %98, i32 0, i32 6
%100 = load i8, ptr %99, align 1
%101 = or i8 %100, 32
store i8 %101, ptr %99, align 1
%102 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%103 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %102, i32 0, i32 0
store ptr %98, ptr %103, align 8
%104 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %102, i32 0, i32 1
store ptr null, ptr %104, align 8
%105 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %102, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %105)
%106 = load ptr, ptr @_llgo_float64, align 8
%107 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %106, i32 0, i32 6
%108 = load i8, ptr %107, align 1
%109 = or i8 %108, 32
store i8 %109, ptr %107, align 1
%110 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %110, i32 0, i32 0
store ptr %106, ptr %111, align 8
%112 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %110, i32 0, i32 1
store ptr null, ptr %112, align 8
%113 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %110, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %113)
%114 = load ptr, ptr @"[10]_llgo_int", align 8
%115 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 80)
store [10 x i64] zeroinitializer, ptr %115, align 4
%116 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%117 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, i32 0, i32 0
store ptr %114, ptr %117, align 8
%118 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, i32 0, i32 1
store ptr %115, ptr %118, align 8
%119 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %116, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %119)
%120 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%121 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%122 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %121, i32 0, i32 0
store ptr %120, ptr %122, align 8
%123 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %121, i32 0, i32 1
store ptr @"main.main$1", ptr %123, align 8
%124 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %121, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %124)
%125 = load ptr, ptr @"*_llgo_int", align 8
%126 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%127 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %126, i32 0, i32 0
store ptr %125, ptr %127, align 8
%128 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %126, i32 0, i32 1
store ptr null, ptr %128, align 8
%129 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %126, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %129)
%130 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0)
%131 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%132 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %131, i32 0, i32 0
store ptr %130, ptr %132, align 8
%133 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %131, i32 0, i32 1
store i64 0, ptr %133, align 4
%134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %131, i32 0, i32 2
store i64 0, ptr %134, align 4
%135 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %131, align 8
%136 = load ptr, ptr @"[]_llgo_int", align 8
%137 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
store %"github.com/goplus/llgo/internal/runtime.Slice" %135, ptr %137, align 8
%138 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%139 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %138, i32 0, i32 0
store ptr %136, ptr %139, align 8
%140 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %138, i32 0, i32 1
store ptr %137, ptr %140, align 8
%141 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %138, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %141)
%142 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%143 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %142, i32 0, i32 0
store ptr @5, ptr %143, align 8
%144 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %142, i32 0, i32 1
store i64 5, ptr %144, align 4
%145 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %142, align 8
%146 = load ptr, ptr @_llgo_string, align 8
%147 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %145, ptr %147, align 8
%148 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%149 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %148, i32 0, i32 0
store ptr %146, ptr %149, align 8
%150 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %148, i32 0, i32 1
store ptr %147, ptr %150, align 8
%151 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %148, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %151)
%152 = load ptr, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8
%153 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
store { i8, i64, i64 } zeroinitializer, ptr %153, align 4
%154 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%155 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %154, i32 0, i32 0
store ptr %152, ptr %155, align 8
%156 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %154, i32 0, i32 1
store ptr %153, ptr %156, align 8
%157 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %154, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %157)
%158 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%159 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %158, i32 0, i32 0
store ptr @13, ptr %159, align 8
%160 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %158, i32 0, i32 1
store i64 0, ptr %160, align 4
%161 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %158, align 8
%162 = load ptr, ptr @_llgo_main.T, align 8
%163 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %161, ptr %163, align 8
%164 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%165 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %164, i32 0, i32 0
store ptr %162, ptr %165, align 8
%166 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %164, i32 0, i32 1
store ptr %163, ptr %166, align 8
%167 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %164, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %167)
ret i32 0
}
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare i64 @"github.com/goplus/llgo/internal/abi.(*Type).Kind"(ptr)
declare ptr @"github.com/goplus/llgo/internal/abi.(*Type).Uncommon"(ptr)
declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr)
declare ptr @"github.com/goplus/llgo/internal/abi.(*Type).Elem"(ptr)
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/abi.init"()
declare void @"github.com/goplus/llgo/internal/runtime.init"()
define void @"main.init$after"() {
_llgo_0:
%0 = load ptr, ptr @_llgo_bool, align 8
%1 = icmp eq ptr %0, null
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
store ptr %2, ptr @_llgo_bool, align 8
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
%3 = load ptr, ptr @_llgo_int, align 8
%4 = icmp eq ptr %3, null
br i1 %4, label %_llgo_3, label %_llgo_4
_llgo_3: ; preds = %_llgo_2
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
store ptr %5, ptr @_llgo_int, align 8
br label %_llgo_4
_llgo_4: ; preds = %_llgo_3, %_llgo_2
%6 = load ptr, ptr @_llgo_int8, align 8
%7 = icmp eq ptr %6, null
br i1 %7, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
store ptr %8, ptr @_llgo_int8, align 8
br label %_llgo_6
_llgo_6: ; preds = %_llgo_5, %_llgo_4
%9 = load ptr, ptr @_llgo_int16, align 8
%10 = icmp eq ptr %9, null
br i1 %10, label %_llgo_7, label %_llgo_8
_llgo_7: ; preds = %_llgo_6
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
store ptr %11, ptr @_llgo_int16, align 8
br label %_llgo_8
_llgo_8: ; preds = %_llgo_7, %_llgo_6
%12 = load ptr, ptr @_llgo_int32, align 8
%13 = icmp eq ptr %12, null
br i1 %13, label %_llgo_9, label %_llgo_10
_llgo_9: ; preds = %_llgo_8
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
store ptr %14, ptr @_llgo_int32, align 8
br label %_llgo_10
_llgo_10: ; preds = %_llgo_9, %_llgo_8
%15 = load ptr, ptr @_llgo_int64, align 8
%16 = icmp eq ptr %15, null
br i1 %16, label %_llgo_11, label %_llgo_12
_llgo_11: ; preds = %_llgo_10
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
store ptr %17, ptr @_llgo_int64, align 8
br label %_llgo_12
_llgo_12: ; preds = %_llgo_11, %_llgo_10
%18 = load ptr, ptr @_llgo_uint, align 8
%19 = icmp eq ptr %18, null
br i1 %19, label %_llgo_13, label %_llgo_14
_llgo_13: ; preds = %_llgo_12
%20 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
store ptr %20, ptr @_llgo_uint, align 8
br label %_llgo_14
_llgo_14: ; preds = %_llgo_13, %_llgo_12
%21 = load ptr, ptr @_llgo_uint8, align 8
%22 = icmp eq ptr %21, null
br i1 %22, label %_llgo_15, label %_llgo_16
_llgo_15: ; preds = %_llgo_14
%23 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
store ptr %23, ptr @_llgo_uint8, align 8
br label %_llgo_16
_llgo_16: ; preds = %_llgo_15, %_llgo_14
%24 = load ptr, ptr @_llgo_uint16, align 8
%25 = icmp eq ptr %24, null
br i1 %25, label %_llgo_17, label %_llgo_18
_llgo_17: ; preds = %_llgo_16
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
store ptr %26, ptr @_llgo_uint16, align 8
br label %_llgo_18
_llgo_18: ; preds = %_llgo_17, %_llgo_16
%27 = load ptr, ptr @_llgo_uint32, align 8
%28 = icmp eq ptr %27, null
br i1 %28, label %_llgo_19, label %_llgo_20
_llgo_19: ; preds = %_llgo_18
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
store ptr %29, ptr @_llgo_uint32, align 8
br label %_llgo_20
_llgo_20: ; preds = %_llgo_19, %_llgo_18
%30 = load ptr, ptr @_llgo_uint64, align 8
%31 = icmp eq ptr %30, null
br i1 %31, label %_llgo_21, label %_llgo_22
_llgo_21: ; preds = %_llgo_20
%32 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
store ptr %32, ptr @_llgo_uint64, align 8
br label %_llgo_22
_llgo_22: ; preds = %_llgo_21, %_llgo_20
%33 = load ptr, ptr @_llgo_uintptr, align 8
%34 = icmp eq ptr %33, null
br i1 %34, label %_llgo_23, label %_llgo_24
_llgo_23: ; preds = %_llgo_22
%35 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
store ptr %35, ptr @_llgo_uintptr, align 8
br label %_llgo_24
_llgo_24: ; preds = %_llgo_23, %_llgo_22
%36 = load ptr, ptr @_llgo_float32, align 8
%37 = icmp eq ptr %36, null
br i1 %37, label %_llgo_25, label %_llgo_26
_llgo_25: ; preds = %_llgo_24
%38 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
store ptr %38, ptr @_llgo_float32, align 8
br label %_llgo_26
_llgo_26: ; preds = %_llgo_25, %_llgo_24
%39 = load ptr, ptr @_llgo_float64, align 8
%40 = icmp eq ptr %39, null
br i1 %40, label %_llgo_27, label %_llgo_28
_llgo_27: ; preds = %_llgo_26
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
store ptr %41, ptr @_llgo_float64, align 8
br label %_llgo_28
_llgo_28: ; preds = %_llgo_27, %_llgo_26
%42 = load ptr, ptr @_llgo_int, align 8
%43 = load ptr, ptr @"[10]_llgo_int", align 8
%44 = icmp eq ptr %43, null
br i1 %44, label %_llgo_29, label %_llgo_30
_llgo_29: ; preds = %_llgo_28
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.ArrayOf"(i64 10, ptr %42)
store ptr %45, ptr @"[10]_llgo_int", align 8
br label %_llgo_30
_llgo_30: ; preds = %_llgo_29, %_llgo_28
%46 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%47 = icmp eq ptr %46, null
br i1 %47, label %_llgo_31, label %_llgo_32
_llgo_31: ; preds = %_llgo_30
%48 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%49 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%50 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 0
store ptr %48, ptr %50, align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 1
store i64 0, ptr %51, align 4
%52 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, i32 0, i32 2
store i64 0, ptr %52, align 4
%53 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %49, align 8
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 0)
%55 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 0
store ptr %54, ptr %56, align 8
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 1
store i64 0, ptr %57, align 4
%58 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, i32 0, i32 2
store i64 0, ptr %58, align 4
%59 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %55, align 8
%60 = call ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice" %53, %"github.com/goplus/llgo/internal/runtime.Slice" %59, i1 false)
store ptr %60, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
br label %_llgo_32
_llgo_32: ; preds = %_llgo_31, %_llgo_30
%61 = load ptr, ptr @_llgo_int, align 8
%62 = load ptr, ptr @"*_llgo_int", align 8
%63 = icmp eq ptr %62, null
br i1 %63, label %_llgo_33, label %_llgo_34
_llgo_33: ; preds = %_llgo_32
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr %61)
store ptr %64, ptr @"*_llgo_int", align 8
br label %_llgo_34
_llgo_34: ; preds = %_llgo_33, %_llgo_32
%65 = load ptr, ptr @_llgo_int, align 8
%66 = load ptr, ptr @"[]_llgo_int", align 8
%67 = icmp eq ptr %66, null
br i1 %67, label %_llgo_35, label %_llgo_36
_llgo_35: ; preds = %_llgo_34
%68 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceOf"(ptr %65)
store ptr %68, ptr @"[]_llgo_int", align 8
br label %_llgo_36
_llgo_36: ; preds = %_llgo_35, %_llgo_34
%69 = load ptr, ptr @_llgo_string, align 8
%70 = icmp eq ptr %69, null
br i1 %70, label %_llgo_37, label %_llgo_38
_llgo_37: ; preds = %_llgo_36
%71 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
store ptr %71, ptr @_llgo_string, align 8
br label %_llgo_38
_llgo_38: ; preds = %_llgo_37, %_llgo_36
%72 = load ptr, ptr @_llgo_int8, align 8
%73 = load ptr, ptr @_llgo_int, align 8
%74 = load ptr, ptr @_llgo_int, align 8
%75 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %75, i32 0, i32 0
store ptr @6, ptr %76, align 8
%77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %75, i32 0, i32 1
store i64 1, ptr %77, align 4
%78 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %75, align 8
%79 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %79, i32 0, i32 0
store ptr @7, ptr %80, align 8
%81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %79, i32 0, i32 1
store i64 0, ptr %81, align 4
%82 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %79, align 8
%83 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %78, ptr %72, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %82, i1 false)
%84 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %84, i32 0, i32 0
store ptr @8, ptr %85, align 8
%86 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %84, i32 0, i32 1
store i64 1, ptr %86, align 4
%87 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %84, align 8
%88 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%89 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %88, i32 0, i32 0
store ptr @9, ptr %89, align 8
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %88, i32 0, i32 1
store i64 0, ptr %90, align 4
%91 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %88, align 8
%92 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %87, ptr %73, i64 8, %"github.com/goplus/llgo/internal/runtime.String" %91, i1 false)
%93 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%94 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %93, i32 0, i32 0
store ptr @10, ptr %94, align 8
%95 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %93, i32 0, i32 1
store i64 1, ptr %95, align 4
%96 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %93, align 8
%97 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 0
store ptr @11, ptr %98, align 8
%99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %97, i32 0, i32 1
store i64 0, ptr %99, align 4
%100 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %97, align 8
%101 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %96, ptr %74, i64 16, %"github.com/goplus/llgo/internal/runtime.String" %100, i1 false)
%102 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%103 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %102, i32 0, i32 0
store ptr @12, ptr %103, align 8
%104 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %102, i32 0, i32 1
store i64 4, ptr %104, align 4
%105 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %102, align 8
%106 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 168)
%107 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 0
store %"github.com/goplus/llgo/internal/abi.StructField" %83, ptr %107, align 8
%108 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 1
store %"github.com/goplus/llgo/internal/abi.StructField" %92, ptr %108, align 8
%109 = getelementptr %"github.com/goplus/llgo/internal/abi.StructField", ptr %106, i64 2
store %"github.com/goplus/llgo/internal/abi.StructField" %101, ptr %109, align 8
%110 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%111 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 0
store ptr %106, ptr %111, align 8
%112 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 1
store i64 3, ptr %112, align 4
%113 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, i32 0, i32 2
store i64 3, ptr %113, align 4
%114 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %110, align 8
%115 = call ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String" %105, i64 24, %"github.com/goplus/llgo/internal/runtime.Slice" %114)
store ptr %115, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8
%116 = load ptr, ptr @_llgo_main.T, align 8
%117 = icmp eq ptr %116, null
br i1 %117, label %_llgo_39, label %_llgo_40
_llgo_39: ; preds = %_llgo_38
%118 = call ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64 24, i64 0, i64 1)
store ptr %118, ptr @_llgo_main.T, align 8
br label %_llgo_40
_llgo_40: ; preds = %_llgo_39, %_llgo_38
%119 = load ptr, ptr @_llgo_string, align 8
br i1 %117, label %_llgo_41, label %_llgo_42
_llgo_41: ; preds = %_llgo_40
%120 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%121 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %120, i32 0, i32 0
store ptr @14, ptr %121, align 8
%122 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %120, i32 0, i32 1
store i64 6, ptr %122, align 4
%123 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %120, align 8
%124 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
%125 = alloca %"github.com/goplus/llgo/internal/abi.Method", align 8
%126 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %125, i32 0, i32 0
store %"github.com/goplus/llgo/internal/runtime.String" %123, ptr %126, align 8
%127 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %125, i32 0, i32 1
store ptr %124, ptr %127, align 8
%128 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %125, i32 0, i32 2
store ptr @"main.(*T).Invoke", ptr %128, align 8
%129 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Method", ptr %125, i32 0, i32 3
store ptr @"main.(*T).Invoke", ptr %129, align 8
%130 = load %"github.com/goplus/llgo/internal/abi.Method", ptr %125, align 8
%131 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 40)
%132 = getelementptr %"github.com/goplus/llgo/internal/abi.Method", ptr %131, i64 0
store %"github.com/goplus/llgo/internal/abi.Method" %130, ptr %132, align 8
%133 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%134 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 0
store ptr %131, ptr %134, align 8
%135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 1
store i64 1, ptr %135, align 4
%136 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, i32 0, i32 2
store i64 1, ptr %136, align 4
%137 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %133, align 8
%138 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%139 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %138, i32 0, i32 0
store ptr @15, ptr %139, align 8
%140 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %138, i32 0, i32 1
store i64 4, ptr %140, align 4
%141 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %138, align 8
%142 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%143 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %142, i32 0, i32 0
store ptr @16, ptr %143, align 8
%144 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %142, i32 0, i32 1
store i64 6, ptr %144, align 4
%145 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %142, align 8
call void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr %118, %"github.com/goplus/llgo/internal/runtime.String" %141, %"github.com/goplus/llgo/internal/runtime.String" %145, ptr %119, { ptr, i64, i64 } zeroinitializer, %"github.com/goplus/llgo/internal/runtime.Slice" %137)
br label %_llgo_42
_llgo_42: ; preds = %_llgo_41, %_llgo_40
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.ArrayOf"(i64, ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
define void @"main.main$1"() {
_llgo_0:
ret void
}
declare ptr @"github.com/goplus/llgo/internal/runtime.Func"(%"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice", i1)
declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceOf"(ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.Struct"(%"github.com/goplus/llgo/internal/runtime.String", i64, %"github.com/goplus/llgo/internal/runtime.Slice")
declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String", ptr, i64, %"github.com/goplus/llgo/internal/runtime.String", i1)
declare ptr @"github.com/goplus/llgo/internal/runtime.NewNamed"(i64, i64, i64)
declare void @"github.com/goplus/llgo/internal/runtime.InitNamed"(ptr, %"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String", ptr, %"github.com/goplus/llgo/internal/runtime.Slice", %"github.com/goplus/llgo/internal/runtime.Slice")

View File

@@ -17,7 +17,7 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_0 _llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1 store i1 true, ptr @"main.init$guard", align 1
call void @"main.init$abi"() call void @"main.init$after"()
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
@@ -51,7 +51,7 @@ _llgo_0:
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
define void @"main.init$abi"() { define void @"main.init$after"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @_llgo_string, align 8 %0 = load ptr, ptr @_llgo_string, align 8
%1 = icmp eq ptr %0, null %1 = icmp eq ptr %0, null

173
cl/blocks/block.go Normal file
View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package blocks
import (
llssa "github.com/goplus/llgo/ssa"
"golang.org/x/tools/go/ssa"
)
type Info struct {
Kind llssa.DoAction
Next int
}
// -----------------------------------------------------------------------------
type blockState struct {
self *ssa.BasicBlock
preds int
succs []int
loop bool
always bool
reach bool
fdel bool
}
func (p *blockState) kind() llssa.DoAction {
if p.loop {
return llssa.DeferInLoop
}
if p.always {
return llssa.DeferAlways
}
return llssa.DeferInCond
}
func newSuccs(succs []*ssa.BasicBlock) []int {
ret := make([]int, len(succs))
for i, blk := range succs {
ret[i] = blk.Index
}
return ret
}
func findLoop(states []*blockState, path []int, from, iblk int) []int {
path = append(path, iblk)
self := states[iblk]
for _, succ := range self.succs {
if states[succ].fdel {
continue
}
if pos := find(path, succ); pos >= 0 {
if pos > 0 {
continue
}
for _, i := range path {
s := states[i]
s.loop = true
s.fdel = true
}
return path
}
if ret := findLoop(states, path, from, succ); ret != nil {
return ret
}
}
return nil
}
// https://en.wikipedia.org/wiki/Topological_sorting
func Infos(blks []*ssa.BasicBlock) []Info {
n := len(blks)
order := make([]int, 1, n+1)
order[0] = 0
end, iend := 0, 0
states := make([]*blockState, n)
for i, blk := range blks {
preds := len(blk.Preds)
if preds == 0 && i != 0 {
order = append(order, i)
}
if isEnd(blk) {
end++
iend = i
}
states[i] = &blockState{
self: blk,
preds: preds,
succs: newSuccs(blk.Succs),
}
}
path := make([]int, 0, n)
if states[0].preds != 0 {
if loop := findLoop(states, path, 0, 0); len(loop) > 0 {
order = append(order, loop[1:]...)
}
} else {
states[0].always = true
}
if end == 1 {
states[iend].always = true
}
pos := 0
retry:
for pos < len(order) {
iblk := order[pos]
pos++
state := states[iblk]
state.fdel = true
for _, succ := range state.succs {
s := states[succ]
if s.fdel {
continue
}
if s.preds--; s.preds == 0 {
order = append(order, succ)
} else {
s.reach = true
}
}
}
if pos < n {
for iblk, state := range states {
if state.fdel || !state.reach {
continue
}
if loop := findLoop(states, path, iblk, iblk); len(loop) > 0 {
order = append(order, loop...)
goto retry
}
}
panic("unreachable")
}
order = append(order, -1)
ret := make([]Info, n)
for i := 0; i < n; i++ {
iblk := order[i]
ret[iblk] = Info{states[iblk].kind(), order[i+1]}
}
return ret
}
func isEnd(blk *ssa.BasicBlock) bool {
// Note: skip recover block
return len(blk.Succs) == 0 && (len(blk.Preds) > 0 || blk.Index == 0)
}
func find(path []int, fv int) int {
for i, v := range path {
if v == fv {
return i
}
}
return -1
}
// -----------------------------------------------------------------------------

140
cl/blocks/block_test.go Normal file
View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package blocks
import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/token"
"go/types"
"log"
"os"
"path"
"strings"
"testing"
"github.com/goplus/gogen/packages"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
llssa "github.com/goplus/llgo/ssa"
)
func TestTestdefer(t *testing.T) {
// debug = true
fromDir(t, "", "../_testdefer")
}
func TestFirstLoop(t *testing.T) {
blk := &ssa.BasicBlock{}
blk.Index = 0
blk.Preds = []*ssa.BasicBlock{blk}
blk.Succs = []*ssa.BasicBlock{blk}
infos := Infos([]*ssa.BasicBlock{blk})
if infos[0].Kind != llssa.DeferInLoop {
t.Fatal("TestFirstLoop")
}
}
func fromDir(t *testing.T, sel, relDir string) {
dir, err := os.Getwd()
if err != nil {
t.Fatal("Getwd failed:", err)
}
dir = path.Join(dir, relDir)
fis, err := os.ReadDir(dir)
if err != nil {
t.Fatal("ReadDir failed:", err)
}
for _, fi := range fis {
name := fi.Name()
if !fi.IsDir() || strings.HasPrefix(name, "_") {
continue
}
t.Run(name, func(t *testing.T) {
testFrom(t, dir+"/"+name, sel)
})
}
}
func testFrom(t *testing.T, pkgDir, sel string) {
if sel != "" && !strings.Contains(pkgDir, sel) {
return
}
log.Println("Parsing", pkgDir)
in := pkgDir + "/in.go"
out := pkgDir + "/out.txt"
b, err := os.ReadFile(out)
if err != nil {
t.Fatal("ReadFile failed:", err)
}
expected := string(b)
testBlockInfo(t, nil, in, expected)
}
func testBlockInfo(t *testing.T, src any, fname, expected string) {
t.Helper()
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, fname, src, parser.ParseComments)
if err != nil {
t.Fatal("ParseFile failed:", err)
}
files := []*ast.File{f}
name := f.Name.Name
pkg := types.NewPackage(name, name)
imp := packages.NewImporter(fset)
foo, _, err := ssautil.BuildPackage(
&types.Config{Importer: imp}, fset, pkg, files, ssa.SanityCheckFunctions)
if err != nil {
t.Fatal("BuildPackage failed:", err)
}
foo.WriteTo(os.Stderr)
for _, member := range foo.Members {
switch f := member.(type) {
case *ssa.Function:
if f.Name() == "main" {
f.WriteTo(os.Stderr)
infos := Infos(f.Blocks)
if v := resultOf(infos); v != expected {
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
}
return
}
}
}
}
func resultOf(infos []Info) string {
var b bytes.Buffer
i := 0
for {
fmt.Fprintf(&b, "%2d: %s\n", i, kinds[infos[i].Kind])
if i = infos[i].Next; i < 0 {
break
}
}
return b.String()
}
var kinds = [...]string{
llssa.DeferAlways: "always",
llssa.DeferInCond: "cond",
llssa.DeferInLoop: "loop",
}

View File

@@ -27,6 +27,7 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/goplus/llgo/cl/blocks"
llssa "github.com/goplus/llgo/ssa" llssa "github.com/goplus/llgo/ssa"
"golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa"
) )
@@ -148,8 +149,11 @@ type context struct {
loaded map[*types.Package]*pkgInfo // loaded packages loaded map[*types.Package]*pkgInfo // loaded packages
bvals map[ssa.Value]llssa.Expr // block values bvals map[ssa.Value]llssa.Expr // block values
vargs map[*ssa.Alloc][]llssa.Expr // varargs vargs map[*ssa.Alloc][]llssa.Expr // varargs
inits []func()
phis []func() blkInfos []blocks.Info
inits []func()
phis []func()
} }
func (p *context) inMain(instr ssa.Instruction) bool { func (p *context) inMain(instr ssa.Instruction) bool {
@@ -277,14 +281,21 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
for i, block := range f.Blocks { for i, block := range f.Blocks {
off[i] = p.compilePhis(b, block) off[i] = p.compilePhis(b, block)
} }
for i, block := range f.Blocks { p.blkInfos = blocks.Infos(f.Blocks)
i := 0
for {
block := f.Blocks[i]
doMainInit := (i == 0 && name == "main") doMainInit := (i == 0 && name == "main")
doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil) doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil)
p.compileBlock(b, block, off[i], doMainInit, doModInit) p.compileBlock(b, block, off[i], doMainInit, doModInit)
if i = p.blkInfos[i].Next; i < 0 {
break
}
} }
for _, phi := range p.phis { for _, phi := range p.phis {
phi() phi()
} }
b.EndBuild()
}) })
} }
return fn, nil, goFunc return fn, nil, goFunc
@@ -515,7 +526,7 @@ func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
for n < ninstr && isPhi(block.Instrs[n]) { for n < ninstr && isPhi(block.Instrs[n]) {
n++ n++
} }
rets := make([]llssa.Expr, n) rets := make([]llssa.Expr, n) // TODO(xsw): check to remove this
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
iv := block.Instrs[i].(*ssa.Phi) iv := block.Instrs[i].(*ssa.Phi)
rets[i] = p.compilePhi(b, iv) rets[i] = p.compilePhi(b, iv)
@@ -548,6 +559,71 @@ func (p *context) compilePhi(b llssa.Builder, v *ssa.Phi) (ret llssa.Expr) {
return return
} }
func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon) (ret llssa.Expr) {
cv := call.Value
if mthd := call.Method; mthd != nil {
o := p.compileValue(b, cv)
fn := b.Imethod(o, mthd)
args := p.compileValues(b, call.Args, fnNormal)
ret = b.Do(act, fn, args...)
return
}
kind := p.funcKind(cv)
if kind == fnIgnore {
return
}
args := call.Args
if debugGoSSA {
log.Println(">>> Do", act, cv, args)
}
switch cv := cv.(type) {
case *ssa.Builtin:
fn := cv.Name()
if fn == "ssa:wrapnilchk" { // TODO(xsw): check nil ptr
arg := args[0]
ret = p.compileValue(b, arg)
} else {
args := p.compileValues(b, args, kind)
ret = b.Do(act, llssa.Builtin(fn), args...)
}
case *ssa.Function:
aFn, pyFn, ftype := p.compileFunction(cv)
// TODO(xsw): check ca != llssa.Call
switch ftype {
case goFunc, cFunc:
args := p.compileValues(b, args, kind)
ret = b.Do(act, aFn.Expr, args...)
case pyFunc:
args := p.compileValues(b, args, kind)
ret = b.Do(act, pyFn.Expr, args...)
case llgoPyList:
args := p.compileValues(b, args, fnHasVArg)
ret = b.PyList(args...)
case llgoCstr:
ret = cstr(b, args)
case llgoAdvance:
ret = p.advance(b, args)
case llgoIndex:
ret = p.index(b, args)
case llgoAlloca:
ret = p.alloca(b, args)
case llgoAllocaCStr:
ret = p.allocaCStr(b, args)
case llgoStringData:
ret = p.stringData(b, args)
case llgoUnreachable: // func unreachable()
b.Unreachable()
default:
log.Panicln("unknown ftype:", ftype)
}
default:
fn := p.compileValue(b, cv)
args := p.compileValues(b, args, kind)
ret = b.Do(act, fn, args...)
}
return
}
func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue bool) (ret llssa.Expr) { func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue bool) (ret llssa.Expr) {
if asValue { if asValue {
if v, ok := p.bvals[iv]; ok { if v, ok := p.bvals[iv]; ok {
@@ -557,67 +633,7 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
} }
switch v := iv.(type) { switch v := iv.(type) {
case *ssa.Call: case *ssa.Call:
cv := v.Call.Value ret = p.call(b, llssa.Call, &v.Call)
if mthd := v.Call.Method; mthd != nil {
o := p.compileValue(b, cv)
fn := b.Imethod(o, v.Call.Method)
args := p.compileValues(b, v.Call.Args, fnNormal)
ret = b.Call(fn, args...)
break
}
kind := p.funcKind(cv)
if kind == fnIgnore {
return
}
args := v.Call.Args
if debugGoSSA {
log.Println(">>> Call", cv, args)
}
switch cv := cv.(type) {
case *ssa.Builtin:
fn := cv.Name()
if fn == "ssa:wrapnilchk" { // TODO(xsw): check nil ptr
arg := args[0]
ret = p.compileValue(b, arg)
// log.Println("wrapnilchk:", ret.TypeOf())
} else {
args := p.compileValues(b, args, kind)
ret = b.BuiltinCall(fn, args...)
}
case *ssa.Function:
aFn, pyFn, ftype := p.compileFunction(cv)
switch ftype {
case goFunc, cFunc:
args := p.compileValues(b, args, kind)
ret = b.Call(aFn.Expr, args...)
case pyFunc:
args := p.compileValues(b, args, kind)
ret = b.Call(pyFn.Expr, args...)
case llgoPyList:
args := p.compileValues(b, args, fnHasVArg)
ret = b.PyList(args...)
case llgoCstr:
ret = cstr(b, args)
case llgoAdvance:
ret = p.advance(b, args)
case llgoIndex:
ret = p.index(b, args)
case llgoAlloca:
ret = p.alloca(b, args)
case llgoAllocaCStr:
ret = p.allocaCStr(b, args)
case llgoStringData:
ret = p.stringData(b, args)
case llgoUnreachable: // func unreachable()
b.Unreachable()
default:
log.Panicln("unknown ftype:", ftype)
}
default:
fn := p.compileValue(b, cv)
args := p.compileValues(b, args, kind)
ret = b.Call(fn, args...)
}
case *ssa.BinOp: case *ssa.BinOp:
x := p.compileValue(b, v.X) x := p.compileValue(b, v.X)
y := p.compileValue(b, v.Y) y := p.compileValue(b, v.Y)
@@ -728,6 +744,10 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
case *ssa.Next: case *ssa.Next:
iter := p.compileValue(b, v.Iter) iter := p.compileValue(b, v.Iter)
ret = b.Next(iter, v.IsString) ret = b.Next(iter, v.IsString)
case *ssa.ChangeInterface:
t := v.Type()
x := p.compileValue(b, v.X)
ret = b.ChangeInterface(p.prog.Type(t, llssa.InGo), x)
default: default:
panic(fmt.Sprintf("compileInstrAndValue: unknown instr - %T\n", iv)) panic(fmt.Sprintf("compileInstrAndValue: unknown instr - %T\n", iv))
} }
@@ -791,6 +811,12 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
key := p.compileValue(b, v.Key) key := p.compileValue(b, v.Key)
val := p.compileValue(b, v.Value) val := p.compileValue(b, v.Value)
b.MapUpdate(m, key, val) b.MapUpdate(m, key, val)
case *ssa.Defer:
p.call(b, p.blkInfos[v.Block().Index].Kind, &v.Call)
case *ssa.Go:
p.call(b, llssa.Go, &v.Call)
case *ssa.RunDefers:
b.RunDefers()
case *ssa.Panic: case *ssa.Panic:
arg := p.compileValue(b, v.X) arg := p.compileValue(b, v.X)
b.Panic(arg) b.Panic(arg)

4
go.mod
View File

@@ -9,13 +9,13 @@ require (
github.com/goplus/mod v0.13.10 github.com/goplus/mod v0.13.10
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/qiniu/x v1.13.10 github.com/qiniu/x v1.13.10
golang.org/x/tools v0.21.0 golang.org/x/tools v0.22.0
) )
require ( require (
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
golang.org/x/mod v0.17.0 // indirect golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.7.0 // indirect
) )

7
go.sum
View File

@@ -30,8 +30,9 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -68,6 +69,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

Binary file not shown.

View File

@@ -34,6 +34,8 @@ import (
"github.com/goplus/llgo/cl" "github.com/goplus/llgo/cl"
"github.com/goplus/llgo/internal/packages" "github.com/goplus/llgo/internal/packages"
"github.com/goplus/llgo/xtool/clang" "github.com/goplus/llgo/xtool/clang"
clangCheck "github.com/goplus/llgo/xtool/clang/check"
"github.com/goplus/llgo/xtool/env"
llssa "github.com/goplus/llgo/ssa" llssa "github.com/goplus/llgo/ssa"
) )
@@ -207,11 +209,33 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
pkg.ExportFile = "" pkg.ExportFile = ""
} }
if kind == cl.PkgLinkExtern { // need to be linked with external library if kind == cl.PkgLinkExtern { // need to be linked with external library
linkFile := os.ExpandEnv(strings.TrimSpace(param)) // format: ';' separated alternative link methods. e.g.
dir, lib := filepath.Split(linkFile) // link: $LLGO_LIB_PYTHON; $(pkg-config --libs python3-embed); -lpython3
command := " -l " + lib expd := ""
if dir != "" { altParts := strings.Split(param, ";")
command += " -L " + dir[:len(dir)-1] for _, param := range altParts {
expd = strings.TrimSpace(env.ExpandEnv(strings.TrimSpace(param)))
if len(expd) > 0 {
break
}
}
if expd == "" {
panic(fmt.Sprintf("'%s' cannot locate the external library", param))
}
command := ""
if expd[0] == '-' {
command += " " + expd
} else {
linkFile := expd
dir, lib := filepath.Split(linkFile)
command = " -l " + lib
if dir != "" {
command += " -L " + dir[:len(dir)-1]
}
}
if err := clangCheck.CheckLinkArgs(command); err != nil {
panic(fmt.Sprintf("test link args '%s' failed\n\texpanded to: %s\n\tresolved to: %v\n\terror: %v", param, expd, command, err))
} }
if isSingleLinkFile(pkg.ExportFile) { if isSingleLinkFile(pkg.ExportFile) {
pkg.ExportFile = command + " " + pkg.ExportFile pkg.ExportFile = command + " " + pkg.ExportFile

Binary file not shown.

View File

@@ -35,13 +35,13 @@ func AllocZ(size uintptr) unsafe.Pointer {
} }
// Zeroinit initializes memory to zero. // Zeroinit initializes memory to zero.
func Zeroinit(p c.Pointer, size uintptr) c.Pointer { func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer {
return c.Memset(p, 0, size) return c.Memset(p, 0, size)
} }
// TracePanic prints panic message. // TracePanic prints panic message.
func TracePanic(v Eface) { func TracePanic(v Eface) {
kind := abi.Kind(v._type.Kind_) kind := v._type.Kind()
switch { switch {
case kind == abi.String: case kind == abi.String:
stringTracef(c.Stderr, c.Str("panic: %s\n"), *(*String)(v.data)) stringTracef(c.Stderr, c.Str("panic: %s\n"), *(*String)(v.data))

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package runtime
// Defer presents defer statements in a function.
type Defer struct {
proc func(uintptr)
bits uintptr
link *Defer
rund int // index of RunDefers
}
// DeferProc calls deferred statements.
func DeferProc(d *Defer) {
for d != nil {
d.proc(d.bits)
d = d.link
_ = d.rund
}
}

View File

@@ -132,7 +132,7 @@ func doInitNamed(ret *Type, pkgPath, name string, underlying *Type, methods []Me
panic("runtime: underlying type is already named") panic("runtime: underlying type is already named")
} }
kind := abi.Kind(ret.Kind_) kind := ret.Kind()
if ret.TFlag != abi.TFlagUninited || kind != underlying.Kind() { if ret.TFlag != abi.TFlagUninited || kind != underlying.Kind() {
panic("initNamed: unexpected named type") panic("initNamed: unexpected named type")
} }
@@ -198,6 +198,9 @@ func Interface(pkgPath, name string, methods []Imethod) *InterfaceType {
// NewItab returns a new itab. // NewItab returns a new itab.
func NewItab(inter *InterfaceType, typ *Type) *Itab { func NewItab(inter *InterfaceType, typ *Type) *Itab {
if typ == nil {
return nil
}
n := len(inter.Methods) n := len(inter.Methods)
size := itabHdrSize + uintptr(n)*pointerSize size := itabHdrSize + uintptr(n)*pointerSize
ptr := AllocU(size) ptr := AllocU(size)
@@ -246,4 +249,21 @@ func methods(u *abi.UncommonType, from string) []abi.Method {
return u.ExportedMethods() return u.ExportedMethods()
} }
func IfaceType(i iface) *abi.Type {
if i.tab == nil {
return nil
}
return i.tab._type
}
func IfacePtrData(i iface) unsafe.Pointer {
if i.tab == nil {
panic(errorString("invalid memory address or nil pointer dereference").Error())
}
if i.tab._type.Kind_&abi.KindDirectIface != 0 {
return unsafe.Pointer(&i.data)
}
return i.data
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -23,7 +23,7 @@ import (
) )
const ( const (
LLGoPackage = "link: $LLGO_LIB_PYTHON" LLGoPackage = "link: $LLGO_LIB_PYTHON; $(pkg-config --libs python3-embed)"
) )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -19,7 +19,6 @@ package ssa
import ( import (
"go/token" "go/token"
"go/types" "go/types"
"unsafe"
"github.com/goplus/llgo/ssa/abi" "github.com/goplus/llgo/ssa/abi"
"github.com/goplus/llvm" "github.com/goplus/llvm"
@@ -285,32 +284,8 @@ func lastParamType(prog Program, fn Expr) Type {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type abiTypes struct {
iniabi unsafe.Pointer
}
func (p Package) hasAbiInit() bool {
return p.iniabi != nil
}
func (p Package) abiInit(b Builder) {
inib := Builder(p.iniabi)
inib.Return()
b.Call(inib.Func.Expr)
}
func (p Package) abiBuilder() Builder {
if p.iniabi == nil {
sigAbiInit := types.NewSignatureType(nil, nil, nil, nil, nil, false)
fn := p.NewFunc(p.Path()+".init$abi", sigAbiInit, InC)
fnb := fn.MakeBody(1)
p.iniabi = unsafe.Pointer(fnb)
}
return Builder(p.iniabi)
}
func (p Package) abiTypeInit(g Global, t types.Type, pub bool) { func (p Package) abiTypeInit(g Global, t types.Type, pub bool) {
b := p.abiBuilder() b := p.afterBuilder()
tabi := b.abiTypeOf(t) tabi := b.abiTypeOf(t)
expr := g.Expr expr := g.Expr
var eq Expr var eq Expr

View File

@@ -85,15 +85,13 @@ func (p Package) NewVar(name string, typ types.Type, bg Background) Global {
return p.doNewVar(name, t) return p.doNewVar(name, t)
} }
/* // NewVarEx creates a new global variable.
// NewVarFrom creates a new global variable. func (p Package) NewVarEx(name string, t Type) Global {
func (p Package) NewVarFrom(name string, t Type) Global {
if v, ok := p.vars[name]; ok { if v, ok := p.vars[name]; ok {
return v return v
} }
return p.doNewVar(name, t) return p.doNewVar(name, t)
} }
*/
func (p Package) doNewVar(name string, t Type) Global { func (p Package) doNewVar(name string, t Type) Global {
var gbl llvm.Value var gbl llvm.Value
@@ -182,6 +180,8 @@ type aFunction struct {
blks []BasicBlock blks []BasicBlock
defer_ *aDefer
params []Type params []Type
freeVars Expr freeVars Expr
base int // base = 1 if hasFreeVars; base = 0 otherwise base int // base = 1 if hasFreeVars; base = 0 otherwise
@@ -222,7 +222,14 @@ func newFunction(fn llvm.Value, t Type, pkg Package, prog Program, hasFreeVars b
if hasFreeVars { if hasFreeVars {
base = 1 base = 1
} }
return &aFunction{Expr{fn, t}, pkg, prog, nil, params, Expr{}, base, hasVArg} return &aFunction{
Expr: Expr{fn, t},
Pkg: pkg,
Prog: prog,
params: params,
base: base,
hasVArg: hasVArg,
}
} }
func newParams(fn Type, prog Program) (params []Type, hasVArg bool) { func newParams(fn Type, prog Program) (params []Type, hasVArg bool) {

View File

@@ -43,6 +43,26 @@ func (v Expr) IsNil() bool {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type builtinTy struct {
name string
}
func (p builtinTy) Underlying() types.Type {
panic("don't call")
}
func (p builtinTy) String() string {
return "builtinTy"
}
// Builtin returns a builtin function expression.
func Builtin(name string) Expr {
tbi := &aType{raw: rawType{&builtinTy{name}}, kind: vkBuiltin}
return Expr{Type: tbi}
}
// -----------------------------------------------------------------------------
type pyVarTy struct { type pyVarTy struct {
mod Expr mod Expr
name string name string
@@ -93,6 +113,16 @@ func (p Program) Zero(t Type) Expr {
ret = llvm.ConstStruct(flds, false) ret = llvm.ConstStruct(flds, false)
case *types.Slice: case *types.Slice:
ret = p.Zero(p.rtType("Slice")).impl ret = p.Zero(p.rtType("Slice")).impl
/* TODO(xsw):
case *types.Interface:
var name string
if u.Empty() {
name = "Eface"
} else {
name = "Iface"
}
ret = p.Zero(p.rtType(name)).impl
*/
default: default:
log.Panicln("todo:", u) log.Panicln("todo:", u)
} }
@@ -443,251 +473,6 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
func checkExpr(v Expr, t types.Type, b Builder) Expr {
if t, ok := t.(*types.Struct); ok && isClosure(t) {
if v.kind != vkClosure {
return b.Pkg.closureStub(b, t, v)
}
}
return v
}
func needsNegativeCheck(x Expr) bool {
if x.kind == vkSigned {
if rv := x.impl.IsAConstantInt(); !rv.IsNil() && rv.SExtValue() >= 0 {
return false
}
return true
}
return false
}
func llvmParamsEx(data Expr, vals []Expr, params *types.Tuple, b Builder) (ret []llvm.Value) {
if data.IsNil() {
return llvmParams(0, vals, params, b)
}
ret = llvmParams(1, vals, params, b)
ret[0] = data.impl
return
}
func llvmParams(base int, vals []Expr, params *types.Tuple, b Builder) (ret []llvm.Value) {
n := params.Len()
if n > 0 {
ret = make([]llvm.Value, len(vals)+base)
for idx, v := range vals {
i := base + idx
if i < n {
v = checkExpr(v, params.At(i).Type(), b)
}
ret[i] = v.impl
}
}
return
}
func llvmFields(vals []Expr, t *types.Struct, b Builder) (ret []llvm.Value) {
n := t.NumFields()
if n > 0 {
ret = make([]llvm.Value, len(vals))
for i, v := range vals {
if i < n {
v = checkExpr(v, t.Field(i).Type(), b)
}
ret[i] = v.impl
}
}
return
}
// -----------------------------------------------------------------------------
// Advance returns the pointer ptr advanced by offset.
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
if debugInstr {
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
}
var elem llvm.Type
var prog = b.Prog
switch t := ptr.raw.Type.(type) {
case *types.Basic: // void
elem = prog.tyInt8()
default:
elem = prog.rawType(t.(*types.Pointer).Elem()).ll
}
ret := llvm.CreateGEP(b.impl, elem, ptr.impl, []llvm.Value{offset.impl})
return Expr{ret, ptr.Type}
}
// Load returns the value at the pointer ptr.
func (b Builder) Load(ptr Expr) Expr {
if debugInstr {
log.Printf("Load %v\n", ptr.impl)
}
if ptr.kind == vkPyVarRef {
return b.pyLoad(ptr)
}
telem := b.Prog.Elem(ptr.Type)
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
}
// Store stores val at the pointer ptr.
func (b Builder) Store(ptr, val Expr) Builder {
raw := ptr.raw.Type
if debugInstr {
log.Printf("Store %v, %v, %v\n", raw, ptr.impl, val.impl)
}
val = checkExpr(val, raw.(*types.Pointer).Elem(), b)
b.impl.CreateStore(val.impl, ptr.impl)
return b
}
func (b Builder) aggregateAlloc(t Type, flds ...llvm.Value) llvm.Value {
prog := b.Prog
size := prog.SizeOf(t)
ptr := b.InlineCall(b.Pkg.rtFunc("AllocU"), prog.IntVal(size, prog.Uintptr())).impl
tll := t.ll
impl := b.impl
for i, fld := range flds {
impl.CreateStore(fld, llvm.CreateStructGEP(impl, tll, ptr, i))
}
return ptr
}
// aggregateValue yields the value of the aggregate X with the fields
func (b Builder) aggregateValue(t Type, flds ...llvm.Value) Expr {
return Expr{aggregateValue(b.impl, t.ll, flds...), t}
}
func aggregateValue(b llvm.Builder, tll llvm.Type, flds ...llvm.Value) llvm.Value {
ptr := llvm.CreateAlloca(b, tll)
for i, fld := range flds {
b.CreateStore(fld, llvm.CreateStructGEP(b, tll, ptr, i))
}
return llvm.CreateLoad(b, tll, ptr)
}
// The MakeClosure instruction yields a closure value whose code is
// Fn and whose free variables' values are supplied by Bindings.
//
// Type() returns a (possibly named) *types.Signature.
//
// Example printed form:
//
// t0 = make closure anon@1.2 [x y z]
// t1 = make closure bound$(main.I).add [i]
func (b Builder) MakeClosure(fn Expr, bindings []Expr) Expr {
if debugInstr {
log.Printf("MakeClosure %v, %v\n", fn, bindings)
}
prog := b.Prog
tfn := fn.Type
sig := tfn.raw.Type.(*types.Signature)
tctx := sig.Params().At(0).Type().Underlying().(*types.Pointer).Elem().(*types.Struct)
flds := llvmFields(bindings, tctx, b)
data := b.aggregateAlloc(prog.rawType(tctx), flds...)
return b.aggregateValue(prog.Closure(tfn), fn.impl, data)
}
// -----------------------------------------------------------------------------
// The Alloc instruction reserves space for a variable of the given type,
// zero-initializes it, and yields its address.
//
// If heap is false, Alloc zero-initializes the same local variable in
// the call frame and returns its address; in this case the Alloc must
// be present in Function.Locals. We call this a "local" alloc.
//
// If heap is true, Alloc allocates a new zero-initialized variable
// each time the instruction is executed. We call this a "new" alloc.
//
// When Alloc is applied to a channel, map or slice type, it returns
// the address of an uninitialized (nil) reference of that kind; store
// the result of MakeSlice, MakeMap or MakeChan in that location to
// instantiate these types.
//
// Example printed form:
//
// t0 = local int
// t1 = new int
func (b Builder) Alloc(elem Type, heap bool) (ret Expr) {
if debugInstr {
log.Printf("Alloc %v, %v\n", elem.RawType(), heap)
}
prog := b.Prog
pkg := b.Pkg
size := SizeOf(prog, elem)
if heap {
ret = b.InlineCall(pkg.rtFunc("AllocZ"), size)
} else {
ret = Expr{llvm.CreateAlloca(b.impl, elem.ll), prog.VoidPtr()}
ret.impl = b.InlineCall(pkg.rtFunc("Zeroinit"), ret, size).impl
}
ret.Type = prog.Pointer(elem)
return
}
// AllocU allocates uninitialized space for n*sizeof(elem) bytes.
func (b Builder) AllocU(elem Type, n ...int64) (ret Expr) {
prog := b.Prog
size := SizeOf(prog, elem, n...)
ret = b.InlineCall(b.Pkg.rtFunc("AllocU"), size)
ret.Type = prog.Pointer(elem)
return
}
// AllocZ allocates zero initialized space for n bytes.
func (b Builder) AllocZ(n Expr) (ret Expr) {
return b.InlineCall(b.Pkg.rtFunc("AllocZ"), n)
}
// Alloca allocates uninitialized space for n bytes.
func (b Builder) Alloca(n Expr) (ret Expr) {
if debugInstr {
log.Printf("Alloca %v\n", n.impl)
}
prog := b.Prog
telem := prog.tyInt8()
ret.impl = llvm.CreateArrayAlloca(b.impl, telem, n.impl)
ret.Type = prog.VoidPtr()
return
}
// AllocaCStr allocates space for copy it from a Go string.
func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
if debugInstr {
log.Printf("AllocaCStr %v\n", gostr.impl)
}
n := b.StringLen(gostr)
n1 := b.BinOp(token.ADD, n, b.Prog.Val(1))
cstr := b.Alloca(n1)
return b.InlineCall(b.Pkg.rtFunc("CStrCopy"), cstr, gostr)
}
/*
// ArrayAlloca reserves space for an array of n elements of type telem.
func (b Builder) ArrayAlloca(telem Type, n Expr) (ret Expr) {
if debugInstr {
log.Printf("ArrayAlloca %v, %v\n", telem.t, n.impl)
}
ret.impl = llvm.CreateArrayAlloca(b.impl, telem.ll, n.impl)
ret.Type = b.Prog.Pointer(telem)
return
}
*/
// ArrayAlloc allocates zero initialized space for an array of n elements of type telem.
func (b Builder) ArrayAlloc(telem Type, n Expr) (ret Expr) {
prog := b.Prog
elemSize := SizeOf(prog, telem)
size := b.BinOp(token.MUL, n, elemSize)
ret.impl = b.AllocZ(size).impl
ret.Type = prog.Pointer(telem)
return
}
// -----------------------------------------------------------------------------
// The ChangeType instruction applies to X a value-preserving type // The ChangeType instruction applies to X a value-preserving type
// change to Type(). // change to Type().
// //
@@ -718,7 +503,6 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) {
typ := t.raw.Type typ := t.raw.Type
switch typ.(type) { switch typ.(type) {
default: default:
// TODO(xsw): remove instr name
ret.impl = llvm.CreateBitCast(b.impl, x.impl, t.ll) ret.impl = llvm.CreateBitCast(b.impl, x.impl, t.ll)
ret.Type = b.Prog.rawType(typ) ret.Type = b.Prog.rawType(typ)
return return
@@ -876,65 +660,6 @@ func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// TODO(xsw): make inline call
func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
return b.Call(fn, args...)
}
// The Call instruction represents a function call.
//
// The Call instruction yields the function result if there is exactly
// one. Otherwise it returns a tuple, the components of which are
// accessed via Extract.
//
// Example printed form:
//
// t2 = println(t0, t1)
// t4 = t3()
func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
if debugInstr {
var b bytes.Buffer
name := fn.impl.Name()
if name == "" {
name = "closure"
}
fmt.Fprint(&b, "Call ", fn.kind, " ", fn.raw.Type, " ", name)
sep := ": "
for _, arg := range args {
fmt.Fprint(&b, sep, arg.impl)
sep = ", "
}
log.Println(b.String())
}
var kind = fn.kind
if kind == vkPyFuncRef {
return b.pyCall(fn, args)
}
var ll llvm.Type
var data Expr
var sig *types.Signature
var prog = b.Prog
var raw = fn.raw.Type
switch kind {
case vkClosure:
data = b.Field(fn, 1)
fn = b.Field(fn, 0)
raw = fn.raw.Type
fallthrough
case vkFuncPtr:
sig = raw.(*types.Signature)
ll = prog.FuncDecl(sig, InC).ll
case vkFuncDecl:
sig = raw.(*types.Signature)
ll = fn.ll
default:
log.Panicf("unreachable: %d(%T)\n", kind, raw)
}
ret.Type = prog.retType(sig)
ret.impl = llvm.CreateCall(b.impl, ll, fn.impl, llvmParamsEx(data, args, sig.Params(), b))
return
}
// The Range instruction yields an iterator over the domain and range // The Range instruction yields an iterator over the domain and range
// of X, which must be a string or map. // of X, which must be a string or map.
// //
@@ -980,6 +705,123 @@ func (b Builder) Next(iter Expr, isString bool) (ret Expr) {
panic("todo") panic("todo")
} }
// -----------------------------------------------------------------------------
// The MakeClosure instruction yields a closure value whose code is
// Fn and whose free variables' values are supplied by Bindings.
//
// Type() returns a (possibly named) *types.Signature.
//
// Example printed form:
//
// t0 = make closure anon@1.2 [x y z]
// t1 = make closure bound$(main.I).add [i]
func (b Builder) MakeClosure(fn Expr, bindings []Expr) Expr {
if debugInstr {
log.Printf("MakeClosure %v, %v\n", fn, bindings)
}
prog := b.Prog
tfn := fn.Type
sig := tfn.raw.Type.(*types.Signature)
tctx := sig.Params().At(0).Type().Underlying().(*types.Pointer).Elem().(*types.Struct)
flds := llvmFields(bindings, tctx, b)
data := b.aggregateAllocU(prog.rawType(tctx), flds...)
return b.aggregateValue(prog.Closure(tfn), fn.impl, data)
}
// -----------------------------------------------------------------------------
// TODO(xsw): make inline call
func (b Builder) InlineCall(fn Expr, args ...Expr) (ret Expr) {
return b.Call(fn, args...)
}
// The Call instruction represents a function call.
//
// The Call instruction yields the function result if there is exactly
// one. Otherwise it returns a tuple, the components of which are
// accessed via Extract.
//
// Example printed form:
//
// t2 = println(t0, t1)
// t4 = t3()
func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
if debugInstr {
logCall("Call", fn, args)
}
var kind = fn.kind
if kind == vkPyFuncRef {
return b.pyCall(fn, args)
}
var ll llvm.Type
var data Expr
var sig *types.Signature
var raw = fn.raw.Type
switch kind {
case vkClosure:
data = b.Field(fn, 1)
fn = b.Field(fn, 0)
raw = fn.raw.Type
fallthrough
case vkFuncPtr:
sig = raw.(*types.Signature)
ll = b.Prog.FuncDecl(sig, InC).ll
case vkFuncDecl:
sig = raw.(*types.Signature)
ll = fn.ll
case vkBuiltin:
bi := raw.(*builtinTy)
return b.BuiltinCall(bi.name, args...)
default:
log.Panicf("unreachable: %d(%T)\n", kind, raw)
}
ret.Type = b.Prog.retType(sig)
ret.impl = llvm.CreateCall(b.impl, ll, fn.impl, llvmParamsEx(data, args, sig.Params(), b))
return
}
func logCall(da string, fn Expr, args []Expr) {
if fn.kind == vkBuiltin {
return
}
var b bytes.Buffer
name := fn.impl.Name()
if name == "" {
name = "closure"
}
fmt.Fprint(&b, da, " ", fn.kind, " ", fn.raw.Type, " ", name)
sep := ": "
for _, arg := range args {
fmt.Fprint(&b, sep, arg.impl)
sep = ", "
}
log.Println(b.String())
}
type DoAction int
const (
Call DoAction = iota
Go
DeferAlways // defer statement executes always
DeferInCond // defer statement executes in a conditional block
DeferInLoop // defer statement executes in a loop block
)
// Do call a function with an action.
func (b Builder) Do(da DoAction, fn Expr, args ...Expr) (ret Expr) {
switch da {
case Call:
return b.Call(fn, args...)
case Go:
b.Go(fn, args...)
default:
b.Defer(da, fn, args...)
}
return
}
// A Builtin represents a specific use of a built-in function, e.g. len. // A Builtin represents a specific use of a built-in function, e.g. len.
// //
// Builtins are immutable values. Builtins do not have addresses. // Builtins are immutable values. Builtins do not have addresses.
@@ -988,6 +830,11 @@ func (b Builder) Next(iter Expr, isString bool) (ret Expr) {
// Go spec (excluding "make" and "new"). // Go spec (excluding "make" and "new").
func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) { func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
switch fn { switch fn {
case "String": // unsafe.String
return b.unsafeString(args[0].impl, args[1].impl)
case "Slice": // unsafe.Slice
size := args[1].impl
return b.unsafeSlice(args[0], size, size)
case "len": case "len":
if len(args) == 1 { if len(args) == 1 {
arg := args[0] arg := args[0]
@@ -1027,8 +874,6 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
} }
} }
} }
case "print", "println":
return b.PrintEx(fn == "println", args...)
case "copy": case "copy":
if len(args) == 2 { if len(args) == 2 {
dst := args[0] dst := args[0]
@@ -1044,11 +889,10 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
} }
} }
} }
case "String": // unsafe.String //case "recover":
return b.unsafeString(args[0].impl, args[1].impl) // return b.Recover()
case "Slice": // unsafe.Slice case "print", "println":
size := args[1].impl return b.PrintEx(fn == "println", args...)
return b.unsafeSlice(args[0], size, size)
} }
panic("todo: " + fn) panic("todo: " + fn)
} }
@@ -1111,3 +955,62 @@ func (b Builder) PrintEx(ln bool, args ...Expr) (ret Expr) {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
func checkExpr(v Expr, t types.Type, b Builder) Expr {
if t, ok := t.(*types.Struct); ok && isClosure(t) {
if v.kind != vkClosure {
return b.Pkg.closureStub(b, t, v)
}
}
return v
}
func needsNegativeCheck(x Expr) bool {
if x.kind == vkSigned {
if rv := x.impl.IsAConstantInt(); !rv.IsNil() && rv.SExtValue() >= 0 {
return false
}
return true
}
return false
}
func llvmParamsEx(data Expr, vals []Expr, params *types.Tuple, b Builder) (ret []llvm.Value) {
if data.IsNil() {
return llvmParams(0, vals, params, b)
}
ret = llvmParams(1, vals, params, b)
ret[0] = data.impl
return
}
func llvmParams(base int, vals []Expr, params *types.Tuple, b Builder) (ret []llvm.Value) {
n := params.Len()
if n > 0 {
ret = make([]llvm.Value, len(vals)+base)
for idx, v := range vals {
i := base + idx
if i < n {
v = checkExpr(v, params.At(i).Type(), b)
}
ret[i] = v.impl
}
}
return
}
func llvmFields(vals []Expr, t *types.Struct, b Builder) (ret []llvm.Value) {
n := t.NumFields()
if n > 0 {
ret = make([]llvm.Value, len(vals))
for i, v := range vals {
if i < n {
v = checkExpr(v, t.Field(i).Type(), b)
}
ret[i] = v.impl
}
}
return
}
// -----------------------------------------------------------------------------

182
ssa/goroutine.go Normal file
View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ssa
import (
"go/token"
"go/types"
"strconv"
"github.com/goplus/llvm"
)
// -----------------------------------------------------------------------------
// func(c.Pointer) c.Pointer
func (p Program) tyRoutine() *types.Signature {
if p.routineTy == nil {
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramPtr)
p.routineTy = types.NewSignatureType(nil, nil, nil, params, params, false)
}
return p.routineTy
}
// func(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
func (p Program) tyPthreadCreate() *types.Signature {
if p.createThdTy == nil {
paramPPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtrPtr().raw.Type)
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
paramRoutine := types.NewParam(token.NoPos, nil, "", p.tyRoutine())
paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type)
params := types.NewTuple(paramPPtr, paramPtr, paramRoutine, paramPtr)
results := types.NewTuple(paramCInt)
p.createThdTy = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.createThdTy
}
func (b Builder) pthreadCreate(pp, attr, routine, arg Expr) Expr {
fn := b.Pkg.cFunc("pthread_create", b.Prog.tyPthreadCreate())
return b.Call(fn, pp, attr, routine, arg)
}
// -----------------------------------------------------------------------------
// The Go instruction creates a new goroutine and calls the specified
// function within it.
//
// Example printed form:
//
// go println(t0, t1)
// go t3()
// go invoke t5.Println(...t6)
func (b Builder) Go(fn Expr, args ...Expr) {
if debugInstr {
logCall("Go", fn, args)
}
prog := b.Prog
pkg := b.Pkg
typs := make([]Type, len(args)+1)
flds := make([]llvm.Value, len(args)+1)
typs[0] = fn.Type
flds[0] = fn.impl
for i, arg := range args {
typs[i+1] = arg.Type
flds[i+1] = arg.impl
}
t := prog.Struct(typs...)
voidPtr := prog.VoidPtr()
data := Expr{b.aggregateMalloc(t, flds...), voidPtr}
size := prog.SizeOf(voidPtr)
pthd := b.Alloca(prog.IntVal(uint64(size), prog.Uintptr()))
b.pthreadCreate(pthd, prog.Null(voidPtr), pkg.routine(t, len(args)), data)
}
func (p Package) routineName() string {
p.iRoutine++
return p.Path() + "._llgo_routine$" + strconv.Itoa(p.iRoutine)
}
func (p Package) routine(t Type, n int) Expr {
prog := p.Prog
routine := p.NewFunc(p.routineName(), prog.tyRoutine(), InC)
b := routine.MakeBody(1)
param := routine.Param(0)
data := Expr{llvm.CreateLoad(b.impl, t.ll, param.impl), t}
args := make([]Expr, n)
fn := b.getField(data, 0)
for i := 0; i < n; i++ {
args[i] = b.getField(data, i+1)
}
b.Call(fn, args...)
b.free(param)
b.Return(prog.Null(prog.VoidPtr()))
return routine.Expr
}
// -----------------------------------------------------------------------------
// func(c.Pointer)
func (p Program) tyDestruct() *types.Signature {
if p.destructTy == nil {
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramPtr)
p.destructTy = types.NewSignatureType(nil, nil, nil, params, nil, false)
}
return p.destructTy
}
// func(*c.Int, func(c.Pointer)) c.Int
func (p Program) tyPthreadKeyCreate() *types.Signature {
if p.createKeyTy == nil {
cint := p.CInt()
cintPtr := p.Pointer(cint)
paramCintPtr := types.NewParam(token.NoPos, nil, "", cintPtr.raw.Type)
paramDestruct := types.NewParam(token.NoPos, nil, "", p.tyDestruct())
paramCInt := types.NewParam(token.NoPos, nil, "", cint.raw.Type)
params := types.NewTuple(paramCintPtr, paramDestruct)
results := types.NewTuple(paramCInt)
p.createKeyTy = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.createKeyTy
}
func (b Builder) pthreadKeyCreate(key, destruct Expr) Expr {
fn := b.Pkg.cFunc("pthread_key_create", b.Prog.tyPthreadKeyCreate())
return b.Call(fn, key, destruct)
}
// -----------------------------------------------------------------------------
// func(c.Int) c.Pointer
func (p Program) tyPthreadGetspecific() *types.Signature {
if p.getSpecTy == nil {
paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type)
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramCInt)
results := types.NewTuple(paramPtr)
p.getSpecTy = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.getSpecTy
}
// func(c.Int, c.Pointer) c.Int
func (p Program) tyPthreadSetspecific() *types.Signature {
if p.setSpecTy == nil {
paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type)
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramCInt, paramPtr)
results := types.NewTuple(paramCInt)
p.setSpecTy = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.setSpecTy
}
func (b Builder) pthreadGetspecific(key Expr) Expr {
fn := b.Pkg.cFunc("pthread_getspecific", b.Prog.tyPthreadGetspecific())
return b.Call(fn, key)
}
func (b Builder) pthreadSetspecific(key, val Expr) Expr {
fn := b.Pkg.cFunc("pthread_setspecific", b.Prog.tyPthreadSetspecific())
return b.Call(fn, key, val)
}
// -----------------------------------------------------------------------------

View File

@@ -69,11 +69,12 @@ func (b Builder) Imethod(intf Expr, method *types.Func) Expr {
rawIntf := intf.raw.Type.Underlying().(*types.Interface) rawIntf := intf.raw.Type.Underlying().(*types.Interface)
tclosure := prog.Type(method.Type(), InGo) tclosure := prog.Type(method.Type(), InGo)
i := iMethodOf(rawIntf, method.Name()) i := iMethodOf(rawIntf, method.Name())
data := b.InlineCall(b.Pkg.rtFunc("IfacePtrData"), intf)
impl := intf.impl impl := intf.impl
itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()} itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()}
pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int())) pfn := b.Advance(itab, prog.IntVal(uint64(i+3), prog.Int()))
fn := b.Load(pfn) fn := b.Load(pfn)
ret := b.aggregateValue(tclosure, fn.impl, b.faceData(impl)) ret := b.aggregateValue(tclosure, fn.impl, data.impl)
return ret return ret
} }
@@ -125,10 +126,16 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
default: default:
panic("todo") panic("todo")
} }
// abi.Type.Kind_ |= abi.KindDirectIface
pkind := b.FieldAddr(tabi, 6)
b.Store(pkind, b.BinOp(token.OR, b.Load(pkind), Expr{prog.IntVal(kindDirectIface, prog.Byte()).impl, prog.Byte()}))
data := llvm.CreateIntToPtr(b.impl, u, prog.tyVoidPtr()) data := llvm.CreateIntToPtr(b.impl, u, prog.tyVoidPtr())
return Expr{b.unsafeInterface(rawIntf, tabi, data), tinter} return Expr{b.unsafeInterface(rawIntf, tabi, data), tinter}
} }
// abi.KindDirectIface
const kindDirectIface = 1 << 5
func (b Builder) valFromData(typ Type, data llvm.Value) Expr { func (b Builder) valFromData(typ Type, data llvm.Value) Expr {
prog := b.Prog prog := b.Prog
kind, real, lvl := abi.DataKindOf(typ.raw.Type, 0, prog.is32Bits) kind, real, lvl := abi.DataKindOf(typ.raw.Type, 0, prog.is32Bits)
@@ -262,6 +269,25 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
return b.valFromData(assertedTyp, b.faceData(x.impl)) return b.valFromData(assertedTyp, b.faceData(x.impl))
} }
// ChangeInterface constructs a value of one interface type from a
// value of another interface type known to be assignable to it.
// This operation cannot fail.
//
// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
// instruction arose from an explicit e.(T) operation; or token.NoPos
// otherwise.
//
// Example printed form:
//
// t1 = change interface interface{} <- I (t0)
func (b Builder) ChangeInterface(typ Type, x Expr) (ret Expr) {
rawIntf := typ.raw.Type.Underlying().(*types.Interface)
tabi := b.faceAbiType(x)
data := b.faceData(x.impl)
return Expr{b.unsafeInterface(rawIntf, tabi, data), typ}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/* /*
@@ -284,7 +310,7 @@ func (b Builder) faceItab(x llvm.Value) llvm.Value {
func (b Builder) faceAbiType(x Expr) Expr { func (b Builder) faceAbiType(x Expr) Expr {
if x.kind == vkIface { if x.kind == vkIface {
panic("todo") return b.InlineCall(b.Pkg.rtFunc("IfaceType"), x)
} }
typ := llvm.CreateExtractValue(b.impl, x.impl, 0) typ := llvm.CreateExtractValue(b.impl, x.impl, 0)
return Expr{typ, b.Prog.AbiTypePtr()} return Expr{typ, b.Prog.AbiTypePtr()}

243
ssa/memory.go Normal file
View File

@@ -0,0 +1,243 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ssa
import (
"go/token"
"go/types"
"log"
"github.com/goplus/llvm"
)
// -----------------------------------------------------------------------------
// Advance returns the pointer ptr advanced by offset.
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
if debugInstr {
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
}
var elem llvm.Type
var prog = b.Prog
switch t := ptr.raw.Type.(type) {
case *types.Basic: // void
elem = prog.tyInt8()
default:
elem = prog.rawType(t.(*types.Pointer).Elem()).ll
}
ret := llvm.CreateGEP(b.impl, elem, ptr.impl, []llvm.Value{offset.impl})
return Expr{ret, ptr.Type}
}
// Load returns the value at the pointer ptr.
func (b Builder) Load(ptr Expr) Expr {
if debugInstr {
log.Printf("Load %v\n", ptr.impl)
}
if ptr.kind == vkPyVarRef {
return b.pyLoad(ptr)
}
telem := b.Prog.Elem(ptr.Type)
return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem}
}
// Store stores val at the pointer ptr.
func (b Builder) Store(ptr, val Expr) Builder {
raw := ptr.raw.Type
if debugInstr {
log.Printf("Store %v, %v, %v\n", raw, ptr.impl, val.impl)
}
val = checkExpr(val, raw.(*types.Pointer).Elem(), b)
b.impl.CreateStore(val.impl, ptr.impl)
return b
}
func (b Builder) aggregateAllocU(t Type, flds ...llvm.Value) llvm.Value {
prog := b.Prog
size := prog.SizeOf(t)
ptr := b.allocUninited(prog.IntVal(size, prog.Uintptr())).impl
aggregateInit(b.impl, ptr, t.ll, flds...)
return ptr
}
func (b Builder) aggregateAlloca(t Type, flds ...llvm.Value) llvm.Value {
prog := b.Prog
size := prog.SizeOf(t)
ptr := b.Alloca(prog.IntVal(size, prog.Uintptr())).impl
aggregateInit(b.impl, ptr, t.ll, flds...)
return ptr
}
func (b Builder) aggregateMalloc(t Type, flds ...llvm.Value) llvm.Value {
prog := b.Prog
size := prog.SizeOf(t)
ptr := b.malloc(prog.IntVal(size, prog.Uintptr())).impl
aggregateInit(b.impl, ptr, t.ll, flds...)
return ptr
}
// aggregateValue yields the value of the aggregate X with the fields
func (b Builder) aggregateValue(t Type, flds ...llvm.Value) Expr {
return Expr{aggregateValue(b.impl, t.ll, flds...), t}
}
func aggregateValue(b llvm.Builder, tll llvm.Type, flds ...llvm.Value) llvm.Value {
ptr := llvm.CreateAlloca(b, tll)
aggregateInit(b, ptr, tll, flds...)
return llvm.CreateLoad(b, tll, ptr)
}
func aggregateInit(b llvm.Builder, ptr llvm.Value, tll llvm.Type, flds ...llvm.Value) {
for i, fld := range flds {
b.CreateStore(fld, llvm.CreateStructGEP(b, tll, ptr, i))
}
}
// -----------------------------------------------------------------------------
// The Alloc instruction reserves space for a variable of the given type,
// zero-initializes it, and yields its address.
//
// If heap is false, Alloc zero-initializes the same local variable in
// the call frame and returns its address; in this case the Alloc must
// be present in Function.Locals. We call this a "local" alloc.
//
// If heap is true, Alloc allocates a new zero-initialized variable
// each time the instruction is executed. We call this a "new" alloc.
//
// When Alloc is applied to a channel, map or slice type, it returns
// the address of an uninitialized (nil) reference of that kind; store
// the result of MakeSlice, MakeMap or MakeChan in that location to
// instantiate these types.
//
// Example printed form:
//
// t0 = local int
// t1 = new int
func (b Builder) Alloc(elem Type, heap bool) (ret Expr) {
if debugInstr {
log.Printf("Alloc %v, %v\n", elem.RawType(), heap)
}
prog := b.Prog
pkg := b.Pkg
size := SizeOf(prog, elem)
if heap {
ret = b.InlineCall(pkg.rtFunc("AllocZ"), size)
} else {
ret = Expr{llvm.CreateAlloca(b.impl, elem.ll), prog.VoidPtr()}
ret.impl = b.InlineCall(pkg.rtFunc("Zeroinit"), ret, size).impl
}
ret.Type = prog.Pointer(elem)
return
}
// AllocU allocates uninitialized space for n*sizeof(elem) bytes.
func (b Builder) AllocU(elem Type, n ...int64) (ret Expr) {
prog := b.Prog
size := SizeOf(prog, elem, n...)
return Expr{b.allocUninited(size).impl, prog.Pointer(elem)}
}
func (b Builder) allocUninited(size Expr) (ret Expr) {
return b.InlineCall(b.Pkg.rtFunc("AllocU"), size)
}
// AllocZ allocates zero initialized space for n bytes.
func (b Builder) AllocZ(n Expr) (ret Expr) {
return b.InlineCall(b.Pkg.rtFunc("AllocZ"), n)
}
// Alloca allocates uninitialized space for n bytes.
func (b Builder) Alloca(n Expr) (ret Expr) {
if debugInstr {
log.Printf("Alloca %v\n", n.impl)
}
prog := b.Prog
telem := prog.tyInt8()
ret.impl = llvm.CreateArrayAlloca(b.impl, telem, n.impl)
ret.Type = prog.VoidPtr()
return
}
// AllocaCStr allocates space for copy it from a Go string.
func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
if debugInstr {
log.Printf("AllocaCStr %v\n", gostr.impl)
}
n := b.StringLen(gostr)
n1 := b.BinOp(token.ADD, n, b.Prog.Val(1))
cstr := b.Alloca(n1)
return b.InlineCall(b.Pkg.rtFunc("CStrCopy"), cstr, gostr)
}
// -----------------------------------------------------------------------------
func (p Program) tyMalloc() *types.Signature {
if p.mallocTy == nil {
paramSize := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramSize)
results := types.NewTuple(paramPtr)
p.mallocTy = types.NewSignatureType(nil, nil, nil, params, results, false)
}
return p.mallocTy
}
func (p Program) tyFree() *types.Signature {
if p.freeTy == nil {
paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type)
params := types.NewTuple(paramPtr)
p.freeTy = types.NewSignatureType(nil, nil, nil, params, nil, false)
}
return p.freeTy
}
func (b Builder) malloc(size Expr) Expr {
fn := b.Pkg.cFunc("malloc", b.Prog.tyMalloc())
return b.Call(fn, size)
}
func (b Builder) free(ptr Expr) Expr {
fn := b.Pkg.cFunc("free", b.Prog.tyFree())
return b.Call(fn, ptr)
}
// -----------------------------------------------------------------------------
/*
// ArrayAlloca reserves space for an array of n elements of type telem.
func (b Builder) ArrayAlloca(telem Type, n Expr) (ret Expr) {
if debugInstr {
log.Printf("ArrayAlloca %v, %v\n", telem.t, n.impl)
}
ret.impl = llvm.CreateArrayAlloca(b.impl, telem.ll, n.impl)
ret.Type = b.Prog.Pointer(telem)
return
}
*/
// ArrayAlloc allocates zero initialized space for an array of n elements of type telem.
func (b Builder) ArrayAlloc(telem Type, n Expr) (ret Expr) {
prog := b.Prog
elemSize := SizeOf(prog, telem)
size := b.BinOp(token.MUL, n, elemSize)
ret.impl = b.AllocZ(size).impl
ret.Type = prog.Pointer(telem)
return
}
// -----------------------------------------------------------------------------

View File

@@ -20,6 +20,7 @@ import (
"go/token" "go/token"
"go/types" "go/types"
"strconv" "strconv"
"unsafe"
"github.com/goplus/llgo/ssa/abi" "github.com/goplus/llgo/ssa/abi"
"github.com/goplus/llvm" "github.com/goplus/llvm"
@@ -112,7 +113,8 @@ type aProgram struct {
target *Target target *Target
td llvm.TargetData td llvm.TargetData
// tm llvm.TargetMachine // tm llvm.TargetMachine
named map[string]llvm.Type named map[string]llvm.Type
fnnamed map[string]int
intType llvm.Type intType llvm.Type
int1Type llvm.Type int1Type llvm.Type
@@ -129,13 +131,14 @@ type aProgram struct {
rtSliceTy llvm.Type rtSliceTy llvm.Type
rtMapTy llvm.Type rtMapTy llvm.Type
anyTy Type anyTy Type
voidTy Type voidTy Type
voidPtr Type voidPtr Type
voidPPtr Type voidPPtr Type
boolTy Type boolTy Type
cstrTy Type cstrTy Type
cintTy Type cintTy Type
//cintPtr Type
stringTy Type stringTy Type
uintptrTy Type uintptrTy Type
intTy Type intTy Type
@@ -147,20 +150,36 @@ type aProgram struct {
u32Ty Type u32Ty Type
i64Ty Type i64Ty Type
u64Ty Type u64Ty Type
pyObjPtr Type pyObjPtr Type
pyObjPPtr Type pyObjPPtr Type
abiTyptr Type
abiTypptr Type
pyImpTy *types.Signature abiTyPtr Type
pyNewList *types.Signature abiTyPPtr Type
pyListSetI *types.Signature deferTy Type
callArgs *types.Signature deferPtr Type
callNoArgs *types.Signature deferPPtr Type
callOneArg *types.Signature
callFOArgs *types.Signature pyImpTy *types.Signature
loadPyModS *types.Signature pyNewList *types.Signature
getAttrStr *types.Signature pyListSetI *types.Signature
floatFromDbl *types.Signature
callNoArgs *types.Signature
callOneArg *types.Signature
callFOArgs *types.Signature
loadPyModS *types.Signature
getAttrStr *types.Signature
mallocTy *types.Signature
freeTy *types.Signature
createKeyTy *types.Signature
createThdTy *types.Signature
getSpecTy *types.Signature
setSpecTy *types.Signature
routineTy *types.Signature
destructTy *types.Signature
//deferFnTy *types.Signature
paramObjPtr_ *types.Var paramObjPtr_ *types.Var
@@ -195,7 +214,7 @@ func NewProgram(target *Target) Program {
return &aProgram{ return &aProgram{
ctx: ctx, gocvt: newGoTypes(), ctx: ctx, gocvt: newGoTypes(),
target: target, td: td, is32Bits: is32Bits, target: target, td: td, is32Bits: is32Bits,
ptrSize: td.PointerSize(), named: make(map[string]llvm.Type), ptrSize: td.PointerSize(), named: make(map[string]llvm.Type), fnnamed: make(map[string]int),
} }
} }
@@ -316,30 +335,44 @@ func (p Program) Struct(typs ...Type) Type {
return p.rawType(types.NewStruct(els, nil)) return p.rawType(types.NewStruct(els, nil))
} }
/* // Defer returns runtime.Defer type.
// Eface returns the empty interface type. func (p Program) Defer() Type {
func (p Program) Eface() Type { if p.deferTy == nil {
if p.efaceTy == nil { p.deferTy = p.rtType("Defer")
p.efaceTy = p.rawType(tyAny)
} }
return p.efaceTy return p.deferTy
} }
*/
// AbiTypePtr returns *abi.Type. // DeferPtr returns *runtime.Defer type.
func (p Program) DeferPtr() Type {
if p.deferPtr == nil {
p.deferPtr = p.Pointer(p.Defer())
}
return p.deferPtr
}
// DeferPtrPtr returns **runtime.Defer type.
func (p Program) DeferPtrPtr() Type {
if p.deferPPtr == nil {
p.deferPPtr = p.Pointer(p.DeferPtr())
}
return p.deferPPtr
}
// AbiTypePtr returns *abi.Type type.
func (p Program) AbiTypePtr() Type { func (p Program) AbiTypePtr() Type {
if p.abiTyptr == nil { if p.abiTyPtr == nil {
p.abiTyptr = p.rawType(types.NewPointer(p.rtNamed("Type"))) p.abiTyPtr = p.rawType(types.NewPointer(p.rtNamed("Type")))
} }
return p.abiTyptr return p.abiTyPtr
} }
// AbiTypePtrPtr returns **abi.Type. // AbiTypePtrPtr returns **abi.Type type.
func (p Program) AbiTypePtrPtr() Type { func (p Program) AbiTypePtrPtr() Type {
if p.abiTypptr == nil { if p.abiTyPPtr == nil {
p.abiTypptr = p.Pointer(p.AbiTypePtr()) p.abiTyPPtr = p.Pointer(p.AbiTypePtr())
} }
return p.abiTypptr return p.abiTyPPtr
} }
// PyObjectPtrPtr returns the **py.Object type. // PyObjectPtrPtr returns the **py.Object type.
@@ -403,7 +436,7 @@ func (p Program) String() Type {
return p.stringTy return p.stringTy
} }
// Any returns any type. // Any returns the any (empty interface) type.
func (p Program) Any() Type { func (p Program) Any() Type {
if p.anyTy == nil { if p.anyTy == nil {
p.anyTy = p.rawType(tyAny) p.anyTy = p.rawType(tyAny)
@@ -411,6 +444,23 @@ func (p Program) Any() Type {
return p.anyTy return p.anyTy
} }
/*
// Eface returns the empty interface type.
// It is equivalent to Any.
func (p Program) Eface() Type {
return p.Any()
}
// CIntPtr returns *c.Int type.
func (p Program) CIntPtr() Type {
if p.cintPtr == nil {
p.cintPtr = p.Pointer(p.CInt())
}
return p.cintPtr
}
*/
// CInt returns c.Int type.
func (p Program) CInt() Type { func (p Program) CInt() Type {
if p.cintTy == nil { // C.int if p.cintTy == nil { // C.int
p.cintTy = p.rawType(types.Typ[types.Int32]) // TODO(xsw): support 64-bit p.cintTy = p.rawType(types.Typ[types.Int32]) // TODO(xsw): support 64-bit
@@ -510,16 +560,18 @@ func (p Program) Uint64() Type {
// and unspecified other things too. // and unspecified other things too.
type aPackage struct { type aPackage struct {
mod llvm.Module mod llvm.Module
abi abi.Builder
Prog Program
vars map[string]Global vars map[string]Global
fns map[string]Function fns map[string]Function
stubs map[string]Function stubs map[string]Function
pyobjs map[string]PyObjRef pyobjs map[string]PyObjRef
pymods map[string]Global pymods map[string]Global
Prog Program afterb unsafe.Pointer
abi abi.Builder iRoutine int
abiTypes
} }
type Package = *aPackage type Package = *aPackage
@@ -531,6 +583,10 @@ func (p Package) rtFunc(fnName string) Expr {
return p.NewFunc(name, sig, InGo).Expr return p.NewFunc(name, sig, InGo).Expr
} }
func (p Package) cFunc(fullName string, sig *types.Signature) Expr {
return p.NewFunc(fullName, sig, InC).Expr
}
func (p Package) pyFunc(fullName string, sig *types.Signature) Expr { func (p Package) pyFunc(fullName string, sig *types.Signature) Expr {
p.Prog.NeedPyInit = true p.Prog.NeedPyInit = true
return p.NewFunc(fullName, sig, InC).Expr return p.NewFunc(fullName, sig, InC).Expr
@@ -581,14 +637,28 @@ func (p Package) String() string {
return p.mod.String() return p.mod.String()
} }
// -----------------------------------------------------------------------------
func (p Package) afterBuilder() Builder {
if p.afterb == nil {
fn := p.NewFunc(p.Path()+".init$after", NoArgsNoRet, InC)
fnb := fn.MakeBody(1)
p.afterb = unsafe.Pointer(fnb)
}
return Builder(p.afterb)
}
// AfterInit is called after the package is initialized (init all packages that depends on). // AfterInit is called after the package is initialized (init all packages that depends on).
func (p Package) AfterInit(b Builder, ret BasicBlock) { func (p Package) AfterInit(b Builder, ret BasicBlock) {
doAbiInit := p.hasAbiInit() p.deferInit()
doAfterb := p.afterb != nil
doPyLoadModSyms := p.pyHasModSyms() doPyLoadModSyms := p.pyHasModSyms()
if doAbiInit || doPyLoadModSyms { if doAfterb || doPyLoadModSyms {
b.SetBlockEx(ret, afterInit, false) b.SetBlockEx(ret, afterInit, false)
if doAbiInit { if doAfterb {
p.abiInit(b) afterb := Builder(p.afterb)
afterb.Return()
b.Call(afterb.Func.Expr)
} }
if doPyLoadModSyms { if doPyLoadModSyms {
p.pyLoadModSyms(b) p.pyLoadModSyms(b)
@@ -596,6 +666,8 @@ func (p Package) AfterInit(b Builder, ret BasicBlock) {
} }
} }
// -----------------------------------------------------------------------------
/* /*
type CodeGenFileType = llvm.CodeGenFileType type CodeGenFileType = llvm.CodeGenFileType
@@ -727,14 +799,14 @@ func (p Program) tyNewList() *types.Signature {
// func(float64) *Object // func(float64) *Object
func (p Program) tyFloatFromDouble() *types.Signature { func (p Program) tyFloatFromDouble() *types.Signature {
if p.callArgs == nil { if p.floatFromDbl == nil {
paramObjPtr := p.paramObjPtr() paramObjPtr := p.paramObjPtr()
paramFloat := types.NewParam(token.NoPos, nil, "", p.Float64().raw.Type) paramFloat := types.NewParam(token.NoPos, nil, "", p.Float64().raw.Type)
params := types.NewTuple(paramFloat) params := types.NewTuple(paramFloat)
results := types.NewTuple(paramObjPtr) results := types.NewTuple(paramObjPtr)
p.callArgs = types.NewSignatureType(nil, nil, nil, params, results, false) p.floatFromDbl = types.NewSignatureType(nil, nil, nil, params, results, false)
} }
return p.callArgs return p.floatFromDbl
} }
// func(*Object, ...) // func(*Object, ...)

View File

@@ -27,6 +27,15 @@ import (
"github.com/goplus/llvm" "github.com/goplus/llvm"
) )
func TestEndDefer(t *testing.T) {
prog := NewProgram(nil)
pkg := prog.NewPackage("foo", "foo")
fn := pkg.NewFunc("main", NoArgsNoRet, InC)
b := fn.MakeBody(1)
fn.defer_ = &aDefer{}
fn.endDefer(b)
}
func TestUnsafeString(t *testing.T) { func TestUnsafeString(t *testing.T) {
prog := NewProgram(nil) prog := NewProgram(nil)
prog.SetRuntime(func() *types.Package { prog.SetRuntime(func() *types.Package {
@@ -36,8 +45,7 @@ func TestUnsafeString(t *testing.T) {
return pkg return pkg
}) })
pkg := prog.NewPackage("foo", "foo") pkg := prog.NewPackage("foo", "foo")
sigMain := types.NewSignatureType(nil, nil, nil, nil, nil, false) b := pkg.NewFunc("main", NoArgsNoRet, InC).MakeBody(1)
b := pkg.NewFunc("main", sigMain, InC).MakeBody(1)
b.Println(b.BuiltinCall("String", b.CStr("hello"), prog.Val(5))) b.Println(b.BuiltinCall("String", b.CStr("hello"), prog.Val(5)))
b.Return() b.Return()
} }
@@ -109,8 +117,7 @@ func TestIndexType(t *testing.T) {
func TestCvtType(t *testing.T) { func TestCvtType(t *testing.T) {
gt := newGoTypes() gt := newGoTypes()
callback := types.NewSignatureType(nil, nil, nil, nil, nil, false) params := types.NewTuple(types.NewParam(0, nil, "", NoArgsNoRet))
params := types.NewTuple(types.NewParam(0, nil, "", callback))
sig := types.NewSignatureType(nil, nil, nil, params, nil, false) sig := types.NewSignatureType(nil, nil, nil, params, nil, false)
ret1 := gt.cvtFunc(sig, nil) ret1 := gt.cvtFunc(sig, nil)
if ret1 == sig { if ret1 == sig {
@@ -126,7 +133,9 @@ func TestCvtType(t *testing.T) {
func TestUserdefExpr(t *testing.T) { func TestUserdefExpr(t *testing.T) {
c := &pyVarTy{} c := &pyVarTy{}
b := &builtinTy{}
_ = c.String() _ = c.String()
_ = b.String()
test := func(a types.Type) { test := func(a types.Type) {
defer func() { defer func() {
if r := recover(); r == nil { if r := recover(); r == nil {
@@ -136,6 +145,7 @@ func TestUserdefExpr(t *testing.T) {
a.Underlying() a.Underlying()
} }
test(c) test(c)
test(b)
} }
func TestAny(t *testing.T) { func TestAny(t *testing.T) {
@@ -166,9 +176,8 @@ func TestPyFunc(t *testing.T) {
py.Scope().Insert(o) py.Scope().Insert(o)
prog.SetPython(py) prog.SetPython(py)
pkg := prog.NewPackage("bar", "foo/bar") pkg := prog.NewPackage("bar", "foo/bar")
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) a := pkg.PyNewFunc("a", NoArgsNoRet, false)
a := pkg.PyNewFunc("a", sig, false) if pkg.PyNewFunc("a", NoArgsNoRet, false) != a {
if pkg.PyNewFunc("a", sig, false) != a {
t.Fatal("NewPyFunc(a) failed") t.Fatal("NewPyFunc(a) failed")
} }
foo := pkg.PyNewModVar("foo", false) foo := pkg.PyNewModVar("foo", false)
@@ -184,6 +193,7 @@ func TestVar(t *testing.T) {
if pkg.NewVar("a", types.Typ[types.Int], InGo) != a { if pkg.NewVar("a", types.Typ[types.Int], InGo) != a {
t.Fatal("NewVar(a) failed") t.Fatal("NewVar(a) failed")
} }
pkg.NewVarEx("a", prog.Type(types.Typ[types.Int], InGo))
a.Init(prog.Val(100)) a.Init(prog.Val(100))
b := pkg.NewVar("b", types.Typ[types.Int], InGo) b := pkg.NewVar("b", types.Typ[types.Int], InGo)
b.Init(a.Expr) b.Init(a.Expr)
@@ -319,8 +329,7 @@ func TestFuncCall(t *testing.T) {
fn.MakeBody(1). fn.MakeBody(1).
Return(prog.Val(1)) Return(prog.Val(1))
sigMain := types.NewSignatureType(nil, nil, nil, nil, nil, false) b := pkg.NewFunc("main", NoArgsNoRet, InGo).MakeBody(1)
b := pkg.NewFunc("main", sigMain, InGo).MakeBody(1)
b.Call(fn.Expr, prog.Val(1), prog.Val(1.2)) b.Call(fn.Expr, prog.Val(1), prog.Val(1.2))
b.Return() b.Return()
@@ -369,8 +378,7 @@ _llgo_0:
func TestJump(t *testing.T) { func TestJump(t *testing.T) {
prog := NewProgram(nil) prog := NewProgram(nil)
pkg := prog.NewPackage("bar", "foo/bar") pkg := prog.NewPackage("bar", "foo/bar")
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) fn := pkg.NewFunc("loop", NoArgsNoRet, InGo)
fn := pkg.NewFunc("loop", sig, InGo)
b := fn.MakeBody(1) b := fn.MakeBody(1)
b.Jump(fn.Block(0)) b.Jump(fn.Block(0))
assertPkg(t, pkg, `; ModuleID = 'foo/bar' assertPkg(t, pkg, `; ModuleID = 'foo/bar'

View File

@@ -19,6 +19,7 @@ package ssa
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"go/token"
"go/types" "go/types"
"log" "log"
"strings" "strings"
@@ -61,6 +62,11 @@ type aBuilder struct {
// Builder represents a builder for creating instructions in a function. // Builder represents a builder for creating instructions in a function.
type Builder = *aBuilder type Builder = *aBuilder
// EndBuild ends the build process of a function.
func (b Builder) EndBuild() {
b.Func.endDefer(b)
}
// Dispose disposes of the builder. // Dispose disposes of the builder.
func (b Builder) Dispose() { func (b Builder) Dispose() {
b.impl.Dispose() b.impl.Dispose()
@@ -128,6 +134,179 @@ func notInit(instr llvm.Value) bool {
return true return true
} }
// -----------------------------------------------------------------------------
const (
deferKey = "__llgo_defer"
)
type aDefer struct {
nextBit int // next defer bit
key Expr // pthread TLS key
data Expr // pointer to runtime.Defer
bitsPtr Expr // pointer to defer bits
rundPtr Expr // pointer to RunDefers index
procBlk BasicBlock // deferProc block
stmts []func(bits Expr)
runsNext []BasicBlock // next blocks of RunDefers
}
/*
// func(uintptr)
func (p Program) tyDeferFunc() *types.Signature {
if p.deferFnTy == nil {
paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type)
params := types.NewTuple(paramUintptr)
p.deferFnTy = types.NewSignatureType(nil, nil, nil, params, nil, false)
}
return p.deferFnTy
}
*/
func (p Package) deferInit() {
keyVar := p.VarOf(deferKey)
if keyVar == nil {
return
}
prog := p.Prog
keyNil := prog.Null(prog.DeferPtrPtr())
keyVar.Init(keyNil)
keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
b := p.afterBuilder()
eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), keyNil)
b.IfThen(eq, func() {
b.pthreadKeyCreate(keyVar.Expr, prog.Null(prog.VoidPtr()))
})
}
func (p Package) newDeferKey() Global {
return p.NewVarEx(deferKey, p.Prog.DeferPtrPtr())
}
func (b Builder) deferKey() Expr {
return b.Load(b.Pkg.newDeferKey().Expr)
}
func (b Builder) getDefer() *aDefer {
self := b.Func
if self.defer_ == nil {
// TODO(xsw): if in pkg.init?
// 0: proc func(uintptr)
// 1: bits uintptr
// 2: link *Defer
// 3: rund int
b.SetBlockEx(b.blk, AtStart, false)
prog := b.Prog
key := b.deferKey()
deferfn := prog.Null(prog.VoidPtr())
zero := prog.Val(uintptr(0))
link := b.pthreadGetspecific(key)
ptr := b.aggregateAlloca(prog.Defer(), deferfn.impl, zero.impl, link.impl)
deferData := Expr{ptr, prog.DeferPtr()}
b.pthreadSetspecific(key, deferData)
b.SetBlockEx(b.blk, AtEnd, false)
self.defer_ = &aDefer{
key: key,
data: deferData,
bitsPtr: b.FieldAddr(deferData, 1),
rundPtr: b.FieldAddr(deferData, 3),
procBlk: self.MakeBlock(),
}
}
return self.defer_
}
// Defer emits a defer instruction.
func (b Builder) Defer(kind DoAction, fn Expr, args ...Expr) {
if debugInstr {
logCall("Defer", fn, args)
}
var prog Program
var nextbit Expr
var self = b.getDefer()
switch kind {
case DeferInCond:
prog = b.Prog
next := self.nextBit
self.nextBit++
bits := b.Load(self.bitsPtr)
nextbit = prog.Val(uintptr(1 << next))
b.Store(self.bitsPtr, b.BinOp(token.OR, bits, nextbit))
case DeferAlways:
// nothing to do
default:
panic("todo: DeferInLoop is not supported")
}
self.stmts = append(self.stmts, func(bits Expr) {
switch kind {
case DeferInCond:
zero := prog.Val(uintptr(0))
has := b.BinOp(token.NEQ, b.BinOp(token.AND, bits, nextbit), zero)
b.IfThen(has, func() {
b.Call(fn, args...)
})
case DeferAlways:
b.Call(fn, args...)
}
})
}
// RunDefers emits instructions to run deferred instructions.
func (b Builder) RunDefers() {
prog := b.Prog
self := b.getDefer()
b.Store(self.rundPtr, prog.Val(len(self.runsNext)))
b.Jump(self.procBlk)
blk := b.Func.MakeBlock()
self.runsNext = append(self.runsNext, blk)
b.SetBlockEx(blk, AtEnd, false)
b.blk.last = blk.last
}
func (p Function) endDefer(b Builder) {
self := p.defer_
if self == nil {
return
}
nexts := self.runsNext
n := len(nexts)
if n == 0 {
return
}
b.SetBlockEx(self.procBlk, AtEnd, true)
bits := b.Load(self.bitsPtr)
stmts := self.stmts
for i := len(stmts) - 1; i >= 0; i-- {
stmts[i](bits)
}
link := b.getField(b.Load(self.data), 2)
b.pthreadSetspecific(self.key, link)
prog := b.Prog
rund := b.Load(self.rundPtr)
sw := b.impl.CreateSwitch(rund.impl, nexts[0].first, n-1)
for i := 1; i < n; i++ {
sw.AddCase(prog.Val(i).impl, nexts[i].first)
}
}
// -----------------------------------------------------------------------------
/*
// Recover emits a recover instruction.
func (b Builder) Recover() (v Expr) {
if debugInstr {
log.Println("Recover")
}
prog := b.Prog
return prog.Zero(prog.Eface())
}
*/
// Panic emits a panic instruction. // Panic emits a panic instruction.
func (b Builder) Panic(v Expr) { func (b Builder) Panic(v Expr) {
if debugInstr { if debugInstr {
@@ -206,6 +385,17 @@ func (b Builder) If(cond Expr, thenb, elseb BasicBlock) {
b.impl.CreateCondBr(cond.impl, thenb.first, elseb.first) b.impl.CreateCondBr(cond.impl, thenb.first, elseb.first)
} }
// IfThen emits an if-then instruction.
func (b Builder) IfThen(cond Expr, then func()) {
blks := b.Func.MakeBlocks(2)
b.If(cond, blks[0], blks[1])
b.SetBlockEx(blks[0], AtEnd, false)
then()
b.Jump(blks[1])
b.SetBlockEx(blks[1], AtEnd, false)
b.blk.last = blks[1].last
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Phi represents a phi node. // Phi represents a phi node.

View File

@@ -44,6 +44,7 @@ const (
vkFuncDecl vkFuncDecl
vkFuncPtr vkFuncPtr
vkClosure vkClosure
vkBuiltin
vkPyFuncRef vkPyFuncRef
vkPyVarRef vkPyVarRef
vkTuple vkTuple
@@ -451,10 +452,20 @@ func (p Program) retType(raw *types.Signature) Type {
} }
} }
func (p Program) llvmNameOf(named *types.Named) (name string) {
name = NameOf(named)
if obj := named.Obj(); obj != nil && obj.Parent() != nil && obj.Parent() != obj.Pkg().Scope() {
index := p.fnnamed[name]
p.fnnamed[name] = index + 1
name += fmt.Sprintf("#%v", index)
}
return name
}
func (p Program) toNamed(raw *types.Named) Type { func (p Program) toNamed(raw *types.Named) Type {
switch t := raw.Underlying().(type) { switch t := raw.Underlying().(type) {
case *types.Struct: case *types.Struct:
name := NameOf(raw) name := p.llvmNameOf(raw)
return &aType{p.toLLVMNamedStruct(name, t), rawType{raw}, vkStruct} return &aType{p.toLLVMNamedStruct(name, t), rawType{raw}, vkStruct}
default: default:
typ := p.rawType(t) typ := p.rawType(t)

View File

@@ -26,14 +26,12 @@ import (
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type goTypes struct { type goTypes struct {
typs map[unsafe.Pointer]unsafe.Pointer typs map[unsafe.Pointer]unsafe.Pointer
named map[string]*types.Named
} }
func newGoTypes() goTypes { func newGoTypes() goTypes {
typs := make(map[unsafe.Pointer]unsafe.Pointer) typs := make(map[unsafe.Pointer]unsafe.Pointer)
named := make(map[string]*types.Named) return goTypes{typs}
return goTypes{typs, named}
} }
type Background int type Background int
@@ -118,14 +116,6 @@ func (p goTypes) cvtNamed(t *types.Named) (raw *types.Named, cvt bool) {
cvt = t != raw cvt = t != raw
return return
} }
defer func() {
p.typs[unsafe.Pointer(t)] = unsafe.Pointer(raw)
}()
id := t.String()
if named, ok := p.named[id]; ok {
return named, false
}
n := t.NumMethods() n := t.NumMethods()
methods := make([]*types.Func, n) methods := make([]*types.Func, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@@ -133,8 +123,7 @@ func (p goTypes) cvtNamed(t *types.Named) (raw *types.Named, cvt bool) {
methods[i] = m methods[i] = m
} }
named := types.NewNamed(t.Obj(), types.Typ[types.Int], methods) named := types.NewNamed(t.Obj(), types.Typ[types.Int], methods)
p.named[id] = named p.typs[unsafe.Pointer(t)] = unsafe.Pointer(named)
defer delete(p.named, id)
if tund, cvt := p.cvtType(t.Underlying()); cvt { if tund, cvt := p.cvtType(t.Underlying()); cvt {
named.SetUnderlying(tund) named.SetUnderlying(tund)
return named, true return named, true

View File

@@ -0,0 +1,26 @@
package check
import (
"errors"
"os/exec"
"runtime"
"strings"
)
func CheckLinkArgs(args string) error {
cmdArgs := strings.Split(args, " ")
cmd := exec.Command("clang")
nul := "/dev/null"
if runtime.GOOS == "windows" {
nul = "NUL"
}
cmd.Args = append(cmd.Args, cmdArgs...)
cmd.Args = append(cmd.Args, "-x", "c", "-o", nul, "-")
src := "int main() {return 0;}"
srcIn := strings.NewReader(src)
cmd.Stdin = srcIn
if out, err := cmd.CombinedOutput(); err != nil {
return errors.New(string(out))
}
return nil
}

32
xtool/env/env.go vendored Normal file
View File

@@ -0,0 +1,32 @@
package env
import (
"os"
"os/exec"
"regexp"
"runtime"
"strings"
)
func ExpandEnv(s string) string {
return expandEnvWithCmd(s)
}
func expandEnvWithCmd(s string) string {
re := regexp.MustCompile(`\$\(([^)]+)\)`)
expanded := re.ReplaceAllStringFunc(s, func(m string) string {
cmd := re.FindStringSubmatch(m)[1]
var out []byte
var err error
if runtime.GOOS == "windows" {
out, err = exec.Command("cmd", "/C", cmd).Output()
} else {
out, err = exec.Command("sh", "-c", cmd).Output()
}
if err != nil {
return ""
}
return strings.TrimSpace(string(out))
})
return os.Expand(expanded, os.Getenv)
}