Commit Graph

1898 Commits

Author SHA1 Message Date
Alex Rønne Petersen
0b67463b92 riscv64: Support the fp alias for register s0 in inline assembly. 2024-12-11 00:09:22 +01:00
Jacob Young
c894ac09a3 dwarf: fix stepping through an inline loop containing one statement
Previously, stepping from the single statement within the loop would
always exit the loop because all of the code unrolled from the loop is
associated with the same line and treated by the debugger as one line.
2024-11-24 17:28:12 -05:00
mlugg
bbbc95afd0 AstGen: add missing rvalue call to labeledBlockExpr
...and fix a minor x86_64 backend bug exposed by this fix.

Resolves: #21974
2024-11-12 14:51:10 +00:00
mlugg
d11bbde5f9 compiler: remove anonymous struct types, unify all tuples
This commit reworks how anonymous struct literals and tuples work.

Previously, an untyped anonymous struct literal
(e.g. `const x = .{ .a = 123 }`) was given an "anonymous struct type",
which is a special kind of struct which coerces using structural
equivalence. This mechanism was a holdover from before we used
RLS / result types as the primary mechanism of type inference. This
commit changes the language so that the type assigned here is a "normal"
struct type. It uses a form of equivalence based on the AST node and the
type's structure, much like a reified (`@Type`) type.

Additionally, tuples have been simplified. The distinction between
"simple" and "complex" tuple types is eliminated. All tuples, even those
explicitly declared using `struct { ... }` syntax, use structural
equivalence, and do not undergo staged type resolution. Tuples are very
restricted: they cannot have non-`auto` layouts, cannot have aligned
fields, and cannot have default values with the exception of `comptime`
fields. Tuples currently do not have optimized layout, but this can be
changed in the future.

This change simplifies the language, and fixes some problematic
coercions through pointers which led to unintuitive behavior.

Resolves: #16865
2024-10-31 20:42:53 +00:00
Andrew Kelley
ba2d006634 link.File.Wasm: remove the "files" abstraction
Removes the `files` field from the Wasm linker, storing the ZigObject
as its own field instead using a tagged union.

This removes a layer of indirection when accessing the ZigObject, and
untangles logic so that we can introduce a "pre-link" phase that
prepares the linker state to handle only incremental updates to the
ZigObject and then minimize logic inside flush().

Furthermore, don't make array elements store their own indexes, that's
always a waste.

Flattens some of the file system hierarchy and unifies variable names
for easier refactoring.

