aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
AgeCommit message (Collapse)Author
2024-01-01Merge pull request #17824 from kcbanner/fixup_msvc_fmaxAndrew Kelley
cbe: add a system for avoiding collisions with C compiler intrinsics
2023-12-03Air: use typesafe `Air.Inst.Index`Jacob Young
I need some indices for a thing...
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-12rework memory management of Module.Namespace hash mapsAndrew Kelley
The motivating problem here was a memory leak in the hash maps of Module.Namespace. The commit deletes more of the legacy incremental compilation implementation. It had things like use of orderedRemove and trying to do too much OOP-style creation and deletion of objects. Instead, this commit iterates over all the namespaces on Module deinit and calls deinit on the hash map fields. This logic is much simpler to reason about. Similarly, change global inline assembly to an array hash map since iterating over the values is a primary use of it, and clean up the remaining values on Module deinit, solving another memory leak. After this there are no more memory leaks remaining when using the x86 backend in a libc-less compiler.
2023-11-07cbe: support rendering union values that have no defined tag typekcbanner
This was regressed in d657b6c0e2ab7c47f5416dc4df1abb2bfbecd4b6, when the comptime memory model for unions was changed to allow them to have no defined tag type.
2023-11-05cbe: handle underscore prexfix on macos, don't mangle extern function nameskcbanner
2023-11-05cbe: add DeclVisibility and zig_extern_mangled to handle exporting mangled ↵kcbanner
symbols under a different name
2023-11-05cbe: avoid collisions with builtins and intrinsicskcbanner
Changes: - Add `isMangledIdent` to determine if `fmtIdent` would make any edits to the identifier - Any function that has a mangled identifier is referred to using the mangled identifer within the current file, but if it is exported the first export will be with the non-mangled name. - Add `zig_import` to import a symbol under a different name - Add a level of indirection to float function names. Now, they are referred to as `zig_float_fn_<float type>_<operation>`. The definitions in zig.h are wrapped with `zig_import` to import the symbol under the real name. The specific problem that sparked this change was the combination of `zig_libc_name_f80(name) __##name##x` with the input `fma`, resulting in `__fmax`, which is a new intrinsic in recent versions of cl.exe. With the above changes in place, compiler_rt can output the following: ``` static zig_weak_linkage_fn zig_f80 zig_e___fmax(zig_f80, zig_f80, zig_f80); zig_export(zig_weak_linkage_fn zig_f80 zig_e___fmax(zig_f80, zig_f80, zig_f80), __fmax, "__fmax"); ``` Within compiler_rt, `zig_e___fmax` is used to refer to the function, but consumers will import `__fmax`, which maps to their `zig_float_fn_f80_fma` definition from zig.h.
2023-10-31cbe: fix `@bitCast` warningsJacob Young
2023-10-31std.builtin.Endian: make the tags lower caseAndrew Kelley
Let's take this breaking change opportunity to fix the style of this enum.
2023-10-25C backend: remove some `@as`Andrew Kelley
2023-10-25cbe: update `DeclGen.decl_index` to support anon declsJacob Young
2023-10-24InternPool: remove runtime_value representationmlugg
The main goal of this commit is to remove the `runtime_value` field from `InternPool.Key` (and its associated representation), but there are a few dominos. Specifically, this mostly eliminates the "maybe runtime" concept from value resolution in Sema: so some resolution functions like `resolveMaybeUndefValAllowVariablesMaybeRuntime` are gone. This required a small change to struct/union/array initializers, to no longer use `runtime_value` if a field was a `variable` - I'm not convinced this case was even reachable, as `variable` should only ever exist as the trivial value of a global runtime `var` decl. Now, the only case in which a `Sema.resolveMaybeUndefVal`-esque function can return the `variable` key is `resolveMaybeUndefValAllowVariables`, which is directly called from `Sema.resolveInstValueAllowVariables` (previously `Sema.resolveInstValue`), which is only used for resolving the value of a Decl from `Module.semaDecl`. While changing these functions, I also slightly reordered and restructured some of them, and updated their doc comments.
2023-10-23Merge pull request #17651 from Vexu/error-limitAndrew Kelley
Make distinct error limit configurable (attempt #2)
2023-10-22remove uses of non-configurable `err_int`Veikka Tuominen
2023-10-21InternPool: store alignment of anon declsAndrew Kelley
Commit 5393e56500d499753dbc39704c0161b47d1e4d5c has a flaw pointed out by @mlugg: the `ty` field of pointer values changes when comptime values are pointer-casted. This commit introduces a new encoding which additionally stores the "original pointer type" which is used to store the alignment of the anonymous decl, and potentially other information in the future such as section and pointer address space. However, this new encoding is only used when the original pointer type differs from the casted pointer type in a meaningful way. I was able to make the LLVM backend and the C backend lower anonymous decls with the appropriate alignment, however I will need some help figuring out how to do this for the backends that lower anonymous decls via src/codegen.zig and the wasm backend.
2023-10-08cbe: fix crash on errorJacob Young
This hashmap value used to be assigned much later during `flushModule`, which never happens if an error is returned by the backend, and attempting to the undefined values would cause a crash.
2023-10-03C backend: render anon declsAndrew Kelley
Introduce the new mechanism needed to render anonymous decls to C code that the frontend is now using. The current strategy is to collect the set of used anonymous decls into one ArrayHashMap for the entire compilation, and then render them during flush(). In the future this may need to be adjusted for incremental compilation purposes, so that removing a Decl from decl_table means that newly unused anonymous decls are no longer rendered. However, let's do one thing at a time. The only goal of this branch is to stop using Module.Decl objects for unnamed constants.
2023-10-03C backend: start handling anonymous declsAndrew Kelley
Start keeping track of dependencies on anon decls for dependency ordering during flush() Currently this causes use of undefined symbols because these dependencies need to get rendered into the output.
2023-10-03compiler: start handling anonymous decls differentlyAndrew Kelley
Instead of explicitly creating a `Module.Decl` object for each anonymous declaration, each `InternPool.Index` value is implicitly understood to be an anonymous declaration when encountered by backend codegen. The memory management strategy for these anonymous decls then becomes to garbage collect them along with standard InternPool garbage. In the interest of a smooth transition, this commit only implements this new scheme for string literals and leaves all the previous mechanisms in place.
2023-10-03codegen: fix field offsets in packed structsXavier Bouchoux
* add nested packed struct/union behavior tests * use ptr_info.packed_offset rather than trying to duplicate the logic from Sema.structFieldPtrByIndex() * use the container_ptr_info.packed_offset to account for non-aligned nested structs. * dedup type.packedStructFieldBitOffset() and module.structPackedFieldBitOffset()
2023-09-29C backend: remove ?*Decl from DeclGenAndrew Kelley
Another simplification. DeclGen already has `decl_index` which can be used to retrieve the `*Decl` if needed.
2023-09-27Rename `@fabs` to `@abs` and accept integersantlilja
Replaces the @fabs builtin with a new @abs builtins which accepts floats, signed integers and vectors of said types.
2023-09-27C backend: flatten out some of the long-lived stateAndrew Kelley
When the compiler's state lives through multiple Compilation.update() calls, the C backend stores the rendered C source code for each decl code body and forward declarations. With this commit, the state is still stored, but it is managed in one big array list in link/C.zig rather than many array lists, one for each decl. This means simpler serialization and deserialization.
2023-09-24cbe: support more symbol attributesMichael Dusan
implement codegen for: - decl weak linkage - decl aliases - fn decl weak linkage windows msvc: - `__declspec(selectany)` is not supported for functions - skip weak linkage for functions closes #17050
2023-09-21compiler: fix structFieldName crash for tuplesAndrew Kelley
When struct types have no field names, the names are implicitly understood to be strings corresponding to the field indexes in declaration order. It used to be the case that a NullTerminatedString would be stored for each field in this case, however, now, callers must handle the possibility that there are no names stored at all. This commit introduces `legacyStructFieldName`, a function to fake the previous behavior. Probably something better could be done by reworking all the callsites of this function.
2023-09-21fix regressions from this branchAndrew Kelley
2023-09-21compiler: move struct types into InternPool properAndrew Kelley
Structs were previously using `SegmentedList` to be given indexes, but were not actually backed by the InternPool arrays. After this, the only remaining uses of `SegmentedList` in the compiler are `Module.Decl` and `Module.Namespace`. Once those last two are migrated to become backed by InternPool arrays as well, we can introduce state serialization via writing these arrays to disk all at once. Unfortunately there are a lot of source code locations that touch the struct type API, so this commit is still work-in-progress. Once I get it compiling and passing the test suite, I can provide some interesting data points such as how it affected the InternPool memory size and performance comparison against master branch. I also couldn't resist migrating over a bunch of alignment API over to use the log2 Alignment type rather than a mismash of u32 and u64 byte units with 0 meaning something implicitly different and special at every location. Turns out you can do all the math you need directly on the log2 representation of alignments.
2023-09-12InternPool: prevent anon struct UAF bugs with type safetyAndrew Kelley
Instead of using actual slices for InternPool.Key.AnonStructType, this commit changes to use Slice types instead, which store a long-lived index rather than a pointer. This is a follow-up to 7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.
2023-08-28llvm/cbe: support slice in `@prefetch`Jacob Young
Closes #16967
2023-08-22compiler: move unions into InternPoolAndrew Kelley
There are a couple concepts here worth understanding: Key.UnionType - This type is available *before* resolving the union's fields. The enum tag type, number of fields, and field names, field types, and field alignments are not available with this. InternPool.UnionType - This one can be obtained from the above type with `InternPool.loadUnionType` which asserts that the union's enum tag type has been resolved. This one has all the information available. Additionally: * ZIR: Turn an unused bit into `any_aligned_fields` flag to help semantic analysis know whether a union has explicit alignment on any fields (usually not). * Sema: delete `resolveTypeRequiresComptime` which had the same type signature and near-duplicate logic to `typeRequiresComptime`. - Make opaque types not report comptime-only (this was inconsistent between the two implementations of this function). * Implement accepted proposal #12556 which is a breaking change.
2023-08-20cbe: elide block result allocation for 0-bit typesmlugg
This logic already existed for the void type, but is also necessary for other 0-bit types. Without it, we try to alloc a local for a 0-bit type which gets translated to a local of type `void` which C doesn't like.
2023-08-18Make NaNs quiet by default and other NaN tidy-up (#16826)Lewis Gaul
* Generalise NaN handling and make std.math.nan() give quiet NaNs * Address uses of std.math.qnan_* and std.math.nan_* consts * Comment out failing test due to issues with signalling NaN * Fix issue in c_builtins.zig where we need qnan_u32
2023-08-05cbe: don't emit traps in naked functionsJacob Young
Closes #16680
2023-07-31std: finish cleanup up asmJacob Young
This also required implementing the necessary syntax in the x86_64 backend.
2023-07-31std: cleanup asm usageJacob Young
After fixing some issues with inline assembly in the C backend, the std cleanups have the side effect of making these functions compatible with the backend, allowing it to be used on linux without linking libc.
2023-07-29codegen: fix access to byte-aligned nested packed struct elemsXavier Bouchoux
When acessing a packed struct member via a byte aligned ptr (from the optimisation in Sema.structFieldPtrByIndex()) the codegen must apply the parent ptr packed_offset in addition to the field offset itself. resolves https://github.com/ziglang/zig/issues/16609
2023-07-19cbe: fix bug where empty enum would be generatednotcancername
fix a bug where an invalid empty enum would be emitted into the C source file if the global error set was empty.
2023-07-18compiler: work around slightly different generics semanticsAndrew Kelley
Both of these cases are interesting, were not covered by behavior tests, and should be inspected carefully with regards to the language specification.
2023-07-18rework generic function callsAndrew Kelley
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-18cbe: fix pointers to aliases of extern valuesJacob Young
2023-07-04bootstrap: support aarch64 in 32-bit modeJacob Young
* `CMakeLists.txt`: support the weird `uname -m` output. * `CMakeLists.txt`: detect and use the C compiler's default arm mode. * cbe: support gcc with both `f128` and `u128` emulated. * std.os.linux.thumb: fix incorrectly passed asm inputs.
2023-06-27Air: store interned values in Air.Inst.Refmlugg
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-25compiler: start moving safety-checks into backendsAndrew Kelley
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-24Merge pull request #16188 from kcbanner/fix_cbe_airErrUnionPayloadPtrSetAndrew Kelley
cbe: fix crash caused by calling `mod.intValue` on `type_inferred_error_set`
2023-06-24cbe: codegen int_from_ptr of slice correctlymlugg
CBE was translating to access the `len` field rather than `ptr`. Air.zig specifies that this operation is valid on a slice.
2023-06-24all: migrate code to new cast builtin syntaxmlugg
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-24cbe: fix another instance of calling `intValue` with an error typeJacob Young
2023-06-24cbe: fix crash caused by calling `mod.intValue` on `type_inferred_error_set`kcbanner