163 Commits

Author SHA1 Message Date
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
mlugg
f2c8fa769a
Sema: refactor generic calls to interleave argument analysis and parameter type resolution
AstGen provides all function call arguments with a result location,
referenced through the call instruction index. The idea is that this
should be the parameter type, but for `anytype` parameters, we use
generic poison, which is required to be handled correctly.

Previously, generic instantiations and inline calls worked by evaluating
all args in advance, before resolving generic parameter types. This
means any generic parameter (not just `anytype` ones) had generic poison
result types. This caused missing result locations in some cases.

Additionally, the generic instantiation logic caused `zirParam` to
analyze the argument types a second time before coercion. This meant
that for nominal types (struct/enum/etc), a *new* type was created,
distinct to the result type which was previously forwarded to the
argument expression.

This commit fixes both of these issues. Generic parameter type
resolution is now interleaved with argument analysis, so that we don't
have unnecessary generic poison types, and generic instantiation logic
now handles parameters itself rather than falling through to the
standard zirParam logic, so avoids duplicating the types.

Resolves: #16566
Resolves: #16258
Resolves: #16753
2023-08-10 10:00:26 +01:00
Jacob Young
dc8a80a191 llvm: support read-write output constraints in assembly
Closes #15227
2023-07-29 09:49:04 -07:00
Andrew Kelley
927f6ec8ca frontend: fix inferred error sets of comptime/inline calls
Previously, they shared function index with the owner decl, but that
would clobber the data stored for inferred error sets of runtime calls.

Now there is an adhoc_inferred_error_set_type which models the problem
much more correctly.
2023-07-18 19:02:06 -07:00
Andrew Kelley
6d72f971af InternPool: implement getExternFunc 2023-07-18 19:02:05 -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
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
mlugg
f26dda2117 all: migrate code to new cast builtin syntax
Most of this migration was performed automatically with `zig fmt`. There
were a few exceptions which I had to manually fix:

