aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/func.go
AgeCommit message (Collapse)Author
2023-10-01all: remove LLVM 14 supportAyke van Laethem
This is a big change: apart from removing LLVM 14 it also removes typed pointer support (which was only fully supported in LLVM up to version 14). This removes about 200 lines of code, but more importantly removes a ton of special cases for LLVM 14.
2023-03-21compiler: correctly generate code for local named typesAyke van Laethem
It is possible to create function-local named types: func foo() any { type named int return named(0) } This patch makes sure they don't alias with named types declared at the package scope. Bug originally found by Damian Gryski while working on reflect support.
2023-03-05compiler; add position information to createConstantAyke van Laethem
Non-functional change. The position information will be used later to emit debug info locations to string constants.
2022-10-19ci: add support for LLVM 15Ayke van Laethem
This commit switches to LLVM 15 everywhere by default, while still keeping LLVM 14 support.
2022-10-19all: remove pointer ElementType callsAyke van Laethem
This is needed for opaque pointers, which are enabled by default in LLVM 15.
2022-10-19all: add type parameter to CreateCallAyke van Laethem
This uses LLVMBuildCall2 in the background, which is the replacement for the deprecated LLVMBuildCall function.
2022-10-19compiler: return a FunctionType (not a PointerType) in getRawFuncTypeAyke van Laethem
This is necessary for opaque pointer support (in LLVM 15).
2022-01-19compiler: remove parentHandle from calling conventionNia Waldvogel
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-19transform: remove switched func loweringNia Waldvogel
The switched func lowering was mainly necessary for coroutines. With coroutines removed, this is no longer necessary.
2021-11-06transform: refactor interrupt loweringAyke van Laethem
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-10-30compiler: add support for recursive function typesAyke van Laethem
This adds support for a construct like this: type foo func(fn foo) Unfortunately, LLVM cannot create function pointers that look like this. LLVM only supports named types for structs (not for pointers) and thus can't add a pointer to a function type of the same type to a parameter of that function type. The fix is simple: cast all function pointers to a void function, in LLVM IR: void ()* Raw function pointers are cast to this type before storing, and cast back to the regular function type before calling. This means that function parameters will never refer to its own type because raw function types are fixed at that one type. Somehow, this does have an effect on binary size in some cases. The effect is small and goes both ways. On top of that, there is work underway in LLVM which would make all pointer types opaque (without a pointee type). This would make this whole commit useless and therefore should fix any size increases that might happen. https://llvm.org/docs/OpaquePointers.html
2021-04-12compiler: decouple func lowering from interface type codesAyke van Laethem
There is no good reason for func values to refer to interface type codes. The only thing they need is a stable identifier for function signatures, which is easily created as a new kind of globals. Decoupling makes it easier to change interface related code.
2021-03-29compiler: fix "fragment covers entire variable" bugAyke van Laethem
This bug could sometimes be triggered by syscall/js code it seems. But it's a generic bug, not specific to WebAssembly.
2021-03-21builder, compiler: compile and cache packages in parallelAyke van Laethem
This commit switches from the previous behavior of compiling the whole program at once, to compiling every package in parallel and linking the LLVM bitcode files together for further whole-program optimization. This is a small performance win, but it has several advantages in the future: - There are many more things that can be done per package in parallel, avoiding the bottleneck at the end of the compiler phase. This should speed up the compiler futher. - This change is a necessary step towards a non-LTO build mode for fast incremental builds that only rebuild the changed package, when compiler speed is more important than binary size. - This change refactors the compiler in such a way that it will be easier to inspect the IR for one package only. Inspecting this IR will be very helpful for compiler developers.
2021-01-29compiler: move settings to a separate Config structAyke van Laethem
Moving settings to a separate config struct has two benefits: - It decouples the compiler a bit from other packages, most importantly the compileopts package. Decoupling is generally a good thing. - Perhaps more importantly, it precisely specifies which settings are used while compiling and affect the resulting LLVM module. This will be necessary for caching the LLVM module. While it would have been possible to cache without this refactor, it would have been very easy to miss a setting and thus let the compiler work with invalid/stale data.
2021-01-24compiler: remove ir packageAyke van Laethem
This package was long making the design of the compiler more complicated than it needs to be. Previously this package implemented several optimization passes, but those passes have since moved to work directly with LLVM IR instead of Go SSA. The only remaining pass is the SimpleDCE pass. This commit removes the *ir.Function type that permeated the whole compiler and instead switches to use *ssa.Function directly. The SimpleDCE pass is kept but is far less tightly coupled to the rest of the compiler so that it can easily be removed once the switch to building and caching packages individually happens.
2020-04-21compiler: add parameter names to IRAyke van Laethem
This makes viewing the IR easier because parameters have readable names. This also makes it easier to write compiler tests (still a work in progress), that work in LLVM 9 and LLVM 10, as LLVM 10 started printing value names for unnamed parameters.
2020-03-27compiler: add dereferenceable_or_null attribute where possibleAyke van Laethem
This gives a hint to the compiler that such parameters are either NULL or point to a valid object that can be dereferenced. This is not directly very useful, but is very useful when combined with https://reviews.llvm.org/D60047 to remove the runtime.isnil hack without regressing escape analysis.
2020-03-25compiler: remove leftover code after refactorAyke van Laethem
A few functions were duplicated during the refactor. They can now be deleted.
2020-03-25compiler: refactor parseExprAyke van Laethem
parseExpr (now createExpr) and all callers (recursively) are switched over to the new builder object!
2020-03-25compiler: refactor function callingAyke van Laethem
2020-03-25compiler: rename Compiler.getValue -> builder.getValueAyke van Laethem
This is a fairly big commit, but it actually changes very little. getValue should really be a property of the builder (or frame), where the previously created instructions are kept.
2020-03-25compiler: refactor createBinOpAyke van Laethem
This commit unfortunately introduces a significant amount of code duplication. However, all that duplicate code should be removed once this refactor is done.
2020-03-25compiler: refactor IR generationAyke van Laethem
This is the first commit in a series to refactor the compiler. The intention is to make sure every function to be compiled eventually has its own IR builder. This will make it much easier to do other refactorings in the future: * Most code won't depend (directly) on the central Compiler object, perhaps making it possible to eliminate it in the future. Right now it's embedded in the `builder` struct but individual fields from the `Compiler` can easily be moved into the `builder` object. * Some functions are not directly exposed in Go SSA, they are wrapper functions for something. At the moment they are included in the list of functions to be compiled with the reachability analysis (SimpleDCE) in the ir package, but eventually this reachability analys will be removed. At that point, it would be very convenient to be able to simply build a function with a new IR builder. The `compilerContext` struct makes sure that it is not possible for `builder` methods to accidentally use global state such as the global IR builder. It is a transitional mechanism and may be removed when finished.
2020-03-21compiler: move funcImplementation to compileoptsAyke van Laethem
This allows packages other than the compiler to know (from a single source of truth) which implemenation is used for Go func values. This refactor is necessary to be able to move the Optimize function to the transform package.
2020-03-17refactor coroutine lowering and tasksJaden Weiss
2019-11-04all: refactor compile optionsAyke van Laethem
Move most of the logic of determining which compiler configuration to use (such as GOOS/GOARCH, build tags, whether to include debug symbols, panic strategy, etc.) into the compileopts package. This makes it a single source of truth for anything related to compiler configuration. It has a few advantages: * The compile configuration is independent of the compiler package. This makes it possible to move optimization passes out of the compiler, as they don't rely on compiler.Config anymore. * There is only one place to look if an incorrect compile option is used. * The compileopts provides some resistance against unintentionally picking the wrong option, such as with c.selectGC() vs c.GC() in the compiler. * It is now a lot easier to change compile options, as most options are getters now.
2019-08-17compiler: add support for 'go' on func valuesAyke van Laethem
This commit allows starting a new goroutine directly from a func value, not just when the static callee is known. This is necessary to support the whole time package, not just the commonly used subset that was compiled with the SimpleDCE pass enabled.
2019-08-05compiler: fix crash with linked lists in interfacesAyke van Laethem
This commit fixes the following issue: https://github.com/tinygo-org/tinygo/issues/309 Also, it prepares for some other reflect-related changes that should make it easier to add support for named types (etc.) in the future.
2019-06-08compiler: refactor named types to create them lazilyAyke van Laethem
This commit refactors named types to be created lazily. Instead of defining all types in advance, do it only when necessary.
2019-06-08compiler: remove superfluous 'err' result in decodeFuncValueAyke van Laethem
2019-05-01compiler: refactor packing of word-sized values in integersAyke van Laethem
There are two places that try to store values directly in pointers, if possible: closures and interfaces. Use the same functions for both.
2019-04-26compiler: refactor parseExprAyke van Laethem
This commit adds getValue which gets a const, global, or result of a local SSA expression and replaces (almost) all uses of parseExpr with getValue. The only remaining use is in parseInstr, which makes sure an instruction is only evaluated once.
2019-04-26compiler: do not return an error from getLLVMTypeAyke van Laethem
This commit replaces "unknown type" errors in getLLVMType with panics. The main reason this is done is that it simplifies the code *a lot*. Many `if err != nil` lines were there just because of type information. Additionally, simply panicking is probably a better approach as the only way this error can be produced is either with big new language features or a serious compiler bug. Panicking is probably a better way to handle this error anyway.
2019-04-17compiler: lower func values to switch + direct callAyke van Laethem
This has several advantages, among them: - Many passes (heap-to-stack, dead arg elimination, inlining) do not work with function pointer calls. Making them normal function calls improves their effectiveness. - Goroutine lowering to LLVM coroutines does not currently support function pointers. By eliminating function pointers, coroutine lowering gets support for them for free. This is especially useful for WebAssembly. Because of the second point, this work is currently only enabled for the WebAssembly target.
2019-04-17compiler: refactor func value handlingAyke van Laethem
This commit refactors all func value handling into a new file, which makes it easier to comprehend it and extend it later.