Граф коммитов

128 коммитов

Автор SHA1 Сообщение Дата
Ayke van Laethem
4acb1a5845 transform: update stringtobytes test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
e0f3333cc3 transform: update stringequal test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
af247e27ff transform: update stacksize test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
ec3a4da4df transform: update panic test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
905269bf11 transform: update maps test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
e4f29ae2f9 transform: update interrupt test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
7fb23824e2 transform: update interface test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
f8a6e662d8 transform: update gc-stackslots test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
0ddd65658e transform: update allocs test to opaque pointers
Also, rename most of the SSA values while we're at it.
2023-03-16 13:46:03 -07:00
Ayke van Laethem
db08b5aaa5 transform: update reflect-implements test to opaque pointers 2023-03-16 13:46:03 -07:00
Ayke van Laethem
71be24e4f9 transform: add debug information to internal/task.stackSize
This has two benefits:
 1. It attributes these bytes to the internal/task package (in
    -size=full), instead of (unknown).
 2. It makes it possible to print the stack sizes variable in GDB.

This is what it might look like in GDB:

    (gdb) p 'internal/task.stackSizes'
    $13 = {344, 120, 80, 2048, 360, 112, 80, 120, 2048, 2048}
2023-03-08 07:09:46 +01:00
Ayke van Laethem
517098c468 transform: fix non-determinism in the interface lowering pass
This non-determinism was introduced in
https://github.com/tinygo-org/tinygo/pull/2640. Non-determinism in the
compiler is a bug because it makes it harder to find whether a compiler
change actually affected the binary.

Fixes https://github.com/tinygo-org/tinygo/issues/3504
2023-03-02 18:47:09 +01:00
Ayke van Laethem
488174767b builder: remove non-ThinLTO build mode
All targets now support ThinLTO so let's remove the old unused code.
2023-02-26 19:22:10 +01:00
Ayke van Laethem
4e8453167f all: refactor reflect package
This is a big commit that changes the way runtime type information is stored in
the binary. Instead of compressing it and storing it in a number of sidetables,
it is stored similar to how the Go compiler toolchain stores it (but still more
compactly).

This has a number of advantages:

  * It is much easier to add new features to reflect support. They can simply
    be added to these structs without requiring massive changes (especially in
    the reflect lowering pass).
  * It removes the reflect lowering pass, which was a large amount of hard to
    understand and debug code.
  * The reflect lowering pass also required merging all LLVM IR into one
    module, which is terrible for performance especially when compiling large
    amounts of code. See issue 2870 for details.
  * It is (probably!) easier to reason about for the compiler.

The downside is that it increases code size a bit, especially when reflect is
involved. I hope to fix some of that in later patches.
2023-02-17 22:54:34 +01:00
Damian Gryski
f0a271bd21 transform: remove duplicate if in gc transform 2022-11-18 20:19:47 +01:00
Ayke van Laethem
4d14d3cd54 avr: support ThinLTO
ThinLTO results in a small code size reduction, which is nice
(especially on these very small chips). It also brings us one step
closer to using ThinLTO everywhere.
2022-11-18 18:40:38 +01:00
Ayke van Laethem
5c622cfc43 compiler: refactor some code for the next commit
This is a pure refactor, it doesn't change the behavior of anything.
It's separate from the next commit so that the actual changes are easier
to read.
2022-11-18 18:40:38 +01:00
Ayke van Laethem
268140ae40 wasm: remove -wasm-abi= flag
This flag controls whether to convert external i64 parameters for use in
a browser-like environment.