Introduces type safety for optional object indexes.
2024-10-30 19:34:58 -07:00
Jakub Konka
56996a2809 link/Coff: simplify file structure by collapsing all files into Coff.zig (#21761)
* coff: collapse Coff/lld.zig logic into Coff.zig

* coff: rename std.coff uses to coff_util

* coff: rename self to coff for *Coff references

* coff: collapse Coff/Atom.zig logic into Coff.zig

* coff: collapse Coff/Relocation.zig logic into Coff.zig

* coff: collapse Coff/ImportTable.zig logic into Coff.zig

* coff: remove unused Coff/Object.zig

* link/Coff: fix rebase gone wrong
2024-10-24 13:50:02 +00:00
Andrew Kelley
989e782a01 link.Elf.ZigObject.updateFunc: reduce data dependencies
Unfortunately it's not a complete solution, so a follow-up commit will
need to do something more drastic like not do the linker task queue at
the same time as codegen task queue.

From that point, it is possible to do more work at the same time but
that should be a separate branch. This one has gotten big enough.
2024-10-23 16:27:39 -07:00
mlugg
73f4c68005 x86_64: handle incoming stack alignment 2024-10-19 19:46:07 +01:00
mlugg
387965a696 x86_64,riscv64: fix incorrect incoming_stack_alignment handling
The whole motivation behind this proposal in the first place was that
the LLVM backend disagrees with the self-hosted backends on what
`@setAlignStack` meant, so we can't just translate the old logic to the
new system! These backends can introduce support for overriding
`incoming_stack_alignment` later on.
2024-10-19 19:46:06 +01:00
mlugg
2d9a167cd2 std.Target: rename defaultCCallingConvention and Cpu.Arch.fromCallconv 2024-10-19 19:15:23 +01:00
mlugg
4be0cf30fc test: update for CallingConvention changes
This also includes some compiler and std changes to correct error
messages which weren't properly updated before.
2024-10-19 19:15:23 +01:00
mlugg
ec19086aa0 compiler: remove @setAlignStack
This commit finishes implementing #21209 by removing the
`@setAlignStack` builtin in favour of `CallingConvention` payloads. The
x86_64 backend is updated to use the stack alignment given in the
calling convention (the LLVM backend was already updated in a previous
commit).

Resolves: #21209
2024-10-19 19:15:23 +01:00
mlugg
bc797a97b1 std: update for new CallingConvention
The old `CallingConvention` type is replaced with the new
`NewCallingConvention`. References to `NewCallingConvention` in the
compiler are updated accordingly. In addition, a few parts of the
standard library are updated to use the new type correctly.
2024-10-19 19:15:23 +01:00
mlugg
51706af908 compiler: introduce new CallingConvention
This commit begins implementing accepted proposal #21209 by making
`std.builtin.CallingConvention` a tagged union.

The stage1 dance here is a little convoluted. This commit introduces the
new type as `NewCallingConvention`, keeping the old `CallingConvention`
around. The compiler uses `std.builtin.NewCallingConvention`
exclusively, but when fetching the type from `std` when running the
compiler (e.g. with `getBuiltinType`), the name `CallingConvention` is
used. This allows a prior build of Zig to be used to build this commit.
The next commit will update `zig1.wasm`, and then the compiler and
standard library can be updated to completely replace
`CallingConvention` with `NewCallingConvention`.

The second half of #21209 is to remove `@setAlignStack`, which will be
implemented in another commit after updating `zig1.wasm`.
2024-10-19 19:08:59 +01:00
David Rubin
e131a2c8e2 implement packed struct equality (#21679) 2024-10-12 20:59:12 -07:00
Samuel Fiedler
58349b2c8e arch/aarch64/Mir: fix spelling (pseudo instead of psuedo) 2024-10-10 13:25:52 -07:00
Jacob Young
d748cfc2b7 x86_64: print pseudo instructions in wip_mir log 2024-10-09 07:48:10 -04:00
Jacob Young
c127c06fd7 Dwarf: implement and test lexical blocks 2024-10-09 07:48:09 -04:00
Pavel Verigo
4b89a4c7cb stage2-wasm: airRem + airMod for floats 2024-10-08 20:58:15 +02:00
David Rubin
043b1adb8d remove @fence (#21585)
closes #11650
2024-10-04 22:21:27 +00:00
Maciej 'vesim' Kuliński
4ceefca14b mips: use byval for all integer types 2024-09-25 07:37:03 -07:00
David Rubin
7f60d2e465 riscv: fix up ptr_elem_val to not doubly lock 2024-09-16 16:42:42 +01:00
David Rubin
bc161430b0 riscv: implement optional_payload_ptr_set 2024-09-12 20:29:10 -04:00
Linus Groh
8588964972 Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Jacob Young
e046977354 codegen: implement output to the .debug_info section 2024-09-10 12:27:57 -04:00
Maciej 'vesim' Kuliński
fb0028a0d7 mips: fix C ABI compatibility 2024-09-07 23:46:30 -07:00
Andrew Kelley
3929cac154 Merge pull request #21257 from mlugg/computed-goto-3
compiler: implement labeled switch/continue
2024-09-04 18:31:28 -07:00
David Rubin
0d295d7635 riscv: implement switch_dispatch & loop_switch_br 2024-09-01 18:31:01 +01:00
David Rubin
97ed239203 riscv: implement repeat and the new switch_br 2024-09-01 18:31:01 +01:00
Jacob Young
d5b01df3c8 x86_64: implement loop_switch_br and switch_dispatch 2024-09-01 18:31:01 +01:00
mlugg
fd70d9db99 x86_64: un-regress loop and switch_br
This does *not* yet implement the new `loop_switch_br` instruction.
2024-09-01 18:30:32 +01:00
mlugg
cb68c0917a wasm: un-regress loop and switch_br
`.loop` is also a block, so the block_depth must be stored *after* block
creation, ensuring a correct block_depth to jump back to when receiving
`.repeat`.

This also un-regresses `switch_br` which now correctly handles ranges
within cases. It supports it for both jump tables as well as regular
conditional branches.
2024-09-01 18:30:31 +01:00
mlugg
5e12ca9fe3 compiler: implement labeled switch/continue 2024-09-01 18:30:31 +01:00
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
David Rubin
fbac7afa0f riscv: implement errunion_payload_ptr_set 2024-09-01 17:34:06 +01:00
mlugg
c62487da76 compiler: avoid field/decl name conflicts
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.
2024-08-29 23:43:52 +01: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
Jacob Young
f289b82d0e Dwarf: implement .eh_frame 2024-08-27 03:55:56 -04: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
f777b29832 fix up merge conflicts with master 2024-08-25 22:43:57 -07:00
David Rubin
1c1feba08e remove mod aliases for Zcus 2024-08-25 15:17:40 -07: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
cbaff43b2a Dwarf: add missing var args info on function decls 2024-08-22 19:53:04 -04:00
Jakub Konka
d3d5ed992c elf: emit .rela.debug* sections for relocatable if required 2024-08-21 01:43:21 -04:00
Jacob Young
55864e98e0 x86_64: support more dwarf locations 2024-08-20 15:08:23 -04:00