Passing it by value means that bringup on new architectures is harder for no
real benefit. Passing it by pointer allows to get the compiler running without
needing to figure out the C calling convention details first. This manifested in
practice on LoongArch, for example.
Most of the required renames here are net wins for readaibility, I'd
say. The ones in `arch` are a little more verbose, but I think better. I
didn't bother renaming the non-conflicting functions in
`arch/arm/bits.zig` and `arch/aarch64/bits.zig`, since these backends
are pretty bit-rotted anyway AIUI.
because it marks the linker section, preventing garbage collection.
Also, name the members because that is required by this intrinsic.
Also, enable the StackDepth option in the sancov pass as a workaround
for https://github.com/llvm/llvm-project/pull/106464, otherwise, LLVM
enables TracePCGuard even though we explicitly disable it.
This matches what LLVM's sancov pass does and is required so that
optimization passes do not delete the instrumentation.
However, this is currently triggering an error: "members of
llvm.compiler.used must be named" so the next commit will add names to
those globals.
It's useful to have TraceCmp based on the results of LLVM optimizations,
while the code coverage bits were emitted by Zig manually, allowing more
careful correlation to points of interest in the source code.
This re-enables the sancov pass in `-ffuzz` mode, but only TraceCmp.
Notably, IndirectCalls is off, which needs to be implemented manually in
the LLVM backend, and StackDepth remains off, because it is not used by
libfuzzer or AFL either.
If stack depth is re-introduced, it can be done with better performance
characteristics by being function call graph aware, and only lowered in
call graph cycles, where its heuristic properties come in useful.
Fixes the fuzzing regression.
instead of relying on the LLVM sancov pass. The LLVM pass is still
executed if trace_pc_guard is requested, disabled otherwise. The LLVM
backend emits the instrumentation directly.
It uses `__sancov_pcs1` symbol name instead of `__sancov_pcs` because
each element is 1 usize instead of 2.
AIR: add CoveragePoint to branch hints which indicates whether those
branches are interesting for code coverage purposes.
Update libfuzzer to use the new instrumentation. It's simplified since
we no longer need the constructor and the pcs are now in a continguous
list.
This is a regression in the fuzzing functionality because the
instrumentation for comparisons is no longer emitted, resulting in worse
fuzzer inputs generated. A future commit will add that instrumentation
back.
These won't live in the parent namespace as decls which causes problems
later in this function, and tests are guaranteed not to be referenced at
comptime anyway, so there's actually no need to run this logic.
The compiler actually doesn't need any functional changes for this: Sema
does reification based on the tag indices of `std.builtin.Type` already!
So, no zig1.wasm update is necessary.
This change is necessary to disallow name clashes between fields and
decls on a type, which is a prerequisite of #9938.
Pointer subtraction on `void *` or function pointers is UB by the C
spec, but is permitted by GCC and Clang as an extension. So, avoid
crashing translate-c in such cases, and follow the extension behavior --
there's nothing else that could really be intended.
Implements the accepted proposal to introduce `@branchHint`. This
builtin is permitted as the first statement of a block if that block is
the direct body of any of the following:
* a function (*not* a `test`)
* either branch of an `if`
* the RHS of a `catch` or `orelse`
* a `switch` prong
* an `or` or `and` expression
It lowers to the ZIR instruction `extended(branch_hint(...))`. When Sema
encounters this instruction, it sets `sema.branch_hint` appropriately,
and `zirCondBr` etc are expected to reset this value as necessary. The
state is on `Sema` rather than `Block` to make it automatically
propagate up non-conditional blocks without special handling. If
`@panic` is reached, the branch hint is set to `.cold` if none was
already set; similarly, error branches get a hint of `.unlikely` if no
hint is explicitly provided. If a condition is comptime-known, `cold`
hints from the taken branch are allowed to propagate up, but other hints
are discarded. This is because a `likely`/`unlikely` hint just indicates
the direction this branch is likely to go, which is redundant
information when the branch is known at comptime; but `cold` hints
indicate that control flow is unlikely to ever reach this branch,
meaning if the branch is always taken from its parent, then the parent
is also unlikely to ever be reached.
This branch information is stored in AIR `cond_br` and `switch_br`. In
addition, `try` and `try_ptr` instructions have variants `try_cold` and
`try_ptr_cold` which indicate that the error case is cold (rather than
just unlikely); this is reachable through e.g. `errdefer unreachable` or
`errdefer @panic("")`.
A new API `unwrapSwitch` is introduced to `Air` to make it more
convenient to access `switch_br` instructions. In time, I plan to update
all AIR instructions to be accessed via an `unwrap` method which returns
a convenient tagged union a la `InternPool.indexToKey`.
The LLVM backend lowers branch hints for conditional branches and
switches as follows:
* If any branch is marked `unpredictable`, the instruction is marked
`!unpredictable`.
* Any branch which is marked as `cold` gets a
`llvm.assume(i1 true) [ "cold"() ]` call to mark the code path cold.
* If any branch is marked `likely` or `unlikely`, branch weight metadata
is attached with `!prof`. Likely branches get a weight of 2000, and
unlikely branches a weight of 1. In `switch` statements, un-annotated
branches get a weight of 1000 as a "middle ground" hint, since there
could be likely *and* unlikely *and* un-annotated branches.
For functions, a `cold` hint corresponds to the `cold` function
attribute, and other hints are currently ignored -- as far as I can tell
LLVM doesn't really have a way to lower them. (Ideally, we would want
the branch hint given in the function to propagate to call sites.)
The compiler and standard library do not yet use this new builtin.
Resolves: #21148
mlugg: this is cherry-picked from Andrew's nosanitize branch (with
Jacob's fixes squashed in) since I needed this for `unpredictable` and
`prof` metadata. The nosanitize-specific changes are reverted in the
next commit.
Co-authored-by: Jacob Young <jacobly0@users.noreply.github.com>
before this, calls to `resolveTypeFieldsStruct` (now renamed to the more correct `resolveStructFieldTypes`) would just throw away the sema that `resolveStructInner` created and create its own. There is no reason to do this, and we fix it to preserve the sema through it all.
My main gripes with this design were that it was incorrectly namespaced, the naming was inconsistent and a bit wrong (`fooAlign` vs `fooAlignment`).
This commit moves all the logic from `PerThread.zig` to use the zcu + tid system that the previous couple commits introduce.
I've organized and merged the functions to be a bit more specific to their own purpose.
- `fieldAlignment` takes a struct or union type, an index, and a Zcu (or the Sema version which takes a Pt), and gives you the alignment of the field at the index.
- `structFieldAlignment` takes the field type itself, and provides the logic to handle special cases, such as externs.
A design goal I had in mind was to avoid using the word 'struct' in the function name, when it worked for things that aren't structs, such as unions.