Commit Graph

590 Commits

Author SHA1 Message Date
Jacob Young
047d6d996e cbe: fix non-msvc externs and exports
Closes #17817
2024-01-03 02:52:25 -05:00
Jacob Young
98b633ff17 Reapply "Merge pull request #17824 from kcbanner/fixup_msvc_fmax"
This reverts commit 2b58978360.
2024-01-03 02:41:21 -05:00
Andrew Kelley
2b58978360 Revert "Merge pull request #17824 from kcbanner/fixup_msvc_fmax"
This reverts commit 7161ed79c4, reversing
changes made to 3f2a65594e.

Unfortunately, this sat in the PR queue too long and the merge broke the
zig1.wasm bootstrap process.
2024-01-01 17:49:57 -07:00
Andrew Kelley
7161ed79c4 Merge pull request #17824 from kcbanner/fixup_msvc_fmax
cbe: add a system for avoiding collisions with C compiler intrinsics
2024-01-01 15:36:16 -08:00
Jacob Young
daf91ed8d1 Air: use typesafe Air.Inst.Index
I need some indices for a thing...
2023-12-03 02:05:06 -08:00
Meghan Denny
2549de80b2 move Module.Decl.Index and Module.Namespace.Index to InternPool 2023-11-26 02:24:40 -05:00
Techatrix
18608223ef convert toType and toValue to Type.fromInterned and Value.fromInterned 2023-11-25 04:09:53 -05:00
Andrew Kelley
91b897ef58 rework memory management of Module.Namespace hash maps
The motivating problem here was a memory leak in the hash maps of
Module.Namespace.

The commit deletes more of the legacy incremental compilation
implementation. It had things like use of orderedRemove and trying to do
too much OOP-style creation and deletion of objects.

Instead, this commit iterates over all the namespaces on Module deinit
and calls deinit on the hash map fields. This logic is much simpler to
reason about.

Similarly, change global inline assembly to an array hash map since
iterating over the values is a primary use of it, and clean up the
remaining values on Module deinit, solving another memory leak.

After this there are no more memory leaks remaining when using the
x86 backend in a libc-less compiler.
2023-11-12 23:21:21 -05:00
kcbanner
35c86984a6 cbe: support rendering union values that have no defined tag type
This was regressed in d657b6c0e2, when
the comptime memory model for unions was changed to allow them to have
no defined tag type.
2023-11-07 00:49:39 +00:00
kcbanner
26dabbf301 cbe: handle underscore prexfix on macos, don't mangle extern function names 2023-11-05 20:34:13 -05:00
kcbanner
192e9a315d cbe: add DeclVisibility and zig_extern_mangled to handle exporting mangled symbols under a different name 2023-11-05 20:34:13 -05:00
kcbanner
ce293c982e cbe: avoid collisions with builtins and intrinsics
Changes:
- Add `isMangledIdent` to determine if `fmtIdent` would make any edits to the identifier
- Any function that has a mangled identifier is referred to using the mangled identifer
  within the current file, but if it is exported the first export will be with the non-mangled name.
- Add `zig_import` to import a symbol under a different name
- Add a level of indirection to float function names. Now, they are referred to as
  `zig_float_fn_<float type>_<operation>`. The definitions in zig.h are wrapped
  with `zig_import` to import the symbol under the real name.

The specific problem that sparked this change was the combination of
`zig_libc_name_f80(name) __##name##x` with the input `fma`, resulting
in `__fmax`, which is a new intrinsic in recent versions of cl.exe.

With the above changes in place, compiler_rt can output the following:

```
static zig_weak_linkage_fn zig_f80 zig_e___fmax(zig_f80, zig_f80, zig_f80);
zig_export(zig_weak_linkage_fn zig_f80 zig_e___fmax(zig_f80, zig_f80, zig_f80), __fmax, "__fmax");
```

