1004 Commits

Author SHA1 Message Date
mlugg
5fb4a7df38
Air: add explicit repeat instruction to repeat loops
This commit introduces a new AIR instruction, `repeat`, which causes
control flow to move back to the start of a given AIR loop. `loop`
instructions will no longer automatically perform this operation after
control flow reaches the end of the body.

The motivation for making this change now was really just consistency
with the upcoming implementation of #8220: it wouldn't make sense to
have this feature work significantly differently. However, there were
already some TODOs kicking around which wanted this feature. It's useful
for two key reasons:

* It allows loops over AIR instruction bodies to loop precisely until
  they reach a `noreturn` instruction. This allows for tail calling a
  few things, and avoiding a range check on each iteration of a hot
  path, plus gives a nice assertion that validates AIR structure a
  little. This is a very minor benefit, which this commit does apply to
  the LLVM and C backends.

* It should allow for more compact ZIR and AIR to be emitted by having
  AstGen emit `repeat` instructions more often rather than having
  `continue` statements `break` to a `block` which is *followed* by a
  `repeat`. This is done in status quo because `repeat` instructions
  only ever cause the direct parent block to repeat. Now that AIR is
  more flexible, this flexibility can be pretty trivially extended to
  ZIR, and we can then emit better ZIR. This commit does not implement
  this.

Support for this feature is currently regressed on all self-hosted
native backends, including x86_64. This support will be added where
necessary before this branch is merged.
2024-09-01 18:30:31 +01:00
mlugg
1b000b90c9
Air: direct representation of ranges in switch cases
This commit modifies the representation of the AIR `switch_br`
instruction to represent ranges in cases. Previously, Sema emitted
different AIR in the case of a range, where the `else` branch of the
`switch_br` contained a simple `cond_br` for each such case which did a
simple range check (`x > a and x < b`). Not only does this add
complexity to Sema, which we would like to minimize, but it also gets in
the way of the implementation of #8220. That proposal turns certain
`switch` statements into a looping construct, and for optimization
purposes, we want to lower this to AIR fairly directly (i.e. without
involving a `loop` instruction). That means we would ideally like a
single instruction to represent the entire `switch` statement, so that
we can dispatch back to it with a different operand as in #8220. This is
not really possible to do correctly under the status quo system.

This commit implements lowering of this new `switch_br` usage in the
LLVM and C backends. The C backend just turns any case containing ranges
entirely into conditionals, as before. The LLVM backend is a little
smarter, and puts scalar items into the `switch` instruction, only using
conditionals for the range cases (which direct to the same bb). All
remaining self-hosted backends are temporarily regressed in the presence
of switch range cases. This functionality will be restored for at least
the x86_64 backend before merge.
2024-09-01 18:30:31 +01:00
Andrew Kelley
e4e91a1314
Merge pull request #21224 from alexrp/mips-gnu-fixes
Fix MIPS PIC level and work around an LLVM bug for `mips(el)-linux-gnueabi(hf)`
2024-08-30 14:47:43 -07:00
Alex Rønne Petersen
5723fcaac1 llvm: Pass EmitOptions to libzigcpp by pointer.
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.
2024-08-30 11:02:12 -07:00
Andrew Kelley
c81219c573 LLVM: use @llvm.used instead of @llvm.compiler.used
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.
2024-08-28 18:07:13 -07:00
Andrew Kelley
9e11c4f60e LLVM: put sancov globals into llvm.compiler.used
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.
2024-08-28 18:07:13 -07:00
Andrew Kelley
1bec824cad LLVM: disable inline 8-bit counters when using trace pc guard 2024-08-28 18:07:13 -07:00
Andrew Kelley
88bba4c154 LLVM: enable sancov pass partially
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.
2024-08-28 18:07:13 -07:00
Andrew Kelley
b8d99a3323 implement code coverage instrumentation manually
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.
2024-08-28 18:07:13 -07:00
mlugg
0fe3fd01dd
std: update std.builtin.Type fields to follow naming conventions
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.
2024-08-28 08:39:59 +01:00
Alex Rønne Petersen
e585103306
llvm: Disable FastISel on MIPS as a workaround for #21215.
Until llvm/llvm-project#106231 trickles down.
2024-08-28 06:19:01 +02:00
Alex Rønne Petersen
7d9edff11d
llvm: Set PIC level 1 for MIPS.
For hysterical raisins, MIPS always uses 1, regardless of `-fpic` vs `-fPIC`.
2024-08-28 06:18:06 +02:00
Jacob Young
8c3f6c72c0 Dwarf: fix and test string format 2024-08-27 02:09:59 -04:00
mlugg
6808ce27bd
compiler,lib,test,langref: migrate @setCold to @branchHint 2024-08-27 00:44:35 +01:00
mlugg
457c94d353
compiler: implement @branchHint, replacing @setCold
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
2024-08-27 00:41:49 +01:00
David Rubin
863f74dcd2
comp: rename module to zcu 2024-08-25 15:17:21 -07:00
David Rubin
80cd53d3bb
sema: clean-up {union,struct}FieldAlignment and friends
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.
2024-08-25 15:16:46 -07:00
David Rubin
b4bb64ce78
sema: rework type resolution to use Zcu when possible 2024-08-25 15:16:42 -07:00
Jacob Young
62f7276501 Dwarf: emit info about inline call sites 2024-08-20 08:09:33 -04:00
Matthew Lugg
54e48f7b7d
Merge pull request #21128 from mlugg/incremental
incremental: more progress
2024-08-19 06:30:54 +01:00
Andrew Kelley
c6677be53b llvm: disable instrumentation in naked functions
closes #21130
2024-08-18 20:36:27 -07:00
mlugg
de49a9a173
Zir: add instructions to fetch std.builtin types
This replaces the constant `Zir.Inst.Ref` tags (and the analagous tags
in `Air.Inst.Ref`, `InternPool.Index`) referring to types in
`std.builtin` with a ZIR instruction `extended(builtin_type(...))` which
instructs Sema to fetch such a type, effectively as if it were a
shorthand for the ZIR for `@import("std").builtin.xyz`.

