This actually used to be how it worked in stage1, and there was this
issue to change it: #2649
So this commit is a reversal to that idea. One motivation for that issue
was avoiding emitting the panic handler in compilations that do not have
any calls to panic. This commit only resolves the panic handler in the
event of a safety check function being emitted, so it does not have that
flaw.
The other reason given in that issue was for optimizations that elide
safety checks. It's yet to be determined whether that was a good idea or
not; this can get re-explored when we start adding optimization passes
to AIR.
This commit adds these AIR instructions, which are only emitted if
`backendSupportsFeature(.safety_checked_arithmetic)` is true:
* add_safe
* sub_safe
* mul_safe
It removes these nonsensical AIR instructions:
* addwrap_optimized
* subwrap_optimized
* mulwrap_optimized
The safety-checked arithmetic functions push the burden of invoking the
panic handler into the backend. This makes for a messier compiler
implementation, but it reduces the amount of AIR instructions emitted by
Sema, which reduces time spent in the secondary bottleneck of the
compiler. It also generates more compact LLVM IR, reducing time spent in
the primary bottleneck of the compiler.
Finally, it eliminates 1 stack allocation per safety-check which was
being used to store the resulting tuple. These allocations were going to
be annoying when combined with suspension points.
Most of this migration was performed automatically with `zig fmt`. There
were a few exceptions which I had to manually fix:
* `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten
* `@truncate`'s fixup is incorrect for vectors
* Test cases are not formatted, and their error locations change
DeclGen/FuncGen methods are for things that pertain to a particular
declaration or function, while Object methods are for things that
pertain to the entire LLVM Module. Many methods were in the wrong
category, such as type and value lowering.
This is a prerequisite commit for a local branch I am working on, which
needs to be able to call lowerValue() without the context of any
particular function or declaration.
The signature is `getOrCreateSubrange(int64_t Lo, int64_t Count)`, so this updates the bindings to match.
This fixes a crash in `lowerDebugTypeImpl` when analyzing slices that have a length of 2^32 or
larger (up to `2^64 >> 3`, which still crashes, because above that the array size in bits overflows u64).
Opaque and `noreturn` makes sense since they don't represent real
values, but `null` and `undefined` are perfectly normal
comptime-only values.
Closes#16088