Compare commits

...

50 Commits

Author SHA1 Message Date
xushiwei
908f0047f8 Merge pull request #199 from visualfc/index
ssa: checkIndex for index/indexAddr
2024-05-18 16:48:26 +08:00
xushiwei
e533903cee Merge pull request #202 from xushiwei/q
py/torch; llpyg: use pysigfetch (by goplus/hdq)
2024-05-18 16:46:56 +08:00
xushiwei
1be8052caa llpyg: fix pysigfetch error handling 2024-05-18 16:45:02 +08:00
xushiwei
668ce4bd2d py/torch; llpyg: use pysigfetch (by goplus/hdq) 2024-05-18 16:03:49 +08:00
visualfc
e7fd038493 ssa: checkIndex for index/indexAddr 2024-05-18 11:08:39 +08:00
visualfc
03edb3bbbe runtime: assertRuntimeError assertNegativeShift assertIndexRange 2024-05-18 10:16:57 +08:00
xushiwei
307a1a295a Merge pull request #201 from xushiwei/q
mv x/ => c/
2024-05-17 22:43:39 +08:00
xushiwei
446df58e92 TestSqlite 2024-05-17 22:41:39 +08:00
xushiwei
1ad5caba93 cl: _testlibc/sqlite fix 2024-05-17 22:38:32 +08:00
xushiwei
9eddc0e4f0 submodule c/llama2/llama2.c 2024-05-17 22:34:34 +08:00
xushiwei
087ba0d81d mv x/ => c/ 2024-05-17 22:33:57 +08:00
xushiwei
3c5cd8f38f Merge pull request #200 from xushiwei/q
py/torch
2024-05-17 21:50:00 +08:00
xushiwei
367743530f py/torch 2024-05-17 21:46:38 +08:00
xushiwei
7370ce2793 Merge pull request #198 from xushiwei/q
Cstr (for Go+)
2024-05-17 21:19:51 +08:00
xushiwei
ba61b42ef5 Cstr (for Go+) 2024-05-17 21:14:41 +08:00
xushiwei
f7e362dd90 Merge pull request #197 from visualfc/global_array
ssa: fix global array
2024-05-17 19:38:51 +08:00
visualfc
66da072fd7 ssa: fix global array 2024-05-17 19:30:56 +08:00
xushiwei
d763534208 Merge pull request #196 from xushiwei/q
build: checkFlag fix (for Go+)
2024-05-17 13:57:31 +08:00
xushiwei
ad05898543 build: checkFlag fix (for Go+) 2024-05-17 13:54:00 +08:00
xushiwei
f930f7878d Merge pull request #195 from xushiwei/q
cl: out.ll regen
2024-05-17 11:16:58 +08:00
xushiwei
d6a75c411b _testpy/pi 2024-05-17 11:14:19 +08:00
xushiwei
568a71e0dc cl: out.ll regen 2024-05-17 11:11:22 +08:00
xushiwei
c92e9aac2c Merge pull request #189 from tsingbx/main_return_0
Main return 0
2024-05-17 11:09:20 +08:00
xushiwei
3012c4a3ff Merge branch 'main' into main_return_0 2024-05-17 11:05:09 +08:00
xushiwei
ebe338ac9a Merge pull request #193 from visualfc/type
ssa: type uint/byte/int32/uint32/int64/uint64
2024-05-17 11:04:12 +08:00
tsingbx
a45523a48c run gentests 2024-05-17 09:48:21 +08:00
tsingbx
5bfeea67d7 change main return to C int 2024-05-17 09:31:48 +08:00
visualfc
f35f15d36c ssa: type uint/byte/int32/uint32/int64/uint64 2024-05-17 09:28:57 +08:00
tsingbx
057af792df main return type chang to C int 2024-05-17 09:06:53 +08:00
xushiwei
41a850e7b2 Merge pull request #194 from xushiwei/q
py/{numpy, pandas}
2024-05-17 09:04:56 +08:00
xushiwei
6be70390a6 py/{numpy, pandas} 2024-05-17 09:01:36 +08:00
xushiwei
1cfe3ee9f8 Merge pull request #192 from xushiwei/q
pysig.Parse; py/pandas
2024-05-17 05:30:18 +08:00
xushiwei
c1927c985a pysig.Parse; py/pandas 2024-05-17 05:25:13 +08:00
xushiwei
309f42994b Merge pull request #191 from visualfc/castint
ssa: fix castInt
2024-05-16 21:20:23 +08:00
visualfc
feb28ecace ssa: fix castInt 2024-05-16 20:43:16 +08:00
xushiwei
00f74b7f0a Merge pull request #190 from xushiwei/q
build fix: -L dir
2024-05-16 18:42:45 +08:00
xushiwei
fcc0e1776b build fix: -L dir 2024-05-16 18:40:49 +08:00
xushiwei
a5ec755c28 Merge pull request #188 from visualfc/shift_check
ssa: binop check shl/shr
2024-05-16 18:04:25 +08:00
visualfc
98945926ca ssa: binop check shl/shr 2024-05-16 16:27:49 +08:00
tsingbx
d3e3767df4 Merge branch 'main' of https://github.com/goplus/llgo into main_return_0 2024-05-16 15:35:05 +08:00
tsingbx
de1281bb66 Add return value to llvm's ir main function definition 2024-05-16 15:27:14 +08:00
xushiwei
07e55c3d89 Merge pull request #187 from visualfc/shift
ssa: binop fix shl/shr size
2024-05-16 10:48:03 +08:00
visualfc
6e4ebeddf4 ssa: binop fix shl/shr size 2024-05-16 10:20:02 +08:00
xushiwei
2b9fb88bf0 Merge pull request #183 from visualfc/print
ssa: builtin print/println
2024-05-16 09:40:14 +08:00
visualfc
022965b9c7 ssa: builtin print/println 2024-05-16 09:33:25 +08:00
xushiwei
6278718a24 Merge pull request #186 from xushiwei/q
README: Key modules
2024-05-16 07:08:46 +08:00
xushiwei
1675daafcd Key modules 2024-05-16 07:08:10 +08:00
xushiwei
ed5b6edf52 Merge pull request #185 from xushiwei/q
README: Development tools
2024-05-16 06:34:55 +08:00
xushiwei
638caa355c Development tools 2024-05-16 06:34:18 +08:00
xushiwei
78b2f9b455 Update README.md 2024-05-16 01:08:21 +08:00
97 changed files with 14281 additions and 921 deletions

4
.gitmodules vendored
View File

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

View File

