aboutsummaryrefslogtreecommitdiffhomepage
path: root/transform/testdata
AgeCommit message (Collapse)Author
2024-10-19compiler: mark stringFromRunes as nocapture/readonlyDamian Gryski
2024-10-19compiler: mark stringFromBytes as nocapture/readonly to help escape analysisDamian Gryski
Fixes #4525
2024-10-18transform: optimize range over []byte(string)Elias Naur
Fixes #2700
2024-07-03transform: fix incorrect alignment of heap-to-stack transformAyke van Laethem
It assumed the maximum alignment was equal to sizeof(void*), which is definitely not the case. So this only worked more or less by accident previously. It now uses the alignment as specified by the frontend, or else `unsafe.Alignof(complex128)` which is typically the maximum alignment of a given platform (though this shouldn't really happen in practice: the optimizer should keep the 'align' attribute in place).
2024-03-19all: move -panic=trap support to the compiler/runtimeAyke van Laethem
Support for `-panic=trap` was previously a pass in the optimization pipeline. This change moves it to the compiler and runtime, which in my opinion is a much better place. As a side effect, it also fixes https://github.com/tinygo-org/tinygo/issues/4161 by trapping inside runtime.runtimePanicAt and not just runtime.runtimePanic. This change also adds a test for the list of imported functions. This is a more generic test where it's easy to add more tests for WebAssembly file properties, such as exported functions.
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-09-23transform: fix bug in StringToBytes optimization passAyke van Laethem
Previously, this pass would convert any read-only use of a runtime.stringToBytes call to use the original string buffer instead. This is incorrect: if there are any writes to the resulting buffer, none of the slice buffer pointers can be converted to use the original read-only string buffer. This commit fixes that bug and adds a test to prove the new (correct) behavior.
2023-06-17wasm: remove i64 workaround, use BigInt insteadAyke van Laethem
Browsers previously didn't support the WebAssembly i64 type, so we had to work around that limitation by converting the LLVM i64 type to something else. Some people used a pair of i32 values, but we used a pointer to a stack allocated i64. Now however, all major browsers and Node.js do support WebAssembly BigInt integration so that i64 values can be passed back and forth between WebAssembly and JavaScript easily. Therefore, I think the time has come to drop support for this workaround. For more information: https://v8.dev/features/wasm-bigint (note that TinyGo has used a slightly different way of passing i64 values between JS and Wasm). For information on browser support: https://webassembly.org/roadmap/
2023-03-22compiler: add alloc attributes to runtime.allocAyke van Laethem
This gives a small improvement now, and is needed to be able to use the Heap2Stack transform that's available in the Attributor pass. This Heap2Stack transform could replace our custom OptimizeAllocs pass. Most of the changes are just IR that changed, the actual change is relatively small. To give an example of why this is useful, here is the code size before this change: $ tinygo build -o test -size=short ./testdata/stdlib.go code data bss | flash ram 95620 1812 968 | 97432 2780 $ tinygo build -o test -size=short ./testdata/stdlib.go code data bss | flash ram 95380 1812 968 | 97192 2780 That's a 0.25% reduction. Not a whole lot, but nice for such a small patch.
2023-03-19transform: fix OptimizeReflectImplements pass for new named elem offsetDamian Gryski
2023-03-16transform: update wasm-abi to use opaque pointersAyke van Laethem
2023-03-16transform: update stringtobytes test to opaque pointersAyke van Laethem
2023-03-16transform: update stringequal test to opaque pointersAyke van Laethem
2023-03-16transform: update stacksize test to opaque pointersAyke van Laethem
2023-03-16transform: update panic test to opaque pointersAyke van Laethem
2023-03-16transform: update maps test to opaque pointersAyke van Laethem
2023-03-16transform: update interrupt test to opaque pointersAyke van Laethem
2023-03-16transform: update interface test to opaque pointersAyke van Laethem
2023-03-16transform: update gc-stackslots test to opaque pointersAyke van Laethem
2023-03-16transform: update allocs test to opaque pointersAyke van Laethem
Also, rename most of the SSA values while we're at it.
2023-03-16transform: update reflect-implements test to opaque pointersAyke van Laethem
2023-03-08transform: add debug information to internal/task.stackSizeAyke van Laethem
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-02-26builder: remove non-ThinLTO build modeAyke van Laethem
All targets now support ThinLTO so let's remove the old unused code.
2023-02-17all: refactor reflect packageAyke van Laethem
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.
2022-06-10transform (MakeGCStackSlots): do not move the stack chain pop earlierNia Waldvogel
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-01gc: drop support for 'precise' globalsAyke van Laethem
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-03-12all: add support for ThinLTOAyke van Laethem
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-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.
2022-01-19internal/task: remove coroutinesNia Waldvogel
2021-12-10transform: allocate the correct amount of bytes in an allocaAyke van Laethem
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-11-30all: add LLVM 12 supportAyke van Laethem
Originally based on a PR by @QuLogic, but extended a lot to get all tests to pass.
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-11-02compiler, runtime: add layout parameter to runtime.allocAyke van Laethem
This layout parameter is currently always nil and ignored, but will eventually contain a pointer to a memory layout. This commit also adds module verification to the transform tests, as I found out that it didn't (and therefore didn't initially catch all bugs).
2021-10-31compiler: simplify interface loweringAyke van Laethem
This commit simplifies the IR a little bit: instead of calling pseudo-functions runtime.interfaceImplements and runtime.interfaceMethod, real declared functions are being called that are then defined in the interface lowering pass. This should simplify the interaction between various transformation passes. It also reduces the number of lines of code, which is generally a good thing.
2021-10-31all: drop support for LLVM 10Ayke van Laethem
2021-09-21transform (coroutines): fix memory corruption for tail calls that reference ↵Nia Waldvogel
stack allocations This change fixes a bug in which `alloca` memory lifetimes would not extend past the suspend of an asynchronous tail call. This would typically manifest as memory corruption, and could happen with or without normal suspending calls within the function.
2021-08-04transform: improve GC stack slot pass to work around a bugAyke van Laethem
Bug 1790 ("musttail call must precede a ret with an optional bitcast") is caused by the GC stack slot pass inserting a store instruction between a musttail call and a return instruction. This is not allowed in LLVM IR. One solution would be to remove the musttail. That would probably work, but 1) the go-llvm API doesn't support this and 2) this might have unforeseen consequences. What I've done in this commit is to move the store instruction to a position earlier in the basic block, just after the last access to the GC stack slot alloca. Thanks to @fgsch for a very small repro, which I've used as a regression test.
2021-06-17compiler: refactor method namesAyke van Laethem
This commit includes two changes: * It makes unexported interface methods package-private, so that it's not possible to type-assert on an unexported method in a different package. * It makes the globals used to identify interface methods defined globals, so that they can (eventually) be left in the program for an eventual non-LTO build mode.
2021-05-26compiler: do not emit nil checks for loading closure variablesAyke van Laethem
Closure variables are allocated in a parent function and are thus never nil. Don't do a nil check before reading or modifying the value. This commit results in a slight reduction in code size in some test cases: calls.go, channel.go, goroutines.go, json.go, sort.go - presumably wherever closures are used.
2021-05-03transform: split interface and reflect loweringAyke van Laethem
These two passes are related, but can definitely work independently. Which is what this change does: it splits the two passes. This should make it easier to change these two new passes in the future. This change now also enables slightly better testing by testing these two passes independently. In particular, the reflect lowering pass got some actual tests: it was barely unit-tested before. I have verified that this doesn't really change code size, at least not on the microbit target. Two tests do change, but in a very minor way (and in opposite direction).
2021-04-26compiler: improve position informationAyke van Laethem
In many cases, position information is not stored in Go SSA instructions because they don't exit directly in the source code. This includes implicit type conversions, implicit returns at the end of a function, the creation of a (hidden) slice when calling a variadic function, and many other cases. I'm not sure where this information is supposed to come from, but this patch takes the value (usually) from the value the instruction refers to. This seems to work well for these implicit conversions. I've also added a few extra tests to the heap-to-stack transform pass, of which one requires this improved position information.
2021-04-22copiler: add function attributes to some runtime callsAyke van Laethem
This allows better escape analysis even without being able to see the entire program. This makes the stack allocation test case more complete but probably won't have much of an effect outside of that (as the compiler is able to infer these attributes in the whole-program functionattrs pass).
2021-04-22main: add -print-allocs flag that lets you print all heap allocationsAyke van Laethem
This flag, if set, is a regexp for function names. If there are heap allocations in the matching function names, these heap allocations will be printed with an explanation why the heap allocation exists (and why the object can't be stack allocated).
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-04-12transform: do not lower zero-sized alloc to allocaAyke van Laethem
The LLVM CoroFrame pass appears to be tripping over this zero-sized alloca. Therefore, do what the runtime would do: return a pointer to runtime.zeroSizedAlloc. Or just don't deal with this case. But don't emit a zero sized alloca to avoid this LLVM bug. More information: https://bugs.llvm.org/show_bug.cgi?id=49916
2021-04-08transform: don't rely on struct name of runtime.typecodeIDAyke van Laethem
Sometimes, LLVM may rename named structs when merging modules. Therefore, we can't rely on typecodeID structs to retain their struct names. This commit changes the interface lowering pass to not rely on these names. The interp package does however still rely on this name, but I hope to fix that in the future.
2021-03-28transform: optimize reflect.Type Implements() methodAyke van Laethem
This commit adds a new transform that converts reflect Implements() calls to runtime.interfaceImplements. At the moment, the Implements() method is not yet implemented (how ironic) but if the value passed to Implements is known at compile time the method call can be optimized to runtime.interfaceImplements to make it a regular interface assert. This commit is the last change necessary to add basic support for the encoding/json package. The json package is certainly not yet fully supported, but some trivial objects can be converted to JSON.
2021-03-23compiler: do not check for impossible type assertsAyke van Laethem
Previously there was code to avoid impossible type asserts but it wasn't great and in fact was too aggressive when combined with reflection. This commit improves this by checking all types that exist in the program that may appear in an interface (even struct fields and the like) but without creating runtime.typecodeID objects with the type assert. This has two advantages: * As mentioned, it optimizes impossible type asserts away. * It allows methods on types that were only asserted on (in runtime.typeAssert) but never used in an interface to be optimized away using GlobalDCE. This may have a cascading effect so that other parts of the code can be further optimized. This sometimes massively improves code size and mostly negates the code size regression of the previous commit.
2021-03-23compiler: merge runtime.typecodeID and runtime.typeInInterfaceAyke van Laethem
This distinction was useful before when reflect wasn't properly supported. Back then it made sense to only include method sets that were actually used in an interface. But now that it is possible to get to other values (for example, by extracting fields from structs) and it is possible to turn them back into interfaces, it is necessary to preserve all method sets that can possibly be used in the program in a type assert, interface assert or interface method call. In the future, this logic will need to be revisited again when reflect.New or reflect.Zero gets implemented. Code size increases a bit in some cases, but usually in a very limited way (except for one outlier in the drivers smoke tests). The next commit will improve the situation significantly.