aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
AgeCommit message (Collapse)Author
2024-04-17compiler: rework comptime pointer representation and accessmlugg
We've got a big one here! This commit reworks how we represent pointers in the InternPool, and rewrites the logic for loading and storing from them at comptime. Firstly, the pointer representation. Previously, pointers were represented in a highly structured manner: pointers to fields, array elements, etc, were explicitly represented. This works well for simple cases, but is quite difficult to handle in the cases of unusual reinterpretations, pointer casts, offsets, etc. Therefore, pointers are now represented in a more "flat" manner. For types without well-defined layouts -- such as comptime-only types, automatic-layout aggregates, and so on -- we still use this "hierarchical" structure. However, for types with well-defined layouts, we use a byte offset associated with the pointer. This allows the comptime pointer access logic to deal with reinterpreted pointers far more gracefully, because the "base address" of a pointer -- for instance a `field` -- is a single value which pointer accesses cannot exceed since the parent has undefined layout. This strategy is also more useful to most backends -- see the updated logic in `codegen.zig` and `codegen/llvm.zig`. For backends which do prefer a chain of field and elements accesses for lowering pointer values, such as SPIR-V, there is a helpful function in `Value` which creates a strategy to derive a pointer value using ideally only field and element accesses. This is actually more correct than the previous logic, since it correctly handles pointer casts which, after the dust has settled, end up referring exactly to an aggregate field or array element. In terms of the pointer access code, it has been rewritten from the ground up. The old logic had become rather a mess of special cases being added whenever bugs were hit, and was still riddled with bugs. The new logic was written to handle the "difficult" cases correctly, the most notable of which is restructuring of a comptime-only array (for instance, converting a `[3][2]comptime_int` to a `[2][3]comptime_int`. Currently, the logic for loading and storing work somewhat differently, but a future change will likely improve the loading logic to bring it more in line with the store strategy. As far as I can tell, the rewrite has fixed all bugs exposed by #19414. As a part of this, the comptime bitcast logic has also been rewritten. Previously, bitcasts simply worked by serializing the entire value into an in-memory buffer, then deserializing it. This strategy has two key weaknesses: pointers, and undefined values. Representations of these values at comptime cannot be easily serialized/deserialized whilst preserving data, which means many bitcasts would become runtime-known if pointers were involved, or would turn `undefined` values into `0xAA`. The new logic works by "flattening" the datastructure to be cast into a sequence of bit-packed atomic values, and then "unflattening" it; using serialization when necessary, but with special handling for `undefined` values and for pointers which align in virtual memory. The resulting code is definitely slower -- more on this later -- but it is correct. The pointer access and bitcast logic required some helper functions and types which are not generally useful elsewhere, so I opted to split them into separate files `Sema/comptime_ptr_access.zig` and `Sema/bitcast.zig`, with simple re-exports in `Sema.zig` for their small public APIs. Whilst working on this branch, I caught various unrelated bugs with transitive Sema errors, and with the handling of `undefined` values. These bugs have been fixed, and corresponding behavior test added. In terms of performance, I do anticipate that this commit will regress performance somewhat, because the new pointer access and bitcast logic is necessarily more complex. I have not yet taken performance measurements, but will do shortly, and post the results in this PR. If the performance regression is severe, I will do work to to optimize the new logic before merge. Resolves: #19452 Resolves: #19460
2024-04-08InternPool: remove slice from byte aggregate keysJacob Young
This deletes a ton of lookups and avoids many UAF bugs. Closes #19485
2024-03-30cbe: rewrite `CType`Jacob Young
Closes #14904
2024-03-27Merge pull request #19430 from ziglang/dwarf-ubJakub Konka
link: fix undefined memory being written out in dwarf and codegen
2024-03-26compiler: eliminate TypedValuemlugg
The only logic which remained in this file was the Value printing logic. This has been moved into a new `print_value.zig`.
2024-03-26compiler: eliminate most usages of TypedValuemlugg
2024-03-26Zcu: eliminate `Decl.alive` fieldmlugg
Legacy anon decls now have three uses: * Type owner decls * Function owner decls * `@export` and `@extern` Therefore, there are no longer any cases where we wish to explicitly omit legacy anon decls from the binary. This means we can remove the concept of an "alive" vs "dead" `Decl`, which also allows us to remove the separate `anon_work_queue` in `Compilation`.
2024-03-26compiler: eliminate legacy Value representationmlugg
Good riddance! Most of these changes are trivial. There's a fix for a minor bug this exposed in `Value.readFromPackedMemory`, but aside from that, it's all just things like changing `intern` calls to `toIntern`.
2024-03-26Zcu.Decl: remove `ty` fieldmlugg
`Decl` can no longer store un-interned values, so this field is now unnecessary. The type can instead be fetched with the new `typeOf` helper method, which just gets the type of the Decl's `Value`.
2024-03-25dwarf+codegen: use appendNTimes instead of writer().writeByteNTimesJakub Konka
2024-03-25compiler: implement analysis-local comptime-mutable memorymlugg
This commit changes how we represent comptime-mutable memory (`comptime var`) in the compiler in order to implement the intended behavior that references to such memory can only exist at comptime. It does *not* clean up the representation of mutable values, improve the representation of comptime-known pointers, or fix the many bugs in the comptime pointer access code. These will be future enhancements. Comptime memory lives for the duration of a single Sema, and is not permitted to escape that one analysis, either by becoming runtime-known or by becoming comptime-known to other analyses. These restrictions mean that we can represent comptime allocations not via Decl, but with state local to Sema - specifically, the new `Sema.comptime_allocs` field. All comptime-mutable allocations, as well as any comptime-known const allocs containing references to such memory, live in here. This allows for relatively fast checking of whether a value references any comptime-mtuable memory, since we need only traverse values up to pointers: pointers to Decls can never reference comptime-mutable memory, and pointers into `Sema.comptime_allocs` always do. This change exposed some faulty pointer access logic in `Value.zig`. I've fixed the important cases, but there are some TODOs I've put in which are definitely possible to hit with sufficiently esoteric code. I plan to resolve these by auditing all direct accesses to pointers (most of them ought to use Sema to perform the pointer access!), but for now this is sufficient for all realistic code and to get tests passing. This change eliminates `Zcu.tmp_hack_arena`, instead using the Sema arena for comptime memory mutations, which is possible since comptime memory is now local to the current Sema. This change should allow `Decl` to store only an `InternPool.Index` rather than a full-blown `ty: Type, val: Value`. This commit does not perform this refactor.
2024-03-25codegen: actually write out padding for packed structs upfrontJakub Konka
2024-03-11std.builtin: make container layout fields lowercaseTristan Ross
2024-03-06InternPool: create specialized functions for loading namespace typesmlugg
Namespace types (`struct`, `enum`, `union`, `opaque`) do not use structural equality - equivalence is based on their Decl index (and soon will change to AST node + captures). However, we previously stored all other information in the corresponding `InternPool.Key` anyway. For logical consistency, it makes sense to have the key only be the true key (that is, the Decl index) and to load all other data through another function. This introduces those functions, by the name of `loadStructType` etc. It's a big diff, but most of it is no-brainer changes. In future, it might be nice to eliminate a bunch of the loaded state in favour of accessor functions on the `LoadedXyzType` types (like how we have `LoadedUnionType.size()`), but that can be explored at a later date.
2024-02-26move Zir to std.zig.ZirAndrew Kelley
Part of an effort to ship more of the compiler in source form.
2024-02-25x86_64: implement `@shuffle`Jacob Young
2024-02-16InternPool: make more use of `NullTerminatedString.Slice`Jacob Young
This should avoid the random pointer invalidation crashes. Closes #18954
2024-02-05compiler: rename value.zig to Value.zigAndrew Kelley
This commit only does the file rename to be friendlier to version control conflicts.
2024-02-02InternPool: use separate key for slicesmlugg
This change eliminates some problematic recursive logic in InternPool, and provides a safer API.
2024-01-24macho: prep for lowering TLS variablesJakub Konka
2024-01-24macho: fix '_' prefixing rules for exportsJakub Konka
2024-01-24macho: fix symbol index dereference in codegen wrt ZigObjectJakub Konka
This is incredibly confusing and I really need to simplify it. Elf also possesses this shortcoming so once I get Coff up to speed it should hopefully become clear on how to refactor this.
2024-01-24codegen: implement more missing bitsJakub Konka
2024-01-24codegen: re-implement enough of codegen to error out instead panicJakub Konka
2024-01-24codegen: re-enable MachO support in genDeclRefJakub Konka
2024-01-24macho: get the ball rolling!Jakub Konka
2024-01-01frontend: fix handling of special builtin moduleAndrew Kelley
it's allocated differently and imported differently
2024-01-01fix a round of compile errors caused by this branchAndrew Kelley
2024-01-01compiler: update references to targetAndrew Kelley
2024-01-01update references to module (to be renamed to zcu)Andrew Kelley
2024-01-01compiler: update references to single_threadedAndrew Kelley
2023-12-04x86_64: implement more operations on vectors with 1-bit elementsJacob Young
2023-12-03x86_64: implement more compliant vectorsJacob Young
2023-12-01test: test with `-fstrip` and fix failuresJacob Young
Closes #17513
2023-11-26move Module.Decl.Index and Module.Namespace.Index to InternPoolMeghan Denny
2023-11-25convert `toType` and `toValue` to `Type.fromInterned` and `Value.fromInterned`Techatrix
2023-11-19compiler: correct unnecessary uses of 'var'mlugg
2023-11-12x86_64: resolve tlv references on first use and spill to the stackJacob Young
This avoids any arbitrary memory operand possibly clobbering rax and sometime rdi with no warning.
2023-11-12elf: set symbol flags such as needs_zig_got in ZigObjectJakub Konka
2023-11-04Merge pull request #17844 from ziglang/elf-objectJakub Konka
elf: handle emitting relocatables and static libraries - humble beginnings
2023-11-04elf: postpone creation of .got.zig entry until code emitJakub Konka
2023-11-04elf: make sure we never emit .got.zig relocs when linking object filesJakub Konka
2023-11-03x86_64: fix std test failuresJacob Young
2023-10-30elf: move incremental codegen bits into ZigObject.zigJakub Konka
2023-10-30elf: rename ZigModule to ZigObjectJakub Konka
2023-10-30coff: implement enough of extern handling to pass comptime export testsJakub Konka
2023-10-30macho: implement enough of extern handling to pass comptime export testsJakub Konka
2023-10-28x86_64: no more load/lea_symbol weirdnessJakub Konka
2023-10-28elf: set needs_got on generated extern varsJakub Konka
2023-10-28x86_64: rename load/lea_memory to load/lea_symbolJakub Konka