@@ -35,7 +35,7 @@ To run these demos (If you haven't installed `llgo` yet, please refer to [How to
```sh ```sh
export LLGOROOT=`pwd` export LLGOROOT=`pwd`
cd <demo-directory> # eg. cd _demo/genints cd <demo-directory> # eg. cd _demo/hello
llgo run . llgo run .
``` ```
@@ -46,7 +46,7 @@ See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for
You can import a Python library in LLGo! You can import a Python library in LLGo!
And you can import any Python library into `llgo` through a program called `llpyg`. The currently imported libraries include: And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The currently imported libraries include:
* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys) * [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os) * [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
@@ -150,15 +150,15 @@ LLGo can easily import any libraries from the C ecosystem. Currently, this impor
The currently imported libraries include: The currently imported libraries include:
* [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/x/llama2) * [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
* [cjson](https://pkg.go.dev/github.com/goplus/llgo/x/cjson) * [cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
* [sqlite](https://pkg.go.dev/github.com/goplus/llgo/x/sqlite) * [sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
Here are some examples related to them: Here are some examples related to them:
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example) * [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
* [mkjson](x/cjson/_demo/mkjson/mkjson.go): create a json object and print it * [mkjson](c/cjson/_demo/mkjson/mkjson.go): create a json object and print it
* [sqlite](x/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo * [sqlitedemo](c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
## Go syntax support ## Go syntax support
@@ -213,3 +213,27 @@ go install -v ./...
### on Windows ### on Windows
TODO TODO
## Development tools
* [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`.
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` to accomplish the task.
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.
How do I generate these tools?
```sh
go install -v ./... # compile all tools except pydump
cd chore/_xtool
llgo install ./... # compile pydump
```
## Key modules
Below are the key modules for understanding the implementation principles of `llgo`:
* [llgo/ssa](https://pkg.go.dev/github.com/goplus/llgo/ssa): It generates LLVM IR files (LLVM SSA) using the semantics (interfaces) of Go SSA. Although `LLVM SSA` and `Go SSA` are both IR languages, they work at completely different levels. `LLVM SSA` is closer to machine code, which abstracts different instruction sets. While `Go SSA` is closer to a high-level language. We can think of it as the instruction set of the `Go computer`. `llgo/ssa` is not just limited to the `llgo` compiler. If we view it as the high-level expressive power of `LLVM`, you'll find it very useful. Prior to `llgo/ssa`, you had to operate `LLVM` using machine code semantics. But now, with the advanced SSA form (in the semantics of Go SSA), you can conveniently utilize `LLVM`.
* [llgo/cl](https://pkg.go.dev/github.com/goplus/llgo/cl): It is the core of the llgo compiler. It converts a Go package into LLVM IR files. It depends on `llgo/ssa`.
* [llgo/internal/build](https://pkg.go.dev/github.com/goplus/llgo/internal/build): It strings together the entire compilation process of `llgo`. It depends on `llgo/ssa` and `llgo/cl`.

View File

@@ -2,7 +2,7 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/llama2" "github.com/goplus/llgo/c/llama2"
) )
func main() { func main() {

1
c/c.go
View File

@@ -33,6 +33,7 @@ type (
LongLong = int64 LongLong = int64
UlongLong = uint64 UlongLong = uint64
Float = float32 Float = float32
Double = float64
Pointer = unsafe.Pointer Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer FilePtr = unsafe.Pointer
) )

View File

@@ -2,7 +2,7 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/cjson" "github.com/goplus/llgo/c/cjson"
) )
func main() { func main() {

View File

@@ -96,6 +96,11 @@ func (o *JSON) SetItem(key *c.Char, item *JSON) c.Int { return 0 }
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted // llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
func (o *JSON) CStr() *c.Char { return nil } func (o *JSON) CStr() *c.Char { return nil }
// Same as CStr. Provided for Go+.
//
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
func (o *JSON) Cstr() *c.Char { return nil }
// Render a JSON entity to text for transfer/storage. // Render a JSON entity to text for transfer/storage.
// //
// llgo:link (*JSON).Print C.cJSON_Print // llgo:link (*JSON).Print C.cJSON_Print

BIN
c/cjson/llgo_autogen.lla Normal file

Binary file not shown.

159
c/llama2/llama2.go Normal file
View File

@@ -0,0 +1,159 @@
/*
* 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 llama2
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
// llgo:type C
type TokenIndex struct {
Str *c.Char
Id c.Int
}
// llgo:type C
type Tokenizer struct {
Vocab **c.Char
VocabScores *c.Float
SortedVocab *TokenIndex
VocabSize c.Int
MaxTokenLength c.Uint
BytePieces [512]uint8 // stores all single-byte strings
}
//go:linkname BuildTokenizer C.build_tokenizer
func BuildTokenizer(t *Tokenizer, tokenizerPath *c.Char, vocabSize c.Int)
//go:linkname FreeTokenizer C.free_tokenizer
func FreeTokenizer(t *Tokenizer)
// -----------------------------------------------------------------------------
// llgo:type C
type Config struct {
Dim c.Int // transformer dimension
HiddenDim c.Int // for ffn layers
NLayers c.Int // number of layers
NHeads c.Int // number of query heads
NKVHeads c.Int // number of key/value heads (can be < query heads because of multiquery)
VocabSize c.Int // vocabulary size, usually 256 (byte-level)
SeqLen c.Int // max sequence length
}
// llgo:type C
type TransformerWeights struct {
// token embedding table
TokenEmbeddingTable *c.Float // (vocab_size, dim)
// weights for rmsnorms
RmsAttWeight *c.Float // (layer, dim) rmsnorm weights
RmsFfnWeight *c.Float // (layer, dim)
// weights for matmuls. note dim == n_heads * head_size
Wq *c.Float // (layer, dim, n_heads * head_size)
Wk *c.Float // (layer, dim, n_kv_heads * head_size)
Wv *c.Float // (layer, dim, n_kv_heads * head_size)
Wo *c.Float // (layer, n_heads * head_size, dim)
// weights for ffn
W1 *c.Float // (layer, hidden_dim, dim)
W2 *c.Float // (layer, dim, hidden_dim)
W3 *c.Float // (layer, hidden_dim, dim)
// final rmsnorm
RmsFinalWeight *c.Float // (dim,)
// (optional) classifier weights for the logits, on the last layer
Wcls *c.Float
}
// llgo:type C
type RunState struct {
// current wave of activations
X *c.Float // activation at current time stamp (dim,)
Xb *c.Float // same, but inside a residual branch (dim,)
Xb2 *c.Float // an additional buffer just for convenience (dim,)
Hb *c.Float // buffer for hidden dimension in the ffn (hidden_dim,)
Hb2 *c.Float // buffer for hidden dimension in the ffn (hidden_dim,)
Q *c.Float // query (dim,)
K *c.Float // key (dim,)
V *c.Float // value (dim,)
Att *c.Float // buffer for scores/attention values (n_heads, seq_len)
Logits *c.Float // output logits
// kv cache
KeyCache *c.Float // (layer, seq_len, dim)
ValueCache *c.Float // (layer, seq_len, dim)
}
// llgo:type C
type Transformer struct {
Config Config // the hyperparameters of the architecture (the blueprint)
Weights TransformerWeights // the weights of the model
State RunState // buffers for the "wave" of activations in the forward pass
// some more state needed to properly clean up the memory mapping (sigh)
Fd c.Int // file descriptor for memory mapping
Data *c.Float // memory mapped data pointer
FileSize uintptr // size of the checkpoint file in bytes
}
//go:linkname BuildTransformer C.build_transformer
func BuildTransformer(t *Transformer, checkpointPath *c.Char)
//go:linkname FreeTransformer C.free_transformer
func FreeTransformer(t *Transformer)
// -----------------------------------------------------------------------------
// llgo:type C
type ProbIndex struct {
Prob c.Float
Index c.Int
} // struct used when sorting probabilities during top-p sampling
// llgo:type C
type Sampler struct {
VocabSize c.Int
Probindex *ProbIndex // buffer used in top-p sampling
Temperature c.Float
Topp c.Float
RngState uint64
}
//go:linkname BuildSampler C.build_sampler
func BuildSampler(sampler *Sampler, vocabSize c.Int, temperature c.Float, topp c.Float, rngSeed uint64)
//go:linkname FreeSampler C.free_sampler
func FreeSampler(sampler *Sampler)
// -----------------------------------------------------------------------------
//go:linkname Generate C.generate
func Generate(
transformer *Transformer, tokenizer *Tokenizer, sampler *Sampler,
prompt *c.Char, steps c.Int)
//go:linkname Chat C.chat
func Chat(
transformer *Transformer, tokenizer *Tokenizer, sampler *Sampler,
cliUserPrompt *c.Char, cliSystemPrompt *c.Char, steps c.Int)
// -----------------------------------------------------------------------------

View File

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

View File

@@ -2,7 +2,7 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/sqlite" "github.com/goplus/llgo/c/sqlite"
) )
func main() { func main() {

BIN
c/sqlite/llgo_autogen.lla Normal file

Binary file not shown.

View File

@@ -22,12 +22,6 @@ import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
type (
Char = c.Char
Int = c.Int
Pointer = c.Pointer
)
const ( const (
LLGoPackage = "link: sqlite3" LLGoPackage = "link: sqlite3"
) )
@@ -44,7 +38,7 @@ type Stmt struct {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type Errno Int type Errno c.Int
const ( const (
OK Errno = 0 // Successful result OK Errno = 0 // Successful result
@@ -83,10 +77,10 @@ const (
) )
// llgo:link (Errno).Errstr C.sqlite3_errstr // llgo:link (Errno).Errstr C.sqlite3_errstr
func (err Errno) Errstr() *Char { return nil } func (err Errno) Errstr() *c.Char { return nil }
// llgo:link (*Sqlite3).Errmsg C.sqlite3_errmsg // llgo:link (*Sqlite3).Errmsg C.sqlite3_errmsg
func (db *Sqlite3) Errmsg() *Char { return nil } func (db *Sqlite3) Errmsg() *c.Char { return nil }
// llgo:link (*Sqlite3).Errcode C.sqlite3_errcode // llgo:link (*Sqlite3).Errcode C.sqlite3_errcode
func (db *Sqlite3) Errcode() Errno { return 0 } func (db *Sqlite3) Errcode() Errno { return 0 }
@@ -97,13 +91,13 @@ func (db *Sqlite3) ExtendedErrcode() Errno { return 0 }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname doOpen C.sqlite3_open //go:linkname doOpen C.sqlite3_open
func doOpen(filename *Char, ppDb **Sqlite3) Errno func doOpen(filename *c.Char, ppDb **Sqlite3) Errno
//go:linkname doOpenV2 C.sqlite3_open_v2 //go:linkname doOpenV2 C.sqlite3_open_v2
func doOpenV2(filename *Char, ppDb **Sqlite3, flags OpenFlags, zVfs *Char) Errno func doOpenV2(filename *c.Char, ppDb **Sqlite3, flags OpenFlags, zVfs *c.Char) Errno
// OpenFlags represents SQLite open flags. // OpenFlags represents SQLite open flags.
type OpenFlags Int type OpenFlags c.Int
const ( const (
OpenReadOnly OpenFlags = 0x00000001 OpenReadOnly OpenFlags = 0x00000001
@@ -132,7 +126,7 @@ const (
// Opening A New Database Connection // Opening A New Database Connection
// filename: Database filename (UTF-8) // filename: Database filename (UTF-8)
func Open(filename *Char) (db *Sqlite3, err Errno) { func Open(filename *c.Char) (db *Sqlite3, err Errno) {
err = doOpen(filename, &db) err = doOpen(filename, &db)
return return
} }
@@ -140,7 +134,7 @@ func Open(filename *Char) (db *Sqlite3, err Errno) {
// Opening A New Database Connection // Opening A New Database Connection
// filename: Database filename (UTF-8) // filename: Database filename (UTF-8)
// zVfs: Name of VFS module to use // zVfs: Name of VFS module to use
func OpenV2(filename *Char, flags OpenFlags, zVfs *Char) (db *Sqlite3, err Errno) { func OpenV2(filename *c.Char, flags OpenFlags, zVfs *c.Char) (db *Sqlite3, err Errno) {
err = doOpenV2(filename, &db, flags, zVfs) err = doOpenV2(filename, &db, flags, zVfs)
return return
} }
@@ -158,22 +152,22 @@ func (db *Sqlite3) CloseV2() Errno { return 0 }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// llgo:link (*Sqlite3).doPrepare C.sqlite3_prepare // llgo:link (*Sqlite3).doPrepare C.sqlite3_prepare
func (*Sqlite3) doPrepare(*Char, Int, **Stmt, **Char) Errno { func (*Sqlite3) doPrepare(*c.Char, c.Int, **Stmt, **c.Char) Errno {
return 0 return 0
} }
// llgo:link (*Sqlite3).doPrepareV2 C.sqlite3_prepare_v2 // llgo:link (*Sqlite3).doPrepareV2 C.sqlite3_prepare_v2
func (*Sqlite3) doPrepareV2(*Char, Int, **Stmt, **Char) Errno { func (*Sqlite3) doPrepareV2(*c.Char, c.Int, **Stmt, **c.Char) Errno {
return 0 return 0
} }
// llgo:link (*Sqlite3).doPrepareV3 C.sqlite3_prepare_v3 // llgo:link (*Sqlite3).doPrepareV3 C.sqlite3_prepare_v3
func (*Sqlite3) doPrepareV3(*Char, Int, PrepareFlags, **Stmt, **Char) Errno { func (*Sqlite3) doPrepareV3(*c.Char, c.Int, PrepareFlags, **Stmt, **c.Char) Errno {
return 0 return 0
} }
// PrepareFlags represents SQLite prepare flags. // PrepareFlags represents SQLite prepare flags.
type PrepareFlags Int type PrepareFlags c.Int
const ( const (
PreparePersistent PrepareFlags = 0x01 PreparePersistent PrepareFlags = 0x01
@@ -183,17 +177,17 @@ const (
// Compiling An SQL Statement // Compiling An SQL Statement
// tail: Pointer to unused portion of sql // tail: Pointer to unused portion of sql
func (db *Sqlite3) Prepare(sql string, tail **Char) (stmt *Stmt, err Errno) { func (db *Sqlite3) Prepare(sql string, tail **c.Char) (stmt *Stmt, err Errno) {
err = db.doPrepare(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail) err = db.doPrepare(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail)
return return
} }
func (db *Sqlite3) PrepareV2(sql string, tail **Char) (stmt *Stmt, err Errno) { func (db *Sqlite3) PrepareV2(sql string, tail **c.Char) (stmt *Stmt, err Errno) {
err = db.doPrepareV2(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail) err = db.doPrepareV2(c.GoStringData(sql), c.Int(len(sql)), &stmt, tail)
return return
} }
func (db *Sqlite3) PrepareV3(sql string, flags PrepareFlags, tail **Char) (stmt *Stmt, err Errno) { func (db *Sqlite3) PrepareV3(sql string, flags PrepareFlags, tail **c.Char) (stmt *Stmt, err Errno) {
err = db.doPrepareV3(c.GoStringData(sql), c.Int(len(sql)), flags, &stmt, tail) err = db.doPrepareV3(c.GoStringData(sql), c.Int(len(sql)), flags, &stmt, tail)
return return
} }
@@ -206,10 +200,10 @@ func (stmt *Stmt) Close() Errno { return 0 }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// llgo:link (*Stmt).BindInt C.sqlite3_bind_int // llgo:link (*Stmt).BindInt C.sqlite3_bind_int
func (*Stmt) BindInt(idx Int, val Int) Errno { return 0 } func (*Stmt) BindInt(idx c.Int, val c.Int) Errno { return 0 }
// llgo:link (*Stmt).BindInt64 C.sqlite3_bind_int64 // llgo:link (*Stmt).BindInt64 C.sqlite3_bind_int64
func (*Stmt) BindInt64(idx Int, val int64) Errno { return 0 } func (*Stmt) BindInt64(idx c.Int, val int64) Errno { return 0 }
/* /*
const ( const (
@@ -219,7 +213,9 @@ const (
*/ */
// llgo:link (*Stmt).BindText C.sqlite3_bind_text // llgo:link (*Stmt).BindText C.sqlite3_bind_text
func (*Stmt) BindText(idx Int, val *Char, nByte Int, destructor func(Pointer)) Errno { return 0 } func (*Stmt) BindText(idx c.Int, val *c.Char, nByte c.Int, destructor func(c.Pointer)) Errno {
return 0
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -238,19 +234,19 @@ func (*Stmt) Step() Errno { return 0 }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// llgo:link (*Stmt).ColumnCount C.sqlite3_column_count // llgo:link (*Stmt).ColumnCount C.sqlite3_column_count
func (stmt *Stmt) ColumnCount() Int { return 0 } func (stmt *Stmt) ColumnCount() c.Int { return 0 }
// llgo:link (*Stmt).ColumnName C.sqlite3_column_name // llgo:link (*Stmt).ColumnName C.sqlite3_column_name
func (stmt *Stmt) ColumnName(idx Int) *Char { return nil } func (stmt *Stmt) ColumnName(idx c.Int) *c.Char { return nil }
// llgo:link (*Stmt).ColumnInt C.sqlite3_column_int // llgo:link (*Stmt).ColumnInt C.sqlite3_column_int
func (stmt *Stmt) ColumnInt(idx Int) Int { return 0 } func (stmt *Stmt) ColumnInt(idx c.Int) c.Int { return 0 }
// llgo:link (*Stmt).ColumnInt64 C.sqlite3_column_int64 // llgo:link (*Stmt).ColumnInt64 C.sqlite3_column_int64
func (stmt *Stmt) ColumnInt64(idx Int) int64 { return 0 } func (stmt *Stmt) ColumnInt64(idx c.Int) int64 { return 0 }
// llgo:link (*Stmt).ColumnText C.sqlite3_column_text // llgo:link (*Stmt).ColumnText C.sqlite3_column_text
func (stmt *Stmt) ColumnText(idx Int) *Char { return nil } func (stmt *Stmt) ColumnText(idx c.Int) *c.Char { return nil }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -258,8 +254,8 @@ func (stmt *Stmt) ColumnText(idx Int) *Char { return nil }
// //
// llgo:link (*Sqlite3).Exec C.sqlite3_exec // llgo:link (*Sqlite3).Exec C.sqlite3_exec
func (*Sqlite3) Exec( func (*Sqlite3) Exec(
sql *Char, callback func(arg Pointer, resultCols Int, colVals, colNames **Char) Int, sql *c.Char, callback func(arg c.Pointer, resultCols c.Int, colVals, colNames **c.Char) c.Int,
arg Pointer, errmsg **Char) Errno { arg c.Pointer, errmsg **c.Char) Errno {
return 0 return 0
} }

View File

@@ -18,9 +18,9 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson"
"github.com/goplus/llgo/py" "github.com/goplus/llgo/py"
"github.com/goplus/llgo/py/inspect" "github.com/goplus/llgo/py/inspect"
"github.com/goplus/llgo/x/cjson"
) )
func main() { func main() {

View File

@@ -29,6 +29,7 @@ import (
"strings" "strings"
"github.com/goplus/gogen" "github.com/goplus/gogen"
"github.com/goplus/llgo/chore/llpyg/pysig"
"github.com/goplus/llgo/ssa" "github.com/goplus/llgo/ssa"
) )
@@ -37,6 +38,7 @@ type symbol struct {
Type string `json:"type"` Type string `json:"type"`
Doc string `json:"doc"` Doc string `json:"doc"`
Sig string `json:"sig"` Sig string `json:"sig"`
URL string `json:"url"`
} }
type module struct { type module struct {
@@ -44,6 +46,29 @@ type module struct {
Items []*symbol `json:"items"` Items []*symbol `json:"items"`
} }
func pydump(pyLib string) (mod module) {
var out bytes.Buffer
cmd := exec.Command("pydump", pyLib)
cmd.Stdout = &out
cmd.Stderr = os.Stderr
cmd.Run()
json.Unmarshal(out.Bytes(), &mod)
return
}
func pysigfetch(pyLib string, names []string) (mod module) {
var out bytes.Buffer
cmd := exec.Command("pysigfetch", pyLib, "-")
cmd.Stdin = strings.NewReader(strings.Join(names, " "))
cmd.Stdout = &out
cmd.Stderr = os.Stderr
cmd.Run()
json.Unmarshal(out.Bytes(), &mod)
return
}
func main() { func main() {
if len(os.Args) < 2 { if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "Usage: llpyg <pythonLibPath>") fmt.Fprintln(os.Stderr, "Usage: llpyg <pythonLibPath>")
@@ -51,25 +76,17 @@ func main() {
} }
pyLib := os.Args[1] pyLib := os.Args[1]
var out bytes.Buffer mod := pydump(pyLib)
pydump := exec.Command("pydump", pyLib) if mod.Name != pyLib {
pydump.Stdout = &out
pydump.Run()
var mod module
json.Unmarshal(out.Bytes(), &mod)
modName := mod.Name
if modName == "" {
log.Printf("import module %s failed\n", pyLib) log.Printf("import module %s failed\n", pyLib)
os.Exit(1) os.Exit(1)
} }
pkg := gogen.NewPackage("", modName, nil) pkg := gogen.NewPackage("", pyLib, nil)
pkg.Import("unsafe").MarkForceUsed(pkg) // import _ "unsafe" pkg.Import("unsafe").MarkForceUsed(pkg) // import _ "unsafe"
py := pkg.Import("github.com/goplus/llgo/py") // import "github.com/goplus/llgo/py" py := pkg.Import("github.com/goplus/llgo/py") // import "github.com/goplus/llgo/py"
f := func(cb *gogen.CodeBuilder) int { f := func(cb *gogen.CodeBuilder) int {
cb.Val("py." + modName) cb.Val("py." + mod.Name)
return 1 return 1
} }
defs := pkg.NewConstDefs(pkg.Types.Scope()) defs := pkg.NewConstDefs(pkg.Types.Scope())
@@ -79,20 +96,22 @@ func main() {
objPtr := types.NewPointer(obj) objPtr := types.NewPointer(obj)
ret := types.NewTuple(pkg.NewParam(0, "", objPtr)) ret := types.NewTuple(pkg.NewParam(0, "", objPtr))
ctx := &context{pkg, obj, objPtr, ret, py} ctx := &context{pkg, obj, objPtr, ret, nil, py}
for _, sym := range mod.Items { ctx.genMod(pkg, &mod)
switch sym.Type { skips := ctx.skips
case "builtin_function_or_method", "function", "ufunc", "method-wrapper": if n := len(skips); n > 0 {
ctx.genFunc(pkg, sym) log.Printf("==> There are %d signatures not found, fetch from doc site\n", n)
case "str", "float", "bool", "type", "dict", "tuple", "list", "object", mod = pysigfetch(pyLib, skips)
"module", "int", "set", "frozenset", "flags", "bool_": // skip ctx.skips = skips[:0]
default: ctx.genMod(pkg, &mod)
t := sym.Type if len(mod.Items) > 0 {
if len(t) > 0 && (t[0] >= 'a' && t[0] <= 'z') && !strings.HasSuffix(t, "_info") { skips = ctx.skips
log.Panicln("unsupport type:", sym.Type) }
} if n := len(skips); n > 0 {
log.Printf("==> Skip %d symbols:\n%v\n", n, skips)
} }
} }
pkg.WriteTo(os.Stdout) pkg.WriteTo(os.Stdout)
} }
@@ -101,67 +120,83 @@ type context struct {
obj *types.Named obj *types.Named
objPtr *types.Pointer objPtr *types.Pointer
ret *types.Tuple ret *types.Tuple
skips []string
py gogen.PkgRef py gogen.PkgRef
} }
func (ctx *context) genMod(pkg *gogen.Package, mod *module) {
for _, sym := range mod.Items {
switch sym.Type {
case "builtin_function_or_method", "function", "ufunc", "method-wrapper":
ctx.genFunc(pkg, sym)
case "str", "float", "bool", "type", "dict", "tuple", "list", "object", "module",
"int", "set", "frozenset", "flags", "bool_", "pybind11_type", "layout",
"memory_format", "qscheme", "dtype", "tensortype": // skip
case "": // pysigfetch: page not found
ctx.skips = append(ctx.skips, sym.Name)
default:
t := sym.Type
if len(t) > 0 && (t[0] >= 'a' && t[0] <= 'z') && !strings.HasSuffix(t, "_info") {
log.Panicln("unsupport type:", sym.Type)
}
}
}
}
func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) { func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
name, symSig := sym.Name, sym.Sig name, symSig := sym.Name, sym.Sig
if len(name) == 0 || name[0] == '_' { if len(name) == 0 || name[0] == '_' {
return return
} }
params, variadic, skip := ctx.genParams(pkg, symSig) if symSig == "<NULL>" {
if skip { ctx.skips = append(ctx.skips, name)
// TODO(xsw): don't skip any func
log.Println("skip func:", name, symSig)
return return
} }
params, variadic := ctx.genParams(pkg, symSig)
name = genName(name, -1) name = genName(name, -1)
sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic) sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic)
fn := pkg.NewFuncDecl(token.NoPos, name, sig) fn := pkg.NewFuncDecl(token.NoPos, name, sig)
list := ctx.genDoc(sym.Doc) list := ctx.genDoc(sym.Doc)
list = append(list, emptyCommentLine) if sym.URL != "" {
if len(list) > 0 {
list = append(list, emptyCommentLine)
}
list = append(list, genSee(sym.URL))
}
if len(list) > 0 {
list = append(list, emptyCommentLine)
}
list = append(list, ctx.genLinkname(name, sym)) list = append(list, ctx.genLinkname(name, sym))
fn.SetComments(pkg, &ast.CommentGroup{List: list}) fn.SetComments(pkg, &ast.CommentGroup{List: list})
// fn.BodyStart(pkg).End() // fn.BodyStart(pkg).End()
} }
func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool, bool) { func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool) {
if sig == "<NULL>" { args := pysig.Parse(sig)
return nil, false, true if len(args) == 0 {
return nil, false
} }
sig = strings.TrimSuffix(strings.TrimPrefix(sig, "("), ")") n := len(args)
if sig == "" { // empty params
return nil, false, false
}
parts := strings.Split(sig, ",")
n := len(parts)
objPtr := ctx.objPtr objPtr := ctx.objPtr
list := make([]*types.Var, 0, n) list := make([]*types.Var, 0, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
part := strings.TrimSpace(parts[i]) name := args[i].Name
if part == "/" { if name == "/" {
continue continue
} }
if part == "*" { if name == "*" || name == "\\*" {
break break
} }
if strings.HasPrefix(part, "*") { if strings.HasPrefix(name, "*") {
if part[1] != '*' { if name[1] != '*' {
list = append(list, ssa.VArg()) list = append(list, ssa.VArg())
return types.NewTuple(list...), true, false return types.NewTuple(list...), true
} }
return types.NewTuple(list...), false, false return types.NewTuple(list...), false
} }
pos := strings.IndexByte(part, '=') list = append(list, pkg.NewParam(0, genName(name, 0), objPtr))
if pos >= 0 {
if strings.HasPrefix(part[pos+1:], "<") { // skip complex default value
return nil, false, true
}
part = part[:pos]
}
list = append(list, pkg.NewParam(0, genName(part, 0), objPtr))
} }
return types.NewTuple(list...), false, false return types.NewTuple(list...), false
} }
func genName(name string, idxDontTitle int) string { func genName(name string, idxDontTitle int) string {
@@ -176,7 +211,7 @@ func genName(name string, idxDontTitle int) string {
} }
name = strings.Join(parts, "") name = strings.Join(parts, "")
switch name { switch name {
case "default", "func", "": case "default", "func", "var", "":
name += "_" name += "_"
} }
return name return name
@@ -187,14 +222,21 @@ func (ctx *context) genLinkname(name string, sym *symbol) *ast.Comment {
} }
func (ctx *context) genDoc(doc string) []*ast.Comment { func (ctx *context) genDoc(doc string) []*ast.Comment {
if doc == "" {
return make([]*ast.Comment, 0, 4)
}
lines := strings.Split(doc, "\n") lines := strings.Split(doc, "\n")
list := make([]*ast.Comment, len(lines), len(lines)+2) list := make([]*ast.Comment, len(lines), len(lines)+4)
for i, line := range lines { for i, line := range lines {
list[i] = &ast.Comment{Text: "// " + line} list[i] = &ast.Comment{Text: "// " + line}
} }
return list return list
} }
func genSee(url string) *ast.Comment {
return &ast.Comment{Text: "// See " + url}
}
var ( var (
emptyCommentLine = &ast.Comment{Text: "//"} emptyCommentLine = &ast.Comment{Text: "//"}
) )

100
chore/llpyg/pysig/parse.go Normal file
View File

@@ -0,0 +1,100 @@
/*
* 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 pysig
import (
"strings"
)
type Arg struct {
Name string
Type string
DefVal string
}
// Parse parses a Python function signature.
func Parse(sig string) (args []*Arg) {
sig = strings.TrimPrefix(sig, "(")
for {
pos := strings.IndexAny(sig, ",:=)")
if pos <= 0 {
return
}
arg := &Arg{Name: strings.TrimSpace(sig[:pos])}
args = append(args, arg)
c := sig[pos]
sig = sig[pos+1:]
switch c {
case ',':
continue
case ':':
arg.Type, sig = parseType(sig)
if strings.HasPrefix(sig, "=") {
arg.DefVal, sig = parseDefVal(sig[1:])
}
case '=':
arg.DefVal, sig = parseDefVal(sig)
case ')':
return
}
sig = strings.TrimPrefix(sig, ",")
}
}
const (
allSpecials = "([<'\""
)
var pairStops = map[byte]string{
'(': ")" + allSpecials,
'[': "]" + allSpecials,
'<': ">" + allSpecials,
'\'': "'" + allSpecials,
'"': "\"",
}
func parseText(sig string, stops string) (left string) {
for {
pos := strings.IndexAny(sig, stops)
if pos < 0 {
return sig
}
if c := sig[pos]; c != stops[0] {
if pstop, ok := pairStops[c]; ok {
sig = strings.TrimPrefix(parseText(sig[pos+1:], pstop), pstop[:1])
continue
}
}
return sig[pos:]
}
}
// stops: "=,)"
func parseType(sig string) (string, string) {
left := parseText(sig, "=,)"+allSpecials)
return resultOf(sig, left), left
}
// stops: ",)"
func parseDefVal(sig string) (string, string) {
left := parseText(sig, ",)"+allSpecials)
return resultOf(sig, left), left
}
func resultOf(sig, left string) string {
return strings.TrimSpace(sig[:len(sig)-len(left)])
}

View File

@@ -0,0 +1,52 @@
/*
* 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 pysig
import "testing"
func TestParse(t *testing.T) {
type testCase struct {
sig string
args []*Arg
}
cases := []testCase{
{"(start=None, *, unit: 'str | None' = None) -> 'TimedeltaIndex'", []*Arg{
{Name: "start", DefVal: "None"},
{Name: "*"},
{Name: "unit", Type: "'str | None'", DefVal: "None"},
}},
{"()", nil},
{"(a =", []*Arg{{Name: "a"}}},
{"(a) -> int", []*Arg{{Name: "a"}}},
{"(a: int)", []*Arg{{Name: "a", Type: "int"}}},
{"(a: int = 1, b: float)", []*Arg{{Name: "a", Type: "int", DefVal: "1"}, {Name: "b", Type: "float"}}},
{"(a = <1>, b = 2.0)", []*Arg{{Name: "a", DefVal: "<1>"}, {Name: "b", DefVal: "2.0"}}},
{"(a: 'Suffixes' = ('_x', '_y'))", []*Arg{{Name: "a", Type: "'Suffixes'", DefVal: "('_x', '_y')"}}},
}
for _, c := range cases {
args := Parse(c.sig)
if len(args) != len(c.args) {
t.Fatalf("%s: len(args) = %v, want %v", c.sig, len(args), len(c.args))
}
for i, arg := range args {
want := c.args[i]
if arg.Name != want.Name || arg.Type != want.Type || arg.DefVal != want.DefVal {
t.Fatalf("%s: args[%v] = %v, want %v", c.sig, i, arg, want)
}
}
}
}

View File

@@ -18,14 +18,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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()
%2 = call i64 @main.max(i64 1, i64 2) %2 = call i64 @main.max(i64 1, i64 2)
ret void ret i32 0
} }
define i64 @main.max(i64 %0, i64 %1) { define i64 @main.max(i64 %0, i64 %1) {

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.hello = global ptr null @main.hello = global [7 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -27,7 +27,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -35,7 +35,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = 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 i32 0
} }
declare void @"github.com/goplus/llgo/cl/internal/stdio.init"() declare void @"github.com/goplus/llgo/cl/internal/stdio.init"()

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -42,7 +42,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -50,7 +50,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = 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 %2) call void (ptr, ...) @printf(ptr @main.format, i64 %2)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -77,7 +77,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -205,7 +205,7 @@ _llgo_2: ; preds = %_llgo_3, %_llgo_1,
store %"github.com/goplus/llgo/internal/runtime.iface" %74, ptr %72, align 8 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) %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) call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %75)
ret void ret i32 0
_llgo_3: ; preds = %_llgo_0 _llgo_3: ; preds = %_llgo_0
br i1 true, label %_llgo_1, label %_llgo_2 br i1 true, label %_llgo_1, label %_llgo_2
@@ -322,7 +322,7 @@ _llgo_15: ; preds = %_llgo_13
br i1 %40, label %_llgo_16, label %_llgo_17 br i1 %40, label %_llgo_16, label %_llgo_17
_llgo_16: ; preds = %_llgo_15 _llgo_16: ; preds = %_llgo_15
%41 = sext i8 %39 to i64 %41 = zext i8 %39 to i64
call void @main.printuint(i64 %41) call void @main.printuint(i64 %41)
br label %_llgo_1 br label %_llgo_1
@@ -335,7 +335,7 @@ _llgo_17: ; preds = %_llgo_15
br i1 %46, label %_llgo_18, label %_llgo_19 br i1 %46, label %_llgo_18, label %_llgo_19
_llgo_18: ; preds = %_llgo_17 _llgo_18: ; preds = %_llgo_17
%47 = sext i16 %45 to i64 %47 = zext i16 %45 to i64
call void @main.printuint(i64 %47) call void @main.printuint(i64 %47)
br label %_llgo_1 br label %_llgo_1
@@ -348,7 +348,7 @@ _llgo_19: ; preds = %_llgo_17
br i1 %52, label %_llgo_20, label %_llgo_21 br i1 %52, label %_llgo_20, label %_llgo_21
_llgo_20: ; preds = %_llgo_19 _llgo_20: ; preds = %_llgo_19
%53 = sext i32 %51 to i64 %53 = zext i32 %51 to i64
call void @main.printuint(i64 %53) call void @main.printuint(i64 %53)
br label %_llgo_1 br label %_llgo_1
@@ -555,64 +555,66 @@ _llgo_24: ; preds = %_llgo_22
br label %_llgo_12 br label %_llgo_12
_llgo_25: ; preds = %_llgo_27 _llgo_25: ; preds = %_llgo_27
%43 = fptosi double %59 to i64 %43 = fptosi double %60 to i64
%44 = add i64 %60, 2 %44 = add i64 %61, 2
%45 = add i64 %43, 48 %45 = add i64 %43, 48
%46 = trunc i64 %45 to i8 %46 = trunc i64 %45 to i8
%47 = getelementptr inbounds i8, ptr %11, i64 %44 %47 = icmp slt i64 %44, 0
store i8 %46, ptr %47, align 1 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %47)
%48 = sitofp i64 %43 to double %48 = getelementptr inbounds i8, ptr %11, i64 %44
%49 = fsub double %59, %48 store i8 %46, ptr %48, align 1
%50 = fmul double %49, 1.000000e+01 %49 = sitofp i64 %43 to double
%51 = add i64 %60, 1 %50 = fsub double %60, %49
%51 = fmul double %50, 1.000000e+01
%52 = add i64 %61, 1
br label %_llgo_27 br label %_llgo_27
_llgo_26: ; preds = %_llgo_27 _llgo_26: ; preds = %_llgo_27
%52 = getelementptr inbounds i8, ptr %11, i64 2 %53 = getelementptr inbounds i8, ptr %11, i64 2
%53 = load i8, ptr %52, align 1 %54 = load i8, ptr %53, align 1
%54 = getelementptr inbounds i8, ptr %11, i64 1 %55 = getelementptr inbounds i8, ptr %11, i64 1
store i8 %53, ptr %54, align 1 store i8 %54, ptr %55, align 1
%55 = getelementptr inbounds i8, ptr %11, i64 2 %56 = getelementptr inbounds i8, ptr %11, i64 2
store i8 46, ptr %55, align 1 store i8 46, ptr %56, align 1
%56 = getelementptr inbounds i8, ptr %11, i64 9 %57 = getelementptr inbounds i8, ptr %11, i64 9
store i8 101, ptr %56, align 1 store i8 101, ptr %57, align 1
%57 = getelementptr inbounds i8, ptr %11, i64 10 %58 = getelementptr inbounds i8, ptr %11, i64 10
store i8 43, ptr %57, align 1 store i8 43, ptr %58, align 1
%58 = icmp slt i64 %19, 0 %59 = icmp slt i64 %19, 0
br i1 %58, label %_llgo_28, label %_llgo_29 br i1 %59, label %_llgo_28, label %_llgo_29
_llgo_27: ; preds = %_llgo_25, %_llgo_12 _llgo_27: ; preds = %_llgo_25, %_llgo_12
%59 = phi double [ %18, %_llgo_12 ], [ %50, %_llgo_25 ] %60 = phi double [ %18, %_llgo_12 ], [ %51, %_llgo_25 ]
%60 = phi i64 [ 0, %_llgo_12 ], [ %51, %_llgo_25 ] %61 = phi i64 [ 0, %_llgo_12 ], [ %52, %_llgo_25 ]
%61 = icmp slt i64 %60, 7 %62 = icmp slt i64 %61, 7
br i1 %61, label %_llgo_25, label %_llgo_26 br i1 %62, label %_llgo_25, label %_llgo_26
_llgo_28: ; preds = %_llgo_26 _llgo_28: ; preds = %_llgo_26
%62 = sub i64 0, %19 %63 = sub i64 0, %19
%63 = getelementptr inbounds i8, ptr %11, i64 10 %64 = getelementptr inbounds i8, ptr %11, i64 10
store i8 45, ptr %63, align 1 store i8 45, ptr %64, align 1
br label %_llgo_29 br label %_llgo_29
_llgo_29: ; preds = %_llgo_28, %_llgo_26 _llgo_29: ; preds = %_llgo_28, %_llgo_26
%64 = phi i64 [ %19, %_llgo_26 ], [ %62, %_llgo_28 ] %65 = phi i64 [ %19, %_llgo_26 ], [ %63, %_llgo_28 ]
%65 = sdiv i64 %64, 100 %66 = sdiv i64 %65, 100
%66 = trunc i64 %65 to i8 %67 = trunc i64 %66 to i8
%67 = add i8 %66, 48 %68 = add i8 %67, 48
%68 = getelementptr inbounds i8, ptr %11, i64 11 %69 = getelementptr inbounds i8, ptr %11, i64 11
store i8 %67, ptr %68, align 1 store i8 %68, ptr %69, align 1
%69 = sdiv i64 %64, 10 %70 = sdiv i64 %65, 10
%70 = trunc i64 %69 to i8 %71 = trunc i64 %70 to i8
%71 = urem i8 %70, 10 %72 = urem i8 %71, 10
%72 = add i8 %71, 48 %73 = add i8 %72, 48
%73 = getelementptr inbounds i8, ptr %11, i64 12 %74 = getelementptr inbounds i8, ptr %11, i64 12
store i8 %72, ptr %73, align 1 store i8 %73, ptr %74, align 1
%74 = srem i64 %64, 10 %75 = srem i64 %65, 10
%75 = trunc i64 %74 to i8 %76 = trunc i64 %75 to i8
%76 = add i8 %75, 48 %77 = add i8 %76, 48
%77 = getelementptr inbounds i8, ptr %11, i64 13 %78 = getelementptr inbounds i8, ptr %11, i64 13
store i8 %76, ptr %77, align 1 store i8 %77, ptr %78, 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) %79 = 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) call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %79)
ret void ret void
} }
@@ -622,43 +624,49 @@ _llgo_0:
br label %_llgo_3 br label %_llgo_3
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%2 = urem i64 %14, 16 %2 = urem i64 %17, 16
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 16) %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 16)
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %3, 0 %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 = icmp slt i64 %18, 0
store i8 %6, ptr %7, align 1 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %7)
%8 = icmp ult i64 %14, 16 %8 = getelementptr inbounds i8, ptr %1, i64 %18
br i1 %8, label %_llgo_5, label %_llgo_4 store i8 %6, ptr %8, align 1
%9 = icmp ult i64 %17, 16
br i1 %9, label %_llgo_5, label %_llgo_4
_llgo_2: ; preds = %_llgo_5, %_llgo_3 _llgo_2: ; preds = %_llgo_5, %_llgo_3
%9 = sub i64 %15, 1 %10 = sub i64 %18, 1
%10 = getelementptr inbounds i8, ptr %1, i64 %9 %11 = icmp slt i64 %10, 0
store i8 120, ptr %10, align 1 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %11)
%11 = sub i64 %9, 1 %12 = getelementptr inbounds i8, ptr %1, i64 %10
%12 = getelementptr inbounds i8, ptr %1, i64 %11 store i8 120, ptr %12, align 1
store i8 48, ptr %12, align 1 %13 = sub i64 %10, 1
%13 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %11, i64 100, i64 100) %14 = icmp slt i64 %13, 0
call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %13) call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
%15 = getelementptr inbounds i8, ptr %1, i64 %13
store i8 48, ptr %15, align 1
%16 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %13, i64 100, i64 100)
call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %16)
ret void ret void
_llgo_3: ; preds = %_llgo_4, %_llgo_0 _llgo_3: ; preds = %_llgo_4, %_llgo_0
%14 = phi i64 [ %0, %_llgo_0 ], [ %17, %_llgo_4 ] %17 = phi i64 [ %0, %_llgo_0 ], [ %20, %_llgo_4 ]
%15 = phi i64 [ 99, %_llgo_0 ], [ %18, %_llgo_4 ] %18 = phi i64 [ 99, %_llgo_0 ], [ %21, %_llgo_4 ]
%16 = icmp sgt i64 %15, 0 %19 = icmp sgt i64 %18, 0
br i1 %16, label %_llgo_1, label %_llgo_2 br i1 %19, label %_llgo_1, label %_llgo_2
_llgo_4: ; preds = %_llgo_5, %_llgo_1 _llgo_4: ; preds = %_llgo_5, %_llgo_1
%17 = udiv i64 %14, 16 %20 = udiv i64 %17, 16
%18 = sub i64 %15, 1 %21 = sub i64 %18, 1
br label %_llgo_3 br label %_llgo_3
_llgo_5: ; preds = %_llgo_1 _llgo_5: ; preds = %_llgo_1
%19 = sub i64 100, %15 %22 = sub i64 100, %18
%20 = load i64, ptr @main.minhexdigits, align 4 %23 = load i64, ptr @main.minhexdigits, align 4
%21 = icmp sge i64 %19, %20 %24 = icmp sge i64 %22, %23
br i1 %21, label %_llgo_2, label %_llgo_4 br i1 %24, label %_llgo_2, label %_llgo_4
} }
define void @main.printint(i64 %0) { define void @main.printint(i64 %0) {
@@ -690,23 +698,25 @@ _llgo_1: ; preds = %_llgo_5, %_llgo_0
br i1 %4, label %_llgo_2, label %_llgo_3 br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %5 = icmp slt i64 %3, 0
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %5)
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%8 = icmp ne i64 %3, 0 %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, i64 %3
br i1 %8, label %_llgo_4, label %_llgo_5 %8 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, align 8
%9 = icmp ne i64 %3, 0
br i1 %9, label %_llgo_4, label %_llgo_5
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
call void @main.printnl() call void @main.printnl()
ret void ret void
_llgo_4: ; preds = %_llgo_2 _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) %10 = 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) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %10)
br label %_llgo_5 br label %_llgo_5
_llgo_5: ; preds = %_llgo_4, %_llgo_2 _llgo_5: ; preds = %_llgo_4, %_llgo_2
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %7) call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %8)
br label %_llgo_1 br label %_llgo_1
} }
@@ -737,28 +747,30 @@ _llgo_0:
br label %_llgo_3 br label %_llgo_3
_llgo_1: ; preds = %_llgo_3 _llgo_1: ; preds = %_llgo_3
%2 = urem i64 %8, 10 %2 = urem i64 %9, 10
%3 = add i64 %2, 48 %3 = add i64 %2, 48
%4 = trunc i64 %3 to i8 %4 = trunc i64 %3 to i8
%5 = getelementptr inbounds i8, ptr %1, i64 %9 %5 = icmp slt i64 %10, 0
store i8 %4, ptr %5, align 1 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %5)
%6 = icmp ult i64 %8, 10 %6 = getelementptr inbounds i8, ptr %1, i64 %10
br i1 %6, label %_llgo_2, label %_llgo_4 store i8 %4, ptr %6, align 1
%7 = icmp ult i64 %9, 10
br i1 %7, label %_llgo_2, label %_llgo_4
_llgo_2: ; preds = %_llgo_3, %_llgo_1 _llgo_2: ; preds = %_llgo_3, %_llgo_1
%7 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %9, i64 100, i64 100) %8 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %1, i64 1, i64 100, i64 %10, i64 100, i64 100)
call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %7) call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %8)
ret void ret void
_llgo_3: ; preds = %_llgo_4, %_llgo_0 _llgo_3: ; preds = %_llgo_4, %_llgo_0
%8 = phi i64 [ %0, %_llgo_0 ], [ %11, %_llgo_4 ] %9 = phi i64 [ %0, %_llgo_0 ], [ %12, %_llgo_4 ]
%9 = phi i64 [ 99, %_llgo_0 ], [ %12, %_llgo_4 ] %10 = phi i64 [ 99, %_llgo_0 ], [ %13, %_llgo_4 ]
%10 = icmp sgt i64 %9, 0 %11 = icmp sgt i64 %10, 0
br i1 %10, label %_llgo_1, label %_llgo_2 br i1 %11, label %_llgo_1, label %_llgo_2
_llgo_4: ; preds = %_llgo_1 _llgo_4: ; preds = %_llgo_1
%11 = udiv i64 %8, 10 %12 = udiv i64 %9, 10
%12 = sub i64 %9, 1 %13 = sub i64 %10, 1
br label %_llgo_3 br label %_llgo_3
} }
@@ -800,3 +812,5 @@ declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llg
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) 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 { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.hello = global ptr null @main.hello = global [7 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -26,14 +26,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -29,14 +29,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -35,14 +35,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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)
ret void ret i32 0
} }
declare void @printf(ptr, ...) declare void @printf(ptr, ...)

View File

@@ -25,7 +25,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -33,7 +33,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = call i32 @main.f(i32 100) %2 = call i32 @main.f(i32 100)
%3 = call i32 (ptr, ...) @printf(ptr @0, i32 %2) %3 = call i32 (ptr, ...) @printf(ptr @0, i32 %2)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -33,7 +33,7 @@ _llgo_1: ; preds = %_llgo_0
br label %_llgo_2 br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

23
cl/_testdata/utf8/in.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"unicode/utf8"
)
func main() {
var str = "中abcd"
for i := 0; i < len(str); {
r, n := utf8.DecodeRuneInString(str[i:])
i += n
println(r)
}
println(index(2) == 3)
}
var array = [...]uint8{
1, 2, 3, 4, 5, 6, 7, 8,
}
func index(n int8) uint8 {
return array[n]
}

101
cl/_testdata/utf8/out.ll Normal file
View File

@@ -0,0 +1,101 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
@main.array = global [8 x i8] undef
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [8 x i8] c"\E4\B8\ADabcd\00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@2 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@3 = private unnamed_addr constant [8 x i8] c"\E4\B8\ADabcd\00", align 1
define i8 @main.index(i8 %0) {
_llgo_0:
%1 = icmp slt i8 %0, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %1)
%2 = zext i8 %0 to i64
%3 = getelementptr inbounds i8, ptr @main.array, i64 %2
%4 = load i8, ptr %3, align 1
ret i8 %4
}
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 @"unicode/utf8.init"()
store i8 1, ptr @main.array, align 1
store i8 2, ptr getelementptr inbounds (i8, ptr @main.array, i64 1), align 1
store i8 3, ptr getelementptr inbounds (i8, ptr @main.array, i64 2), align 1
store i8 4, ptr getelementptr inbounds (i8, ptr @main.array, i64 3), align 1
store i8 5, ptr getelementptr inbounds (i8, ptr @main.array, i64 4), align 1
store i8 6, ptr getelementptr inbounds (i8, ptr @main.array, i64 5), align 1
store i8 7, ptr getelementptr inbounds (i8, ptr @main.array, i64 6), align 1
store i8 8, ptr getelementptr inbounds (i8, ptr @main.array, i64 7), align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
br label %_llgo_3
_llgo_1: ; preds = %_llgo_3
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 7)
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %2, i64 %14, i64 %3)
%5 = call { i32, i64 } @"unicode/utf8.DecodeRuneInString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
%6 = extractvalue { i32, i64 } %5, 0
%7 = extractvalue { i32, i64 } %5, 1
%8 = add i64 %14, %7
%9 = sext i32 %6 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %9)
%10 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %10)
br label %_llgo_3
_llgo_2: ; preds = %_llgo_3
%11 = call i8 @main.index(i8 2)
%12 = icmp eq i8 %11, 3
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 %12)
%13 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %13)
ret i32 0
_llgo_3: ; preds = %_llgo_1, %_llgo_0
%14 = phi i64 [ 0, %_llgo_0 ], [ %8, %_llgo_1 ]
%15 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 7)
%16 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %15, 1
%17 = icmp slt i64 %14, %16
br i1 %17, label %_llgo_1, label %_llgo_2
}
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
declare void @"unicode/utf8.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.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64)
declare { i32, i64 } @"unicode/utf8.DecodeRuneInString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1)

View File

@@ -22,7 +22,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -43,7 +43,7 @@ _llgo_0:
store %"github.com/goplus/llgo/internal/runtime.iface" %11, ptr %9, align 8 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) %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) call void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %12)
ret void ret i32 0
} }
define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
@@ -58,12 +58,14 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %4, label %_llgo_2, label %_llgo_3 br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %5 = icmp slt i64 %3, 0
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %5)
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, i64 %3
%9 = call i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %7, ptr %8) %8 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, align 8
%10 = call i32 (ptr, ...) @printf(ptr @0, i64 %9) %9 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%10 = call i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %8, ptr %9)
%11 = call i32 (ptr, ...) @printf(ptr @0, i64 %10)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
@@ -80,6 +82,8 @@ declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llg
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 void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -30,7 +30,7 @@ _llgo_0:
%3 = add i64 %2, 1 %3 = add i64 %2, 1
store i64 %3, ptr @main.a, align 4 store i64 %3, ptr @main.a, align 4
%4 = load i64, ptr @main.a, align 4 %4 = load i64, ptr @main.a, align 4
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -19,7 +19,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -36,7 +36,7 @@ _llgo_1: ; preds = %_llgo_3
br label %_llgo_3 br label %_llgo_3
_llgo_2: ; preds = %_llgo_3 _llgo_2: ; preds = %_llgo_3
ret void ret i32 0
_llgo_3: ; preds = %_llgo_1, %_llgo_0 _llgo_3: ; preds = %_llgo_1, %_llgo_0
%7 = phi i32 [ 0, %_llgo_0 ], [ %6, %_llgo_1 ] %7 = phi i32 [ 0, %_llgo_0 ], [ %6, %_llgo_1 ]

View File

@@ -2,7 +2,7 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/x/sqlite" "github.com/goplus/llgo/c/sqlite"
) )
func main() { func main() {

View File

@@ -35,18 +35,18 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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()
%2 = call { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr @1, i32 130, ptr null) %2 = call { ptr, i32 } @"github.com/goplus/llgo/c/sqlite.OpenV2"(ptr @1, i32 130, ptr null)
%3 = extractvalue { ptr, i32 } %2, 0 %3 = extractvalue { ptr, i32 } %2, 0
%4 = extractvalue { ptr, i32 } %2, 1 %4 = extractvalue { ptr, i32 } %2, 1
call void @main.check(i32 %4) call void @main.check(i32 %4)
%5 = call i32 @sqlite3_close(ptr %3) %5 = call i32 @sqlite3_close(ptr %3)
ret void ret i32 0
} }
declare ptr @sqlite3_errstr(i32) declare ptr @sqlite3_errstr(i32)
@@ -57,6 +57,6 @@ declare void @exit(i32)
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr, i32, ptr) declare { ptr, i32 } @"github.com/goplus/llgo/c/sqlite.OpenV2"(ptr, i32, ptr)
declare i32 @sqlite3_close(ptr) declare i32 @sqlite3_close(ptr)

View File

@@ -32,7 +32,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
call void @Py_Initialize() call void @Py_Initialize()
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
@@ -48,7 +48,7 @@ _llgo_0:
%8 = call i32 (ptr, ...) @printf(ptr @0, double %7) %8 = call i32 (ptr, ...) @printf(ptr @0, double %7)
%9 = call ptr @PyUnicode_AsUTF8(ptr %6) %9 = call ptr @PyUnicode_AsUTF8(ptr %6)
%10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9) %10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/py/math.init"() declare void @"github.com/goplus/llgo/py/math.init"()

View File

@@ -25,7 +25,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
call void @Py_Initialize() call void @Py_Initialize()
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
@@ -39,7 +39,7 @@ _llgo_0:
%6 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %5, ptr %2, ptr %3, ptr %4, ptr null) %6 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %5, ptr %2, ptr %3, ptr %4, ptr null)
%7 = call i32 @PyLong_AsLong(ptr %6) %7 = call i32 @PyLong_AsLong(ptr %6)
%8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7) %8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/py/math.init"() declare void @"github.com/goplus/llgo/py/math.init"()

View File

@@ -27,7 +27,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
call void @Py_Initialize() call void @Py_Initialize()
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
@@ -95,7 +95,7 @@ _llgo_0:
%60 = call ptr @PyObject_Str(ptr %53) %60 = call ptr @PyObject_Str(ptr %53)
%61 = call ptr @PyUnicode_AsUTF8(ptr %60) %61 = call ptr @PyUnicode_AsUTF8(ptr %60)
%62 = call i32 (ptr, ...) @printf(ptr @2, ptr %61) %62 = call i32 (ptr, ...) @printf(ptr @2, ptr %61)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/py/numpy.init"() declare void @"github.com/goplus/llgo/py/numpy.init"()

View File

@@ -22,7 +22,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
call void @Py_Initialize() call void @Py_Initialize()
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
@@ -33,7 +33,7 @@ _llgo_0:
%3 = call ptr @PyObject_GetAttrString(ptr %2, ptr @1) %3 = call ptr @PyObject_GetAttrString(ptr %2, ptr @1)
%4 = call double @PyFloat_AsDouble(ptr %3) %4 = call double @PyFloat_AsDouble(ptr %3)
%5 = call i32 (ptr, ...) @printf(ptr @0, double %4) %5 = call i32 (ptr, ...) @printf(ptr @0, double %4)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/py/math.init"() declare void @"github.com/goplus/llgo/py/math.init"()

View File

@@ -25,7 +25,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
call void @Py_Initialize() call void @Py_Initialize()
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
@@ -38,7 +38,7 @@ _llgo_0:
%5 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %4, ptr %2, ptr %3, ptr null) %5 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %4, ptr %2, ptr %3, ptr null)
%6 = call double @PyFloat_AsDouble(ptr %5) %6 = call double @PyFloat_AsDouble(ptr %5)
%7 = call i32 (ptr, ...) @printf(ptr @0, double %6) %7 = call i32 (ptr, ...) @printf(ptr @0, double %6)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/py/math.init"() declare void @"github.com/goplus/llgo/py/math.init"()

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -29,7 +29,7 @@ _llgo_0:
%2 = alloca i8, i64 4, align 1 %2 = alloca i8, i64 4, align 1
%3 = call ptr @memcpy(ptr %2, ptr @0, i64 4) %3 = call ptr @memcpy(ptr %2, ptr @0, i64 4)
%4 = call i32 (ptr, ...) @printf(ptr @1, ptr %2) %4 = call i32 (ptr, ...) @printf(ptr @1, ptr %2)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -27,7 +27,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -39,7 +39,7 @@ _llgo_0:
%5 = alloca i8, i64 %4, align 1 %5 = alloca i8, i64 %4, align 1
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %5, %"github.com/goplus/llgo/internal/runtime.String" %2) %6 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %5, %"github.com/goplus/llgo/internal/runtime.String" %2)
%7 = call i32 (ptr, ...) @printf(ptr %6) %7 = call i32 (ptr, ...) @printf(ptr %6)
ret void ret i32 0
} }
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)

View File

@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -39,7 +39,7 @@ _llgo_0:
%3 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %2, i64 100) %3 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %2, i64 100)
%4 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %3) %4 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.iface" %3)
%5 = call i32 (ptr, ...) @printf(ptr @0, i64 %4) %5 = call i32 (ptr, ...) @printf(ptr @0, i64 %4)
ret void ret i32 0
} }
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"github.com/goplus/llgo/internal/runtime/c" "unsafe"
) )
var a int64 = 1<<63 - 1 var a int64 = 1<<63 - 1
@@ -11,47 +11,19 @@ var n uint64 = 1<<64 - 1
func main() { func main() {
var s = []int{1, 2, 3, 4} var s = []int{1, 2, 3, 4}
var a = [...]int{1, 2, 3, 4} var a = [...]int{1, 2, 3, 4}
d := make([]byte, 4, 10)
println(s, len(s), cap(s))
println(d, len(d), cap(d))
println(len(a), cap(a), cap(&a), len(&a))
println(len([]int{1, 2, 3, 4}), len([4]int{1, 2, 3, 4}))
println(len(s[1:]), cap(s[1:]), len(s[1:2]), cap(s[1:2]), len(s[1:2:2]), cap(s[1:2:2]))
println(len(a[1:]), cap(a[1:]), len(a[1:2]), cap(a[1:2]), len(a[1:2:2]), cap(a[1:2:2]))
out(len(s)) println("hello", "hello"[1:], "hello"[1:2], len("hello"[5:]))
out(len([]int{1, 2, 3, 4})) println(append(s, 5, 6, 7, 8))
out(len(a))
out(len(&a))
out(len([4]int{1, 2, 3, 4}))
out(cap(s))
out(cap(a))
out(cap(&a))
out(len(s[1:]))
out(cap(s[1:]))
out(len(s[1:2]))
out(cap(s[1:2]))
out(len(s[1:2:2]))
out(cap(s[1:2:2]))
out(len(a[1:]))
out(cap(a[1:]))
out(len(a[1:2]))
out(cap(a[1:2]))
out(len(a[1:2:2]))
out(cap(a[1:2:2]))
string_len("hello")
string_len("hello"[1:])
string_len("hello"[1:2])
string_len("hello"[5:])
s = append(s, 5, 6, 7, 8)
out(len(s))
data := []byte{'a', 'b', 'c'} data := []byte{'a', 'b', 'c'}
data = append(data, "def"...) data = append(data, "def"...)
out(len(data)) println(data)
} var i any = 100
println(true, 100, -100, uint(255), int32(-100), 100.5, i, &i, uintptr(unsafe.Pointer(&i)))
func string_len(s string) {
out(len(s))
}
func out(n int) {
c.Printf(c.Str("%d\n"), n)
} }

View File

@@ -3,6 +3,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@main.a = global ptr null @main.a = global ptr null
@main.b = global ptr null @main.b = global ptr null
@@ -10,12 +11,50 @@ source_filename = "main"
@main.n = global ptr null @main.n = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = 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 [2 x i8] c" \00", align 1
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @1 = private unnamed_addr constant [2 x i8] c" \00", align 1
@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @2 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @3 = private unnamed_addr constant [2 x i8] c" \00", align 1
@4 = private unnamed_addr constant [4 x i8] c"def\00", align 1 @4 = private unnamed_addr constant [2 x i8] c" \00", align 1
@5 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @5 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@6 = private unnamed_addr constant [2 x i8] c" \00", align 1
@7 = private unnamed_addr constant [2 x i8] c" \00", align 1
@8 = private unnamed_addr constant [2 x i8] c" \00", align 1
@9 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@10 = private unnamed_addr constant [2 x i8] c" \00", align 1
@11 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@12 = private unnamed_addr constant [2 x i8] c" \00", align 1
@13 = private unnamed_addr constant [2 x i8] c" \00", align 1
@14 = private unnamed_addr constant [2 x i8] c" \00", align 1
@15 = private unnamed_addr constant [2 x i8] c" \00", align 1
@16 = private unnamed_addr constant [2 x i8] c" \00", align 1
@17 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@18 = private unnamed_addr constant [2 x i8] c" \00", align 1
@19 = private unnamed_addr constant [2 x i8] c" \00", align 1
@20 = private unnamed_addr constant [2 x i8] c" \00", align 1
@21 = private unnamed_addr constant [2 x i8] c" \00", align 1
@22 = private unnamed_addr constant [2 x i8] c" \00", align 1
@23 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@24 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@25 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@26 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@27 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@28 = private unnamed_addr constant [2 x i8] c" \00", align 1
@29 = private unnamed_addr constant [2 x i8] c" \00", align 1
@30 = private unnamed_addr constant [2 x i8] c" \00", align 1
@31 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@32 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@33 = private unnamed_addr constant [4 x i8] c"def\00", align 1
@34 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@35 = private unnamed_addr constant [2 x i8] c" \00", align 1
@36 = private unnamed_addr constant [2 x i8] c" \00", align 1
@37 = private unnamed_addr constant [2 x i8] c" \00", align 1
@38 = private unnamed_addr constant [2 x i8] c" \00", align 1
@39 = private unnamed_addr constant [2 x i8] c" \00", align 1
@40 = private unnamed_addr constant [2 x i8] c" \00", align 1
@41 = private unnamed_addr constant [2 x i8] c" \00", align 1
@42 = private unnamed_addr constant [2 x i8] c" \00", align 1
@43 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -33,7 +72,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -58,133 +97,220 @@ _llgo_0:
store i64 2, ptr %10, align 4 store i64 2, ptr %10, align 4
store i64 3, ptr %11, align 4 store i64 3, ptr %11, align 4
store i64 4, ptr %12, align 4 store i64 4, ptr %12, align 4
%13 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1 %13 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 10)
call void @main.out(i64 %13) %14 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %13, i64 1, i64 10, i64 0, i64 4, i64 10)
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %15 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1
%15 = getelementptr inbounds i64, ptr %14, i64 0 %16 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
store i64 1, ptr %15, align 4 call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%16 = getelementptr inbounds i64, ptr %14, i64 1 %17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1)
store i64 2, ptr %16, align 4 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %17)
%17 = getelementptr inbounds i64, ptr %14, i64 2 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %15)
store i64 3, ptr %17, align 4 %18 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 1)
%18 = getelementptr inbounds i64, ptr %14, i64 3 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18)
store i64 4, ptr %18, align 4 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %16)
%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) %19 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
%20 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %19, 1 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %19)
call void @main.out(i64 %20) %20 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %14, 1
call void @main.out(i64 4) %21 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %14, 2
call void @main.out(i64 4) call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %14)
call void @main.out(i64 4) %22 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1)
%21 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %22)
call void @main.out(i64 %21) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %20)
call void @main.out(i64 4) %23 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1)
call void @main.out(i64 4) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %23)
%22 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %21)
%23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 %24 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1)
%24 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %24)
%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) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4)
%26 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %25, 1 %25 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1)
call void @main.out(i64 %26) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %25)
%27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4)
%28 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 %26 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1)
%29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %26)
%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) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4)
%31 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %30, 2 %27 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1)
call void @main.out(i64 %31) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %27)
%32 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4)
%33 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 %28 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 1)
%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) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %28)
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%30 = getelementptr inbounds i64, ptr %29, i64 0
store i64 1, ptr %30, align 4
%31 = getelementptr inbounds i64, ptr %29, i64 1
store i64 2, ptr %31, align 4
%32 = getelementptr inbounds i64, ptr %29, i64 2
store i64 3, ptr %32, align 4
%33 = getelementptr inbounds i64, ptr %29, i64 3
store i64 4, ptr %33, align 4
%34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 4, i64 0, i64 4, i64 4)
%35 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %34, 1 %35 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %34, 1
call void @main.out(i64 %35) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %35)
%36 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 %36 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 1)
%37 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %36)
%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) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4)
%39 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %38, 2 %37 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 1)
call void @main.out(i64 %39) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %37)
%40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 %38 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%41 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 %39 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 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) %40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%43 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %42, 1 %41 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %40, i64 8, i64 %38, i64 1, i64 %39, i64 %38)
call void @main.out(i64 %43) %42 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %41, 1
%43 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 %44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%45 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 %45 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%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) %46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %43, i64 1, i64 %44, i64 %43)
%47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %46, 2 %47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %46, 2
call void @main.out(i64 %47) %48 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%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 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%49 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %48, 1 %50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %49, i64 8, i64 %48, i64 1, i64 2, i64 %48)
call void @main.out(i64 %49) %51 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, 1
%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) %52 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%51 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, 2 %53 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
call void @main.out(i64 %51) %54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %53, i64 8, i64 %52, i64 1, i64 2, i64 %52)
%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 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %52, 1
call void @main.out(i64 %53)
%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 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, 2 %55 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, 2
call void @main.out(i64 %55) %56 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 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 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%57 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %56, 1 %58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %57, i64 8, i64 %56, i64 1, i64 2, i64 2)
call void @main.out(i64 %57) %59 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %58, 1
%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) %60 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%59 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %58, 2 %61 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
call void @main.out(i64 %59) %62 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %61, i64 8, i64 %60, i64 1, i64 2, i64 2)
%60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5) %63 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %62, 2
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %42)
%61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) %64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 1)
%62 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %61, 1 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %64)
%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 @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %47)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63) %65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @13, i64 1)
%64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %65)
%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) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %51)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %65) %66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @14, i64 1)
%66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %66)
%67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %55)
%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) %67 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @15, i64 1)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %67)
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %59)
%70 = getelementptr inbounds i64, ptr %69, i64 0 %68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @16, i64 1)
store i64 5, ptr %70, align 4 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %68)
%71 = getelementptr inbounds i64, ptr %69, i64 1 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %63)
store i64 6, ptr %71, align 4 %69 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @17, i64 1)
%72 = getelementptr inbounds i64, ptr %69, i64 2 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %69)
store i64 7, ptr %72, align 4 %70 = 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)
%73 = getelementptr inbounds i64, ptr %69, i64 3 %71 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %70, 1
store i64 8, ptr %73, align 4 %72 = 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)
%74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %69, i64 8, i64 4, i64 0, i64 4, i64 4) %73 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %72, 2
%75 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 0 %74 = 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)
%76 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 1 %75 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 1
%77 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %7, ptr %75, i64 %76, i64 8) %76 = 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)
%78 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %77, 1 %77 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %76, 2
call void @main.out(i64 %78) %78 = 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)
%79 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3) %79 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 1
%80 = getelementptr inbounds i8, ptr %79, i64 0 %80 = 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)
store i8 97, ptr %80, align 1 %81 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %80, 2
%81 = getelementptr inbounds i8, ptr %79, i64 1 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %71)
store i8 98, ptr %81, align 1 %82 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @18, i64 1)
%82 = getelementptr inbounds i8, ptr %79, i64 2 call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %82)
store i8 99, ptr %82, align 1 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %73)
%83 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %79, i64 1, i64 3, i64 0, i64 3, i64 3) %83 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @19, i64 1)
%84 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 3) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %83)
%85 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 0 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %75)
%86 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 1 %84 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @20, i64 1)
%87 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %83, ptr %85, i64 %86, i64 1) call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %84)
%88 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 1 call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %77)
call void @main.out(i64 %88) %85 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @21, i64 1)
ret void call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %85)
} call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %79)
%86 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @22, i64 1)
define void @main.out(i64 %0) { call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %86)
_llgo_0: call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %81)
%1 = call i32 (ptr, ...) @printf(ptr @5, i64 %0) %87 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @23, i64 1)
ret void call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %87)
} %88 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @24, i64 5)
%89 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %88, 1
define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) { %90 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %88, i64 1, i64 %89)
_llgo_0: %91 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @25, i64 5)
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1 %92 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %91, i64 1, i64 2)
call void @main.out(i64 %1) %93 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @26, i64 5)
ret void %94 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %93, 1
%95 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %93, i64 5, i64 %94)
%96 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %95, 1
%97 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @27, i64 5)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %97)
%98 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @28, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %98)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %90)
%99 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @29, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %99)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %92)
%100 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @30, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %100)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %96)
%101 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @31, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %101)
%102 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%103 = getelementptr inbounds i64, ptr %102, i64 0
store i64 5, ptr %103, align 4
%104 = getelementptr inbounds i64, ptr %102, i64 1
store i64 6, ptr %104, align 4
%105 = getelementptr inbounds i64, ptr %102, i64 2
store i64 7, ptr %105, align 4
%106 = getelementptr inbounds i64, ptr %102, i64 3
store i64 8, ptr %106, align 4
%107 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %102, i64 8, i64 4, i64 0, i64 4, i64 4)
%108 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %107, 0
%109 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %107, 1
%110 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %7, ptr %108, i64 %109, i64 8)
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %110)
%111 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @32, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %111)
%112 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3)
%113 = getelementptr inbounds i8, ptr %112, i64 0
store i8 97, ptr %113, align 1
%114 = getelementptr inbounds i8, ptr %112, i64 1
store i8 98, ptr %114, align 1
%115 = getelementptr inbounds i8, ptr %112, i64 2
store i8 99, ptr %115, align 1
%116 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %112, i64 1, i64 3, i64 0, i64 3, i64 3)
%117 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @33, i64 3)
%118 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %117, 0
%119 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %117, 1
%120 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %116, ptr %118, i64 %119, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %120)
%121 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @34, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %121)
%122 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%123 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%124 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %123, i64 100)
store %"github.com/goplus/llgo/internal/runtime.iface" %124, ptr %122, align 8
%125 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %122, align 8
%126 = ptrtoint ptr %122 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 true)
%127 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @35, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %127)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 100)
%128 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @36, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %128)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100)
%129 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @37, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %129)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 255)
%130 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @38, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %130)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100)
%131 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @39, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %131)
call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double 1.005000e+02)
%132 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @40, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %132)
call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %125)
%133 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @41, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %133)
call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %122)
%134 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @42, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %134)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %126)
%135 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @43, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %135)
ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
@@ -193,10 +319,28 @@ 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 void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
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 void @"github.com/goplus/llgo/internal/runtime.PrintInt"(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 %"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.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64)
declare i32 @printf(ptr, ...) 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 void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1)
declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double)
declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface")
declare void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr)

View File

@@ -28,7 +28,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -48,7 +48,7 @@ _llgo_0:
store ptr null, ptr %8, align 8 store ptr null, ptr %8, align 8
%9 = load { ptr, ptr }, ptr %6, align 8 %9 = load { ptr, ptr }, ptr %6, align 8
call void @main.callback(ptr @1, { ptr, ptr } %9) call void @main.callback(ptr @1, { ptr, ptr } %9)
ret void ret i32 0
} }
define void @main.print(ptr %0) { define void @main.print(ptr %0) {

View File

@@ -199,7 +199,7 @@ _llgo_2: ; preds = %_llgo_0
define void @main.cvtUinptr(i32 %0, i64 %1) { define void @main.cvtUinptr(i32 %0, i64 %1) {
_llgo_0: _llgo_0:
%2 = sext i32 %0 to i64 %2 = zext i32 %0 to i64
%3 = icmp ne i64 %2, %1 %3 = icmp ne i64 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2 br i1 %3, label %_llgo_1, label %_llgo_2
@@ -237,7 +237,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -298,7 +298,7 @@ _llgo_0:
call void @main.cvt32to64(i32 0, i64 0) call void @main.cvt32to64(i32 0, i64 0)
call void @main.cvt32to64(i32 2147483647, i64 2147483647) call void @main.cvt32to64(i32 2147483647, i64 2147483647)
call void @main.cvtUinptr(i32 1024, i64 1024) call void @main.cvtUinptr(i32 1024, i64 1024)
ret void ret i32 0
} }
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)

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -47,7 +47,7 @@ _llgo_0:
%13 = extractvalue { ptr, ptr } %12, 1 %13 = extractvalue { ptr, ptr } %12, 1
%14 = extractvalue { ptr, ptr } %12, 0 %14 = extractvalue { ptr, ptr } %12, 0
call void %14(ptr %13) call void %14(ptr %13)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -25,8 +25,8 @@ _llgo_0:
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
%5 = phi ptr [ %3, %_llgo_0 ], [ %18, %_llgo_2 ] %5 = phi ptr [ %3, %_llgo_0 ], [ %19, %_llgo_2 ]
%6 = phi i64 [ %4, %_llgo_0 ], [ %19, %_llgo_2 ] %6 = phi i64 [ %4, %_llgo_0 ], [ %20, %_llgo_2 ]
%7 = phi i64 [ -1, %_llgo_0 ], [ %12, %_llgo_2 ] %7 = phi i64 [ -1, %_llgo_0 ], [ %12, %_llgo_2 ]
%8 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %8 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %8, i32 0, i32 0 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %8, i32 0, i32 0
@@ -39,12 +39,14 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %13, label %_llgo_2, label %_llgo_3 br i1 %13, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%14 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %14 = icmp slt i64 %12, 0
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %14)
%16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 %15 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16) %16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i64 %12
%18 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %17, 0 %17 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %16, align 8
%19 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %17, 1 %18 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %17)
%19 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %18, 0
%20 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %18, 1
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
@@ -73,7 +75,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -97,9 +99,11 @@ _llgo_0:
%14 = alloca i8, i64 %13, align 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) %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 @6, ptr %15) %16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @6, ptr %15)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
declare %"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)

View File

@@ -19,14 +19,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -28,7 +28,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = 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
%3 = load { [16 x i8] }, ptr @_bar_y, align 1 %3 = load { [16 x i8] }, ptr @_bar_y, align 1
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -20,7 +20,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -28,7 +28,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = load ptr, ptr @__stderrp, align 8 %2 = load ptr, ptr @__stderrp, align 8
call void (ptr, ptr, ...) @fprintf(ptr %2, ptr @0, i64 100) call void (ptr, ptr, ...) @fprintf(ptr %2, ptr @0, i64 100)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -3,9 +3,9 @@ source_filename = "main"
%"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.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, i32, i32 }
@main.basicTypes = global ptr null @main.basicTypes = global [25 x ptr] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@main.sizeBasicTypes = global ptr null @main.sizeBasicTypes = global [25 x i64] undef
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = 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
@@ -50,7 +50,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -63,7 +63,7 @@ _llgo_0:
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %2, i32 0, i32 0 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/abi.Type", ptr %2, i32 0, i32 0
%7 = load i64, ptr %6, align 4 %7 = load i64, ptr %6, align 4
%8 = call i32 (ptr, ...) @printf(ptr @0, i64 %5, i64 %7) %8 = call i32 (ptr, ...) @printf(ptr @0, i64 %5, i64 %7)
ret void ret i32 0
} }
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)

View File

@@ -25,14 +25,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 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)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -37,7 +37,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = call i32 @strlen(ptr @main.format) %2 = call i32 @strlen(ptr @main.format)
call void (ptr, ...) @printf(ptr @main.format, i32 %2) call void (ptr, ...) @printf(ptr @main.format, i32 %2)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -128,7 +128,7 @@ _llgo_0:
%70 = getelementptr inbounds i8, ptr %69, i64 1 %70 = getelementptr inbounds i8, ptr %69, i64 1
%71 = load i8, ptr %70, align 1 %71 = load i8, ptr %70, align 1
%72 = call i32 (ptr, ...) @printf(ptr @6, i8 %71) %72 = call i32 (ptr, ...) @printf(ptr @6, i8 %71)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -29,9 +29,11 @@ _llgo_2: ; preds = %_llgo_1
%9 = extractvalue { ptr, ptr } %1, 1 %9 = extractvalue { ptr, ptr } %1, 1
%10 = extractvalue { ptr, ptr } %1, 0 %10 = extractvalue { ptr, ptr } %1, 0
%11 = call i32 %10(ptr %9) %11 = call i32 %10(ptr %9)
%12 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 0 %12 = icmp slt i64 %7, 0
%13 = getelementptr inbounds i32, ptr %12, i64 %7 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %12)
store i32 %11, ptr %13, align 4 %13 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 0
%14 = getelementptr inbounds i32, ptr %13, i64 %7
store i32 %11, ptr %14, align 4
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
@@ -63,7 +65,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -86,79 +88,87 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %10, 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
%11 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 0 %11 = icmp slt i64 %9, 0
%12 = getelementptr inbounds i32, ptr %11, i64 %9 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %11)
%13 = load i32, ptr %12, align 4 %12 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 0
%14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13) %13 = getelementptr inbounds i32, ptr %12, i64 %9
%14 = load i32, ptr %13, align 4
%15 = call i32 (ptr, ...) @printf(ptr @0, i32 %14)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4) %16 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4)
store i32 1, ptr %15, align 4 store i32 1, ptr %16, align 4
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %17 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%17 = getelementptr inbounds { ptr }, ptr %16, i32 0, i32 0 %18 = getelementptr inbounds { ptr }, ptr %17, i32 0, i32 0
store ptr %15, ptr %17, align 8 store ptr %16, ptr %18, align 8
%18 = alloca { ptr, ptr }, align 8 %19 = alloca { ptr, ptr }, align 8
%19 = getelementptr inbounds { ptr, ptr }, ptr %18, i32 0, i32 0 %20 = getelementptr inbounds { ptr, ptr }, ptr %19, i32 0, i32 0
store ptr @"main.main$1", ptr %19, align 8 store ptr @"main.main$1", ptr %20, align 8
%20 = getelementptr inbounds { ptr, ptr }, ptr %18, i32 0, i32 1 %21 = getelementptr inbounds { ptr, ptr }, ptr %19, i32 0, i32 1
store ptr %16, ptr %20, align 8 store ptr %17, ptr %21, align 8
%21 = load { ptr, ptr }, ptr %18, align 8 %22 = load { ptr, ptr }, ptr %19, align 8
%22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21) %23 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %22)
%23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 1 %24 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %23, 1
br label %_llgo_4 br label %_llgo_4
_llgo_4: ; preds = %_llgo_5, %_llgo_3 _llgo_4: ; preds = %_llgo_5, %_llgo_3
%24 = phi i64 [ -1, %_llgo_3 ], [ %25, %_llgo_5 ] %25 = phi i64 [ -1, %_llgo_3 ], [ %26, %_llgo_5 ]
%25 = add i64 %24, 1 %26 = add i64 %25, 1
%26 = icmp slt i64 %25, %23 %27 = icmp slt i64 %26, %24
br i1 %26, label %_llgo_5, label %_llgo_6 br i1 %27, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4 _llgo_5: ; preds = %_llgo_4
%27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 0 %28 = icmp slt i64 %26, 0
%28 = getelementptr inbounds i32, ptr %27, i64 %25 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %28)
%29 = load i32, ptr %28, align 4 %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %23, 0
%30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29) %30 = getelementptr inbounds i32, ptr %29, i64 %26
%31 = load i32, ptr %30, align 4
%32 = call i32 (ptr, ...) @printf(ptr @1, i32 %31)
br label %_llgo_4 br label %_llgo_4
_llgo_6: ; preds = %_llgo_4 _llgo_6: ; preds = %_llgo_4
%31 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4) %33 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 4)
%32 = getelementptr inbounds %main.generator, ptr %31, i32 0, i32 0 %34 = getelementptr inbounds %main.generator, ptr %33, i32 0, i32 0
store i32 1, ptr %32, align 4 store i32 1, ptr %34, align 4
%33 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %35 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%34 = getelementptr inbounds { ptr }, ptr %33, i32 0, i32 0 %36 = getelementptr inbounds { ptr }, ptr %35, i32 0, i32 0
store ptr %31, ptr %34, align 8 store ptr %33, ptr %36, align 8
%35 = alloca { ptr, ptr }, align 8 %37 = alloca { ptr, ptr }, align 8
%36 = getelementptr inbounds { ptr, ptr }, ptr %35, i32 0, i32 0 %38 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 0
store ptr @"main.next$bound", ptr %36, align 8 store ptr @"main.next$bound", ptr %38, align 8
%37 = getelementptr inbounds { ptr, ptr }, ptr %35, i32 0, i32 1 %39 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 1
store ptr %33, ptr %37, align 8 store ptr %35, ptr %39, align 8
%38 = load { ptr, ptr }, ptr %35, align 8 %40 = load { ptr, ptr }, ptr %37, align 8
%39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38) %41 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %40)
%40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 1 %42 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %41, 1
br label %_llgo_7 br label %_llgo_7
_llgo_7: ; preds = %_llgo_8, %_llgo_6 _llgo_7: ; preds = %_llgo_8, %_llgo_6
%41 = phi i64 [ -1, %_llgo_6 ], [ %42, %_llgo_8 ] %43 = phi i64 [ -1, %_llgo_6 ], [ %44, %_llgo_8 ]
%42 = add i64 %41, 1 %44 = add i64 %43, 1
%43 = icmp slt i64 %42, %40 %45 = icmp slt i64 %44, %42
br i1 %43, label %_llgo_8, label %_llgo_9 br i1 %45, label %_llgo_8, label %_llgo_9
_llgo_8: ; preds = %_llgo_7 _llgo_8: ; preds = %_llgo_7
%44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 0 %46 = icmp slt i64 %44, 0
%45 = getelementptr inbounds i32, ptr %44, i64 %42 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %46)
%46 = load i32, ptr %45, align 4 %47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %41, 0
%47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46) %48 = getelementptr inbounds i32, ptr %47, i64 %44
%49 = load i32, ptr %48, align 4
%50 = call i32 (ptr, ...) @printf(ptr @2, i32 %49)
br label %_llgo_7 br label %_llgo_7
_llgo_9: ; preds = %_llgo_7 _llgo_9: ; preds = %_llgo_7
ret void ret i32 0
} }
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64)
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare i32 @rand() declare i32 @rand()

View File

@@ -26,7 +26,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -34,7 +34,7 @@ _llgo_0:
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)
call void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr @4, ptr @5, ptr @6, ptr @7) call void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr @4, ptr @5, ptr @6, ptr @7)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr, ptr, ptr, ptr) declare void @"github.com/goplus/llgo/cl/internal/linktarget.F"(ptr, ptr, ptr, ptr)

View File

@@ -19,7 +19,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -27,7 +27,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"() %2 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeSmallMap"()
%3 = call i32 (ptr, ...) @printf(ptr @0, <null operand!>) %3 = call i32 (ptr, ...) @printf(ptr @0, <null operand!>)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

42
cl/_testrt/mask/in.go Normal file
View File

@@ -0,0 +1,42 @@
package main
func main() {
println(mask(1))
println(mask_shl(127, 5))
println(mask_shl8(127, 5))
println(mask_shl8u(127, 5))
println(mask_shl8(127, 16))
println(mask_shl8u(127, 16))
println(mask_shr(127, 5))
println(mask_shr8(127, 5))
println(mask_shr8u(127, 5))
println(mask_shr8(127, 16))
}
func mask(x int8) int32 {
return int32(x) << 31 >> 31
}
func mask_shl8(x int8, y int) int8 {
return x << y
}
func mask_shl8u(x uint8, y int) uint8 {
return x << y
}
func mask_shl(x int, y int) int {
return x << y
}
func mask_shr8(x int8, y int) int8 {
return x >> y
}
func mask_shr8u(x uint8, y int) uint8 {
return x >> y
}
func mask_shr(x int, y int) int {
return x >> y
}

173
cl/_testrt/mask/out.ll Normal file
View File

@@ -0,0 +1,173 @@
; ModuleID = 'main'
source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@2 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@3 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@5 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@6 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@7 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@8 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@9 = private unnamed_addr constant [2 x i8] c"\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 i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = call i32 @main.mask(i8 1)
%3 = sext i32 %2 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3)
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
%5 = call i64 @main.mask_shl(i64 127, i64 5)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %5)
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %6)
%7 = call i8 @main.mask_shl8(i8 127, i64 5)
%8 = sext i8 %7 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %8)
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %9)
%10 = call i8 @main.mask_shl8u(i8 127, i64 5)
%11 = zext i8 %10 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %11)
%12 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %12)
%13 = call i8 @main.mask_shl8(i8 127, i64 16)
%14 = sext i8 %13 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %14)
%15 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %15)
%16 = call i8 @main.mask_shl8u(i8 127, i64 16)
%17 = zext i8 %16 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %17)
%18 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18)
%19 = call i64 @main.mask_shr(i64 127, i64 5)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %19)
%20 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %20)
%21 = call i8 @main.mask_shr8(i8 127, i64 5)
%22 = sext i8 %21 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %22)
%23 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %23)
%24 = call i8 @main.mask_shr8u(i8 127, i64 5)
%25 = zext i8 %24 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %25)
%26 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %26)
%27 = call i8 @main.mask_shr8(i8 127, i64 16)
%28 = sext i8 %27 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %28)
%29 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %29)
ret i32 0
}
define i32 @main.mask(i8 %0) {
_llgo_0:
%1 = sext i8 %0 to i32
%2 = shl i32 %1, 31
%3 = select i1 false, i32 0, i32 %2
%4 = ashr i32 %3, 31
ret i32 %4
}
define i64 @main.mask_shl(i64 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = icmp uge i64 %1, 64
%4 = shl i64 %0, %1
%5 = select i1 %3, i64 0, i64 %4
ret i64 %5
}
define i8 @main.mask_shl8(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = trunc i64 %1 to i8
%4 = icmp uge i8 %3, 8
%5 = shl i8 %0, %3
%6 = select i1 %4, i8 0, i8 %5
ret i8 %6
}
define i8 @main.mask_shl8u(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = trunc i64 %1 to i8
%4 = icmp uge i8 %3, 8
%5 = shl i8 %0, %3
%6 = select i1 %4, i8 0, i8 %5
ret i8 %6
}
define i64 @main.mask_shr(i64 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = icmp uge i64 %1, 64
%4 = select i1 %3, i64 63, i64 %1
%5 = ashr i64 %0, %4
ret i64 %5
}
define i8 @main.mask_shr8(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = trunc i64 %1 to i8
%4 = icmp uge i8 %3, 8
%5 = select i1 %4, i8 7, i8 %3
%6 = ashr i8 %0, %5
ret i8 %6
}
define i8 @main.mask_shr8u(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
call void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1 %2)
%3 = trunc i64 %1 to i8
%4 = icmp uge i8 %3, 8
%5 = lshr i8 %0, %3
%6 = select i1 %4, i8 0, i8 %5
ret i8 %6
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String")
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.AssertNegativeShift"(i1)

View File

@@ -23,7 +23,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -120,7 +120,7 @@ _llgo_0:
%77 = extractvalue { ptr, ptr } %75, 0 %77 = extractvalue { ptr, ptr } %75, 0
%78 = call i64 %77(ptr %76, i64 -3) %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) %79 = call i32 (ptr, ...) @printf(ptr @0, i64 %46, i64 %53, i64 %57, i64 %63, i64 %69, i64 %78)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -22,7 +22,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8

View File

@@ -19,7 +19,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -48,13 +48,15 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %12, 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
%13 = getelementptr inbounds i64, ptr %2, i64 %11 %13 = icmp slt i64 %11, 0
%14 = load i64, ptr %13, align 4 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %13)
%15 = call i32 (ptr, ...) @printf(ptr @0, i64 %14) %14 = getelementptr inbounds i64, ptr %2, i64 %11
%15 = load i64, ptr %14, align 4
%16 = call i32 (ptr, ...) @printf(ptr @0, i64 %15)
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
@@ -72,4 +74,6 @@ _llgo_0:
ret i32 %5 ret i32 %5
} }
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -45,7 +45,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -69,7 +69,7 @@ _llgo_0:
%17 = extractvalue { ptr, ptr } %15, 0 %17 = extractvalue { ptr, ptr } %15, 0
%18 = call i64 %17(ptr %16, i64 100, i64 200) %18 = call i64 %17(ptr %16, i64 100, i64 200)
%19 = call i32 (ptr, ...) @printf(ptr @2, i64 %18, i64 %14) %19 = call i32 (ptr, ...) @printf(ptr @2, i64 %18, i64 %14)
ret void ret i32 0
} }
define i64 @"main.add$1"(i64 %0, i64 %1) { define i64 @"main.add$1"(i64 %0, i64 %1) {

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -37,7 +37,7 @@ _llgo_0:
call void @main.init() call void @main.init()
%2 = call i32 @strlen(ptr @main.format) %2 = call i32 @strlen(ptr @main.format)
call void (ptr, ...) @printf(ptr @main.format, i32 %2) call void (ptr, ...) @printf(ptr @main.format, i32 %2)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -3,7 +3,7 @@ source_filename = "main"
%main.Foo = type { i32, i1 } %main.Foo = type { i32, i1 }
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -57,7 +57,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -71,7 +71,7 @@ _llgo_0:
store i1 true, ptr %5, align 1 store i1 true, ptr %5, align 1
%6 = load %main.Foo, ptr %3, align 4 %6 = load %main.Foo, ptr %3, align 4
call void @"(main.Foo).Print"(%main.Foo %6) call void @"(main.Foo).Print"(%main.Foo %6)
ret void ret i32 0
} }
declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64) declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64)

View File

@@ -21,7 +21,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -39,7 +39,7 @@ _llgo_0:
%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) %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)
%8 = call i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %8 = call i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
%9 = call i32 (ptr, ...) @printf(ptr @0, i64 %8) %9 = call i32 (ptr, ...) @printf(ptr @0, i64 %8)
ret void ret i32 0
} }
define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
@@ -48,17 +48,19 @@ _llgo_0:
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
%2 = phi i64 [ 0, %_llgo_0 ], [ %9, %_llgo_2 ] %2 = phi i64 [ 0, %_llgo_0 ], [ %10, %_llgo_2 ]
%3 = phi i64 [ -1, %_llgo_0 ], [ %4, %_llgo_2 ] %3 = phi i64 [ -1, %_llgo_0 ], [ %4, %_llgo_2 ]
%4 = add i64 %3, 1 %4 = add i64 %3, 1
%5 = icmp slt i64 %4, %1 %5 = icmp slt i64 %4, %1
br i1 %5, label %_llgo_2, label %_llgo_3 br i1 %5, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %6 = icmp slt i64 %4, 0
%7 = getelementptr inbounds i64, ptr %6, i64 %4 call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %6)
%8 = load i64, ptr %7, align 4 %7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%9 = add i64 %2, %8 %8 = getelementptr inbounds i64, ptr %7, i64 %4
%9 = load i64, ptr %8, align 4
%10 = add i64 %2, %9
br label %_llgo_1 br label %_llgo_1
_llgo_3: ; preds = %_llgo_1 _llgo_3: ; preds = %_llgo_1
@@ -72,3 +74,5 @@ 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 i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)
declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1)

View File

@@ -1,7 +1,7 @@
; ModuleID = 'main' ; ModuleID = 'main'
source_filename = "main" source_filename = "main"
@main.format = global ptr null @main.format = global [10 x i8] undef
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@__llgo_argc = global ptr null @__llgo_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@@ -45,7 +45,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -57,7 +57,7 @@ _llgo_0:
store i32 100, ptr %3, align 4 store i32 100, ptr %3, align 4
store i1 true, ptr %4, align 1 store i1 true, ptr %4, align 1
call void @main.Print(ptr %2) call void @main.Print(ptr %2)
ret void ret i32 0
} }
declare void @printf(ptr, ...) declare void @printf(ptr, ...)

View File

@@ -25,7 +25,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void ret void
} }
define void @main(i32 %0, ptr %1) { define i32 @main(i32 %0, ptr %1) {
_llgo_0: _llgo_0:
store i32 %0, ptr @__llgo_argc, align 4 store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8 store ptr %1, ptr @__llgo_argv, align 8
@@ -33,7 +33,7 @@ _llgo_0:
call void @main.init() call void @main.init()
call void @main.foo() call void @main.foo()
%2 = call i32 (ptr, ...) @printf(ptr @0) %2 = call i32 (ptr, ...) @printf(ptr @0)
ret void ret i32 0
} }
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()

View File

@@ -152,6 +152,10 @@ type context struct {
phis []func() phis []func()
} }
func (p *context) inMain(instr ssa.Instruction) bool {
return instr.Parent().Name() == "main"
}
func (p *context) compileType(pkg llssa.Package, t *ssa.Type) { func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
tn := t.Object().(*types.TypeName) tn := t.Object().(*types.TypeName)
if tn.IsAlias() { // don't need to compile alias type if tn.IsAlias() { // don't need to compile alias type
@@ -246,10 +250,13 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
argc := types.NewParam(token.NoPos, pkgTypes, "", types.Typ[types.Int32]) argc := types.NewParam(token.NoPos, pkgTypes, "", types.Typ[types.Int32])
argv := types.NewParam(token.NoPos, pkgTypes, "", argvTy) argv := types.NewParam(token.NoPos, pkgTypes, "", argvTy)
params := types.NewTuple(argc, argv) params := types.NewTuple(argc, argv)
sig = types.NewSignatureType(nil, nil, nil, params, nil, false) ret := types.NewParam(token.NoPos, pkgTypes, "", p.prog.CInt().RawType())
results := types.NewTuple(ret)
sig = types.NewSignatureType(nil, nil, nil, params, results, 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 {
fn.MakeBlocks(nblk) // to set fn.HasBody() = true fn.MakeBlocks(nblk) // to set fn.HasBody() = true
p.inits = append(p.inits, func() { p.inits = append(p.inits, func() {
@@ -779,6 +786,10 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
results[i] = p.compileValue(b, r) results[i] = p.compileValue(b, r)
} }
} }
if p.inMain(instr) {
results = make([]llssa.Expr, 1)
results[0] = p.prog.IntVal(0, p.prog.CInt())
}
b.Return(results...) b.Return(results...)
case *ssa.If: case *ssa.If:
fn := p.fn fn := p.fn

View File

@@ -45,7 +45,7 @@ func TestFromTestdata(t *testing.T) {
} }
func TestSqlite(t *testing.T) { func TestSqlite(t *testing.T) {
cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/llgo_autogen.ll") cltest.Pkg(t, "github.com/goplus/llgo/c/sqlite", "../c/sqlite/llgo_autogen.ll")
} }
func TestFromTestpymath(t *testing.T) { func TestFromTestpymath(t *testing.T) {

Binary file not shown.

View File

@@ -209,7 +209,7 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
dir, lib := filepath.Split(linkFile) dir, lib := filepath.Split(linkFile)
command := " -l " + lib command := " -l " + lib
if dir != "" { if dir != "" {
command += " -L " + dir command += " -L " + dir[:len(dir)-1]
} }
if isSingleLinkFile(pkg.ExportFile) { if isSingleLinkFile(pkg.ExportFile) {
pkg.ExportFile = command + " " + pkg.ExportFile pkg.ExportFile = command + " " + pkg.ExportFile
@@ -371,6 +371,7 @@ var (
"-x": false, // -x: print the commands "-x": false, // -x: print the commands
"-tags": true, // -tags 'tag,list': a space-separated list of build tags to consider satisfied during the build "-tags": true, // -tags 'tag,list': a space-separated list of build tags to consider satisfied during the build
"-pkgdir": true, // -pkgdir dir: install and load all packages from dir instead of the usual locations "-pkgdir": true, // -pkgdir dir: install and load all packages from dir instead of the usual locations
"-ldflags": true, // --ldflags 'flag list': arguments to pass on each go tool link invocation
} }
) )
@@ -403,7 +404,11 @@ func SkipFlagArgs(args []string) int {
} }
func checkFlag(arg string, i *int, verbose *bool, swflags map[string]bool) { func checkFlag(arg string, i *int, verbose *bool, swflags map[string]bool) {
if hasarg, ok := swflags[arg]; ok { if pos := strings.IndexByte(arg, '='); pos > 0 {
if verbose != nil && arg == "-v=true" {
*verbose = true
}
} else if hasarg, ok := swflags[arg]; ok {
if hasarg { if hasarg {
*i++ *i++
} else if verbose != nil && arg == "-v" { } else if verbose != nil && arg == "-v" {

27
internal/runtime/error.go Normal file
View File

@@ -0,0 +1,27 @@
package runtime
type errorString string
func (e errorString) RuntimeError() {}
func (e errorString) Error() string {
return "runtime error: " + string(e)
}
func AssertRuntimeError(b bool, msg string) {
if b {
panic(errorString(msg).Error())
}
}
func AssertNegativeShift(b bool) {
if b {
panic(errorString("negative shift amount").Error())
}
}
func AssertIndexRange(b bool) {
if b {
panic(errorString("index out of range").Error())
}
}

Binary file not shown.

172
internal/runtime/print.go Normal file
View File

@@ -0,0 +1,172 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// The compiler knows that a print of a value of this type
// should use printhex instead of printuint (decimal).
func bytes(s string) (ret []byte) {
rp := (*Slice)(unsafe.Pointer(&ret))
sp := (*String)(unsafe.Pointer(&s))
rp.data = sp.data
rp.len = sp.len
rp.cap = sp.len
return
}
func gwrite(b []byte) {
if len(b) == 0 {
return
}
for _, v := range b {
c.Fprintf(c.Stderr, c.Str("%c"), v)
}
}
func PrintBool(v bool) {
if v {
PrintString("true")
} else {
PrintString("false")
}
}
func PrintFloat(v float64) {
switch {
case v != v:
PrintString("NaN")
return
case v+v == v && v > 0:
PrintString("+Inf")
return
case v+v == v && v < 0:
PrintString("-Inf")
return
}
const n = 7 // digits printed
var buf [n + 7]byte
buf[0] = '+'
e := 0 // exp
if v == 0 {
if 1/v < 0 {
buf[0] = '-'
}
} else {
if v < 0 {
v = -v
buf[0] = '-'
}
// normalize
for v >= 10 {
e++
v /= 10
}
for v < 1 {
e--
v *= 10
}
// round
h := 5.0
for i := 0; i < n; i++ {
h /= 10
}
v += h
if v >= 10 {
e++
v /= 10
}
}
// format +d.dddd+edd
for i := 0; i < n; i++ {
s := int(v)
buf[i+2] = byte(s + '0')
v -= float64(s)
v *= 10
}
buf[1] = buf[2]
buf[2] = '.'
buf[n+2] = 'e'
buf[n+3] = '+'
if e < 0 {
e = -e
buf[n+3] = '-'
}
buf[n+4] = byte(e/100) + '0'
buf[n+5] = byte(e/10)%10 + '0'
buf[n+6] = byte(e%10) + '0'
gwrite(buf[:])
}
// func PrintComplex(c complex128) {
// print("(", real(c), imag(c), "i)")
// }
func PrintUint(v uint64) {
var buf [100]byte
i := len(buf)
for i--; i > 0; i-- {
buf[i] = byte(v%10 + '0')
if v < 10 {
break
}
v /= 10
}
gwrite(buf[i:])
}
func PrintInt(v int64) {
if v < 0 {
PrintString("-")
v = -v
}
PrintUint(uint64(v))
}
func PrintHex(v uint64) {
const dig = "0123456789abcdef"
var buf [100]byte
i := len(buf)
for i--; i > 0; i-- {
buf[i] = dig[v%16]
if v < 16 && len(buf)-i >= 0 {
break
}
v /= 16
}
i--
buf[i] = 'x'
i--
buf[i] = '0'
gwrite(buf[i:])
}
func PrintPointer(p unsafe.Pointer) {
PrintHex(uint64(uintptr(p)))
}
func PrintString(s string) {
gwrite(bytes(s))
}
func PrintSlice(s Slice) {
sp := (*Slice)(unsafe.Pointer(&s))
print("[", s.len, "/", s.cap, "]")
PrintPointer(sp.data)
}
func PrintIface(i iface) {
print("(", i.tab, ",", i.data, ")")
}

View File

@@ -111,6 +111,102 @@ func ShowConfig(mode *py.Object) *py.Object
//go:linkname Isfortran py.isfortran //go:linkname Isfortran py.isfortran
func Isfortran(a *py.Object) *py.Object func Isfortran(a *py.Object) *py.Object
// Return an array representing the indices of a grid.
//
// Compute an array where the subarrays contain index values 0, 1, ...
// varying only along the corresponding axis.
//
// Parameters
// ----------
// dimensions : sequence of ints
//
// The shape of the grid.
//
// dtype : dtype, optional
//
// Data type of the result.
//
// sparse : boolean, optional
//
// Return a sparse representation of the grid instead of a dense
// representation. Default is False.
//
// .. versionadded:: 1.17
//
// Returns
// -------
// grid : one ndarray or tuple of ndarrays
//
// If sparse is False:
// Returns one array of grid indices,
// ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
// If sparse is True:
// Returns a tuple of arrays, with
// ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with
// dimensions[i] in the ith place
//
// See Also
// --------
// mgrid, ogrid, meshgrid
//
// Notes
// -----
// The output shape in the dense case is obtained by prepending the number
// of dimensions in front of the tuple of dimensions, i.e. if `dimensions`
// is a tuple “(r0, ..., rN-1)“ of length “N“, the output shape is
// “(N, r0, ..., rN-1)“.
//
// The subarrays “grid[k]“ contains the N-D array of indices along the
// “k-th“ axis. Explicitly::
//
// grid[k, i0, i1, ..., iN-1] = ik
//
// Examples
// --------
// >>> grid = np.indices((2, 3))
// >>> grid.shape
// (2, 2, 3)
// >>> grid[0] # row indices
// array([[0, 0, 0],
//
// [1, 1, 1]])
//
// >>> grid[1] # column indices
// array([[0, 1, 2],
//
// [0, 1, 2]])
//
// The indices can be used as an index into an array.
//
// >>> x = np.arange(20).reshape(5, 4)
// >>> row, col = np.indices((2, 3))
// >>> x[row, col]
// array([[0, 1, 2],
//
// [4, 5, 6]])
//
// Note that it would be more straightforward in the above example to
// extract the required elements directly with “x[:2, :3]“.
//
// If sparse is set to true, the grid will be returned in a sparse
// representation.
//
// >>> i, j = np.indices((2, 3), sparse=True)
// >>> i.shape
// (2, 1)
// >>> j.shape
// (1, 3)
// >>> i # row indices
// array([[0],
//
// [1]])
//
// >>> j # column indices
// array([[0, 1, 2]])
//
//go:linkname Indices py.indices
func Indices(dimensions *py.Object, dtype *py.Object, sparse *py.Object) *py.Object
// Construct an array by executing a function over each coordinate. // Construct an array by executing a function over each coordinate.
// //
// The resulting array therefore has a value “fn(x, y, z)“ at // The resulting array therefore has a value “fn(x, y, z)“ at
@@ -3458,67 +3554,6 @@ func Frexp(__llgo_va_list ...interface{}) *py.Object
//go:linkname Gcd py.gcd //go:linkname Gcd py.gcd
func Gcd(__llgo_va_list ...interface{}) *py.Object func Gcd(__llgo_va_list ...interface{}) *py.Object
// greater_equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Return the truth value of (x1 >= x2) element-wise.
//
// Parameters
// ----------
// x1, x2 : array_like
//
// Input arrays.
// If ``x1.shape != x2.shape``, they must be broadcastable to a common
// shape (which becomes the shape of the output).
//
// out : ndarray, None, or tuple of ndarray and None, optional
//
// A location into which the result is stored. If provided, it must have
// a shape that the inputs broadcast to. If not provided or None,
// a freshly-allocated array is returned. A tuple (possible only as a
// keyword argument) must have length equal to the number of outputs.
//
// where : array_like, optional
//
// This condition is broadcast over the input. At locations where the
// condition is True, the `out` array will be set to the ufunc result.
// Elsewhere, the `out` array will retain its original value.
// Note that if an uninitialized `out` array is created via the default
// ``out=None``, locations within it where the condition is False will
// remain uninitialized.
//
// **kwargs
//
// For other keyword-only arguments, see the
// :ref:`ufunc docs <ufuncs.kwargs>`.
//
// Returns
// -------
// out : bool or ndarray of bool
//
// Output array, element-wise comparison of `x1` and `x2`.
// Typically of type bool, unless ``dtype=object`` is passed.
// This is a scalar if both `x1` and `x2` are scalars.
//
// See Also
// --------
// greater, less, less_equal, equal, not_equal
//
// Examples
// --------
// >>> np.greater_equal([4, 2, 1], [2, 2, 2])
// array([ True, True, False])
//
// The “>=“ operator can be used as a shorthand for “np.greater_equal“
// on ndarrays.
//
// >>> a = np.array([4, 2, 1])
// >>> b = np.array([2, 2, 2])
// >>> a >= b
// array([ True, True, False])
//
//go:linkname GreaterEqual py.greater_equal
func GreaterEqual(__llgo_va_list ...interface{}) *py.Object
// heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) // heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
// //
// Compute the Heaviside step function. // Compute the Heaviside step function.
@@ -6204,6 +6239,70 @@ func RightShift(__llgo_va_list ...interface{}) *py.Object
//go:linkname Rint py.rint //go:linkname Rint py.rint
func Rint(__llgo_va_list ...interface{}) *py.Object func Rint(__llgo_va_list ...interface{}) *py.Object
// sign(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Returns an element-wise indication of the sign of a number.
//
// The `sign` function returns “-1 if x < 0, 0 if x==0, 1 if x > 0“. nan
// is returned for nan inputs.
//
// For complex inputs, the `sign` function returns
// “sign(x.real) + 0j if x.real != 0 else sign(x.imag) + 0j“.
//
// complex(nan, 0) is returned for complex nan inputs.
//
// Parameters
// ----------
// x : array_like
//
// Input values.
//
// out : ndarray, None, or tuple of ndarray and None, optional
//
// A location into which the result is stored. If provided, it must have
// a shape that the inputs broadcast to. If not provided or None,
// a freshly-allocated array is returned. A tuple (possible only as a
// keyword argument) must have length equal to the number of outputs.
//
// where : array_like, optional
//
// This condition is broadcast over the input. At locations where the
// condition is True, the `out` array will be set to the ufunc result.
// Elsewhere, the `out` array will retain its original value.
// Note that if an uninitialized `out` array is created via the default
// ``out=None``, locations within it where the condition is False will
// remain uninitialized.
//
// **kwargs
//
// For other keyword-only arguments, see the
// :ref:`ufunc docs <ufuncs.kwargs>`.
//
// Returns
// -------
// y : ndarray
//
// The sign of `x`.
// This is a scalar if `x` is a scalar.
//
// Notes
// -----
// There is more than one definition of sign in common use for complex
// numbers. The definition used here is equivalent to :math:`x/\sqrt{x*x}`
// which is different from a common alternative, :math:`x/|x|`.
//
// Examples
// --------
// >>> np.sign([-5., 4.5])
// array([-1., 1.])
// >>> np.sign(0)
// 0
// >>> np.sign(5-2j)
// (1+0j)
//
//go:linkname Sign py.sign
func Sign(__llgo_va_list ...interface{}) *py.Object
// signbit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) // signbit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
// //
// Returns element-wise True where signbit is set (less than zero). // Returns element-wise True where signbit is set (less than zero).
@@ -9017,6 +9116,130 @@ func GetArrayWrap(__llgo_va_list ...interface{}) *py.Object
//go:linkname BroadcastShapes py.broadcast_shapes //go:linkname BroadcastShapes py.broadcast_shapes
func BroadcastShapes(__llgo_va_list ...interface{}) *py.Object func BroadcastShapes(__llgo_va_list ...interface{}) *py.Object
// Return a 2-D array with ones on the diagonal and zeros elsewhere.
//
// Parameters
// ----------
// N : int
//
// Number of rows in the output.
//
// M : int, optional
//
// Number of columns in the output. If None, defaults to `N`.
//
// k : int, optional
//
// Index of the diagonal: 0 (the default) refers to the main diagonal,
// a positive value refers to an upper diagonal, and a negative value
// to a lower diagonal.
//
// dtype : data-type, optional
//
// Data-type of the returned array.
//
// order : {'C', 'F'}, optional
//
// Whether the output should be stored in row-major (C-style) or
// column-major (Fortran-style) order in memory.
//
// .. versionadded:: 1.14.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// I : ndarray of shape (N,M)
//
// An array where all elements are equal to zero, except for the `k`-th
// diagonal, whose values are equal to one.
//
// See Also
// --------
// identity : (almost) equivalent function
// diag : diagonal 2-D array from a 1-D array specified by the user.
//
// Examples
// --------
// >>> np.eye(2, dtype=int)
// array([[1, 0],
//
// [0, 1]])
//
// >>> np.eye(3, k=1)
// array([[0., 1., 0.],
//
// [0., 0., 1.],
// [0., 0., 0.]])
//
//go:linkname Eye py.eye
func Eye(N *py.Object, M *py.Object, k *py.Object, dtype *py.Object, order *py.Object) *py.Object
// An array with ones at and below the given diagonal and zeros elsewhere.
//
// Parameters
// ----------
// N : int
//
// Number of rows in the array.
//
// M : int, optional
//
// Number of columns in the array.
// By default, `M` is taken equal to `N`.
//
// k : int, optional
//
// The sub-diagonal at and below which the array is filled.
// `k` = 0 is the main diagonal, while `k` < 0 is below it,
// and `k` > 0 is above. The default is 0.
//
// dtype : dtype, optional
//
// Data type of the returned array. The default is float.
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// tri : ndarray of shape (N, M)
//
// Array with its lower triangle filled with ones and zero elsewhere;
// in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise.
//
// Examples
// --------
// >>> np.tri(3, 5, 2, dtype=int)
// array([[1, 1, 1, 0, 0],
//
// [1, 1, 1, 1, 0],
// [1, 1, 1, 1, 1]])
//
// >>> np.tri(3, 5, -1)
// array([[0., 0., 0., 0., 0.],
//
// [1., 0., 0., 0., 0.],
// [1., 1., 0., 0., 0.]])
//
//go:linkname Tri py.tri
func Tri(N *py.Object, M *py.Object, k *py.Object, dtype *py.Object) *py.Object
// Return the indices to access (n, n) arrays, given a masking function. // Return the indices to access (n, n) arrays, given a masking function.
// //
// Assume `mask_func` is a function that, for a square array a of size // Assume `mask_func` is a function that, for a square array a of size
@@ -9502,6 +9725,49 @@ func GetInclude() *py.Object
//go:linkname Info py.info //go:linkname Info py.info
func Info(object *py.Object, maxwidth *py.Object, output *py.Object, toplevel *py.Object) *py.Object func Info(object *py.Object, maxwidth *py.Object, output *py.Object, toplevel *py.Object) *py.Object
// Print or write to a file the source code for a NumPy object.
//
// The source code is only returned for objects written in Python. Many
// functions and classes are defined in C and will therefore not return
// useful information.
//
// Parameters
// ----------
// object : numpy object
//
// Input object. This can be any object (function, class, module,
// ...).
//
// output : file object, optional
//
// If `output` not supplied then source code is printed to screen
// (sys.stdout). File object must be created with either write 'w' or
// append 'a' modes.
//
// See Also
// --------
// lookfor, info
//
// Examples
// --------
// >>> np.source(np.interp) #doctest: +SKIP
// In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
// def interp(x, xp, fp, left=None, right=None):
//
// """.... (full docstring printed)"""
// if isinstance(x, (float, int, number)):
// return compiled_interp([x], xp, fp, left, right).item()
// else:
// return compiled_interp(x, xp, fp, left, right)
//
// The source code is only returned for objects written in Python.
//
// >>> np.source(np.array) #doctest: +SKIP
// Not available for this object.
//
//go:linkname Source py.source
func Source(object *py.Object, output *py.Object) *py.Object
// Print the NumPy arrays in the given dictionary. // Print the NumPy arrays in the given dictionary.
// //
// If there is no dictionary passed in or `vardict` is None then returns // If there is no dictionary passed in or `vardict` is None then returns
@@ -9718,6 +9984,538 @@ func SafeEval(source *py.Object) *py.Object
//go:linkname ShowRuntime py.show_runtime //go:linkname ShowRuntime py.show_runtime
func ShowRuntime() *py.Object func ShowRuntime() *py.Object
// Load data from a text file.
//
// Parameters
// ----------
// fname : file, str, pathlib.Path, list of str, generator
//
// File, filename, list, or generator to read. If the filename
// extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
// that generators must return bytes or strings. The strings
// in a list or produced by a generator are treated as lines.
//
// dtype : data-type, optional
//
// Data-type of the resulting array; default: float. If this is a
// structured data-type, the resulting array will be 1-dimensional, and
// each row will be interpreted as an element of the array. In this
// case, the number of columns used must match the number of fields in
// the data-type.
//
// comments : str or sequence of str or None, optional
//
// The characters or list of characters used to indicate the start of a
// comment. None implies no comments. For backwards compatibility, byte
// strings will be decoded as 'latin1'. The default is '#'.
//
// delimiter : str, optional
//
// The character used to separate the values. For backwards compatibility,
// byte strings will be decoded as 'latin1'. The default is whitespace.
//
// .. versionchanged:: 1.23.0
// Only single character delimiters are supported. Newline characters
// cannot be used as the delimiter.
//
// converters : dict or callable, optional
//
// Converter functions to customize value parsing. If `converters` is
// callable, the function is applied to all columns, else it must be a
// dict that maps column number to a parser function.
// See examples for further details.
// Default: None.
//
// .. versionchanged:: 1.23.0
// The ability to pass a single callable to be applied to all columns
// was added.
//
// skiprows : int, optional
//
// Skip the first `skiprows` lines, including comments; default: 0.
//
// usecols : int or sequence, optional
//
// Which columns to read, with 0 being the first. For example,
// ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
// The default, None, results in all columns being read.
//
// .. versionchanged:: 1.11.0
// When a single column has to be read it is possible to use
// an integer instead of a tuple. E.g ``usecols = 3`` reads the
// fourth column the same way as ``usecols = (3,)`` would.
//
// unpack : bool, optional
//
// If True, the returned array is transposed, so that arguments may be
// unpacked using ``x, y, z = loadtxt(...)``. When used with a
// structured data-type, arrays are returned for each field.
// Default is False.
//
// ndmin : int, optional
//
// The returned array will have at least `ndmin` dimensions.
// Otherwise mono-dimensional axes will be squeezed.
// Legal values: 0 (default), 1 or 2.
//
// .. versionadded:: 1.6.0
//
// encoding : str, optional
//
// Encoding used to decode the inputfile. Does not apply to input streams.
// The special value 'bytes' enables backward compatibility workarounds
// that ensures you receive byte arrays as results if possible and passes
// 'latin1' encoded strings to converters. Override this value to receive
// unicode arrays and pass strings as input to converters. If set to None
// the system default is used. The default value is 'bytes'.
//
// .. versionadded:: 1.14.0
//
// max_rows : int, optional
//
// Read `max_rows` rows of content after `skiprows` lines. The default is
// to read all the rows. Note that empty rows containing no data such as
// empty lines and comment lines are not counted towards `max_rows`,
// while such lines are counted in `skiprows`.
//
// .. versionadded:: 1.16.0
//
// .. versionchanged:: 1.23.0
// Lines containing no data, including comment lines (e.g., lines
// starting with '#' or as specified via `comments`) are not counted
// towards `max_rows`.
//
// quotechar : unicode character or None, optional
//
// The character used to denote the start and end of a quoted item.
// Occurrences of the delimiter or comment characters are ignored within
// a quoted item. The default value is ``quotechar=None``, which means
// quoting support is disabled.
//
// If two consecutive instances of `quotechar` are found within a quoted
// field, the first is treated as an escape character. See examples.
//
// .. versionadded:: 1.23.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// out : ndarray
//
// Data read from the text file.
//
// See Also
// --------
// load, fromstring, fromregex
// genfromtxt : Load data with missing values handled as specified.
// scipy.io.loadmat : reads MATLAB data files
//
// Notes
// -----
// This function aims to be a fast reader for simply formatted files. The
// `genfromtxt` function provides more sophisticated handling of, e.g.,
// lines with missing values.
//
// Each row in the input text file must have the same number of values to be
// able to read all values. If all rows do not have same number of values, a
// subset of up to n columns (where n is the least number of values present
// in all rows) can be read by specifying the columns via `usecols`.
//
// .. versionadded:: 1.10.0
//
// The strings produced by the Python float.hex method can be used as
// input for floats.
//
// Examples
// --------
// >>> from io import StringIO # StringIO behaves like a file object
// >>> c = StringIO("0 1\n2 3")
// >>> np.loadtxt(c)
// array([[0., 1.],
//
// [2., 3.]])
//
// >>> d = StringIO("M 21 72\nF 35 58")
// >>> np.loadtxt(d, dtype={'names': ('gender', 'age', 'weight'),
// ... 'formats': ('S1', 'i4', 'f4')})
// array([(b'M', 21, 72.), (b'F', 35, 58.)],
//
// dtype=[('gender', 'S1'), ('age', '<i4'), ('weight', '<f4')])
//
// >>> c = StringIO("1,0,2\n3,0,4")
// >>> x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True)
// >>> x
// array([1., 3.])
// >>> y
// array([2., 4.])
//
// The `converters` argument is used to specify functions to preprocess the
// text prior to parsing. `converters` can be a dictionary that maps
// preprocessing functions to each column:
//
// >>> s = StringIO("1.618, 2.296\n3.141, 4.669\n")
// >>> conv = {
// ... 0: lambda x: np.floor(float(x)), # conversion fn for column 0
// ... 1: lambda x: np.ceil(float(x)), # conversion fn for column 1
// ... }
// >>> np.loadtxt(s, delimiter=",", converters=conv)
// array([[1., 3.],
//
// [3., 5.]])
//
// `converters` can be a callable instead of a dictionary, in which case it
// is applied to all columns:
//
// >>> s = StringIO("0xDE 0xAD\n0xC0 0xDE")
// >>> import functools
// >>> conv = functools.partial(int, base=16)
// >>> np.loadtxt(s, converters=conv)
// array([[222., 173.],
//
// [192., 222.]])
//
// This example shows how `converters` can be used to convert a field
// with a trailing minus sign into a negative number.
//
// >>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94')
// >>> def conv(fld):
// ... return -float(fld[:-1]) if fld.endswith(b'-') else float(fld)
// ...
// >>> np.loadtxt(s, converters=conv)
// array([[ 10.01, -31.25],
//
// [ 19.22, 64.31],
// [-17.57, 63.94]])
//
// Using a callable as the converter can be particularly useful for handling
// values with different formatting, e.g. floats with underscores:
//
// >>> s = StringIO("1 2.7 100_000")
// >>> np.loadtxt(s, converters=float)
// array([1.e+00, 2.7e+00, 1.e+05])
//
// This idea can be extended to automatically handle values specified in
// many different formats:
//
// >>> def conv(val):
// ... try:
// ... return float(val)
// ... except ValueError:
// ... return float.fromhex(val)
// >>> s = StringIO("1, 2.5, 3_000, 0b4, 0x1.4000000000000p+2")
// >>> np.loadtxt(s, delimiter=",", converters=conv, encoding=None)
// array([1.0e+00, 2.5e+00, 3.0e+03, 1.8e+02, 5.0e+00])
//
// Note that with the default “encoding="bytes"“, the inputs to the
// converter function are latin-1 encoded byte strings. To deactivate the
// implicit encoding prior to conversion, use “encoding=None“
//
// >>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94')
// >>> conv = lambda x: -float(x[:-1]) if x.endswith('-') else float(x)
// >>> np.loadtxt(s, converters=conv, encoding=None)
// array([[ 10.01, -31.25],
//
// [ 19.22, 64.31],
// [-17.57, 63.94]])
//
// Support for quoted fields is enabled with the `quotechar` parameter.
// Comment and delimiter characters are ignored when they appear within a
// quoted item delineated by `quotechar`:
//
// >>> s = StringIO('"alpha, #42", 10.0\n"beta, #64", 2.0\n')
// >>> dtype = np.dtype([("label", "U12"), ("value", float)])
// >>> np.loadtxt(s, dtype=dtype, delimiter=",", quotechar='"')
// array([('alpha, #42', 10.), ('beta, #64', 2.)],
//
// dtype=[('label', '<U12'), ('value', '<f8')])
//
// Quoted fields can be separated by multiple whitespace characters:
//
// >>> s = StringIO('"alpha, #42" 10.0\n"beta, #64" 2.0\n')
// >>> dtype = np.dtype([("label", "U12"), ("value", float)])
// >>> np.loadtxt(s, dtype=dtype, delimiter=None, quotechar='"')
// array([('alpha, #42', 10.), ('beta, #64', 2.)],
//
// dtype=[('label', '<U12'), ('value', '<f8')])
//
// Two consecutive quote characters within a quoted field are treated as a
// single escaped character:
//
// >>> s = StringIO('"Hello, my name is ""Monty""!"')
// >>> np.loadtxt(s, dtype="U", delimiter=",", quotechar='"')
// array('Hello, my name is "Monty"!', dtype='<U26')
//
// Read subset of columns when all rows do not contain equal number of values:
//
// >>> d = StringIO("1 2\n2 4\n3 9 12\n4 16 20")
// >>> np.loadtxt(d, usecols=(0, 1))
// array([[ 1., 2.],
//
// [ 2., 4.],
// [ 3., 9.],
// [ 4., 16.]])
//
//go:linkname Loadtxt py.loadtxt
func Loadtxt(fname *py.Object, dtype *py.Object, comments *py.Object, delimiter *py.Object, converters *py.Object, skiprows *py.Object, usecols *py.Object, unpack *py.Object, ndmin *py.Object, encoding *py.Object, maxRows *py.Object) *py.Object
// Load data from a text file, with missing values handled as specified.
//
// Each line past the first `skip_header` lines is split at the `delimiter`
// character, and characters following the `comments` character are discarded.
//
// Parameters
// ----------
// fname : file, str, pathlib.Path, list of str, generator
//
// File, filename, list, or generator to read. If the filename
// extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
// that generators must return bytes or strings. The strings
// in a list or produced by a generator are treated as lines.
//
// dtype : dtype, optional
//
// Data type of the resulting array.
// If None, the dtypes will be determined by the contents of each
// column, individually.
//
// comments : str, optional
//
// The character used to indicate the start of a comment.
// All the characters occurring on a line after a comment are discarded.
//
// delimiter : str, int, or sequence, optional
//
// The string used to separate values. By default, any consecutive
// whitespaces act as delimiter. An integer or sequence of integers
// can also be provided as width(s) of each field.
//
// skiprows : int, optional
//
// `skiprows` was removed in numpy 1.10. Please use `skip_header` instead.
//
// skip_header : int, optional
//
// The number of lines to skip at the beginning of the file.
//
// skip_footer : int, optional
//
// The number of lines to skip at the end of the file.
//
// converters : variable, optional
//
// The set of functions that convert the data of a column to a value.
// The converters can also be used to provide a default value
// for missing data: ``converters = {3: lambda s: float(s or 0)}``.
//
// missing : variable, optional
//
// `missing` was removed in numpy 1.10. Please use `missing_values`
// instead.
//
// missing_values : variable, optional
//
// The set of strings corresponding to missing data.
//
// filling_values : variable, optional
//
// The set of values to be used as default when the data are missing.
//
// usecols : sequence, optional
//
// Which columns to read, with 0 being the first. For example,
// ``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns.
//
// names : {None, True, str, sequence}, optional
//
// If `names` is True, the field names are read from the first line after
// the first `skip_header` lines. This line can optionally be preceded
// by a comment delimiter. If `names` is a sequence or a single-string of
// comma-separated names, the names will be used to define the field names
// in a structured dtype. If `names` is None, the names of the dtype
// fields will be used, if any.
//
// excludelist : sequence, optional
//
// A list of names to exclude. This list is appended to the default list
// ['return','file','print']. Excluded names are appended with an
// underscore: for example, `file` would become `file_`.
//
// deletechars : str, optional
//
// A string combining invalid characters that must be deleted from the
// names.
//
// defaultfmt : str, optional
//
// A format used to define default field names, such as "f%i" or "f_%02i".
//
// autostrip : bool, optional
//
// Whether to automatically strip white spaces from the variables.
//
// replace_space : char, optional
//
// Character(s) used in replacement of white spaces in the variable
// names. By default, use a '_'.
//
// case_sensitive : {True, False, 'upper', 'lower'}, optional
//
// If True, field names are case sensitive.
// If False or 'upper', field names are converted to upper case.
// If 'lower', field names are converted to lower case.
//
// unpack : bool, optional
//
// If True, the returned array is transposed, so that arguments may be
// unpacked using ``x, y, z = genfromtxt(...)``. When used with a
// structured data-type, arrays are returned for each field.
// Default is False.
//
// usemask : bool, optional
//
// If True, return a masked array.
// If False, return a regular array.
//
// loose : bool, optional
//
// If True, do not raise errors for invalid values.
//
// invalid_raise : bool, optional
//
// If True, an exception is raised if an inconsistency is detected in the
// number of columns.
// If False, a warning is emitted and the offending lines are skipped.
//
// max_rows : int, optional
//
// The maximum number of rows to read. Must not be used with skip_footer
// at the same time. If given, the value must be at least 1. Default is
// to read the entire file.
//
// .. versionadded:: 1.10.0
//
// encoding : str, optional
//
// Encoding used to decode the inputfile. Does not apply when `fname` is
// a file object. The special value 'bytes' enables backward compatibility
// workarounds that ensure that you receive byte arrays when possible
// and passes latin1 encoded strings to converters. Override this value to
// receive unicode arrays and pass strings as input to converters. If set
// to None the system default is used. The default value is 'bytes'.
//
// .. versionadded:: 1.14.0
//
// ndmin : int, optional
//
// Same parameter as `loadtxt`
//
// .. versionadded:: 1.23.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// out : ndarray
//
// Data read from the text file. If `usemask` is True, this is a
// masked array.
//
// See Also
// --------
// numpy.loadtxt : equivalent function when no data is missing.
//
// Notes
// -----
// - When spaces are used as delimiters, or when no delimiter has been given
// as input, there should not be any missing data between two fields.
// - When the variables are named (either by a flexible dtype or with `names`),
// there must not be any header in the file (else a ValueError
// exception is raised).
// - Individual values are not stripped of spaces by default.
// When using a custom converter, make sure the function does remove spaces.
//
// References
// ----------
// .. [1] NumPy User Guide, section `I/O with NumPy
//
// <https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html>`_.
//
// Examples
// --------
// >>> from io import StringIO
// >>> import numpy as np
//
// # Comma delimited file with mixed dtype
//
// >>> s = StringIO(u"1,1.3,abcde")
// >>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
// ... ('mystring','S5')], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// Using dtype = None
//
// >>> _ = s.seek(0) # needed for StringIO example only
// >>> data = np.genfromtxt(s, dtype=None,
// ... names = ['myint','myfloat','mystring'], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// # Specifying dtype and names
//
// >>> _ = s.seek(0)
// >>> data = np.genfromtxt(s, dtype="i8,f8,S5",
// ... names=['myint','myfloat','mystring'], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// # An example with fixed-width columns
//
// >>> s = StringIO(u"11.3abcde")
// >>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'],
// ... delimiter=[1,3,5])
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('intvar', '<i8'), ('fltvar', '<f8'), ('strvar', 'S5')])
//
// # An example to show comments
//
// >>> f = StringIO(”'
// ... text,# of chars
// ... hello world,11
// ... numpy,5”')
// >>> np.genfromtxt(f, dtype='S12,S12', delimiter=',')
// array([(b'text', b”), (b'hello world', b'11'), (b'numpy', b'5')],
//
// dtype=[('f0', 'S12'), ('f1', 'S12')])
//
//go:linkname Genfromtxt py.genfromtxt
func Genfromtxt(fname *py.Object, dtype *py.Object, comments *py.Object, delimiter *py.Object, skipHeader *py.Object, skipFooter *py.Object, converters *py.Object, missingValues *py.Object, fillingValues *py.Object, usecols *py.Object, names *py.Object, excludelist *py.Object, deletechars *py.Object, replaceSpace *py.Object, autostrip *py.Object, caseSensitive *py.Object, defaultfmt *py.Object, unpack *py.Object, usemask *py.Object, loose *py.Object, invalidRaise *py.Object, maxRows *py.Object, encoding *py.Object) *py.Object
// Load ASCII data from a file and return it in a record array. // Load ASCII data from a file and return it in a record array.
// //
// If “usemask=False“ a standard `recarray` is returned, // If “usemask=False“ a standard `recarray` is returned,

View File

@@ -42,15 +42,6 @@ func Arange(start, stop, step, dtype *py.Object) *py.Object
//go:linkname Empty py.empty //go:linkname Empty py.empty
func Empty(shape, dtype, order *py.Object) *py.Object func Empty(shape, dtype, order *py.Object) *py.Object
// Return a 2-D array with ones on the diagonal and zeros elsewhere.
//
// numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C', *, like=None)
//
// See https://numpy.org/doc/stable/reference/generated/numpy.eye.html#numpy-eye
//
//go:linkname Eye py.eye
func Eye(N, M, k, dtype, order *py.Object) *py.Object
// Return a new array of given shape and type, filled with zeros. // Return a new array of given shape and type, filled with zeros.
// //
// numpy.zeros(shape, dtype=float, order='C', *, like=None) // numpy.zeros(shape, dtype=float, order='C', *, like=None)

7351
py/pandas/gen.go Normal file

File diff suppressed because it is too large Load Diff

BIN
py/pandas/llgo_autogen.lla Normal file

Binary file not shown.

57
py/pandas/pandas.go Normal file
View File

@@ -0,0 +1,57 @@
/*
* 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 pandas
import (
_ "unsafe"
"github.com/goplus/llgo/py"
)
// https://pandas.pydata.org/docs/reference/index.html
// read_excel(io, sheet_name=0, *, header=0, names=None, index_col=None, usecols=None,
// dtype=None, engine=None, converters=None, true_values=None, false_values=None,
// skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True,
// verbose=False, parse_dates=False, date_parser=_NoDefault.no_default, date_format=None,
// thousands=None, decimal='.', comment=None, skipfooter=0, storage_options=None,
// dtype_backend=_NoDefault.no_default, engine_kwargs=None)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html
//
//go:linkname ReadExcel py.read_excel
func ReadExcel(io, sheetName *py.Object) *py.Object
// See https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
//
//go:linkname ReadCsv py.read_csv
func ReadCsv(filepathOrBuffer *py.Object) *py.Object
// eval(expr, parser='pandas', engine=None, local_dict=None, global_dict=None, resolvers=(),
// level=0, target=None, inplace=False)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.eval.html#pandas.eval
//
//go:linkname Eval py.eval
func Eval(expr, parser, engine, localDict, globalDict, resolvers, level, target, inplace *py.Object) *py.Object
// show_versions(as_json=False)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.show_versions.html
//
//go:linkname ShowVersions py.show_versions
func ShowVersions(asJson *py.Object) *py.Object

2
py/torch/doc.txt Normal file
View File

@@ -0,0 +1,2 @@
==> Skip 303 symbols:
[classproperty get_file_path prepare_multiprocessing_environment set_autocast_enabled is_autocast_enabled clear_autocast_cache set_autocast_cpu_enabled is_autocast_cpu_enabled set_autocast_cpu_dtype get_autocast_cpu_dtype set_autocast_gpu_dtype get_autocast_gpu_dtype set_autocast_xla_enabled is_autocast_xla_enabled set_autocast_xla_dtype get_autocast_xla_dtype set_autocast_ipu_enabled is_autocast_ipu_enabled set_autocast_ipu_dtype get_autocast_ipu_dtype autocast_increment_nesting autocast_decrement_nesting is_autocast_cache_enabled set_autocast_cache_enabled set_anomaly_enabled is_anomaly_enabled is_anomaly_check_nan_enabled parse_ir parse_schema unify_type_list fork wait parse_type_comment merge_type_from_type_comment import_ir_module import_ir_module_from_buffer vitals_enabled set_vital read_vitals init_num_threads sym_sqrt obj candidate typename abs_ acos_ acosh_ adaptive_avg_pool1d adaptive_max_pool1d addmv_ affine_grid_generator alias_copy align_tensors alpha_dropout alpha_dropout_ arccos_ arccosh_ arcsin_ arcsinh_ arctan_ arctanh_ as_strided_ as_strided_copy as_strided_scatter asin_ asinh_ atan_ atanh_ avg_pool1d batch_norm batch_norm_backward_elemt batch_norm_backward_reduce batch_norm_elemt batch_norm_gather_stats batch_norm_gather_stats_with_counts batch_norm_stats batch_norm_update_stats bilinear binary_cross_entropy_with_logits binomial ccol_indices_copy ceil_ celu celu_ channel_shuffle choose_qparams_optimized clamp_ clamp_max clamp_max_ clamp_min clamp_min_ clip_ col_indices_copy conj_physical_ constant_pad_nd conv1d conv2d conv3d conv_tbc conv_transpose1d conv_transpose2d conv_transpose3d convolution cos_ cosh_ cosine_embedding_loss cosine_similarity crow_indices_copy ctc_loss cudnn_affine_grid_generator cudnn_batch_norm cudnn_convolution cudnn_convolution_add_relu cudnn_convolution_relu cudnn_convolution_transpose cudnn_grid_sampler cudnn_is_acceptable deg2rad_ detach detach_ detach_copy diagonal_copy dropout dropout_ dsmm embedding embedding_bag embedding_renorm_ empty_permuted empty_quantized erf_ erfc_ exp2_ exp_ expand_copy expm1_ fbgemm_linear_fp16_weight fbgemm_linear_fp16_weight_fp32_activation fbgemm_linear_int8_weight fbgemm_linear_int8_weight_fp32_activation fbgemm_linear_quantize_weight fbgemm_pack_gemm_matrix_fp16 fbgemm_pack_quantized_matrix feature_alpha_dropout feature_alpha_dropout_ feature_dropout feature_dropout_ fill fill_ fix_ floor_ frac_ frobenius_norm fused_moving_avg_obs_fake_quant gcd_ get_device grid_sampler grid_sampler_2d grid_sampler_3d group_norm gru gru_cell hardshrink hinge_embedding_loss hsmm i0_ index_fill index_put index_put_ indices_copy instance_norm int_repr is_distributed is_inference is_neg is_same_size is_signed is_vulkan_available kl_div layer_norm lcm_ ldexp_ log10_ log1p_ log2_ log_ log_softmax logit_ lstm lstm_cell margin_ranking_loss masked_fill masked_scatter max_pool1d max_pool1d_with_indices max_pool2d max_pool3d miopen_batch_norm miopen_convolution miopen_convolution_add_relu miopen_convolution_relu miopen_convolution_transpose miopen_depthwise_convolution miopen_rnn mkldnn_adaptive_avg_pool2d mkldnn_convolution mkldnn_linear_backward_weights mkldnn_max_pool2d mkldnn_max_pool3d mkldnn_rnn_layer nan_to_num_ native_batch_norm native_channel_shuffle native_dropout native_group_norm native_layer_norm native_norm neg_ negative_ nonzero_static norm_except_dim nuclear_norm pairwise_distance pdist permute_copy pixel_shuffle pixel_unshuffle poisson_nll_loss prelu put q_per_channel_axis q_per_channel_scales q_per_channel_zero_points q_scale q_zero_point quantize_per_tensor_dynamic quantized_gru_cell quantized_lstm_cell quantized_max_pool3d quantized_rnn_relu_cell quantized_rnn_tanh_cell rad2deg_ reciprocal_ relu relu_ resize_as_ resize_as_sparse_ rnn_relu rnn_relu_cell rnn_tanh rnn_tanh_cell round_ row_indices_copy rrelu rrelu_ rsqrt_ rsub saddmm scalar_tensor segment_reduce select_copy selu selu_ sigmoid_ sin_ sinc_ sinh_ slice_copy split_copy split_with_sizes split_with_sizes_copy spmm sqrt_ square_ squeeze_copy sym_constrain_range sym_constrain_range_for_size t_copy tan_ tanh_ threshold threshold_ transpose_copy triplet_margin_loss trunc_ unbind_copy unfold_copy unsafe_chunk unsafe_split unsafe_split_with_sizes unsqueeze_copy values_copy view_as_complex_copy view_as_real_copy view_copy xlogy_ zero_ to_dlpack matrix_rank eig solve lstsq symeig]

4144
py/torch/gen.go Normal file

File diff suppressed because it is too large Load Diff

BIN
py/torch/llgo_autogen.lla Normal file

Binary file not shown.

View File

@@ -45,3 +45,8 @@ func (u *Object) CStrAndLen() (*c.Char, uintptr) { return nil, 0 }
// //
// llgo:link (*Object).CStr C.PyUnicode_AsUTF8 // llgo:link (*Object).CStr C.PyUnicode_AsUTF8
func (u *Object) CStr() *c.Char { return nil } func (u *Object) CStr() *c.Char { return nil }
// Same as CStr. Provided for Go+.
//
// llgo:link (*Object).Cstr C.PyUnicode_AsUTF8
func (u *Object) Cstr() *c.Char { return nil }

View File

@@ -60,6 +60,7 @@ type NamedConst = *aNamedConst
type aGlobal struct { type aGlobal struct {
Expr Expr
array bool
} }
// A Global is a named Value holding the address of a package-level // A Global is a named Value holding the address of a package-level
@@ -72,8 +73,17 @@ func (p Package) NewVar(name string, typ types.Type, bg Background) Global {
return v return v
} }
t := p.Prog.Type(typ, bg) t := p.Prog.Type(typ, bg)
gbl := llvm.AddGlobal(p.mod, t.ll, name) var gbl llvm.Value
ret := &aGlobal{Expr{gbl, t}} var array bool
if t.kind == vkPtr && p.Prog.Elem(t).kind == vkArray {
typ := p.Prog.Elem(t).ll
gbl = llvm.AddGlobal(p.mod, typ, name)
gbl.SetInitializer(llvm.Undef(typ))
array = true
} else {
gbl = llvm.AddGlobal(p.mod, t.ll, name)
}
ret := &aGlobal{Expr{gbl, t}, array}
p.vars[name] = ret p.vars[name] = ret
return ret return ret
} }
@@ -85,6 +95,9 @@ func (p Package) VarOf(name string) Global {
// Init initializes the global variable with the given value. // Init initializes the global variable with the given value.
func (g Global) Init(v Expr) { func (g Global) Init(v Expr) {
if g.array && v.kind == vkPtr {
return
}
g.impl.SetInitializer(v.impl) g.impl.SetInitializer(v.impl)
} }

View File

@@ -320,15 +320,36 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
} }
} }
case isLogicOp(op): // op: & | ^ << >> &^ case isLogicOp(op): // op: & | ^ << >> &^
if op == token.AND_NOT { switch op {
case token.AND_NOT:
return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.Type} return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.Type}
case token.SHL, token.SHR:
if needsNegativeCheck(y) {
check := Expr{b.impl.CreateICmp(llvm.IntSLT, y.impl, llvm.ConstInt(y.ll, 0, false), ""), b.Prog.Bool()}
b.InlineCall(b.Func.Pkg.rtFunc("AssertNegativeShift"), check)
}
xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type)
if xsize != ysize {
y = b.Convert(x.Type, y)
}
overflows := b.impl.CreateICmp(llvm.IntUGE, y.impl, llvm.ConstInt(y.ll, xsize*8, false), "")
xzero := llvm.ConstInt(x.ll, 0, false)
if op == token.SHL {
rhs := b.impl.CreateShl(x.impl, y.impl, "")
return Expr{b.impl.CreateSelect(overflows, xzero, rhs, ""), x.Type}
} else {
if x.kind == vkSigned {
rhs := b.impl.CreateSelect(overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl, "")
return Expr{b.impl.CreateAShr(x.impl, rhs, ""), x.Type}
} else {
rsh := b.impl.CreateLShr(x.impl, y.impl, "")
return Expr{b.impl.CreateSelect(overflows, xzero, rsh, ""), x.Type}
}
}
default:
llop := logicOpToLLVM[op-logicOpBase]
return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type}
} }
kind := x.kind
llop := logicOpToLLVM[op-logicOpBase]
if op == token.SHR && kind == vkUnsigned {
llop = llvm.LShr // Logical Shift Right
}
return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type}
case isPredOp(op): // op: == != < <= < >= case isPredOp(op): // op: == != < <= < >=
tret := b.Prog.Bool() tret := b.Prog.Bool()
kind := x.kind kind := x.kind
@@ -702,6 +723,7 @@ func (b Builder) IndexAddr(x, idx Expr) Expr {
if debugInstr { if debugInstr {
log.Printf("IndexAddr %v, %v\n", x.impl, idx.impl) log.Printf("IndexAddr %v, %v\n", x.impl, idx.impl)
} }
idx = b.checkIndex(idx)
prog := b.Prog prog := b.Prog
telem := prog.Index(x.Type) telem := prog.Index(x.Type)
pt := prog.Pointer(telem) pt := prog.Pointer(telem)
@@ -716,6 +738,30 @@ func (b Builder) IndexAddr(x, idx Expr) Expr {
return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, x.impl, indices), pt} return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, x.impl, indices), pt}
} }
func needsNegativeCheck(x Expr) bool {
if x.kind == vkSigned {
if rv := x.impl.IsAConstantInt(); !rv.IsNil() && rv.SExtValue() >= 0 {
return false
}
return true
}
return false
}
// check index >= 0 and size to uint
func (b Builder) checkIndex(idx Expr) Expr {
if needsNegativeCheck(idx) {
check := Expr{b.impl.CreateICmp(llvm.IntSLT, idx.impl, llvm.ConstInt(idx.ll, 0, false), ""), b.Prog.Bool()}
b.InlineCall(b.Func.Pkg.rtFunc("AssertIndexRange"), check)
}
typ := b.Prog.Uint()
if b.Prog.SizeOf(idx.Type) < b.Prog.SizeOf(typ) {
idx.Type = typ
idx.impl = castUintptr(b, idx.impl, typ)
}
return idx
}
// The Index instruction yields element Index of collection X, an array, // The Index instruction yields element Index of collection X, an array,
// string or type parameter containing an array, a string, a pointer to an, // string or type parameter containing an array, a string, a pointer to an,
// array or a slice. // array or a slice.
@@ -747,6 +793,7 @@ func (b Builder) Index(x, idx Expr, addr func(Expr) Expr) Expr {
b.Store(ptr, x) b.Store(ptr, x)
} }
} }
idx = b.checkIndex(idx)
pt := prog.Pointer(telem) pt := prog.Pointer(telem)
indices := []llvm.Value{idx.impl} indices := []llvm.Value{idx.impl}
buf := Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt} buf := Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt}
@@ -1038,7 +1085,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
case *types.Basic: case *types.Basic:
switch typ.Kind() { switch typ.Kind() {
case types.Uintptr: case types.Uintptr:
ret.impl = castInt(b.impl, x.impl, t.ll) ret.impl = castUintptr(b, x.impl, t)
return return
case types.UnsafePointer: case types.UnsafePointer:
ret.impl = castPtr(b.impl, x.impl, t.ll) ret.impl = castPtr(b.impl, x.impl, t.ll)
@@ -1046,19 +1093,10 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
} }
switch xtyp := x.RawType().Underlying().(type) { switch xtyp := x.RawType().Underlying().(type) {
case *types.Basic: case *types.Basic:
size := b.Prog.SizeOf(t)
xsize := b.Prog.SizeOf(x.Type)
if typ.Info()&types.IsInteger != 0 { if typ.Info()&types.IsInteger != 0 {
// int <- int/float // int <- int/float
if xtyp.Info()&types.IsInteger != 0 { if xtyp.Info()&types.IsInteger != 0 {
// if xsize > size { ret.impl = castInt(b, x.impl, t)
// ret.impl = b.impl.CreateTrunc(x.impl, t.ll, "")
// } else if typ.Info()&types.IsUnsigned != 0 {
// ret.impl = b.impl.CreateZExt(x.impl, t.ll, "")
// } else {
// ret.impl = b.impl.CreateSExt(x.impl, t.ll, "")
// }
ret.impl = castInt(b.impl, x.impl, t.ll)
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
if typ.Info()&types.IsUnsigned != 0 { if typ.Info()&types.IsUnsigned != 0 {
@@ -1078,11 +1116,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
} }
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
if xsize > size { ret.impl = castFloat(b, x.impl, t)
ret.impl = b.impl.CreateFPTrunc(x.impl, t.ll, "")
} else {
ret.impl = b.impl.CreateFPExt(x.impl, t.ll, "")
}
return return
} }
} }
@@ -1094,15 +1128,33 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
panic("todo") panic("todo")
} }
func castInt(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value { func castUintptr(b Builder, x llvm.Value, typ Type) llvm.Value {
xt := x.Type() if x.Type().TypeKind() == llvm.PointerTypeKind {
if xt.TypeKind() == llvm.PointerTypeKind { return llvm.CreatePtrToInt(b.impl, x, typ.ll)
return llvm.CreatePtrToInt(b, x, t)
} }
if xt.IntTypeWidth() <= t.IntTypeWidth() { return castInt(b, x, typ)
return llvm.CreateIntCast(b, x, t) }
func castInt(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size {
return b.impl.CreateTrunc(x, typ.ll, "")
} else if typ.kind == vkUnsigned {
return b.impl.CreateZExt(x, typ.ll, "")
} else {
return b.impl.CreateSExt(x, typ.ll, "")
}
}
func castFloat(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size {
return b.impl.CreateFPTrunc(x, typ.ll, "")
} else {
return b.impl.CreateFPExt(x, typ.ll, "")
} }
return llvm.CreateTrunc(b, x, t)
} }
func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value { func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
@@ -1224,12 +1276,12 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
conv := func(v llvm.Value) llvm.Value { conv := func(v llvm.Value) llvm.Value {
switch kind { switch kind {
case types.Float32: case types.Float32:
v = castInt(b.impl, v, b.Prog.tyInt32()) v = castInt(b, v, b.Prog.Int32())
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
case types.Float64: case types.Float64:
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
default: default:
v = castInt(b.impl, v, assertedTyp.ll) v = castInt(b, v, assertedTyp)
} }
return v return v
} }
@@ -1378,7 +1430,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl
return return
case vkString: case vkString:
etSize := b.Prog.SizeOf(b.Prog.Type(types.Typ[types.Byte], InGo)) etSize := b.Prog.SizeOf(b.Prog.Byte())
ret.Type = src.Type ret.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl
@@ -1386,6 +1438,50 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
} }
} }
} }
case "print", "println":
ln := fn == "println"
ret.Type = b.Prog.Void()
for i, arg := range args {
if ln && i > 0 {
b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" "))
}
var fn string
var typ Type
switch arg.kind {
case vkBool:
fn = "PrintBool"
case vkSigned:
fn = "PrintInt"
typ = b.Prog.Int64()
case vkUnsigned:
fn = "PrintUint"
typ = b.Prog.Uint64()
case vkFloat:
fn = "PrintFloat"
typ = b.Prog.Float64()
case vkSlice:
fn = "PrintSlice"
case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef:
fn = "PrintPointer"
typ = b.Prog.VoidPtr()
case vkString:
fn = "PrintString"
case vkInterface:
fn = "PrintIface"
// case vkComplex:
// fn = "PrintComplex"
default:
panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType()))
}
if typ != nil && typ != arg.Type {
arg = b.Convert(typ, arg)
}
b.InlineCall(b.Func.Pkg.rtFunc(fn), arg)
}
if ln {
b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str("\n"))
}
return
} }
panic("todo") panic("todo")
} }

View File

@@ -134,7 +134,13 @@ type aProgram struct {
stringTy Type stringTy Type
uintptrTy Type uintptrTy Type
intTy Type intTy Type
uintTy Type
f64Ty Type f64Ty Type
byteTy Type
i32Ty Type
u32Ty Type
i64Ty Type
u64Ty Type
pyObjPtr Type pyObjPtr Type
pyObjPPtr Type pyObjPPtr Type
@@ -351,6 +357,14 @@ func (p Program) Int() Type {
return p.intTy return p.intTy
} }
// Uint returns uint type.
func (p Program) Uint() Type {
if p.uintTy == nil {
p.uintTy = p.rawType(types.Typ[types.Uint])
}
return p.uintTy
}
// Uintptr returns uintptr type. // Uintptr returns uintptr type.
func (p Program) Uintptr() Type { func (p Program) Uintptr() Type {
if p.uintptrTy == nil { if p.uintptrTy == nil {
@@ -367,6 +381,46 @@ func (p Program) Float64() Type {
return p.f64Ty return p.f64Ty
} }
// Byte returns byte type.
func (p Program) Byte() Type {
if p.byteTy == nil {
p.byteTy = p.rawType(types.Typ[types.Byte])
}
return p.byteTy
}
// Int32 returns int32 type.
func (p Program) Int32() Type {
if p.i32Ty == nil {
p.i32Ty = p.rawType(types.Typ[types.Int32])
}
return p.i32Ty
}
// Uint32 returns uint32 type.
func (p Program) Uint32() Type {
if p.u32Ty == nil {
p.u32Ty = p.rawType(types.Typ[types.Uint32])
}
return p.u32Ty
}
// Int64 returns int64 type.
func (p Program) Int64() Type {
if p.i64Ty == nil {
p.i64Ty = p.rawType(types.Typ[types.Int64])
}
return p.i64Ty
}
// Uint64 returns uint64 type.
func (p Program) Uint64() Type {
if p.u64Ty == nil {
p.u64Ty = p.rawType(types.Typ[types.Uint64])
}
return p.u64Ty
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// A Package is a single analyzed Go package containing Members for // A Package is a single analyzed Go package containing Members for

View File

@@ -446,7 +446,7 @@ func TestUnOp(t *testing.T) {
b := fn.MakeBody(1) b := fn.MakeBody(1)
ptr := fn.Param(0) ptr := fn.Param(0)
val := b.UnOp(token.MUL, ptr) val := b.UnOp(token.MUL, ptr)
val2 := b.BinOp(token.SHR, val, prog.Val(1)) val2 := b.BinOp(token.XOR, val, prog.Val(1))
b.Store(ptr, val2) b.Store(ptr, val2)
b.Return(val2) b.Return(val2)
assertPkg(t, pkg, `; ModuleID = 'foo/bar' assertPkg(t, pkg, `; ModuleID = 'foo/bar'
@@ -455,9 +455,34 @@ source_filename = "foo/bar"
define i64 @fn(ptr %0) { define i64 @fn(ptr %0) {
_llgo_0: _llgo_0:
%1 = load i64, ptr %0, align 4 %1 = load i64, ptr %0, align 4
%2 = ashr i64 %1, 1 %2 = xor i64 %1, 1
store i64 %2, ptr %0, align 4 store i64 %2, ptr %0, align 4
ret i64 %2 ret i64 %2
} }
`) `)
} }
func TestBasicType(t *testing.T) {
type typeInfo struct {
typ Type
kind types.BasicKind
}
prog := NewProgram(nil)
infos := []*typeInfo{
{prog.Bool(), types.Bool},
{prog.Byte(), types.Byte},
{prog.Int(), types.Int},
{prog.Uint(), types.Uint},
{prog.Int32(), types.Int32},
{prog.Int64(), types.Int64},
{prog.Uint32(), types.Uint32},
{prog.Uint64(), types.Uint64},
{prog.Uintptr(), types.Uintptr},
{prog.VoidPtr(), types.UnsafePointer},
}
for _, info := range infos {
if info.typ.RawType() != types.Typ[info.kind] {
t.Fatal("bad type", info)
}
}
}

View File

@@ -47,6 +47,9 @@ const (
vkPyVarRef vkPyVarRef
vkTuple vkTuple
vkSlice vkSlice
vkArray
vkMap
vkInterface
vkPhisExpr = -1 vkPhisExpr = -1
) )
@@ -240,11 +243,11 @@ func (p Program) toType(raw types.Type) Type {
elem := p.rawType(t.Elem()) elem := p.rawType(t.Elem())
return &aType{llvm.PointerType(elem.ll, 0), typ, vkPtr} return &aType{llvm.PointerType(elem.ll, 0), typ, vkPtr}
case *types.Interface: case *types.Interface:
return &aType{p.rtIface(), typ, vkInvalid} return &aType{p.rtIface(), typ, vkInterface}
case *types.Slice: case *types.Slice:
return &aType{p.rtSlice(), typ, vkSlice} return &aType{p.rtSlice(), typ, vkSlice}
case *types.Map: case *types.Map:
return &aType{p.rtMap(), typ, vkInvalid} return &aType{p.rtMap(), typ, vkMap}
case *types.Struct: case *types.Struct:
ll, kind := p.toLLVMStruct(t) ll, kind := p.toLLVMStruct(t)
return &aType{ll, typ, kind} return &aType{ll, typ, kind}
@@ -254,7 +257,7 @@ func (p Program) toType(raw types.Type) Type {
return &aType{p.toLLVMFuncPtr(t), typ, vkFuncPtr} return &aType{p.toLLVMFuncPtr(t), typ, vkFuncPtr}
case *types.Array: case *types.Array:
elem := p.rawType(t.Elem()) elem := p.rawType(t.Elem())
return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid} return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkArray}
case *types.Chan: case *types.Chan:
} }
panic(fmt.Sprintf("toLLVMType: todo - %T\n", typ)) panic(fmt.Sprintf("toLLVMType: todo - %T\n", typ))

Binary file not shown.

View File

@@ -1,268 +0,0 @@
/*
* 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 llama2
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link"
)
type (
Char = c.Char
Int = c.Int
Uint = c.Uint
Float = c.Float
)
// -----------------------------------------------------------------------------
/*
typedef struct {
char *str;
int id;
} TokenIndex;
typedef struct {
char** vocab;
float* vocab_scores;
TokenIndex *sorted_vocab;
int vocab_size;
unsigned int max_token_length;
unsigned char byte_pieces[512]; // stores all single-byte strings
} Tokenizer;
void build_tokenizer(Tokenizer* t, char* tokenizer_path, int vocab_size);
void free_tokenizer(Tokenizer* t);
typedef struct {
int dim; // transformer dimension
int hidden_dim; // for ffn layers
int n_layers; // number of layers
int n_heads; // number of query heads
int n_kv_heads; // number of key/value heads (can be < query heads because of multiquery)
int vocab_size; // vocabulary size, usually 256 (byte-level)
int seq_len; // max sequence length
} Config;
typedef struct {
// token embedding table
float* token_embedding_table; // (vocab_size, dim)
// weights for rmsnorms
float* rms_att_weight; // (layer, dim) rmsnorm weights
float* rms_ffn_weight; // (layer, dim)
// weights for matmuls. note dim == n_heads * head_size
float* wq; // (layer, dim, n_heads * head_size)
float* wk; // (layer, dim, n_kv_heads * head_size)
float* wv; // (layer, dim, n_kv_heads * head_size)
float* wo; // (layer, n_heads * head_size, dim)
// weights for ffn
float* w1; // (layer, hidden_dim, dim)
float* w2; // (layer, dim, hidden_dim)
float* w3; // (layer, hidden_dim, dim)
// final rmsnorm
float* rms_final_weight; // (dim,)
// (optional) classifier weights for the logits, on the last layer
float* wcls;
} TransformerWeights;
typedef struct {
// current wave of activations
float *x; // activation at current time stamp (dim,)
float *xb; // same, but inside a residual branch (dim,)
float *xb2; // an additional buffer just for convenience (dim,)
float *hb; // buffer for hidden dimension in the ffn (hidden_dim,)
float *hb2; // buffer for hidden dimension in the ffn (hidden_dim,)
float *q; // query (dim,)
float *k; // key (dim,)
float *v; // value (dim,)
float *att; // buffer for scores/attention values (n_heads, seq_len)
float *logits; // output logits
// kv cache
float* key_cache; // (layer, seq_len, dim)
float* value_cache; // (layer, seq_len, dim)
} RunState;
typedef struct {
Config config; // the hyperparameters of the architecture (the blueprint)
TransformerWeights weights; // the weights of the model
RunState state; // buffers for the "wave" of activations in the forward pass
// some more state needed to properly clean up the memory mapping (sigh)
int fd; // file descriptor for memory mapping
float* data; // memory mapped data pointer
ssize_t file_size; // size of the checkpoint file in bytes
} Transformer;
void build_transformer(Transformer *t, char* checkpoint_path);
void free_transformer(Transformer* t);
typedef struct {
float prob;
int index;
} ProbIndex; // struct used when sorting probabilities during top-p sampling
typedef struct {
int vocab_size;
ProbIndex* probindex; // buffer used in top-p sampling
float temperature;
float topp;
unsigned long long rng_state;
} Sampler;
void build_sampler(Sampler* sampler, int vocab_size, float temperature, float topp, unsigned long long rng_seed);
void free_sampler(Sampler* sampler);
void generate(Transformer *transformer, Tokenizer *tokenizer, Sampler *sampler, char *prompt, int steps);
*/
// -----------------------------------------------------------------------------
// llgo:type C
type TokenIndex struct {
Str *Char
Id Int
}
// llgo:type C
type Tokenizer struct {
Vocab **Char
VocabScores *Float
SortedVocab *TokenIndex
VocabSize Int
MaxTokenLength Uint
BytePieces [512]uint8 // stores all single-byte strings
}
//go:linkname BuildTokenizer C.build_tokenizer
func BuildTokenizer(t *Tokenizer, tokenizerPath *Char, vocabSize Int)
//go:linkname FreeTokenizer C.free_tokenizer
func FreeTokenizer(t *Tokenizer)
// -----------------------------------------------------------------------------
// llgo:type C
type Config struct {
Dim Int // transformer dimension
HiddenDim Int // for ffn layers
NLayers Int // number of layers
NHeads Int // number of query heads
NKVHeads Int // number of key/value heads (can be < query heads because of multiquery)
VocabSize Int // vocabulary size, usually 256 (byte-level)
SeqLen Int // max sequence length
}
// llgo:type C
type TransformerWeights struct {
// token embedding table
TokenEmbeddingTable *Float // (vocab_size, dim)
// weights for rmsnorms
RmsAttWeight *Float // (layer, dim) rmsnorm weights
RmsFfnWeight *Float // (layer, dim)
// weights for matmuls. note dim == n_heads * head_size
Wq *Float // (layer, dim, n_heads * head_size)
Wk *Float // (layer, dim, n_kv_heads * head_size)
Wv *Float // (layer, dim, n_kv_heads * head_size)
Wo *Float // (layer, n_heads * head_size, dim)
// weights for ffn
W1 *Float // (layer, hidden_dim, dim)
W2 *Float // (layer, dim, hidden_dim)
W3 *Float // (layer, hidden_dim, dim)
// final rmsnorm
RmsFinalWeight *Float // (dim,)
// (optional) classifier weights for the logits, on the last layer
Wcls *Float
}
// llgo:type C
type RunState struct {
// current wave of activations
X *Float // activation at current time stamp (dim,)
Xb *Float // same, but inside a residual branch (dim,)
Xb2 *Float // an additional buffer just for convenience (dim,)
Hb *Float // buffer for hidden dimension in the ffn (hidden_dim,)
Hb2 *Float // buffer for hidden dimension in the ffn (hidden_dim,)
Q *Float // query (dim,)
K *Float // key (dim,)
V *Float // value (dim,)
Att *Float // buffer for scores/attention values (n_heads, seq_len)
Logits *Float // output logits
// kv cache
KeyCache *Float // (layer, seq_len, dim)
ValueCache *Float // (layer, seq_len, dim)
}
// llgo:type C
type Transformer struct {
Config Config // the hyperparameters of the architecture (the blueprint)
Weights TransformerWeights // the weights of the model
State RunState // buffers for the "wave" of activations in the forward pass
// some more state needed to properly clean up the memory mapping (sigh)
Fd Int // file descriptor for memory mapping
Data *Float // memory mapped data pointer
FileSize uintptr // size of the checkpoint file in bytes
}
//go:linkname BuildTransformer C.build_transformer
func BuildTransformer(t *Transformer, checkpointPath *Char)
//go:linkname FreeTransformer C.free_transformer
func FreeTransformer(t *Transformer)
// -----------------------------------------------------------------------------
// llgo:type C
type ProbIndex struct {
Prob Float
Index Int
} // struct used when sorting probabilities during top-p sampling
// llgo:type C
type Sampler struct {
VocabSize Int
Probindex *ProbIndex // buffer used in top-p sampling
Temperature Float
Topp Float
RngState uint64
}
//go:linkname BuildSampler C.build_sampler
func BuildSampler(sampler *Sampler, vocabSize Int, temperature Float, topp Float, rngSeed uint64)
//go:linkname FreeSampler C.free_sampler
func FreeSampler(sampler *Sampler)
// -----------------------------------------------------------------------------
//go:linkname Generate C.generate
func Generate(
transformer *Transformer, tokenizer *Tokenizer, sampler *Sampler,
prompt *Char, steps Int)
//go:linkname Chat C.chat
func Chat(
transformer *Transformer, tokenizer *Tokenizer, sampler *Sampler,
cliUserPrompt *Char, cliSystemPrompt *Char, steps Int)
// -----------------------------------------------------------------------------

Binary file not shown.