Within compiler_rt, `zig_e___fmax` is used to refer to the function, but consumers
will import `__fmax`, which maps to their `zig_float_fn_f80_fma` definition from zig.h.
2023-11-05 20:34:13 -05:00
Jacob Young
13b1e10b8f cbe: fix @bitCast warnings 2023-10-31 21:37:40 -04:00
Andrew Kelley
3fc6fc6812 std.builtin.Endian: make the tags lower case
Let's take this breaking change opportunity to fix the style of this
enum.
2023-10-31 21:37:35 -04:00
Andrew Kelley
cbcef2d806 C backend: remove some @as 2023-10-25 19:57:02 -07:00
Jacob Young
51f7e5412a cbe: update DeclGen.decl_index to support anon decls 2023-10-25 19:57:02 -07:00
mlugg
20bb81166f InternPool: remove runtime_value representation
The main goal of this commit is to remove the `runtime_value` field from
`InternPool.Key` (and its associated representation), but there are a
few dominos. Specifically, this mostly eliminates the "maybe runtime"
concept from value resolution in Sema: so some resolution functions like
`resolveMaybeUndefValAllowVariablesMaybeRuntime` are gone. This required
a small change to struct/union/array initializers, to no longer
use `runtime_value` if a field was a `variable` - I'm not convinced this
case was even reachable, as `variable` should only ever exist as the
trivial value of a global runtime `var` decl.

Now, the only case in which a `Sema.resolveMaybeUndefVal`-esque function
can return the `variable` key is `resolveMaybeUndefValAllowVariables`,
which is directly called from `Sema.resolveInstValueAllowVariables`
(previously `Sema.resolveInstValue`), which is only used for resolving
the value of a Decl from `Module.semaDecl`.

