515 Commits

Author SHA1 Message Date
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
David Rubin
f777b29832
fix up merge conflicts with master 2024-08-25 22:43:57 -07:00
David Rubin
b4bb64ce78
sema: rework type resolution to use Zcu when possible 2024-08-25 15:16:42 -07: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
Jakub Konka
df9ac485da codegen: fix rebase gone wrong 2024-08-17 08:31:16 +02:00
Jakub Konka
96441bd829 macho: update codegen and linker to distributed jump table approach 2024-08-17 08:14:38 +02:00
Jacob Young
ef11bc9899 Dwarf: rework self-hosted debug info from scratch
This is in preparation for incremental and actually being able to debug
executables built by the x86_64 backend.
2024-08-16 15:22:55 -04:00
Jakub Konka
0fd0b11bc4 riscv: do not emit GOT relocations for special linker symbols 2024-08-15 10:21:20 +02:00
Jakub Konka
8a0cb7002e elf: introduce Symbol.flags.is_extern_ptr for refs potentially needing GOT 2024-08-15 10:05:41 +02:00
Jakub Konka
16abf51cee x86_64: handle lea_symbol returned by genNavRef 2024-08-13 13:30:24 +02: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
Jakub Konka
41e9b8b6c8 elf: fix compile errors 2024-08-07 10:21:02 +02:00
David Rubin
574028ed5e
riscv: boilerplate for creating lazy functions 2024-07-26 04:05:44 -07:00
Jakub Konka
2b84592858 macho: run more things in parallel 2024-07-22 12:06:02 +02:00
Jacob Young
4f742c4cfc dev: introduce dev environments that enable compiler feature sets 2024-07-19 22:35:33 -07:00
Jakub Konka
5b4c0cc1f9 macho: update ZigObject to use new ownership model 2024-07-18 09:13:08 +02:00
Jakub Konka
9d9b5a11e8
Merge pull request #20474 from Rexicon226/riscv
more RISC-V backend progress
2024-07-17 08:39:44 +02:00
mlugg
f84a4953d2
Value: eliminate static recursion loop from value printing 2024-07-16 11:38:21 +01:00
David Rubin
0460572899
riscv: @atomicRmw
Now we generate debug undefined constants when the user asks for them to dedup across the function decl. This takes 2 instructions instead of 7 in the RISC-V backend.

TODO, we need to dedupe across function decl boundaries.
2024-07-14 23:02:32 -07:00
Jacob Young
a1053e8e1d InternPool: add and use a mutate mutex for each list
This allows the mutate mutex to only be locked during actual grows,
which are rare. For the lists that didn't previously have a mutex, this
change has little effect since grows are rare and there is zero
contention on a mutex that is only ever locked by one thread.  This
change allows `extra` to be mutated without racing with a grow.
2024-07-13 04:47:38 -04:00
Jacob Young
c2316c5228 InternPool: make global_error_set thread-safe 2024-07-10 21:39:55 -04:00
Jacob Young
ca02266157 Zcu: pass PerThread to intern pool string functions 2024-07-07 22:59:52 -04:00
Jacob Young
525f341f33 Zcu: introduce PerThread and pass to all the functions 2024-07-07 22:59:52 -04:00
Andrew Kelley
30ec43a6c7 Zcu: extract permanent state from File
Primarily, this commit removes 2 fields from File, relying on the data
being stored in the `files` field, with the key as the path digest, and
the value as the struct decl corresponding to the File. This table is
serialized into the compiler state that survives between incremental
updates.

Meanwhile, the File struct remains ephemeral data that can be
reconstructed the first time it is needed by the compiler process, as
well as operated on by independent worker threads.

A key outcome of this commit is that there is now a stable index that
can be used to refer to a File. This will be needed when serializing
error messages to survive incremental compilation updates.
2024-07-04 17:51:35 -07:00
mlugg
2f0f1efa6f
compiler: type.zig -> Type.zig 2024-07-04 21:01:42 +01:00
mlugg
ded5c759f8
Zcu: store LazySrcLoc in error messages
This change modifies `Zcu.ErrorMsg` to store a `Zcu.LazySrcLoc` rather
than a `Zcu.SrcLoc`. Everything else is dominoes.

The reason for this change is incremental compilation. If a failed
`AnalUnit` is up-to-date on an update, we want to re-use the old error
messages. However, the file containing the error location may have been
modified, and `SrcLoc` cannot survive such a modification. `LazySrcLoc`
is designed to be correct across incremental updates. Therefore, we
defer source location resolution until `Compilation` gathers the compile
errors into the `ErrorBundle`.
2024-07-04 21:01:41 +01:00
Andrew Kelley
0fcd59eada rename src/Module.zig to src/Zcu.zig
This patch is a pure rename plus only changing the file path in
`@import` sites, so it is expected to not create version control
conflicts, even when rebasing.
2024-06-22 22:59:56 -04:00
mlugg
d0e74ffe52
compiler: rework comptime pointer representation and access
We've got a big one here! This commit reworks how we represent pointers
in the InternPool, and rewrites the logic for loading and storing from
them at comptime.

