1184 Commits

Author SHA1 Message Date
Andrew Kelley
bad836a69b Compilation: revert some stuff 2025-07-19 19:57:37 -07:00
Andrew Kelley
93378e2e7b std.zig: finish updating to new I/O API 2025-07-19 19:57:37 -07:00
Andrew Kelley
6e55898661 Compilation: refactor std.fs -> fs
no functional change
2025-07-18 06:42:54 -07:00
Andrew Kelley
c4776d66af update compiler 2025-07-16 17:20:02 -07:00
antlilja
e3b79d65d8 LLVM: Move pt field from Object to NavGen
* LLVM: Pass correct tid to emit
* Store stack trace type in Zcu
* Don't use pt.errorIntType in LLVM backend
2025-07-13 12:16:17 -07:00
Joost Doornbos
3974540e5a Fix memory leak in CObject.Diag.Bundle.destroy() 2025-07-13 04:38:58 +02:00
Andrew Kelley
5378fdb153 std.fmt: fully remove format string from format methods
Introduces `std.fmt.alt` which is a helper for calling alternate format
methods besides one named "format".
2025-07-07 22:43:53 -07:00
Andrew Kelley
30c2921eb8 compiler: update a bunch of format strings 2025-07-07 22:43:52 -07:00
Andrew Kelley
d5c97fded5 compiler: fix a bunch of format strings 2025-07-07 22:43:52 -07:00
Andrew Kelley
756a2dbf1a compiler: upgrade various std.io API usage 2025-07-07 22:43:52 -07:00
Andrew Kelley
941bc37193 compiler: update all instances of std.fmt.Formatter 2025-07-07 22:43:52 -07:00
Andrew Kelley
f71d97e4cb update compiler source to new APIs 2025-07-07 22:43:52 -07:00
Andrew Kelley
0e37ff0d59 std.fmt: breaking API changes
added adapter to AnyWriter and GenericWriter to help bridge the gap
between old and new API

make std.testing.expectFmt work at compile-time

std.fmt no longer has a dependency on std.unicode. Formatted printing
was never properly unicode-aware. Now it no longer pretends to be.

Breakage/deprecations:
* std.fs.File.reader -> std.fs.File.deprecatedReader
* std.fs.File.writer -> std.fs.File.deprecatedWriter
* std.io.GenericReader -> std.io.Reader
* std.io.GenericWriter -> std.io.Writer
* std.io.AnyReader -> std.io.Reader
* std.io.AnyWriter -> std.io.Writer
* std.fmt.format -> std.fmt.deprecatedFormat
* std.fmt.fmtSliceEscapeLower -> std.ascii.hexEscape
* std.fmt.fmtSliceEscapeUpper -> std.ascii.hexEscape
* std.fmt.fmtSliceHexLower -> {x}
* std.fmt.fmtSliceHexUpper -> {X}
* std.fmt.fmtIntSizeDec -> {B}
* std.fmt.fmtIntSizeBin -> {Bi}
* std.fmt.fmtDuration -> {D}
* std.fmt.fmtDurationSigned -> {D}
* {} -> {f} when there is a format method
* format method signature
  - anytype -> *std.io.Writer
  - inferred error set -> error{WriteFailed}
  - options -> (deleted)
* std.fmt.Formatted
  - now takes context type explicitly
  - no fmt string
2025-07-07 22:43:51 -07:00
Andrew Kelley
0b3f0124dc std.io: move getStdIn, getStdOut, getStdErr functions to fs.File
preparing to rearrange std.io namespace into an interface

how to upgrade:

std.io.getStdIn() -> std.fs.File.stdin()
std.io.getStdOut() -> std.fs.File.stdout()
std.io.getStdErr() -> std.fs.File.stderr()
2025-07-07 22:43:51 -07:00
Andrew Kelley
aa52bb8327 zig fmt 2025-07-07 13:39:16 -07:00
Alex Rønne Petersen
1f1082e36d
wasi: Build emulated libraries into libc.a
This matches what we do for small helper libraries like this in MinGW-w64. It
simplifies the compiler a bit, and also means the build system doesn't have to
treat these library names specially.