* `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten
* `@truncate`'s fixup is incorrect for vectors
* Test cases are not formatted, and their error locations change
2023-06-24 16:56:39 -07:00
Jacob Young
52ec121469 Sema: optimize callers of indexToKey 2023-06-20 14:02:09 -04:00
Jacob Young
ad3e0e4eb4 Sema: optimize typeHasOnePossibleValue 2023-06-20 14:02:08 -04:00
Jacob Young
3c4b58cea7 Air: optimize around byval struct passing compiler bug 2023-06-20 14:02:08 -04:00
Eric Joldasov
50339f595a all: zig fmt and rename "@XToY" to "@YFromX"
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-19 12:34:42 -07:00
Eric Joldasov
a6c8ee5231 compiler: rename "@XToY" to "@YFromX", zig fmt: rewrite them
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-19 12:34:24 -07:00
Andrew Kelley
90a877f462 InternPool: pass by const pointer
The Zig language allows the compiler to make this optimization
automatically. We should definitely make the compiler do that, and
revert this commit. However, that will not happen in this branch, and I
want to continue to explore achieving performance parity with
merge-base. So, this commit changes all InternPool parameters to be
passed by const pointer rather than by value.

I measured a 1.03x ± 0.03 speedup vs the previous commit compiling the
(set of passing) behavior tests. Against merge-base, this commit is
1.17x ± 0.04 slower, which is an improvement from the previous
measurement of 1.22x ± 0.02.

Related issue: #13510
Related issue: #14129
Related issue: #15688
2023-06-10 20:47:57 -07:00
Andrew Kelley
66c4396854 AIR: eliminate the values array 2023-06-10 20:47:55 -07:00
Andrew Kelley
f37c0a4593 Sema: inferred allocations no longer abuse type/value system
Previously, there were types and values for inferred allocations and a
lot of special-case handling. Now, instead, the special casing is
limited to AIR instructions for these use cases.

Instead of storing data in Value payloads, the data is now stored in AIR
instruction data as well as the previously `void` value type of the
`unresolved_inferred_allocs` hash map.
2023-06-10 20:47:55 -07:00
Jacob Young
70cc68e999 Air: remove constant tag
Some uses have been moved to their own tag, the rest use interned.

Also, finish porting comptime mutation to be more InternPool aware.
2023-06-10 20:47:55 -07:00
Jacob Young
1a4626d2cf InternPool: remove more legacy values
Reinstate some tags that will be needed for comptime init.
2023-06-10 20:47:54 -07:00
Jacob Young
6e0de1d116 InternPool: port most of value tags 2023-06-10 20:47:54 -07:00
Jacob Young
dfd91abfe1 InternPool: add more pointer values 2023-06-10 20:47:54 -07:00
Andrew Kelley
7e19c95668 Sema: move inferred_alloc_const/mut_type to InternPool
Now, all types are migrated to use `InternPool`. The `Type.Tag` enum is
deleted in this commit.
2023-06-10 20:47:54 -07:00
Andrew Kelley
dfb3521160 compiler: remove var_args_param_type from SimpleType
This is now represented instead by a special `InternPool.Index.Tag` that
has no corresponding type/value.
2023-06-10 20:47:53 -07:00
Andrew Kelley
9ff514b6a3 compiler: move error union types and error set types to InternPool
One change worth noting in this commit is that `module.global_error_set`
is no longer kept strictly up-to-date. The previous code reserved
integer error values when dealing with error set types, but this is no
longer needed because the integer values are not needed for semantic
analysis unless `@errorToInt` or `@intToError` are used and therefore
may be assigned lazily.
2023-06-10 20:47:53 -07:00
Andrew Kelley
17882162b3 stage2: move function types to InternPool 2023-06-10 20:47:53 -07:00
Andrew Kelley
88dbd62bcb stage2: move enum tag values into the InternPool
I'm seeing a new assertion trip: the call to `enumTagFieldIndex` in the
implementation of `@Type` is attempting to query the field index of an
union's enum tag, but the type of the enum tag value provided is not the
same as the union's tag type. Most likely this is a problem with type
coercion, since values are now typed.

Another problem is that I added some hacks in std.builtin because I
didn't see any convenient way to access them from Sema. That should
definitely be cleaned up before merging this branch.
2023-06-10 20:46:17 -07:00
mlugg
2ffef605c7 Replace uses of Value.zero, Value.one, Value.negative_one
This is a bit nasty, mainly because Type.onePossibleValue is now
errorable, which is a quite viral change.
2023-06-10 20:42:29 -07:00
Andrew Kelley
75900ec1b5 stage2: move integer values to InternPool 2023-06-10 20:42:29 -07:00
Andrew Kelley
9ec0017f46 stage2: migrate many pointer types to the InternPool 2023-06-10 20:42:28 -07:00
Andrew Kelley
2f05b1482a Sema: update core comptime detection logic to be InternPool aware
* Add some assertions to make sure instructions are not none. I tested
   all these with master branch as well and made sure the behavior tests
   still passed with the assertions intact (along with a handful of
   callsite updates).
 * Fix Sema.resolveMaybeUndefValAllowVariablesMaybeRuntime not noticing
   that interned values are comptime-known. This was causing all kinds
   of chaos.
 * Fix print_air writeType calling tag() without checking for ip_index
2023-06-10 20:42:28 -07:00
Andrew Kelley
5e636643d2 stage2: move many Type encodings to InternPool
Notably, `vector`.

Additionally, all alternate encodings of `pointer`, `optional`, and
`array`.
2023-06-10 20:42:27 -07:00
Andrew Kelley
ca3cf93b21 stage2: move most simple values to InternPool 2023-06-10 20:40:04 -07:00
Andrew Kelley
836d8a1f64 stage2: move most simple types to InternPool 2023-06-10 20:40:04 -07:00
Andrew Kelley
00f82f1c46 stage2: add interned AIR tag
This required additionally passing the `InternPool` into some AIR
methods.

Also, implement `Type.isNoReturn` for interned types.
2023-06-10 20:40:03 -07:00
Andrew Kelley
9aec2758cc stage2: start the InternPool transition
Instead of doing everything at once which is a hopelessly large task,
this introduces a piecemeal transition that can be done in small
increments at a time.

This is a minimal changeset that keeps the compiler compiling. It only
uses the InternPool for a small set of types.

Behavior tests are not passing.

Air.Inst.Ref and Zir.Inst.Ref are separated into different enums but
compile-time verified to have the same fields in the same order.

The large set of changes is mainly to deal with the fact that most Type
and Value methods now require a Module to be passed in, so that the
InternPool object can be accessed.
2023-06-10 20:40:03 -07:00
Andrew Kelley
792bbfa301 Sema: fix memcpy alias safety incorrect math
Previously it was not multiplying by the element ABI size. Now, it uses
ptr_add instructions which do math based on the element type.
2023-04-25 11:23:41 -07:00
Andrew Kelley
5378fdffdc stage2: introduce store_safe AIR instruction
store:
The value to store may be undefined, in which case the destination
memory region has undefined bytes after this instruction is
evaluated. In such case ignoring this instruction is legal
lowering.

store_safe:
Same as `store`, except if the value to store is undefined, the
memory region should be filled with 0xaa bytes, and any other
safety metadata such as Valgrind integrations should be notified of
this memory region being undefined.
2023-04-25 11:23:41 -07:00
Andrew Kelley
881e931ee1 x86_64 backend: implement @memset for element ABI size > 1
* make memset and memset_safe guarantee that if the length is
   comptime-known then it will be nonzero.
2023-04-25 11:23:41 -07:00
Andrew Kelley
057c950093 LLVM backend: support non-byte-sized memset
Also introduce memset_safe AIR tag and support it in C backend and LLVM
backend.
2023-04-25 11:23:41 -07:00
Andrew Kelley
edb5e493e6 update @memcpy to require equal src and dest lens
* Sema: upgrade operands to array pointers if possible when emitting
   AIR.
 * Implement safety checks for length mismatch and aliasing.
 * AIR: make ptrtoint support slice operands. Implement in LLVM backend.
 * C backend: implement new `@memset` semantics. `@memcpy` is not done
   yet.
2023-04-25 11:23:40 -07:00
Andrew Kelley
a5c910adb6 change semantics of @memcpy and @memset
Now they use slices or array pointers with any element type instead of
requiring byte pointers.

This is a breaking enhancement to the language.

The safety check for overlapping pointers will be implemented in a
future commit.

closes #14040
2023-04-25 11:23:40 -07:00
zooster
bc8e1e1de4
Improvements to docs and text
* docs(std.math): elaborate on difference between absCast and absInt

* docs(std.rand.Random.weightedIndex): elaborate on likelihood

I think this makes it easier to understand.

* langref: add small reminder

* docs(std.fs.path.extension): brevity

* docs(std.bit_set.StaticBitSet): mention the specific types

* std.debug.TTY: explain what purpose this struct serves

This should also make it clearer that this struct is not supposed to provide unrelated terminal manipulation functionality such as setting the cursor position or something because terminals are complicated and we should keep this struct simple and focused on debugging.

* langref(package listing): brevity

* langref: explain what exactly `threadlocal` causes to happen

* std.array_list: link between swapRemove and orderedRemove

Maybe this can serve as a TLDR and make it easier to decide.

* PrefetchOptions.locality: clarify docs that this is a range

This confused me previously and I thought I can only use either 0 or 3.

* fix typos and more

* std.builtin.CallingConvention: document some CCs

* langref: explain possibly cryptic names

I think it helps knowing what exactly these acronyms (@clz and @ctz) and
abbreviations (@popCount) mean.

* variadic function error: add missing preposition

* std.fmt.format docs: nicely hyphenate

* help menu: say what to optimize for

I think this is slightly more specific than just calling it
"optimizations". These are speed optimizations. I used the word
"performance" here.
2023-04-23 21:06:21 +03:00
mlugg
407dc6eee4
Liveness: avoid emitting unused instructions or marking their operands as used
Backends want to avoid emitting unused instructions which do not have
side effects: to that end, they all have `Liveness.isUnused` checks for
many instructions. However, checking this in the backends avoids a lot
of potential optimizations. For instance, if a nested field is loaded,
then the first field access would still be emitted, since its result is
used by the next access (which is then unreferenced).

To elide more instructions, Liveness can track this data instead. For
operands which do not have to be lowered (i.e. are not side effecting
and are not something special like `arg), Liveness can ignore their
operand usages, and push the unused information further up, potentially
marking many more instructions as unreferenced.

