29 Commits

Author SHA1 Message Date
Jaden Weiss 9890c760cf transform (func-lowering): remove specializations from function value lowering and fix lowering of a function value of an unimplemented type
Previously, the function value lowering pass had special cases for when there were 0 or 1 function implementations.
However, the results of the pass were incorrect in both of these cases.
This change removes the specializations and fixes the transformation.

In the case that there was a single function implementation, the compiler emitted a select instruction to obtain the function pointer.
This selected between null and the implementing function pointer.
While this was technically correct, it failed to eliminate indirect function calls.
This prevented discovery of these calls by the coroutine lowering pass, and caused async function calls to be passed through unlowered.
As a result, the generated code had undefined behavior (usually resulting in a segfault).

In the case of no function implementations, the lowering code was correct.
However, the lowering code was not run.
The discovery of function signatures was accomplished by scanning implementations, and when there were no implementations nothing was discovered or lowered.

For maintainability reasons, I have removed both specializations rather than fixing them.
This substantially simplifies the code, and reduces the amount of variation that we need to worry about for testing purposes.
The IR now generated in the cases of 0 or 1 function implementations can be efficiently simplified by LLVM's optimization passes.
Therefore, there should not be a substantial regression in terms of performance or machine code size.
2020-04-12 22:43:43 +02:00
Jaden Weiss bb5f7534e5 transform (coroutines): remove map iteration from coroutine lowering pass
The coroutine lowering pass had issues where it iterated over maps, sometimes resulting in non-deterministic output.
This change removes many of the maps and ensures that the transformations are deterministic.
2020-04-12 16:54:40 +02:00
Ayke van Laethem 0afd42c439 main: switch to LLVM 10
This commit also adds a bit of version independence, in particular for
external commands. It also adds the LLVM version to the `tinygo version`
command, which might help while debugging.
2020-04-09 20:23:51 +02:00
Ayke van Laethem 584e94ce2f transform: allow updating tests with -update flag
This should make it much easier to update existing tests.
2020-04-09 20:23:51 +02:00
Jaden Weiss ae16b2c922 transform (gc): track phi nodes in stack slots 2020-04-02 15:06:58 +02:00
Jaden Weiss 62e78c0a26 runtime (gc): add garbage collector that uses an external allocator 2020-03-30 14:35:29 +02:00
Ayke van Laethem f8876ea245 compiler, transform: remove runtime.isnil hack
This hack was originally introduced in
https://github.com/tinygo-org/tinygo/pull/251 to fix an escape analysis
regression after https://github.com/tinygo-org/tinygo/pull/222
introduced nil checks. Since a new optimization in LLVM (see
https://reviews.llvm.org/D60047) this hack is not necessary anymore and
can be removed.

I've compared all regular tests and smoke tests before and after to
check the size. In most cases this change was an improvement although
there are a few regressions.
2020-03-27 07:38:16 +01:00
Ayke van Laethem 3b1759f463 transform: fix error in interface lowering pass
It appears that LLVM can sometimes recognize that multiple calls to
runtime.interfaceMethod can be merged into one. When that happens, the
interface lowering pass shows an error as it didn't expect that
situation.

Luckily the fix is very easy.
2020-03-25 16:28:38 +01:00
Ayke van Laethem 26aba72729 transform: replace panics with source locations
Panics are bad for usability: whenever something breaks, the user is
shown a (not very informative) backtrace. Replace it with real error
messages instead, that even try to display the Go source location.
2020-03-24 15:07:55 +01:00
Ayke van Laethem 9d3de55229 compiler: move Optimizer function to transform package
This refactor is a prerequisite to much larger refactors in the
compiler.
2020-03-21 15:45:25 +01:00
Ayke van Laethem c5cb2cec9b compiler: move NonConstGlobals pass to transform package 2020-03-19 19:56:08 +01:00
Ayke van Laethem b6314fa6ab compiler: move ApplyFunctionSections to transform package 2020-03-19 19:56:08 +01:00
Jaden Weiss 6a50f25a48 refactor coroutine lowering and tasks 2020-03-17 12:16:10 +01:00
Jaden Weiss 67229af879 transform: do not track const globals 2020-02-24 21:04:50 +01:00
Ayke van Laethem 519adf3aef transform: wasm-abi: create temporary allocas in the entry block
This avoids problems with goroutines in WebAssembly, and is generally a
good thing. It fixes some cases of the following problem:

    LLVM ERROR: Coroutines cannot handle non static allocas yet
2020-01-28 19:29:09 +01:00
Ayke van Laethem 4d79d473c4 compiler: move wasm ABI workaround to transform package
By considering this as a regular transformation, it can be easily
tested.
2020-01-28 19:29:09 +01:00
Ayke van Laethem 415c60551e runtime/fe310: add support for PLIC interrupts
This commit adds support for software vectoring in the PLIC interrupt.
The interrupt table is created by the compiler, which leads to very
compact code while retaining the flexibility that the interrupt API
provides.
2020-01-27 19:58:39 +01:00
Ayke van Laethem a5ed993f8d all: add compiler support for interrupts
This commit lets the compiler know about interrupts and allows
optimizations to be performed based on that: interrupts are eliminated
when they appear to be unused in a program. This is done with a new
pseudo-call (runtime/interrupt.New) that is treated specially by the
compiler.
2020-01-20 21:19:12 +01:00
Ayke van Laethem 5a70c88483 transform: make reflection sidetables constant globals
These globals are (and must be!) never modified by the reflect package.
By marking them as constant, they will be put in read-only memory. This
reduces RAM consumption on microcontrollers.
2019-12-21 22:59:23 +01:00
Ayke van Laethem 374349cfa5 compiler: refactor func lowering to the transform package
This commit makes a number of changes:

  * It avoids a dependency on Compiler.emitStartGoroutine.
  * It moves the func-lowering pass to the transform package.
  * It adds testing to func lowering.

No functionality should have changed with this commit.
2019-12-04 22:19:49 +01:00
Ayke van Laethem f0bb3c092d compiler: move GC passes to the transform package 2019-11-25 09:14:31 +01:00
Jaden Weiss 98eee7c22a compiler: add support for async interface calls 2019-11-17 23:46:10 +01:00
Ayke van Laethem 172efc26a7 compiler: move ReplacePanicsWithTrap pass to transforms
This moves the transformation pass to the right location, and adds tests
to see that it actually works correctly.
2019-11-16 18:41:28 +01:00
Ayke van Laethem e20af665fa compiler,transform: move interface lowering to transform package 2019-11-15 23:37:17 +01:00
Jaden Weiss 93961f9d41 fix incorrect starting value for optimized allocations in a loop 2019-11-13 16:45:09 +01:00
Ayke van Laethem 7369a0e7f2 all: add support for Windows 2019-10-17 00:14:59 +02:00
Ayke van Laethem 65beddafe8 compiler: move OptimizeStringToBytes to transform package
Unfortunately, while doing this I found that it doesn't actually apply
in any real-world programs (tested with `make smoketest`), apparently
because nil pointer checking messes with the functionattrs pass. I hope
to fix that after moving to LLVM 9, which has an optimization that makes
nil pointer checking easier to implement.
2019-09-22 08:25:50 +02:00
Ayke van Laethem 8cd2c7502e all: move OptimizeMaps to transforms and add tests 2019-09-15 21:26:27 +02:00
Ayke van Laethem d905476231 all: refactor heap-to-stack transform into the transform package
Also add unit tests.

This is the first of several transformation (optimization/lowering)
passes that I'd like to move to the new transform package. This
separates the compiler from the optimizer.

Also, it finally adds unit tests for the compiler, not just end-to-end
compilation tests. This should improve robustness and should make it
easier to change these transformation passes in the future.
While the heap-to-stack transform is relatively simple, other passes are
much more complex. Adding unit tests not only helps robustness over
time, but also doubles as documentation as to what these transformation
passes do exactly.
2019-09-15 21:26:27 +02:00