Compare commits

..

120 Commits

Author SHA1 Message Date
xushiwei
1463ed4835 Merge pull request #155 from xushiwei/q
retract v0.8.0
2024-05-13 01:01:25 +08:00
xushiwei
b959de18d5 retract v0.8.0 2024-05-13 01:00:54 +08:00
xushiwei
edac3f73c2 Merge pull request #154 from xushiwei/q
compileBlock bugfix: pyMod
2024-05-13 00:52:57 +08:00
xushiwei
388b19eed5 _testpy: sort by module name 2024-05-13 00:50:58 +08:00
xushiwei
a337136389 _testpy 2024-05-13 00:45:41 +08:00
xushiwei
31d5a8ac10 compileBlock bugfix: pyMod 2024-05-13 00:41:42 +08:00
xushiwei
46527f56ce Update README.md 2024-05-13 00:10:28 +08:00
xushiwei
a575c17eca Merge pull request #153 from xushiwei/q
README
2024-05-13 00:05:46 +08:00
xushiwei
a6ea3b1e6f README 2024-05-12 23:59:24 +08:00
xushiwei
4d2ad842a4 Merge pull request #152 from xushiwei/q
llgo/ssa: LoadPyModSyms; SetBlockEx AfterInit
2024-05-12 23:47:51 +08:00
xushiwei
ce0f5f3797 testpy: os.Getcwd 2024-05-12 23:45:56 +08:00
xushiwei
9e0d22ac90 x/sqlite/llgo_autogen.lla 2024-05-12 23:43:51 +08:00
xushiwei
ddc2c56115 gentests 2024-05-12 23:42:16 +08:00
xushiwei
acfbe6902a FuncDecl bugfix: even in C, we need to add ctx for method 2024-05-12 23:37:12 +08:00
xushiwei
f7dfab481b vkPyFunc => vkPyFuncRef 2024-05-12 23:08:44 +08:00
xushiwei
23692430d5 llgo/ssa: SetBlockEx AfterInit 2024-05-12 22:51:25 +08:00
xushiwei
03fe594339 compileBlock: use LoadPyModSyms 2024-05-12 20:03:27 +08:00
xushiwei
45babef689 compileBlock refactor 2024-05-12 18:42:45 +08:00
xushiwei
9ac0450255 llgo/ssa: LoadPyModSyms 2024-05-12 18:27:23 +08:00
xushiwei
b1d55f657d Merge pull request #151 from xushiwei/q
llgo/ssa: StringData/StringLen; cl: TestPython; build: PkgLinkExtern
2024-05-12 15:59:58 +08:00
xushiwei
aac5e7b3cd TestFromTestdata: print 2024-05-12 15:56:05 +08:00
xushiwei
791634c377 conflict fix 2024-05-12 15:52:29 +08:00
xushiwei
090149eab6 llgo/ssa: StringData/StringLen 2024-05-12 15:42:50 +08:00
xushiwei
acecbf587d cl: TestPython; build: PkgLinkExtern 2024-05-12 13:05:15 +08:00
xushiwei
4ef46971d0 Merge pull request #150 from xushiwei/q
TestFromTestpymath; llgo/ssa: NewPyFunc add param doInit
2024-05-12 12:18:09 +08:00
xushiwei
2e3cc49782 llgo/ssa: NewPyFunc add param doInit 2024-05-12 12:14:26 +08:00
xushiwei
8a0189b079 TestFromTestpymath 2024-05-12 11:51:46 +08:00
xushiwei
0edd7f6df0 Merge pull request #149 from xushiwei/q
PyInit
2024-05-12 11:28:04 +08:00
xushiwei
0b058bc2e8 test NewPyModVar 2024-05-12 11:26:09 +08:00
xushiwei
f9ef9cab81 TestSetBlockEx 2024-05-12 11:22:55 +08:00
xushiwei
fbb2150d88 TestFromTestpy 2024-05-12 11:13:04 +08:00
xushiwei
0912f1f509 PyInit 2024-05-12 11:11:19 +08:00
xushiwei
64c13fa9ae llgo/ssa: NewPyFunc fix 2024-05-12 00:24:56 +08:00
xushiwei
2a5f9d9641 Merge pull request #148 from xushiwei/q
_pydemo: callpy; PyFunction
2024-05-11 23:55:32 +08:00
xushiwei
6c32fe87e6 TestSetPython, TestPyFunc 2024-05-11 23:53:08 +08:00
xushiwei
09e9cc99d3 Merge pull request #147 from visualfc/typenamed
fix types named recursive
2024-05-11 23:42:06 +08:00
xushiwei
94a7ee024a llgo/ssa: pyCall; demo: _pydemo/callpy 2024-05-11 23:38:21 +08:00
xushiwei
a2d7a8c978 llgo/ssa: PyFunction; NewPyFunc 2024-05-11 21:55:50 +08:00
xushiwei
15499ddc14 cl: _testpy/math 2024-05-11 15:12:42 +08:00
xushiwei
97cb312386 llgo/ssa: b.NewPyModVar, b.ImportPyMod, PyObjectPtr, PyObjectPtrPtr 2024-05-11 15:07:50 +08:00
visualfc
92827a1f04 fix types named recursive 2024-05-11 13:34:08 +08:00
xushiwei
00222c7808 compileBlock: support pyModule init 2024-05-11 11:33:35 +08:00
xushiwei
427d87be68 cl: initPyModule 2024-05-11 10:07:46 +08:00
xushiwei
2560a333b6 FloatAsDouble => Float64 2024-05-11 06:55:57 +08:00
xushiwei
c6b76db789 Merge pull request #146 from xushiwei/q
LLGoPackage: PkgPyModule
2024-05-11 06:47:25 +08:00
xushiwei
1414853fce LLGoPackage: PkgPyModule 2024-05-11 06:44:45 +08:00
xushiwei
cbe384a3be Merge pull request #145 from xushiwei/q
pyimport & deomo: callpy (todo)
2024-05-11 06:25:35 +08:00
xushiwei
cca46573ea pyimport & deomo: callpy (todo) 2024-05-11 06:23:05 +08:00
xushiwei
2589c23998 Merge pull request #144 from xushiwei/q
nmindex: query auto add _ prefix
2024-05-11 05:45:26 +08:00
xushiwei
29830865d9 nmindex: query auto add _ prefix 2024-05-11 05:43:27 +08:00
xushiwei
35dbc7b0b5 Merge pull request #143 from xushiwei/q
mv x/<tool> => xtool/<tool>
2024-05-11 05:29:38 +08:00
xushiwei
cd266213ce mv x/<tool> => xtool/<tool> 2024-05-11 05:27:38 +08:00
xushiwei
875eadeb19 Merge pull request #142 from xushiwei/q
py/README
2024-05-11 05:18:41 +08:00
xushiwei
67896c63a7 py/README 2024-05-11 05:18:17 +08:00
xushiwei
c643f734e9 Merge pull request #141 from xushiwei/q
move python demos to _pydemo
2024-05-11 05:05:07 +08:00
xushiwei
31d91f5e87 move python demos to _pydemo 2024-05-11 05:04:02 +08:00
xushiwei
2a92f1bc55 Merge pull request #140 from xushiwei/q
py demo: hellpy, clpy, callpy
2024-05-11 04:31:40 +08:00
xushiwei
d9db5528f5 py demo: hellpy, clpy, callpy 2024-05-11 04:26:41 +08:00
xushiwei
22a4ffb78b Merge pull request #139 from visualfc/iface
typeAssert: bool float string
2024-05-11 02:49:31 +08:00
visualfc
1fb37c37fe binop: token.AND_NOT 2024-05-10 21:34:54 +08:00
visualfc
aae663e5e5 binop: bool eql/neq 2024-05-10 21:06:19 +08:00
visualfc
e985eda857 typeAssert: bool float string 2024-05-10 13:46:39 +08:00
xushiwei
c9cc7ad9f7 Merge pull request #138 from xushiwei/q
demo: hellopy (python)
2024-05-09 20:34:09 +08:00
xushiwei
65f88cc64e demo: hellopy (python) 2024-05-09 20:33:39 +08:00
xushiwei
374ff92444 Merge pull request #136 from visualfc/vkfloat
ssa: bitcast float => iface.data
2024-05-09 17:45:57 +08:00
xushiwei
6d56a60d2b Merge pull request #137 from xushiwei/q
build: PkgLinkExtern
2024-05-09 17:43:44 +08:00
visualfc
75aea37ced ssa: bitcast float => iface.data 2024-05-09 16:01:30 +08:00
xushiwei
b133f70b6b build: PkgLinkExtern 2024-05-09 14:51:01 +08:00
xushiwei
093af00bbe build: canSkipToBuild 2024-05-09 14:19:31 +08:00
xushiwei
f1da2613be Merge pull request #135 from xushiwei/q
nmindex support python
2024-05-09 12:09:06 +08:00
xushiwei
1800c52c04 nm.IndexFile skip err 2024-05-09 12:08:19 +08:00
xushiwei
329f65a1ad nmindex support python 2024-05-09 12:03:21 +08:00
xushiwei
d4dd0c00ff Update README.md 2024-05-09 07:19:13 +08:00
xushiwei
d9a24f5ac2 Merge pull request #134 from xushiwei/q
cl: checkVArgs bugfix
2024-05-09 06:57:27 +08:00
xushiwei
a13d9a92bd TestErrAllocaCStr 2024-05-09 06:55:07 +08:00
xushiwei
2b70bb60a9 MakeInterface: remove delayExpr 2024-05-09 06:48:16 +08:00
xushiwei
48737e361a cl: checkVArgs bugfix 2024-05-09 06:19:09 +08:00
xushiwei
8e9f019f82 Merge pull request #133 from xushiwei/sqlite
demo: sqlite
2024-05-08 23:24:12 +08:00
xushiwei
f6a7815837 Merge pull request #132 from visualfc/convert
ssa.convert real numeric types
2024-05-08 23:22:32 +08:00
xushiwei
5016de56fe demo 2024-05-08 23:19:49 +08:00
xushiwei
879e4a0061 build: support multiple link files in a package 2024-05-08 18:57:14 +08:00
visualfc
6eaf21e5a6 ssa.convert real numeric types 2024-05-08 16:19:14 +08:00
xushiwei
b0b38c02b2 TestRecvTypeName 2024-05-08 15:01:50 +08:00
xushiwei
cd8e1f2080 importPkg: support method linkname 2024-05-08 14:48:34 +08:00
xushiwei
6cc58c194f recvTypeName 2024-05-08 14:19:33 +08:00
xushiwei
14cf646c47 cl: importPkg support linkname of method 2024-05-08 13:12:22 +08:00
xushiwei
d49197cbe9 llgen: support sqlite.ll 2024-05-08 11:49:19 +08:00
xushiwei
1687faa438 alias c.GoStringData = runtime.StringData 2024-05-08 11:14:14 +08:00
xushiwei
f0e3e556cf demo: sqlite 2024-05-08 10:43:10 +08:00
xushiwei
c9e8709490 Merge pull request #131 from xushiwei/sqlite
llgo/x/sqlite
2024-05-07 23:59:03 +08:00
xushiwei
52dcfaa452 llgo/x/sqlite 2024-05-07 23:51:12 +08:00
xushiwei
9b5a30896d Merge pull request #130 from xushiwei/sqlite
build: decodeLinkFile (support *.lla)
2024-05-07 21:20:59 +08:00
xushiwei
4e1450bbb5 cltest: decodeLinkFile 2024-05-07 21:18:04 +08:00
xushiwei
d478efe444 build: decodeLinkFile (support *.lla) 2024-05-07 21:06:47 +08:00
xushiwei
dacb662d99 replace .ll => .lla 2024-05-07 20:52:26 +08:00
xushiwei
f8cd76bd92 Merge pull request #129 from xushiwei/sqlite
sqlite version-3.45.3
2024-05-07 20:00:44 +08:00
xushiwei
6392fd41c6 Merge branch 'llama2' into sqlite 2024-05-07 19:58:20 +08:00
xushiwei
9d91152f01 submodule sqlite version-3.45.3 2024-05-07 19:57:39 +08:00
xushiwei
13972c932b Merge pull request #128 from xushiwei/llama2
demo: llama2-c
2024-05-07 18:47:59 +08:00
xushiwei
81ec9017fc llama2-c README 2024-05-07 18:44:51 +08:00
xushiwei
79b11b9f51 demo: llama2-c 2024-05-07 18:42:53 +08:00
xushiwei
d474a051fd Merge pull request #127 from xushiwei/llama2
cl: instr llgo.index/advance
2024-05-07 17:43:09 +08:00
xushiwei
073cac8530 TestErrInitLinkname 2024-05-07 17:39:12 +08:00
xushiwei
bc3dca45e7 importPkg refactor: don't depend token.Pos 2024-05-07 17:31:25 +08:00
xushiwei
ff36c3dfae llgo/ssa: Advance fix 2024-05-07 16:12:27 +08:00
xushiwei
5a5d86ccc3 cl: instr llgo.index/advance 2024-05-07 16:05:18 +08:00
xushiwei
942b1f5159 funcName: fix fn.Pkg == nil 2024-05-07 15:39:46 +08:00
xushiwei
c93fce87da cl: initLinkname support //llgo:link 2024-05-07 15:35:37 +08:00
xushiwei
1038b06510 Merge pull request #125 from visualfc/op
ssa.UnOp: sub/not/xor
2024-05-07 10:22:03 +08:00
xushiwei
f8de6022dc Merge pull request #126 from xushiwei/llama2
llama2 deps
2024-05-07 10:19:23 +08:00
xushiwei
a8ead2543d runtime: c.Argc, c.Argv, c.Getopt 2024-05-07 10:16:03 +08:00
xushiwei
db856c4391 Merge pull request #124 from goplus/dependabot/go_modules/golang.org/x/tools-0.21.0
build(deps): bump golang.org/x/tools from 0.20.0 to 0.21.0
2024-05-07 09:56:45 +08:00
visualfc
68949c28c8 ssa.UnOp: sub/not/xor 2024-05-07 09:55:51 +08:00
dependabot[bot]
cf67795ff4 build(deps): bump golang.org/x/tools from 0.20.0 to 0.21.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.20.0 to 0.21.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.20.0...v0.21.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-05-07 00:59:11 +00:00
xushiwei
1136526e4c cl.PkgLinkOnly; llgoRoot, llgoPkgLinkFile 2024-05-07 08:05:56 +08:00
xushiwei
0edeb5cfd0 runtime: Float, Time 2024-05-07 07:32:25 +08:00
xushiwei
bc7412f6c9 Merge pull request #123 from xushiwei/llama2
llgo/x/llama2
2024-05-07 07:25:23 +08:00
xushiwei
025cff9494 llgo/x/llama2 2024-05-07 07:22:49 +08:00
xushiwei
445e7154e8 Merge pull request #122 from xushiwei/q
runtime: c.Uint
2024-05-07 00:17:44 +08:00
xushiwei
4eb7e4000b runtime: c.Uint 2024-05-07 00:15:06 +08:00
138 changed files with 5764 additions and 2196 deletions

5
.gitignore vendored
View File

@@ -8,12 +8,17 @@
*.so *.so
*.dylib *.dylib
test.db
llgo_autogen.ll
stories*.bin
.DS_Store .DS_Store
err.log err.log
_go/ _go/
_runtime/ _runtime/
_tinygo/ _tinygo/
build.dir/
.vscode/
# Test binary, built with `go test -c` # Test binary, built with `go test -c`
*.test *.test

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "x/llama2/llama2.c"]
path = x/llama2/llama2.c
url = https://github.com/karpathy/llama2.c.git
[submodule "x/sqlite/sqlite"]
path = x/sqlite/sqlite
url = https://github.com/sqlite/sqlite.git

View File

