aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
AgeCommit message (Collapse)Author
2022-03-14CBE: split {clz,ctz,mod,popCount,byteSwap,bitReverse} by typeDaniele Cocca
This also surfaces the fact that clz, ctz and popCount didn't actually support 128 bit integers, despite what was claimed by 226fcd7c709ec664c5d883042cf7beb3026f66cb. This was partially hidden by the fact that the test code for popCount only exercised 128 bit integers in a comptime context. This commit duplicates that test case for runtime ints too.
2022-03-14stage2: rework Value storage of structs and arraysAndrew Kelley
Now they both use `Value.Tag.aggregate`. Additionally the LLVM backend now has implemented lowering of tuple values.
2022-03-14LLVM: fix int_to_float signedness detectionAndrew Kelley
It was checking if the result (float) type was a signed int rather than checking the operand (integer) type.
2022-03-14LLVM: fix debug info for local varsAndrew Kelley
Previously we incorrectly used the pointer type as the debug info type.
2022-03-14Remove signed_type from zig_{clz,ctz,popcount}Daniele Cocca
This parameter is only currently needed by zig_byte_swap() and zig_bit_reverse(). This commit adds an option to airBuiltinCall() to allow emitting the signedness information only when needed, removing this unused parameter from the other builtins.
2022-03-14Review suggestion: use hasRuntimeBitsIgnoreComptime()Daniele Cocca
This should cover not only integers, as done in 87744a7ea9a2449764a110da4210d7750e3938ee, but also void, enums with a single field, etc... Co-authored-by: Andrew Kelley <andrew@ziglang.org>
2022-03-13CBE: implement popCount, byteSwap, bitReverse for ints <= 128 bitsDaniele Cocca
This folds the airCountZeroes() code from 226fcd7c709ec664c5d883042cf7beb3026f66cb back into airBuiltinCall(), since most of these builtins happen to require the same arguments and can be unified under a common function signature.
2022-03-13CBE: skip 0 bit integers from function signaturesDaniele Cocca
This was already done for void types, and needs to be done for 0 bit integer types as well to align the rendered function signatures with the effective size of extra.data.args_len as seen by airCall().
2022-03-13stage2: add debug info for locals in the LLVM backendAndrew Kelley
Adds 2 new AIR instructions: * dbg_var_ptr * dbg_var_val Sema no longer emits dbg_stmt AIR instructions when strip=true. LLVM backend: fixed lowerPtrToVoid when calling ptrAlignment on the element type is problematic. LLVM backend: fixed alloca instructions improperly getting debug location annotated, causing chaotic debug info behavior. zig_llvm.cpp: fixed incorrect bindings for a function that should use unsigned integers for line and column. A bunch of C test cases regressed because the new dbg_var AIR instructions caused their operands to be alive, exposing latent bugs. Mostly it's just a problem that the C backend lowers mutable and const slices to the same C type, so we need to represent that in the C backend instead of printing two duplicate typedefs.
2022-03-12stage2 llvm: do not use getIntrinsic for airFrameAddressVeikka Tuominen
getIntrinsic gets the return type wrong so we have to add the function manually
2022-03-11LLVM: use hasRuntimeBitsIgnoreComptime instead of hasRuntimeBitsAndrew Kelley
LLVM codegen doesn't care whether types are comptime or not. Comptime types aren't supposed to make it to codegen anyway.
2022-03-11LLVM: fix debug info for pointers to voidAndrew Kelley
2022-03-11CBE: implement clz, ctz for ints <= 128 bitsDaniele Cocca
2022-03-11stage2: implement `@shuffle` at runtimeVeikka Tuominen
2022-03-11stage2: passing threadlocal tests for x86_64-linuxAndrew Kelley
* use the real start code for LLVM backend with x86_64-linux - there is still a check for zig_backend after initializing the TLS area to skip some stuff. * introduce new AIR instructions and implement them for the LLVM backend. They are the same as `call` except with a modifier. - call_always_tail - call_never_tail - call_never_inline * LLVM backend calls hasRuntimeBitsIgnoringComptime in more places to avoid unnecessarily depending on comptimeOnly being resolved for some types. * LLVM backend: remove duplicate code for setting linkage and value name. The canonical place for this is in `updateDeclExports`. * LLVM backend: do some assembly template massaging to make `%%` rendered as `%`. More hacks will be needed to make inline assembly catch up with stage1.
2022-03-10stage2 llvm: implement lowerParentPtr for int_{u,i}64Veikka Tuominen
2022-03-09Sema: implement pointer to tuple to pointer to array coercionAndrew Kelley
This involved an LLVM backend fix for the aggregate_init instruction.
2022-03-08LLVM: fix memory leak of debug type namesAndrew Kelley
This required adjusting `Type.nameAlloc` to be used with a general-purpose allocator and added `Type.nameAllocArena` for the arena use case (avoids allocation sometimes).
2022-03-08LLVM: add debug info for opaque, vector, and tuplesAndrew Kelley
Also fix UAF of Type memory in the di_type_map.
2022-03-08LLVM: no longer store args into alloca instructionsAndrew Kelley
Previously, we did this so that we could insert a debug variable declaration intrinsic on the alloca. But there is a dbg.value intrinsic for declaring variables that are values.
2022-03-08LLVM: add debug info for parametersAndrew Kelley
2022-03-08LLVM: fix not handling dbg_stmt relative lineAndrew Kelley
Also make `namespaceToDebugScope` behave correctly for file-level structs. Instead of being inside their own scope, they use the file scope.
2022-03-08LLVM: add debug type lowering for ptr, slice, opaque, optionalAndrew Kelley
also fix issue with memoization and recursiveness.
2022-03-08LLVM: memoize debug types and add enum debug typesAndrew Kelley
2022-03-08LLVM: add DISubprogram and DIType lowering; handle dbg_stmtAndrew Kelley
2022-03-08LLVM: add compile unit to debug infoAndrew Kelley
This commit also adds a bunch of bindings for debug info.
2022-03-06stage2: rework `@mulAdd`Andrew Kelley
* mul_add AIR instruction: use `pl_op` instead of `ty_pl`. The type is always the same as the operand; no need to waste bytes redundantly storing the type. * AstGen: use coerced_ty for all the operands except for one which we use to communicate the type. * Sema: use the correct source location for requireRuntimeBlock in handling of `@mulAdd`. * native backends: handle liveness even for the functions that are TODO. * C backend: implement `@mulAdd`. It lowers to libc calls. * LLVM backend: make `@mulAdd` handle all float types. - improved fptrunc and fpext to handle f80 with compiler-rt calls. * Value.mulAdd: handle all float types and use the `@mulAdd` builtin. * behavior tests: revert the changes to testing `@mulAdd`. These changes broke the test coverage, making it only tested at compile-time. Improved f80 support: * std.math.fma handles f80 * move fma functions from freestanding libc to compiler-rt - add __fmax and fmal - make __fmax and fmaq only exported when they don't alias fmal. - make their linkage weak just like the rest of compiler-rt symbols. * removed `longDoubleIsF128` and replaced it with `longDoubleIs` which takes a type as a parameter. The implementation is now more accurate and handles more targets. Similarly, in stage2 the function CTypes.sizeInBits is more accurate for long double for more targets.
2022-03-06stage2: implement `@mulAdd` for scalar floatsJohn Schmidt
2022-03-06stage2: Fix wasm linker for llvm backendLuuk de Gram
This fixes 2 entrypoints within the self-hosted wasm linker that would be called for the llvm backend, whereas we should simply call into the llvm backend to perform such action. i.e. not allocate a decl index when we have an llvm object, and when flushing a module, we should be calling it on llvm's object, rather than have the wasm linker perform the operation. Also, this fixes the wasm intrinsics for wasm.memory.size and wasm.memory.grow. Lastly, this commit ensures that when an extern function is being resolved, we tell LLVM how to import such function.
2022-03-03stage2: cleanups to wasm memory intrinsicsAndrew Kelley
* AIR: use pl_op instead of ty_pl for wasm_memory_size. No need to store the type because the type is always `u32`. * AstGen: use coerced_ty for `@wasmMemorySize` and `@wasmMemoryGrow` and do the coercions in Sema. * Sema: use more accurate source locations for errors. * Provide more information in the compiler error message. * Codegen: use liveness data to avoid lowering unused `@wasmMemorySize`. * LLVM backend: add implementation - I wasn't able to test it because we are hitting a linker error for `-target wasm32-wasi -fLLVM`. * C backend: use `zig_unimplemented()` instead of silently doing wrong behavior for these builtins. * behavior tests: branch only on stage2_arch for inclusion of the wasm.zig file. We would change it to `builtin.cpu.arch` but that is causing a compiler crash on some backends.
2022-03-03cbe: Implement wasm builtinsLuuk de Gram
This implements the wasm builtins by lowering to builtins that are supported by c-compilers. In this case: Clang. This also simplifies the `AIR` instruction as it now uses the payload field of `ty_pl` and `pl_op` directly to store the index argument rather than storing it inside Extra. This saves us 4 bytes per builtin call.
2022-03-03Update behavior testsLuuk de Gram
2022-03-03wasm: Implement `@wasmMemoryGrow` builtinLuuk de Gram
Similarly to the other wasm builtin, this implements the grow variation where the memory index is a comptime known value. The operand as well as the result are runtime values. This also verifies during semantic analysis the target we're building for is wasm, or else emits a compilation error. This means that other backends do not have to handle this AIR instruction, other than the wasm and LLVM backends.
2022-03-03wasm: Implement `@wasmMemorySize()` builtinLuuk de Gram
This implements the `wasmMemorySize` builtin, in Sema and the Wasm backend. The Stage2 implementation differs from stage1 in the way that `index` must be a comptime value. The stage1 variant is incorrect, as the index is part of the instruction encoding, and therefore, cannot be a runtime value.
2022-03-03stage2 llvm: Lower 0-bit field-ptr as ptr-to-voidCody Tapscott
2022-03-03LLVM: fix lowering of unions and switchesAndrew Kelley
`Module.Union.getLayout` now additionally returns a `padding` field which tells how many bytes are between the final field end offset and the ending offset of the union. This is used by the LLVM backend to explicitly insert padding. LLVM backend: lowering of unions now inserts additional padding so that LLVM's internals will agree on the ABI size to match what ABI size zig wants unions to be. This is an alternative to calling LLVMABISizeOfType and LLVMABIAlignmentOfType which end up crashing when recursive struct definitions come into play. We no longer ever call these two functions and the bindings are deleted to avoid future footgun firings. LLVM backend: lowering of unions now represents untagged unions consistently. Before it was tripping an assertion. LLVM backend: switch cases call inttoptr on the case items and condition if necessary. Prevents tripping an LLVM assertion. After this commit, we are no longer tripping over any LLVM assertions.
2022-03-02LLVM: aggregate_init supports structsAndrew Kelley
in addition to tuples
2022-03-02stage2: implement `@extern`Veikka Tuominen
2022-03-01stage2: introduce anonymous struct literalsAndrew Kelley
2022-03-01LLVM: add extra padding to structs and tuples sometimesAndrew Kelley
* Sema: resolve type fully when emitting an alloc AIR instruction to avoid tripping assertion for checking struct field alignment. * LLVM backend: keep a reference to the LLVM target data alive during lowering so that we can ask LLVM what it thinks the ABI alignment and size of LLVM types are. We need this in order to lower tuples and structs so that we can put in extra padding bytes when Zig disagrees with LLVM about the size or alignment of something. * LLVM backend: make the LLVM struct type packed that contains the most aligned union field and the padding. This prevents the struct from being too big according to LLVM. In the future, we may want to consider instead emitting unions in a "flat" manner; putting the tag, most aligned union field, and padding all in the same struct field space. * LLVM backend: make structs with 2 or fewer fields return isByRef=false. This results in more efficient codegen. This required lowering of bitcast to sometimes store the struct into an alloca, ptrcast, and then load because LLVM does not allow bitcasting structs. * enable more passing behavior tests.
2022-03-01LLVM: fix tripping assertionsAndrew Kelley
Packed structs were tripping an LLVM assertion due to calling `LLVMConstZExt` from i16 to i16. Solved by using instead `LLVMConstZExtOrBitCast`. Unions were tripping an LLVM assertion due to a typo using the union llvm type to construct an integer value rather than the tag type.
2022-03-01LLVM: fix when sret and isByRef ret_ty disagreeAndrew Kelley
This can happen functions use the C ABI.
2022-02-28stage2: fix frame_address AIR instructionAndrew Kelley
Various places were assuming different union tags. Now it is consistently a no-op instruction, just like the similar instruction ret_addr.
2022-02-28stage2: implement `@frameAddress`Veikka Tuominen
2022-02-27stage2: fix bitcast to optional ptr in llvm backend; omit safety check for ↵Veikka Tuominen
intToPtr on optional ptr
2022-02-26stage2: implement `@unionInit`Andrew Kelley
The ZIR instruction `union_init_ptr` is renamed to `union_init`. I made it always use by-value semantics for now, not taking the time to invest in result location semantics, in case we decide to change the rules for unions. This way is much simpler. There is a new AIR instruction: union_init. This is for a comptime known tag, runtime-known field value. vector_init is renamed to aggregate_init, which solves a TODO comment.
2022-02-26stage2: various fixes to get one test passingVeikka Tuominen
* resolve error sets before merging them * implement tupleFieldPtr * make ret_ptr behave like alloc with zero sized types in llvm backend
2022-02-24spirv spec: do not align packed struct fieldsVeikka Tuominen
2022-02-24stage2: implement fieldParentPtrVeikka Tuominen
2022-02-23stage2: integer-backed packed structsAndrew Kelley
This implements #10113 for the self-hosted compiler only. It removes the ability to override alignment of packed struct fields, and removes the ability to put pointers and arrays inside packed structs. After this commit, nearly all the behavior tests pass for the stage2 llvm backend that involve packed structs. I didn't implement the compile errors or compile error tests yet. I'm waiting until we have stage2 building itself and then I want to rework the compile error test harness with inspiration from Vexu's arocc test harness. At that point it should be a much nicer dev experience to work on compile errors.