Rather than accepting a canonical branch and a target branch
we allow to directly merge a branch into the parent branch.
This is possible as there's no overlapping and we have infinite
registers to our availability. This makes merging a lot simpler.
When determining the type of a local (read: register), we would
previously subtract the stack locals also. However, this locals
are also within the same `locals` list, meaning the type of the
local we were retrieving was off by 2. This could create a validation
error when we re-use a local of a different type.
Upon a branch, we only allow locals to be freed which were allocated
within the same branch as where they die. This ensures that when two
or more branches target the same operand we do not try to free
it more than once. This does however not implement freeing the local
upon branch merging yet.
When reusing an operand it increases the reference count, then when
an operand dies it will only decrease the reference count. When
this reaches 0, the local will be virtually freed, meaning it can be
re-used for a new local.
By reference counting the locals, we can ensure that when we free
a local, no local will be reused while it still has references pointing
to it. This prevents misscompilations. The compiler will also panic if
we free a local more than we reference it, introducing extra safety to
ensure they match up.
This hooks reusal of locals into liveness analysis.
Meaning that when an operand dies, and is a local,
it will automatically be freed so it can be re-used
when a new local is required. The result of this, is
a lower allocation required for locals. Having less
locals means smaller binary size, as well as faster
compilation speed when loaded by the runtime.
* When a field starts at some bit offset within a byte you need to load
starting from that byte and shift, not starting from the next byte,
so a rounded-down divide is required here, not a rounded-up one.
* Remove paragraph from doc that no longer relates to anything.
Closes#12363
When we want a runtime pointer to a zero-bit value we use an undef
pointer, but what if we want a runtime pointer to a comptime-only value?
Normally, if `T` is a comptime-only type such as `*const comptime_int`,
then `*const T` would also be a comptime-only type, so anything
referencing a comptime-only value is usually also comptime-only, and
therefore not emitted to the executable.
However, what if instead we have a `*const anyopaque` pointing to a
comptime-only value? Certainly, `*const anyopaque` is a runtime type,
and so we need some runtime value to store, even when it happens to be
pointing to a comptime-only value. In this case we want to do the same
thing as we do when pointing to a zero-bit value, so we use
`hasRuntimeBits` to handle both cases instead of ignoring comptime.
Closes#12025
Due to the unavailability of fchdir in Windows, a call for setting the
CWD needs to either call chdir with the path string or call
SetCurrentDirectory.
Either way, since we are dealing with a Handle in Windows, a call for
GetFinalPathNameByHandle is necessary for getting the file path first.
The definition of HKEY__ as a struct with an unused int field is only the case in the Windows headers when `STRICT` is defined. From https://learn.microsoft.com/en-us/windows/win32/winprog/enabling-strict:
> When STRICT is defined, data type definitions change as follows:
>
> - Specific handle types are defined to be mutually exclusive; for example, you will not be able to pass an HWND where an HDC type argument is required. Without STRICT, all handles are defined as HANDLE, so the compiler does not prevent you from using one type of handle where another type is expected.
Zig's `opaque {}` already gives this benefit to us, so the usage of a struct with an unused field is unnecessary, and it was causing HKEY to have an alignment of 4, which is a problem because there are HKEY constants like HKEY_LOCAL_MACHINE (0x80000002) that are not 4-byte aligned. Without this change, the compiler would not allow something like HKEY_LOCAL_MACHINE to be defined since it enforces pointer alignment.
This makes the following changes for i386:
long long and unsigned long long have 4 byte alignment on non-Windows
f64 (double) has 4-byte alignment on non-Windows
long double is 80 bits and has 4 byte alignment on mingw
long double on android is 64 bits, not 80: https://www.uclibc.org/docs/psABI-i386.pdfFixes#12453Fixes#12987
This change also exposes some of the existing functions under both the
PPC-style names symbols and the compiler-rt-style names, since Zig
currently lowers softfloat calls to the latter.
Stage 2's softfloat support still had a couple of gaps, which were
preventing us from lowering `f16` on this target. With any luck,
this is enough to get PPC64 working as a Tier 2 target again.