@@ -8,7 +8,51 @@ llgo - A Go compiler based on LLVM
[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/llgo.svg)](https://pkg.go.dev/github.com/goplus/llgo) [![GoDoc](https://pkg.go.dev/badge/github.com/goplus/llgo.svg)](https://pkg.go.dev/github.com/goplus/llgo)
[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop) [![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop)
This is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem. It's a subproject of [the Go+ project](https://github.com/goplus/gop). This is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
## C standard libary support
```go
package main
import "github.com/goplus/llgo/c"
func main() {
c.Printf(c.Str("Hello world\n"))
}
```
This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by llgo for generating a C string constant.
See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials.
## Python support
You can import a Python library in llgo! For example:
```go
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/math"
)
func main() {
x := math.Sqrt(py.Float(2))
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
}
```
Here, We call `py.Float(2)` to create a Python floating point number 2, and pass it to Pythons `math.sqrt` to get `x`. Then use `x.Float64()` to convert the Python object to Go's `float64` type, and finally we print the value through C `printf`.
## Other frequently used libraries
TODO
## How to install ## How to install
@@ -32,6 +76,11 @@ sudo apt-get install --no-install-recommends llvm-17-dev
go install -v ./... go install -v ./...
``` ```
### on Windows
TODO
## Demo ## Demo
The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it): The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it):
@@ -40,10 +89,37 @@ The `_demo` directory contains our demos (it start with `_` to prevent the `go`
* [concat](_demo/concat/concat.go): call C fprintf with stderr, and Go variadic function * [concat](_demo/concat/concat.go): call C fprintf with stderr, and Go variadic function
* [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. qsort) * [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. qsort)
* [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)
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
And the `_pydemo` directory contains python related demos:
* [callpy](_pydemo/callpy/callpy.go): call Python standard library function `math.sqrt`
### How to run demos ### How to run demos
To run the demos in directory `_demo`:
```sh ```sh
cd <demo-directory> # eg. cd _demo/genints cd <demo-directory> # eg. cd _demo/genints
llgo run . llgo run .
``` ```
To run the demos in directory `_pydemo`, you need to set the `LLGO_LIB_PYTHON` environment variable first. Assuming you use Python 3.12, and the `libpython3.12.so` (or `libpython3.12.dylib` or `python3.12.lib`) file is in the /foo/bar directory, then you need to set `LLGO_LIB_PYTHON` to:
```sh
export LLGO_LIB_PYTHON=/foo/bar/python3.12
```
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this:
```sh
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
```
Then you can run the demos in directory `_pydemo`:
```sh
cd <demo-directory> # eg. cd _pydemo/callpy
llgo run .
```

137
_demo/llama2-c/README.md Normal file
View File

@@ -0,0 +1,137 @@
llama2 - Inference Llama 2 in LLGo
=====
<p align="center">
<img src="assets/llama_cute.jpg" width="300" height="300" alt="Cute Llama">
</p>
Have you ever wanted to inference a baby [Llama 2](https://ai.meta.com/llama/) model in Go? No? Well, now you can!
This is based on [llama2.c](https://github.com/karpathy/llama2.c), we didn't port anything! So it's very different from these Go implementations:
* https://github.com/nikolaydubina/llama2.go
* https://github.com/tmc/go-llama2
llgo plays a great role as a bridge, allowing the C ecosystem to be seamlessly connected to Go.
You might think that you need many billion parameter LLMs to do anything useful, but in fact very small LLMs can have surprisingly strong performance if you make the domain narrow enough (ref: [TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories) paper). This repo is a "fullstack" train + inference solution for Llama 2 LLM, with focus on minimalism and simplicity.
As the architecture is identical, you can also load and inference Meta's Llama 2 models. However, the current code only inferences models in fp32, so you will most likely not be able to productively load models larger than 7B.
## feel the magic
How to run this example? The simplest way is to run it without any arguments:
```bash
llgo run .
```
This means it uses the default model checkpoint file (`stories15M.bin`), and the default prompt (`Once upon a time`).
You need download the model checkpoint file first. Download this 15M parameter model trained on the [TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories) dataset (~60MB download):
```bash
wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
```
If you want to specify a prompt (eg. `Long long ago`):
```bash
llgo run . 'Long long ago'
```
We can also try a bit bigger 42M parameter model (ie. `stories42M.bin`):
```bash
wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories42M.bin
llgo run . -m stories42M.bin 'Long long ago'
```
There is also an even better 110M param model available, see [models](#models).
Quick note on sampling, the recommendation for ~best results is to sample with `-t 1.0 -p 0.9`, i.e. temperature 1.0 (default) but also top-p sampling at 0.9 (default). Intuitively, top-p ensures that tokens with tiny probabilities do not get sampled, so we can't get "unlucky" during sampling, and we are less likely to go "off the rails" afterwards. More generally, to control the diversity of samples use either the temperature (i.e. vary `-t` between 0 and 1 and keep top-p off with `-p 0`) or the top-p value (i.e. vary `-p` between 0 and 1 and keep `-t 1`), but not both. Nice explainers on LLM sampling strategies include [this](https://peterchng.com/blog/2023/05/02/token-selection-strategies-top-k-top-p-and-temperature/), [this](https://docs.cohere.com/docs/controlling-generation-with-top-k-top-p) or [this](https://huggingface.co/blog/how-to-generate).
## Meta's Llama 2 models
As the neural net architecture is identical, we can also inference the Llama 2 models released by Meta. Sadly there is a bit of friction here due to licensing (I can't directly upload the checkpoints, I think). So Step 1, get the Llama 2 checkpoints by following the [Meta instructions](https://github.com/facebookresearch/llama). Once we have those checkpoints, we have to convert them into the llama2.c format.
For this we need to install the python dependencies (`pip install -r requirements.txt`) and then use the `export.py` file, e.g. for 7B model:
```bash
python export.py llama2_7b.bin --meta-llama path/to/llama/model/7B
```
The export will take ~10 minutes or so and generate a 26GB file (the weights of the 7B model in float32) called `llama2_7b.bin` in the current directory. It has been [reported](https://github.com/karpathy/llama2.c/pull/85) that despite efforts. I would not attempt to run anything above 7B right now for two reasons: first, 13B+ currently doesn't work because of integer flow in pointer arithmetic, which is yet to be fixed, and second, even if it were fixed, this repo is doing float32 inference right now, so it would be fairly unusably slow. Once the export is done, we can run it:
```bash
./run llama2_7b.bin
```
This ran at about 4 tokens/s compiled with [OpenMP](#OpenMP) on 96 threads on my CPU Linux box in the cloud. (On my MacBook Air M1, currently it's closer to 30 seconds per token if you just build with `make runfast`.) Example output:
> The purpose of this document is to highlight the state-of-the-art of CoO generation technologies, both recent developments and those in commercial use. The focus is on the technologies with the highest merit to become the dominating processes of the future and therefore to be technologies of interest to S&amp;T ... R&amp;D. As such, CoO generation technologies developed in Russia, Japan and Europe are described in some depth. The document starts with an introduction to cobalt oxides as complex products and a short view on cobalt as an essential material. The document continues with the discussion of the available CoO generation processes with respect to energy and capital consumption as well as to environmental damage.
base models... ¯\\_(ツ)_/¯. Since we can inference the base model, it should be possible to also inference the chat model quite easily, and have a conversation with it. And if we can find a way to run 7B more efficiently, we can start adding LoRA to our training script, and going wild with finetunes all within the repo!
You can also try Meta's Code Llama models even if support for them is incomplete. In particular, some hyperparameters changed (e.g. the constant in RoPE layer), so the inference is not exactly correct and a bit buggy right now. Looking into fixes. Make sure to build the tokenizer for the plain and instruct variants and pass it when doing inference.
```bash
python export.py codellama2_7b.bin --meta-llama /path/to/CodeLlama-7b
python tokenizer.py --tokenizer-model=/path/to/CodeLlama-7b/tokenizer.model
./run codellama2_7b.bin -z /path/to/CodeLlama-7b/tokenizer.bin
```
Chat with Code Llama Instruct:
```bash
python export.py codellama2_7b_instruct.bin --meta-llama /path/to/CodeLlama-7b-Instruct
python tokenizer.py --tokenizer-model=/path/to/CodeLlama-7b-Instruct/tokenizer.model
./run codellama2_7b_instruct.bin -m chat -z /path/to/CodeLlama-7b-Instruct/tokenizer.bin
```
## huggingface models
We can load any huggingface models that use the Llama 2 architecture. See the script [export.py](export.py) and the `--hf` flag to export the model .bin file.
## models
For the sake of examples of smaller, from-scratch models, I trained a small model series on TinyStories. All of these trained in a few hours on my training setup (4X A100 40GB GPUs). The 110M took around 24 hours. I am hosting them on huggingface hub [tinyllamas](https://huggingface.co/karpathy/tinyllamas), both in the original PyTorch .pt, and also in the llama2.c format .bin:
| model | dim | n_layers | n_heads | n_kv_heads | max context length | parameters | val loss | download
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 260K | 64 | 5 | 8 | 4 | 512 | 260K | 1.297 | [stories260K](https://huggingface.co/karpathy/tinyllamas/tree/main/stories260K)
| OG | 288 | 6 | 6 | 6 | 256 | 15M | 1.072 | [stories15M.bin](https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin) |
| 42M| 512 | 8 | 8 | 8 | 1024 | 42M | 0.847 | [stories42M.bin](https://huggingface.co/karpathy/tinyllamas/resolve/main/stories42M.bin) |
| 110M| 768 | 12 | 12 | 12 | 1024 | 110M | 0.760 | [stories110M.bin](https://huggingface.co/karpathy/tinyllamas/resolve/main/stories110M.bin) |
You'll notice that the 110M model is equivalent to GPT-1 in size. Alternatively, this is also the smallest model in the GPT-2 series (`GPT-2 small`), except the max context length is only 1024 instead of 2048. The only notable changes from GPT-1/2 architecture is that Llama uses RoPE relatively positional embeddings instead of absolute/learned positional embeddings, a bit more fancy SwiGLU non-linearity in the MLP, RMSNorm instead of LayerNorm, bias=False on all Linear layers, and is optionally multiquery.
## training
Let's see how we can train a baby Llama 2 from scratch using the code in this repo. First let's download and pretokenize some source dataset, e.g. I like [TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories) so this is the only example currently available in this repo. But it should be very easy to add datasets, see the code.
```bash
python tinystories.py download
python tinystories.py pretokenize
```
Then train our model:
```bash
python train.py
```
**brief training guide**. See the train.py script for more exotic launches and hyperparameter overrides. Here is a brief guide to how to set the parameters. Look at the table at the very end of the [Chinchilla paper](https://arxiv.org/abs/2203.15556) to get a sense of how the Transformer parameters (dim, n_layers, n_heads) grow or shrink together. Extrapolate/interpolate this pattern to get bigger or smaller transformers. Set the max context length however you wish, depending on the problem: this should be the max number of tokens that matter to predict the next token. E.g. Llama 2 uses 2048. Next, you want the _total_ batch size per update (printed by the script as "tokens per iteration will be:") to be somewhere around 100K tokens for medium-sized applications. For tiny applications it could be lower, for large training (e.g. GPTs/LLamas) it is usually ~0.5M, or even more. You get there by first maxing out the batch_size to whatever your system allows (e.g. mine was 16 in a recent run because after that my GPU runs out of memory), and then you want to increase gradient_accumulation_steps to be as high as necessary to reach the total batch size of ~100K. Finally, you want to tune your learning_rate (LR). You want this to be as high as your training allows. Very small networks can get away with a large LR (e.g. 1e-3 or even higher). Large networks need lower LRs. 3e-4 is a safe choice in most medium-sized applications, but can be too low for small networks, so try to increase it! Finally, max_iters is the length of training. Play with different settings. I mostly only ever tune these parameters and leave most of the others unchanged. Here is an example of how I trained the 110M model, which I don't think is anywhere near optimal, but looked sensible to me: dim 768, n_layers 12, n_heads 12 (so size of each head is 768 / 12 = 64 channels), seq len of 1024, batch size 16 (this is the most that fit my A100 40GB GPU), gradient_accumulation_steps = 8 was needed to get total tokens batch size to be 16 batch size * 1024 tokens in sequence * 8 grad_accum = 131,072 tokens per update. Good. Learning rate 4e-4 (probably a little too low). max_iters 200K (probably a bit too high). Dropout 0.1, as that usually helps a bit at medium size. That was it. I ran using Distributed Data Parallel (DDP) on 4 GPUs on my cloud machine, training took ~day or so.
Totally understand if you want to skip model training, for simple demo just download one of the pretrained models (see [models](#models) section), e.g.:
```bash
wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
```
Once we have the model.bin file, we can inference in C. Compile the C code first:
```bash
llgo run . -m stories15M.bin
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

50
_demo/llama2-c/run.go Normal file
View File

@@ -0,0 +1,50 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/llama2"
)
func main() {
var prompt *c.Char = c.Str("Once upon a time")
var checkpointPath *c.Char = c.Str("stories15M.bin")
var tokenizerPath *c.Char = c.Str("tokenizer.bin")
var temperature, topp c.Float = 1.0, 0.9
var steps c.Int = 256
var rngSeed uint64 = uint64(c.Time(nil))
loop: // parse command line arguments
for {
switch c.Getopt(c.Argc, c.Argv, c.Str("m:")) {
case 'm':
checkpointPath = c.Optarg
c.Fprintf(c.Stderr, c.Str("==> use model: %s\n"), checkpointPath)
case -1:
break loop
}
}
if c.Optind < c.Argc {
prompt = c.Index(c.Argv, c.Optind)
c.Fprintf(c.Stderr, c.Str("==> prompt: %s\n"), prompt)
}
// build the Transformer via the model .bin file
var transformer llama2.Transformer
llama2.BuildTransformer(&transformer, checkpointPath)
// build the Tokenizer via the tokenizer .bin file
var tokenizer llama2.Tokenizer
llama2.BuildTokenizer(&tokenizer, tokenizerPath, transformer.Config.VocabSize)
// build the Sampler
var sampler llama2.Sampler
llama2.BuildSampler(&sampler, transformer.Config.VocabSize, temperature, topp, rngSeed)
// run!
llama2.Generate(&transformer, &tokenizer, &sampler, prompt, steps)
// memory and file handles cleanup
llama2.FreeSampler(&sampler)
llama2.FreeTokenizer(&tokenizer)
llama2.FreeTransformer(&transformer)
}

Binary file not shown.

61
_demo/sqlite/sqlite.go Normal file
View File

@@ -0,0 +1,61 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/sqlite"
)
func main() {
c.Remove(c.Str("test.db"))
db, err := sqlite.Open(c.Str("test.db"))
check(err, db, "sqlite: Open")
err = db.Exec(c.Str("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"), nil, nil, nil)
check(err, db, "sqlite: Exec CREATE TABLE")
stmt, err := db.PrepareV3("INSERT INTO users (id, name) VALUES (?, ?)", 0, nil)
check(err, db, "sqlite: PrepareV3 INSERT")
stmt.BindInt(1, 100)
stmt.BindText(2, c.Str("Hello World"), -1, nil)
err = stmt.Step()
checkDone(err, db, "sqlite: Step INSERT 1")
stmt.Reset()
stmt.BindInt(1, 200)
stmt.BindText(2, c.Str("This is llgo"), -1, nil)
err = stmt.Step()
checkDone(err, db, "sqlite: Step INSERT 2")
stmt.Close()
stmt, err = db.PrepareV3("SELECT * FROM users", 0, nil)
check(err, db, "sqlite: PrepareV3 SELECT")
for {
if err = stmt.Step(); err != sqlite.HasRow {
break
}
c.Printf(c.Str("==> id=%d, name=%s\n"), stmt.ColumnInt(0), stmt.ColumnText(1))
}
checkDone(err, db, "sqlite: Step done")
stmt.Close()
db.Close()
}
func check(err sqlite.Errno, db *sqlite.Sqlite3, at string) {
if err != sqlite.OK {
c.Printf(c.Str("==> %s Error: (%d) %s\n"), c.AllocaCStr(at), err, db.Errmsg())
c.Exit(1)
}
}
func checkDone(err sqlite.Errno, db *sqlite.Sqlite3, at string) {
if err != sqlite.Done {
check(err, db, at)
}
}

12
_pydemo/callpy/callpy.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/math"
)
func main() {
x := math.Sqrt(py.Float(2))
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
}

102
c/c.go
View File

@@ -16,6 +16,7 @@
package c package c
// typedef unsigned int uint;
import "C" import "C"
import "unsafe" import "unsafe"
@@ -26,24 +27,24 @@ const (
type ( type (
Char = int8 Char = int8
Int = C.int Int = C.int
Uint = C.uint
Float = float32
Pointer = unsafe.Pointer Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer FilePtr = unsafe.Pointer
) )
//go:linkname Stdin __stdinp type integer interface {
var Stdin FilePtr ~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
}
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr
//go:linkname Str llgo.cstr //go:linkname Str llgo.cstr
func Str(string) *Char func Str(string) *Char
//go:linkname Advance llgo.advance // llgo:link Advance llgo.advance
func Advance(ptr Pointer, offset int) Pointer func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
// llgo:link Index llgo.index
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
//go:linkname Alloca llgo.alloca //go:linkname Alloca llgo.alloca
func Alloca(size uintptr) Pointer func Alloca(size uintptr) Pointer
@@ -54,9 +55,6 @@ func AllocaCStr(s string) *Char
//go:linkname Unreachable llgo.unreachable //go:linkname Unreachable llgo.unreachable
func Unreachable() func Unreachable()
//go:linkname Rand C.rand
func Rand() Int
//go:linkname Malloc C.malloc //go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer func Malloc(size uintptr) Pointer
@@ -66,11 +64,85 @@ func Memcpy(dst, src Pointer, n uintptr) Pointer
//go:linkname Memset C.memset //go:linkname Memset C.memset
func Memset(s Pointer, c Int, n uintptr) Pointer func Memset(s Pointer, c Int, n uintptr) Pointer
// -----------------------------------------------------------------------------
//go:linkname GoStringData llgo.stringData
func GoStringData(string) *Char
// -----------------------------------------------------------------------------
//go:linkname Remove C.remove
func Remove(path *Char) Int
// -----------------------------------------------------------------------------
//go:linkname Exit C.exit
func Exit(Int)
// -----------------------------------------------------------------------------
//go:linkname Rand C.rand
func Rand() Int
//go:linkname Qsort C.qsort
func Qsort(base Pointer, count, elem uintptr, compar func(a, b Pointer) Int)
// -----------------------------------------------------------------------------
//go:linkname Stdin __stdinp
var Stdin FilePtr
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr
//go:linkname Printf C.printf //go:linkname Printf C.printf
func Printf(format *Char, __llgo_va_list ...any) Int func Printf(format *Char, __llgo_va_list ...any) Int
//go:linkname Fprintf C.fprintf //go:linkname Fprintf C.fprintf
func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int func Fprintf(fp FilePtr, format *Char, __llgo_va_list ...any) Int
//go:linkname Qsort C.qsort // -----------------------------------------------------------------------------
func Qsort(base Pointer, count, elem uintptr, compar func(a, b Pointer) Int)
//go:linkname Time C.time
func Time(*int32) int32
// -----------------------------------------------------------------------------
type Option struct {
Name *Char
HasArg Int
Flag *Int
Val Int
}
//go:linkname Argc __llgo_argc
var Argc Int
//go:linkname Argv __llgo_argv
var Argv **Char
//go:linkname Optarg optarg
var Optarg *Char
//go:linkname Optind optind
var Optind Int
//go:linkname Opterr opterr
var Opterr Int
//go:linkname Optopt optopt
var Optopt Int
//go:linkname Getopt C.getopt
func Getopt(argc Int, argv **Char, optstring *Char) Int
//go:linkname GetoptLong C.getopt_long
func GetoptLong(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
//go:linkname GetoptLongOnly C.getopt_long_only
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
// -----------------------------------------------------------------------------

View File

@@ -22,7 +22,7 @@ import (
"log" "log"
"os" "os"
"github.com/goplus/llgo/x/ar" "github.com/goplus/llgo/xtool/ar"
) )
func main() { func main() {

View File

@@ -22,7 +22,7 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/goplus/llgo/x/clang/parser" "github.com/goplus/llgo/xtool/clang/parser"
) )
var ( var (

View File

@@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/goplus/llgo/x/clang/preprocessor" "github.com/goplus/llgo/xtool/clang/preprocessor"
) )
func usage() { func usage() {

View File

@@ -31,7 +31,9 @@ func main() {
llgen.Verbose = false llgen.Verbose = false
llgenDir(dir + "/cl/_testlibc")
llgenDir(dir + "/cl/_testrt") llgenDir(dir + "/cl/_testrt")
llgenDir(dir+"/cl/_testpy", "")
llgenDir(dir+"/cl/_testdata", "") llgenDir(dir+"/cl/_testdata", "")
} }

View File

@@ -18,9 +18,10 @@ package main
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"github.com/goplus/llgo/x/nm" "github.com/goplus/llgo/xtool/env/llvm"
) )
func main() { func main() {
@@ -29,9 +30,8 @@ func main() {
return return
} }
nm := nm.New("nm") nm := llvm.New().Nm()
items, err := nm.List(os.Args[1]) items, err := nm.List(os.Args[1])
check(err)
for _, item := range items { for _, item := range items {
if item.File != "" { if item.File != "" {
fmt.Printf("\n%s:\n", item.File) fmt.Printf("\n%s:\n", item.File)
@@ -44,10 +44,7 @@ func main() {
} }
} }
} }
}
func check(err error) {
if err != nil { if err != nil {
panic(err) log.Println(err)
} }
} }

View File

@@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/goplus/llgo/x/env/llvm" "github.com/goplus/llgo/xtool/env/llvm"
"github.com/goplus/llgo/x/nm" "github.com/goplus/llgo/xtool/nm"
) )
func main() { func main() {
@@ -64,6 +64,7 @@ func makeIndex() {
usrLib(true), usrLib(true),
stdLib("LLGO_STDROOT"), stdLib("LLGO_STDROOT"),
stdLib("LLGO_USRROOT"), stdLib("LLGO_USRROOT"),
pythonLib(),
} }
err := b.Index(libDirs, idxDir, func(path string) { err := b.Index(libDirs, idxDir, func(path string) {
fmt.Println("==>", path) fmt.Println("==>", path)
@@ -72,6 +73,11 @@ func makeIndex() {
} }
func query(q string) { func query(q string) {
if len(q) > 0 {
if c := q[0]; c != '*' && c != '_' {
q = "_" + q
}
}
files, err := nm.Query(indexDir(), q) files, err := nm.Query(indexDir(), q)
check(err) check(err)
for _, f := range files { for _, f := range files {
@@ -103,6 +109,10 @@ func usrLib(local bool) string {
return "/usr/lib" return "/usr/lib"
} }
func pythonLib() string {
return os.Getenv("LLGO_PYTHON_ROOT")
}
func check(err error) { func check(err error) {
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -16,11 +18,13 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call i64 @main.max(i64 1, i64 2) %2 = call i64 @main.max(i64 1, i64 2)
ret void ret void
} }

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.hello = global ptr null @main.hello = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -25,11 +27,13 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call i64 @"github.com/goplus/llgo/cl/internal/stdio.Max"(i64 2, i64 100) %2 = call i64 @"github.com/goplus/llgo/cl/internal/stdio.Max"(i64 2, i64 100)
call void (ptr, ...) @printf(ptr @main.hello) call void (ptr, ...) @printf(ptr @main.hello)
ret void ret void
} }

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define i64 @"(main.T).Add"(i64 %0, i64 %1) { define i64 @"(main.T).Add"(i64 %0, i64 %1) {
_llgo_0: _llgo_0:
@@ -40,12 +42,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call i64 @"(main.T).Add"(i64 1, i64 2) %2 = call i64 @"(main.T).Add"(i64 1, i64 2)
call void (ptr, ...) @printf(ptr @main.format, i64 %0) call void (ptr, ...) @printf(ptr @main.format, i64 %2)
ret void ret void
} }

View File

@@ -10,82 +10,88 @@ func gwrite(b []byte) {
if len(b) == 0 { if len(b) == 0 {
return return
} }
for _, v := range b { c.Printf(c.Str("%s"), b)
c.Printf(c.Str("%c"), v) }
func printbool(v bool) {
if v {
printstring("true")
} else {
printstring("false")
} }
} }
// func printfloat(v float64) { func printfloat(v float64) {
// switch { switch {
// case v != v: case v != v:
// printstring("NaN") printstring("NaN")
// return return
// case v+v == v && v > 0: case v+v == v && v > 0:
// printstring("+Inf") printstring("+Inf")
// return return
// case v+v == v && v < 0: case v+v == v && v < 0:
// printstring("-Inf") printstring("-Inf")
// return return
// } }
// const n = 7 // digits printed const n = 7 // digits printed
// var buf [n + 7]byte var buf [n + 7]byte
// buf[0] = '+' buf[0] = '+'
// e := 0 // exp e := 0 // exp
// if v == 0 { if v == 0 {
// if 1/v < 0 { if 1/v < 0 {
// buf[0] = '-' buf[0] = '-'
// } }
// } else { } else {
// if v < 0 { if v < 0 {
// v = -v v = -v
// buf[0] = '-' buf[0] = '-'
// } }
// // normalize // normalize
// for v >= 10 { for v >= 10 {
// e++ e++
// v /= 10 v /= 10
// } }
// for v < 1 { for v < 1 {
// e-- e--
// v *= 10 v *= 10
// } }
// // round // round
// h := 5.0 h := 5.0
// for i := 0; i < n; i++ { for i := 0; i < n; i++ {
// h /= 10 h /= 10
// } }
// v += h v += h
// if v >= 10 { if v >= 10 {
// e++ e++
// v /= 10 v /= 10
// } }
// } }
// // format +d.dddd+edd // format +d.dddd+edd
// for i := 0; i < n; i++ { for i := 0; i < n; i++ {
// s := int(v) s := int(v)
// buf[i+2] = byte(s + '0') buf[i+2] = byte(s + '0')
// v -= float64(s) v -= float64(s)
// v *= 10 v *= 10
// } }
// buf[1] = buf[2] buf[1] = buf[2]
// buf[2] = '.' buf[2] = '.'
// buf[n+2] = 'e' buf[n+2] = 'e'
// buf[n+3] = '+' buf[n+3] = '+'
// if e < 0 { if e < 0 {
// e = -e e = -e
// buf[n+3] = '-' buf[n+3] = '-'
// } }
// buf[n+4] = byte(e/100) + '0' buf[n+4] = byte(e/100) + '0'
// buf[n+5] = byte(e/10)%10 + '0' buf[n+5] = byte(e/10)%10 + '0'
// buf[n+6] = byte(e%10) + '0' buf[n+6] = byte(e%10) + '0'
// gwrite(buf[:]) gwrite(buf[:])
// } }
func printuint(v uint64) { func printuint(v uint64) {
var buf [100]byte var buf [100]byte
@@ -100,13 +106,13 @@ func printuint(v uint64) {
gwrite(buf[i:]) gwrite(buf[i:])
} }
// func printint(v int64) { func printint(v int64) {
// if v < 0 { if v < 0 {
// printstring("-") printstring("-")
// v = -v v = -v
// } }
// printuint(uint64(v)) printuint(uint64(v))
// } }
var minhexdigits = 0 var minhexdigits = 0
@@ -171,4 +177,88 @@ func main() {
printnl() printnl()
printhex(0x1234abcf) printhex(0x1234abcf)
printnl() printnl()
prinxor(1)
printnl()
prinsub(100)
printnl()
prinusub(1<<64 - 1)
printnl()
prinfsub(100.1)
printnl()
printany(float32(1e9))
printnl()
printany(float64(2e9))
printnl()
var b bool = true
if b == true && b != false {
println("check bool", b)
}
n1 := 0b1001
n2 := 0b0011
println("check &^", n1&^n2 == 0b1000, n2&^n1 == 0b0010)
println(true, false, 'a', 'A', rune('中'),
int8(1), int16(2), int32(3), int64(4), 5,
uint8(1), uint16(2), uint32(3), uint64(4), uintptr(5),
"llgo")
}
func println(args ...any) {
for i, v := range args {
if i != 0 {
printstring(" ")
}
printany(v)
}
printnl()
}
func printany(v any) {
switch v := v.(type) {
case bool:
printbool(v)
case int:
printint(int64(v))
case int8:
printint(int64(v))
case int16:
printint(int64(v))
case int32:
printint(int64(v))
case int64:
printint(int64(v))
case uint:
printuint(uint64(v))
case uint8:
printuint(uint64(v))
case uint16:
printuint(uint64(v))
case uint32:
printuint(uint64(v))
case uint64:
printuint(uint64(v))
case uintptr:
printuint(uint64(v))
case float32:
printfloat(float64(v))
case float64:
printfloat(float64(v))
case string:
printstring(v)
}
}
func prinxor(n int64) {
printint(^n)
}
func prinsub(n int64) {
printint(-n)
}
func prinusub(n uint64) {
printuint(-n)
}
func prinfsub(n float64) {
printfloat(-n)
} }

View File

@@ -5,14 +5,27 @@ 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/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@main.minhexdigits = global ptr null @main.minhexdigits = global ptr null
@0 = private unnamed_addr constant [3 x i8] c"%c\00", align 1 @0 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@1 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1 @1 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1
@2 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1 @2 = private unnamed_addr constant [11 x i8] c"check bool\00", align 1
@3 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 @3 = private unnamed_addr constant [9 x i8] c"check &^\00", align 1
@4 = private unnamed_addr constant [2 x i8] c" \00", align 1 @4 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1
@5 = private unnamed_addr constant [5 x i8] c"true\00", align 1
@6 = private unnamed_addr constant [6 x i8] c"false\00", align 1
@7 = private unnamed_addr constant [4 x i8] c"NaN\00", align 1
@8 = private unnamed_addr constant [5 x i8] c"+Inf\00", align 1
@9 = private unnamed_addr constant [5 x i8] c"-Inf\00", align 1
@10 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1
@11 = private unnamed_addr constant [2 x i8] c"-\00", align 1
@12 = private unnamed_addr constant [2 x i8] c" \00", align 1
@13 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@14 = private unnamed_addr constant [2 x i8] c" \00", align 1
define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) { define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0: _llgo_0:
@@ -46,23 +59,7 @@ _llgo_1: ; preds = %_llgo_0
ret void ret void
_llgo_2: ; preds = %_llgo_0 _llgo_2: ; preds = %_llgo_0
%3 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %3 = call i32 (ptr, ...) @printf(ptr @0, %"github.com/goplus/llgo/internal/runtime.Slice" %0)
br label %_llgo_3
_llgo_3: ; preds = %_llgo_4, %_llgo_2
%4 = phi i64 [ -1, %_llgo_2 ], [ %5, %_llgo_4 ]
%5 = add i64 %4, 1
%6 = icmp slt i64 %5, %3
br i1 %6, label %_llgo_4, label %_llgo_5
_llgo_4: ; preds = %_llgo_3
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
%8 = getelementptr inbounds i8, ptr %7, i64 %5
%9 = load i8, ptr %8, align 1
%10 = call i32 (ptr, ...) @printf(ptr @0, i8 %9)
br label %_llgo_3
_llgo_5: ; preds = %_llgo_3
ret void ret void
} }
@@ -80,17 +77,542 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 4) %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 4)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
call void @main.printnl() call void @main.printnl()
call void @main.printuint(i64 1024) call void @main.printuint(i64 1024)
call void @main.printnl() call void @main.printnl()
call void @main.printhex(i64 305441743) call void @main.printhex(i64 305441743)
call void @main.printnl() call void @main.printnl()
call void @main.prinxor(i64 1)
call void @main.printnl()
call void @main.prinsub(i64 100)
call void @main.printnl()
call void @main.prinusub(i64 -1)
call void @main.printnl()
call void @main.prinfsub(double 1.001000e+02)
call void @main.printnl()
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
%4 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %3, i64 1315859240)
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %4)
call void @main.printnl()
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
%6 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %5, i64 4746175415993761792)
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %6)
call void @main.printnl()
br i1 true, label %_llgo_3, label %_llgo_2
_llgo_1: ; preds = %_llgo_3
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, i64 0
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 10)
%10 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %9)
store %"github.com/goplus/llgo/internal/runtime.iface" %10, ptr %8, align 8
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, i64 1
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%13 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %12, i64 -1)
store %"github.com/goplus/llgo/internal/runtime.iface" %13, ptr %11, align 8
%14 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %7, i64 16, i64 2, i64 0, i64 2, i64 2)
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %14)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
%16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 0
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 8)
%18 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %17)
store %"github.com/goplus/llgo/internal/runtime.iface" %18, ptr %16, align 8
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 1
%20 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%21 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %20, i64 -1)
store %"github.com/goplus/llgo/internal/runtime.iface" %21, ptr %19, align 8
%22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 2
%23 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%24 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %23, i64 -1)
store %"github.com/goplus/llgo/internal/runtime.iface" %24, ptr %22, align 8
%25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %15, i64 16, i64 3, i64 0, i64 3, i64 3)
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %25)
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 256)
%27 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 0
%28 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%29 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %28, i64 -1)
store %"github.com/goplus/llgo/internal/runtime.iface" %29, ptr %27, align 8
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 1
%31 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%32 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %31, i64 0)
store %"github.com/goplus/llgo/internal/runtime.iface" %32, ptr %30, align 8
%33 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 2
%34 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%35 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %34, i64 97)
store %"github.com/goplus/llgo/internal/runtime.iface" %35, ptr %33, align 8
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 3
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%38 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %37, i64 65)
store %"github.com/goplus/llgo/internal/runtime.iface" %38, ptr %36, align 8
%39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 4
%40 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%41 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %40, i64 20013)
store %"github.com/goplus/llgo/internal/runtime.iface" %41, ptr %39, align 8
%42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 5
%43 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
%44 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %43, i64 1)
store %"github.com/goplus/llgo/internal/runtime.iface" %44, ptr %42, align 8
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 6
%46 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
%47 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %46, i64 2)
store %"github.com/goplus/llgo/internal/runtime.iface" %47, ptr %45, align 8
%48 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 7
%49 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%50 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %49, i64 3)
store %"github.com/goplus/llgo/internal/runtime.iface" %50, ptr %48, align 8
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 8
%52 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
%53 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %52, i64 4)
store %"github.com/goplus/llgo/internal/runtime.iface" %53, ptr %51, align 8
%54 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 9
%55 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%56 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %55, i64 5)
store %"github.com/goplus/llgo/internal/runtime.iface" %56, ptr %54, align 8
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 10
%58 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
%59 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %58, i64 1)
store %"github.com/goplus/llgo/internal/runtime.iface" %59, ptr %57, align 8
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 11
%61 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
%62 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %61, i64 2)
store %"github.com/goplus/llgo/internal/runtime.iface" %62, ptr %60, align 8
%63 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 12
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
%65 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %64, i64 3)
store %"github.com/goplus/llgo/internal/runtime.iface" %65, ptr %63, align 8
%66 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 13
%67 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
%68 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %67, i64 4)
store %"github.com/goplus/llgo/internal/runtime.iface" %68, ptr %66, align 8
%69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 14
%70 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
%71 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %70, i64 5)
store %"github.com/goplus/llgo/internal/runtime.iface" %71, ptr %69, align 8
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 15
%73 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 4)
%74 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %73)
store %"github.com/goplus/llgo/internal/runtime.iface" %74, ptr %72, align 8
%75 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %26, i64 16, i64 16, i64 0, i64 16, i64 16)
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %75)
ret void
_llgo_3: ; preds = %_llgo_0
br i1 true, label %_llgo_1, label %_llgo_2
}
define void @main.prinfsub(double %0) {
_llgo_0:
%1 = fneg double %0
call void @main.printfloat(double %1)
ret void
}
define void @main.prinsub(i64 %0) {
_llgo_0:
%1 = sub i64 0, %0
call void @main.printint(i64 %1)
ret void
}
define void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
%2 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1)
%3 = extractvalue { i64, i1 } %2, 0
%4 = trunc i64 %3 to i1
%5 = extractvalue { i64, i1 } %2, 1
br i1 %5, label %_llgo_2, label %_llgo_3
_llgo_1: ; preds = %_llgo_30, %_llgo_29, %_llgo_28, %_llgo_26, %_llgo_24, %_llgo_22, %_llgo_20, %_llgo_18, %_llgo_16, %_llgo_14, %_llgo_12, %_llgo_10, %_llgo_8, %_llgo_6, %_llgo_4, %_llgo_2
ret void
_llgo_2: ; preds = %_llgo_0
call void @main.printbool(i1 %4)
br label %_llgo_1
_llgo_3: ; preds = %_llgo_0
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%7 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %6)
%8 = extractvalue { i64, i1 } %7, 0
%9 = extractvalue { i64, i1 } %7, 1
br i1 %9, label %_llgo_4, label %_llgo_5
_llgo_4: ; preds = %_llgo_3
call void @main.printint(i64 %8)
br label %_llgo_1
_llgo_5: ; preds = %_llgo_3
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
%11 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %10)
%12 = extractvalue { i64, i1 } %11, 0
%13 = trunc i64 %12 to i8
%14 = extractvalue { i64, i1 } %11, 1
br i1 %14, label %_llgo_6, label %_llgo_7
_llgo_6: ; preds = %_llgo_5
%15 = sext i8 %13 to i64
call void @main.printint(i64 %15)
br label %_llgo_1
_llgo_7: ; preds = %_llgo_5
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
%17 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %16)
%18 = extractvalue { i64, i1 } %17, 0
%19 = trunc i64 %18 to i16
%20 = extractvalue { i64, i1 } %17, 1
br i1 %20, label %_llgo_8, label %_llgo_9
_llgo_8: ; preds = %_llgo_7
%21 = sext i16 %19 to i64
call void @main.printint(i64 %21)
br label %_llgo_1
_llgo_9: ; preds = %_llgo_7
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%23 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %22)
%24 = extractvalue { i64, i1 } %23, 0
%25 = trunc i64 %24 to i32
%26 = extractvalue { i64, i1 } %23, 1
br i1 %26, label %_llgo_10, label %_llgo_11
_llgo_10: ; preds = %_llgo_9
%27 = sext i32 %25 to i64
call void @main.printint(i64 %27)
br label %_llgo_1
_llgo_11: ; preds = %_llgo_9
%28 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
%29 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %28)
%30 = extractvalue { i64, i1 } %29, 0
%31 = extractvalue { i64, i1 } %29, 1
br i1 %31, label %_llgo_12, label %_llgo_13
_llgo_12: ; preds = %_llgo_11
call void @main.printint(i64 %30)
br label %_llgo_1
_llgo_13: ; preds = %_llgo_11
%32 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
%33 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %32)
%34 = extractvalue { i64, i1 } %33, 0
%35 = extractvalue { i64, i1 } %33, 1
br i1 %35, label %_llgo_14, label %_llgo_15
_llgo_14: ; preds = %_llgo_13
call void @main.printuint(i64 %34)
br label %_llgo_1
_llgo_15: ; preds = %_llgo_13
%36 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
%37 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %36)
%38 = extractvalue { i64, i1 } %37, 0
%39 = trunc i64 %38 to i8
%40 = extractvalue { i64, i1 } %37, 1
br i1 %40, label %_llgo_16, label %_llgo_17
_llgo_16: ; preds = %_llgo_15
%41 = sext i8 %39 to i64
call void @main.printuint(i64 %41)
br label %_llgo_1
_llgo_17: ; preds = %_llgo_15
%42 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
%43 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %42)
%44 = extractvalue { i64, i1 } %43, 0
%45 = trunc i64 %44 to i16
%46 = extractvalue { i64, i1 } %43, 1
br i1 %46, label %_llgo_18, label %_llgo_19
_llgo_18: ; preds = %_llgo_17
%47 = sext i16 %45 to i64
call void @main.printuint(i64 %47)
br label %_llgo_1
_llgo_19: ; preds = %_llgo_17
%48 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
%49 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %48)
%50 = extractvalue { i64, i1 } %49, 0
%51 = trunc i64 %50 to i32
%52 = extractvalue { i64, i1 } %49, 1
br i1 %52, label %_llgo_20, label %_llgo_21
_llgo_20: ; preds = %_llgo_19
%53 = sext i32 %51 to i64
call void @main.printuint(i64 %53)
br label %_llgo_1
_llgo_21: ; preds = %_llgo_19
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
%55 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %54)
%56 = extractvalue { i64, i1 } %55, 0
%57 = extractvalue { i64, i1 } %55, 1
br i1 %57, label %_llgo_22, label %_llgo_23
_llgo_22: ; preds = %_llgo_21
call void @main.printuint(i64 %56)
br label %_llgo_1
_llgo_23: ; preds = %_llgo_21
%58 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
%59 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %58)
%60 = extractvalue { i64, i1 } %59, 0
%61 = extractvalue { i64, i1 } %59, 1
br i1 %61, label %_llgo_24, label %_llgo_25
_llgo_24: ; preds = %_llgo_23
call void @main.printuint(i64 %60)
br label %_llgo_1
_llgo_25: ; preds = %_llgo_23
%62 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
%63 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %62)
%64 = extractvalue { i64, i1 } %63, 0
%65 = trunc i64 %64 to i32
%66 = bitcast i32 %65 to float
%67 = extractvalue { i64, i1 } %63, 1
br i1 %67, label %_llgo_26, label %_llgo_27
_llgo_26: ; preds = %_llgo_25
%68 = fpext float %66 to double
call void @main.printfloat(double %68)
br label %_llgo_1
_llgo_27: ; preds = %_llgo_25
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
%70 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %69)
%71 = extractvalue { i64, i1 } %70, 0
%72 = bitcast i64 %71 to double
%73 = extractvalue { i64, i1 } %70, 1
br i1 %73, label %_llgo_28, label %_llgo_29
_llgo_28: ; preds = %_llgo_27
call void @main.printfloat(double %72)
br label %_llgo_1
_llgo_29: ; preds = %_llgo_27
%74 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
%75 = call { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %74)
%76 = extractvalue { %"github.com/goplus/llgo/internal/runtime.String", i1 } %75, 0
%77 = extractvalue { %"github.com/goplus/llgo/internal/runtime.String", i1 } %75, 1
br i1 %77, label %_llgo_30, label %_llgo_1
_llgo_30: ; preds = %_llgo_29
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %76)
br label %_llgo_1
}
define void @main.printbool(i1 %0) {
_llgo_0:
br i1 %0, label %_llgo_1, label %_llgo_3
_llgo_1: ; preds = %_llgo_0
%1 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 4)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %1)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_3, %_llgo_1
ret void
_llgo_3: ; preds = %_llgo_0
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 5)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
br label %_llgo_2
}
define void @main.printfloat(double %0) {
_llgo_0:
%1 = fcmp one double %0, %0
br i1 %1, label %_llgo_1, label %_llgo_3
_llgo_1: ; preds = %_llgo_0
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 3)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
ret void
_llgo_2: ; preds = %_llgo_7
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 4)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %3)
ret void
_llgo_3: ; preds = %_llgo_0
%4 = fadd double %0, %0
%5 = fcmp oeq double %4, %0
br i1 %5, label %_llgo_6, label %_llgo_7
_llgo_4: ; preds = %_llgo_10
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 4)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %6)
ret void
_llgo_5: ; preds = %_llgo_7
%7 = fadd double %0, %0
%8 = fcmp oeq double %7, %0
br i1 %8, label %_llgo_9, label %_llgo_10
_llgo_6: ; preds = %_llgo_3
%9 = fcmp ogt double %0, 0.000000e+00
br label %_llgo_7
_llgo_7: ; preds = %_llgo_6, %_llgo_3
%10 = phi i1 [ false, %_llgo_3 ], [ %9, %_llgo_6 ]
br i1 %10, label %_llgo_2, label %_llgo_5
_llgo_8: ; preds = %_llgo_10
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 14)
%12 = getelementptr inbounds i8, ptr %11, i64 0
store i8 43, ptr %12, align 1
%13 = fcmp oeq double %0, 0.000000e+00
br i1 %13, label %_llgo_11, label %_llgo_13
_llgo_9: ; preds = %_llgo_5
%14 = fcmp olt double %0, 0.000000e+00
br label %_llgo_10
_llgo_10: ; preds = %_llgo_9, %_llgo_5
%15 = phi i1 [ false, %_llgo_5 ], [ %14, %_llgo_9 ]
br i1 %15, label %_llgo_4, label %_llgo_8
_llgo_11: ; preds = %_llgo_8
%16 = fdiv double 1.000000e+00, %0
%17 = fcmp olt double %16, 0.000000e+00
br i1 %17, label %_llgo_14, label %_llgo_12
_llgo_12: ; preds = %_llgo_24, %_llgo_22, %_llgo_14, %_llgo_11
%18 = phi double [ %0, %_llgo_11 ], [ %36, %_llgo_22 ], [ %0, %_llgo_14 ], [ %42, %_llgo_24 ]
%19 = phi i64 [ 0, %_llgo_11 ], [ %32, %_llgo_22 ], [ 0, %_llgo_14 ], [ %41, %_llgo_24 ]
br label %_llgo_27
_llgo_13: ; preds = %_llgo_8
%20 = fcmp olt double %0, 0.000000e+00
br i1 %20, label %_llgo_15, label %_llgo_17
_llgo_14: ; preds = %_llgo_11
%21 = getelementptr inbounds i8, ptr %11, i64 0
store i8 45, ptr %21, align 1
br label %_llgo_12
_llgo_15: ; preds = %_llgo_13
%22 = fneg double %0
%23 = getelementptr inbounds i8, ptr %11, i64 0
store i8 45, ptr %23, align 1
br label %_llgo_17
_llgo_16: ; preds = %_llgo_17
%24 = add i64 %27, 1
%25 = fdiv double %26, 1.000000e+01
br label %_llgo_17
_llgo_17: ; preds = %_llgo_16, %_llgo_15, %_llgo_13
%26 = phi double [ %0, %_llgo_13 ], [ %25, %_llgo_16 ], [ %22, %_llgo_15 ]
%27 = phi i64 [ 0, %_llgo_13 ], [ %24, %_llgo_16 ], [ 0, %_llgo_15 ]
%28 = fcmp oge double %26, 1.000000e+01
br i1 %28, label %_llgo_16, label %_llgo_20
_llgo_18: ; preds = %_llgo_20
%29 = sub i64 %32, 1
%30 = fmul double %31, 1.000000e+01
br label %_llgo_20
_llgo_19: ; preds = %_llgo_20
br label %_llgo_23
_llgo_20: ; preds = %_llgo_18, %_llgo_17
%31 = phi double [ %26, %_llgo_17 ], [ %30, %_llgo_18 ]
%32 = phi i64 [ %27, %_llgo_17 ], [ %29, %_llgo_18 ]
%33 = fcmp olt double %31, 1.000000e+00
br i1 %33, label %_llgo_18, label %_llgo_19
_llgo_21: ; preds = %_llgo_23
%34 = fdiv double %38, 1.000000e+01
%35 = add i64 %39, 1
br label %_llgo_23
_llgo_22: ; preds = %_llgo_23
%36 = fadd double %31, %38
%37 = fcmp oge double %36, 1.000000e+01
br i1 %37, label %_llgo_24, label %_llgo_12
_llgo_23: ; preds = %_llgo_21, %_llgo_19
%38 = phi double [ 5.000000e+00, %_llgo_19 ], [ %34, %_llgo_21 ]
%39 = phi i64 [ 0, %_llgo_19 ], [ %35, %_llgo_21 ]
%40 = icmp slt i64 %39, 7
br i1 %40, label %_llgo_21, label %_llgo_22
_llgo_24: ; preds = %_llgo_22
%41 = add i64 %32, 1
%42 = fdiv double %36, 1.000000e+01
br label %_llgo_12
_llgo_25: ; preds = %_llgo_27
%43 = fptosi double %59 to i64
%44 = add i64 %60, 2
%45 = add i64 %43, 48
%46 = trunc i64 %45 to i8
%47 = getelementptr inbounds i8, ptr %11, i64 %44
store i8 %46, ptr %47, align 1
%48 = sitofp i64 %43 to double
%49 = fsub double %59, %48
%50 = fmul double %49, 1.000000e+01
%51 = add i64 %60, 1
br label %_llgo_27
_llgo_26: ; preds = %_llgo_27
%52 = getelementptr inbounds i8, ptr %11, i64 2
%53 = load i8, ptr %52, align 1
%54 = getelementptr inbounds i8, ptr %11, i64 1
store i8 %53, ptr %54, align 1
%55 = getelementptr inbounds i8, ptr %11, i64 2
store i8 46, ptr %55, align 1
%56 = getelementptr inbounds i8, ptr %11, i64 9
store i8 101, ptr %56, align 1
%57 = getelementptr inbounds i8, ptr %11, i64 10
store i8 43, ptr %57, align 1
%58 = icmp slt i64 %19, 0
br i1 %58, label %_llgo_28, label %_llgo_29
_llgo_27: ; preds = %_llgo_25, %_llgo_12
%59 = phi double [ %18, %_llgo_12 ], [ %50, %_llgo_25 ]
%60 = phi i64 [ 0, %_llgo_12 ], [ %51, %_llgo_25 ]
%61 = icmp slt i64 %60, 7
br i1 %61, label %_llgo_25, label %_llgo_26
_llgo_28: ; preds = %_llgo_26
%62 = sub i64 0, %19
%63 = getelementptr inbounds i8, ptr %11, i64 10
store i8 45, ptr %63, align 1
br label %_llgo_29
_llgo_29: ; preds = %_llgo_28, %_llgo_26
%64 = phi i64 [ %19, %_llgo_26 ], [ %62, %_llgo_28 ]
%65 = sdiv i64 %64, 100
%66 = trunc i64 %65 to i8
%67 = add i8 %66, 48
%68 = getelementptr inbounds i8, ptr %11, i64 11
store i8 %67, ptr %68, align 1
%69 = sdiv i64 %64, 10
%70 = trunc i64 %69 to i8
%71 = urem i8 %70, 10
%72 = add i8 %71, 48
%73 = getelementptr inbounds i8, ptr %11, i64 12
store i8 %72, ptr %73, align 1
%74 = srem i64 %64, 10
%75 = trunc i64 %74 to i8
%76 = add i8 %75, 48
%77 = getelementptr inbounds i8, ptr %11, i64 13
store i8 %76, ptr %77, align 1
%78 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %11, i64 1, i64 14, i64 0, i64 14, i64 14)
call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %78)
ret void ret void
} }
@@ -101,8 +623,8 @@ _llgo_0:
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%2 = urem i64 %14, 16 %2 = urem i64 %14, 16
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 16) %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 16)
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %3) %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %3, 0
%5 = getelementptr inbounds i8, ptr %4, i64 %2 %5 = getelementptr inbounds i8, ptr %4, i64 %2
%6 = load i8, ptr %5, align 1 %6 = load i8, ptr %5, align 1
%7 = getelementptr inbounds i8, ptr %1, i64 %15 %7 = getelementptr inbounds i8, ptr %1, i64 %15
@@ -139,16 +661,65 @@ _llgo_5: ; preds = %_llgo_1
br i1 %21, label %_llgo_2, label %_llgo_4 br i1 %21, label %_llgo_2, label %_llgo_4
} }
define void @main.printint(i64 %0) {
_llgo_0:
%1 = icmp slt i64 %0, 0
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 1)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
%3 = sub i64 0, %0
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
%4 = phi i64 [ %0, %_llgo_0 ], [ %3, %_llgo_1 ]
call void @main.printuint(i64 %4)
ret void
}
define void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
br label %_llgo_1
_llgo_1: ; preds = %_llgo_5, %_llgo_0
%2 = phi i64 [ -1, %_llgo_0 ], [ %3, %_llgo_5 ]
%3 = add i64 %2, 1
%4 = icmp slt i64 %3, %1
br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
%8 = icmp ne i64 %3, 0
br i1 %8, label %_llgo_4, label %_llgo_5
_llgo_3: ; preds = %_llgo_1
call void @main.printnl()
ret void
_llgo_4: ; preds = %_llgo_2
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 1)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %9)
br label %_llgo_5
_llgo_5: ; preds = %_llgo_4, %_llgo_2
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %7)
br label %_llgo_1
}
define void @main.printnl() { define void @main.printnl() {
_llgo_0: _llgo_0:
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1) %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @13, i64 1)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
ret void ret void
} }
define void @main.printsp() { define void @main.printsp() {
_llgo_0: _llgo_0:
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1) %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @14, i64 1)
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
ret void ret void
} }
@@ -191,6 +762,20 @@ _llgo_4: ; preds = %_llgo_1
br label %_llgo_3 br label %_llgo_3
} }
define void @main.prinusub(i64 %0) {
_llgo_0:
%1 = sub i64 0, %0
call void @main.printuint(i64 %1)
ret void
}
define void @main.prinxor(i64 %0) {
_llgo_0:
%1 = xor i64 %0, -1
call void @main.printint(i64 %1)
ret void
}
define ptr @main.stringStructOf(ptr %0) { define ptr @main.stringStructOf(ptr %0) {
_llgo_0: _llgo_0:
ret ptr %0 ret ptr %0
@@ -200,14 +785,22 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String") declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64)
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String")
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.hello = global ptr null @main.hello = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -24,8 +26,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void (ptr, ...) @printf(ptr @main.hello) call void (ptr, ...) @printf(ptr @main.hello)

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -27,8 +29,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void (ptr, ...) @printf(ptr @main.format, i64 100) call void (ptr, ...) @printf(ptr @main.format, i64 100)

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @"(*main.T).Print"(ptr %0, i64 %1) { define void @"(*main.T).Print"(ptr %0, i64 %1) {
_llgo_0: _llgo_0:
@@ -33,8 +35,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void @"(*main.T).Print"(ptr @main.format, i64 100) call void @"(*main.T).Print"(ptr @main.format, i64 100)

13
cl/_testdata/uint/in.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "github.com/goplus/llgo/c"
func f(a c.Uint) c.Uint {
a++
return a
}
func main() {
var a c.Uint = 100
c.Printf(c.Str("Hello, %u\n"), f(a))
}

41
cl/_testdata/uint/out.ll Normal file
View File

@@ -0,0 +1,41 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [11 x i8] c"Hello, %u\0A\00", align 1
define i32 @main.f(i32 %0) {
_llgo_0:
%1 = add i32 %0, 1
ret i32 %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 void @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 i32 @main.f(i32 100)
%3 = call i32 (ptr, ...) @printf(ptr @0, i32 %2)
ret void
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare i32 @printf(ptr, ...)

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.a = global ptr null @main.a = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -18,8 +20,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
br i1 false, label %_llgo_1, label %_llgo_2 br i1 false, label %_llgo_1, label %_llgo_2

13
cl/_testdata/vargs/in.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "github.com/goplus/llgo/internal/runtime/c"
func test(a ...any) {
for _, v := range a {
c.Printf(c.Str("%d\n"), v.(int))
}
}
func main() {
test(1, 2, 3)
}

89
cl/_testdata/vargs/out.ll Normal file
View File

@@ -0,0 +1,89 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"%d\0A\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 void @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 48)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %2, i64 0
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %4, i64 1)
store %"github.com/goplus/llgo/internal/runtime.iface" %5, ptr %3, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %2, i64 1
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%8 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %7, i64 2)
store %"github.com/goplus/llgo/internal/runtime.iface" %8, ptr %6, align 8
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %2, i64 2
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%11 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %10, i64 3)
store %"github.com/goplus/llgo/internal/runtime.iface" %11, ptr %9, align 8
%12 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 16, i64 3, i64 0, i64 3, i64 3)
call void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %12)
ret void
}
define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0
%2 = phi i64 [ -1, %_llgo_0 ], [ %3, %_llgo_2 ]
%3 = add i64 %2, 1
%4 = icmp slt i64 %3, %1
br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%9 = call i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %7, ptr %8)
%10 = call i32 (ptr, ...) @printf(ptr @0, i64 %9)
br label %_llgo_1
_llgo_3: ; preds = %_llgo_1
ret void
}
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.Basic"(i64)
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare i32 @printf(ptr, ...)

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.a = global ptr null @main.a = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -18,14 +20,16 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = load i64, ptr @main.a, align 4
%1 = add i64 %0, 1
store i64 %1, ptr @main.a, align 4
%2 = load i64, ptr @main.a, align 4 %2 = load i64, ptr @main.a, align 4
%3 = add i64 %2, 1
store i64 %3, ptr @main.a, align 4
%4 = load i64, ptr @main.a, align 4
ret void ret void
} }

11
cl/_testlibc/argv/in.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"github.com/goplus/llgo/c"
)
func main() {
for i := c.Int(0); i < c.Argc; i++ {
c.Printf(c.Str("%s\n"), c.Index(c.Argv, i))
}
}

50
cl/_testlibc/argv/out.ll Normal file
View File

@@ -0,0 +1,50 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"%s\0A\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 void @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()
br label %_llgo_3
_llgo_1: ; preds = %_llgo_3
%2 = load ptr, ptr @__llgo_argv, align 8
%3 = getelementptr ptr, ptr %2, i32 %7
%4 = load ptr, ptr %3, align 8
%5 = call i32 (ptr, ...) @printf(ptr @0, ptr %4)
%6 = add i32 %7, 1
br label %_llgo_3
_llgo_2: ; preds = %_llgo_3
ret void
_llgo_3: ; preds = %_llgo_1, %_llgo_0
%7 = phi i32 [ 0, %_llgo_0 ], [ %6, %_llgo_1 ]
%8 = load i32, ptr @__llgo_argc, align 4
%9 = icmp slt i32 %7, %8
br i1 %9, label %_llgo_1, label %_llgo_2
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare i32 @printf(ptr, ...)

20
cl/_testlibc/sqlite/in.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/sqlite"
)
func main() {
db, err := sqlite.OpenV2(c.Str(":memory:"), sqlite.OpenReadWrite|sqlite.OpenMemory, nil)
check(err)
db.Close()
}
func check(err sqlite.Errno) {
if err != sqlite.OK {
c.Printf(c.Str("==> Error: (%d) %s\n"), err, err.Errstr())
c.Exit(1)
}
}

View File

@@ -0,0 +1,62 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [20 x i8] c"==> Error: (%d) %s\0A\00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@1 = private unnamed_addr constant [9 x i8] c":memory:\00", align 1
define void @main.check(i32 %0) {
_llgo_0:
%1 = icmp ne i32 %0, 0
br i1 %1, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%2 = call ptr @sqlite3_errstr(i32 %0)
%3 = call i32 (ptr, ...) @printf(ptr @0, i32 %0, ptr %2)
call void @exit(i32 1)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
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
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define void @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, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr @1, i32 130, ptr null)
%3 = extractvalue { ptr, i32 } %2, 0
%4 = extractvalue { ptr, i32 } %2, 1
call void @main.check(i32 %4)
%5 = call i32 @sqlite3_close(ptr %3)
ret void
}
declare ptr @sqlite3_errstr(i32)
declare i32 @printf(ptr, ...)
declare void @exit(i32)
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr, i32, ptr)
declare i32 @sqlite3_close(ptr)

15
cl/_testpy/callpy/in.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/math"
"github.com/goplus/llgo/py/os"
)
func main() {
x := math.Sqrt(py.Float(2))
wd := os.Getcwd()
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
c.Printf(c.Str("cwd = %s\n"), wd.CStr())
}

74
cl/_testpy/callpy/out.ll Normal file
View File

@@ -0,0 +1,74 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@__llgo_py.math.sqrt = linkonce global ptr null
@__llgo_py.os.getcwd = linkonce global ptr null
@0 = private unnamed_addr constant [14 x i8] c"sqrt(2) = %f\0A\00", align 1
@1 = private unnamed_addr constant [10 x i8] c"cwd = %s\0A\00", align 1
@__llgo_py.math = external global ptr
@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1
@__llgo_py.os = external global ptr
@3 = private unnamed_addr constant [7 x i8] c"getcwd\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
call void @"github.com/goplus/llgo/py/math.init"()
call void @"github.com/goplus/llgo/py/os.init"()
%1 = load ptr, ptr @__llgo_py.math, align 8
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null)
%2 = load ptr, ptr @__llgo_py.os, align 8
call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null)
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define void @main(i32 %0, ptr %1) {
_llgo_0:
call void @Py_Initialize()
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 @PyFloat_FromDouble(double 2.000000e+00)
%3 = load ptr, ptr @__llgo_py.math.sqrt, align 8
%4 = call ptr @PyObject_CallOneArg(ptr %3, ptr %2)
%5 = load ptr, ptr @__llgo_py.os.getcwd, align 8
%6 = call ptr @PyObject_CallNoArgs(ptr %5)
%7 = call double @PyFloat_AsDouble(ptr %4)
%8 = call i32 (ptr, ...) @printf(ptr @0, double %7)
%9 = call ptr @PyBytes_AsString(ptr %6)
%10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9)
ret void
}
declare void @"github.com/goplus/llgo/py/math.init"()
declare void @"github.com/goplus/llgo/py/os.init"()
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @PyFloat_FromDouble(double)
declare ptr @PyObject_CallOneArg(ptr, ptr)
declare ptr @PyObject_CallNoArgs(ptr)
declare double @PyFloat_AsDouble(ptr)
declare i32 @printf(ptr, ...)
declare ptr @PyBytes_AsString(ptr)
declare void @llgoLoadPyModSyms(ptr, ...)
declare void @Py_Initialize()

14
cl/_testpy/math/in.go Normal file
View File

@@ -0,0 +1,14 @@
package math
import (
_ "unsafe"
"github.com/goplus/llgo/py"
)
const (
LLGoPackage = "py.math"
)
//go:linkname Sqrt py.sqrt
func Sqrt(x *py.Object) *py.Object

29
cl/_testpy/math/out.ll Normal file
View File

@@ -0,0 +1,29 @@
; ModuleID = 'math'
source_filename = "math"
@__llgo_py.math.sqrt = external global ptr
@"math.init$guard" = global ptr null
@__llgo_py.math = linkonce global ptr null
@0 = private unnamed_addr constant [5 x i8] c"math\00", align 1
define void @math.init() {
_llgo_0:
%0 = load i1, ptr @"math.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"math.init$guard", align 1
%1 = load ptr, ptr @__llgo_py.math, align 8
%2 = icmp ne ptr %1, null
br i1 %2, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0
ret void
_llgo_3: ; preds = %_llgo_1
%3 = call ptr @PyImport_ImportModule(ptr @0)
store ptr %3, ptr @__llgo_py.math, align 8
br label %_llgo_2
}
declare ptr @PyImport_ImportModule(ptr)

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"Hi\0A\00", align 1 @0 = private unnamed_addr constant [4 x i8] c"Hi\0A\00", align 1
@1 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @1 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
@@ -18,13 +20,15 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = alloca i8, i64 4, align 1 %2 = alloca i8, i64 4, align 1
%1 = call ptr @memcpy(ptr %0, ptr @0, i64 4) %3 = call ptr @memcpy(ptr %2, ptr @0, i64 4)
%2 = call i32 (ptr, ...) @printf(ptr @1, ptr %0) %4 = call i32 (ptr, ...) @printf(ptr @1, ptr %2)
ret void ret void
} }

View File

@@ -5,6 +5,8 @@ source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [13 x i8] c"Hello world\0A\00", align 1 @0 = private unnamed_addr constant [13 x i8] c"Hello world\0A\00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define %"github.com/goplus/llgo/internal/runtime.String" @main.hello() { define %"github.com/goplus/llgo/internal/runtime.String" @main.hello() {
_llgo_0: _llgo_0:
@@ -25,16 +27,18 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @main.hello() %2 = call %"github.com/goplus/llgo/internal/runtime.String" @main.hello()
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0) %3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
%2 = add i64 %1, 1 %4 = add i64 %3, 1
%3 = alloca i8, i64 %2, align 1 %5 = alloca i8, i64 %4, align 1
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %3, %"github.com/goplus/llgo/internal/runtime.String" %0) %6 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %5, %"github.com/goplus/llgo/internal/runtime.String" %2)
%5 = call i32 (ptr, ...) @printf(ptr %4) %7 = call i32 (ptr, ...) @printf(ptr %6)
ret void ret void
} }
@@ -42,8 +46,6 @@ declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/ll
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String") declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -4,6 +4,8 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1
define i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %0) { define i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
@@ -27,14 +29,16 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%1 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %0, i64 100) %3 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %2, i64 100)
%2 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %1) %4 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %3)
%3 = call i32 (ptr, ...) @printf(ptr @0, i64 %2) %5 = call i32 (ptr, ...) @printf(ptr @0, i64 %4)
ret void ret void
} }

View File

@@ -8,6 +8,8 @@ source_filename = "main"
@main.b = global ptr null @main.b = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@main.n = global ptr null @main.n = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @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 @1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@@ -30,113 +32,115 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%1 = getelementptr inbounds i64, ptr %0, i64 0 %3 = getelementptr inbounds i64, ptr %2, i64 0
store i64 1, ptr %1, align 4 store i64 1, ptr %3, align 4
%2 = getelementptr inbounds i64, ptr %0, i64 1 %4 = getelementptr inbounds i64, ptr %2, i64 1
store i64 2, ptr %2, align 4 store i64 2, ptr %4, align 4
%3 = getelementptr inbounds i64, ptr %0, i64 2 %5 = getelementptr inbounds i64, ptr %2, i64 2
store i64 3, ptr %3, align 4 store i64 3, ptr %5, align 4
%4 = getelementptr inbounds i64, ptr %0, i64 3 %6 = getelementptr inbounds i64, ptr %2, i64 3
store i64 4, ptr %4, align 4 store i64 4, ptr %6, align 4
%5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %0, i64 8, i64 4, i64 0, i64 4, i64 4) %7 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 8, i64 4, i64 0, i64 4, i64 4)
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %8 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%7 = getelementptr inbounds i64, ptr %6, i64 0 %9 = getelementptr inbounds i64, ptr %8, i64 0
%8 = getelementptr inbounds i64, ptr %6, i64 1 %10 = getelementptr inbounds i64, ptr %8, i64 1
%9 = getelementptr inbounds i64, ptr %6, i64 2 %11 = getelementptr inbounds i64, ptr %8, i64 2
%10 = getelementptr inbounds i64, ptr %6, i64 3 %12 = getelementptr inbounds i64, ptr %8, i64 3
store i64 1, ptr %7, align 4 store i64 1, ptr %9, align 4
store i64 2, ptr %8, align 4 store i64 2, ptr %10, align 4
store i64 3, ptr %9, align 4 store i64 3, ptr %11, align 4
store i64 4, ptr %10, align 4 store i64 4, ptr %12, align 4
%11 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
call void @main.out(i64 %11) call void @main.out(i64 %13)
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%13 = getelementptr inbounds i64, ptr %12, i64 0 %15 = getelementptr inbounds i64, ptr %14, i64 0
store i64 1, ptr %13, align 4 store i64 1, ptr %15, align 4
%14 = getelementptr inbounds i64, ptr %12, i64 1 %16 = getelementptr inbounds i64, ptr %14, i64 1
store i64 2, ptr %14, align 4 store i64 2, ptr %16, align 4
%15 = getelementptr inbounds i64, ptr %12, i64 2 %17 = getelementptr inbounds i64, ptr %14, i64 2
store i64 3, ptr %15, align 4 store i64 3, ptr %17, align 4
%16 = getelementptr inbounds i64, ptr %12, i64 3 %18 = getelementptr inbounds i64, ptr %14, i64 3
store i64 4, ptr %16, align 4 store i64 4, ptr %18, align 4
%17 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %12, i64 8, i64 4, i64 0, i64 4, i64 4) %19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4)
%18 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %17) %20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %19)
call void @main.out(i64 %18) call void @main.out(i64 %20)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
%19 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
call void @main.out(i64 %19) call void @main.out(i64 %21)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
%20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %22 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %24 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%23 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %22, i64 8, i64 %20, i64 1, i64 %21, i64 %20) %25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22)
%24 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %23) %26 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %25)
call void @main.out(i64 %24) call void @main.out(i64 %26)
%25 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %27 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%26 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %28 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%27 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %29 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%28 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %27, i64 8, i64 %25, i64 1, i64 %26, i64 %25) %30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27)
%29 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %28) %31 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %30)
call void @main.out(i64 %29) call void @main.out(i64 %31)
%30 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %32 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%31 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %33 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%32 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %31, i64 8, i64 %30, i64 1, i64 2, i64 %30) %34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32)
%33 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %32) %35 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %34)
call void @main.out(i64 %33) call void @main.out(i64 %35)
%34 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %36 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%35 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %37 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%36 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %35, i64 8, i64 %34, i64 1, i64 2, i64 %34) %38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36)
%37 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %36) %39 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %38)
call void @main.out(i64 %37) call void @main.out(i64 %39)
%38 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%39 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %41 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%40 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %39, i64 8, i64 %38, i64 1, i64 2, i64 2) %42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2)
%41 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %40) %43 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %42)
call void @main.out(i64 %41) call void @main.out(i64 %43)
%42 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %44 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%43 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %45 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%44 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %43, i64 8, i64 %42, i64 1, i64 2, i64 2) %46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2)
%45 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %44) %47 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %46)
call void @main.out(i64 %45)
%46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 4, i64 4)
%47 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %46)
call void @main.out(i64 %47) call void @main.out(i64 %47)
%48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 4, i64 4) %48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
%49 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %48) %49 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %48)
call void @main.out(i64 %49) call void @main.out(i64 %49)
%50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 2, i64 4) %50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
%51 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %50) %51 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %50)
call void @main.out(i64 %51) call void @main.out(i64 %51)
%52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 2, i64 4) %52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
%53 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %52) %53 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %52)
call void @main.out(i64 %53) call void @main.out(i64 %53)
%54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 2, i64 2) %54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
%55 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %54) %55 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %54)
call void @main.out(i64 %55) call void @main.out(i64 %55)
%56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %6, i64 8, i64 4, i64 1, i64 2, i64 2) %56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
%57 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %56) %57 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %56)
call void @main.out(i64 %57) call void @main.out(i64 %57)
%58 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5) %58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %58) %59 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %58)
%59 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) call void @main.out(i64 %59)
%60 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %59) %60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5)
%61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %59, i64 1, i64 %60) call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %61) %61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
%62 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5) %62 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %61, 1
%63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %62, i64 1, i64 2) %63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %61, i64 1, i64 %62)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63) call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63)
%64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) %64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5)
%65 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %64) %65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %64, i64 1, i64 2)
%66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %64, i64 5, i64 %65) call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %65)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %66) %66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
%67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68)
ret void ret void
} }
@@ -148,7 +152,7 @@ _llgo_0:
define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) { define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1
call void @main.out(i64 %1) call void @main.out(i64 %1)
ret void ret void
} }
@@ -167,8 +171,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/go
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1 @0 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1
@1 = private unnamed_addr constant [10 x i8] c"callback\0A\00", align 1 @1 = private unnamed_addr constant [10 x i8] c"callback\0A\00", align 1
@@ -26,24 +28,26 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = alloca { ptr, ptr }, align 8 %2 = alloca { ptr, ptr }, align 8
%1 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 0 %3 = getelementptr inbounds { ptr, ptr }, ptr %2, i32 0, i32 0
store ptr @__llgo_stub.main.print, ptr %1, align 8 store ptr @__llgo_stub.main.print, ptr %3, align 8
%2 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 1 %4 = getelementptr inbounds { ptr, ptr }, ptr %2, i32 0, i32 1
store ptr null, ptr %2, align 8 store ptr null, ptr %4, align 8
%3 = load { ptr, ptr }, ptr %0, align 8 %5 = load { ptr, ptr }, ptr %2, align 8
call void @main.callback(ptr @0, { ptr, ptr } %3) call void @main.callback(ptr @0, { ptr, ptr } %5)
%4 = alloca { ptr, ptr }, align 8 %6 = alloca { ptr, ptr }, align 8
%5 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 0 %7 = getelementptr inbounds { ptr, ptr }, ptr %6, i32 0, i32 0
store ptr @__llgo_stub.main.print, ptr %5, align 8 store ptr @__llgo_stub.main.print, ptr %7, align 8
%6 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 1 %8 = getelementptr inbounds { ptr, ptr }, ptr %6, i32 0, i32 1
store ptr null, ptr %6, align 8 store ptr null, ptr %8, align 8
%7 = load { ptr, ptr }, ptr %4, align 8 %9 = load { ptr, ptr }, ptr %6, align 8
call void @main.callback(ptr @1, { ptr, ptr } %7) call void @main.callback(ptr @1, { ptr, ptr } %9)
ret void ret void
} }

158
cl/_testrt/cast/in.go Normal file
View File

@@ -0,0 +1,158 @@
package main
//"github.com/goplus/llgo/internal/runtime/c"
func main() {
cvt64to8(0, 0)
cvt64to8(127, 127)
cvt64to8(128, -128)
cvt64to8(-128, -128)
cvt64to8(-129, 127)
cvt64to8(256, 0)
cvt64to8U(0, 0)
cvt64to8U(255, 255)
cvt64to8U(256, 0)
cvt64to8U(257, 1)
cvt64to8U(-1, 255)
cvt32Fto8(0.1, 0)
cvt32Fto8(127.1, 127)
cvt32Fto8(128.1, -128)
cvt32Fto8(-128.1, -128)
cvt32Fto8(-129.1, 127)
cvt32Fto8(256.1, 0)
cvt32Fto8U(0, 0)
cvt32Fto8U(255, 255)
cvt32Fto8U(256, 0)
cvt32Fto8U(257, 1)
cvt32Fto8U(-1, 255)
// MaxInt32 = 1<<31 - 1 // 2147483647
// MinInt32 = -1 << 31 // -2147483648
cvt32Fto32(0, 0)
cvt32Fto32(1.5, 1)
cvt32Fto32(1147483647.1, 1147483648)
cvt32Fto32(2147483647.1, -2147483648)
cvt32Fto32(4147483647.1, -2147483648)
cvt32Fto32(-2147483648.1, -2147483648)
cvt32Fto32(-2147482648.1, -2147482624)
// MaxUint32 = 1<<32 - 1 // 4294967295
cvt32Fto32U(0, 0)
cvt32Fto32U(1.5, 1)
cvt32Fto32U(4294967295.1, 0)
cvt32Fto32U(5294967295.1, 1000000000)
cvt32Fto32U(-4294967295.1, 0)
cvt32Fto32U(-1294967295.1, 3000000000)
cvt32Fto32U(-1.1, 4294967295)
// MaxFloat32 = 0x1p127 * (1 + (1 - 0x1p-23)) // 3.40282346638528859811704183484516925440e+38
// SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23 // 1.401298464324817070923729583289916131280e-45
// MaxFloat64 = 0x1p1023 * (1 + (1 - 0x1p-52)) // 1.79769313486231570814527423731704356798070e+308
// SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324
cvt32Fto64F(0, 0)
cvt32Fto64F(1.5, 1.5)
cvt32Fto64F(1e10, 1e10)
cvt32Fto64F(-1e10, -1e10)
cvt64Fto32F(0, 0)
cvt64Fto32F(1.5, 1.5)
cvt64Fto32F(1e10, 1e10)
cvt64Fto32F(-1e10, -1e10)
// MaxInt64 = 1<<63 - 1 // 9223372036854775807
// MinInt64 = -1 << 63 // -9223372036854775808
cvt64to64F(0, 0)
cvt64to64F(1e10, 1e10)
cvt64to64F(9223372036854775807, 9223372036854775807)
cvt64to64F(-9223372036854775807, -9223372036854775807)
// MaxUint64 = 1<<64 - 1 // 18446744073709551615
cvt64Uto64F(0, 0)
cvt64Uto64F(1e10, 1e10)
cvt64Uto64F(9223372036854775807, 9223372036854775807)
cvt64Uto64F(18446744073709551615, 18446744073709551615)
cvt32to64(0, 0)
cvt32to64(2147483647, 2147483647)
cvtUinptr(1024, 1024)
}
func cvtUinptr(a int32, b uintptr) {
if uintptr(a) != b {
panic("error")
}
if int32(b) != a {
panic("error")
}
}
func cvt32to64(a int32, b int64) {
if int64(a) != b {
panic("error")
}
}
func cvt64to64F(a int64, b float64) {
if float64(a) != b {
panic("error")
}
}
func cvt64Uto64F(a uint64, b float64) {
if float64(a) != b {
panic("error")
}
}
func cvt64Fto32F(a float64, b float32) {
if float32(a) != b {
panic("error")
}
}
func cvt32Fto64F(a float32, b float64) {
if float64(a) != b {
panic("error")
}
}
func cvt32Fto32(a float32, b int32) {
if int32(a) != b {
panic("error")
}
}
func cvt32Fto32U(a float32, b uint32) {
if uint32(a) != b {
panic("error")
}
}
func cvt32Fto8(a float32, b int8) {
if int8(a) != b {
panic("error")
}
}
func cvt32Fto8U(a float32, b uint8) {
if uint8(a) != b {
panic("error")
}
}
func cvt64to8(a int64, b int8) {
if int8(a) != b {
panic("error")
}
}
func cvt64to8U(a int, b uint8) {
if uint8(a) != b {
panic("error")
}
}

310
cl/_testrt/cast/out.ll Normal file
View File

@@ -0,0 +1,310 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@1 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@2 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@3 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@4 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@5 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@6 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@7 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@8 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@9 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@10 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@11 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@12 = private unnamed_addr constant [6 x i8] c"error\00", align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.cvt32Fto32(float %0, i32 %1) {
_llgo_0:
%2 = fptosi float %0 to i32
%3 = icmp ne i32 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt32Fto32U(float %0, i32 %1) {
_llgo_0:
%2 = fptoui float %0 to i32
%3 = icmp ne i32 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt32Fto64F(float %0, double %1) {
_llgo_0:
%2 = fpext float %0 to double
%3 = fcmp one double %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt32Fto8(float %0, i8 %1) {
_llgo_0:
%2 = fptosi float %0 to i8
%3 = icmp ne i8 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt32Fto8U(float %0, i8 %1) {
_llgo_0:
%2 = fptoui float %0 to i8
%3 = icmp ne i8 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt32to64(i32 %0, i64 %1) {
_llgo_0:
%2 = sext i32 %0 to i64
%3 = icmp ne i64 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt64Fto32F(double %0, float %1) {
_llgo_0:
%2 = fptrunc double %0 to float
%3 = fcmp one float %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt64Uto64F(i64 %0, double %1) {
_llgo_0:
%2 = uitofp i64 %0 to double
%3 = fcmp one double %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt64to64F(i64 %0, double %1) {
_llgo_0:
%2 = sitofp i64 %0 to double
%3 = fcmp one double %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt64to8(i64 %0, i8 %1) {
_llgo_0:
%2 = trunc i64 %0 to i8
%3 = icmp ne i8 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvt64to8U(i64 %0, i8 %1) {
_llgo_0:
%2 = trunc i64 %0 to i8
%3 = icmp ne i8 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
ret void
}
define void @main.cvtUinptr(i32 %0, i64 %1) {
_llgo_0:
%2 = sext i32 %0 to i64
%3 = icmp ne i64 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 5)
%5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5)
unreachable
_llgo_2: ; preds = %_llgo_0
%6 = trunc i64 %1 to i32
%7 = icmp ne i32 %6, %0
br i1 %7, label %_llgo_3, label %_llgo_4
_llgo_3: ; preds = %_llgo_2
%8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 5)
%9 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %8)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %9)
unreachable
_llgo_4: ; preds = %_llgo_2
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
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define void @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 @main.cvt64to8(i64 0, i8 0)
call void @main.cvt64to8(i64 127, i8 127)
call void @main.cvt64to8(i64 128, i8 -128)
call void @main.cvt64to8(i64 -128, i8 -128)
call void @main.cvt64to8(i64 -129, i8 127)
call void @main.cvt64to8(i64 256, i8 0)
call void @main.cvt64to8U(i64 0, i8 0)
call void @main.cvt64to8U(i64 255, i8 -1)
call void @main.cvt64to8U(i64 256, i8 0)
call void @main.cvt64to8U(i64 257, i8 1)
call void @main.cvt64to8U(i64 -1, i8 -1)
call void @main.cvt32Fto8(float 0x3FB99999A0000000, i8 0)
call void @main.cvt32Fto8(float 0x405FC66660000000, i8 127)
call void @main.cvt32Fto8(float 0x4060033340000000, i8 -128)
call void @main.cvt32Fto8(float 0xC060033340000000, i8 -128)
call void @main.cvt32Fto8(float 0xC060233340000000, i8 127)
call void @main.cvt32Fto8(float 0x40700199A0000000, i8 0)
call void @main.cvt32Fto8U(float 0.000000e+00, i8 0)
call void @main.cvt32Fto8U(float 2.550000e+02, i8 -1)
call void @main.cvt32Fto8U(float 2.560000e+02, i8 0)
call void @main.cvt32Fto8U(float 2.570000e+02, i8 1)
call void @main.cvt32Fto8U(float -1.000000e+00, i8 -1)
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 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 0xC1DFFFFF00000000, i32 -2147482624)
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 0x41F0000000000000, i32 0)
call void @main.cvt32Fto32U(float 0x41F3B9ACA0000000, i32 1000000000)
call void @main.cvt32Fto32U(float 0xC1F0000000000000, i32 0)
call void @main.cvt32Fto32U(float 0xC1D34BE880000000, i32 -1294967296)
call void @main.cvt32Fto32U(float 0xBFF19999A0000000, i32 -1)
call void @main.cvt32Fto64F(float 0.000000e+00, double 0.000000e+00)
call void @main.cvt32Fto64F(float 1.500000e+00, double 1.500000e+00)
call void @main.cvt32Fto64F(float 1.000000e+10, double 1.000000e+10)
call void @main.cvt32Fto64F(float -1.000000e+10, double -1.000000e+10)
call void @main.cvt64Fto32F(double 0.000000e+00, float 0.000000e+00)
call void @main.cvt64Fto32F(double 1.500000e+00, float 1.500000e+00)
call void @main.cvt64Fto32F(double 1.000000e+10, float 1.000000e+10)
call void @main.cvt64Fto32F(double -1.000000e+10, float -1.000000e+10)
call void @main.cvt64to64F(i64 0, double 0.000000e+00)
call void @main.cvt64to64F(i64 10000000000, double 1.000000e+10)
call void @main.cvt64to64F(i64 9223372036854775807, double 0x43E0000000000000)
call void @main.cvt64to64F(i64 -9223372036854775807, double 0xC3E0000000000000)
call void @main.cvt64Uto64F(i64 0, double 0.000000e+00)
call void @main.cvt64Uto64F(i64 10000000000, double 1.000000e+10)
call void @main.cvt64Uto64F(i64 9223372036854775807, double 0x43E0000000000000)
call void @main.cvt64Uto64F(i64 -1, double 0x43F0000000000000)
call void @main.cvt32to64(i32 0, i64 0)
call void @main.cvt32to64(i32 2147483647, i64 2147483647)
call void @main.cvtUinptr(i32 1024, i64 1024)
ret void
}
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface")
declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 @0 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
@1 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 @1 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
@@ -18,31 +20,33 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void @"main.main$1"(i64 100, i64 200) call void @"main.main$1"(i64 100, i64 200)
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%1 = alloca { ptr, ptr }, align 8 %3 = alloca { ptr, ptr }, align 8
%2 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 0 %4 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 0
store ptr @"__llgo_stub.main.main$2", ptr %2, align 8 store ptr @"__llgo_stub.main.main$2", ptr %4, align 8
%3 = getelementptr inbounds { ptr, ptr }, ptr %1, i32 0, i32 1 %5 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 1
store ptr null, ptr %3, align 8 store ptr null, ptr %5, align 8
%4 = load { ptr, ptr }, ptr %1, align 8 %6 = load { ptr, ptr }, ptr %3, align 8
store { ptr, ptr } %4, ptr %0, align 8 store { ptr, ptr } %6, ptr %2, align 8
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%6 = getelementptr inbounds { ptr }, ptr %5, i32 0, i32 0 %8 = getelementptr inbounds { ptr }, ptr %7, i32 0, i32 0
store ptr %0, ptr %6, align 8 store ptr %2, ptr %8, align 8
%7 = alloca { ptr, ptr }, align 8 %9 = alloca { ptr, ptr }, align 8
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0 %10 = getelementptr inbounds { ptr, ptr }, ptr %9, i32 0, i32 0
store ptr @"main.main$3", ptr %8, align 8 store ptr @"main.main$3", ptr %10, align 8
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1 %11 = getelementptr inbounds { ptr, ptr }, ptr %9, i32 0, i32 1
store ptr %5, ptr %9, align 8 store ptr %7, ptr %11, align 8
%10 = load { ptr, ptr }, ptr %7, align 8 %12 = load { ptr, ptr }, ptr %9, align 8
%11 = extractvalue { ptr, ptr } %10, 1 %13 = extractvalue { ptr, ptr } %12, 1
%12 = extractvalue { ptr, ptr } %10, 0 %14 = extractvalue { ptr, ptr } %12, 0
call void %12(ptr %11) call void %14(ptr %13)
ret void ret void
} }

View File

@@ -6,6 +6,8 @@ source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 @0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@1 = 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 [2 x i8] c" \00", align 1 @2 = private unnamed_addr constant [2 x i8] c" \00", align 1
@3 = private unnamed_addr constant [6 x i8] c"World\00", align 1 @3 = private unnamed_addr constant [6 x i8] c"World\00", align 1
@@ -60,28 +62,30 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i64 0 %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 0
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
store %"github.com/goplus/llgo/internal/runtime.String" %2, ptr %1, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i64 1
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
store %"github.com/goplus/llgo/internal/runtime.String" %4, ptr %3, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %4, ptr %3, align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i64 2 %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 1
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) %6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %5, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %5, align 8
%7 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %0, i64 16, i64 3, i64 0, i64 3, i64 3) %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 2
%8 = call %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
%9 = load ptr, ptr @__stderrp, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %8, ptr %7, align 8
%10 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %8) %9 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 16, i64 3, i64 0, i64 3, i64 3)
%11 = add i64 %10, 1 %10 = call %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %9)
%12 = alloca i8, i64 %11, align 1 %11 = load ptr, ptr @__stderrp, align 8
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %12, %"github.com/goplus/llgo/internal/runtime.String" %8) %12 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %10, 1
%14 = call i32 (ptr, ptr, ...) @fprintf(ptr %9, ptr @4, ptr %13) %13 = add i64 %12, 1
%14 = alloca i8, i64 %13, align 1
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %14, %"github.com/goplus/llgo/internal/runtime.String" %10)
%16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @4, ptr %15)
ret void ret void
} }
@@ -99,8 +103,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String") declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
declare i32 @fprintf(ptr, ptr, ...) declare i32 @fprintf(ptr, ptr, ...)

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [14 x i8] c"Hello, world\0A\00", align 1 @0 = private unnamed_addr constant [14 x i8] c"Hello, world\0A\00", align 1
define void @main.init() { define void @main.init() {
@@ -17,8 +19,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void (ptr, ...) @printf(ptr @0) call void (ptr, ...) @printf(ptr @0)

View File

@@ -4,6 +4,8 @@ source_filename = "main"
@_bar_x = external global ptr @_bar_x = external global ptr
@_bar_y = external global ptr @_bar_y = external global ptr
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -18,12 +20,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = load { [16 x i8], [2 x ptr] }, ptr @_bar_x, align 8 %2 = load { [16 x i8], [2 x ptr] }, ptr @_bar_x, align 8
%1 = load { [16 x i8] }, ptr @_bar_y, align 1 %3 = load { [16 x i8] }, ptr @_bar_y, align 1
ret void ret void
} }

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__stderrp = external global ptr @__stderrp = external global ptr
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1
define void @main.init() { define void @main.init() {
@@ -18,12 +20,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = load ptr, ptr @__stderrp, align 8 %2 = load ptr, ptr @__stderrp, align 8
call void (ptr, ptr, ...) @fprintf(ptr %0, ptr @0, i64 100) call void (ptr, ptr, ...) @fprintf(ptr %2, ptr @0, i64 100)
ret void ret void
} }

View File

@@ -6,6 +6,8 @@ source_filename = "main"
@main.basicTypes = global ptr null @main.basicTypes = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@main.sizeBasicTypes = global ptr null @main.sizeBasicTypes = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [20 x i8] c"Kind: %d, Size: %d\0A\00", align 1 @0 = private unnamed_addr constant [20 x i8] c"Kind: %d, Size: %d\0A\00", align 1
define ptr @main.Basic(i64 %0) { define ptr @main.Basic(i64 %0) {
@@ -48,17 +50,19 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @main.Basic(i64 24) %2 = call ptr @main.Basic(i64 24)
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 6 %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %2, i32 0, i32 6
%2 = load i8, ptr %1, align 1 %4 = load i8, ptr %3, align 1
%3 = sext i8 %2 to i64 %5 = sext i8 %4 to i64
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 0 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %2, i32 0, i32 0
%5 = load i64, ptr %4, align 4 %7 = load i64, ptr %6, align 4
%6 = call i32 (ptr, ...) @printf(ptr @0, i64 %3, i64 %5) %8 = call i32 (ptr, ...) @printf(ptr @0, i64 %5, i64 %7)
ret void ret void
} }

View File

@@ -4,6 +4,8 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.foo(%"github.com/goplus/llgo/internal/runtime.iface" %0) { define void @main.foo(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
_llgo_0: _llgo_0:
@@ -23,8 +25,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void @main.foo(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer) call void @main.foo(%"github.com/goplus/llgo/internal/runtime.iface" zeroinitializer)

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -27,12 +29,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call i32 @strlen(ptr @main.format) %2 = call i32 @strlen(ptr @main.format)
call void (ptr, ...) @printf(ptr @main.format, i32 %0) call void (ptr, ...) @printf(ptr @main.format, i32 %2)
ret void ret void
} }

View File

@@ -5,6 +5,8 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 @0 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
@1 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 @1 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
@2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@@ -27,103 +29,105 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = alloca %main.point, align 8 %2 = alloca %main.point, align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %0, i64 16) %3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
%2 = alloca [3 x %main.point], align 8 %4 = alloca [3 x %main.point], align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 48) %5 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %4, i64 48)
%4 = getelementptr inbounds %main.point, ptr %3, i64 0 %6 = getelementptr inbounds %main.point, ptr %5, i64 0
%5 = getelementptr inbounds %main.point, ptr %4, i32 0, i32 0 %7 = getelementptr inbounds %main.point, ptr %6, i32 0, i32 0
%6 = getelementptr inbounds %main.point, ptr %4, i32 0, i32 1 %8 = getelementptr inbounds %main.point, ptr %6, i32 0, i32 1
%7 = getelementptr inbounds %main.point, ptr %3, i64 1 %9 = getelementptr inbounds %main.point, ptr %5, i64 1
%8 = getelementptr inbounds %main.point, ptr %7, i32 0, i32 0 %10 = getelementptr inbounds %main.point, ptr %9, i32 0, i32 0
%9 = getelementptr inbounds %main.point, ptr %7, i32 0, i32 1 %11 = getelementptr inbounds %main.point, ptr %9, i32 0, i32 1
%10 = getelementptr inbounds %main.point, ptr %3, i64 2 %12 = getelementptr inbounds %main.point, ptr %5, i64 2
%11 = getelementptr inbounds %main.point, ptr %10, i32 0, i32 0 %13 = getelementptr inbounds %main.point, ptr %12, i32 0, i32 0
%12 = getelementptr inbounds %main.point, ptr %10, i32 0, i32 1 %14 = getelementptr inbounds %main.point, ptr %12, i32 0, i32 1
store i64 1, ptr %5, align 4 store i64 1, ptr %7, align 4
store i64 2, ptr %6, align 4 store i64 2, ptr %8, align 4
store i64 3, ptr %8, align 4 store i64 3, ptr %10, align 4
store i64 4, ptr %9, align 4 store i64 4, ptr %11, align 4
store i64 5, ptr %11, align 4 store i64 5, ptr %13, align 4
store i64 6, ptr %12, align 4 store i64 6, ptr %14, align 4
%13 = load [3 x %main.point], ptr %3, align 4 %15 = load [3 x %main.point], ptr %5, align 4
%14 = getelementptr inbounds %main.point, ptr %3, i64 2 %16 = getelementptr inbounds %main.point, ptr %5, i64 2
%15 = load %main.point, ptr %14, align 4 %17 = load %main.point, ptr %16, align 4
store %main.point %15, ptr %1, align 4 store %main.point %17, ptr %3, align 4
%16 = getelementptr inbounds %main.point, ptr %1, i32 0, i32 0 %18 = getelementptr inbounds %main.point, ptr %3, i32 0, i32 0
%17 = load i64, ptr %16, align 4
%18 = getelementptr inbounds %main.point, ptr %1, i32 0, i32 1
%19 = load i64, ptr %18, align 4 %19 = load i64, ptr %18, align 4
%20 = call i32 (ptr, ...) @printf(ptr @0, i64 %17, i64 %19) %20 = getelementptr inbounds %main.point, ptr %3, i32 0, i32 1
%21 = alloca [2 x i64], align 8 %21 = load i64, ptr %20, align 4
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %21, i64 16) %22 = call i32 (ptr, ...) @printf(ptr @0, i64 %19, i64 %21)
%23 = alloca [2 x [2 x i64]], align 8 %23 = alloca [2 x i64], align 8
%24 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %23, i64 32) %24 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %23, i64 16)
%25 = getelementptr inbounds [2 x i64], ptr %24, i64 0 %25 = alloca [2 x [2 x i64]], align 8
%26 = getelementptr inbounds i64, ptr %25, i64 0 %26 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %25, i64 32)
%27 = getelementptr inbounds i64, ptr %25, i64 1 %27 = getelementptr inbounds [2 x i64], ptr %26, i64 0
%28 = getelementptr inbounds [2 x i64], ptr %24, i64 1 %28 = getelementptr inbounds i64, ptr %27, i64 0
%29 = getelementptr inbounds i64, ptr %28, i64 0 %29 = getelementptr inbounds i64, ptr %27, i64 1
%30 = getelementptr inbounds i64, ptr %28, i64 1 %30 = getelementptr inbounds [2 x i64], ptr %26, i64 1
store i64 1, ptr %26, align 4 %31 = getelementptr inbounds i64, ptr %30, i64 0
store i64 2, ptr %27, align 4 %32 = getelementptr inbounds i64, ptr %30, i64 1
store i64 3, ptr %29, align 4 store i64 1, ptr %28, align 4
store i64 4, ptr %30, align 4 store i64 2, ptr %29, align 4
%31 = load [2 x [2 x i64]], ptr %24, align 4 store i64 3, ptr %31, align 4
%32 = getelementptr inbounds [2 x i64], ptr %24, i64 1 store i64 4, ptr %32, align 4
%33 = load [2 x i64], ptr %32, align 4 %33 = load [2 x [2 x i64]], ptr %26, align 4
store [2 x i64] %33, ptr %22, align 4 %34 = getelementptr inbounds [2 x i64], ptr %26, i64 1
%34 = getelementptr inbounds i64, ptr %22, i64 0 %35 = load [2 x i64], ptr %34, align 4
%35 = load i64, ptr %34, align 4 store [2 x i64] %35, ptr %24, align 4
%36 = getelementptr inbounds i64, ptr %22, i64 1 %36 = getelementptr inbounds i64, ptr %24, i64 0
%37 = load i64, ptr %36, align 4 %37 = load i64, ptr %36, align 4
%38 = call i32 (ptr, ...) @printf(ptr @1, i64 %35, i64 %37) %38 = getelementptr inbounds i64, ptr %24, i64 1
%39 = alloca [5 x i64], align 8 %39 = load i64, ptr %38, align 4
%40 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %39, i64 40) %40 = call i32 (ptr, ...) @printf(ptr @1, i64 %37, i64 %39)
%41 = getelementptr inbounds i64, ptr %40, i64 0 %41 = alloca [5 x i64], align 8
%42 = getelementptr inbounds i64, ptr %40, i64 1 %42 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %41, i64 40)
%43 = getelementptr inbounds i64, ptr %40, i64 2 %43 = getelementptr inbounds i64, ptr %42, i64 0
%44 = getelementptr inbounds i64, ptr %40, i64 3 %44 = getelementptr inbounds i64, ptr %42, i64 1
%45 = getelementptr inbounds i64, ptr %40, i64 4 %45 = getelementptr inbounds i64, ptr %42, i64 2
store i64 1, ptr %41, align 4 %46 = getelementptr inbounds i64, ptr %42, i64 3
store i64 2, ptr %42, align 4 %47 = getelementptr inbounds i64, ptr %42, i64 4
store i64 3, ptr %43, align 4 store i64 1, ptr %43, align 4
store i64 4, ptr %44, align 4 store i64 2, ptr %44, align 4
store i64 5, ptr %45, align 4 store i64 3, ptr %45, align 4
%46 = load [5 x i64], ptr %40, align 4 store i64 4, ptr %46, align 4
%47 = getelementptr inbounds i64, ptr %40, i64 2 store i64 5, ptr %47, align 4
%48 = load i64, ptr %47, align 4 %48 = load [5 x i64], ptr %42, align 4
%49 = call i32 (ptr, ...) @printf(ptr @2, i64 %48) %49 = getelementptr inbounds i64, ptr %42, i64 2
%50 = alloca [5 x i64], align 8 %50 = load i64, ptr %49, align 4
%51 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %50, i64 40) %51 = call i32 (ptr, ...) @printf(ptr @2, i64 %50)
%52 = getelementptr inbounds i64, ptr %51, i64 0 %52 = alloca [5 x i64], align 8
%53 = getelementptr inbounds i64, ptr %51, i64 1 %53 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %52, i64 40)
%54 = getelementptr inbounds i64, ptr %51, i64 2 %54 = getelementptr inbounds i64, ptr %53, i64 0
%55 = getelementptr inbounds i64, ptr %51, i64 3 %55 = getelementptr inbounds i64, ptr %53, i64 1
%56 = getelementptr inbounds i64, ptr %51, i64 4 %56 = getelementptr inbounds i64, ptr %53, i64 2
store i64 1, ptr %52, align 4 %57 = getelementptr inbounds i64, ptr %53, i64 3
store i64 2, ptr %53, align 4 %58 = getelementptr inbounds i64, ptr %53, i64 4
store i64 3, ptr %54, align 4 store i64 1, ptr %54, align 4
store i64 4, ptr %55, align 4 store i64 2, ptr %55, align 4
store i64 5, ptr %56, align 4 store i64 3, ptr %56, align 4
%57 = load [5 x i64], ptr %51, align 4 store i64 4, ptr %57, align 4
%58 = getelementptr inbounds i64, ptr %51, i64 2 store i64 5, ptr %58, align 4
%59 = load i64, ptr %58, align 4 %59 = load [5 x i64], ptr %53, align 4
%60 = call i32 (ptr, ...) @printf(ptr @3, i64 %59) %60 = getelementptr inbounds i64, ptr %53, i64 2
%61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 6) %61 = load i64, ptr %60, align 4
%62 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %61) %62 = call i32 (ptr, ...) @printf(ptr @3, i64 %61)
%63 = getelementptr inbounds i8, ptr %62, i64 2 %63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 6)
%64 = load i8, ptr %63, align 1 %64 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %63, 0
%65 = call i32 (ptr, ...) @printf(ptr @4, i8 %64) %65 = getelementptr inbounds i8, ptr %64, i64 2
%66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 6) %66 = load i8, ptr %65, align 1
%67 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %66) %67 = call i32 (ptr, ...) @printf(ptr @4, i8 %66)
%68 = getelementptr inbounds i8, ptr %67, i64 1 %68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 6)
%69 = load i8, ptr %68, align 1 %69 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %68, 0
%70 = call i32 (ptr, ...) @printf(ptr @6, i8 %69) %70 = getelementptr inbounds i8, ptr %69, i64 1
%71 = load i8, ptr %70, align 1
%72 = call i32 (ptr, ...) @printf(ptr @6, i8 %71)
ret void ret void
} }
@@ -134,5 +138,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String")

View File

@@ -5,6 +5,8 @@ source_filename = "main"
%main.generator = type { i32 } %main.generator = type { i32 }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@@ -61,90 +63,92 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = alloca { ptr, ptr }, align 8 %2 = alloca { ptr, ptr }, align 8
%1 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 0 %3 = getelementptr inbounds { ptr, ptr }, ptr %2, i32 0, i32 0
store ptr @__llgo_stub.rand, ptr %1, align 8 store ptr @__llgo_stub.rand, ptr %3, align 8
%2 = getelementptr inbounds { ptr, ptr }, ptr %0, i32 0, i32 1 %4 = getelementptr inbounds { ptr, ptr }, ptr %2, i32 0, i32 1
store ptr null, ptr %2, align 8 store ptr null, ptr %4, align 8
%3 = load { ptr, ptr }, ptr %0, align 8 %5 = load { ptr, ptr }, ptr %2, align 8
%4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %3) %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5)
%5 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) %7 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %6)
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
%6 = phi i64 [ -1, %_llgo_0 ], [ %7, %_llgo_2 ] %8 = phi i64 [ -1, %_llgo_0 ], [ %9, %_llgo_2 ]
%7 = add i64 %6, 1 %9 = add i64 %8, 1
%8 = icmp slt i64 %7, %5 %10 = icmp slt i64 %9, %7
br i1 %8, label %_llgo_2, label %_llgo_3 br i1 %10, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%9 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) %11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %6)
%10 = getelementptr inbounds i32, ptr %9, i64 %7 %12 = getelementptr inbounds i32, ptr %11, i64 %9
%11 = load i32, ptr %10, align 4 %13 = load i32, ptr %12, align 4
%12 = call i32 (ptr, ...) @printf(ptr @0, i32 %11) %14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4) %15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4)
store i32 1, ptr %13, align 4 store i32 1, ptr %15, align 4
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %16 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%15 = getelementptr inbounds { ptr }, ptr %14, i32 0, i32 0 %17 = getelementptr inbounds { ptr }, ptr %16, i32 0, i32 0
store ptr %13, ptr %15, align 8 store ptr %15, ptr %17, align 8
%16 = alloca { ptr, ptr }, align 8 %18 = alloca { ptr, ptr }, align 8
%17 = getelementptr inbounds { ptr, ptr }, ptr %16, i32 0, i32 0 %19 = getelementptr inbounds { ptr, ptr }, ptr %18, i32 0, i32 0
store ptr @"main.main$1", ptr %17, align 8 store ptr @"main.main$1", ptr %19, align 8
%18 = getelementptr inbounds { ptr, ptr }, ptr %16, i32 0, i32 1 %20 = getelementptr inbounds { ptr, ptr }, ptr %18, i32 0, i32 1
store ptr %14, ptr %18, align 8 store ptr %16, ptr %20, align 8
%19 = load { ptr, ptr }, ptr %16, align 8 %21 = load { ptr, ptr }, ptr %18, align 8
%20 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %19) %22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21)
%21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %20) %23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %22)
br label %_llgo_4 br label %_llgo_4
_llgo_4: ; preds = %_llgo_5, %_llgo_3 _llgo_4: ; preds = %_llgo_5, %_llgo_3
%22 = phi i64 [ -1, %_llgo_3 ], [ %23, %_llgo_5 ] %24 = phi i64 [ -1, %_llgo_3 ], [ %25, %_llgo_5 ]
%23 = add i64 %22, 1 %25 = add i64 %24, 1
%24 = icmp slt i64 %23, %21 %26 = icmp slt i64 %25, %23
br i1 %24, label %_llgo_5, label %_llgo_6 br i1 %26, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4 _llgo_5: ; preds = %_llgo_4
%25 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %20) %27 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %22)
%26 = getelementptr inbounds i32, ptr %25, i64 %23 %28 = getelementptr inbounds i32, ptr %27, i64 %25
%27 = load i32, ptr %26, align 4 %29 = load i32, ptr %28, align 4
%28 = call i32 (ptr, ...) @printf(ptr @1, i32 %27) %30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29)
br label %_llgo_4 br label %_llgo_4
_llgo_6: ; preds = %_llgo_4 _llgo_6: ; preds = %_llgo_4
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4) %31 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4)
%30 = getelementptr inbounds %main.generator, ptr %29, i32 0, i32 0 %32 = getelementptr inbounds %main.generator, ptr %31, i32 0, i32 0
store i32 1, ptr %30, align 4 store i32 1, ptr %32, align 4
%31 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %33 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%32 = getelementptr inbounds { ptr }, ptr %31, i32 0, i32 0 %34 = getelementptr inbounds { ptr }, ptr %33, i32 0, i32 0
store ptr %29, ptr %32, align 8 store ptr %31, ptr %34, align 8
%33 = alloca { ptr, ptr }, align 8 %35 = alloca { ptr, ptr }, align 8
%34 = getelementptr inbounds { ptr, ptr }, ptr %33, i32 0, i32 0 %36 = getelementptr inbounds { ptr, ptr }, ptr %35, i32 0, i32 0
store ptr @"main.next$bound", ptr %34, align 8 store ptr @"main.next$bound", ptr %36, align 8
%35 = getelementptr inbounds { ptr, ptr }, ptr %33, i32 0, i32 1 %37 = getelementptr inbounds { ptr, ptr }, ptr %35, i32 0, i32 1
store ptr %31, ptr %35, align 8 store ptr %33, ptr %37, align 8
%36 = load { ptr, ptr }, ptr %33, align 8 %38 = load { ptr, ptr }, ptr %35, align 8
%37 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %36) %39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38)
%38 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %37) %40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %39)
br label %_llgo_7 br label %_llgo_7
_llgo_7: ; preds = %_llgo_8, %_llgo_6 _llgo_7: ; preds = %_llgo_8, %_llgo_6
%39 = phi i64 [ -1, %_llgo_6 ], [ %40, %_llgo_8 ] %41 = phi i64 [ -1, %_llgo_6 ], [ %42, %_llgo_8 ]
%40 = add i64 %39, 1 %42 = add i64 %41, 1
%41 = icmp slt i64 %40, %38 %43 = icmp slt i64 %42, %40
br i1 %41, label %_llgo_8, label %_llgo_9 br i1 %43, label %_llgo_8, label %_llgo_9
_llgo_8: ; preds = %_llgo_7 _llgo_8: ; preds = %_llgo_7
%42 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %37) %44 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %39)
%43 = getelementptr inbounds i32, ptr %42, i64 %40 %45 = getelementptr inbounds i32, ptr %44, i64 %42
%44 = load i32, ptr %43, align 4 %46 = load i32, ptr %45, align 4
%45 = call i32 (ptr, ...) @printf(ptr @2, i32 %44) %47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46)
br label %_llgo_7 br label %_llgo_7
_llgo_9: ; preds = %_llgo_7 _llgo_9: ; preds = %_llgo_7

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [2 x i8] c"a\00", align 1 @0 = private unnamed_addr constant [2 x i8] c"a\00", align 1
@1 = private unnamed_addr constant [2 x i8] c"b\00", align 1 @1 = private unnamed_addr constant [2 x i8] c"b\00", align 1
@2 = private unnamed_addr constant [2 x i8] c"c\00", align 1 @2 = private unnamed_addr constant [2 x i8] c"c\00", align 1
@@ -24,8 +26,10 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr @0, ptr @1, ptr @2, ptr @3) call void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr @0, ptr @1, ptr @2, ptr @3)

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1
define void @main.init() { define void @main.init() {
@@ -17,12 +19,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"() %2 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"()
%1 = call i32 (ptr, ...) @printf(ptr @0, <null operand!>) %3 = call i32 (ptr, ...) @printf(ptr @0, <null operand!>)
ret void ret void
} }

39
cl/_testrt/named/in.go Normal file
View File

@@ -0,0 +1,39 @@
package main
import "github.com/goplus/llgo/internal/runtime/c"
type mSpanList struct {
first *mspan
last *mspan
}
type minfo struct {
span *mspan
info int
}
type mspan struct {
next *mspan
prev *mspan
list *mSpanList
info minfo
value int
check func(int) int
}
func main() {
m := &mspan{}
m.value = 100
m.next = &mspan{}
m.next.value = 200
m.list = &mSpanList{}
m.list.last = &mspan{}
m.list.last.value = 300
m.info.info = 10
m.info.span = m
m.check = func(n int) int {
return m.value * n
}
c.Printf(c.Str("%d %d %d %d %d %d\n"), m.next.value, m.list.last.value, m.info.info,
m.info.span.value, m.check(-2), m.info.span.check(-3))
}

143
cl/_testrt/named/out.ll Normal file
View File

@@ -0,0 +1,143 @@
; ModuleID = 'main'
source_filename = "main"
%main.mspan = type { ptr, ptr, ptr, %main.minfo, i64, { ptr, ptr } }
%main.minfo = type { ptr, i64 }
%main.mSpanList = type { ptr, ptr }
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [19 x i8] c"%d %d %d %d %d %d\0A\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 void @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 8)
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
store ptr %3, ptr %2, align 8
%4 = load ptr, ptr %2, align 8
%5 = getelementptr inbounds %main.mspan, ptr %4, i32 0, i32 4
store i64 100, ptr %5, align 4
%6 = load ptr, ptr %2, align 8
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
%8 = getelementptr inbounds %main.mspan, ptr %6, i32 0, i32 0
store ptr %7, ptr %8, align 8
%9 = load ptr, ptr %2, align 8
%10 = getelementptr inbounds %main.mspan, ptr %9, i32 0, i32 0
%11 = load ptr, ptr %10, align 8
%12 = getelementptr inbounds %main.mspan, ptr %11, i32 0, i32 4
store i64 200, ptr %12, align 4
%13 = load ptr, ptr %2, align 8
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%15 = getelementptr inbounds %main.mspan, ptr %13, i32 0, i32 2
store ptr %14, ptr %15, align 8
%16 = load ptr, ptr %2, align 8
%17 = getelementptr inbounds %main.mspan, ptr %16, i32 0, i32 2
%18 = load ptr, ptr %17, align 8
%19 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
%20 = getelementptr inbounds %main.mSpanList, ptr %18, i32 0, i32 1
store ptr %19, ptr %20, align 8
%21 = load ptr, ptr %2, align 8
%22 = getelementptr inbounds %main.mspan, ptr %21, i32 0, i32 2
%23 = load ptr, ptr %22, align 8
%24 = getelementptr inbounds %main.mSpanList, ptr %23, i32 0, i32 1
%25 = load ptr, ptr %24, align 8
%26 = getelementptr inbounds %main.mspan, ptr %25, i32 0, i32 4
store i64 300, ptr %26, align 4
%27 = load ptr, ptr %2, align 8
%28 = getelementptr inbounds %main.mspan, ptr %27, i32 0, i32 3
%29 = getelementptr inbounds %main.minfo, ptr %28, i32 0, i32 1
store i64 10, ptr %29, align 4
%30 = load ptr, ptr %2, align 8
%31 = getelementptr inbounds %main.mspan, ptr %30, i32 0, i32 3
%32 = load ptr, ptr %2, align 8
%33 = getelementptr inbounds %main.minfo, ptr %31, i32 0, i32 0
store ptr %32, ptr %33, align 8
%34 = load ptr, ptr %2, align 8
%35 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%36 = getelementptr inbounds { ptr }, ptr %35, i32 0, i32 0
store ptr %2, ptr %36, align 8
%37 = alloca { ptr, ptr }, align 8
%38 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 0
store ptr @"main.main$1", ptr %38, align 8
%39 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 1
store ptr %35, ptr %39, align 8
%40 = load { ptr, ptr }, ptr %37, align 8
%41 = getelementptr inbounds %main.mspan, ptr %34, i32 0, i32 5
store { ptr, ptr } %40, ptr %41, align 8
%42 = load ptr, ptr %2, align 8
%43 = getelementptr inbounds %main.mspan, ptr %42, i32 0, i32 0
%44 = load ptr, ptr %43, align 8
%45 = getelementptr inbounds %main.mspan, ptr %44, i32 0, i32 4
%46 = load i64, ptr %45, align 4
%47 = load ptr, ptr %2, align 8
%48 = getelementptr inbounds %main.mspan, ptr %47, i32 0, i32 2
%49 = load ptr, ptr %48, align 8
%50 = getelementptr inbounds %main.mSpanList, ptr %49, i32 0, i32 1
%51 = load ptr, ptr %50, align 8
%52 = getelementptr inbounds %main.mspan, ptr %51, i32 0, i32 4
%53 = load i64, ptr %52, align 4
%54 = load ptr, ptr %2, align 8
%55 = getelementptr inbounds %main.mspan, ptr %54, i32 0, i32 3
%56 = getelementptr inbounds %main.minfo, ptr %55, i32 0, i32 1
%57 = load i64, ptr %56, align 4
%58 = load ptr, ptr %2, align 8
%59 = getelementptr inbounds %main.mspan, ptr %58, i32 0, i32 3
%60 = getelementptr inbounds %main.minfo, ptr %59, i32 0, i32 0
%61 = load ptr, ptr %60, align 8
%62 = getelementptr inbounds %main.mspan, ptr %61, i32 0, i32 4
%63 = load i64, ptr %62, align 4
%64 = load ptr, ptr %2, align 8
%65 = getelementptr inbounds %main.mspan, ptr %64, i32 0, i32 5
%66 = load { ptr, ptr }, ptr %65, align 8
%67 = extractvalue { ptr, ptr } %66, 1
%68 = extractvalue { ptr, ptr } %66, 0
%69 = call i64 %68(ptr %67, i64 -2)
%70 = load ptr, ptr %2, align 8
%71 = getelementptr inbounds %main.mspan, ptr %70, i32 0, i32 3
%72 = getelementptr inbounds %main.minfo, ptr %71, i32 0, i32 0
%73 = load ptr, ptr %72, align 8
%74 = getelementptr inbounds %main.mspan, ptr %73, i32 0, i32 5
%75 = load { ptr, ptr }, ptr %74, align 8
%76 = extractvalue { ptr, ptr } %75, 1
%77 = extractvalue { ptr, ptr } %75, 0
%78 = call i64 %77(ptr %76, i64 -3)
%79 = call i32 (ptr, ...) @printf(ptr @0, i64 %46, i64 %53, i64 %57, i64 %63, i64 %69, i64 %78)
ret void
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define i64 @"main.main$1"(ptr %0, i64 %1) {
_llgo_0:
%2 = load { ptr }, ptr %0, align 8
%3 = extractvalue { ptr } %2, 0
%4 = load ptr, ptr %3, align 8
%5 = getelementptr inbounds %main.mspan, ptr %4, i32 0, i32 4
%6 = load i64, ptr %5, align 4
%7 = mul i64 %6, %1
ret i64 %7
}
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
declare i32 @printf(ptr, ...)

View File

@@ -5,6 +5,8 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } %"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [14 x i8] c"panic message\00", align 1 @0 = private unnamed_addr constant [14 x i8] c"panic message\00", align 1
define void @main.init() { define void @main.init() {
@@ -20,13 +22,15 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 13) %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 13)
%1 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %0) %3 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %2)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %1) call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %3)
unreachable unreachable
} }

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
define void @main.init() { define void @main.init() {
@@ -17,36 +19,38 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 40)
%1 = getelementptr inbounds i64, ptr %0, i64 0 %3 = getelementptr inbounds i64, ptr %2, i64 0
%2 = getelementptr inbounds i64, ptr %0, i64 1 %4 = getelementptr inbounds i64, ptr %2, i64 1
%3 = getelementptr inbounds i64, ptr %0, i64 2 %5 = getelementptr inbounds i64, ptr %2, i64 2
%4 = getelementptr inbounds i64, ptr %0, i64 3 %6 = getelementptr inbounds i64, ptr %2, i64 3
%5 = getelementptr inbounds i64, ptr %0, i64 4 %7 = getelementptr inbounds i64, ptr %2, i64 4
store i64 100, ptr %1, align 4 store i64 100, ptr %3, align 4
store i64 8, ptr %2, align 4 store i64 8, ptr %4, align 4
store i64 23, ptr %3, align 4 store i64 23, ptr %5, align 4
store i64 2, ptr %4, align 4 store i64 2, ptr %6, align 4
store i64 7, ptr %5, align 4 store i64 7, ptr %7, align 4
%6 = getelementptr inbounds i64, ptr %0, i64 0 %8 = getelementptr inbounds i64, ptr %2, i64 0
call void @qsort(ptr %6, i64 5, i64 8, ptr @"main.main$1") call void @qsort(ptr %8, i64 5, i64 8, ptr @"main.main$1")
%7 = load [5 x i64], ptr %0, align 4 %9 = load [5 x i64], ptr %2, align 4
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
%8 = phi i64 [ -1, %_llgo_0 ], [ %9, %_llgo_2 ] %10 = phi i64 [ -1, %_llgo_0 ], [ %11, %_llgo_2 ]
%9 = add i64 %8, 1 %11 = add i64 %10, 1
%10 = icmp slt i64 %9, 5 %12 = icmp slt i64 %11, 5
br i1 %10, label %_llgo_2, label %_llgo_3 br i1 %12, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%11 = getelementptr inbounds i64, ptr %0, i64 %9 %13 = getelementptr inbounds i64, ptr %2, i64 %11
%12 = load i64, ptr %11, align 4 %14 = load i64, ptr %13, align 4
%13 = call i32 (ptr, ...) @printf(ptr @0, i64 %12) %15 = call i32 (ptr, ...) @printf(ptr @0, i64 %14)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@2 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1 @2 = private unnamed_addr constant [7 x i8] c"%d %d\0A\00", align 1
@@ -43,28 +45,30 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call { ptr, ptr } @"main.main$1"() %2 = call { ptr, ptr } @"main.main$1"()
%1 = extractvalue { ptr, ptr } %0, 1 %3 = extractvalue { ptr, ptr } %2, 1
%2 = extractvalue { ptr, ptr } %0, 0 %4 = extractvalue { ptr, ptr } %2, 0
%3 = call i64 %2(ptr %1, i64 100, i64 200) %5 = call i64 %4(ptr %3, i64 100, i64 200)
%4 = call i32 (ptr, ...) @printf(ptr @0, i64 %3) %6 = call i32 (ptr, ...) @printf(ptr @0, i64 %5)
%5 = call { ptr, ptr } @main.add() %7 = call { ptr, ptr } @main.add()
%6 = extractvalue { ptr, ptr } %5, 1 %8 = extractvalue { ptr, ptr } %7, 1
%7 = extractvalue { ptr, ptr } %5, 0 %9 = extractvalue { ptr, ptr } %7, 0
%8 = call i64 %7(ptr %6, i64 100, i64 200) %10 = call i64 %9(ptr %8, i64 100, i64 200)
%9 = call i32 (ptr, ...) @printf(ptr @1, i64 %8) %11 = call i32 (ptr, ...) @printf(ptr @1, i64 %10)
%10 = call { { ptr, ptr }, i64 } @main.add2() %12 = call { { ptr, ptr }, i64 } @main.add2()
%11 = extractvalue { { ptr, ptr }, i64 } %10, 0 %13 = extractvalue { { ptr, ptr }, i64 } %12, 0
%12 = extractvalue { { ptr, ptr }, i64 } %10, 1 %14 = extractvalue { { ptr, ptr }, i64 } %12, 1
%13 = call { ptr, ptr } @main.add() %15 = call { ptr, ptr } @main.add()
%14 = extractvalue { ptr, ptr } %13, 1 %16 = extractvalue { ptr, ptr } %15, 1
%15 = extractvalue { ptr, ptr } %13, 0 %17 = extractvalue { ptr, ptr } %15, 0
%16 = call i64 %15(ptr %14, i64 100, i64 200) %18 = call i64 %17(ptr %16, i64 100, i64 200)
%17 = call i32 (ptr, ...) @printf(ptr @2, i64 %16, i64 %12) %19 = call i32 (ptr, ...) @printf(ptr @2, i64 %18, i64 %14)
ret void ret void
} }

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -27,12 +29,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call i32 @strlen(ptr @main.format) %2 = call i32 @strlen(ptr @main.format)
call void (ptr, ...) @printf(ptr @main.format, i32 %0) call void (ptr, ...) @printf(ptr @main.format, i32 %2)
ret void ret void
} }

View File

@@ -5,6 +5,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @"(main.Foo).Print"(%main.Foo %0) { define void @"(main.Foo).Print"(%main.Foo %0) {
_llgo_0: _llgo_0:
@@ -55,18 +57,20 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = alloca %main.Foo, align 8 %2 = alloca %main.Foo, align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %0, i64 8) %3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 8)
%2 = getelementptr inbounds %main.Foo, ptr %1, i32 0, i32 0 %4 = getelementptr inbounds %main.Foo, ptr %3, i32 0, i32 0
%3 = getelementptr inbounds %main.Foo, ptr %1, i32 0, i32 1 %5 = getelementptr inbounds %main.Foo, ptr %3, i32 0, i32 1
store i32 100, ptr %2, align 4 store i32 100, ptr %4, align 4
store i1 true, ptr %3, align 1 store i1 true, ptr %5, align 1
%4 = load %main.Foo, ptr %1, align 4 %6 = load %main.Foo, ptr %3, align 4
call void @"(main.Foo).Print"(%main.Foo %4) call void @"(main.Foo).Print"(%main.Foo %6)
ret void ret void
} }

View File

@@ -4,6 +4,8 @@ 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 }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 @0 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1
define void @main.init() { define void @main.init() {
@@ -19,22 +21,24 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%1 = getelementptr inbounds i64, ptr %0, i64 0 %3 = getelementptr inbounds i64, ptr %2, i64 0
store i64 1, ptr %1, align 4 store i64 1, ptr %3, align 4
%2 = getelementptr inbounds i64, ptr %0, i64 1 %4 = getelementptr inbounds i64, ptr %2, i64 1
store i64 2, ptr %2, align 4 store i64 2, ptr %4, align 4
%3 = getelementptr inbounds i64, ptr %0, i64 2 %5 = getelementptr inbounds i64, ptr %2, i64 2
store i64 3, ptr %3, align 4 store i64 3, ptr %5, align 4
%4 = getelementptr inbounds i64, ptr %0, i64 3 %6 = getelementptr inbounds i64, ptr %2, i64 3
store i64 4, ptr %4, align 4 store i64 4, ptr %6, align 4
%5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %0, i64 8, i64 4, i64 0, i64 4, i64 4) %7 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 8, i64 4, i64 0, i64 4, i64 4)
%6 = call i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %5) %8 = call i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%7 = call i32 (ptr, ...) @printf(ptr @0, i64 %6) %9 = call i32 (ptr, ...) @printf(ptr @0, i64 %8)
ret void ret void
} }

View File

@@ -3,6 +3,8 @@ source_filename = "main"
@main.format = global ptr null @main.format = global ptr null
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
define void @main.Print(ptr %0) { define void @main.Print(ptr %0) {
_llgo_0: _llgo_0:
@@ -43,16 +45,18 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
%1 = getelementptr inbounds { i32, i1 }, ptr %0, i32 0, i32 0 %3 = getelementptr inbounds { i32, i1 }, ptr %2, i32 0, i32 0
%2 = getelementptr inbounds { i32, i1 }, ptr %0, i32 0, i32 1 %4 = getelementptr inbounds { i32, i1 }, ptr %2, i32 0, i32 1
store i32 100, ptr %1, align 4 store i32 100, ptr %3, align 4
store i1 true, ptr %2, align 1 store i1 true, ptr %4, align 1
call void @main.Print(ptr %0) call void @main.Print(ptr %2)
ret void ret void
} }

View File

@@ -2,6 +2,8 @@
source_filename = "main" source_filename = "main"
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1 @0 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1
define void @main.foo() { define void @main.foo() {
@@ -23,12 +25,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main() { define void @main(i32 %0, ptr %1) {
_llgo_0: _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 @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init() call void @main.init()
call void @main.foo() call void @main.foo()
%0 = call i32 (ptr, ...) @printf(ptr @0) %2 = call i32 (ptr, ...) @printf(ptr @0)
ret void ret void
} }

View File

@@ -17,6 +17,7 @@
package cl package cl
import ( import (
"go/ast"
"go/constant" "go/constant"
"go/types" "go/types"
"testing" "testing"
@@ -25,6 +26,27 @@ import (
"golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa"
) )
func TestRecvTypeName(t *testing.T) {
if ret := recvTypeName(&ast.IndexExpr{
X: &ast.Ident{Name: "Pointer"},
Index: &ast.Ident{Name: "T"},
}); ret != "Pointer" {
t.Fatal("recvTypeName IndexExpr:", ret)
}
if ret := recvTypeName(&ast.IndexListExpr{
X: &ast.Ident{Name: "Pointer"},
Indices: []ast.Expr{&ast.Ident{Name: "T"}},
}); ret != "Pointer" {
t.Fatal("recvTypeName IndexListExpr:", ret)
}
defer func() {
if r := recover(); r == nil {
t.Fatal("recvTypeName: no error?")
}
}()
recvTypeName(&ast.BadExpr{})
}
/* /*
func TestErrCompileValue(t *testing.T) { func TestErrCompileValue(t *testing.T) {
defer func() { defer func() {
@@ -78,6 +100,16 @@ func TestErrAlloca(t *testing.T) {
ctx.alloca(nil, nil) ctx.alloca(nil, nil)
} }
func TestErrAllocaCStr(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fatal("allocaCStr: no error?")
}
}()
var ctx context
ctx.allocaCStr(nil, nil)
}
func TestCStrNoArgs(t *testing.T) { func TestCStrNoArgs(t *testing.T) {
defer func() { defer func() {
if r := recover(); r == nil { if r := recover(); r == nil {
@@ -108,16 +140,19 @@ func TestPkgNoInit(t *testing.T) {
} }
func TestPkgKind(t *testing.T) { func TestPkgKind(t *testing.T) {
if v := pkgKind("noinit"); v != PkgNoInit { if v, _ := pkgKind("link: hello.a"); v != PkgLinkExtern {
t.Fatal("pkgKind:", v) t.Fatal("pkgKind:", v)
} }
if v := pkgKind(""); v != PkgLLGo { if v, _ := pkgKind("noinit"); v != PkgNoInit {
t.Fatal("pkgKind:", v)
}
if v, _ := pkgKind(""); v != PkgLLGo {
t.Fatal("pkgKind:", v) t.Fatal("pkgKind:", v)
} }
} }
func TestPkgKindOf(t *testing.T) { func TestPkgKindOf(t *testing.T) {
if v := PkgKindOf(types.Unsafe); v != PkgDeclOnly { if v, _ := PkgKindOf(types.Unsafe); v != PkgDeclOnly {
t.Fatal("PkgKindOf unsafe:", v) t.Fatal("PkgKindOf unsafe:", v)
} }
pkg := types.NewPackage("foo", "foo") pkg := types.NewPackage("foo", "foo")
@@ -126,7 +161,7 @@ func TestPkgKindOf(t *testing.T) {
0, pkg, "LLGoPackage", types.Typ[types.String], 0, pkg, "LLGoPackage", types.Typ[types.String],
constant.MakeString("noinit")), constant.MakeString("noinit")),
) )
if v := PkgKindOf(pkg); v != PkgNoInit { if v, _ := PkgKindOf(pkg); v != PkgNoInit {
t.Fatal("PkgKindOf foo:", v) t.Fatal("PkgKindOf foo:", v)
} }
} }
@@ -159,13 +194,21 @@ func TestErrImport(t *testing.T) {
} }
func TestErrInitLinkname(t *testing.T) { func TestErrInitLinkname(t *testing.T) {
var ctx context
ctx.initLinkname("//llgo:link abc", func(name string) (string, bool, bool) {
return "", false, false
})
ctx.initLinkname("//go:linkname Printf printf", func(name string) (string, bool, bool) {
return "", false, false
})
defer func() { defer func() {
if r := recover(); r == nil { if r := recover(); r == nil {
t.Fatal("initLinkname: no error?") t.Fatal("initLinkname: no error?")
} }
}() }()
var ctx context ctx.initLinkname("//go:linkname Printf printf", func(name string) (string, bool, bool) {
ctx.initLinkname("foo", "//go:linkname Printf printf", false) return "foo.Printf", false, name == "Printf"
})
} }
func TestErrVarOf(t *testing.T) { func TestErrVarOf(t *testing.T) {

View File

@@ -17,10 +17,12 @@
package cltest package cltest
import ( import (
"archive/zip"
"go/ast" "go/ast"
"go/parser" "go/parser"
"go/token" "go/token"
"go/types" "go/types"
"io"
"log" "log"
"os" "os"
"path" "path"
@@ -63,11 +65,36 @@ func FromDir(t *testing.T, sel, relDir string, byLLGen bool) {
} }
} }
// *.ll => *.lla
func decodeLinkFile(llFile string) (data []byte, err error) {
zipFile := llFile + "a"
zipf, err := zip.OpenReader(zipFile)
if err != nil {
return
}
defer zipf.Close()
f, err := zipf.Open("llgo_autogen.ll")
if err != nil {
return
}
defer f.Close()
data, err = io.ReadAll(f)
if err == nil {
os.WriteFile(llFile, data, 0644)
}
return
}
func Pkg(t *testing.T, pkgPath, outFile string) { func Pkg(t *testing.T, pkgPath, outFile string) {
b, err := os.ReadFile(outFile) b, err := os.ReadFile(outFile)
if err != nil { if err != nil {
if !os.IsNotExist(err) {
t.Fatal("ReadFile failed:", err) t.Fatal("ReadFile failed:", err)
} }
if b, err = decodeLinkFile(outFile); err != nil {
t.Fatal("decodeLinkFile failed:", err)
}
}
expected := string(b) expected := string(b)
if v := llgen.GenFrom(pkgPath); v != expected { if v := llgen.GenFrom(pkgPath); v != expected {
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
@@ -120,11 +147,23 @@ func TestCompileEx(t *testing.T, src any, fname, expected string) {
} }
return rt return rt
}) })
prog.SetPython(func() *types.Package {
rt, err := imp.Import(llssa.PkgPython)
if err != nil {
t.Fatal("load python failed:", err)
}
return rt
})
ret, err := cl.NewPackage(prog, foo, files) ret, err := cl.NewPackage(prog, foo, files)
if err != nil { if err != nil {
t.Fatal("cl.NewPackage failed:", err) t.Fatal("cl.NewPackage failed:", err)
} }
if prog.NeedPyInit { // call PyInit if needed
ret.PyInit()
}
if v := ret.String(); v != expected { if v := ret.String(); v != expected {
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
} }

View File

@@ -62,13 +62,15 @@ const (
) )
func (p *context) funcKind(vfn ssa.Value) int { func (p *context) funcKind(vfn ssa.Value) int {
if fn, ok := vfn.(*ssa.Function); ok && fn.Signature.Recv() == nil { if fn, ok := vfn.(*ssa.Function); ok {
params := fn.Signature.Params() params := fn.Signature.Params()
n := params.Len() n := params.Len()
if n == 0 { if n == 0 {
if fn.Signature.Recv() == nil {
if fn.Name() == "init" && p.pkgNoInit(fn.Pkg.Pkg) { if fn.Name() == "init" && p.pkgNoInit(fn.Pkg.Pkg) {
return fnIgnore return fnIgnore
} }
}
} else { } else {
last := params.At(n - 1) last := params.At(n - 1)
if last.Name() == llssa.NameValist { if last.Name() == llssa.NameValist {
@@ -121,8 +123,12 @@ type instrOrValue interface {
const ( const (
PkgNormal = iota PkgNormal = iota
PkgLLGo PkgLLGo
PkgPyModule // py.<module>
PkgNoInit // noinit: a package that don't need to be initialized PkgNoInit // noinit: a package that don't need to be initialized
PkgDeclOnly // decl: a package that only have declarations PkgDeclOnly // decl: a package that only have declarations
PkgLinkIR // link llvm ir (.ll)
PkgLinkExtern // link external object (.a/.so/.dll/.dylib/etc.)
// PkgLinkBitCode // link bitcode (.bc)
) )
type pkgInfo struct { type pkgInfo struct {
@@ -137,6 +143,7 @@ type context struct {
goProg *ssa.Program goProg *ssa.Program
goTyps *types.Package goTyps *types.Package
goPkg *ssa.Package goPkg *ssa.Package
pyMod string
link map[string]string // pkgPath.nameInPkg => linkname link map[string]string // pkgPath.nameInPkg => linkname
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
@@ -169,7 +176,7 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
for i, n := 0, mthds.Len(); i < n; i++ { for i, n := 0, mthds.Len(); i < n; i++ {
mthd := mthds.At(i) mthd := mthds.At(i)
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil { if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
p.compileFuncDecl(pkg, mthd.Obj().Pkg(), ssaMthd) p.compileFuncDecl(pkg, ssaMthd, false)
} }
} }
} }
@@ -200,14 +207,23 @@ func makeClosureCtx(pkg *types.Package, vars []*ssa.FreeVar) *types.Var {
return types.NewParam(token.NoPos, pkg, "__llgo_ctx", t) return types.NewParam(token.NoPos, pkg, "__llgo_ctx", t)
} }
func (p *context) compileFuncDecl(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) llssa.Function { var (
name, ftype := p.funcName(pkgTypes, f, true) argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8]))
)
func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyObjRef, int) {
pkgTypes, name, ftype := p.funcName(f, true)
if ftype != goFunc { if ftype != goFunc {
return nil if ftype == pyFunc {
// TODO(xsw): pyMod == ""
fnName := pysymPrefix + p.pyMod + "." + name
return nil, pkg.NewPyFunc(fnName, f.Signature, call), pyFunc
}
return nil, nil, ignoredFunc
} }
fn := pkg.FuncOf(name) fn := pkg.FuncOf(name)
if fn != nil && fn.HasBody() { if fn != nil && fn.HasBody() {
return fn return fn, nil, goFunc
} }
var sig = f.Signature var sig = f.Signature
@@ -224,6 +240,12 @@ func (p *context) compileFuncDecl(pkg llssa.Package, pkgTypes *types.Package, f
} }
} }
if fn == nil { if fn == nil {
if name == "main" {
argc := types.NewParam(token.NoPos, pkgTypes, "", types.Typ[types.Int32])
argv := types.NewParam(token.NoPos, pkgTypes, "", argvTy)
params := types.NewTuple(argc, argv)
sig = types.NewSignatureType(nil, nil, nil, params, nil, false)
}
fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx) fn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), hasCtx)
} }
if nblk := len(f.Blocks); nblk > 0 { if nblk := len(f.Blocks); nblk > 0 {
@@ -247,55 +269,137 @@ func (p *context) compileFuncDecl(pkg llssa.Package, pkgTypes *types.Package, f
off[i] = p.compilePhis(b, block) off[i] = p.compilePhis(b, block)
} }
for i, block := range f.Blocks { for i, block := range f.Blocks {
p.compileBlock(b, block, off[i], i == 0 && name == "main") doMainInit := (i == 0 && name == "main")
doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil)
p.compileBlock(b, block, off[i], doMainInit, doModInit)
} }
for _, phi := range p.phis { for _, phi := range p.phis {
phi() phi()
} }
}) })
} }
return fn return fn, nil, goFunc
} }
// funcOf returns a function by name and set ftype = goFunc, cFunc, etc. // funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
// or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc. // or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc.
func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) { func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObjRef, ftype int) {
pkgTypes := p.ensureLoaded(fn.Pkg.Pkg) pkgTypes, name, ftype := p.funcName(fn, false)
switch ftype {
case pyFunc:
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
pkg := p.pkg pkg := p.pkg
name, ftype := p.funcName(pkgTypes, fn, false) fnName := pysymPrefix + mod + "." + name
if ftype == llgoInstr { if pyFn = pkg.PyObjOf(fnName); pyFn == nil {
pyFn = pkg.NewPyFunc(fnName, fn.Signature, true)
return
}
}
ftype = ignoredFunc
case llgoInstr:
switch name { switch name {
case "cstr": case "cstr":
ftype = llgoCstr ftype = llgoCstr
case "advance": case "advance":
ftype = llgoAdvance ftype = llgoAdvance
case "index":
ftype = llgoIndex
case "alloca": case "alloca":
ftype = llgoAlloca ftype = llgoAlloca
case "allocaCStr": case "allocaCStr":
ftype = llgoAllocaCStr ftype = llgoAllocaCStr
case "stringData":
ftype = llgoStringData
case "unreachable": case "unreachable":
ftype = llgoUnreachable ftype = llgoUnreachable
default: default:
panic("unknown llgo instruction: " + name) panic("unknown llgo instruction: " + name)
} }
} else if ret = pkg.FuncOf(name); ret == nil && len(fn.FreeVars) == 0 { default:
pkg := p.pkg
if aFn = pkg.FuncOf(name); aFn == nil {
if len(fn.FreeVars) > 0 {
return nil, nil, ignoredFunc
}
sig := fn.Signature sig := fn.Signature
ret = pkg.NewFuncEx(name, sig, llssa.Background(ftype), false) aFn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), false)
}
} }
return return
} }
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doInit bool) llssa.BasicBlock { func modOf(name string) string {
ret := p.fn.Block(block.Index) if pos := strings.LastIndexByte(name, '.'); pos > 0 {
return name[:pos]
}
return ""
}
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock {
var last int
var pyModInit bool
var prog = p.prog
var pkg = p.pkg
var instrs = block.Instrs[n:]
var ret = p.fn.Block(block.Index)
b.SetBlock(ret) b.SetBlock(ret)
if doInit { if doModInit {
pkg := p.pkg if pyModInit = p.pyMod != ""; pyModInit {
last = len(instrs) - 1
instrs = instrs[:last]
} else {
// TODO(xsw): confirm pyMod don't need to call LoadPyModSyms
p.inits = append(p.inits, func() {
if objs := pkg.PyObjs(); len(objs) > 0 {
mods := make(map[string][]llssa.PyObjRef)
for name, obj := range objs {
modName := modOf(name)
mods[modName] = append(mods[modName], obj)
}
// sort by module name
modNames := make([]string, 0, len(mods))
for modName := range mods {
modNames = append(modNames, modName)
}
sort.Strings(modNames)
b.SetBlockEx(ret, llssa.AfterInit)
for _, modName := range modNames {
objs := mods[modName]
b.LoadPyModSyms(modName, objs...)
}
}
})
}
} else if doMainInit {
fn := p.fn
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
argc.Init(prog.Null(argc.Type))
argv.Init(prog.Null(argv.Type))
b.Store(argc.Expr, fn.Param(0))
b.Store(argv.Expr, fn.Param(1))
callRuntimeInit(b, pkg) callRuntimeInit(b, pkg)
b.Call(pkg.FuncOf("main.init").Expr) b.Call(pkg.FuncOf("main.init").Expr)
} }
for _, instr := range block.Instrs[n:] { for _, instr := range instrs {
p.compileInstr(b, instr) p.compileInstr(b, instr)
} }
if pyModInit {
jump := block.Instrs[n+last].(*ssa.Jump)
jumpTo := p.jumpTo(jump)
modPath := p.pyMod
modName := pysymPrefix + modPath
modPtr := pkg.NewPyModVar(modName, true).Expr
mod := b.Load(modPtr)
cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type))
newBlk := p.fn.MakeBlock()
b.If(cond, jumpTo, newBlk)
b.SetBlock(newBlk)
b.Store(modPtr, b.ImportPyMod(modPath))
b.Jump(jumpTo)
}
return ret return ret
} }
@@ -304,8 +408,7 @@ const (
) )
func callRuntimeInit(b llssa.Builder, pkg llssa.Package) { func callRuntimeInit(b llssa.Builder, pkg llssa.Package) {
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) fn := pkg.NewFunc(RuntimeInit, llssa.NoArgsNoRet, llssa.InC) // don't need to convert runtime.init
fn := pkg.NewFunc(RuntimeInit, sig, llssa.InC) // don't need to convert runtime.init
b.Call(fn.Expr) b.Call(fn.Expr)
} }
@@ -333,9 +436,9 @@ func (p *context) isVArgs(vx ssa.Value) (ret []llssa.Expr, ok bool) {
} }
func (p *context) checkVArgs(v *ssa.Alloc, t *types.Pointer) bool { func (p *context) checkVArgs(v *ssa.Alloc, t *types.Pointer) bool {
if v.Comment == "varargs" { // this is a varargs allocation if v.Comment == "varargs" { // this maybe a varargs allocation
if arr, ok := t.Elem().(*types.Array); ok { if arr, ok := t.Elem().(*types.Array); ok {
if isAny(arr.Elem()) { if isAny(arr.Elem()) && isVargs(p, v) {
p.vargs[v] = make([]llssa.Expr, arr.Len()) p.vargs[v] = make([]llssa.Expr, arr.Len())
return true return true
} }
@@ -344,6 +447,20 @@ func (p *context) checkVArgs(v *ssa.Alloc, t *types.Pointer) bool {
return false return false
} }
func isVargs(ctx *context, v *ssa.Alloc) bool {
refs := *v.Referrers()
n := len(refs)
lastref := refs[n-1]
if i, ok := lastref.(*ssa.Slice); ok {
if refs = *i.Referrers(); len(refs) == 1 {
if call, ok := refs[0].(*ssa.Call); ok {
return ctx.funcKind(call.Call.Value) == fnHasVArg
}
}
}
return false
}
// func cstr(string) *int8 // func cstr(string) *int8
func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
if len(args) == 1 { if len(args) == 1 {
@@ -357,6 +474,12 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
panic("cstr(<string-literal>): invalid arguments") panic("cstr(<string-literal>): invalid arguments")
} }
// func index(arr *T, idx int) T
func (p *context) index(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
return b.Load(p.advance(b, args))
}
// func advance(ptr *T, offset int) *T
func (p *context) advance(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { func (p *context) advance(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
if len(args) == 2 { if len(args) == 2 {
ptr := p.compileValue(b, args[0]) ptr := p.compileValue(b, args[0])
@@ -384,6 +507,15 @@ func (p *context) allocaCStr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr)
panic("allocaCStr(s string): invalid arguments") panic("allocaCStr(s string): invalid arguments")
} }
// func stringData(s string) *int8
func (p *context) stringData(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
if len(args) == 1 {
s := p.compileValue(b, args[0])
return b.StringData(s)
}
panic("stringData(s string): invalid arguments")
}
func isPhi(i ssa.Instruction) bool { func isPhi(i ssa.Instruction) bool {
_, ok := i.(*ssa.Phi) _, ok := i.(*ssa.Phi)
return ok return ok
@@ -391,7 +523,7 @@ func isPhi(i ssa.Instruction) bool {
func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int { func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
ret := p.fn.Block(block.Index) ret := p.fn.Block(block.Index)
b.SetBlock(ret) b.SetBlockEx(ret, llssa.AtEnd)
if ninstr := len(block.Instrs); ninstr > 0 { if ninstr := len(block.Instrs); ninstr > 0 {
if isPhi(block.Instrs[0]) { if isPhi(block.Instrs[0]) {
n := 1 n := 1
@@ -439,40 +571,47 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
} }
switch v := iv.(type) { switch v := iv.(type) {
case *ssa.Call: case *ssa.Call:
call := v.Call cv := v.Call.Value
cv := call.Value
kind := p.funcKind(cv) kind := p.funcKind(cv)
if kind == fnIgnore { if kind == fnIgnore {
return return
} }
args := v.Call.Args
if debugGoSSA { if debugGoSSA {
log.Println(">>> Call", cv, call.Args) log.Println(">>> Call", cv, args)
} }
switch cv := cv.(type) { switch cv := cv.(type) {
case *ssa.Builtin: case *ssa.Builtin:
fn := cv.Name() fn := cv.Name()
if fn == "ssa:wrapnilchk" { // TODO(xsw): check nil ptr if fn == "ssa:wrapnilchk" { // TODO(xsw): check nil ptr
arg := call.Args[0] arg := args[0]
ret = p.compileValue(b, arg) ret = p.compileValue(b, arg)
// log.Println("wrapnilchk:", ret.TypeOf()) // log.Println("wrapnilchk:", ret.TypeOf())
} else { } else {
args := p.compileValues(b, call.Args, kind) args := p.compileValues(b, args, kind)
ret = b.BuiltinCall(fn, args...) ret = b.BuiltinCall(fn, args...)
} }
case *ssa.Function: case *ssa.Function:
fn, ftype := p.compileFunction(cv) aFn, pyFn, ftype := p.compileFunction(cv)
switch ftype { switch ftype {
case goFunc, cFunc: case goFunc, cFunc:
args := p.compileValues(b, call.Args, kind) args := p.compileValues(b, args, kind)
ret = b.Call(fn.Expr, args...) ret = b.Call(aFn.Expr, args...)
case pyFunc:
args := p.compileValues(b, args, kind)
ret = b.Call(pyFn.Expr, args...)
case llgoCstr: case llgoCstr:
ret = cstr(b, call.Args) ret = cstr(b, args)
case llgoAdvance: case llgoAdvance:
ret = p.advance(b, call.Args) ret = p.advance(b, args)
case llgoIndex:
ret = p.index(b, args)
case llgoAlloca: case llgoAlloca:
ret = p.alloca(b, call.Args) ret = p.alloca(b, args)
case llgoAllocaCStr: case llgoAllocaCStr:
ret = p.allocaCStr(b, call.Args) ret = p.allocaCStr(b, args)
case llgoStringData:
ret = p.stringData(b, args)
case llgoUnreachable: // func unreachable() case llgoUnreachable: // func unreachable()
b.Unreachable() b.Unreachable()
default: default:
@@ -480,7 +619,7 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
} }
default: default:
fn := p.compileValue(b, cv) fn := p.compileValue(b, cv)
args := p.compileValues(b, call.Args, kind) args := p.compileValues(b, args, kind)
ret = b.Call(fn, args...) ret = b.Call(fn, args...)
} }
case *ssa.BinOp: case *ssa.BinOp:
@@ -503,7 +642,7 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
ret = b.FieldAddr(x, v.Field) ret = b.FieldAddr(x, v.Field)
case *ssa.Alloc: case *ssa.Alloc:
t := v.Type().(*types.Pointer) t := v.Type().(*types.Pointer)
if p.checkVArgs(v, t) { // varargs: this is a varargs allocation if p.checkVArgs(v, t) { // varargs: this maybe a varargs allocation
return return
} }
elem := p.prog.Type(t.Elem(), llssa.InGo) elem := p.prog.Type(t.Elem(), llssa.InGo)
@@ -549,12 +688,18 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
} }
ret = b.Slice(x, low, high, max) ret = b.Slice(x, low, high, max)
case *ssa.MakeInterface: case *ssa.MakeInterface:
const ( if refs := *v.Referrers(); len(refs) == 1 {
delayExpr = true // varargs: don't need to convert an expr to any if ref, ok := refs[0].(*ssa.Store); ok {
) if va, ok := ref.Addr.(*ssa.IndexAddr); ok {
if _, ok = p.isVArgs(va.X); ok { // varargs: this is a varargs store
return
}
}
}
}
t := p.prog.Type(v.Type(), llssa.InGo) t := p.prog.Type(v.Type(), llssa.InGo)
x := p.compileValue(b, v.X) x := p.compileValue(b, v.X)
ret = b.MakeInterface(t, x, delayExpr) ret = b.MakeInterface(t, x)
case *ssa.MakeSlice: case *ssa.MakeSlice:
var nCap llssa.Expr var nCap llssa.Expr
t := p.prog.Type(v.Type(), llssa.InGo) t := p.prog.Type(v.Type(), llssa.InGo)
@@ -588,6 +733,12 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
return ret return ret
} }
func (p *context) jumpTo(v *ssa.Jump) llssa.BasicBlock {
fn := p.fn
succs := v.Block().Succs
return fn.Block(succs[0].Index)
}
func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) { func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
if iv, ok := instr.(instrOrValue); ok { if iv, ok := instr.(instrOrValue); ok {
p.compileInstrOrValue(b, iv, false) p.compileInstrOrValue(b, iv, false)
@@ -611,9 +762,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
val := p.compileValue(b, v.Val) val := p.compileValue(b, v.Val)
b.Store(ptr, val) b.Store(ptr, val)
case *ssa.Jump: case *ssa.Jump:
fn := p.fn jmpb := p.jumpTo(v)
succs := v.Block().Succs
jmpb := fn.Block(succs[0].Index)
b.Jump(jmpb) b.Jump(jmpb)
case *ssa.Return: case *ssa.Return:
var results []llssa.Expr var results []llssa.Expr
@@ -644,12 +793,13 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
} }
} }
func (p *context) compileFunction(v *ssa.Function) (llssa.Function, int) { func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyObjRef, kind int) {
// v.Pkg == nil: means auto generated function? // v.Pkg == nil: means auto generated function?
if v.Pkg == p.goPkg || v.Pkg == nil { if v.Pkg == p.goPkg || v.Pkg == nil {
// function in this package // function in this package
if fn := p.compileFuncDecl(p.pkg, p.goTyps, v); fn != nil { goFn, pyFn, kind = p.compileFuncDecl(p.pkg, v, true)
return fn, goFunc if kind != ignoredFunc {
return
} }
} }
return p.funcOf(v) return p.funcOf(v)
@@ -668,8 +818,11 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr {
} }
} }
case *ssa.Function: case *ssa.Function:
fn, _ := p.compileFunction(v) aFn, pyFn, _ := p.compileFunction(v)
return fn.Expr if aFn != nil {
return aFn.Expr
}
return pyFn.Expr
case *ssa.Global: case *ssa.Global:
g := p.varOf(v) g := p.varOf(v)
return g.Expr return g.Expr
@@ -752,16 +905,18 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
types.Unsafe: {kind: PkgDeclOnly}, // TODO(xsw): PkgNoInit or PkgDeclOnly? types.Unsafe: {kind: PkgDeclOnly}, // TODO(xsw): PkgNoInit or PkgDeclOnly?
}, },
} }
ctx.initPyModule()
ctx.initFiles(pkgPath, files) ctx.initFiles(pkgPath, files)
for _, m := range members { for _, m := range members {
member := m.val member := m.val
switch member := member.(type) { switch member := member.(type) {
case *ssa.Function: case *ssa.Function:
if member.TypeParams() != nil { if member.TypeParams() != nil || member.TypeArgs() != nil {
// TODO(xsw): don't compile generic functions
// Do not try to build generic (non-instantiated) functions. // Do not try to build generic (non-instantiated) functions.
continue continue
} }
ctx.compileFuncDecl(ret, member.Pkg.Pkg, member) ctx.compileFuncDecl(ret, member, false)
case *ssa.Type: case *ssa.Type:
ctx.compileType(ret, member) ctx.compileType(ret, member)
case *ssa.Global: case *ssa.Global:

View File

@@ -28,6 +28,14 @@ func testCompile(t *testing.T, src, expected string) {
cltest.TestCompileEx(t, src, "foo.go", expected) cltest.TestCompileEx(t, src, "foo.go", expected)
} }
func TestFromTestpy(t *testing.T) {
cltest.FromDir(t, "", "./_testpy", false)
}
func TestFromTestlibc(t *testing.T) {
cltest.FromDir(t, "", "./_testlibc", true)
}
func TestFromTestrt(t *testing.T) { func TestFromTestrt(t *testing.T) {
cltest.FromDir(t, "", "./_testrt", true) cltest.FromDir(t, "", "./_testrt", true)
} }
@@ -36,6 +44,18 @@ func TestFromTestdata(t *testing.T) {
cltest.FromDir(t, "", "./_testdata", false) cltest.FromDir(t, "", "./_testdata", false)
} }
func TestSqlite(t *testing.T) {
cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/sqlite.ll")
}
func TestFromTestpymath(t *testing.T) {
cltest.Pkg(t, ssa.PkgPython+"/math", "../py/math/llgo_autogen.ll")
}
func TestPython(t *testing.T) {
cltest.Pkg(t, ssa.PkgPython, "../py/llgo_autogen.ll")
}
func TestRuntime(t *testing.T) { func TestRuntime(t *testing.T) {
cltest.Pkg(t, ssa.PkgRuntime, "../internal/runtime/llgo_autogen.ll") cltest.Pkg(t, ssa.PkgRuntime, "../internal/runtime/llgo_autogen.ll")
} }

View File

@@ -18,6 +18,7 @@ package cl
import ( import (
"bytes" "bytes"
"fmt"
"go/ast" "go/ast"
"go/constant" "go/constant"
"go/token" "go/token"
@@ -29,79 +30,132 @@ import (
"golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa"
) )
type contentLines = [][]byte // -----------------------------------------------------------------------------
type contentMap = map[string]contentLines
func contentOf(m contentMap, file string) (lines contentLines, err error) { type symInfo struct {
if v, ok := m[file]; ok { file string
return v, nil fullName string
isVar bool
} }
type pkgSymInfo struct {
files map[string][]byte // file => content
syms map[string]symInfo // name => isVar
}
func newPkgSymInfo() *pkgSymInfo {
return &pkgSymInfo{
files: make(map[string][]byte),
syms: make(map[string]symInfo),
}
}
func (p *pkgSymInfo) addSym(fset *token.FileSet, pos token.Pos, fullName, inPkgName string, isVar bool) {
f := fset.File(pos)
if fp := f.Position(pos); fp.Line > 2 {
file := fp.Filename
if _, ok := p.files[file]; !ok {
b, err := os.ReadFile(file) b, err := os.ReadFile(file)
if err == nil { if err == nil {
lines = bytes.Split(b, []byte{'\n'}) p.files[file] = b
m[file] = lines }
}
p.syms[inPkgName] = symInfo{file, fullName, isVar}
}
}
func (p *pkgSymInfo) initLinknames(ctx *context) {
for file, b := range p.files {
lines := bytes.Split(b, []byte{'\n'})
for _, line := range lines {
ctx.initLinkname(string(line), func(inPkgName string) (fullName string, isVar, ok bool) {
if sym, ok := p.syms[inPkgName]; ok && file == sym.file {
return sym.fullName, sym.isVar, true
} }
return return
})
}
}
} }
// PkgKindOf returns the kind of a package. // PkgKindOf returns the kind of a package.
func PkgKindOf(pkg *types.Package) int { func PkgKindOf(pkg *types.Package) (int, string) {
scope := pkg.Scope() scope := pkg.Scope()
kind := pkgKindByScope(scope) kind, param := pkgKindByScope(scope)
if kind == PkgNormal { if kind == PkgNormal {
kind = pkgKindByPath(pkg.Path()) kind = pkgKindByPath(pkg.Path())
} }
return kind return kind, param
} }
// decl: a package that only contains declarations // decl: a package that only contains declarations
// noinit: a package that does not need to be initialized // noinit: a package that does not need to be initialized
func pkgKind(v string) int { func pkgKind(v string) (int, string) {
switch v { switch v {
case "link":
return PkgLinkIR, ""
case "decl": case "decl":
return PkgDeclOnly return PkgDeclOnly, ""
case "noinit": case "noinit":
return PkgNoInit return PkgNoInit, ""
default:
// case "link:bc":
// return PkgLinkBitCode
if strings.HasPrefix(v, "link:") { // "link: <libpath>"
return PkgLinkExtern, v[5:]
} else if strings.HasPrefix(v, "py.") { // "py.<module>"
return PkgPyModule, v[3:]
} }
return PkgLLGo }
return PkgLLGo, ""
} }
func pkgKindByScope(scope *types.Scope) int { func pkgKindByScope(scope *types.Scope) (int, string) {
if v, ok := scope.Lookup("LLGoPackage").(*types.Const); ok { if v, ok := scope.Lookup("LLGoPackage").(*types.Const); ok {
if v := v.Val(); v.Kind() == constant.String { if v := v.Val(); v.Kind() == constant.String {
return pkgKind(constant.StringVal(v)) return pkgKind(constant.StringVal(v))
} }
return PkgLLGo return PkgLLGo, ""
} }
return PkgNormal return PkgNormal, ""
} }
func (p *context) importPkg(pkg *types.Package, i *pkgInfo) { func (p *context) importPkg(pkg *types.Package, i *pkgInfo) {
scope := pkg.Scope() scope := pkg.Scope()
kind := pkgKindByScope(scope) kind, _ := pkgKindByScope(scope)
if kind == PkgNormal { if kind == PkgNormal {
return return
} }
i.kind = kind i.kind = kind
fset := p.fset fset := p.fset
names := scope.Names()
contents := make(contentMap)
pkgPath := llssa.PathOf(pkg) pkgPath := llssa.PathOf(pkg)
names := scope.Names()
syms := newPkgSymInfo()
for _, name := range names { for _, name := range names {
if token.IsExported(name) {
obj := scope.Lookup(name) obj := scope.Lookup(name)
switch obj := obj.(type) { switch obj := obj.(type) {
case *types.Func: case *types.Func:
if pos := obj.Pos(); pos != token.NoPos { if pos := obj.Pos(); pos != token.NoPos {
p.initLinknameByPos(fset, pos, pkgPath, contents, false) fullName, inPkgName := typesFuncName(pkgPath, obj)
syms.addSym(fset, pos, fullName, inPkgName, false)
}
case *types.TypeName:
if !obj.IsAlias() {
if t, ok := obj.Type().(*types.Named); ok {
for i, n := 0, t.NumMethods(); i < n; i++ {
fn := t.Method(i)
fullName, inPkgName := typesFuncName(pkgPath, fn)
syms.addSym(fset, fn.Pos(), fullName, inPkgName, false)
}
}
} }
case *types.Var: case *types.Var:
if pos := obj.Pos(); pos != token.NoPos { if pos := obj.Pos(); pos != token.NoPos {
p.initLinknameByPos(fset, pos, pkgPath, contents, true) syms.addSym(fset, pos, pkgPath+"."+name, name, true)
}
} }
} }
} }
syms.initLinknames(p)
} }
func (p *context) initFiles(pkgPath string, files []*ast.File) { func (p *context) initFiles(pkgPath string, files []*ast.File) {
@@ -109,61 +163,121 @@ func (p *context) initFiles(pkgPath string, files []*ast.File) {
for _, decl := range file.Decls { for _, decl := range file.Decls {
switch decl := decl.(type) { switch decl := decl.(type) {
case *ast.FuncDecl: case *ast.FuncDecl:
if decl.Recv == nil { fullName, inPkgName := astFuncName(pkgPath, decl)
p.initLinknameByDoc(decl.Doc, pkgPath, false) p.initLinknameByDoc(decl.Doc, fullName, inPkgName, false)
}
case *ast.GenDecl: case *ast.GenDecl:
if decl.Tok == token.VAR && len(decl.Specs) == 1 { if decl.Tok == token.VAR && len(decl.Specs) == 1 {
p.initLinknameByDoc(decl.Doc, pkgPath, true) if names := decl.Specs[0].(*ast.ValueSpec).Names; len(names) == 1 {
inPkgName := names[0].Name
p.initLinknameByDoc(decl.Doc, pkgPath+"."+inPkgName, inPkgName, true)
}
} }
} }
} }
} }
} }
func (p *context) initLinknameByDoc(doc *ast.CommentGroup, pkgPath string, isVar bool) { func (p *context) initLinknameByDoc(doc *ast.CommentGroup, fullName, inPkgName string, isVar bool) {
if doc != nil { if doc != nil {
if n := len(doc.List); n > 0 { if n := len(doc.List); n > 0 {
line := doc.List[n-1].Text line := doc.List[n-1].Text
p.initLinkname(pkgPath, line, isVar) p.initLinkname(line, func(name string) (_ string, _, ok bool) {
return fullName, isVar, name == inPkgName
})
} }
} }
} }
func (p *context) initLinknameByPos(fset *token.FileSet, pos token.Pos, pkgPath string, contents contentMap, isVar bool) { func (p *context) initLinkname(line string, f func(inPkgName string) (fullName string, isVar, ok bool)) {
f := fset.File(pos)
if fp := f.Position(pos); fp.Line > 2 {
lines, err := contentOf(contents, fp.Filename)
if err != nil {
panic(err)
}
if i := fp.Line - 2; i < len(lines) {
line := string(lines[i])
p.initLinkname(pkgPath, line, isVar)
}
}
}
func (p *context) initLinkname(pkgPath, line string, isVar bool) {
const ( const (
linkname = "//go:linkname " linkname = "//go:linkname "
llgolink = "//llgo:link "
llgolink2 = "// llgo:link "
) )
if strings.HasPrefix(line, linkname) { if strings.HasPrefix(line, linkname) {
text := strings.TrimSpace(line[len(linkname):]) p.initLink(line, len(linkname), f)
} else if strings.HasPrefix(line, llgolink2) {
p.initLink(line, len(llgolink2), f)
} else if strings.HasPrefix(line, llgolink) {
p.initLink(line, len(llgolink), f)
}
}
func (p *context) initLink(line string, prefix int, f func(inPkgName string) (fullName string, isVar, ok bool)) {
text := strings.TrimSpace(line[prefix:])
if idx := strings.IndexByte(text, ' '); idx > 0 { if idx := strings.IndexByte(text, ' '); idx > 0 {
inPkgName := text[:idx]
if fullName, isVar, ok := f(inPkgName); ok {
link := strings.TrimLeft(text[idx+1:], " ") link := strings.TrimLeft(text[idx+1:], " ")
if isVar || strings.Contains(link, ".") { // eg. C.printf, C.strlen, llgo.cstr if isVar || strings.Contains(link, ".") { // eg. C.printf, C.strlen, llgo.cstr
name := pkgPath + "." + text[:idx] p.link[fullName] = link
p.link[name] = link
} else { } else {
panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf") panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf")
} }
} else if c := inPkgName[0]; c >= 'A' && c <= 'Z' {
fmt.Fprintln(os.Stderr, "==>", line)
fmt.Fprintf(os.Stderr, "llgo: linkname %s not found and ignored\n", inPkgName)
} }
} }
} }
// func: pkg.name func recvTypeName(t ast.Expr) string {
// method: (pkg.T).name, (*pkg.T).name switch t := t.(type) {
case *ast.Ident:
return t.Name
case *ast.IndexExpr:
return trecvTypeName(t.X, t.Index)
case *ast.IndexListExpr:
return trecvTypeName(t.X, t.Indices...)
}
panic("unreachable")
}
// TODO(xsw): support generic type
func trecvTypeName(t ast.Expr, indices ...ast.Expr) string {
_ = indices
return t.(*ast.Ident).Name
}
// inPkgName:
// - func: name
// - method: (T).name, (*T).name
// fullName:
// - func: pkg.name
// - method: (pkg.T).name, (*pkg.T).name
func astFuncName(pkgPath string, fn *ast.FuncDecl) (fullName, inPkgName string) {
name := fn.Name.Name
if recv := fn.Recv; recv != nil && len(recv.List) == 1 {
tPrefix := "("
t := recv.List[0].Type
if tp, ok := t.(*ast.StarExpr); ok {
t, tPrefix = tp.X, "(*"
}
tSuffix := recvTypeName(t) + ")." + name
return tPrefix + pkgPath + "." + tSuffix, tPrefix + tSuffix
}
return pkgPath + "." + name, name
}
func typesFuncName(pkgPath string, fn *types.Func) (fullName, inPkgName string) {
sig := fn.Type().(*types.Signature)
name := fn.Name()
if recv := sig.Recv(); recv != nil {
tPrefix := "("
t := recv.Type()
if tp, ok := t.(*types.Pointer); ok {
t, tPrefix = tp.Elem(), "(*"
}
tSuffix := t.(*types.Named).Obj().Name() + ")." + name
return tPrefix + pkgPath + "." + tSuffix, tPrefix + tSuffix
}
return pkgPath + "." + name, name
}
// TODO(xsw): may can use typesFuncName
// fullName:
// - func: pkg.name
// - method: (pkg.T).name, (*pkg.T).name
func funcName(pkg *types.Package, fn *ssa.Function) string { func funcName(pkg *types.Package, fn *ssa.Function) string {
sig := fn.Signature sig := fn.Signature
name := fn.Name() name := fn.Name()
@@ -193,6 +307,7 @@ const (
ignoredFunc = iota ignoredFunc = iota
goFunc = int(llssa.InGo) goFunc = int(llssa.InGo)
cFunc = int(llssa.InC) cFunc = int(llssa.InC)
pyFunc = int(llssa.InPython)
llgoInstr = -1 llgoInstr = -1
llgoInstrBase = 0x80 llgoInstrBase = 0x80
@@ -201,23 +316,42 @@ const (
llgoAlloca = llgoInstrBase + 2 llgoAlloca = llgoInstrBase + 2
llgoAllocaCStr = llgoInstrBase + 3 llgoAllocaCStr = llgoInstrBase + 3
llgoAdvance = llgoInstrBase + 4 llgoAdvance = llgoInstrBase + 4
llgoIndex = llgoInstrBase + 5
llgoStringData = llgoInstrBase + 6
) )
func (p *context) funcName(pkg *types.Package, fn *ssa.Function, ignore bool) (string, int) { func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
name := funcName(pkg, fn) var pkg *types.Package
if ignore && ignoreName(name) || checkCgo(fn.Name()) { var orgName string
return name, ignoredFunc if origin := fn.Origin(); origin != nil {
pkg = origin.Pkg.Pkg
p.ensureLoaded(pkg)
orgName = funcName(pkg, origin)
} else {
if fnPkg := fn.Pkg; fnPkg != nil {
pkg = fnPkg.Pkg
} else {
pkg = p.goTyps
} }
if v, ok := p.link[name]; ok { p.ensureLoaded(pkg)
orgName = funcName(pkg, fn)
if ignore && ignoreName(orgName) || checkCgo(fn.Name()) {
return nil, orgName, ignoredFunc
}
}
if v, ok := p.link[orgName]; ok {
if strings.HasPrefix(v, "C.") { if strings.HasPrefix(v, "C.") {
return v[2:], cFunc return nil, v[2:], cFunc
}
if strings.HasPrefix(v, "py.") {
return pkg, v[3:], pyFunc
} }
if strings.HasPrefix(v, "llgo.") { if strings.HasPrefix(v, "llgo.") {
return v[5:], llgoInstr return nil, v[5:], llgoInstr
} }
return v, goFunc return pkg, v, goFunc
} }
return name, goFunc return pkg, funcName(pkg, fn), goFunc
} }
const ( const (
@@ -264,3 +398,17 @@ func pkgKindByPath(pkgPath string) int {
} }
return PkgNormal return PkgNormal
} }
// -----------------------------------------------------------------------------
const (
pysymPrefix = "__llgo_py."
)
func (p *context) initPyModule() {
if kind, mod := pkgKindByScope(p.goTyps.Scope()); kind == PkgPyModule {
p.pyMod = mod
}
}
// -----------------------------------------------------------------------------

4
go.mod
View File

@@ -9,7 +9,7 @@ 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.20.0 golang.org/x/tools v0.21.0
) )
require ( require (
@@ -18,3 +18,5 @@ require (
golang.org/x/mod v0.17.0 // indirect golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.7.0 // indirect
) )
retract v0.8.0

7
go.sum
View File

@@ -1,6 +1,7 @@
github.com/aykevl/go-wasm v0.0.1 h1:lPxy8l48P39W7I0tLrtCrLfZBOUq9IWZ7odGdyJP2AM= github.com/aykevl/go-wasm v0.0.1 h1:lPxy8l48P39W7I0tLrtCrLfZBOUq9IWZ7odGdyJP2AM=
github.com/aykevl/go-wasm v0.0.1/go.mod h1:b4nggwg3lEkNKOU4wzhtLKz2q2sLxSHFnc98aGt6z/Y= github.com/aykevl/go-wasm v0.0.1/go.mod h1:b4nggwg3lEkNKOU4wzhtLKz2q2sLxSHFnc98aGt6z/Y=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/goplus/gogen v1.15.2 h1:Q6XaSx/Zi5tWnjfAziYsQI6Jv6MgODRpFtOYqNkiiqM= github.com/goplus/gogen v1.15.2 h1:Q6XaSx/Zi5tWnjfAziYsQI6Jv6MgODRpFtOYqNkiiqM=
@@ -15,10 +16,12 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qiniu/x v1.13.10 h1:J4Z3XugYzAq85SlyAfqlKVrbf05glMbAOh+QncsDQpE= github.com/qiniu/x v1.13.10 h1:J4Z3XugYzAq85SlyAfqlKVrbf05glMbAOh+QncsDQpE=
github.com/qiniu/x v1.13.10/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E= github.com/qiniu/x v1.13.10/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -65,6 +68,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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
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=

View File

@@ -1,636 +0,0 @@
; ModuleID = 'github.com/goplus/llgo/internal/abi'
source_filename = "github.com/goplus/llgo/internal/abi"
%"github.com/goplus/llgo/internal/abi.ArrayType" = type { %"github.com/goplus/llgo/internal/abi.Type", ptr, ptr, i64 }
%"github.com/goplus/llgo/internal/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, i32, i32 }
%"github.com/goplus/llgo/internal/abi.ChanType" = type { %"github.com/goplus/llgo/internal/abi.Type", ptr, i64 }
%"github.com/goplus/llgo/internal/abi.FuncType" = type { %"github.com/goplus/llgo/internal/abi.Type", i16, i16 }
%"github.com/goplus/llgo/internal/abi.InterfaceType" = type { %"github.com/goplus/llgo/internal/abi.Type", %"github.com/goplus/llgo/internal/abi.Name", %"github.com/goplus/llgo/internal/runtime.Slice" }
%"github.com/goplus/llgo/internal/abi.Name" = type { ptr }
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/abi.MapType" = type { %"github.com/goplus/llgo/internal/abi.Type", ptr, ptr, ptr, { ptr, ptr }, i8, i8, i16, i32 }
%"github.com/goplus/llgo/internal/abi.PtrType" = type { %"github.com/goplus/llgo/internal/abi.Type", ptr }
%"github.com/goplus/llgo/internal/abi.SliceType" = type { %"github.com/goplus/llgo/internal/abi.Type", ptr }
%"github.com/goplus/llgo/internal/abi.StructType" = type { %"github.com/goplus/llgo/internal/abi.Type", %"github.com/goplus/llgo/internal/abi.Name", %"github.com/goplus/llgo/internal/runtime.Slice" }
@"github.com/goplus/llgo/internal/abi.init$guard" = global ptr null
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.ArrayType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ArrayType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.ChanType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.ChanType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.ChanType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).Elem"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Elem"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.FuncType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.FuncType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.FuncType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.FuncType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).Elem"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Elem"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.InterfaceType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.InterfaceType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.InterfaceType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.InterfaceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.MapType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.MapType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.MapType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.PtrType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.PtrType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.PtrType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.SliceType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.SliceType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.SliceType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).ArrayType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).Common"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).Elem"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).Elem"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).FuncType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).InterfaceType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %1)
ret ptr %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.StructType).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %1)
ret i64 %2
}
define i64 @"(*github.com/goplus/llgo/internal/abi.StructType).Len"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %1)
ret i64 %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).MapType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.StructType).StructType"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.StructType", ptr %0, i32 0, i32 0
%2 = call ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %1)
ret ptr %2
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).ArrayType"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp ne i64 %1, 17
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
ret ptr null
_llgo_2: ; preds = %_llgo_0
ret ptr %0
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).Common"(ptr %0) {
_llgo_0:
ret ptr %0
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).Elem"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp eq i64 %1, 17
br i1 %2, label %_llgo_1, label %_llgo_3
_llgo_1: ; preds = %_llgo_0
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 1
%4 = load ptr, ptr %3, align 8
ret ptr %4
_llgo_2: ; preds = %_llgo_3
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ChanType", ptr %0, i32 0, i32 1
%6 = load ptr, ptr %5, align 8
ret ptr %6
_llgo_3: ; preds = %_llgo_0
%7 = icmp eq i64 %1, 18
br i1 %7, label %_llgo_2, label %_llgo_5
_llgo_4: ; preds = %_llgo_5
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.MapType", ptr %0, i32 0, i32 2
%9 = load ptr, ptr %8, align 8
ret ptr %9
_llgo_5: ; preds = %_llgo_3
%10 = icmp eq i64 %1, 21
br i1 %10, label %_llgo_4, label %_llgo_7
_llgo_6: ; preds = %_llgo_7
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.PtrType", ptr %0, i32 0, i32 1
%12 = load ptr, ptr %11, align 8
ret ptr %12
_llgo_7: ; preds = %_llgo_5
%13 = icmp eq i64 %1, 22
br i1 %13, label %_llgo_6, label %_llgo_9
_llgo_8: ; preds = %_llgo_9
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.SliceType", ptr %0, i32 0, i32 1
%15 = load ptr, ptr %14, align 8
ret ptr %15
_llgo_9: ; preds = %_llgo_7
%16 = icmp eq i64 %1, 23
br i1 %16, label %_llgo_8, label %_llgo_10
_llgo_10: ; preds = %_llgo_9
ret ptr null
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).FuncType"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp ne i64 %1, 19
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
ret ptr null
_llgo_2: ; preds = %_llgo_0
ret ptr %0
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).InterfaceType"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp ne i64 %1, 20
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
ret ptr null
_llgo_2: ; preds = %_llgo_0
ret ptr %0
}
define i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0) {
_llgo_0:
%1 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %0, i32 0, i32 6
%2 = load i8, ptr %1, align 1
%3 = and i8 %2, 31
%4 = sext i8 %3 to i64
ret i64 %4
}
define i64 @"(*github.com/goplus/llgo/internal/abi.Type).Len"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp eq i64 %1, 17
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.ArrayType", ptr %0, i32 0, i32 3
%4 = load i64, ptr %3, align 4
ret i64 %4
_llgo_2: ; preds = %_llgo_0
ret i64 0
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).MapType"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp ne i64 %1, 21
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
ret ptr null
_llgo_2: ; preds = %_llgo_0
ret ptr %0
}
define ptr @"(*github.com/goplus/llgo/internal/abi.Type).StructType"(ptr %0) {
_llgo_0:
%1 = call i64 @"(*github.com/goplus/llgo/internal/abi.Type).Kind"(ptr %0)
%2 = icmp ne i64 %1, 25
br i1 %2, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
ret ptr null
_llgo_2: ; preds = %_llgo_0
ret ptr %0
}
define void @"github.com/goplus/llgo/internal/abi.init"() {
_llgo_0:
%0 = load i1, ptr @"github.com/goplus/llgo/internal/abi.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"github.com/goplus/llgo/internal/abi.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}

Binary file not shown.

View File

@@ -29,7 +29,7 @@ import (
"time" "time"
wasm "github.com/aykevl/go-wasm" wasm "github.com/aykevl/go-wasm"
"github.com/goplus/llgo/x/ar" "github.com/goplus/llgo/xtool/ar"
) )
// Create creates an arcive for static linking from a list of object files // Create creates an arcive for static linking from a list of object files

View File

@@ -17,9 +17,11 @@
package build package build
import ( import (
"archive/zip"
"fmt" "fmt"
"go/token" "go/token"
"go/types" "go/types"
"io"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@@ -31,7 +33,7 @@ import (
"golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa"
"github.com/goplus/llgo/cl" "github.com/goplus/llgo/cl"
"github.com/goplus/llgo/x/clang" "github.com/goplus/llgo/xtool/clang"
llssa "github.com/goplus/llgo/ssa" llssa "github.com/goplus/llgo/ssa"
) )
@@ -118,18 +120,31 @@ func Do(args []string, conf *Config) {
cl.SetDebug(cl.DbgFlagAll) cl.SetDebug(cl.DbgFlagAll)
} }
var needRt bool
var rt []*packages.Package var rt []*packages.Package
prog := llssa.NewProgram(nil) prog := llssa.NewProgram(nil)
prog.SetRuntime(func() *types.Package { load := func() []*packages.Package {
rt, err = packages.Load(cfg, llssa.PkgRuntime) if rt == nil {
var err error
rt, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
check(err) check(err)
}
return rt
}
prog.SetRuntime(func() *types.Package {
needRt = true
rt := load()
return rt[0].Types return rt[0].Types
}) })
prog.SetPython(func() *types.Package {
rt := load()
return rt[1].Types
})
pkgs := buildAllPkgs(prog, initial, mode, verbose) pkgs := buildAllPkgs(prog, initial, mode, verbose)
var runtimeFiles []string var runtimeFiles []string
if rt != nil { if needRt {
runtimeFiles = allLinkFiles(rt) runtimeFiles = allLinkFiles(rt)
} }
if mode != ModeBuild { if mode != ModeBuild {
@@ -145,12 +160,22 @@ func Do(args []string, conf *Config) {
} }
} }
func setNeedRuntime(pkg *packages.Package) { func setNeedRuntimeOrPyInit(pkg *packages.Package, needRuntime, needPyInit bool) {
pkg.ID = "" // just use pkg.Module to mark it needs runtime v := []byte{'0', '0'}
if needRuntime {
v[0] = '1'
}
if needPyInit {
v[1] = '1'
}
pkg.ID = string(v) // just use pkg.ID to mark it needs runtime
} }
func isNeedRuntime(pkg *packages.Package) bool { func isNeedRuntimeOrPyInit(pkg *packages.Package) (needRuntime, needPyInit bool) {
return pkg.ID == "" if len(pkg.ID) == 2 {
return pkg.ID[0] == '1', pkg.ID[1] == '1'
}
return
} }
func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) (pkgs []*aPackage) { func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) (pkgs []*aPackage) {
@@ -163,10 +188,36 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
} }
fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg) fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg)
} }
for _, pkg := range pkgs { for _, aPkg := range pkgs {
buildPkg(prog, pkg, mode, verbose) pkg := aPkg.Package
if prog.NeedRuntime() { switch kind, param := cl.PkgKindOf(pkg.Types); kind {
setNeedRuntime(pkg.Package) case cl.PkgDeclOnly:
// skip packages that only contain declarations
// and set no export file
pkg.ExportFile = ""
case cl.PkgLinkIR, cl.PkgLinkExtern, cl.PkgPyModule:
pkgPath := pkg.PkgPath
if isPkgInLLGo(pkgPath) {
pkg.ExportFile = concatPkgLinkFiles(pkgPath)
} else {
panic("todo")
}
if kind == cl.PkgLinkExtern { // need to be linked with external library
linkFile := os.ExpandEnv(strings.TrimSpace(param))
dir, lib := filepath.Split(linkFile)
command := " -l " + lib
if dir != "" {
command += " -L " + dir
}
if isMultiLinkFiles(pkg.ExportFile) {
pkg.ExportFile = command + pkg.ExportFile
} else {
pkg.ExportFile = command + " " + pkg.ExportFile
}
}
default:
buildPkg(prog, aPkg, mode, verbose)
setNeedRuntimeOrPyInit(pkg, prog.NeedRuntime, prog.NeedPyInit)
} }
} }
return return
@@ -185,27 +236,43 @@ func linkMainPkg(pkg *packages.Package, pkgs []*aPackage, runtimeFiles []string,
args[1] = app args[1] = app
args[2] = "-Wno-override-module" args[2] = "-Wno-override-module"
needRuntime := false needRuntime := false
needPyInit := false
packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) { packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) {
if p.ExportFile != "" && !isRuntimePkg(p.PkgPath) { // skip packages that only contain declarations if p.ExportFile != "" && !isRuntimePkg(p.PkgPath) { // skip packages that only contain declarations
args = append(args, p.ExportFile+".ll") args = appendLinkFiles(args, p.ExportFile)
need1, need2 := isNeedRuntimeOrPyInit(p)
if !needRuntime { if !needRuntime {
needRuntime = isNeedRuntime(p) needRuntime = need1
}
if !needPyInit {
needPyInit = need2
} }
} }
}) })
var aPkg *aPackage
for _, v := range pkgs {
if v.Package == pkg { // found this package
aPkg = v
break
}
}
dirty := false
if needRuntime && runtimeFiles != nil { if needRuntime && runtimeFiles != nil {
args = append(args, runtimeFiles...) args = append(args, runtimeFiles...)
} else { } else {
for _, aPkg := range pkgs { dirty = true
if aPkg.Package == pkg { // make empty runtime.init if no runtime needed fn := aPkg.LPkg.FuncOf(cl.RuntimeInit)
fn.MakeBody(1).Return()
}
if needPyInit {
dirty = aPkg.LPkg.PyInit()
}
if dirty && needLLFile(mode) {
lpkg := aPkg.LPkg lpkg := aPkg.LPkg
lpkg.FuncOf(cl.RuntimeInit).MakeBody(1).Return() os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644)
if needLLFile(mode) {
file := pkg.ExportFile + ".ll"
os.WriteFile(file, []byte(lpkg.String()), 0644)
}
}
}
} }
if verbose || mode != ModeRun { if verbose || mode != ModeRun {
@@ -236,28 +303,33 @@ func linkMainPkg(pkg *packages.Package, pkgs []*aPackage, runtimeFiles []string,
func buildPkg(prog llssa.Program, aPkg *aPackage, mode Mode, verbose bool) { func buildPkg(prog llssa.Program, aPkg *aPackage, mode Mode, verbose bool) {
pkg := aPkg.Package pkg := aPkg.Package
if cl.PkgKindOf(pkg.Types) == cl.PkgDeclOnly {
// skip packages that only contain declarations
// and set no export file
pkg.ExportFile = ""
return
}
pkgPath := pkg.PkgPath pkgPath := pkg.PkgPath
if verbose { if verbose {
fmt.Fprintln(os.Stderr, pkgPath) fmt.Fprintln(os.Stderr, pkgPath)
} }
if pkgPath == "unsafe" { // TODO(xsw): maybe can remove this special case if canSkipToBuild(pkgPath) {
pkg.ExportFile = ""
return return
} }
ret, err := cl.NewPackage(prog, aPkg.SSA, pkg.Syntax) ret, err := cl.NewPackage(prog, aPkg.SSA, pkg.Syntax)
check(err) check(err)
if needLLFile(mode) { if needLLFile(mode) {
file := pkg.ExportFile + ".ll" pkg.ExportFile += ".ll"
os.WriteFile(file, []byte(ret.String()), 0644) os.WriteFile(pkg.ExportFile, []byte(ret.String()), 0644)
} }
aPkg.LPkg = ret aPkg.LPkg = ret
} }
func canSkipToBuild(pkgPath string) bool {
switch pkgPath {
case "unsafe", "runtime", "errors", "sync", "sync/atomic":
return true
default:
return strings.HasPrefix(pkgPath, "internal/") ||
strings.HasPrefix(pkgPath, "runtime/internal/")
}
}
type aPackage struct { type aPackage struct {
*packages.Package *packages.Package
SSA *ssa.Package SSA *ssa.Package
@@ -342,12 +414,12 @@ func checkFlag(arg string, i *int, verbose *bool, swflags map[string]bool) {
func allLinkFiles(rt []*packages.Package) (outFiles []string) { func allLinkFiles(rt []*packages.Package) (outFiles []string) {
outFiles = make([]string, 0, len(rt)) outFiles = make([]string, 0, len(rt))
root := rootLLGo(rt[0])
packages.Visit(rt, nil, func(p *packages.Package) { packages.Visit(rt, nil, func(p *packages.Package) {
pkgPath := p.PkgPath pkgPath := p.PkgPath
if isRuntimePkg(pkgPath) { if isRuntimePkg(pkgPath) {
outFile := filepath.Join(root+pkgPath[len(llgoModPath):], "llgo_autogen.ll") llgoPkgLinkFiles(pkgPath, func(linkFile string) {
outFiles = append(outFiles, outFile) outFiles = append(outFiles, linkFile)
})
} }
}) })
return return
@@ -366,16 +438,78 @@ func isRuntimePkg(pkgPath string) bool {
return false return false
} }
// TODO(xsw): llgo root dir var (
func rootLLGo(runtime *packages.Package) string { rootDir string
return runtime.Module.Dir )
func llgoRoot() string {
if rootDir == "" {
root := os.Getenv("LLGOROOT")
if root == "" {
panic("todo: LLGOROOT not set")
}
rootDir, _ = filepath.Abs(root)
}
return rootDir
}
func appendLinkFiles(args []string, file string) []string {
if isMultiLinkFiles(file) {
return append(args, strings.Split(file[1:], " ")...)
}
return append(args, file)
}
func isMultiLinkFiles(ret string) bool {
return len(ret) > 0 && ret[0] == ' '
}
func concatPkgLinkFiles(pkgPath string) string {
var b strings.Builder
var ret string
var n int
llgoPkgLinkFiles(pkgPath, func(linkFile string) {
if n == 0 {
ret = linkFile
} else {
b.WriteByte(' ')
b.WriteString(linkFile)
}
n++
})
if n > 1 {
b.WriteByte(' ')
b.WriteString(ret)
return b.String()
}
return ret
}
func llgoPkgLinkFiles(pkgPath string, procFile func(linkFile string)) {
dir := llgoRoot() + pkgPath[len(llgoModPath):] + "/"
llFile := dir + "llgo_autogen.ll"
llaFile := llFile + "a"
zipf, err := zip.OpenReader(llaFile)
if err != nil {
procFile(llFile)
return
}
defer zipf.Close()
for _, f := range zipf.File {
procFile(dir + f.Name)
}
if _, err := os.Stat(llFile); os.IsNotExist(err) {
for _, f := range zipf.File {
decodeFile(dir+f.Name, f)
}
}
} }
const ( const (
llgoModPath = "github.com/goplus/llgo" llgoModPath = "github.com/goplus/llgo"
) )
/*
func isPkgInLLGo(pkgPath string) bool { func isPkgInLLGo(pkgPath string) bool {
return isPkgInMod(pkgPath, llgoModPath) return isPkgInMod(pkgPath, llgoModPath)
} }
@@ -387,8 +521,52 @@ func isPkgInMod(pkgPath, modPath string) bool {
} }
return false return false
} }
/*
func llgoPkgLinkFile(pkgPath string) string {
// if kind == cl.PkgLinkBitCode {
// return filepath.Join(llgoRoot()+pkgPath[len(llgoModPath):], "llgo_autogen.bc")
// }
llFile := filepath.Join(llgoRoot()+pkgPath[len(llgoModPath):], "llgo_autogen.ll")
if _, err := os.Stat(llFile); os.IsNotExist(err) {
decodeLinkFile(llFile)
}
return llFile
}
// *.ll => *.lla
func decodeLinkFile(llFile string) {
zipFile := llFile + "a"
zipf, err := zip.OpenReader(zipFile)
if err != nil {
return
}
defer zipf.Close()
f, err := zipf.Open("llgo_autogen.ll")
if err != nil {
return
}
defer f.Close()
data, err := io.ReadAll(f)
if err == nil {
os.WriteFile(llFile, data, 0644)
}
}
*/ */
func decodeFile(outFile string, zipf *zip.File) (err error) {
f, err := zipf.Open()
if err != nil {
return
}
defer f.Close()
data, err := io.ReadAll(f)
if err == nil {
err = os.WriteFile(outFile, data, 0644)
}
return
}
func check(err error) { func check(err error) {
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -30,6 +30,7 @@ import (
"golang.org/x/tools/go/ssa/ssautil" "golang.org/x/tools/go/ssa/ssautil"
llssa "github.com/goplus/llgo/ssa" llssa "github.com/goplus/llgo/ssa"
cpackages "golang.org/x/tools/go/packages"
) )
func Init() { func Init() {
@@ -71,14 +72,17 @@ func Gen(pkgPath, inFile string, src any) string {
} }
prog := llssa.NewProgram(nil) prog := llssa.NewProgram(nil)
prog.SetRuntime(func() *types.Package { initRtAndPy(prog, &cpackages.Config{
rt, err := imp.Import(llssa.PkgRuntime) Mode: loadSyntax | cpackages.NeedDeps,
check(err)
return rt
}) })
ret, err := cl.NewPackage(prog, ssaPkg, files) ret, err := cl.NewPackage(prog, ssaPkg, files)
check(err) check(err)
if prog.NeedPyInit { // call PyInit if needed
ret.PyInit()
}
return ret.String() return ret.String()
} }

View File

@@ -19,6 +19,7 @@ package llgen
import ( import (
"go/types" "go/types"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -37,6 +38,27 @@ const (
loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo
) )
func initRtAndPy(prog llssa.Program, cfg *packages.Config) {
var pkgRtAndPy []*packages.Package
load := func() []*packages.Package {
if pkgRtAndPy == nil {
var err error
pkgRtAndPy, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
check(err)
}
return pkgRtAndPy
}
prog.SetRuntime(func() *types.Package {
rt := load()
return rt[0].Types
})
prog.SetPython(func() *types.Package {
rt := load()
return rt[1].Types
})
}
func GenFrom(fileOrPkg string) string { func GenFrom(fileOrPkg string) string {
cfg := &packages.Config{ cfg := &packages.Config{
Mode: loadSyntax | packages.NeedDeps, Mode: loadSyntax | packages.NeedDeps,
@@ -51,11 +73,7 @@ func GenFrom(fileOrPkg string) string {
ssaPkg.Build() ssaPkg.Build()
prog := llssa.NewProgram(nil) prog := llssa.NewProgram(nil)
prog.SetRuntime(func() *types.Package { initRtAndPy(prog, cfg)
rt, err := packages.Load(cfg, llssa.PkgRuntime)
check(err)
return rt[0].Types
})
if Verbose { if Verbose {
ssaPkg.WriteTo(os.Stderr) ssaPkg.WriteTo(os.Stderr)
@@ -64,6 +82,10 @@ func GenFrom(fileOrPkg string) string {
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax) ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)
check(err) check(err)
if prog.NeedPyInit { // call PyInit if needed
ret.PyInit()
}
return ret.String() return ret.String()
} }
@@ -74,10 +96,15 @@ func DoFile(fileOrPkg, outFile string) {
} }
func SmartDoFile(inFile string, pkgPath ...string) { func SmartDoFile(inFile string, pkgPath ...string) {
const autgenFile = "llgo_autogen.ll"
dir, _ := filepath.Split(inFile) dir, _ := filepath.Split(inFile)
fname := "llgo_autogen.ll" absDir, _ := filepath.Abs(dir)
if inCompilerDir(dir) { absDir = filepath.ToSlash(absDir)
fname := autgenFile
if inCompilerDir(absDir) {
fname = "out.ll" fname = "out.ll"
} else if inSqlite(absDir) {
fname = "sqlite.ll"
} }
outFile := dir + fname outFile := dir + fname
@@ -86,9 +113,23 @@ func SmartDoFile(inFile string, pkgPath ...string) {
} else { } else {
DoFile(inFile, outFile) DoFile(inFile, outFile)
} }
if false && fname == autgenFile {
genZip(absDir, "llgo_autogen.lla", autgenFile)
}
}
func genZip(dir string, outFile, inFile string) {
cmd := exec.Command("zip", outFile, inFile)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
} }
func inCompilerDir(dir string) bool { func inCompilerDir(dir string) bool {
dir, _ = filepath.Abs(dir) return strings.Contains(dir, "/llgo/cl/")
return strings.Contains(filepath.ToSlash(dir), "/llgo/cl/") }
func inSqlite(dir string) bool {
return strings.HasSuffix(dir, "/llgo/x/sqlite")
} }

View File

@@ -1,623 +0,0 @@
; ModuleID = 'github.com/goplus/llgo/internal/runtime'
source_filename = "github.com/goplus/llgo/internal/runtime"
%"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/runtime.itab" = type { ptr, ptr, i32, [4 x i8], [1 x i64] }
%"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, i32, i32 }
%"github.com/goplus/llgo/internal/runtime.hmap" = type { i64, i8, i8, i16, i32, ptr, ptr, i64, ptr }
@"github.com/goplus/llgo/internal/runtime.TyAny" = global ptr null
@"github.com/goplus/llgo/internal/runtime.basicTypes" = global ptr null
@"github.com/goplus/llgo/internal/runtime.init$guard" = global ptr null
@"github.com/goplus/llgo/internal/runtime.sizeBasicTypes" = global ptr null
@0 = private unnamed_addr constant [21 x i8] c"I2Int: type mismatch\00", align 1
@1 = private unnamed_addr constant [26 x i8] c"slice index out of bounds\00", align 1
@2 = private unnamed_addr constant [33 x i8] c"string slice index out of bounds\00", align 1
@__stderrp = external global ptr
@3 = private unnamed_addr constant [11 x i8] c"panic: %s\0A\00", align 1
define ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 %0) {
_llgo_0:
%1 = call ptr @malloc(i64 %0)
ret ptr %1
}
define ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %0) {
_llgo_0:
%1 = call ptr @malloc(i64 %0)
%2 = call ptr @memset(ptr %1, i32 0, i64 %0)
ret ptr %2
}
define ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 %0) {
_llgo_0:
%1 = getelementptr inbounds ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 %0
%2 = load ptr, ptr %1, align 8
ret ptr %2
}
define ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1
%5 = load i64, ptr %4, align 4
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 0
%7 = load ptr, ptr %6, align 8
%8 = call ptr @memcpy(ptr %0, ptr %7, i64 %5)
%9 = getelementptr inbounds i8, ptr %0, i64 %5
store i8 0, ptr %9, align 1
ret ptr %0
}
define ptr @"github.com/goplus/llgo/internal/runtime.CStrDup"(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
%4 = load i64, ptr %3, align 4
%5 = add i64 %4, 1
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 %5)
%7 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %6, %"github.com/goplus/llgo/internal/runtime.String" %7)
ret ptr %8
}
define { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1) {
_llgo_0:
%2 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
store %"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %3, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %5, i32 0, i32 1
%7 = load ptr, ptr %6, align 8
%8 = icmp eq ptr %7, %1
br i1 %8, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %3, i32 0, i32 1
%10 = load ptr, ptr %9, align 8
%11 = ptrtoint ptr %10 to i64
%mrv = insertvalue { i64, i1 } poison, i64 %11, 0
%mrv1 = insertvalue { i64, i1 } %mrv, i1 true, 1
ret { i64, i1 } %mrv1
_llgo_2: ; preds = %_llgo_0
ret { i64, i1 } zeroinitializer
}
define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.EmptyString"() {
_llgo_0:
%0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %0, i64 16)
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 0
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1
store ptr null, ptr %2, align 8
store i64 0, ptr %3, align 4
%4 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %1, align 8
ret %"github.com/goplus/llgo/internal/runtime.String" %4
}
define i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1) {
_llgo_0:
%2 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
store %"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %3, align 8
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %3, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %5, i32 0, i32 1
%7 = load ptr, ptr %6, align 8
%8 = icmp eq ptr %7, %1
br i1 %8, label %_llgo_1, label %_llgo_2
_llgo_1: ; preds = %_llgo_0
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %3, i32 0, i32 1
%10 = load ptr, ptr %9, align 8
%11 = ptrtoint ptr %10 to i64
ret i64 %11
_llgo_2: ; preds = %_llgo_0
%12 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 20)
%13 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %12)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %13)
unreachable
}
define %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAny"(ptr %0, ptr %1) {
_llgo_0:
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 0
%4 = load ptr, ptr @"github.com/goplus/llgo/internal/runtime.TyAny", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 1
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 2
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 4
%8 = getelementptr inbounds i64, ptr %7, i64 0
store ptr %4, ptr %3, align 8
store ptr %0, ptr %5, align 8
store i32 0, ptr %6, align 4
store i64 0, ptr %8, align 4
%9 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %9, i64 16)
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 0
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 1
store ptr %2, ptr %11, align 8
store ptr %1, ptr %12, align 8
%13 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, align 8
ret %"github.com/goplus/llgo/internal/runtime.iface" %13
}
define %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %0, i64 %1) {
_llgo_0:
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 0
%4 = load ptr, ptr @"github.com/goplus/llgo/internal/runtime.TyAny", align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 1
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 2
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %2, i32 0, i32 4
%8 = getelementptr inbounds i64, ptr %7, i64 0
store ptr %4, ptr %3, align 8
store ptr %0, ptr %5, align 8
store i32 0, ptr %6, align 4
store i64 0, ptr %8, align 4
%9 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %9, i64 16)
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 0
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 1
%13 = inttoptr i64 %1 to ptr
store ptr %2, ptr %11, align 8
store ptr %13, ptr %12, align 8
%14 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, align 8
ret %"github.com/goplus/llgo/internal/runtime.iface" %14
}
define %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %1, align 8
%2 = load ptr, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 24), align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 0
%5 = load ptr, ptr @"github.com/goplus/llgo/internal/runtime.TyAny", align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 1
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 2
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 4
%9 = getelementptr inbounds i64, ptr %8, i64 0
store ptr %5, ptr %4, align 8
store ptr %2, ptr %6, align 8
store i32 0, ptr %7, align 4
store i64 0, ptr %9, align 4
%10 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %10, i64 16)
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %11, i32 0, i32 0
%13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %11, i32 0, i32 1
store ptr %3, ptr %12, align 8
store ptr %1, ptr %13, align 8
%14 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %11, align 8
ret %"github.com/goplus/llgo/internal/runtime.iface" %14
}
define %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeInterface"(ptr %0, ptr %1, ptr %2) {
_llgo_0:
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 0
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 1
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 2
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %3, i32 0, i32 4
%8 = getelementptr inbounds i64, ptr %7, i64 0
store ptr %0, ptr %4, align 8
store ptr %1, ptr %5, align 8
store i32 0, ptr %6, align 4
store i64 0, ptr %8, align 4
%9 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %9, i64 16)
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 0
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, i32 0, i32 1
store ptr %3, ptr %11, align 8
store ptr %2, ptr %12, align 8
%13 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %10, align 8
ret %"github.com/goplus/llgo/internal/runtime.iface" %13
}
define ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"() {
_llgo_0:
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.makemap_small"()
ret ptr %0
}
define %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %3, i64 24)
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %4, i32 0, i32 0
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %4, i32 0, i32 1
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %4, i32 0, i32 2
store ptr %0, ptr %5, align 8
store i64 %1, ptr %6, align 4
store i64 %2, ptr %7, align 4
%8 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %4, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %8
}
define %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) {
_llgo_0:
%6 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %6, i64 24)
%8 = icmp slt i64 %3, 0
br i1 %8, label %_llgo_1, label %_llgo_5
_llgo_1: ; preds = %_llgo_5, %_llgo_4, %_llgo_3, %_llgo_0
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 25)
%10 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %9)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %10)
unreachable
_llgo_2: ; preds = %_llgo_3
%11 = sub i64 %4, %3
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %7, i32 0, i32 1
store i64 %11, ptr %12, align 4
%13 = sub i64 %5, %3
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %7, i32 0, i32 2
store i64 %13, ptr %14, align 4
%15 = sub i64 %5, %3
%16 = icmp sgt i64 %15, 0
br i1 %16, label %_llgo_6, label %_llgo_8
_llgo_3: ; preds = %_llgo_4
%17 = icmp sgt i64 %5, %2
br i1 %17, label %_llgo_1, label %_llgo_2
_llgo_4: ; preds = %_llgo_5
%18 = icmp slt i64 %5, %4
br i1 %18, label %_llgo_1, label %_llgo_3
_llgo_5: ; preds = %_llgo_0
%19 = icmp slt i64 %4, %3
br i1 %19, label %_llgo_1, label %_llgo_4
_llgo_6: ; preds = %_llgo_2
%20 = mul i64 %3, %1
%21 = getelementptr i8, ptr %0, i64 %20
%22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %7, i32 0, i32 0
store ptr %21, ptr %22, align 8
br label %_llgo_7
_llgo_7: ; preds = %_llgo_8, %_llgo_6
%23 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %7, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %23
_llgo_8: ; preds = %_llgo_2
%24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %7, i32 0, i32 0
store ptr %0, ptr %24, align 8
br label %_llgo_7
}
define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr %0, i64 %1) {
_llgo_0:
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 0
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1
store ptr %0, ptr %4, align 8
store i64 %1, ptr %5, align 4
%6 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %3, align 8
ret %"github.com/goplus/llgo/internal/runtime.String" %6
}
define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %0, i64 %1, i64 %2) {
_llgo_0:
%3 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %3, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %4, align 8
%5 = icmp slt i64 %1, 0
br i1 %5, label %_llgo_1, label %_llgo_4
_llgo_1: ; preds = %_llgo_4, %_llgo_3, %_llgo_0
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 32)
%7 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %6)
call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %7)
unreachable
_llgo_2: ; preds = %_llgo_3
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
%9 = load i64, ptr %8, align 4
%10 = icmp slt i64 %1, %9
br i1 %10, label %_llgo_5, label %_llgo_6
_llgo_3: ; preds = %_llgo_4
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
%12 = load i64, ptr %11, align 4
%13 = icmp sgt i64 %2, %12
br i1 %13, label %_llgo_1, label %_llgo_2
_llgo_4: ; preds = %_llgo_0
%14 = icmp slt i64 %2, %1
br i1 %14, label %_llgo_1, label %_llgo_3
_llgo_5: ; preds = %_llgo_2
%15 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %15, i64 16)
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 0
%18 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 0
%19 = load ptr, ptr %18, align 8
%20 = getelementptr i8, ptr %19, i64 %1
%21 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %16, i32 0, i32 1
%22 = sub i64 %2, %1
store ptr %20, ptr %17, align 8
store i64 %22, ptr %21, align 4
%23 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8
ret %"github.com/goplus/llgo/internal/runtime.String" %23
_llgo_6: ; preds = %_llgo_2
%24 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%25 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %24, i64 16)
%26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %25, i32 0, i32 0
%27 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %25, i32 0, i32 1
store ptr null, ptr %26, align 8
store i64 0, ptr %27, align 4
%28 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %25, align 8
ret %"github.com/goplus/llgo/internal/runtime.String" %28
}
define %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NilSlice"() {
_llgo_0:
%0 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %0, i64 24)
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 0
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 1
%4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 2
store ptr null, ptr %2, align 8
store i64 0, ptr %3, align 4
store i64 0, ptr %4, align 4
%5 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, align 8
ret %"github.com/goplus/llgo/internal/runtime.Slice" %5
}
define i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 24)
store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, i32 0, i32 2
%4 = load i64, ptr %3, align 4
ret i64 %4
}
define ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 24)
store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, i32 0, i32 0
%4 = load ptr, ptr %3, align 8
ret ptr %4
}
define i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 24)
store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %2, i32 0, i32 1
%4 = load i64, ptr %3, align 4
ret i64 %4
}
define %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %0, %"github.com/goplus/llgo/internal/runtime.String" %1) {
_llgo_0:
%2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %2, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %3, align 8
%4 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %4, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %5, align 8
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1
%7 = load i64, ptr %6, align 4
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1
%9 = load i64, ptr %8, align 4
%10 = add i64 %7, %9
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 %10)
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 0
%13 = load ptr, ptr %12, align 8
%14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1
%15 = load i64, ptr %14, align 4
%16 = call ptr @memcpy(ptr %11, ptr %13, i64 %15)
%17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %3, i32 0, i32 1
%18 = load i64, ptr %17, align 4
%19 = getelementptr i8, ptr %11, i64 %18
%20 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 0
%21 = load ptr, ptr %20, align 8
%22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1
%23 = load i64, ptr %22, align 4
%24 = call ptr @memcpy(ptr %19, ptr %21, i64 %23)
%25 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %25, i64 16)
%27 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %26, i32 0, i32 0
%28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %26, i32 0, i32 1
store ptr %11, ptr %27, align 8
store i64 %10, ptr %28, align 4
%29 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %26, align 8
ret %"github.com/goplus/llgo/internal/runtime.String" %29
}
define ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0
%4 = load ptr, ptr %3, align 8
ret ptr %4
}
define i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1
%4 = load i64, ptr %3, align 4
ret i64 %4
}
define void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
_llgo_0:
%1 = alloca %"github.com/goplus/llgo/internal/runtime.iface", align 8
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %1, i64 16)
store %"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %2, align 8
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %2, i32 0, i32 0
%4 = load ptr, ptr %3, align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.itab", ptr %4, i32 0, i32 1
%6 = load ptr, ptr %5, align 8
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %6, i32 0, i32 6
%8 = load i8, ptr %7, align 1
%9 = sext i8 %8 to i64
%10 = icmp eq i64 %9, 24
br i1 %10, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0
ret void
_llgo_2: ; preds = %_llgo_0
%11 = load ptr, ptr @__stderrp, align 8
%12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %2, i32 0, i32 1
%13 = load ptr, ptr %12, align 8
%14 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %13, align 8
call void @"github.com/goplus/llgo/internal/runtime.stringTracef"(ptr %11, ptr @3, %"github.com/goplus/llgo/internal/runtime.String" %14)
br label %_llgo_1
}
define ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %0, i64 %1) {
_llgo_0:
%2 = call ptr @memset(ptr %0, i32 0, i64 %1)
ret ptr %2
}
define ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 56)
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %1, i32 0, i32 0
%3 = getelementptr inbounds i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 %0
%4 = load i64, ptr %3, align 4
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %1, i32 0, i32 2
%6 = trunc i64 %0 to i32
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %1, i32 0, i32 6
%8 = trunc i64 %0 to i8
store i64 %4, ptr %2, align 4
store i32 %6, ptr %5, align 4
store i8 %8, ptr %7, align 1
ret ptr %1
}
define void @"github.com/goplus/llgo/internal/runtime.init"() {
_llgo_0:
%0 = load i1, ptr @"github.com/goplus/llgo/internal/runtime.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"github.com/goplus/llgo/internal/runtime.init$guard", align 1
call void @"github.com/goplus/llgo/internal/abi.init"()
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 88)
store ptr %1, ptr @"github.com/goplus/llgo/internal/runtime.TyAny", align 8
store i64 1, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 1), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 2), align 4
store i64 1, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 3), align 4
store i64 2, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 4), align 4
store i64 4, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 5), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 6), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 7), align 4
store i64 1, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 8), align 4
store i64 2, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 9), align 4
store i64 4, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 10), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 11), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 12), align 4
store i64 4, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 13), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 14), align 4
store i64 8, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 15), align 4
store i64 16, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 16), align 4
store i64 16, ptr getelementptr inbounds (i64, ptr @"github.com/goplus/llgo/internal/runtime.sizeBasicTypes", i64 24), align 4
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 1)
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 2)
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 3)
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 4)
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 5)
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 6)
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 7)
%9 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 8)
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 9)
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 10)
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 11)
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 12)
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 13)
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 14)
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 15)
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 16)
%18 = call ptr @"github.com/goplus/llgo/internal/runtime.basicType"(i64 24)
store ptr %2, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 1), align 8
store ptr %3, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 2), align 8
store ptr %4, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 3), align 8
store ptr %5, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 4), align 8
store ptr %6, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 5), align 8
store ptr %7, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 6), align 8
store ptr %8, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 7), align 8
store ptr %9, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 8), align 8
store ptr %10, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 9), align 8
store ptr %11, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 10), align 8
store ptr %12, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 11), align 8
store ptr %13, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 12), align 8
store ptr %14, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 13), align 8
store ptr %15, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 14), align 8
store ptr %16, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 15), align 8
store ptr %17, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 16), align 8
store ptr %18, ptr getelementptr inbounds (ptr, ptr @"github.com/goplus/llgo/internal/runtime.basicTypes", i64 24), align 8
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i1 @"github.com/goplus/llgo/internal/runtime.isEmpty"(i8 %0) {
_llgo_0:
%1 = icmp ule i8 %0, 1
ret i1 %1
}
define ptr @"github.com/goplus/llgo/internal/runtime.makemap_small"() {
_llgo_0:
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
%1 = call i32 @rand()
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.hmap", ptr %0, i32 0, i32 4
store i32 %1, ptr %2, align 4
ret ptr %0
}
define void @"github.com/goplus/llgo/internal/runtime.stringTracef"(ptr %0, ptr %1, %"github.com/goplus/llgo/internal/runtime.String" %2) {
_llgo_0:
%3 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %3, i64 16)
store %"github.com/goplus/llgo/internal/runtime.String" %2, ptr %4, align 8
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %4, i32 0, i32 1
%6 = load i64, ptr %5, align 4
%7 = add i64 %6, 1
%8 = alloca i8, i64 %7, align 1
%9 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %4, align 8
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %8, %"github.com/goplus/llgo/internal/runtime.String" %9)
%11 = call i32 (ptr, ptr, ...) @fprintf(ptr %0, ptr %1, ptr %10)
ret void
}
declare ptr @malloc(i64)
declare ptr @memset(ptr, i32, i64)
declare ptr @memcpy(ptr, ptr, i64)
declare void @"github.com/goplus/llgo/internal/abi.init"()
declare i32 @rand()
declare i32 @fprintf(ptr, ptr, ...)

Binary file not shown.

View File

@@ -77,4 +77,18 @@ func CheckI2Int(v Interface, t *Type) (uintptr, bool) {
return 0, false return 0, false
} }
func I2String(v Interface, t *Type) string {
if v.tab._type == t {
return *(*string)(v.data)
}
panic("I2String: type mismatch")
}
func CheckI2String(v Interface, t *Type) (string, bool) {
if v.tab._type == t {
return *(*string)(v.data), true
}
return "", false
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -45,16 +45,6 @@ func NewString(data unsafe.Pointer, len int) String {
return String{data, len} return String{data, len}
} }
// StringLen returns the length of a string.
func StringLen(s String) int {
return s.len
}
// StringData returns the data pointer of a string.
func StringData(s String) unsafe.Pointer {
return s.data
}
// StringCat concatenates two strings. // StringCat concatenates two strings.
func StringCat(a, b String) String { func StringCat(a, b String) String {
n := a.len + b.len n := a.len + b.len

33
py/README.md Normal file
View File

@@ -0,0 +1,33 @@
Linking Python to Go
=====
TODO
## Demo
The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it):
* [hellopy](_demo/hellopy/hello.go): link Python to Go and say `Hello world`
* [clpy](_demo/clpy/cleval.go): compile Python code and eval.
* [callpy](_demo/callpy/call.go): call Python standard library function `math.sqrt`.
### How to run demos
To run the demos in directory `_demo`, you need to set the `LLGO_LIB_PYTHON` environment variable first. Assuming you use Python 3.12, and the `libpython3.12.so` (or `libpython3.12.dylib` or `python3.12.lib`) file is in the /foo/bar directory, then you need to set `LLGO_LIB_PYTHON` to:
```sh
export LLGO_LIB_PYTHON=/foo/bar/python3.12
```
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this:
```sh
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
```
Then you can run the demos in directory `_demo`:
```sh
cd <demo-directory> # eg. cd _demo/hellopy
llgo run .
```

19
py/_demo/callpy/call.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
)
func main() {
py.Initialize()
py.SetProgramName(*c.Argv)
math := py.ImportModule(c.Str("math"))
sqrt := math.GetAttrString(c.Str("sqrt"))
sqrt2 := sqrt.CallOneArg(py.Float(2))
c.Printf(c.Str("sqrt(2) = %f\n"), sqrt2.Float64())
sqrt2.DecRef()
sqrt.DecRef()
math.DecRef()
py.Finalize()
}

23
py/_demo/clpy/cleval.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
)
func main() {
py.Initialize()
py.SetProgramName(*c.Argv)
code := py.CompileString(c.Str(`print('Hello, World!')`), c.Str(`hello.py`), py.EvalInput)
if code != nil {
mod := py.ImportModule(c.Str("__main__"))
gbl := mod.ModuleGetDict()
result := py.EvalCode(code, gbl, nil)
result.DecRef()
mod.DecRef()
code.DecRef()
}
py.Finalize()
}

13
py/_demo/hellopy/hello.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/py"
)
func main() {
py.Initialize()
py.SetProgramName(*c.Argv)
py.RunSimpleString(c.Str(`print('Hello, World!')`))
py.Finalize()
}

25
py/_pyg/module.c Normal file
View File

@@ -0,0 +1,25 @@
#include <stdlib.h>
#include <stdarg.h>
// example:
// llgoLoadPyModSyms(mod, "name1", &func1, "name2", &func2, NULL)
typedef struct PyObject PyObject;
PyObject* PyObject_GetAttrString(PyObject* mod, const char* attrName);
void llgoLoadPyModSyms(PyObject* mod, ...) {
va_list ap;
va_start(ap, mod);
for (;;) {
const char* name = va_arg(ap, const char*);
if (name == NULL) {
break;
}
PyObject** pfunc = va_arg(ap, PyObject**);
if (*pfunc == NULL) {
*pfunc = PyObject_GetAttrString(mod, name);
}
}
va_end(ap);
}

46
py/bytes.go Normal file
View File

@@ -0,0 +1,46 @@
/*
* 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 py
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// https://docs.python.org/3/c-api/bytes.html
// String returns a new bytes object from a C string.
//
//go:linkname FromCStr C.PyBytes_FromString
func FromCStr(s *c.Char) *Object
// FromString returns a new bytes object from a Go string.
func FromString(s string) *Object {
return stringFromStringAndSize(c.GoStringData(s), uintptr(len(s)))
}
//go:linkname stringFromStringAndSize C.PyBytes_FromStringAndSize
func stringFromStringAndSize(s *c.Char, size uintptr) *Object
// CStr returns the content of a bytes object as a C string.
//
// llgo:link (*Object).CStr C.PyBytes_AsString
func (o *Object) CStr() *c.Char { return nil }
// llgo:link (*Object).Strlen C.PyBytes_Size
func (o *Object) Strlen() uintptr { return 0 }

32
py/float.go Normal file
View File

@@ -0,0 +1,32 @@
/*
* 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 py
import (
_ "unsafe"
)
// https://docs.python.org/3/c-api/float.html
//go:linkname Float C.PyFloat_FromDouble
func Float(v float64) *Object
//go:linkname FloatFromSring C.PyFloat_FromString
func FloatFromSring(v *Object) *Object
// llgo:link (*Object).Float64 C.PyFloat_AsDouble
func (o *Object) Float64() float64 { return 0 }

6
py/llgo.cfg Normal file
View File

@@ -0,0 +1,6 @@
{
"cl": [
"clang -emit-llvm -S -o module.ll -c _pyg/module.c",
"rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll module.ll",
]
}

BIN
py/llgo_autogen.lla Normal file

Binary file not shown.

BIN
py/math/llgo_autogen.lla Normal file

Binary file not shown.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,12 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
package gocmd package math
// ----------------------------------------------------------------------------- import (
_ "unsafe"
type BuildConfig struct { "github.com/goplus/llgo/py"
Output string )
}
// ----------------------------------------------------------------------------- const (
LLGoPackage = "py.math"
)
//go:linkname Sqrt py.sqrt
func Sqrt(x *py.Object) *py.Object

56
py/module.go Normal file
View File

@@ -0,0 +1,56 @@
/*
* 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 py
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// This is a wrapper around py.Import which takes a const char* as an argument
// instead of an Object.
//
//go:linkname ImportModule C.PyImport_ImportModule
func ImportModule(name *c.Char) *Object
// This is a higher-level interface that calls the current “import hook function” (with
// an explicit level of 0, meaning absolute import). It invokes the __import__() function
// from the __builtins__ of the current globals. This means that the import is done using
// whatever import hooks are installed in the current environment.
//
// This function always uses absolute imports.
//
//go:linkname Import C.PyImport_Import
func Import(name *Object) *Object
// Return the dictionary object that implements modules namespace; this object is the same
// as the __dict__ attribute of the module object. If module is not a module object (or a
// subtype of a module object), SystemError is raised and nil is returned.
//
// It is recommended extensions use other Module and Object functions rather than directly
// manipulate a modules __dict__.
//
// llgo:link (*Object).ModuleGetDict C.PyModule_GetDict
func (m *Object) ModuleGetDict() *Object { return nil }
// llgo:link (*Object).ModuleLoadSyms C.llgoLoadPyModSyms
func (m *Object) ModuleLoadSyms(__llgo_va_list ...any) {}
// -----------------------------------------------------------------------------

82
py/module.ll Normal file
View File

@@ -0,0 +1,82 @@
; ModuleID = '_pyg/module.c'
source_filename = "_pyg/module.c"
%struct.PyObject = type opaque
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
define void @llgoLoadPyModSyms(%struct.PyObject* noundef %0, ...) #0 {
%2 = alloca %struct.PyObject*, align 8
%3 = alloca i8*, align 8
%4 = alloca i8*, align 8
%5 = alloca i8*, align 8
%6 = alloca %struct.PyObject**, align 8
%7 = alloca %struct.PyObject**, align 8
store %struct.PyObject* %0, %struct.PyObject** %2, align 8
%8 = bitcast i8** %3 to i8*
call void @llvm.va_start(i8* %8)
br label %9
9: ; preds = %26, %1
%10 = va_arg i8** %3, i8*
store i8* %10, i8** %5, align 8
%11 = load i8*, i8** %5, align 8
store i8* %11, i8** %4, align 8
%12 = load i8*, i8** %4, align 8
%13 = icmp eq i8* %12, null
br i1 %13, label %14, label %15
14: ; preds = %9
br label %27
15: ; preds = %9
%16 = va_arg i8** %3, %struct.PyObject**
store %struct.PyObject** %16, %struct.PyObject*** %7, align 8
%17 = load %struct.PyObject**, %struct.PyObject*** %7, align 8
store %struct.PyObject** %17, %struct.PyObject*** %6, align 8
%18 = load %struct.PyObject**, %struct.PyObject*** %6, align 8
%19 = load %struct.PyObject*, %struct.PyObject** %18, align 8
%20 = icmp eq %struct.PyObject* %19, null
br i1 %20, label %21, label %26
21: ; preds = %15
%22 = load %struct.PyObject*, %struct.PyObject** %2, align 8
%23 = load i8*, i8** %4, align 8
%24 = call %struct.PyObject* @PyObject_GetAttrString(%struct.PyObject* noundef %22, i8* noundef %23)
%25 = load %struct.PyObject**, %struct.PyObject*** %6, align 8
store %struct.PyObject* %24, %struct.PyObject** %25, align 8
br label %26
26: ; preds = %21, %15
br label %9
27: ; preds = %14
%28 = bitcast i8** %3 to i8*
call void @llvm.va_end(i8* %28)
ret void
}
; Function Attrs: nocallback nofree nosync nounwind willreturn
declare void @llvm.va_start(i8*) #1
declare %struct.PyObject* @PyObject_GetAttrString(%struct.PyObject* noundef, i8* noundef) #2
; Function Attrs: nocallback nofree nosync nounwind willreturn
declare void @llvm.va_end(i8*) #1
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.5a,+zcm,+zcz" }
attributes #1 = { nocallback nofree nosync nounwind willreturn }
attributes #2 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.5a,+zcm,+zcz" }
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
!llvm.ident = !{!9}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 8, !"branch-target-enforcement", i32 0}
!3 = !{i32 8, !"sign-return-address", i32 0}
!4 = !{i32 8, !"sign-return-address-all", i32 0}
!5 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
!6 = !{i32 7, !"PIC Level", i32 2}
!7 = !{i32 7, !"uwtable", i32 1}
!8 = !{i32 7, !"frame-pointer", i32 1}
!9 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}

158
py/object.go Normal file
View File

@@ -0,0 +1,158 @@
/*
* 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 py
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// Object represents a Python object.
type Object struct {
Unused [8]byte
}
// Create a new value based on a format string similar to those accepted by the
// PyArg_Parse* family of functions and a sequence of values. Returns the value or
// nil in the case of an error; an exception will be raised if nil is returned.
// See https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
//
//go:linkname BuildValue C.Py_BuildValue
func BuildValue(format *c.Char, __llgo_va_list ...any) *Object
// llgo:link (*Object).DecRef C.Py_DecRef
func (o *Object) DecRef() {}
// -----------------------------------------------------------------------------
// Retrieve an attribute named attrName from object o. Returns the attribute value on success,
// or nil on failure. This is the equivalent of the Python expression o.attrName.
//
// llgo:link (*Object).GetAttr C.PyObject_GetAttr
func (o *Object) GetAttr(attrName *Object) *Object { return nil }
// llgo:link (*Object).GetAttrString C.PyObject_GetAttrString
func (o *Object) GetAttrString(attrName *c.Char) *Object { return nil }
// -----------------------------------------------------------------------------
// Determine if the object o is callable. Return 1 if the object is callable and
// 0 otherwise. This function always succeeds.
//
// llgo:link (*Object).Callable C.PyCallable_Check
func (o *Object) Callable() c.Int { return 0 }
// Call a callable Python object o, with arguments given by the tuple args, and
// named arguments given by the dictionary kwargs.
//
// args must not be nil; use an empty tuple if no arguments are needed. If no named
// arguments are needed, kwargs can be nil.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// This is the equivalent of the Python expression: o(*args, **kwargs).
//
// llgo:link (*Object).Call C.PyObject_Call
func (o *Object) Call(args, kwargs *Object) *Object { return nil }
// Call a callable Python object callable without any arguments. It is the most
// efficient way to call a callable Python object without any argument.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// llgo:link (*Object).CallNoArgs C.PyObject_CallNoArgs
func (o *Object) CallNoArgs() *Object { return nil }
// Call a callable Python object callable with exactly 1 positional argument arg
// and no keyword arguments.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// llgo:link (*Object).CallOneArg C.PyObject_CallOneArg
func (o *Object) CallOneArg(arg *Object) *Object { return nil }
// Call a callable Python object o, with arguments given by the tuple args. If no
// arguments are needed, then args can be nil.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// This is the equivalent of the Python expression: o(*args).
//
// llgo:link (*Object).CallObject C.PyObject_CallObject
func (o *Object) CallObject(callable, args *Object) *Object { return nil }
// Call a callable Python object o, with a variable number of C arguments. The C
// arguments are described using a py.BuildValue style format string. The format
// can be nil, indicating that no arguments are provided.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// This is the equivalent of the Python expression: o(*args).
//
// Note that if you only pass PyObject* args, (*Object).CallFunctionObjArgs is a
// faster alternative.
//
// llgo:link (*Object).CallFunction C.PyObject_CallFunction
func (o *Object) CallFunction(format *c.Char, __llgo_va_list ...any) *Object { return nil }
// Call a callable Python object o, with a variable number of PyObject* arguments.
// The arguments are provided as a variable number of parameters followed by nil.
//
// Return the result of the call on success, or raise an exception and return nil
// on failure.
//
// This is the equivalent of the Python expression: o(arg1, arg2, ...).
//
// llgo:link (*Object).CallFunctionObjArgs C.PyObject_CallFunctionObjArgs
func (o *Object) CallFunctionObjArgs(__llgo_va_list ...any) *Object { return nil }
// llgo:link (*Object).CallMethod C.PyObject_CallMethod
func (o *Object) CallMethod(name *c.Char, format *c.Char, __llgo_va_list ...any) *Object {
return nil
}
// llgo:link (*Object).CallMethodObjArgs C.PyObject_CallMethodObjArgs
func (o *Object) CallMethodObjArgs(name *Object, __llgo_va_list ...any) *Object { return nil }
// llgo:link (*Object).CallMethodNoArgs C.PyObject_CallMethodNoArgs
func (o *Object) CallMethodNoArgs(name *Object) *Object { return nil }
// llgo:link (*Object).CallMethodOneArg C.PyObject_CallMethodOneArg
func (o *Object) CallMethodOneArg(name, arg *Object) *Object { return nil }
// llgo:link (*Object).Vectorcall C.PyObject_Vectorcall
func (o *Object) Vectorcall(args **Object, nargs uintptr, kwnames *Object) *Object {
return nil
}
// llgo:link (*Object).VectorcallDict C.PyObject_VectorcallDict
func (o *Object) VectorcallDict(args **Object, nargs uintptr, kwdict *Object) *Object {
return nil
}
// llgo:link (*Object).VectorcallMethod C.PyObject_VectorcallMethod
func (o *Object) VectorcallMethod(name *Object, args **Object, nargs uintptr, kwnames *Object) *Object {
return nil
}
// -----------------------------------------------------------------------------

BIN
py/os/llgo_autogen.lla Normal file

Binary file not shown.

30
py/os/os.go Normal file
View File

@@ -0,0 +1,30 @@
/*
* 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 os
import (
_ "unsafe"
"github.com/goplus/llgo/py"
)
const (
LLGoPackage = "py.os"
)
//go:linkname Getcwd py.getcwd
func Getcwd() *py.Object

Some files were not shown because too many files have changed in this diff Show More