Commit Graph

105 Commits

Author SHA1 Message Date
Ayke van Laethem d27cfb1585 WIP shadow-stack based mark/sweep collector 2019-01-17 21:01:15 +01:00
Ayke van Laethem c840757352 compiler/interface: fix comparison with error value 2019-01-14 20:56:05 +01:00
Ron Evans b4dd2dbf60 docs: change links in README and remove old ReadTheDocs pages to point to TinyGo.org site
Signed-off-by: Ron Evans <ron@hybridgroup.com>
2019-01-13 20:29:45 +01:00
Ayke 107fccb288 all: add support for more architectures and GOOS/GOARCH (#118)
This commit does two things:

  * It adds support for the GOOS and GOARCH environment variables. They
    fall back to runtime.GO* only when not available.
  * It adds support for 3 new architectures: 386, arm, and arm64. For
    now, this is Linux-only.
2019-01-05 11:46:25 +01:00
Konstantin Yegupov f44dff6f59 compiler: allow slicing arrays of a named type 2019-01-04 15:55:57 +01:00
Ayke 873c1c3b4d Reduce code size for AVR (#116)
* all: add support for specifying target CPU in target config
* avr: specify the chip name in the target CPU

This reduces code size by a large margin. For examples/blinky, it
reduces code size from 1360 to 1266 when compiling for the Arduino Uno
(94 bytes, or ~7%).
2019-01-04 14:58:35 +01:00
Konstantin Yegupov a8dd82538e all: add flag to enable i64 parameters in WebAssembly 2019-01-03 18:09:33 +01:00
Ayke van Laethem 18b16fc151 compiler: run some optimizations after interface lowering
By running these interprocedural optimizations after interface lowering,
in particular the heap-to-stack transformation pass, interfaces can be
zero cost in some more cases.

For example, say you have the following interface:

    type Writer interface {
        Write([]byte) (int, error)
    }

and you do something with it:

    func foo(w io.Writer) {
        w.Write([]byte("foo"))
    }

this commit enables escape analysis across interface boundaries, which
means that the Write call does not cause an allocation if all
implementations of io.Writer do not let the slice escape. This enables
broader uses of interfaces, as they are now a zero-cost abstraction in
more cases.
2018-12-22 19:06:01 +01:00
Ayke van Laethem 5a15d4162d compiler: add optsize function attr to reduce binary size
This is also added by Clang at -Oz and results in slightly smaller
binaries.
2018-12-22 18:58:43 +01:00
Ron Evans cb648d8ae1 compiler: pass -cflags and -ldflags to tinygo CLI command
Signed-off-by: Ron Evans <ron@hybridgroup.com>
2018-12-13 20:10:27 +01:00
Ayke van Laethem 6cacafb8dc cgo: add package directory to header include paths 2018-12-10 15:38:03 +01:00
Ayke van Laethem dea660b21c main: compile C source files in packages
TODO: C++ etc. files
2018-12-10 15:38:01 +01:00
Ayke van Laethem e10d05c74f loader: switch to custom program loader 2018-12-10 15:36:23 +01:00
Ayke van Laethem 564b1b3312 compiler: always use fat function pointers with context
This reduces complexity in the compiler without affecting binary sizes
too much.

Cortex-M0:   no changes
Linux x64:   no changes
WebAssembly: some testcases (calls, coroutines, map) are slightly bigger
2018-12-09 18:47:39 +01:00
Ayke van Laethem 3fec22e819 compiler: avoid function pointers in defer calls
Implement defer in a different way, which results in smaller binaries.
The binary produced from testdata/calls.go (the only test case with
defer) is reduced a bit in size, but the savings in bytes greatly vary
by architecture:

Cortex-M0:    -96 .text / flash
WebAssembly: -215 entire file
Linux x64:    -32 .text

Deferred functions in TinyGo were implemented by creating a linked list
of struct objects that contain a function pointer to a thunk, a pointer
to the next object, and a list of parameters. When it was time to run
deferred functions, a helper runtime function called each function
pointer (the thunk) with the struct pointer as a parameter. This thunk
would then in turn extract the saved function parameter from the struct
and call the real function.

What this commit changes, is that the loop to call deferred functions is
moved into the end of the function (practically inlining it) and
replacing the thunks with direct calls inside this loop. This makes it
much easier for LLVM to perform all kinds of optimizations like inlining
and dead argument elimination.
2018-12-09 16:44:37 +01:00
Ayke van Laethem 23b283366d compiler: add header comment to defer.go 2018-12-01 22:43:01 +01:00
Ayke van Laethem 69fbfbddbb compiler: move defer code out of compiler.go
This puts all defer-related code into a single file, making it easier to
understand it.
2018-12-01 19:23:56 +01:00
Ayke van Laethem b78562f95c compiler: add names to some of the IR instructions
This makes debugging LLVM IR easier.
2018-12-01 18:36:05 +01:00
Ayke van Laethem e54a1c4dc0 compiler: disallow exporting functions that have their address taken
This simplifies the ABI a lot and makes future changes easier.
In the future, determining which functions need a context parameter
should be moved from IR generation into an optimization pass, avoiding
the need for recursively scanning the Go SSA.
2018-12-01 17:41:20 +01:00
Ayke van Laethem da0a02d128 compiler: return error messages with source location
Replace most errors returned by the compiler (using errors.New) with an
error type that includes the source location.
2018-12-01 17:41:15 +01:00
Ayke van Laethem b4c90f3677 compiler: lower interfaces in a separate pass
This commit changes many things:

  * Most interface-related operations are moved into an optimization
    pass for more modularity. IR construction creates pseudo-calls which
    are lowered in this pass.
  * Type codes are assigned in this interface lowering pass, after DCE.
  * Type codes are sorted by usage: types more often used in type
    asserts are assigned lower numbers to ease jump table construction
    during machine code generation.
  * Interface assertions are optimized: they are replaced by constant
    false, comparison against a constant, or a typeswitch with only
    concrete types in the general case.
  * Interface calls are replaced with unreachable, direct calls, or a
    concrete type switch with direct calls depending on the number of
    implementing types. This hopefully makes some interface patterns
    zero-cost.

These changes lead to a ~0.5K reduction in code size on Cortex-M for
testdata/interface.go. It appears that a major cause for this is the
replacement of function pointers with direct calls, which are far more
susceptible to optimization. Also, not having a fixed global array of
function pointers greatly helps dead code elimination.

This change also makes future optimizations easier, like optimizations
on interface value comparisons.
2018-12-01 13:26:06 +01:00
Ayke van Laethem f0fb1bd41a compiler: fix binops on named types in struct fields 2018-11-24 22:13:01 +01:00
Ayke van Laethem d887d645f7 arm: implement SVCall
The SVCall function call is lowered to an inline "svc" instruction. The
first parameter *must* be a constant number.
2018-11-21 17:06:56 +01:00
Ayke van Laethem 27fc397e21 arm: implement arm.ReadRegister
This pseudo-function reads the contents of the specified register, for
example "sp".
2018-11-18 18:40:36 +01:00
Ayke van Laethem 8cb7b583d8 compiler: support creating slices with uncommon initial len/cap types 2018-11-18 18:35:29 +01:00
Ayke van Laethem c220c140ef all: make garbage collector configurable 2018-11-17 15:14:05 +01:00
Ayke van Laethem 21db7e6099 main: move "tinygo" build tag to compiler
Replace "tgo" with "tinygo" and set it always (even with `tinygo run`).
2018-11-17 14:36:41 +01:00
Ayke van Laethem 100901574b compiler: let escape analysis look across bitcasts
This is necessary to avoid memory allocation in the math packages in
some functions.
2018-11-16 23:03:38 +01:00
Denys Smirnov 46755b774e compiler: fix another usage of the named type 2018-11-16 11:34:22 +01:00
Ayke van Laethem 1ed019771d compiler: set debug info when defining a function
Move attaching debug info to where the function is defined. As LLVM does
not allow setting debug info on declarations, this makes more sense and
is less error-prone.

This commit fixes debug info when using CGo.
2018-11-15 20:00:00 +01:00
Ayke van Laethem 668c1741c3 compiler: implement array equality
Implement binops == and != on array types.
2018-11-15 11:51:16 +01:00
Ayke van Laethem 6292a0fd2e compiler: fix bug in for range loop over a named map type 2018-11-14 15:43:50 +01:00
Ayke van Laethem 9bddaae04a compiler: support any int type in slice indexes
Make sure the compiler will correctly compile indexes of type uint64,
for example.
2018-11-14 14:41:40 +01:00
Ayke van Laethem ee7c276493 compiler: update integer type sizes
* Use 64-bit integers on 64-bit platforms, just like gc and gccgo:
  https://golang.org/doc/go1.1#int
* Do not use a separate length type. Instead, use uintptr everywhere a
  length is expected.
2018-11-14 14:01:04 +01:00
Ayke van Laethem 101d41dc58 compiler: pass i64 return value in an extra pointer param
To support the WebAssembly<->JS barrier, return values also have to be
passed in memory. i64 return values are used by syscall/js, so must be
supported across this ABI barrier.
2018-11-14 12:35:43 +01:00
Ayke van Laethem 26acc89f9c compiler: avoid load/store on zero-length data
These loads/stores probably would get optimized away anyway, but not
emitting them helps the init interpreter.
2018-11-09 15:48:47 +01:00
Ayke van Laethem 2ddb6f788a compiler: move interface-related stuff to a separate file
This makes it easier to get an overview of everything interface related,
because interfaces are quite complicated and were scattered through the
(huge!) compiler.go file.
2018-11-09 15:20:38 +01:00
Ayke van Laethem d1c0d6120a compiler: simplify runtime.interfaceMethod signature slightly
Code size is not affected, as dead arguments are eliminated anyway.
It makes future interface optimizations hopefully easier to implement.
2018-11-09 15:20:38 +01:00
Marc-Antoine Ruel b1cf69a523 compiler: implement binop string: <, <=, >, >=
Include unit tests.
2018-11-08 20:48:29 -05:00
Ayke van Laethem bb3d05169d interp: add new compile-time package initialization interpreter
This interpreter currently complements the Go SSA level interpreter. It
may stay complementary or may be the only interpreter in the future.

This interpreter is experimental and not yet finished (there are known
bugs!) so it is disabled by default. It can be enabled by passing the
-initinterp flag.

The goal is to be able to run all initializations at compile time except
for the ones having side effects. This mostly works except perhaps for a
few edge cases.

In the future, this interpeter may be used to actually run regular Go
code, perhaps in a shell.
2018-11-04 18:40:51 +01:00
Ayke van Laethem e930a1ead5 compiler: allow multiple basic blocks in package initializers
I don't know why they sometimes have them, but apparently some packages
do. Don't panic in that case, the interpreter will stop anyway on the
first branch.
2018-11-03 20:22:00 +01:00
Ayke van Laethem a531caa2e9 compiler: implement deferring of interface calls 2018-11-03 20:21:43 +01:00
Ayke van Laethem 8f8942d763 compiler: make all functions unnamed_addr
In Go, function pointers are not comparable. This means that the address
itself is not significant and functions can therefore be merged.

Add the unnamed_addr attribute to all functions to learn LLVM about this
fact. At the moment the mergefunc pass hasn't been enabled, but it
should be in the future to reduce code size.
2018-11-03 18:47:49 +01:00
Ayke van Laethem 60eefe1568 compiler: do not abort on verification failure 2018-11-03 18:24:57 +01:00
Ayke van Laethem e66d457c42 compiler: fix float <-> int conversions 2018-11-03 12:20:55 +01:00
Ayke van Laethem 8da1a5bc17 compiler: add comment to interface call signatures 2018-11-03 12:04:33 +01:00
Ayke van Laethem 2e22d53e5d compiler: work around i64 limitation in JavaScript
JavaScript does not support i64 directly, so make sure we pass a pointer
instead which can be read from JavaScript.

This is a temporary workaround which should be removed once JavaScript
supports some form of i64 (probably in the form of BigInt).
2018-11-03 12:03:49 +01:00
Ayke van Laethem d7844ce124 compiler, runtime: move defer notes to the runtime file
This seems like the more appropriate place to describe the
implementation of defer.
2018-11-01 11:42:04 +01:00
Ayke van Laethem c7cf6f0e82 docs: move calling convention documentation here 2018-11-01 11:41:24 +01:00
Ayke van Laethem 8a211d36aa compiler: only produce one bitcast from an alloca
This makes passes simpler, by being able to look at the (only) bitcast
from an alloca to know the expected type.
2018-10-30 20:10:29 +01:00