Closes #24325.
2025-07-06 20:05:18 +02:00
Alex Rønne Petersen
b461d07a54 Sema: Stop adding Windows implib link inputs for extern "..." syntax.
Closes #23971.
2025-07-06 01:00:18 +02:00
Ryan Liptak
09f4e2d9d1 resinator: Fix include directory detection when cross-compiling from certain host archs
Previously, resinator would use the host arch as the target arch when looking for windows-gnu include directories. However, Zig only thinks it can provide a libc for targets specified in the `std.zig.target.available_libcs` array, which only includes a few for windows-gnu. Therefore, when cross-compiling from a host architecture that doesn't have a windows-gnu target in the available_libcs list, resinator would fail to detect the MinGW include directories.

Now, the custom option `/:target` is passed to `zig rc` which is intended for the COFF object file target, but can be re-used for the include directory target as well. For the include directory target, resinator will convert the MachineType to the relevant arch, or fail if there is no  equivalent arch/no support for detecting the includes for the MachineType (currently 64-bit Itanium and EBC).

Fixes the `windows_resources` standalone test failing when the host is, for example, `riscv64-linux`.
2025-06-28 19:52:18 -07:00
Jacob Young
ed37a1a33c coff: add hack to build a compiler-rt dynamic library
This is not meant to be a long-term solution, but it's the easiest thing
to get working quickly at the moment. The main intention of this hack is
to allow more tests to be enabled. By the time the coff linker is far
enough along to be enabled by default, this will no longer be required.
2025-06-19 18:41:12 -04:00
Jacob Young
e92b129063 Compilation: fix use after free
Closes #23967
2025-06-19 18:41:11 -04:00
Jacob Young
917640810e Target: pass and use locals by pointer instead of by value
This struct is larger than 256 bytes and code that copies it
consistently shows up in profiles of the compiler.
2025-06-19 11:45:06 -04:00
mlugg
8aab222ffb Compilation: add missing link file options to cache manifest
Also add a standalone test which covers the `-fentry` case. It does this
by performing two reproducible compilations which are identical other
than having different entry points, and checking whether the emitted
binaries are identical (they should *not* be).

Resolves: #23869
2025-06-17 15:33:50 +01:00
mlugg
71baa5e769
compiler: improve progress output
Update the estimated total items for the codegen and link progress nodes
earlier. Rather than waiting for the main thread to dispatch the tasks,
we can add the item to the estimated total as soon as we queue the main
task. The only difference is we need to complete it even in error cases.
2025-06-12 17:51:31 +01:00
mlugg
5bb5aaf932
compiler: don't queue too much AIR/MIR
Without this cap, unlucky scheduling and/or details of what pipeline
stages perform best on the host machine could cause many gigabytes of
MIR to be stuck in the queue. At a certain point, pause the main thread
until some of the functions in flight have been processed.
2025-06-12 17:51:31 +01:00
mlugg
f9a670d46d
Compilation: prevent zig1 depending on fd_readdir
This isn't really coherent to model as a `Feature`; this makes sense
because of zig1's specific environment. As such, I opted to check
`dev.env` directly.
2025-06-12 17:51:31 +01:00
mlugg
d7afd797cc
Zcu: handle unreferenced test_functions correctly
Previously, `PerThread.populateTestFunctions` was analyzing the
`test_functions` declaration if it hadn't already been analyzed, so that
it could then populate it. However, the logic for doing this wasn't
actually correct, because it didn't trigger the necessary type
resolution. I could have tried to fix this, but there's actually a
simpler solution! If the `test_functions` declaration isn't referenced
or has a compile error, then we simply don't need to update it; either
it's unreferenced so its value doesn't matter, or we're going to get a
compile error anyway. Either way, we can just give up early. This avoids
doing semantic analysis after `performAllTheWork` finishes.

