Frontend improvements:
* When compiling in `zig test` mode, put a task on the work queue to
analyze the main package root file. Normally, start code does
`_ = import("root");` to make Zig analyze the user's code, however in
the case of `zig test`, the root source file is the test runner.
Without this change, no tests are picked up.
* In the main pipeline, once semantic analysis is finished, if there
are no compile errors, populate the `test_functions` Decl with the
set of test functions picked up from semantic analysis.
* Value: add `array` and `slice` Tags.
LLVM backend improvements:
* Fix incremental updates of globals. Previously the
value of a global would not get replaced with a new value.
* Fix LLVM type of arrays. They were incorrectly sending
the ABI size as the element count.
* Remove the FuncGen parameter from genTypedValue. This function is for
generating global constants and there is no function available when
it is being called.
- The `ref_val` case is now commented out. I'd like to eliminate
`ref_val` as one of the possible Value Tags. Instead it should
always be done via `decl_ref`.
* Implement constant value generation for slices, arrays, and structs.
* Constant value generation for functions supports the `decl_ref` tag.
* 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.
* properly set global variables to const if they are not a global
variable.
* implement global variable initializations.
* initial implementation of llvmType() for structs and functions.
* implement genTypedValue for variable tags
* implement more AIR instructions: varptr, slice_ptr, slice_len,
slice_elem_val, ptr_slice_elem_val, unwrap_errunion_payload,
unwrap_errunion_payload_ptr, unwrap_errunion_err,
unwrap_errunion_err_ptr.
These AIR instructions are the next blockers for `zig test` to work for
this backend.
After this commit, the "hello world" x86_64 test case passes for the
LLVM backend as well.
This is an initial version, todo:
- Also make this work for u64 values, as the table must be indexed by u32.
- Add support for signed integers.
- Add support for enums.
* 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.
* Added doc comments for `std.Target.ObjectFormat` enum
* `std.Target.oFileExt` is removed because it is incorrect for Plan-9
targets. Instead, use `std.Target.ObjectFormat.fileExt` and pass a
CPU architecture.
* Added `Compilation.Directory.joinZ` for when a null byte is desired.
* Improvements to `Compilation.create` logic for computing `use_llvm`
and reporting errors in contradictory flags. `-femit-llvm-ir` and
`-femit-llvm-bc` will now imply `-fLLVM`.
* Fix compilation when passing `.bc` files on the command line.
* Improvements to the stage2 LLVM backend:
- cleaned up error messages and error reporting. Properly bubble up
some errors rather than dumping to stderr; others turn into panics.
- properly call ZigLLVMCreateTargetMachine and
ZigLLVMTargetMachineEmitToFile and implement calculation of the
respective parameters (cpu features, code model, abi name, lto,
tsan, etc).
- LLVM module verification only runs in debug builds of the compiler
- use LLVMDumpModule rather than printToString because in the case
that we incorrectly pass a null pointer to LLVM it may crash during
dumping the module and having it partially printed is helpful in
this case.
- support -femit-asm, -fno-emit-bin, -femit-llvm-ir, -femit-llvm-bc
- Support LLVM backend when used with Mach-O and WASM linkers.
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.
- Get correct types in wasm backend.
- `arg` is already a `Ref`, therefore simply use `@intToEnum`.
- Fix regression in `zirBoolBr, where the order of insertion was incorrect.
- Update `fail()` to not require a `srcLoc`.
This brings it in line with other backends, and we were always passing 'node_offset = 0', anyway.
- Fix unused local due to change of architecture wrt function/decl generation.
- Replace all old instructions to indexes within the function signatures.
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.
to the link infrastructure, instead of being stored with Module.Fn. This
moves towards a strategy to make more efficient use of memory by not
storing Air or Liveness data in the Fn struct, but computing it on
demand, immediately sending it to the backend, and then immediately
freeing it.
Backends which want to defer codegen until flush() such as SPIR-V
must move the Air/Liveness data upon `updateFunc` being called and keep
track of that data in the backend implementation itself.
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.
* less branching by passing parameters in the main op code switch.
* properly pass the target when asking the type system for int info.
* handle u8, i16, etc when it is represented using
int_unsigned/int_signed tag.
* compile error instead of assertion failure for unimplemented cases
(greater than 64 bits integer).
* control flow cleanups
* zig.h: expand macros into inline functions
* reduce the complexity of the test case by making it one test case
that calls multiple functions. Also fix the problem of c_int max
value mismatch between host and target.
* Inferred error sets are stored in the return Type of the function,
owned by the Module.Fn. So it cleans up that memory in deinit().
* Sema: update the inferred error set in zirRetErrValue
- Update relevant code in wrapErrorUnion
* C backend: improve some some instructions to take advantage of
liveness analysis to avoid being emitted when unused.
* C backend: when an error union has a payload type with no runtime
bits, emit the error union as the same type as the error set.
AstGen had the then-else logic backwards for if expressions
on error unions. This commit fixes it.
Turns out AstGen only really needs `is_non_null` and `is_non_err`,
and does not need the `is_null` or `is_err` variants. So I removed the
`is_null{,_ptr}` and `is_err{,_ptr}` ZIR instructions (-4) and
added `is_non_err`, `is_non_err_ptr` ZIR instructions (+2) for
a total of (-2) ZIR instructions, giving us a tiny bit more headroom
within the 256 tag limit. This required swapping the order of
then/else blocks in a handful of cases, but ultimately means the
ZIR will be in the same as source order, which is convenient
when debugging.
AIR code on the other hand, gains the `is_non_err` and `is_non_err_ptr`
instructions.
Sema: fix logic in zirErrUnionCode and zirErrUnionCodePtr returning the
wrong result type.
* ZIR: add two instructions:
- ret_err_value_code
- ret_err_value
* AstGen: add countDefers and utilize it to emit more efficient ZIR for
return expressions in the presence of defers.
* AstGen: implement |err| payloads for `errdefer` syntax.
- There is not an "unused capture" error for it yet.
* AstGen: `return error.Foo` syntax gets a hot path in return
expressions, using the new ZIR instructions. This also is part of
implementing inferred error sets, since we need to tell Sema to add
an error value to the inferred error set before it gets coerced.
* Sema: implement `@setCold`.
- Implement `@setCold` support for C backend.
* `@panic` and regular safety panics such as `unreachable` now properly
invoke `std.builtin.panic`.
* C backend: improve pointer and function value rendering.
* C linker: fix redundant typedefs.
* Add Type.error_set_inferred.
* Fix Value.format for enum_literal, enum_field_index, bytes.
* Remove the C backend test that checks for identical text
I measured a 14% reduction in Total ZIR Bytes from master branch
for std/os.zig.
There is now a distinction between `@import` with a .zig extension and
without. Without a .zig extension it assumes it is a package name, and
returns error.PackageNotFound if not mapped into the package table.
We can just use bitcast instead of error_to_int, int_to_error since
errorToInt and intToError do not actually do anything, just change types.
This allows us to remove 2 air ops that were the exact same as bitcast
- hash/eql functions moved into a Context object
- *Context functions pass an explicit context
- *Adapted functions pass specialized keys and contexts
- new getPtr() function returns a pointer to value
- remove functions renamed to fetchRemove
- new remove functions return bool
- removeAssertDiscard deleted, use assert(remove(...)) instead
- Keys and values are stored in separate arrays
- Entry is now {*K, *V}, the new KV is {K, V}
- BufSet/BufMap functions renamed to match other set/map types
- fixed iterating-while-modifying bug in src/link/C.zig