This flag was needed in the past because back then we only supported
wasm on browsers but no WASI. Now, I can't think of a reason why anybody
would want to change the default. For `-target=wasm` (used for
browser-like environments), the wasm_exec.js file expects this
i64-via-stack ABI. For WASI, there is no limitation on i64 values and
`-wasm-abi=generic` is the default.
2022-11-04 08:28:26 +01:00
Ayke van Laethem
2b7f562202 ci: add support for LLVM 15
This commit switches to LLVM 15 everywhere by default, while still
keeping LLVM 14 support.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
d435fc868b transform: fix memory corruption issues
There was a bug in the wasm ABI lowering pass (found using
AddressSanitizer on LLVM 15) that resulted in a rather subtle memory
corruption. This commit fixes this issues.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
62df1d7490 all: remove pointer ElementType calls
This is needed for opaque pointers, which are enabled by default in
LLVM 15.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
09ec846c9f all: replace llvm.Const* calls with builder.Create* calls
A number of llvm.Const* functions (in particular extractvalue and
insertvalue) were removed in LLVM 15, so we have to use a builder
instead. This builder will create the same constant values, it simply
uses a different API.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
f57cffce2d all: add type parameter to *GEP calls
This is necessary for LLVM 15.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
7b6a9fab42 all: add type parameter to CreateLoad
This is needed for LLVM 15.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
6bc6de8f82 all: add type parameter to CreateCall
This uses LLVMBuildCall2 in the background, which is the replacement for
the deprecated LLVMBuildCall function.
2022-10-19 22:23:19 +02:00
Ayke van Laethem
65d65c1313 wasm: fix GC scanning of allocas
Scanning of allocas was entirely broken on WebAssembly. The code
intended to do this was never run. There were also no tests.

Looking into this further, I found that it is actually not really
necessary to do that: the C stack can be scanned conservatively and in
fact this was already done for goroutine stacks (because they live on
the heap and are always referenced). It wasn't done for the system stack
however.

With these fixes, I believe code should be both faster *and* more
correct.

I found this in my work to get opaque pointers supported in LLVM 15,
because the code that was never reached now finally got run and was
actually quite buggy.
2022-10-19 18:36:53 +02:00
Ayke van Laethem
5f96d2b784 all: add flag for setting the goroutine stack size
This is helpful in some cases where the default stack size isn't big
enough.
2022-09-15 12:43:51 +02:00
Damian Gryski
f9ba99344a all: update _test.go files for ioutil changes 2022-08-07 10:32:23 +02:00
Ayke van Laethem
c7a23183e8 all: format code according to Go 1.19 rules
Go 1.19 started reformatting code in a way that makes it more obvious
how it will be rendered on pkg.go.dev. It gets it almost right, but not
entirely. Therefore, I had to modify some of the comments so that they
are formatted correctly.
2022-08-04 12:18:32 +02:00
José Carlos Chávez
a07287d3c6 fix: fixes tinygo test ./... syntax. 2022-06-11 12:11:08 +02:00
Nia Waldvogel
2c93a4085c transform (MakeGCStackSlots): do not move the stack chain pop earlier
Previously, the MakeGCStackSlots pass would attempt to pop the stack chain before a tail call.
This resulted in use-after-free bugs when the tail call allocated memory and used a value allocated by its caller.
Instead of trying to move the stack chain pop, remove the tail flag from the call.
2022-06-10 17:25:02 +02:00
Ayke van Laethem
2d61972475 gc: drop support for 'precise' globals
Precise globals require a whole program optimization pass that is hard
to support when building packages separately. This patch removes support
for these globals by converting the last use (Linux) to use
linker-defined symbols instead.

For details, see: https://github.com/tinygo-org/tinygo/issues/2870
2022-06-01 21:21:30 +02:00
Ayke van Laethem
97842b367c transform: run OptimizeMaps during package optimizations
This shrinks transform.Optimize() a little bit, working towards the goal
of https://github.com/tinygo-org/tinygo/issues/2870. I ran the smoke
tests and there is no practical downside: one test got smaller (??) and
one had a different .hex hash, but other than that there was no
difference.

This should also make TinyGo a liiitle bit faster but it's probably not
even measurable.
2022-05-30 20:39:42 +02:00
Ayke van Laethem
9246899b30 builder: move some code to transform package
The transform package is the more appropriate location for package-level
optimizations, to match `transform.Optimize` for whole-program
optimizations.
This is just a refactor, to make later changes easier to read.
2022-05-30 20:39:42 +02:00
Ayke van Laethem
777d3f3ea5 builder: free LLVM objects after use
This reduces the TinyGo memory consumption when running

  make tinygo-test