Previously, this was achieved through constant tags in `Ref`. The
analagous `InternPool` indices began as `simple_type` values, and were
later rewritten to the correct type information. This system was kind of
brittle, and more importantly, isn't compatible with incremental
compilation of std, since incremental compilation relies on the ability
to recreate types at different indices when they change. Replacing the
old system with this instruction slightly increases the size of ZIR, but
it simplifies logic and allows incremental compilation to work correctly
on the standard library.

This shouldn't have a significant impact on ZIR size or compiler
performance, but I will take measurements in the PR to confirm this.
2024-08-18 18:10:59 +01:00
mlugg
895267c916 frontend: incremental progress
This commit makes more progress towards incremental compilation, fixing
some crashes in the frontend. Notably, it fixes the regressions introduced
by #20964. It also cleans up the "outdated file root" mechanism, by
virtue of deleting it: we now detect outdated file roots just after
updating ZIR refs, and re-scan their namespaces.
2024-08-17 18:50:10 -04:00
Andrew Kelley
11176d22f8
Merge pull request #21073 from alexrp/test-changes
`test`: QoL for port work, more mips re-enablement
2024-08-15 22:23:48 -07:00
Alex Rønne Petersen
7a8e86e46c
llvm: Don't emit extra debug instructions for dbg_var_val in naked functions. 2024-08-15 10:56:33 +02:00
Alex Rønne Petersen
acad2fae44
llvm: Remove the aarch64-windows @llvm.dbg.value() workaround.
https://github.com/llvm/llvm-project/issues/56484
2024-08-15 10:56:33 +02:00
Alex Rønne Petersen
2bf244c0e9
llvm: Always omit the frame pointer for naked functions. 2024-08-15 10:56:33 +02:00
Andrew Kelley
78fb9c0a17
Merge pull request #21031 from linusg/std-target-naming
std.Target: Function naming cleanup
2024-08-14 10:36:24 -07:00
Alex Rønne Petersen
819fe51a7e
llvm: Disable f128 on powerpc*-aix.
https://github.com/llvm/llvm-project/issues/101545
2024-08-13 23:30:43 +02:00
Alex Rønne Petersen
2f101e2b6e
llvm: Disable f128 on mips64(el).
https://github.com/llvm/llvm-project/issues/96432
2024-08-13 23:30:43 +02:00
Alex Rønne Petersen
18e94c355e
llvm: Also disable f16/f128 on aarch64_be with soft float. 2024-08-13 23:30:43 +02:00
Robin Voetter
bcfc7cf13c
nvptx: add implementations for GPU builtins 2024-08-13 20:07:23 +02:00
Andrew Kelley
f988cea825
Merge pull request #21019 from alexrp/target-os-cleanup
`std.Target`: Remove `minix` and `liteos`, rename `glsl450` to `opengl`, and some minor housekeeping
2024-08-12 16:06:57 -07:00
Alex Rønne Petersen
82b0f44721 llvm: Disable lowering to f16 on s390x.
https://github.com/llvm/llvm-project/issues/50374
2024-08-12 16:01:59 -07:00
Alex Rønne Petersen
a1a823f69c llvm: Disable lowering to f128 on sparc32.
efc6b50d2d/llvm/lib/Target/Sparc/SparcISelLowering.cpp (L561-L562)
2024-08-12 16:01:34 -07:00
Alex Rønne Petersen
9f1fb45201
llvm: Move some OS selection prongs for clarity.
This makes it clearer which OSs are not known to or supported by LLVM at all vs
the ones where we're intentionally passing choosing "unknown".
2024-08-12 09:03:08 +02:00
Alex Rønne Petersen
8af4d65108
std.Target: Remove liteos OS tag.
It has not seen development in 4 years.

https://github.com/LiteOS/LiteOS/commits/master
2024-08-12 08:59:49 +02:00
Alex Rønne Petersen
e211dce6fc
std.Target: Remove minix OS tag.
It has not seen development in 6 years. RIP.

