aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
AgeCommit message (Collapse)Author
2022-01-24stage2: rework a lot of stuffAndrew Kelley
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
2022-01-24llvm backend: fix not updating map after deleting globalAndrew Kelley
This was uncaught UB!
2022-01-24stage2: type system treats fn ptr and body separatelyAndrew Kelley
This commit updates stage2 to enforce the property that the syntax `fn()void` is a function *body* not a *pointer*. To get a pointer, the syntax `*const fn()void` is required. ZIR puts function alignment into the func instruction rather than the decl because this way it makes it into function types. LLVM backend respects function alignments. Struct and Union have methods `fieldSrcLoc` to help look up source locations of their fields. These trigger full loading, tokenization, and parsing of source files, so should only be called once it is confirmed that an error message needs to be printed. There are some nice new error hints for explaining why a type is required to be comptime, particularly for structs that contain function body types. `Type.requiresComptime` is now moved into Sema because it can fail and might need to trigger field type resolution. Comptime pointer loading takes into account types that do not have a well-defined memory layout and does not try to compute a byte offset for them. `fn()void` syntax no longer secretly makes a pointer. You get a function body type, which requires comptime. However a pointer to a function body can be runtime known (obviously). Compile errors that report "expected pointer, found ..." are factored out into convenience functions `checkPtrOperand` and `checkPtrType` and have a note about function pointers. Implemented `Value.hash` for functions, enum literals, and undefined values. stage1 is not updated to this (yet?), so some workarounds and disabled tests are needed to keep everything working. Should we update stage1 to these new type semantics? Yes probably because I don't want to add too much conditional compilation logic in the std lib for the different backends.
2022-01-24Cleanup unnecessary switches in union logicCody Tapscott
2022-01-24Run `zig fmt`Cody Tapscott
2022-01-24Add `union` support to the C backend.Cody Tapscott
There are some differences vs. the union encoding in the LLVM backend: - Tagged unions with a 0-bit payload do not become their tag type. Instead, they are a struct with an empty `union` as their payload field. - We do not order the `payload`/`tag` storage based on their alignment
2022-01-24Fix rendering of `void` function argsCody Tapscott
2022-01-24Add support for rendering `.enum_numbered`Cody Tapscott
2022-01-24Avoid identifier conflicts with reserved C keywordsCody Tapscott
2022-01-24Add support for rendering `.elem_ptr`Cody Tapscott
2022-01-23c backend: Implement aligning fields and local/global variablesJimmi Holst Christensen
There are some restrictions here. - We either need C11 or a compiler that supports the aligned attribute - We cannot provide align less than the type's natural C alignment.
2022-01-20stage2: implement tuplesAndrew Kelley
* AIR instruction vector_init gains the ability to init arrays and tuples in addition to vectors. This will probably also gain the ability to initialize structs and be renamed to `aggregate_init`. * AstGen prefers to use an `anon_array_init` ZIR instruction for local variables when the init expr is an array literal and there is no type.
2022-01-18stage2: implement `@prefetch`Andrew Kelley
This reverts commit f423b5949b8722d4b290f57c3d06d015e39217b0, re-instating commit d48e4245b68bf25c7f41804a5012ac157a5ee546.
2022-01-18Revert "stage2: implement `@prefetch`"Andrew Kelley
This reverts commit d48e4245b68bf25c7f41804a5012ac157a5ee546. I have no idea why this is failing Drone CI, but in a branch, reverting this commit solved the problem.
2022-01-15stage2: implement `@prefetch`Andrew Kelley
2022-01-15stage2: fix Decl garbage collection not marking enoughAndrew Kelley
It is the job of codegen backends to mark Decls that are referenced as alive so that the frontend does not sweep them with the garbage. This commit unifies the code between the backends with an added method on Decl. The implementation is more complete than before, switching on the Decl val tag and recursing into sub-values. As a result, two more array tests are passing.
2022-01-13stage2: detection of comptime array literalsAndrew Kelley
Introduce `validate_array_init_comptime`, similar to `validate_struct_init_comptime` introduced in 713d2a9b3883942491b40738245232680877cc66. `zirValidateArrayInit` is improved to detect comptime array literals and emit AIR accordingly. This code is very similar to the changes introduced in that same commit for `zirValidateStructInit`. The C backend needed some improvements to continue passing the same set of tests: * `resolveInst` for arrays now will add a local `static const` with the array value and so then `elem_val` instructions reference that local. It memoizes accesses using `value_map`, which is changed to use `Air.Inst.Ref` as the key rather than `Air.Inst.Index`. * This required a mechanism for writing to a "header" which is lines that appear at the beginning of a function body, before everything else. * dbg_stmt output comments rather than `#line` directives. TODO comment reproduced here: We need to re-evaluate whether to emit these or not. If we naively emit these directives, the output file will report bogus line numbers because every newline after the #line directive adds one to the line. We also don't print the filename yet, so the output is strictly unhelpful. If we wanted to go this route, we would need to go all the way and not output newlines until the next dbg_stmt occurs. Perhaps an additional compilation option is in order? `Value.elemValue` is improved to support `elem_ptr` values.
2022-01-13stage2: fix build on 32-bit ISAsAndrew Kelley
Fixes regression introduced in 93b854eb745ab3294054ae71150fe60f134f4d10.
2022-01-12stage2: implement `@ctz` and `@clz` including SIMDAndrew Kelley
AIR: * `array_elem_val` is now allowed to be used with a vector as the array type. * New instructions: splat, vector_init AstGen: * The splat ZIR instruction uses coerced_ty for the ResultLoc, avoiding an unnecessary `as` instruction, since the coercion will be performed in Sema. * Builtins that accept vectors now ignore the type parameter. Comment from this commit reproduced here: The accepted proposal #6835 tells us to remove the type parameter from these builtins. To stay source-compatible with stage1, we still observe the parameter here, but we do not encode it into the ZIR. To implement this proposal in stage2, only AstGen code will need to be changed. Sema: * `clz` and `ctz` ZIR instructions are now handled by the same function which accept AIR tag and comptime eval function pointer to differentiate. * `@typeInfo` for vectors is implemented. * `@splat` is implemented. It takes advantage of `Value.Tag.repeated` 😎 * `elemValue` is implemented for vectors, when the index is a scalar. Handling a vector index is still TODO. * Element-wise coercion is implemented for vectors. It could probably be optimized a bit, but it is at least complete & correct. * `Type.intInfo` supports vectors, returning int info for the element. * `Value.ctz` initial implementation. Needs work. * `Value.eql` is implemented for arrays and vectors. LLVM backend: * Implement vector support when lowering `array_elem_val`. * Implement vector support when lowering `ctz` and `clz`. * Implement `splat` and `vector_init`.
2022-01-08stage2: @errorName sema+llvmRobin Voetter
2022-01-07Fix llvmFieldIndex for zero sized fieldsJimmi Holst Christensen
It is possible for Zig to emit field ptr instructions to fields whos type is zero sized. In this case llvm should return a pointer which points to the next none zero sized parameter.
2022-01-06zig fmtAndrew Kelley
2022-01-06Sema: const inferred alloc infers comptime-nessAndrew Kelley
const locals now detect if the value ends up being comptime known. In such case, it replaces the runtime AIR instructions with a decl_ref const. In the backends, some more sophisticated logic for marking decls as alive was needed to prevent Decls incorrectly being garbage collected that were indirectly referenced in such manner.
2022-01-03linker: fix build-obj and -fno-emit-binAndrew Kelley
This commit fixes two problems: * `zig build-obj` regressed from the cache-mode branch. It would crash because it assumed that dirname on the emit bin path would not be null. This assumption was invalid when outputting to the current working directory - a pretty common use case for `zig build-obj`. * When using the LLVM backend, `-fno-emit-bin` combined with any other kind of emitting, such as `-femit-asm`, emitted nothing. Both issues are now fixed.
2022-01-03stage2: introduce renameTmpIntoCache into the linker APIAndrew Kelley
Doc comments reproduced here: This function is called by the frontend before flush(). It communicates that `options.bin_file.emit` directory needs to be renamed from `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`. The frontend would like to simply perform a file system rename, however, some linker backends care about the file paths of the objects they are linking. So this function call tells linker backends to rename the paths of object files to observe the new directory path. Linker backends which do not have this requirement can fall back to the simple implementation at the bottom of this function. This function is only called when CacheMode is `whole`. This solves stack trace regressions on Windows and macOS because the linker backends do not observe object file paths until flush().
2021-12-30CBE; implement airLoad and airStore for arrays (#10452)drew
Effectively a small continuation of #10152 This allows the for.zig behavior tests to pass. Unfortunately to fully test everything I had to move a lot of behavior tests from array.zig; most of them now pass (sorry @rainbowbismuth!) I'm also conflicted on how I store constants into arrays because it's kind of stupid; array's can't be re-initialized using the same syntax, so instead of initializing each element, a new array is made which is copied into the destination. This also required that renderValue can't emit string literals for byte arrays given that they need to always have an extra byte for the NULL terminator, meaning that strings are no longer grep-able in the output.
2021-12-28stage2: LLVM backend: fix lowering of union constantsAndrew Kelley
Comment from this commit reproduced here: LLVM does not allow us to change the type of globals. So we must create a new global with the correct type, copy all its attributes, and then update all references to point to the new global, delete the original, and rename the new one to the old one's name. This is necessary because LLVM does not support const bitcasting a struct with padding bytes, which is needed to lower a const union value to LLVM, when a field other than the most-aligned is active. Instead, we must lower to an unnamed struct, and pointer cast at usage sites of the global. Such an unnamed struct is the cause of the global type mismatch, because we don't have the LLVM type until the *value* is created, whereas the global needs to be created based on the type alone, because lowering the value may reference the global as a pointer.
2021-12-27stage2: LLVM backend: fix const packed structsAndrew Kelley
When doing LLVM const bit shifting we must make sure the integer bit sizes are wide enough or else LLVM gives us a poison result.
2021-12-27stage2: make tests/behaviour/void.zig work with c backendMatthew Hall
* fix initialisation of void* fields of structs (initialises to 0xaa.. rather than {}) * don't generate struct fields when the field type does not have codegen bits * in airAlloc generate a void* literal if the element type does not have codegen bits
2021-12-27stage2: LLVM backend: implement `@tagName` for enumsAndrew Kelley
Introduced a new AIR instruction: `tag_name`. Reasons to do this instead of lowering it in Sema to a switch, function call, array lookup, or if-else tower: * Sema is a bottleneck; do less work in Sema whenever possible. * If any optimization passes run, and the operand to becomes comptime-known, then it could change to have a comptime result value instead of lowering to a function or array or something which would then have to be garbage-collected. * Backends may want to choose to use a function and a switch branch, or they may want to use a different strategy. Codegen for `@tagName` is implemented for the LLVM backend but not any others yet. Introduced some new `Type` tags: * `const_slice_u8_sentinel_0` * `manyptr_const_u8_sentinel_0` The motivation for this was to make typeof() on the tag_name AIR instruction non-allocating. A bunch more enum tests are passing now.
2021-12-24stage2: LLVM: fix lowering of packed structsAndrew Kelley
* ensure enough capacity when building the LLVM type and value. * add explicit padding field and populate it to ensure proper alignment.
2021-12-23stage2: initial implementation of packed structsAndrew Kelley
Layout algorithm: all `align(0)` fields are squished together as if they were a single integer with a number of bits equal to `@bitSizeOf` each field added together. Then the natural ABI alignment of that integer is used for that pseudo-field.
2021-12-21Sema: fix empty struct initAndrew Kelley
* Extract common logic between `zirStructInitEmpty` and `zirStructInit`. * `resolveTypeFields` additionally sets status to `have_layout` if the total number of fields is 0.
2021-12-21C backend: implement `ret_addr`Andrew Kelley
2021-12-21stage2: @shlWithOverflowRobin Voetter
2021-12-21stage2: @subWithOverflowRobin Voetter
2021-12-21stage2: make anyopaque sizedRobin Voetter
While this is technically incorrect, proper handling of anyopaque, as well as regular opaque, is probably best left until pointers to zero-sized types having no bits is abolished.
2021-12-21stage2: @mulWithOverflowRobin Voetter
2021-12-21stage2: @returnAddress()Robin Voetter
2021-12-21stage2: @addWithOverflowRobin Voetter
2021-12-21stage2: allow multiple inferred error sets per FnRobin Voetter
This allows the inferred error set of comptime and inline invocations to be resolved separately from the inferred error set of the runtime version or other comptime/inline invocations.
2021-12-21stage2: move inferred error set state into funcRobin Voetter
2021-12-03stage2: use Target.Abi instead of introducing Target.TargetAbiAndrew Kelley
This branch introduced std.Target.TargetAbi when we already had std.Target.Abi which was, unsurprisingly, already suited for this task. Also pull out the -mabi= cc flag addition to the common area instead of duplicating it for assembly and c files.
2021-12-03default mabi based on RISC-V extensions and -mabi build optionvole-dev
The target abi can also be set in build.zig via LibExeObjStep.target_abi The value passed in is checked that it is a valid value in std.Target.TargetAbi The target abi is also validated against the target cpu
2021-11-30allocgate: renamed getAllocator function to allocatorLee Cannon
2021-11-30allocgate: stage 1 and 2 buildingLee Cannon
2021-11-30allocgate: std Allocator interface refactorLee Cannon
2021-11-30std lib API deprecations for the upcoming 0.9.0 releaseAndrew Kelley
See #3811
2021-11-26Sema: fix analyzeBlockBody logicAndrew Kelley
Previously, when a coercion needed to be inserted into a break instruction, the `br` AIR instruction would be rewritten so that the block operand was a sub-block that did the coercion. The problem is that the sub-block itself was never added to the parent block, resulting in the `br` instruction operand being a bad reference. Now, the `br` AIR instruction that needs to have coercion instructions added is replaced with the sub-block itself with type `noreturn`, and then the sub-block has the coercion instructions and a new `br` instruction that breaks from the original block. LLVM backend needed to be fixed to lower `noreturn` blocks without emitting an unused LLVM basic block.
2021-11-24stage2: fix unwrap function call with optional pointer return valueAndrew Kelley