diff --git a/README.md b/README.md index 14dc9c07ea..62bcffb756 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -llgo - A Go compiler based on LLVM +LLGo - A Go compiler based on LLVM ===== [![Build Status](https://github.com/xgo-dev/llgo/actions/workflows/go.yml/badge.svg)](https://github.com/xgo-dev/llgo/actions/workflows/go.yml) @@ -7,7 +7,7 @@ llgo - A Go compiler based on LLVM [![GoDoc](https://pkg.go.dev/badge/github.com/xgo-dev/llgo.svg)](https://pkg.go.dev/github.com/xgo-dev/llgo) [![XGo](https://img.shields.io/badge/project-XGo-blue.svg)](https://github.com/goplus/xgo) -LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python and JavaScript. It's a subproject of [the XGo project](https://github.com/goplus/gop). +LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem, including Python and JavaScript. It's a subproject of [the XGo project](https://github.com/goplus/gop). LLGo aims to expand the boundaries of Go/XGo, providing limitless possibilities such as: @@ -23,10 +23,25 @@ How can these be achieved? LLGo := Go * C ecosystem ``` -LLGo is compatible with C ecosystem through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**. C ecosystem includes all languages that are ABI compatible with C (eg. C/C++, Python, JavaScript, Objective-C, Swift, etc). +LLGo is compatible with the C ecosystem through the C **Application Binary Interface (ABI)**, while LLGo is compatible with Go at the **source-code level**. The C ecosystem includes languages that expose C-compatible interfaces (e.g. C/C++, Python, JavaScript, Objective-C, and Swift). -## C/C++ standard libary support +## Project status + +LLGo is compatible with Go 1.20+ source code and supports the complete Go 1.26 language syntax. Compatibility is checked against applicable upstream [`GOROOT/test`](test/goroot/README.md) cases using pinned Go 1.24 and Go 1.26 toolchains. Remaining applicable differences are recorded in [`xfail.yaml`](test/goroot/xfail.yaml); gc-specific mechanisms outside LLGo's compatibility goals are documented in [`notapplicable.yaml`](test/goroot/notapplicable.yaml). + +LLGo fully supports the Go standard library on supported native platforms; see [Go standard library support](#go-standard-library-support) for validation and target-specific details. + +LLGo uses a different runtime from the standard Go toolchain. Native goroutines map 1:1 to OS threads with fixed native stacks, so direct C calls require no Go-to-C stack or scheduler transition, avoiding the cgo overhead that makes frequent C calls costly in standard Go. The default garbage collector is conservative BDWGC. + +| Target | Current coverage | +| --- | --- | +| Native | Linux amd64/arm64 and macOS amd64/arm64 [release artifacts](https://github.com/xgo-dev/llgo/releases); primary CI on Linux amd64 and macOS arm64 | +| WebAssembly | `js/wasm` and `wasip1/wasm` builds; WASI and Emscripten CI coverage | +| Embedded | [`-target`](doc/Embedded_Cmd.md) configurations for supported boards and MCUs, with selected QEMU/emulator smoke tests | + + +## C/C++ standard library support You can import a C/C++ standard library in LLGo! @@ -60,7 +75,7 @@ func main() { This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by `llgo` for generating a C string constant. -The `_demo` directory contains some C standard libary related demos (it start with `_` to prevent the `go` command from compiling it): +The `_demo` directory contains C library demos (it starts with `_` to prevent the `go` command from compiling it): * [hello](_demo/c/hello/hello.go): call C `printf` to print `Hello world` * [concat](_demo/c/concat/concat.go): call C `fprintf` with `stderr` @@ -76,7 +91,7 @@ llgo run . ## How to support C/C++ and Python -LLGo use `go:linkname` to link an extern symbol througth its ABI: +LLGo uses `go:linkname` to link an external symbol through the C ABI: @@ -123,7 +138,7 @@ func main() { You can import a Python library in LLGo! -And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The following libraries have been included in `llgo`: +You can import Python libraries into `llgo` through `llpyg` (see [Development tools](#development-tools)). Available bindings include: * [py](https://pkg.go.dev/github.com/goplus/lib/py) (abi) * [py/std](https://pkg.go.dev/github.com/goplus/lib/py/std) (builtins) @@ -138,7 +153,7 @@ And you can import any Python library into `llgo` through a program called `llpy * [py/torch](https://pkg.go.dev/github.com/goplus/lib/py/torch) * [py/matplotlib](https://pkg.go.dev/github.com/goplus/lib/py/matplotlib) -Note: For third-party libraries (such as pandas and pytorch), you still need to install the library files. +Third-party libraries such as pandas and PyTorch must be installed separately. Here is an example: @@ -220,9 +235,9 @@ llgo run . ## Other frequently used libraries -LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports. +LLGo can easily import libraries from the C ecosystem. C/C++ bindings are maintained manually, but the import process will be automated in the future, as with Python library imports. -The currently supported libraries include: +Available bindings include: * [c/bdwgc](https://pkg.go.dev/github.com/goplus/lib/c/bdwgc) * [c/cjson](https://pkg.go.dev/github.com/goplus/lib/c/cjson) @@ -241,7 +256,7 @@ The currently supported libraries include: Here are some examples related to them: -* [llama2-c](_demo/c/llama2-c): inference Llama 2 (It's the first llgo AI example) +* [llama2-c](_demo/c/llama2-c): inference Llama 2 (the first LLGo AI example) * [mkjson](https://github.com/goplus/lib/tree/main/c/cjson/_demo/mkjson/mkjson.go): create a json object and print it * [sqlitedemo](https://github.com/goplus/lib/tree/main/c/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo * [tetris](https://github.com/goplus/lib/tree/main/c/raylib/_demo/tetris/tetris.go): a tetris game based on raylib @@ -249,7 +264,7 @@ Here are some examples related to them: ## Go syntax support -All Go syntax (including `cgo`) is already supported. Here are some examples: +LLGo supports the complete Go 1.26 language syntax and `cgo`. Here are some examples: * [concat](_demo/c/concat/concat.go): define a variadic function * [genints](_demo/c/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function) @@ -258,101 +273,41 @@ All Go syntax (including `cgo`) is already supported. Here are some examples: * [goroutine](_demo/go/goroutine/goroutine.go): goroutine demo -### Defer - -LLGo now supports `defer` within loops, matching Go's semantics of executing defers in LIFO order for every iteration. The usual caveat from Go still applies: be mindful of loop-heavy defer usage because it allocates per iteration. - - ### Garbage Collection (GC) -By default, LLGo implements `gc` based on [bdwgc](https://www.hboehm.info/gc/) (also known as [libgc](https://www.hboehm.info/gc/)). +By default, LLGo implements garbage collection with [BDWGC](https://www.hboehm.info/gc/) (also known as libgc). Bare-metal embedded targets instead use a TinyGo-derived conservative mark-and-sweep collector. -However, you can disable gc by specifying the `nogc` tag. For example: +Garbage collection can be disabled with the `nogc` build tag. For example: ```sh llgo run -tags nogc . ``` -## Go packages support - -Here are the Go packages that can be imported correctly: - -* [unsafe](https://pkg.go.dev/unsafe) -* [unicode](https://pkg.go.dev/unicode) -* [unicode/utf8](https://pkg.go.dev/unicode/utf8) -* [unicode/utf16](https://pkg.go.dev/unicode/utf16) -* [math](https://pkg.go.dev/math) -* [math/big](https://pkg.go.dev/math/big) (partially) -* [math/bits](https://pkg.go.dev/math/bits) -* [math/cmplx](https://pkg.go.dev/math/cmplx) -* [math/rand](https://pkg.go.dev/math/rand) -* [net/url](https://pkg.go.dev/net/url) -* [errors](https://pkg.go.dev/errors) -* [context](https://pkg.go.dev/context) -* [io](https://pkg.go.dev/io) -* [io/fs](https://pkg.go.dev/io/fs) -* [io/ioutil](https://pkg.go.dev/io/ioutil) -* [log](https://pkg.go.dev/log) -* [flag](https://pkg.go.dev/flag) -* [sort](https://pkg.go.dev/sort) -* [bytes](https://pkg.go.dev/bytes) -* [bufio](https://pkg.go.dev/bufio) -* [strings](https://pkg.go.dev/strings) -* [strconv](https://pkg.go.dev/strconv) -* [path](https://pkg.go.dev/path) -* [path/filepath](https://pkg.go.dev/path/filepath) -* [sync/atomic](https://pkg.go.dev/sync/atomic) -* [sync](https://pkg.go.dev/sync) (partially) -* [syscall](https://pkg.go.dev/syscall) (partially) -* [runtime](https://pkg.go.dev/runtime) (partially) -* [os](https://pkg.go.dev/os) (partially) -* [os/exec](https://pkg.go.dev/os/exec) (partially) -* [fmt](https://pkg.go.dev/fmt) (partially) -* [reflect](https://pkg.go.dev/reflect) (partially) -* [time](https://pkg.go.dev/time) (partially) -* [encoding](https://pkg.go.dev/encoding) -* [encoding/binary](https://pkg.go.dev/encoding/binary) -* [encoding/hex](https://pkg.go.dev/encoding/hex) -* [encoding/base32](https://pkg.go.dev/encoding/base32) -* [encoding/base64](https://pkg.go.dev/encoding/base64) -* [encoding/csv](https://pkg.go.dev/encoding/csv) -* [net/textproto](https://pkg.go.dev/net/textproto) -* [hash](https://pkg.go.dev/hash) -* [hash/adler32](https://pkg.go.dev/hash/adler32) -* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially) -* [hash/crc64](https://pkg.go.dev/hash/crc64) -* [hash/maphash](https://pkg.go.dev/hash/maphash) (partially) -* [crypto](https://pkg.go.dev/crypto) -* [crypto/md5](https://pkg.go.dev/crypto/md5) -* [crypto/sha1](https://pkg.go.dev/crypto/sha1) -* [crypto/sha256](https://pkg.go.dev/crypto/sha256) -* [crypto/sha512](https://pkg.go.dev/crypto/sha512) (partially) -* [crypto/hmac](https://pkg.go.dev/crypto/hmac) (partially) -* [crypto/rand](https://pkg.go.dev/crypto/rand) (partially) -* [crypto/subtle](https://pkg.go.dev/crypto/subtle) (partially) -* [regexp](https://pkg.go.dev/regexp) -* [regexp/syntax](https://pkg.go.dev/regexp/syntax) -* [go/token](https://pkg.go.dev/go/token) -* [go/scanner](https://pkg.go.dev/go/scanner) -* [go/parser](https://pkg.go.dev/go/parser) +## Go standard library support + +LLGo fully supports the Go standard library on supported native platforms. CI requires compatibility coverage for every public package and exported symbol in the primary Go toolchain, and runs [`test/std`](test/std/README.md) with both supported toolchains. + +Other targets may not provide every OS service or implementation-specific runtime behavior. ## Dependencies -- [Go 1.21+](https://go.dev) -- [LLVM 18](https://llvm.org) -- [Clang 18](https://clang.llvm.org) -- [LLD 18](https://lld.llvm.org) +- [Go 1.24+](https://go.dev) (to build LLGo; CI also validates user packages with pinned Go 1.24 and Go 1.26 toolchains) +- [LLVM 19](https://llvm.org) +- [Clang 19](https://clang.llvm.org) +- [LLD 19](https://lld.llvm.org) - [pkg-config 0.29+](https://gitlab.freedesktop.org/pkg-config/pkg-config) - [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/) +- [libffi](https://sourceware.org/libffi/) +- [libuv](https://libuv.org/) - [OpenSSL 3.0+](https://www.openssl.org/) - [zlib 1.2+](https://github.com/madler/zlib) - [Python 3.12+](https://www.python.org) (optional, for [github.com/goplus/lib/py](https://pkg.go.dev/github.com/goplus/lib/py)) ## How to install -Follow these steps to generate the `llgo` command (its usage is the same as the `go` command): +Follow these steps to install the `llgo` command, whose usage is similar to the `go` command: ### on macOS @@ -419,7 +374,7 @@ cd llgo ## Development tools -* [pydump](_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`. +* [pydump](_xtool/pydump): It is the first production program compiled with `llgo` rather than `go`. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`. * [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it. * [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task. * [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll). @@ -449,6 +404,6 @@ go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch Below are the key modules for understanding the implementation principles of `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`. +* [ssa](https://pkg.go.dev/github.com/goplus/llgo/ssa): It generates LLVM IR files (LLVM SSA) using the semantics and 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 and abstracts over 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 limited to the `llgo` compiler. If we view it as providing the high-level expressive power of `LLVM`, it is very useful. Its advanced SSA form lets clients use LLVM without operating directly on machine-code semantics. * [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`. * [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`.