While changing these functions, I also slightly reordered and
restructured some of them, and updated their doc comments.
2023-10-24 14:28:33 +01:00
Andrew Kelley
94d61ce964 Merge pull request #17651 from Vexu/error-limit
Make distinct error limit configurable (attempt #2)
2023-10-23 03:19:03 -04:00
Veikka Tuominen
9d9e22e716 remove uses of non-configurable err_int 2023-10-22 14:29:26 +03:00
Andrew Kelley
7bab406c79 InternPool: store alignment of anon decls
Commit 5393e56500d499753dbc39704c0161b47d1e4d5c has a flaw pointed out
by @mlugg: the `ty` field of pointer values changes when comptime values
are pointer-casted. This commit introduces a new encoding which
additionally stores the "original pointer type" which is used to store
the alignment of the anonymous decl, and potentially other information
in the future such as section and pointer address space. However, this
new encoding is only used when the original pointer type differs from
the casted pointer type in a meaningful way.

I was able to make the LLVM backend and the C backend lower anonymous
decls with the appropriate alignment, however I will need some help
figuring out how to do this for the backends that lower anonymous decls
via src/codegen.zig and the wasm backend.
2023-10-21 21:38:41 -04:00
Jacob Young
a9b37ac637 cbe: fix crash on error
This hashmap value used to be assigned much later during `flushModule`,
which never happens if an error is returned by the backend, and
attempting to the undefined values would cause a crash.
2023-10-08 00:06:17 -04:00
Andrew Kelley
c4b0b7a30b C backend: render anon decls
Introduce the new mechanism needed to render anonymous decls to C code
that the frontend is now using.

The current strategy is to collect the set of used anonymous decls into
one ArrayHashMap for the entire compilation, and then render them during
flush().

In the future this may need to be adjusted for incremental compilation
purposes, so that removing a Decl from decl_table means that newly
unused anonymous decls are no longer rendered. However, let's do one
thing at a time. The only goal of this branch is to stop using
Module.Decl objects for unnamed constants.
2023-10-03 12:12:51 -07:00
Andrew Kelley
9d069d98e3 C backend: start handling anonymous decls
Start keeping track of dependencies on anon decls for dependency
ordering during flush()

Currently this causes use of undefined symbols because these
dependencies need to get rendered into the output.
2023-10-03 12:12:51 -07:00
Andrew Kelley
c0b5512544 compiler: start handling anonymous decls differently
Instead of explicitly creating a `Module.Decl` object for each anonymous
declaration, each `InternPool.Index` value is implicitly understood to
be an anonymous declaration when encountered by backend codegen.

The memory management strategy for these anonymous decls then becomes to
garbage collect them along with standard InternPool garbage.

In the interest of a smooth transition, this commit only implements this
new scheme for string literals and leaves all the previous mechanisms in
place.
2023-10-03 12:12:50 -07:00
Xavier Bouchoux
62d178e91a codegen: fix field offsets in packed structs
* add nested packed struct/union behavior tests
 * use ptr_info.packed_offset rather than trying to duplicate the logic from Sema.structFieldPtrByIndex()
 * use the container_ptr_info.packed_offset to account for non-aligned nested structs.
 * dedup type.packedStructFieldBitOffset() and module.structPackedFieldBitOffset()
2023-10-03 06:39:20 +02:00
Andrew Kelley
7c605ba62c C backend: remove ?*Decl from DeclGen
Another simplification. DeclGen already has `decl_index` which can be
used to retrieve the `*Decl` if needed.
2023-09-29 19:14:17 -07:00
antlilja
6a29646a55 Rename @fabs to @abs and accept integers
Replaces the @fabs builtin with a new @abs builtins which accepts
floats, signed integers and vectors of said types.
2023-09-27 11:15:53 -07:00
Andrew Kelley
1606717b5f C backend: flatten out some of the long-lived state
When the compiler's state lives through multiple Compilation.update()
calls, the C backend stores the rendered C source code for each
decl code body and forward declarations.

With this commit, the state is still stored, but it is managed in one
big array list in link/C.zig rather than many array lists, one for each
decl. This means simpler serialization and deserialization.
2023-09-27 04:09:22 -07:00
Michael Dusan
127198e58c cbe: support more symbol attributes
implement codegen for:

- decl weak linkage
- decl aliases
- fn decl weak linkage

windows msvc:
- `__declspec(selectany)` is not supported for functions
- skip weak linkage for functions

closes #17050
2023-09-24 14:44:15 -07:00
Andrew Kelley
81b5df347a compiler: fix structFieldName crash for tuples
When struct types have no field names, the names are implicitly
understood to be strings corresponding to the field indexes in
declaration order. It used to be the case that a NullTerminatedString
would be stored for each field in this case, however, now, callers must
handle the possibility that there are no names stored at all. This
commit introduces `legacyStructFieldName`, a function to fake the
previous behavior. Probably something better could be done by reworking
all the callsites of this function.
2023-09-21 17:29:34 -07:00
Andrew Kelley
baea62a8ad fix regressions from this branch 2023-09-21 14:48:40 -07:00
Andrew Kelley
accd5701c2 compiler: move struct types into InternPool proper
Structs were previously using `SegmentedList` to be given indexes, but
were not actually backed by the InternPool arrays.

After this, the only remaining uses of `SegmentedList` in the compiler
are `Module.Decl` and `Module.Namespace`. Once those last two are
migrated to become backed by InternPool arrays as well, we can introduce
state serialization via writing these arrays to disk all at once.

Unfortunately there are a lot of source code locations that touch the
struct type API, so this commit is still work-in-progress. Once I get it
compiling and passing the test suite, I can provide some interesting
data points such as how it affected the InternPool memory size and
performance comparison against master branch.

I also couldn't resist migrating over a bunch of alignment API over to
use the log2 Alignment type rather than a mismash of u32 and u64 byte
units with 0 meaning something implicitly different and special at every
location. Turns out you can do all the math you need directly on the
log2 representation of alignments.
2023-09-21 14:48:40 -07:00
Andrew Kelley
cb6201715a InternPool: prevent anon struct UAF bugs with type safety
Instead of using actual slices for InternPool.Key.AnonStructType, this
commit changes to use Slice types instead, which store a
long-lived index rather than a pointer.

This is a follow-up to 7ef1eb1c27.
2023-09-12 20:08:56 -04:00
Jacob Young
c429bb5d2f llvm/cbe: support slice in @prefetch
Closes #16967
2023-08-28 19:04:53 -07:00
Andrew Kelley
ada0010471 compiler: move unions into InternPool
There are a couple concepts here worth understanding:

Key.UnionType - This type is available *before* resolving the union's
fields. The enum tag type, number of fields, and field names, field
types, and field alignments are not available with this.

InternPool.UnionType - This one can be obtained from the above type with
`InternPool.loadUnionType` which asserts that the union's enum tag type
has been resolved. This one has all the information available.

Additionally:

* ZIR: Turn an unused bit into `any_aligned_fields` flag to help
  semantic analysis know whether a union has explicit alignment on any
  fields (usually not).
* Sema: delete `resolveTypeRequiresComptime` which had the same type
  signature and near-duplicate logic to `typeRequiresComptime`.
  - Make opaque types not report comptime-only (this was inconsistent
    between the two implementations of this function).
* Implement accepted proposal #12556 which is a breaking change.
2023-08-22 13:54:14 -07:00
mlugg
7a85ad151d cbe: elide block result allocation for 0-bit types
This logic already existed for the void type, but is also necessary for
other 0-bit types. Without it, we try to alloc a local for a 0-bit type
which gets translated to a local of type `void` which C doesn't like.
2023-08-20 11:58:14 -07:00
Lewis Gaul
387b0ac4f1 Make NaNs quiet by default and other NaN tidy-up (#16826)
* Generalise NaN handling and make std.math.nan() give quiet NaNs

* Address uses of std.math.qnan_* and std.math.nan_* consts

* Comment out failing test due to issues with signalling NaN

* Fix issue in c_builtins.zig where we need qnan_u32
2023-08-18 02:07:49 -04:00
Jacob Young
b8c9d5ae98 cbe: don't emit traps in naked functions
Closes #16680
2023-08-05 16:44:56 -07:00
Jacob Young
228c956377 std: finish cleanup up asm
This also required implementing the necessary syntax in the x86_64 backend.
2023-07-31 03:49:21 -04:00
Jacob Young
817fa3af86 std: cleanup asm usage
After fixing some issues with inline assembly in the C backend, the std
cleanups have the side effect of making these functions compatible with
the backend, allowing it to be used on linux without linking libc.
2023-07-31 01:58:10 -04:00
Xavier Bouchoux
8c367ef99a codegen: fix access to byte-aligned nested packed struct elems
When acessing a packed struct member via a byte aligned ptr (from the optimisation in Sema.structFieldPtrByIndex())
the codegen must apply the parent ptr packed_offset in addition to the field offset itself.

resolves https://github.com/ziglang/zig/issues/16609
2023-07-29 18:16:13 +02:00
notcancername
ce859cfcb8 cbe: fix bug where empty enum would be generated
fix a bug where an invalid empty enum would be emitted into the C
source file if the global error set was empty.
2023-07-19 23:20:25 -04:00
Andrew Kelley
b03d34429d compiler: work around slightly different generics semantics
Both of these cases are interesting, were not covered by behavior tests,
and should be inspected carefully with regards to the language
specification.
2023-07-18 19:02:06 -07:00
Andrew Kelley
db33ee45b7 rework generic function calls
Abridged summary:

 * Move `Module.Fn` into `InternPool`.
 * Delete a lot of confusing and problematic `Sema` logic related to
   generic function calls.

This commit removes `Module.Fn` and replaces it with two new
`InternPool.Tag` values:

 * `func_decl` - corresponding to a function declared in the source
   code. This one contains line/column numbers, zir_body_inst, etc.

 * `func_instance` - one for each monomorphization of a generic
   function. Contains a reference to the `func_decl` from whence the
   instantiation came, along with the `comptime` parameter values (or
   types in the case of `anytype`)

Since `InternPool` provides deduplication on these values, these fields
are now deleted from `Module`:

 * `monomorphed_func_keys`
 * `monomorphed_funcs`
 * `align_stack_fns`

Instead of these, Sema logic for generic function instantiation now
unconditionally evaluates the function prototype expression for every
generic callsite. This is technically required in order for type
coercions to work. The previous code had some dubious, probably wrong
hacks to make things work, such as `hashUncoerced`. I'm not 100% sure
how we were able to eliminate that function and still pass all the
behavior tests, but I'm pretty sure things were still broken without
doing type coercion for every generic function call argument.

After the function prototype is evaluated, it produces a deduplicated
`func_instance` `InternPool.Index` which can then be used for the
generic function call.

Some other nice things made by this simplification are the removal of
`comptime_args_fn_inst` and `preallocated_new_func` from `Sema`, and the
messy logic associated with them.

I have not yet been able to measure the perf of this against master
branch. On one hand, it reduces memory usage and pointer chasing of the
most heavily used `InternPool` Tag - function bodies - but on the other
hand, it does evaluate function prototype expressions more than before.
We will soon find out.
2023-07-18 19:02:05 -07:00
Jacob Young
70c71935c7 cbe: fix pointers to aliases of extern values 2023-07-18 17:58:39 -07:00
Jacob Young
78eb3c5617 bootstrap: support aarch64 in 32-bit mode
* `CMakeLists.txt`: support the weird `uname -m` output.
 * `CMakeLists.txt`: detect and use the C compiler's default arm mode.
 * cbe: support gcc with both `f128` and `u128` emulated.
 * std.os.linux.thumb: fix incorrectly passed asm inputs.
2023-07-04 15:47:07 -07:00
mlugg
ff37ccd298 Air: store interned values in Air.Inst.Ref
Previously, interned values were represented as AIR instructions using
the `interned` tag. Now, the AIR ref directly encodes the InternPool
index. The encoding works as follows:
* If the ref matches one of the static values, it corresponds to the same InternPool index.
* Otherwise, if the MSB is 0, the ref corresponds to an InternPool index.
* Otherwise, if the MSB is 1, the ref corresponds to an AIR instruction index (after removing the MSB).

Note that since most static InternPool indices are low values (the
exceptions being `.none` and `.var_args_param_type`), the first rule is
almost a nop.
2023-06-27 01:21:32 -07:00
Andrew Kelley
9684947faa compiler: start moving safety-checks into backends
This actually used to be how it worked in stage1, and there was this
issue to change it: #2649

So this commit is a reversal to that idea. One motivation for that issue
was avoiding emitting the panic handler in compilations that do not have
any calls to panic. This commit only resolves the panic handler in the
event of a safety check function being emitted, so it does not have that
flaw.

The other reason given in that issue was for optimizations that elide
safety checks. It's yet to be determined whether that was a good idea or
not; this can get re-explored when we start adding optimization passes
to AIR.

This commit adds these AIR instructions, which are only emitted if
`backendSupportsFeature(.safety_checked_arithmetic)` is true:
 * add_safe
 * sub_safe
 * mul_safe

It removes these nonsensical AIR instructions:
 * addwrap_optimized
 * subwrap_optimized
 * mulwrap_optimized

The safety-checked arithmetic functions push the burden of invoking the
panic handler into the backend. This makes for a messier compiler
implementation, but it reduces the amount of AIR instructions emitted by
Sema, which reduces time spent in the secondary bottleneck of the
compiler. It also generates more compact LLVM IR, reducing time spent in
the primary bottleneck of the compiler.

Finally, it eliminates 1 stack allocation per safety-check which was
being used to store the resulting tuple. These allocations were going to
be annoying when combined with suspension points.
2023-06-25 01:41:08 -07:00
Andrew Kelley
a31ba25a3d Merge pull request #16188 from kcbanner/fix_cbe_airErrUnionPayloadPtrSet
cbe: fix crash caused by calling `mod.intValue` on `type_inferred_error_set`
2023-06-24 21:53:59 -07:00
mlugg
67997a699a cbe: codegen int_from_ptr of slice correctly
CBE was translating to access the `len` field rather than `ptr`.
Air.zig specifies that this operation is valid on a slice.
2023-06-24 16:56:40 -07:00