22 Commits

Author SHA1 Message Date
Ayke van Laethem ba95eb3e1b compiler: use LLVM intrinsics for math trig operations
I think this failed in the past, but presumably those failures have been
fixed by now. So these intrinsics can now be used.

Using these intrinsics instead of the native Go implementations helps
LLVM to reason about them: it can for example evaluate the value at
compile time or do optimizations like convert
`float32(math.Sin(float64(x)))` into a 32-bit sin operation. If the math
operation is not available on the target platform the C library
implementation will be used instead.
2026-06-25 18:31:58 +02:00
Damian Gryski f496571747 compiler: add instrinsic for crypto/internal/constanttime.boolToUint8 2026-04-11 12:38:36 +01:00
Nia Waldvogel a40586d092 compiler: implement copy directly
The compiler now implements the copy builtin directly instead of calling sliceCopy.
The length is calculated with the llvm.umax.* intrinsics, and the move is performed by llvm.memmove.*.
Both of these operations are easily understood by LLVM's optimization passes.
The type's alignment is also provided to llvm.memmove.*, which is useful when rewriting the move.

Interp no longer needs to reimplement sliceCopy.
Some edge case handling was implemented by sliceCopy but not llvm.memmove.*/llvm.memcpy.*.
I copied this over, so copies of external slices should work now.
Volatile moves/copies are now run at runtime by interp.

There is a 4-byte size increase due to some confusing length logic in sendUSBPacket.
I will look at sendUSBPacket in a future PR.
2026-01-05 15:10:31 -05:00
Ayke van Laethem b203314c2f machine: make sure DMA buffers do not escape unnecessarily
Writing the pointer of a buffer to memory-mapped I/O will normally cause
it to escape, which forces the compiler to heap-allocate the buffer. But
we do know how long the value stays alive, so we can tell the compiler
to keep it alive exactly until it is not needed anymore - and tell it to
not treat the pointer-to-uintptr cast as escaping.
2025-11-12 18:07:53 +01:00
Ayke van Laethem 34efc3a381 compiler: implement internal/abi.Escape 2025-08-06 17:08:26 +02:00
Ayke van Laethem 81ce7fb738 LLVM 18 support 2024-05-24 19:12:26 +02:00
Ayke van Laethem 1da1abe314 all: remove LLVM 14 support
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-10-01 18:32:15 +02:00
Ayke van Laethem a2f886a67a compiler: implement clear builtin for slices 2023-08-04 11:59:11 +02:00
Ayke van Laethem 464ebc4fe1 compiler: implement most math/bits functions
These functions can be implemented more efficiently using LLVM
intrinsics. That makes them the Go equivalent of functions like
__builtin_clz which are also implemented using these LLVM intrinsics.

I believe the Go compiler does something very similar: IIRC it converts
calls to these functions into optimal instructions for the given
architecture.

I tested these by running `tinygo test math/bits` after uncommenting the
tests that would always fail (the *PanicZero and *PanicOverflow tests).
2023-03-29 20:55:09 +02:00
Ayke van Laethem 0ce539ad42 compiler; add position information to createConstant
Non-functional change. The position information will be used later to
emit debug info locations to string constants.
2023-03-05 17:13:16 -08:00
Ayke van Laethem c02cc339c5 runtime: implement KeepAlive using inline assembly 2023-02-18 10:50: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 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 9e8739bb47 compiler: replace math aliases with intrinsics
This is really a few more-or-less separate changes:

  * Remove all math aliases that were used in Go 1.16 and below (the
    math.[A-Z] aliases).
  * Replace math aliases with an assembly implementation (the math.arch*
    aliases) with a LLVM intrinsic, where one is available.
  * Include missing math functions in picolibc build.

This leaves just four math aliases:

  * math.archHypot and math.archModf do not have a LLVM builtin
    equivalent. They could be replaced with calls to libm, and I think
    that would be a good idea in the long term.
  * math.archMax and math.archMin do have a LLVM builtin equivalent
    (llvm.maximum.f64, llvm.minimum.f64), but unfortunately they crash
    when used. Apparently these exact operations are not yet widely
    supported in hardware and they don't have a libm equivalent either.

There are more LLVM builtins that we could use for the math package
(such as FMA), but I will leave that to a future change. It could
potentially speed up some math operations.
2022-08-30 17:33:16 +02:00
Ayke van Laethem 20a7a6fd54 compiler: replace some math operation bodies with fast intrinsics
Instead of changing the calls, replace the function bodies themselves.
This is useful for a number of reasons, see
https://github.com/tinygo-org/tinygo/pull/2920 for more information.

I have removed the math intrinsics tests because they are no longer
useful. Instead, I think `tinygo test math` should suffice.
2022-08-30 17:33:16 +02:00
Ayke van Laethem b8a6a1f62b compiler: use the LLVM builtins everywhere
This gives some more optimization opportunities to LLVM, because it
understands these intrinsics. For example, it might convert
llvm.sqrt.f64 to llvm.sqrt.f32 if possible.
2022-08-28 23:37:56 +02:00
Ayke van Laethem 4262f0ff1f compiler: really define runtime.mem* as LLVM intrinsic wrappers
This makes it possible to //go:linkname them from other places, like in
the reflect package. And is in my opinion a much cleaner solution.
2022-06-24 11:10:24 +02:00
Ayke van Laethem 1ceb63d14c compiler: really define runtime/volatile.* functions
This makes them available to deferred calls, among others.
2022-06-24 11:10:24 +02:00
Ayke van Laethem e1052f921c compiler: define atomic intrinsic functions directly
This changes the compiler from treating calls to sync/atomic.* functions
as special calls (emitted directly at the call site) to actually
defining their declarations when there is no Go SSA implementation. And
rely on the inliner to inline these very small functions.
This works a bit better in practice. For example, this makes it possible
to use these functions in deferred function calls.

This commit is a bit large because it also needs to refactor a few
things to make it possible to define such intrinsic functions.
2022-06-24 11:10:24 +02:00
Ayke van Laethem 58565b42cc compiler: move LLVM math builtin support into the compiler
This simplifies src/runtime/math.go, which I eventually want to remove
entirely by moving the given functionality into the compiler.
2021-08-10 20:08:27 +02:00
Ayke van Laethem 91d1a23b14 compiler,runtime: translate memzero calls to LLVM memset intrinsics
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-27 21:01:59 +01:00
Ayke van Laethem eaa54bc7e3 compiler,runtime: use LLVM intrinsics for memcpy/memmove
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-27 21:01:59 +01:00