from 5.8GB to around 2GB on my laptop.
2022-05-30 07:53:28 +02:00
Ayke van Laethem
5c23f6fb6c all: remove support for LLVM 11 and LLVM 12
This removes a lot of backwards compatibility cruft and makes it
possible to start using features that need LLVM 13 or newer.
For example:

  * https://github.com/tinygo-org/tinygo/pull/2637
  * https://github.com/tinygo-org/tinygo/pull/2830
2022-05-07 17:15:35 +02:00
Ayke van Laethem
ef3b3c0d6a transform: fix poison value in heap-to-stack transform
In https://github.com/tinygo-org/tinygo/issues/2777, a poison value
ended up in `runtime.alloc`. This shouldn't happen, especially not for
well written code. So I'm not sure why it happens. But here is a fix
anyway.
2022-04-15 22:54:25 +02:00
Ayke van Laethem
c0d257d682 compiler: fix difference in aliases in interface methods
There used to be a difference between `byte` and `uint8` in interface
methods. These are aliases, so they should be treated the same.
This patch introduces a custom serialization format for types,
circumventing the `Type.String()` method that is slightly wrong for our
purposes.

This also fixes an issue with the `any` keyword in Go 1.18, which
suffers from the same problem (but this time actually leads to a crash).
2022-04-07 12:54:17 +02:00
Ayke van Laethem
603fff78d4 all: add support for ThinLTO
ThinLTO optimizes across LLVM modules at link time. This means that
optimizations (such as inlining and const-propagation) are possible
between C and Go. This makes this change especially useful for CGo, but
not just for CGo. By doing some optimizations at link time, the linker
can discard some unused functions and this leads to a size reduction on
average. It does increase code size in some cases, but that's true for
most optimizations.

I've excluded a number of targets for now (wasm, avr, xtensa, windows,
macos). They can probably be supported with some more work, but that
should be done in separate PRs.

Overall, this change results in an average 3.24% size reduction over all
the tinygo.org/x/drivers smoke tests.

TODO: this commit runs part of the pass pipeline twice. We should set
the PrepareForThinLTO flag in the PassManagerBuilder for even further
reduced code size (0.7%) and improved compilation speed.
2022-03-12 12:55:38 +01:00
Damian Gryski
4b2edc9a26 compiler: move allocations > 256 bytes to the heap 2022-02-11 19:46:37 +01:00
Nia Waldvogel
c6ae1c58fc compiler: remove parentHandle from calling convention
This removes the parentHandle argument from the internal calling convention.
It was formerly used to implment coroutines.
Now that coroutines have been removed, it is no longer necessary.
2022-01-19 14:42:02 -05:00
Nia Waldvogel
0c2fefa09b transform: remove switched func lowering
The switched func lowering was mainly necessary for coroutines.
With coroutines removed, this is no longer necessary.
2022-01-19 14:42:02 -05:00
Nia Waldvogel
ea2a6b70b2 internal/task: remove coroutines 2022-01-19 14:42:02 -05:00
Ayke van Laethem
ebd4969cde all: switch to LLVM 13
This adds support for building with `-tags=llvm13` and switches to LLVM
13 for tinygo binaries that are statically linked against LLVM.

Some notes on this commit:

  * Added `-mfloat-abi=soft` to all Cortex-M targets because otherwise
    nrfx would complain that floating point was enabled on Cortex-M0.
    That's not the case, but with `-mfloat-abi=soft` the `__SOFTFP__`
    macro is defined which silences this warning.
    See: https://reviews.llvm.org/D100372
  * Changed from `--sysroot=<root>` to `-nostdlib -isystem <root>` for
    musl because with Clang 13, even with `--sysroot` some system
    libraries are used which we don't want.
  * Changed all `-Xclang -internal-isystem -Xclang` to simply
    `-isystem`, for consistency with the above change. It appears to
    have the same effect.
  * Moved WebAssembly function declarations to the top of the file in
    task_asyncify_wasm.S because (apparently) the assembler has become
    more strict.
