aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler
AgeCommit message (Collapse)Author
2020-06-14device: add new cross-arch Asm and AsmFull functionsAyke van Laethem
This is necessary to avoid a circular dependency between the device/avr and runtime/interrupts package in the next commit. It may be worth replacing existing calls like device/arm.Asm to device.Asm, to have a single place where these are defined.
2020-06-08compiler/runtime: move the channel blocked list onto the stackJaden Weiss
Previously, chansend and chanrecv allocated a heap object before blocking on a channel. This object was used to implement a linked list of goroutines blocked on the channel. The chansend and chanrecv now instead accept a buffer to store this object in as an argument. The compiler now creates a stack allocation for this object and passes it in.
2020-06-08compiler: add support for custom code modelYannis Huber
2020-05-28compiler: add support for atomic operationsAyke van Laethem
This also implements DisableInterrupts/EnableInterrupts for RISC-V, as those operations were needed to implement a few libcalls.
2020-05-27compiler: fix a few crashes due to named typesAyke van Laethem
There were a few cases left where a named type would cause a crash in the compiler. While going through enough code would have found them eventually, I specifically looked for the `Type().(` pattern: a Type() call that is then used in a type assert. Most of those were indeed bugs, although for some I couldn't come up with a reproducer so I left them as-is.
2020-05-27loader: load packages using Go modulesAyke van Laethem
This commit replaces the existing ad-hoc package loader with a package loader that uses the x/tools/go/packages package to find all to-be-loaded packages.
2020-05-27loader: merge roots from both Go and TinyGo in a cached directoryAyke van Laethem
This commit changes the way that packages are looked up. Instead of working around the loader package by modifying the GOROOT variable for specific packages, create a new GOROOT using symlinks. This GOROOT is cached for the specified configuration (Go version, underlying GOROOT path, TinyGo path, whether to override the syscall package). This will also enable go module support in the future. Windows is a bit harder to support, because it only allows the creation of symlinks when developer mode is enabled. This is worked around by using symlinks and if that fails, using directory junctions or hardlinks instead. This should work in the vast majority of cases. The only case it doesn't work, is if developer mode is disabled and TinyGo, the Go toolchain, and the cache directory are not all on the same filesystem. If this is a problem, it is still possible to improve the code by using file copies instead. As a side effect, this also makes diagnostics use a relative file path only when the file is not in GOROOT or in TINYGOROOT.
2020-05-21cgo: Add LDFlags supportLucas Teske
2020-05-16internal/bytealg: reimplement bytealg in pure GoJaden Weiss
Previously, we implemented individual bytealg functions via linknaming, and had to update them every once in a while when we hit linker errors. Instead, this change reimplements the bytealg package in pure Go. If something is missing, it will cause a compiler error rather than a linker error. This is easier to test and maintain.
2020-05-12runtime: add cap and len support for chanscornelk
2020-04-29all: replace ReadRegister with AsmFull inline assemblyAyke van Laethem
This makes AsmFull more powerful (by supporting return values) and avoids a compiler builtin.
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-04-13compiler/llvm.go: fix typosuzuki-koya
2020-04-13compiler: unexport some exported symbolsAyke van Laethem
Some symbols (constants/types/methods) were exported while they are an implementation detail. To keep the public API clean, unexport them.
2020-04-09compiler: pass interface typecode through defer framesJaden Weiss
Previously, the typecode was passed via a direct reference, which results in invalid IR when the defer is not reached in all return paths. It also results in incorrect behavior if the defer is in a loop, causing all defers to use the typecode of the last iteration.
2020-04-04compiler: optimize comparing interface values against nilAyke van Laethem
This is a very common case. Avoiding a runtime.interfaceEqual call leads to a very big reduction in code size in some cases (while it doesn't affect many other examples). A number of driver smoke tests are reduced by about 4kB just with this optimization. I found this issue while looking into automatically calculating the required amount of stack space for goroutines. The runtime.interfaceEqual function is recursive, so it is best avoided.
2020-04-03compiler: add debug info to goroutine start wrappersAyke van Laethem
2020-04-02compiler: track PHI nodesJaden Weiss
2020-04-02compiler: track the result of string concatenationJaden Weiss
Before this commit, the garbage collector was able to collect string values while they were still in use.
2020-03-29compiler: add support for anonymous type assertsAyke van Laethem
This is used for example by the errors package, which contains: if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { return true } The interface here is not a named type.
2020-03-28interp: show backtrace with errorAyke van Laethem
This should make it much easier to figure out why and where an error happens at package initialization time.
2020-03-28ir: add descriptive error messages to SimpleDCE passJaden Weiss
This commit modifies the SimpleDCE pass to emit errors similar to those emitted by gc when the main function is missing.
2020-03-28compiler: implement spec-compliant shiftsJaden Weiss
Previously, the compiler used LLVM's shift instructions directly, which have UB whenever the shifts are large or negative. This commit adds runtime checks for negative shifts, and handles oversized shifts.
2020-03-27compiler,runtime: translate memzero calls to LLVM memset intrinsicsAyke van Laethem
This gives the optimizer a bit more information about what the calls do. This should result in slightly better generated code. Code size sometimes goes up and sometimes goes down. I blame the code size going up on the inliner which inlines more functions, because compiling the smoke tests in the drivers repository with -opt=1 results in a slight code size reduction in all cases.
2020-03-27compiler,runtime: use LLVM intrinsics for memcpy/memmoveAyke van Laethem
This replaces the custom runtime.memcpy and runtime.memmove functions with calls to LLVM builtins that should hopefully allow LLVM to better optimize such calls. They will be lowered to regular libc memcpy/memmove when they can't be optimized away. When testing this change with some smoke tests, I found that many smoke tests resulted in slightly larger binary sizes with this commit applied. I looked into it and it appears that machine.sendUSBPacket was not inlined before while it is with this commit applied. Additionally, when I compared all driver smoke tests with -opt=1 I saw that many were reduced slightly in binary size and none increased in size.
2020-03-27compiler, transform: remove runtime.isnil hackAyke van Laethem
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-27compiler: avoid nil pointer checks with unsafe.PointerAyke van Laethem
The unsafe.Pointer type is used for many low-level operations, especially in the runtime. It can for example be used to copy the contents of a slice (in the copy builtin) independent of the slice element type.
2020-03-27compiler: do not perform nil checking when indexing slicesAyke van Laethem
The x/tools/go/ssa package splits slice loads/stores into two operations. So for code like this: x = p[3] It has two instructions: x_ptr = &p[3] x = *x_ptr This makes the IR simpler, but also means we're accidentally inserting more nil checks than necessary: the slice index operation has effectively already checked for nil by performing a bounds check. Therefore, omit nil pointer checks for pointers created by *ssa.IndexAddr. This change is necessary to make sure a future removal of runtime.isnil will not cause the escape analysis pass to regress. Apart from that, it reduces code size slightly in many smoke tests (with no increases in code size).
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: refactor public interfaceAyke van Laethem
This commit merges NewCompiler and Compile into one simplifying the external interface. More importantly, it does away with the entire Compiler object so the public API becomes a lot smaller. The refactor is not complete: eventually, the compiler should just compile a single package without trying to load it first (that should be done by the builder package).
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: remove *Frame typeAyke van Laethem
2020-03-25compiler: refactor creation of functionsAyke van Laethem
2020-03-25compiler: refactor top-level createInstruction functionAyke van Laethem
2020-03-25compiler: refactor starting new goroutinesAyke van Laethem
2020-03-25compiler: refactor defer operationsAyke van Laethem
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: refactor builtinsAyke van Laethem
2020-03-25compiler: refactor map operations to use the builder objectAyke van Laethem
2020-03-25compiler: refactor interface creation and callingAyke van Laethem
2020-03-25compiler: refactor interface invoke wrapper creationAyke van Laethem
Now that most of the utility compiler methods are ported over to the builder or compilerContext, it is possible to avoid having to do the wrapper creation in two steps. A new builder is created just to create the wrapper. This is a small reduction in line count (and a significant reduction in complexity!), even though more documentation was added.
2020-03-25compiler: refactor parseConvertAyke van Laethem
2020-03-25compiler: refactor parseUnOpAyke van Laethem
2020-03-25compiler: refactor creating of channel operationsAyke van Laethem
2020-03-25compiler: refactor assertsAyke van Laethem
2020-03-25compiler: refactor parseTypeAssertAyke van Laethem
Move to the builder object, and rename to createTypeAssert.
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.