In doing this, I also uncovered a bug in the LLVM backend relating to
discarding the result of `@cVaArg`, which this change fixes. A behaviour
test has been added to cover it.
2023-04-20 20:28:48 +01:00
Jacob Young
23d7921758 Sema: avoid emitting loops that can't loop
If a `loop` ends with a `noreturn` instruction, then it cannot loop and
will be emitted as a `block` instead.
2023-04-10 20:57:49 -04:00
Robin Voetter
3357c59ceb new builtins: @workItemId, @workGroupId, @workGroupSize
* @workItemId returns the index of the work item in a work group for a
  dimension.
* @workGroupId returns the index of the work group in the kernel dispatch for a
  dimension.
* @workGroupSize returns the size of the work group for a dimension.

These builtins are mainly useful for GPU backends. They are currently only
implemented for the AMDGCN LLVM backend.
2023-03-30 12:20:24 +03:00
r00ster91
65368683ad add @trap builtin
This introduces a new builtin function that compiles down to something that results in an illegal instruction exception/interrupt.
It can be used to exit a program abnormally.

This implements the builtin for all backends.
2023-03-04 12:08:19 +01:00
Veikka Tuominen
4e64373fc0 fix generic function arg debug info referencing wrong parameter
Closes #14123
2022-12-30 17:00:50 +02:00
Andrew Kelley
aca9c74e80
Merge pull request #13914 from Vexu/variadic
implement defining C variadic functions
2022-12-18 16:24:13 -05:00
r00ster91
aac2d6b56f std.builtin: rename Type.UnionField and Type.StructField's field_type to type 2022-12-17 14:11:33 +01:00
Veikka Tuominen
9bb1104e37 implement defining C variadic functions 2022-12-17 13:22:09 +02:00