2022-01-09 11:04:10 +01:00
Ayke van Laethem
ef8c1a187d transform: allocate the correct amount of bytes in an alloca
When I wrote the code originally, I didn't know about SetAlignment so I
hacked a way around it by allocating [...]uintptr types. However, this
allocates a few too many bytes in some cases.
This commit changes this to only allocate the space that we actually
need.

The code size effect is mixed, but generally positive. The combined
average is reduced by 0.27% with more programs being reduced in size
than are increasing in size.
2021-12-10 10:48:24 +01:00
Ayke van Laethem
5127b9d65b all: add LLVM 12 support
Originally based on a PR by @QuLogic, but extended a lot to get all
tests to pass.
2021-11-30 21:53:16 +01:00
Nia Waldvogel
641dcd7c16 internal/task: use asyncify on webassembly
This change implements a new "scheduler" for WebAssembly using binaryen's asyncify transform.
This is more reliable than the current "coroutines" transform, and works with non-Go code in the call stack.

runtime (js/wasm): handle scheduler nesting

If WASM calls into JS which calls back into WASM, it is possible for the scheduler to nest.
The event from the callback must be handled immediately, so the task cannot simply be deferred to the outer scheduler.
This creates a minimal scheduler loop which is used to handle such nesting.
2021-11-14 10:49:28 +01:00
Ayke van Laethem
cf640290a3 compiler: add "target-cpu" and "target-features" attributes
This matches Clang, and with that, it adds support for inlining between
Go and C because LLVM only allows inlining if the "target-cpu" and
"target-features" string attributes match.

For example, take a look at the following code:

    // int add(int a, int b) {
    //   return a + b;
    // }
    import "C"

    func main() {
        println(C.add(3, 5))
    }

The 'add' function is not inlined into the main function before this
commit, but after it, it can be inlined and trivially be optimized to
`println(8)`.
2021-11-10 11:16:13 +01:00
Ayke van Laethem
7caf0732fa transform: add debug info in interface lowering pass
This is fake debug info. It doesn't point to a source location because
there is no source location. However, it helps to correctly attribute
code size usage to particular packages.

I've also updated builder/sizes.go with some debugging helpers.
2021-11-06 10:50:55 +01:00
Ayke van Laethem
edcece33ca transform: refactor interrupt lowering
Instead of doing everything in the interrupt lowering pass, generate
some more code in gen-device to declare interrupt handler functions and
do some work in the compiler so that interrupt lowering becomes a lot
simpler.

This has several benefits:

  - Overall code is smaller, in particular the interrupt lowering pass.
  - The code should be a bit less "magical" and instead a bit easier to
    read. In particular, instead of having a magic
    runtime.callInterruptHandler (that is fully written by the interrupt
    lowering pass), the runtime calls a generated function like
    device/sifive.InterruptHandler where this switch already exists in
    code.
  - Debug information is improved. This can be helpful during actual
    debugging but is also useful for other uses of DWARF debug
    information.

For an example on debug information improvement, this is what a
backtrace might look like before this commit:

    Breakpoint 1, 0x00000b46 in UART0_IRQHandler ()
    (gdb) bt
    #0  0x00000b46 in UART0_IRQHandler ()
    #1  <signal handler called>
    [..etc]

Notice that the debugger doesn't see the source code location where it
has stopped.

After this commit, breaking at the same line might look like this:

    Breakpoint 1, (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    200			uart.Receive(byte(nrf.UART0.RXD.Get()))
    (gdb) bt
    #0  (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    #1  UART0_IRQHandler () at /home/ayke/src/github.com/tinygo-org/tinygo/src/device/nrf/nrf51.go:176
    #2  <signal handler called>
    [..etc]

By now, the debugger sees an actual source location for UART0_IRQHandler
(in the generated file) and an inlined function.
2021-11-06 09:40:15 +01:00