Also, get rid of the "Code Generation" progress node while updating the
test decl: this is a linking task.
2025-06-12 17:51:30 +01:00
mlugg
ac745edbbd
compiler: estimate totals for "Code Generation" and "Linking" progress nodes 2025-06-12 13:55:41 +01:00
mlugg
db5d85b8c8
compiler: improve progress output
* "Flush" nodes ("LLVM Emit Object", "ELF Flush") appear under "Linking"

* "Code Generation" disappears when all analysis and codegen is done

* We only show one node under "Semantic Analysis" to accurately convey
  that analysis isn't happening in parallel, but rather that we're
  pausing one task to do another
2025-06-12 13:55:41 +01:00
Jacob Young
c95b1bf2d3
x86_64: remove air references from mir 2025-06-12 13:55:41 +01:00
mlugg
b5f73f8a7b
compiler: rework emit paths and cache modes
Previously, various doc comments heavily disagreed with the
implementation on both what lives where on the filesystem at what time,
and how that was represented in code. Notably, the combination of emit
paths outside the cache and `disable_lld_caching` created a kind of
ad-hoc "cache disable" mechanism -- which didn't actually *work* very
well, 'most everything still ended up in this cache. There was also a
long-standing issue where building using the LLVM backend would put a
random object file in your cwd.

This commit reworks how emit paths are specified in
`Compilation.CreateOptions`, how they are represented internally, and
how the cache usage is specified.

There are now 3 options for `Compilation.CacheMode`:
* `.none`: do not use the cache. The paths we have to emit to are
  relative to the compiler cwd (they're either user-specified, or
  defaults inferred from the root name). If we create any temporary
  files (e.g. the ZCU object when using the LLVM backend) they are
  emitted to a directory in `local_cache/tmp/`, which is deleted once
  the update finishes.
* `.whole`: cache the compilation based on all inputs, including file
  contents. All emit paths are computed by the compiler (and will be
  stored as relative to the local cache directory); it is a CLI error to
  specify an explicit emit path. Artifacts (including temporary files)
  are written to a directory under `local_cache/tmp/`, which is later
  renamed to an appropriate `local_cache/o/`. The caller (who is using
  `--listen`; e.g. the build system) learns the name of this directory,
  and can get the artifacts from it.
* `.incremental`: similar to `.whole`, but Zig source file contents, and
  anything else which incremental compilation can handle changes for, is
  not included in the cache manifest. We don't need to do the dance
  where the output directory is initially in `tmp/`, because our digest
  is computed entirely from CLI inputs.

To be clear, the difference between `CacheMode.whole` and
`CacheMode.incremental` is unchanged. `CacheMode.none` is new
(previously it was sort of poorly imitated with `CacheMode.whole`). The
defined behavior for temporary/intermediate files is new.

`.none` is used for direct CLI invocations like `zig build-exe foo.zig`.
The other cache modes are reserved for `--listen`, and the cache mode in
use is currently just based on the presence of the `-fincremental` flag.

There are two cases in which `CacheMode.whole` is used despite there
being no `--listen` flag: `zig test` and `zig run`. Unless an explicit
`-femit-bin=xxx` argument is passed on the CLI, these subcommands will
use `CacheMode.whole`, so that they can put the output somewhere without
polluting the cwd (plus, caching is potentially more useful for direct
usage of these subcommands).

