AIR:
* div is renamed to div_trunc.
* Add div_float, div_floor, div_exact.
- Implemented in Sema and LLVM codegen. C backend has a stub.
Improvements to std.math.big.Int:
* Add `eqZero` function to `Mutable`.
* Fix incorrect results for `divFloor`.
Compiler-rt:
* Add muloti4 to the stage2 section.
* Restructure elemPtr a bit
* New AIR instruction: slice_elem_ptr, which returns a pointer to an element of a slice
* Value: adapt elemPtr to work on slices
* New AIR instruction: slice, which constructs a slice out of a pointer
and a length.
* AstGen: use `coerced_ty` for start and end expressions, use `none`
for the sentinel, and don't try to load the result of the slice
operation because it returns a by-value result.
* Sema: pointer arithmetic is extracted into analyzePointerArithmetic
and it is used by the implementation of slice.
- Also I implemented comptime pointer addition.
* Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them
inside the slice semantic analysis.
- The approach in stage2 is much cleaner than stage1 because it uses
more granular analysis calls for obtaining the slice pointer, doing
arithmetic on it, and checking if the length is comptime-known.
* Sema: use the slice Value Tag for slices when doing coercion from
pointer-to-array.
* LLVM backend: detect when emitting a GEP instruction into a
pointer-to-array and add the extra index that is required.
* Type: ptrAlignment for c_void returns 0.
* Implement Value.hash and Value.eql for slices.
* Remove accidentally duplicated behavior test.
* std.os: take advantage of `@minimum`. It's probably time to
deprecate `std.min` and `std.max`.
* New AIR instructions: min and max
* Introduce SIMD vector support to stage2
* Add `@Type` support for vectors
* Sema: add `checkSimdBinOp` which can be re-used for other arithmatic
operators that want to support vectors.
* Implement coercion from vectors to arrays.
- In backends this is handled with bitcast for vector to array,
however maybe we want to reduce the amount of branching by
introducing an explicit AIR instruction for it in the future.
* LLVM backend: implement lowering vector types
* Sema: Implement `slice.ptr` at comptime
* Value: improve `numberMin` and `numberMax` to support floats in
addition to integers, and make them behave properly in the presence
of NaN.
* Add AIR instructions: ret_ptr, ret_load
- This allows Sema to be blissfully unaware of the backend's decision
to implement by-val/by-ref semantics for struct/union/array types.
Backends can lower these simply as alloc, load, ret instructions,
or they can take advantage of them to use a result pointer.
* Add AIR instruction: array_elem_val
- Allows for better codegen for `Sema.elemVal`.
* Implement calculation of ABI alignment and ABI size for unions.
* Before appending the following AIR instructions to a block,
resolveTypeLayout is called on the type:
- call - return type
- ret - return type
- store_ptr - elem type
* Sema: fix memory leak in `zirArrayInit` and other cleanups to this
function.
* x86_64: implement the full x86_64 C ABI according to the spec
* Type: implement `intInfo` for error sets.
* Type: implement `intTagType` for tagged unions.
The Zig type tag `Fn` is now used exclusively for function bodies.
Function pointers are modeled as `*const T` where `T` is a `Fn` type.
* The `call` AIR instruction now allows a function pointer operand as
well as a function operand.
* Sema now has a coercion from function body to function pointer.
* Function type syntax, e.g. `fn()void`, now returns zig tag type of
Pointer with child Fn, rather than Fn directly.
- I think this should probably be reverted. Will discuss the lang
specs before doing this. Idea being that function pointers would
need to be specified as `*const fn()void` rather than `fn() void`.
LLVM backend:
* Enable calling the panic handler (previously this just
emitted `@breakpoint()` since the backend could not handle the panic
function).
* Implement sret
* Introduce `isByRef` and implement it for structs and arrays. Types
that are `isByRef` are now passed as pointers to functions, and e.g.
`elem_val` will return a pointer instead of doing a load.
* Move the function type creating code from `resolveLlvmFunction` to
`llvmType` where it belongs; now there is only 1 instance of this
logic instead of two.
* Add the `nonnull` attribute to non-optional pointer parameters.
* Fix `resolveGlobalDecl` not using fully-qualified names and not using
the `decl_map`.
* Implement `genTypedValue` for pointer-like optionals.
* Fix memory leak when lowering `block` instruction and OOM occurs.
* Implement volatile checks where relevant.
* Update AIR instruction `intcast` to allow the dest type to be an
enum.
* LLVM backend: update `intcast` to support when the bit counts of
operand and dest type are the same. This was already a requirement of
the instruction previously.
* Type: `intInfo` supports the case when the type is an enum, and
retrieves the info for the integer tag type. This makes it pretty
easy for backends to implement `intcast` without having to care
explicitly that the new type is an enum. As a bonus, simple enums
never have to go through the type system; their signedness and bit
count are computed directly.
The "int to enum" behavior test case is now passing for stage2 in the
LLVM backend.
Also improve the LLVM backend to support lowering bigints to LLVM
values.
Moves over a bunch of math.zig test cases to the "passing for stage2"
section.
* Remove the builtins `@addWithSaturation`, `@subWithSaturation`,
`@mulWithSaturation`, and `@shlWithSaturation` now that we have
first-class syntax for saturating arithmetic.
* langref: Clarify the behavior of `@shlExact`.
* Ast: rename `bit_shift_left` to `shl` and `bit_shift_right` to `shr`
for consistency.
* Air: rename to include underscore separator with consistency with
the rest of the ops.
* Air: add shl_exact instruction
* Use non-extended tags for saturating arithmetic, to keep it
simple so that all the arithmetic operations can be done the same
way.
- Sema: unify analyzeArithmetic with analyzeSatArithmetic
- implement comptime `+|`, `-|`, and `*|`
- allow float operands to saturating arithmetic
* `<<|` allows any integer type for the RHS.
* C backend: fix rebase conflicts
* LLVM backend: reduce the amount of branching for arithmetic ops
* zig.h: fix magic number not matching actual size of C integer types
- adds initial support for the operators +|, -|, *|, <<|, +|=, -|=, *|=, <<|=
- uses operators in addition to builtins in behavior test
- adds binOpExt() and assignBinOpExt() to AstGen.zig. these need to be audited
* AIR: add `mod` instruction for modulus division
- Implement for LLVM backend
* Sema: implement `@mod`, `@rem`, and `%`.
* Sema: fix comptime switch evaluation
* Sema: implement comptime shift left
* Sema: fix the logic inside analyzeArithmetic to handle all the
nuances between the different mathematical operations.
- Implement comptime wrapping operations
* AIR: add `get_union_tag` instruction
- implement in LLVM backend
* Sema: implement == and != for union and enum literal
- Also implement coercion from union to its own tag type
* Value: implement hashing for union values
The motivating example is this snippet:
comptime assert(@typeInfo(T) == .Float);
This was the next blocker for stage2 building compiler-rt.
Now it is switch at compile-time on an integer.
* AIR instructions struct_field_ptr and related functions now are also
emitted by the frontend for unions. Backends must inspect the type
of the pointer operand to lower the instructions correctly.
- These will be renamed to `agg_field_ptr` (short for "aggregate") in
the future.
* Introduce the new `set_union_tag` AIR instruction.
* Introduce `Module.EnumNumbered` and associated `Type` methods. This
is for enums which have no decls, but do have the possibility of
overriding the integer tag type and tag values.
* Sema: Implement support for union tag types in both the
auto-generated and explicitly-provided cases, as well as explicitly
provided enum tag values in union declarations.
* LLVM backend: implement lowering union types, union field pointer
instructions, and the new `set_union_tag` instruction.
* prepare compiler-rt to support being compiled by stage2
- put in a few minor workarounds that will be removed later, such as
using `builtin.stage2_arch` rather than `builtin.cpu.arch`.
- only try to export a few symbols for now - we'll move more symbols
over to the "working in stage2" section as they become functional
and gain test coverage.
- use `inline fn` at function declarations rather than `@call` with an
always_inline modifier at the callsites, to avoid depending on the
anonymous array literal syntax language feature (for now).
* AIR: replace floatcast instruction with fptrunc and fpext for
shortening and widening floating point values, respectively.
* Introduce a new ZIR instruction, `export_value`, which implements
`@export` for the case when the thing to be exported is a local
comptime value that points to a function.
- AstGen: fix `@export` not properly reporting ambiguous decl
references.
* Sema: handle ExportOptions linkage. The value is now available to all
backends.
- Implement setting global linkage as appropriate in the LLVM
backend. I did not yet inspect the LLVM IR, so this still needs to
be audited. There is already a pending task to make sure the alias
stuff is working as intended, and this is related.
- Sema almost handles section, just a tiny bit more code is needed in
`resolveExportOptions`.
* Sema: implement float widening and shortening for both `@floatCast`
and float coercion.
- Implement the LLVM backend code for this as well.
* introduce float_to_int and int_to_float AIR instructionts and
implement for the LLVM backend and C backend.
* Sema: implement `zirIntToFloat`.
* Sema: implement `@atomicRmw` comptime evaluation
- introduce `storePtrVal` for when one needs to store a Value to a
pointer which is a Value, and assert it happens at comptime.
* Value: introduce new functionality:
- intToFloat
- numberAddWrap
- numberSubWrap
- numberMax
- numberMin
- bitwiseAnd
- bitwiseNand (not implemented yet)
- bitwiseOr
- bitwiseXor
* Sema: hook up `zirBitwise` to the new Value bitwise implementations
* Type: rename `isFloat` to `isRuntimeFloat` because it returns `false`
for `comptime_float`.
* langref: add some more "see also" links for atomics
* Add the following AIR instructions
- atomic_load
- atomic_store_unordered
- atomic_store_monotonic
- atomic_store_release
- atomic_store_seq_cst
- atomic_rmw
* Implement those AIR instructions in LLVM and C backends.
* AstGen: make the `ty` result locations for `@atomicRmw`, `@atomicLoad`,
and `@atomicStore` be `coerced_ty` to avoid unnecessary ZIR
instructions when Sema will be doing the coercions redundantly.
* Sema for `@atomicLoad` and `@atomicRmw` is done, however Sema for
`@atomicStore` is not yet implemented.
- comptime eval for `@atomicRmw` is not yet implemented.
* Sema: flesh out `coerceInMemoryAllowed` a little bit more. It can now
handle pointers.
* Implement Sema for `@cmpxchgWeak` and `@cmpxchgStrong`. Both runtime
and comptime codepaths are implement.
* Implement Codegen for LLVM backend and C backend.
* Add LazySrcLoc.node_offset_builtin_call_argX 3...5
* Sema: rework comptime control flow.
- `error.ComptimeReturn` is used to signal that a comptime function
call has returned a result (stored in the Inlining struct).
`analyzeCall` notices this and handles the result.
- The ZIR instructions `break_inline`, `block_inline`,
`condbr_inline` are now redundant and can be deleted. `break`,
`block`, and `condbr` function equivalently inside a comptime scope.
- The ZIR instructions `loop` and `repeat` also are modified to
directly perform comptime control flow inside a comptime scope,
skipping an unnecessary mechanism for analysis of runtime code.
This makes Zig perform closer to an interpreter when evaluating
comptime code.
* Sema: zirRetErrValue looks at Sema.ret_fn_ty rather than sema.func
for adding to the inferred error set. This fixes a bug for
inlined/comptime function calls.
* Implement ZIR printing for cmpxchg.
* stage1: make cmpxchg respect --single-threaded
- Our LLVM C++ API wrapper failed to expose this boolean flag before.
* Fix AIR printing for struct fields showing incorrect liveness data.
The big change in this commit is making `semaDecl` resolve the fields if
the Decl ends up being a struct or union. It needs to do this while
the `Sema` is still in scope, because it will have the resolved AIR
instructions that the field type expressions possibly reference. We do
this after the decl is populated and set to `complete` so that a `Decl`
may reference itself.
Everything else is fixes and improvements to make the test suite pass
again after making this change.
* New AIR instruction: `ptr_elem_ptr`
- Implemented for LLVM backend
* New Type tag: `type_info` which represents `std.builtin.TypeInfo`. It
is used by AstGen for the operand type of `@Type`.
* ZIR instruction `set_float_mode` uses `coerced_ty` to avoid
superfluous `as` instruction on operand.
* ZIR instruction `Type` uses `coerced_ty` to properly handle result
location type of operand.
* Fix two instances of `enum_nonexhaustive` Value Tag not handled
properly - it should generally be handled the same as `enum_full`.
* Fix struct and union field resolution not copying Type and Value
objects into its Decl arena.
* Fix enum tag value resolution discarding the ZIR=>AIR instruction map
for the child Sema, when they still needed to be accessed.
* Fix `zirResolveInferredAlloc` use-after-free in the AIR instructions
data array.
* Fix `elemPtrArray` not respecting const/mutable attribute of pointer
in the result type.
* Fix LLVM backend crashing when `updateDeclExports` is called before
`updateDecl`/`updateFunc` (which is, according to the API, perfectly
legal for the frontend to do).
* Fix LLVM backend handling element pointer of pointer-to-array. It
needed another index in the GEP otherwise LLVM saw the wrong type.
* Fix LLVM test cases not returning 0 from main, causing test failures.
Fixes a regression introduced in
6a5094872f10acc629543cc7f10533b438d0283a.
* Implement comptime shift-right.
* Implement `@Type` for integers and `@TypeInfo` for integers.
* Implement union initialization syntax.
* Implement `zirFieldType` for unions.
* Implement `elemPtrArray` for a runtime-known operand.
* Make `zirLog2IntType` support RHS of shift being `comptime_int`. In
this case it returns `comptime_int`.
The motivating test case for this commit was originally:
```zig
test "example" {
var l: List(10) = undefined;
l.array[1] = 1;
}
fn List(comptime L: usize) type {
var T = u8;
return struct {
array: [L]T,
};
}
```
However I changed it to:
```zig
test "example" {
var l: List = undefined;
l.array[1] = 1;
}
const List = blk: {
const T = [10]u8;
break :blk struct {
array: T,
};
};
```
Which ended up being a similar, smaller problem. The former test case
will require a similar solution in the implementation of comptime
function calls - checking if the result of the function call is a struct
or union, and using the child `Sema` before it is destroyed to resolve
the fields.
* New AIR instructions: ptr_add, ptr_sub, ptr_elem_val, ptr_ptr_elem_val
- See the doc comments for details.
* Sema: implement runtime pointer arithmetic.
* Sema: implement elem_val for many-pointers.
* Sema: support coercion from `*[N:s]T` to `[*]T`.
* Type: isIndexable handles many-pointers.
* `Value.toType` accepts a buffer parameter instead of an allocator
parameter and can no longer fail.
* Module: remove the unused `mod: *Module` parameter from various
functions.
* `Value.compare` now accepts a `Type` parameter which indicates the
type of both operands. There is also a `Value.compareHetero` which
accepts only Value parameters and supports comparing mixed types.
Likewise, `Value.eql` requires a `Type` parameter.
* `Value.hash` is removed; instead the hash map context structs now
have a `ty: Type` field, and the hash function lives there, where it
has access to a Value's Type when it computes a hash.
- This allowed the hash function to be greatly simplified and sound
in the sense that the same Values, even with different
representations, always hash to the same thing.
* Sema: Fix source location of zirCmp when an operand is runtime known
but needs to be comptime known.
* Remove unused target parameter from `Value.floatCast`.
* AIR no longer has a `variables` array. Instead of the `varptr`
instruction, Sema emits a constant with a `decl_ref`.
* AIR no longer has a `ref` instruction. There is no longer any
instruction that takes a value and returns a pointer to it. If this
is desired, Sema must either create an anynomous Decl and return a
constant `decl_ref`, or in the case of a runtime value, emit an
`alloc` instruction, `store` the value to it, and then return the
`alloc`.
* The `ref_val` Value Tag is eliminated. `decl_ref` should be used
instead. Also added is `eu_payload_ptr` which points to the payload
of an error union, given an error union pointer.
In general, Sema should avoid calling `analyzeRef` if it can be helped.
For example in the case of field_val and elem_val, there should never be
a reason to create a temporary (alloc or decl). Recent previous commits
made progress along that front.
There is a new abstraction in Sema, which looks like this:
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
// here 'anon_decl.arena()` may be used
const decl = try anon_decl.finish(ty, val);
// decl is typically now used with `decl_ref`.
This pattern is used to upgrade `ref_val` usages to `decl_ref` usages.
Additional improvements:
* Sema: fix source location resolution for calling convention
expression.
* Sema: properly report "unable to resolve comptime value" for loads of
global variables. There is now a set of functions which can be
called if the callee wants to obtain the Value even if the tag is
`variable` (indicating comptime-known address but runtime-known value).
* Sema: `coerce` resolves builtin types before checking equality.
* Sema: fix `u1_type` missing from `addType`, making this type have a
slightly more efficient representation in AIR.
* LLVM backend: fix `genTypedValue` for tags `decl_ref` and `variable`
to properly do an LLVMConstBitCast.
* Remove unused parameter from `Value.toEnum`.
After this commit, some test cases are no longer passing. This is due to
the more principled approach to comptime references causing more
anonymous decls to get sent to the linker for codegen. However, in all
these cases the decls are not actually referenced by the runtime machine
code. A future commit in this branch will implement garbage collection
of decls so that unused decls do not get sent to the linker for codegen.
This will make the tests go back to passing.
* Add AIR instruction: struct_field_val
- This is part of an effort to eliminate the AIR instruction `ref`.
- It's implemented for C backend and LLVM backend so far.
* Rename `resolvePossiblyUndefinedValue` to `resolveMaybeUndefVal` just
to save some columns on long lines.
* Sema: add `fieldVal` alongside `fieldPtr` (renamed from
`namedFieldPtr`). This is part of an effort to eliminate the AIR
instruction `ref`. The idea is to avoid unnecessary loads, stores,
stack usage, and IR instructions, by paying a DRY cost.
LLVM backend improvements:
* internal linkage vs exported linkage is implemented, along with
aliases. There is an issue with incremental updates due to missing
LLVM API for deleting aliases; see the relevant comment in this commit.
- `updateDeclExports` is hooked up to the LLVM backend now.
* Fix usage of `Type.tag() == .noreturn` rather than calling `isNoReturn()`.
* Properly mark global variables as mutable/constant.
* Fix llvm type generation of function pointers
* Fix codegen for calls of function pointers
* Implement llvm type generation of error unions and error sets.
* Implement AIR instructions: addwrap, subwrap, mul, mulwrap, div,
bit_and, bool_and, bit_or, bool_or, xor, struct_field_ptr,
struct_field_val, unwrap_errunion_err, add for floats, sub for
floats.
After this commit, `zig test` on a file with `test "example" {}`
correctly generates and executes a test binary. However the
`test_functions` slice is undefined and just happens to be going into
the .bss section, causing the length to be 0. The next step towards
`zig test` will be replacing the `test_functions` Decl Value with the
set of test function pointers, before it is sent to linker/codegen.
* There is now a main_pkg in addition to root_pkg. They are usually the
same. When using `zig test`, main_pkg is the user's source file and
root_pkg has the test runner.
* scanDecl no longer looks for test decls outside the package being
tested. honoring `--test-filter` is still TODO.
* test runner main function has a void return value rather than
`anyerror!void`
* Sema is improved to generate better AIR for for loops on slices.
* Sema: fix incorrect capacity calculation in zirBoolBr
* Sema: add compile errors for trying to use slice fields as an lvalue.
* Sema: fix type coercion for error unions
* Sema: fix analyzeVarRef generating garbage AIR
* C codegen: fix renderValue for error unions with 0 bit payload
* C codegen: implement function pointer calls
* CLI: fix usage text
Adds 4 new AIR instructions:
* slice_len, slice_ptr: to get the ptr and len fields of a slice.
* slice_elem_val, ptr_slice_elem_val: to get the element value of
a slice, and a pointer to a slice.
AstGen gains a new functionality:
* One of the unused flags of struct decls is now used to indicate
structs that are known to have non-zero size based on the AST alone.
Now supports multiple items pointing to the same body. This is a common
pattern even when using a jump table, with multiple cases pointing to
the same block of code.
In the case of a range specified, the items are moved to branches in the
else body. A future improvement may make it possible to have jump table
items as well as ranges pointing to the same block of code.
* some instructions are not implemented yet
* fix off-by-1 in Air.getMainBody
* Compilation: use `@import("builtin")` rather than `std.builtin`
for the values that are different for different build configurations.
* Sema: avoid calling `addType` in between
air_instructions.ensureUnusedCapacity and corresponding
appendAssumeCapacity because it can possibly add an instruction.
* Value: functions print their names
Additionally: ZIR encoding for floats now supports float literals up to
f64, not only f32. This is because we no longer need a source location
for this instruction.
Now the branch is compiling again, provided that one uses
`-Dskip-non-native`, but many code paths are disabled. The code paths
can now be re-enabled one at a time and updated to conform to the new
AIR memory layout.
It's pretty compact, with each AIR instruction only taking up 4 bits,
plus a sparse table for special instructions such as conditional branch,
switch branch, and function calls with more than 2 arguments.
This commit changes the AIR file and the documentation of the memory
layout. The actual work of modifying the surrounding code (in Sema and
codegen) is not yet done.