* https://github.com/Stichting-MINIX-Research-Foundation/minix/commits/master
* https://groups.google.com/g/minix3/c/nUG1NwxXXkg
2024-08-12 08:59:49 +02:00
Alex Rønne Petersen
eb4539a27d
std.Target: Rename glsl450 Arch tag to opengl.
Versions can simply use the normal version range mechanism, or alternatively an
Abi tag if that makes more sense. For now, we only care about 4.5 anyway.
2024-08-12 08:59:47 +02:00
Andrew Kelley
61dac74128
Merge pull request #20985 from alexrp/gpu-nonsense
Follow-up on `std.Target` GPU changes in #20960
2024-08-11 20:23:28 -07:00
Linus Groh
4ef956ef14 std.Target: Rename c_type_* functions to camel case
From https://ziglang.org/documentation/master/#Names:

> If `x` is otherwise callable, then `x` should be `camelCase`.
2024-08-12 00:36:51 +01:00
mlugg
153e7d6235
frontend: give all container types namespaces
Eliding the namespace when a container type has no decls was an
experiment in saving memory, but it ended up causing more trouble than
it was worth in various places. So, take the small memory hit for
reified types, and just give every container type a namespace.
2024-08-11 07:30:21 +01:00
mlugg
548a087faf
compiler: split Decl into Nav and Cau
The type `Zcu.Decl` in the compiler is problematic: over time it has
gained many responsibilities. Every source declaration, container type,
generic instantiation, and `@extern` has a `Decl`. The functions of
these `Decl`s are in some cases entirely disjoint.

After careful analysis, I determined that the two main responsibilities
of `Decl` are as follows:
* A `Decl` acts as the "subject" of semantic analysis at comptime. A
  single unit of analysis is either a runtime function body, or a
  `Decl`. It registers incremental dependencies, tracks analysis errors,
  etc.
* A `Decl` acts as a "global variable": a pointer to it is consistent,
  and it may be lowered to a specific symbol by the codegen backend.

This commit eliminates `Decl` and introduces new types to model these
responsibilities: `Cau` (Comptime Analysis Unit) and `Nav` (Named
Addressable Value).

Every source declaration, and every container type requiring resolution
(so *not* including `opaque`), has a `Cau`. For a source declaration,
this `Cau` performs the resolution of its value. (When #131 is
implemented, it is unsolved whether type and value resolution will share
a `Cau` or have two distinct `Cau`s.) For a type, this `Cau` is the
context in which type resolution occurs.

Every non-`comptime` source declaration, every generic instantiation,
and every distinct `extern` has a `Nav`. These are sent to codegen/link:
the backends by definition do not care about `Cau`s.

This commit has some minor technically-breaking changes surrounding
`usingnamespace`. I don't think they'll impact anyone, since the changes
are fixes around semantics which were previously inconsistent (the
behavior changed depending on hashmap iteration order!).

Aside from that, this changeset has no significant user-facing changes.
Instead, it is an internal refactor which makes it easier to correctly
model the responsibilities of different objects, particularly regarding
incremental compilation. The performance impact should be negligible,
but I will take measurements before merging this work into `master`.

Co-authored-by: Jacob Young <jacobly0@users.noreply.github.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2024-08-11 07:29:41 +01:00
Andrew Kelley
61fbdebd61
Merge pull request #20969 from alexrp/llvm-unsup-targets
`llvm`: Fix hasLlvmSupport() for dxil, spirv[32,64], and kalimba.
2024-08-07 22:50:08 -07:00
Alex Rønne Petersen
4e56653628
llvm: Add a comment clarifying our mapping of the opencl OS tag. 2024-08-07 21:42:22 +02:00
Alex Rønne Petersen
c11b997662
llvm: Set vendor tag in target triple for GPU backends. 2024-08-07 21:31:39 +02:00
Alex Rønne Petersen
746f20d21f
llvm: Use unreachable in targetTriple() for targets without LLVM support. 2024-08-07 09:39:42 +02:00
Alex Rønne Petersen
a9f68410d0
llvm: Clarify in initializeLLVMTarget() that there's no kalimba backend. 2024-08-07 09:39:42 +02:00
Alex Rønne Petersen
e5c75479c2
std.Target: Rework isPPC()/isPPC64() functions.
* Rename isPPC() -> isPowerPC32().
* Rename isPPC64() -> isPowerPC64().
* Add new isPowerPC() function which covers both.

There was confusion even in the standard library about what isPPC() meant. This
change makes these functions work how I think most people actually expect them
to work, and makes them consistent with isMIPS(), isSPARC(), etc.

I chose to rename from PPC to PowerPC because 1) it's more consistent with the
other functions, and 2) it'll cause loud rather than silent breakage for anyone
who might have been depending on isPPC() while misunderstanding it.
2024-08-01 20:58:05 +02:00
Alex Rønne Petersen
b49b7501cf
std.Target: Remove cloudabi OS tag.
It's discontinued in favor of WASI.

https://github.com/NuxiNL/cloudlibc
2024-07-30 06:30:26 +02:00