Users of `--listen` (such as the build system) can now use
`std.zig.EmitArtifact.cacheName` to find out what an output will be
named. This avoids having to synchronize logic between the compiler and
all users of `--listen`.
2025-06-12 13:55:40 +01:00
mlugg
c0df707066
wasm: get self-hosted compiling, and supporting separate_thread
My original goal here was just to get the self-hosted Wasm backend
compiling again after the pipeline change, but it turned out that from
there it was pretty simple to entirely eliminate the shared state
between `codegen.wasm` and `link.Wasm`. As such, this commit not only
fixes the backend, but makes it the second backend (after CBE) to
support the new 1:N:1 threading model.
2025-06-12 13:55:40 +01:00
mlugg
5ab307cf47
compiler: get most backends compiling again
As of this commit, every backend other than self-hosted Wasm and
self-hosted SPIR-V compiles and (at least somewhat) functions again.
Those two backends are currently disabled with panics.

Note that `Zcu.Feature.separate_thread` is *not* enabled for the fixed
backends. Avoiding linker references from codegen is a non-trivial task,
and can be done after this branch.
2025-06-12 13:55:40 +01:00
mlugg
9eb400ef19
compiler: rework backend pipeline to separate codegen and link
The idea here is that instead of the linker calling into codegen,
instead codegen should run before we touch the linker, and after MIR is
produced, it is sent to the linker. Aside from simplifying the call
graph (by preventing N linkers from each calling into M codegen
backends!), this has the huge benefit that it is possible to
parallellize codegen separately from linking. The threading model can
look like this:

* 1 semantic analysis thread, which generates AIR
* N codegen threads, which process AIR into MIR
* 1 linker thread, which emits MIR to the binary

The codegen threads are also responsible for `Air.Legalize` and
`Air.Liveness`; it's more efficient to do this work here instead of
blocking the main thread for this trivially parallel task.

I have repurposed the `Zcu.Feature.separate_thread` backend feature to
indicate support for this 1:N:1 threading pattern. This commit makes the
C backend support this feature, since it was relatively easy to divorce
from `link.C`: it just required eliminating some shared buffers. Other
backends don't currently support this feature. In fact, they don't even
compile -- the next few commits will fix them back up.
2025-06-12 13:55:40 +01:00
mlugg
66d15d9d09
link: make checking for failed types the responsibility of Compilation 2025-06-12 13:55:40 +01:00
mlugg
2fb6f5c1ad
link: divorce LLD from the self-hosted linkers
Similar to the previous commit, this commit untangles LLD integration
from the self-hosted linkers. Despite the big network of functions which
were involved, it turns out what was going on here is quite simple. The
LLD linking logic is actually very self-contained; it requires a few
flags from the `link.File.OpenOptions`, but that's really about it. We
don't need any of the mutable state on `Elf`/`Coff`/`Wasm`, for
instance. There was some legacy code trying to handle support for using
self-hosted codegen with LLD, but that's not a supported use case, so
I've just stripped it out.

For now, I've just pasted the logic for linking the 3 targets we
currently support using LLD for into this new linker implementation,
`link.Lld`; however, it's almost certainly possible to combine some of
the logic and simplify this file a bit. But to be honest, it's not
actually that bad right now.

This commit ends up eliminating the distinction between `flush` and
`flushZcu` (formerly `flushModule`) in linkers, where the latter
previously meant something along the lines of "flush, but if you're
going to be linking with LLD, just flush the ZCU object file, don't
actually link"?. The distinction here doesn't seem like it was properly
defined, and most linkers seem to treat them as essentially identical
anyway. Regardless, all calls to `flushZcu` are gone now, so it's
deleted -- one `flush` to rule them all!

The end result of this commit and the preceding one is that LLVM and LLD
fit into the pipeline much more sanely:

* If we're using LLVM for the ZCU, that state is on `zcu.llvm_object`
* If we're using LLD to link, then the `link.File` is a `link.Lld`
* Calls to "ZCU link functions" (e.g. `updateNav`) lower to calls to the
  LLVM object if it's available, or otherwise to the `link.File` if it's
  available (neither is available under `-fno-emit-bin`)
* After everything is done, linking is finalized by calling `flush` on
  the `link.File`; for `link.Lld` this invokes LLD, for other linkers it
  flushes self-hosted linker state