Firstly, the pointer representation. Previously, pointers were
represented in a highly structured manner: pointers to fields, array
elements, etc, were explicitly represented. This works well for simple
cases, but is quite difficult to handle in the cases of unusual
reinterpretations, pointer casts, offsets, etc. Therefore, pointers are
now represented in a more "flat" manner. For types without well-defined
layouts -- such as comptime-only types, automatic-layout aggregates, and
so on -- we still use this "hierarchical" structure. However, for types
with well-defined layouts, we use a byte offset associated with the
pointer. This allows the comptime pointer access logic to deal with
reinterpreted pointers far more gracefully, because the "base address"
of a pointer -- for instance a `field` -- is a single value which
pointer accesses cannot exceed since the parent has undefined layout.
This strategy is also more useful to most backends -- see the updated
logic in `codegen.zig` and `codegen/llvm.zig`. For backends which do
prefer a chain of field and elements accesses for lowering pointer
values, such as SPIR-V, there is a helpful function in `Value` which
creates a strategy to derive a pointer value using ideally only field
and element accesses. This is actually more correct than the previous
logic, since it correctly handles pointer casts which, after the dust
has settled, end up referring exactly to an aggregate field or array
element.

In terms of the pointer access code, it has been rewritten from the
ground up. The old logic had become rather a mess of special cases being
added whenever bugs were hit, and was still riddled with bugs. The new
logic was written to handle the "difficult" cases correctly, the most
notable of which is restructuring of a comptime-only array (for
instance, converting a `[3][2]comptime_int` to a `[2][3]comptime_int`.
Currently, the logic for loading and storing work somewhat differently,
but a future change will likely improve the loading logic to bring it
more in line with the store strategy. As far as I can tell, the rewrite
has fixed all bugs exposed by #19414.

As a part of this, the comptime bitcast logic has also been rewritten.
Previously, bitcasts simply worked by serializing the entire value into
an in-memory buffer, then deserializing it. This strategy has two key
weaknesses: pointers, and undefined values. Representations of these
values at comptime cannot be easily serialized/deserialized whilst
preserving data, which means many bitcasts would become runtime-known if
pointers were involved, or would turn `undefined` values into `0xAA`.
The new logic works by "flattening" the datastructure to be cast into a
sequence of bit-packed atomic values, and then "unflattening" it; using
serialization when necessary, but with special handling for `undefined`
values and for pointers which align in virtual memory. The resulting
code is definitely slower -- more on this later -- but it is correct.

The pointer access and bitcast logic required some helper functions and
types which are not generally useful elsewhere, so I opted to split them
into separate files `Sema/comptime_ptr_access.zig` and
`Sema/bitcast.zig`, with simple re-exports in `Sema.zig` for their small
public APIs.

Whilst working on this branch, I caught various unrelated bugs with
transitive Sema errors, and with the handling of `undefined` values.
These bugs have been fixed, and corresponding behavior test added.

In terms of performance, I do anticipate that this commit will regress
performance somewhat, because the new pointer access and bitcast logic
is necessarily more complex. I have not yet taken performance
measurements, but will do shortly, and post the results in this PR. If
the performance regression is severe, I will do work to to optimize the
new logic before merge.

Resolves: #19452
Resolves: #19460
2024-04-17 13:41:25 +01:00
Jacob Young
7611d90ba0 InternPool: remove slice from byte aggregate keys
This deletes a ton of lookups and avoids many UAF bugs.

Closes #19485
2024-04-08 13:24:08 -04:00
Jacob Young
5a41704f7e cbe: rewrite CType
Closes #14904
2024-03-30 20:50:48 -04:00
Jakub Konka
9dac8db2df
Merge pull request #19430 from ziglang/dwarf-ub
link: fix undefined memory being written out in dwarf and codegen
2024-03-27 17:29:30 +01:00
mlugg
2a245e3b78
compiler: eliminate TypedValue
The only logic which remained in this file was the Value printing logic.
This has been moved into a new `print_value.zig`.
2024-03-26 13:48:07 +00:00
mlugg
a61def10c6
compiler: eliminate most usages of TypedValue 2024-03-26 13:48:07 +00:00
mlugg
26a94e8481
Zcu: eliminate Decl.alive field
Legacy anon decls now have three uses:
* Type owner decls
* Function owner decls
* `@export` and `@extern`

Therefore, there are no longer any cases where we wish to explicitly
omit legacy anon decls from the binary. This means we can remove the
concept of an "alive" vs "dead" `Decl`, which also allows us to remove
the separate `anon_work_queue` in `Compilation`.
2024-03-26 13:48:06 +00:00
mlugg
884d957b6c
compiler: eliminate legacy Value representation
Good riddance!

Most of these changes are trivial. There's a fix for a minor bug this
exposed in `Value.readFromPackedMemory`, but aside from that, it's all
just things like changing `intern` calls to `toIntern`.
2024-03-26 13:48:06 +00:00
mlugg
c6f3e9d79c
Zcu.Decl: remove ty field
`Decl` can no longer store un-interned values, so this field is now
unnecessary. The type can instead be fetched with the new `typeOf`
helper method, which just gets the type of the Decl's `Value`.
2024-03-26 13:48:06 +00:00
Jakub Konka
ae1b2bfcad dwarf+codegen: use appendNTimes instead of writer().writeByteNTimes 2024-03-25 23:48:39 +01:00
mlugg
9c3670fc93
compiler: implement analysis-local comptime-mutable memory
This commit changes how we represent comptime-mutable memory
(`comptime var`) in the compiler in order to implement the intended
behavior that references to such memory can only exist at comptime.

It does *not* clean up the representation of mutable values, improve the
representation of comptime-known pointers, or fix the many bugs in the
comptime pointer access code. These will be future enhancements.

Comptime memory lives for the duration of a single Sema, and is not
permitted to escape that one analysis, either by becoming runtime-known
or by becoming comptime-known to other analyses. These restrictions mean
that we can represent comptime allocations not via Decl, but with state
local to Sema - specifically, the new `Sema.comptime_allocs` field. All
comptime-mutable allocations, as well as any comptime-known const allocs
containing references to such memory, live in here. This allows for
relatively fast checking of whether a value references any
comptime-mtuable memory, since we need only traverse values up to
pointers: pointers to Decls can never reference comptime-mutable memory,
and pointers into `Sema.comptime_allocs` always do.

This change exposed some faulty pointer access logic in `Value.zig`.
I've fixed the important cases, but there are some TODOs I've put in
which are definitely possible to hit with sufficiently esoteric code. I
plan to resolve these by auditing all direct accesses to pointers (most
of them ought to use Sema to perform the pointer access!), but for now
this is sufficient for all realistic code and to get tests passing.

This change eliminates `Zcu.tmp_hack_arena`, instead using the Sema
arena for comptime memory mutations, which is possible since comptime
memory is now local to the current Sema.

This change should allow `Decl` to store only an `InternPool.Index`
rather than a full-blown `ty: Type, val: Value`. This commit does not
perform this refactor.
2024-03-25 14:49:41 +00:00
Jakub Konka
e599ed4a5f codegen: actually write out padding for packed structs upfront 2024-03-25 00:00:33 +01:00
Tristan Ross
099f3c4039
std.builtin: make container layout fields lowercase 2024-03-11 07:09:07 -07:00
mlugg
975b859377
InternPool: create specialized functions for loading namespace types
Namespace types (`struct`, `enum`, `union`, `opaque`) do not use
structural equality - equivalence is based on their Decl index (and soon
will change to AST node + captures). However, we previously stored all
other information in the corresponding `InternPool.Key` anyway. For
logical consistency, it makes sense to have the key only be the true key
(that is, the Decl index) and to load all other data through another
function. This introduces those functions, by the name of
`loadStructType` etc. It's a big diff, but most of it is no-brainer
changes.

In future, it might be nice to eliminate a bunch of the loaded state in
favour of accessor functions on the `LoadedXyzType` types (like how we
have `LoadedUnionType.size()`), but that can be explored at a later
date.
2024-03-06 21:26:37 +00:00
Andrew Kelley
7b37bc771b move Zir to std.zig.Zir
Part of an effort to ship more of the compiler in source form.
2024-02-26 21:35:30 -07:00
Jacob Young
2fdc9e6ae8 x86_64: implement @shuffle 2024-02-25 11:22:10 +01:00
Jacob Young
6f08e17229 InternPool: make more use of NullTerminatedString.Slice
This should avoid the random pointer invalidation crashes.

Closes #18954
2024-02-16 00:27:25 -08:00
Andrew Kelley
78f15bc714 compiler: rename value.zig to Value.zig
This commit only does the file rename to be friendlier to version
control conflicts.
2024-02-05 18:13:07 -07:00
mlugg
9eda6ccefc InternPool: use separate key for slices
This change eliminates some problematic recursive logic in InternPool,
and provides a safer API.
2024-02-02 11:02:03 +00:00
Jakub Konka
55f57ceb2e macho: prep for lowering TLS variables 2024-01-24 12:34:42 +01:00
Jakub Konka
0143dd8fdc macho: fix '_' prefixing rules for exports 2024-01-24 12:34:41 +01:00
Jakub Konka
a8629fb850 macho: fix symbol index dereference in codegen wrt ZigObject
This is incredibly confusing and I really need to simplify it.
Elf also possesses this shortcoming so once I get Coff up to speed
it should hopefully become clear on how to refactor this.
2024-01-24 12:34:41 +01:00
Jakub Konka
a79a038e61 codegen: implement more missing bits 2024-01-24 12:34:41 +01:00