There's one messy thing remaining, and that's how self-hosted function
codegen in a ZCU works; right now, we process AIR with a call sequence
something like this:

* `link.doTask`
* `Zcu.PerThread.linkerUpdateFunc`
* `link.File.updateFunc`
* `link.Elf.updateFunc`
* `link.Elf.ZigObject.updateFunc`
* `codegen.generateFunction`
* `arch.x86_64.CodeGen.generate`

So, we start in the linker, take a scenic detour through `Zcu`, go back
to the linker, into its implementation, and then... right back out, into
code which is generic over the linker implementation, and then dispatch
on the *backend* instead! Of course, within `arch.x86_64.CodeGen`, there
are some more places which switch on the `link` implementation being
used. This is all pretty silly... so it shall be my next target.
2025-06-12 13:55:39 +01:00
mlugg
3743c3e39c
compiler: slightly untangle LLVM from the linkers
The main goal of this commit is to make it easier to decouple codegen
from the linkers by being able to do LLVM codegen without going through
the `link.File`; however, this ended up being a nice refactor anyway.

Previously, every linker stored an optional `llvm.Object`, which was
populated when using LLVM for the ZCU *and* linking an output binary;
and `Zcu` also stored an optional `llvm.Object`, which was used only
when we needed LLVM for the ZCU (e.g. for `-femit-llvm-bc`) but were not
emitting a binary.

This situation was incredibly silly. It meant there were N+1 places the
LLVM object might be instead of just 1, and it meant that every linker
had to start a bunch of methods by checking for an LLVM object, and just
dispatching to the corresponding method on *it* instead if it was not
`null`.

Instead, we now always store the LLVM object on the `Zcu` -- which makes
sense, because it corresponds to the object emitted by, well, the Zig
Compilation Unit! The linkers now mostly don't make reference to LLVM.
`Compilation` makes sure to emit the LLVM object if necessary before
calling `flush`, so it is ready for the linker. Also, all of the
`link.File` methods which act on the ZCU -- like `updateNav` -- now
check for the LLVM object in `link.zig` instead of in every single
individual linker implementation. Notably, the change to LLVM emit
improves this rather ludicrous call chain in the `-fllvm -flld` case:

* Compilation.flush
* link.File.flush
* link.Elf.flush
* link.Elf.linkWithLLD
* link.Elf.flushModule
* link.emitLlvmObject
* Compilation.emitLlvmObject
* llvm.Object.emit

Replacing it with this one:

* Compilation.flush
* llvm.Object.emit

...although we do currently still end up in `link.Elf.linkWithLLD` to do
the actual linking. The logic for invoking LLD should probably also be
unified at least somewhat; I haven't done that in this commit.
2025-06-12 13:55:39 +01:00
mlugg
424e6ac54b
compiler: minor refactors to ZCU linking
* The `codegen_nav`, `codegen_func`, `codegen_type` tasks are renamed to
  `link_nav`, `link_func`, and `link_type`, to more accurately reflect
  their purpose of sending data to the *linker*. Currently, `link_func`
  remains responsible for codegen; this will change in an upcoming
  commit.

* Don't go on a pointless detour through `PerThread` when linking ZCU
  functions/`Nav`s; so, the `linkerUpdateNav` etc logic now lives in
  `link.zig`. Currently, `linkerUpdateFunc` is an exception, because it
  has broader responsibilities including codegen, but this will be
  solved in an upcoming commit.
2025-06-12 13:55:39 +01:00
Jacob Young
37f763560b x86_64: fix switch dispatch bug
Also closes #23902
2025-06-06 23:42:15 -07:00
Jacob Young
5986bdf868 Compilation: enable the x86_64 backend by default for debug builds
Closes #22257
2025-06-06 23:42:14 -07:00
Alex Rønne Petersen
9d534790eb std.Target: Introduce Cpu convenience functions for feature tests.
Before:

* std.Target.arm.featureSetHas(target.cpu.features, .has_v7)
* std.Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov })
* std.Target.wasm.featureSetHasAll(target.cpu.features, .{ .atomics, .bulk_memory })

After:

* target.cpu.has(.arm, .has_v7)
* target.cpu.hasAny(.x86, &.{ .sse, .avx, .cmov })
* target.cpu.hasAll(.wasm, &.{ .atomics, .bulk_memory })
2025-06-05 06:12:00 +02:00
Alex Rønne Petersen
14873f9a34
Merge pull request #24068 from alexrp/android-pic-pie
compiler: Rework PIE option logic.
2025-06-05 01:14:03 +02:00
Alex Rønne Petersen
bc8ace2a6d compiler-rt: Issue VALGRIND_DISCARD_TRANSLATIONS request in __clear_cache().
Closes #24030.
2025-06-04 13:25:21 +02:00
Alex Rønne Petersen
c620836945
zig cc: Pass -f(no-)PIE to clang.
Otherwise we rely on Clang's default which is known to not always match ours.
2025-06-04 10:32:30 +02:00
Alex Rønne Petersen
cd03a0a153 compiler: Don't link ucrtbased.dll when targeting *-windows-msvc in Debug mode.
Linking it by default means that we produce binaries that, effectively, only run
on systems which have the Windows SDK installed because ucrtbased.dll is not
redistributable, and the Windows SDK is what actually installs ucrtbased.dll
into %SYSTEM32%. The resulting binaries also can't run under Wine because Wine
does not provide ucrtbased.dll.

It is also inconsistent with our behavior for *-windows-gnu where we always link
ucrtbase.dll. See #23983, #24019, and #24053 for more details.

So just use ucrtbase.dll regardless of mode. With this change, we can also drop
the implicit definition of the _DEBUG macro in zig cc, which has in some cases
been problematic for users.

Users who want to opt into the old behavior can do so, both for *-windows-msvc
and *-windows-gnu, by explicitly passing -lucrtbased and -D_DEBUG. We might
consider adding a more ergonomic flag like -fdebug-crt to the zig build-* family
of commands in the future.

Closes #24052.
2025-06-04 05:04:29 +02:00
Alex Rønne Petersen
fa8073795a Revert "mingw: Link to ucrtbased.dll instead of API set DLLs in Debug mode."
This reverts commit 4641e9556d1343e95e4676e2f1e3024173db9962.

See discussion on #24052.
2025-06-02 08:06:37 +02:00
Jacob Young
b48d6ff619
Legalize: implement scalarization of @select 2025-06-01 08:24:01 +01:00
Alex Rønne Petersen
4641e9556d mingw: Link to ucrtbased.dll instead of API set DLLs in Debug mode.
By using the debug UCRT, we get access to functions like _CrtDbgReport.

Closes #23983.
2025-05-30 02:11:36 +02:00
mlugg
aeed5f9ebd
compiler: introduce incremental debug server
In a compiler built with debug extensions, pass `--debug-incremental` to
spawn the "incremental debug server". This is a TCP server exposing a
REPL which allows querying a bunch of compiler state, some of which is
stored only when that flag is passed. Eventually, this will probably
move into `std.zig.Server`/`std.zig.Client`, but this is easier to work
with right now. The easiest way to interact with the server is `telnet`.
2025-05-25 04:43:43 +01:00
mlugg
3416452d56 compiler: fix ZIR hash not including compiler version
This was an unintentional regression in 23c8175 which meant that
backwards-incompatible ZIR changes would have caused compiler crashes if
old caches were present.
2025-05-21 11:11:28 +01:00
Alex Rønne Petersen
7c9035f635 link.Elf: Don't require linking libc for dynamic linker path to take effect.
Closes #23813.
2025-05-21 06:08:50 +02:00