aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm
AgeCommit message (Collapse)Author
2021-11-16stage2: equality compare optional with non-optionalAndrew Kelley
2021-10-25Merge pull request #9874 from leecannon/frame_pointerAndrew Kelley
Make omiting frame pointer independent of build mode
2021-10-21stage2: more division supportAndrew Kelley
AIR: * div is renamed to div_trunc. * Add div_float, div_floor, div_exact. - Implemented in Sema and LLVM codegen. C backend has a stub. Improvements to std.math.big.Int: * Add `eqZero` function to `Mutable`. * Fix incorrect results for `divFloor`. Compiler-rt: * Add muloti4 to the stage2 section.
2021-10-20stage2: implement slicingAndrew Kelley
* New AIR instruction: slice, which constructs a slice out of a pointer and a length. * AstGen: use `coerced_ty` for start and end expressions, use `none` for the sentinel, and don't try to load the result of the slice operation because it returns a by-value result. * Sema: pointer arithmetic is extracted into analyzePointerArithmetic and it is used by the implementation of slice. - Also I implemented comptime pointer addition. * Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them inside the slice semantic analysis. - The approach in stage2 is much cleaner than stage1 because it uses more granular analysis calls for obtaining the slice pointer, doing arithmetic on it, and checking if the length is comptime-known. * Sema: use the slice Value Tag for slices when doing coercion from pointer-to-array. * LLVM backend: detect when emitting a GEP instruction into a pointer-to-array and add the extra index that is required. * Type: ptrAlignment for c_void returns 0. * Implement Value.hash and Value.eql for slices. * Remove accidentally duplicated behavior test.
2021-10-20stage2: LLVM backend: implement switch_brAndrew Kelley
2021-10-17stage2: vector constantsRobin Voetter
2021-10-17stage2: array->vector coercionRobin Voetter
2021-10-16stage2 - add llvm bindings to create attributes with string valuesLee Cannon
2021-10-15stage2: make hasCodeGenBits() always true for pointersAndrew Kelley
* LLVM backend: The `alloc` AIR instruction as well as pointer constants which point to a 0-bit element type now call a common codepath to produce a `*const llvm.Value` which is a non-zero pointer with a bogus-but-properly-aligned address. * LLVM backend: improve the lowering of optional types. * Type: `hasCodeGenBits()` now returns `true` for pointers even when it returns `false` for their element types. Effectively, #6706 is now implemented in stage2 but not stage1.
2021-10-14stage2: implement `@minimum` and `@maximum`, including vectorsAndrew Kelley
* std.os: take advantage of `@minimum`. It's probably time to deprecate `std.min` and `std.max`. * New AIR instructions: min and max * Introduce SIMD vector support to stage2 * Add `@Type` support for vectors * Sema: add `checkSimdBinOp` which can be re-used for other arithmatic operators that want to support vectors. * Implement coercion from vectors to arrays. - In backends this is handled with bitcast for vector to array, however maybe we want to reduce the amount of branching by introducing an explicit AIR instruction for it in the future. * LLVM backend: implement lowering vector types * Sema: Implement `slice.ptr` at comptime * Value: improve `numberMin` and `numberMax` to support floats in addition to integers, and make them behave properly in the presence of NaN.
2021-10-14stage2: improved union supportAndrew Kelley
* `Module.Union.getFullyQualifiedName` returns a sentinel-terminated slice so that backends that need null-termination do not need an additional copy. * Module.Union: implement a `getLayout` function which returns information about ABI size and alignment so that the LLVM backend can properly lower union types into llvm types. * Sema: `resolveType` now returns `error.GenericPoison` rather than a Type with tag `generic_poison`. Callsites that want to allow that need to bypass this higher-level function. * Sema: implement coercion of enums and enum literals to unions. * Sema: fix comptime mutation of pointers to unions * LLVM backend: fully implement proper lowering of union types and values according to the union layout, and update the handling of AIR instructions that deal with unions to support union layouts. * LLVM backend: handle `decl_ref_mut` - Maybe this should be unreachable since comptime vars should be changed to be non-mutable when they go out of scope, but it's harmless for the LLVM backend to support lowering the value. * Type: fix `requiresComptime` for optionals, pointers, and some other types. This function is still wrong for structs, unions, and enums.
2021-10-12stage2: fix comptime stores and sentinel-terminated arraysAndrew Kelley
* ZIR: the `array_type_sentinel` now has a source node attached to it for proper error reporting. * Refactor: move `Module.arrayType` to `Type.array` * Value: the `bytes` and `array` tags now include the sentinel, if the type has one. This simplifies comptime evaluation logic. * Sema: fix `zirStructInitEmpty` to properly handle when the type is void or a sentinel-terminated array. This handles the syntax `void{}` and `[0:X]T{}`. * Sema: fix the logic for reporting "cannot store runtime value in compile time variable" as well as for emitting a runtime store when a pointer value is comptime known but it is a global variable. * Sema: implement elemVal for double pointer to array. This can happen with this code for example: `var a: *[1]u8 = undefined; _ = a[0];` * Sema: Rework the `storePtrVal` function to properly handle nested structs and arrays. - Also it now handles comptime stores through a bitcasted pointer. When the pointer element type and the type according to the Decl don't match, the element value is bitcasted before storage.
2021-10-11stage2: support nested structs and arrays and sretAndrew Kelley
* Add AIR instructions: ret_ptr, ret_load - This allows Sema to be blissfully unaware of the backend's decision to implement by-val/by-ref semantics for struct/union/array types. Backends can lower these simply as alloc, load, ret instructions, or they can take advantage of them to use a result pointer. * Add AIR instruction: array_elem_val - Allows for better codegen for `Sema.elemVal`. * Implement calculation of ABI alignment and ABI size for unions. * Before appending the following AIR instructions to a block, resolveTypeLayout is called on the type: - call - return type - ret - return type - store_ptr - elem type * Sema: fix memory leak in `zirArrayInit` and other cleanups to this function. * x86_64: implement the full x86_64 C ABI according to the spec * Type: implement `intInfo` for error sets. * Type: implement `intTagType` for tagged unions. The Zig type tag `Fn` is now used exclusively for function bodies. Function pointers are modeled as `*const T` where `T` is a `Fn` type. * The `call` AIR instruction now allows a function pointer operand as well as a function operand. * Sema now has a coercion from function body to function pointer. * Function type syntax, e.g. `fn()void`, now returns zig tag type of Pointer with child Fn, rather than Fn directly. - I think this should probably be reverted. Will discuss the lang specs before doing this. Idea being that function pointers would need to be specified as `*const fn()void` rather than `fn() void`. LLVM backend: * Enable calling the panic handler (previously this just emitted `@breakpoint()` since the backend could not handle the panic function). * Implement sret * Introduce `isByRef` and implement it for structs and arrays. Types that are `isByRef` are now passed as pointers to functions, and e.g. `elem_val` will return a pointer instead of doing a load. * Move the function type creating code from `resolveLlvmFunction` to `llvmType` where it belongs; now there is only 1 instance of this logic instead of two. * Add the `nonnull` attribute to non-optional pointer parameters. * Fix `resolveGlobalDecl` not using fully-qualified names and not using the `decl_map`. * Implement `genTypedValue` for pointer-like optionals. * Fix memory leak when lowering `block` instruction and OOM occurs. * Implement volatile checks where relevant.
2021-10-05stage2: LLVM backend: miscompilation fixesAndrew Kelley
* work around a stage1 miscompilation leading to the wrong integer comparison predicate being emitted. * fix the bug of not annotating callsites with the calling convention of the callee, leading to undefined behavior. * add the `nobuiltin` attribute when building freestanding libc or compiler_rt libraries to prevent e.g. memcpy from being "optimized" into a call to itself. * compiler-rt: change a call to be comptime to make the generated LLVM IR simpler and easier to study. I still can't enable the widening tests due to the compiler-rt compare function being miscompiled in some not-yet-diagnosed way.
2021-09-30Merge remote-tracking branch 'origin/master' into llvm13Andrew Kelley
2021-09-29stage2: LLVM backend: properly set module target dataAndrew Kelley
Also fix tripping LLVM assert having to do with 0 bit integers. stage2 behavior tests now run clean in a debug build of llvm 12.
2021-09-29stage2: LLVM backend: implement struct type fwd declsAndrew Kelley
Makes struct types able to refer to themselves.
2021-09-28stage2: implement `@clz` and `@ctz`Andrew Kelley
Also improve the LLVM backend to support lowering bigints to LLVM values. Moves over a bunch of math.zig test cases to the "passing for stage2" section.
2021-09-28saturating arithmetic modificationsAndrew Kelley
* Remove the builtins `@addWithSaturation`, `@subWithSaturation`, `@mulWithSaturation`, and `@shlWithSaturation` now that we have first-class syntax for saturating arithmetic. * langref: Clarify the behavior of `@shlExact`. * Ast: rename `bit_shift_left` to `shl` and `bit_shift_right` to `shr` for consistency. * Air: rename to include underscore separator with consistency with the rest of the ops. * Air: add shl_exact instruction * Use non-extended tags for saturating arithmetic, to keep it simple so that all the arithmetic operations can be done the same way. - Sema: unify analyzeArithmetic with analyzeSatArithmetic - implement comptime `+|`, `-|`, and `*|` - allow float operands to saturating arithmetic * `<<|` allows any integer type for the RHS. * C backend: fix rebase conflicts * LLVM backend: reduce the amount of branching for arithmetic ops * zig.h: fix magic number not matching actual size of C integer types
2021-09-28sat-arithmetic: add operator supportTravis Staloch
- adds initial support for the operators +|, -|, *|, <<|, +|=, -|=, *|=, <<|= - uses operators in addition to builtins in behavior test - adds binOpExt() and assignBinOpExt() to AstGen.zig. these need to be audited
2021-09-24stage2: implement `@memset` and `@memcpy` builtinsAndrew Kelley
2021-09-23stage2: LLVM backend: improved naming and exportingAndrew Kelley
Introduce an explicit decl_map for *Decl to LLVMValueRef. Doc comment reproduced here: Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, but that has some downsides: * we have to compute the fully qualified name every time we want to do the lookup * for externally linked functions, the name is not fully qualified, but when a Decl goes from exported to not exported and vice-versa, we would use the wrong version of the name and incorrectly get function not found in the llvm module. * it works for functions not all globals. Therefore, this table keeps track of the mapping. Non-exported functions now use fully-qualified symbol names. `Module.Decl.getFullyQualifiedName` now returns a sentinel-terminated slice which is useful to pass to LLVMAddFunction. Instead of using aliases for all external symbols, now the LLVM backend takes advantage of LLVMSetValueName to rename functions that become exported. Aliases are still used for the second and remaining exports. freeDecl is now handled properly in the LLVM backend, deleting the LLVMValueRef corresponding to the Decl being deleted. The linker backends for ELF, COFF, Mach-O, and Wasm had to be updated to forward the freeDecl call to the LLVM backend.
2021-09-23stage2: prepare for building freestanding libcAndrew Kelley
Extracts lib/std/special/c_stage1.zig from lib/std/special/c.zig. When the self-hosted compiler is further along, all the logic from c_stage1.zig will be migrated back c.zig and then c_stage1.zig will be deleted. Until then we have a simpler implementation of c.zig that only uses features already implemented in self-hosted. So far it only contains memcpy and memset, with slightly different (arguably more correct!) implementations that are compatible with self-hosted. Additionally, this commit improves the LLVM backend: * use the more efficient and convenient fnInfo() when lowering function type info. * fix incremental compilation not deleting all basic blocks of a function. * hook up calling conventions * hook up the following function attributes: - noredzone, nounwind, uwtable, minsize, optsize, sanitize_thread
2021-09-21stage2: progress towards ability to compile compiler-rtAndrew Kelley
* prepare compiler-rt to support being compiled by stage2 - put in a few minor workarounds that will be removed later, such as using `builtin.stage2_arch` rather than `builtin.cpu.arch`. - only try to export a few symbols for now - we'll move more symbols over to the "working in stage2" section as they become functional and gain test coverage. - use `inline fn` at function declarations rather than `@call` with an always_inline modifier at the callsites, to avoid depending on the anonymous array literal syntax language feature (for now). * AIR: replace floatcast instruction with fptrunc and fpext for shortening and widening floating point values, respectively. * Introduce a new ZIR instruction, `export_value`, which implements `@export` for the case when the thing to be exported is a local comptime value that points to a function. - AstGen: fix `@export` not properly reporting ambiguous decl references. * Sema: handle ExportOptions linkage. The value is now available to all backends. - Implement setting global linkage as appropriate in the LLVM backend. I did not yet inspect the LLVM IR, so this still needs to be audited. There is already a pending task to make sure the alias stuff is working as intended, and this is related. - Sema almost handles section, just a tiny bit more code is needed in `resolveExportOptions`. * Sema: implement float widening and shortening for both `@floatCast` and float coercion. - Implement the LLVM backend code for this as well.
2021-09-20Merge branch 'address-space' of Snektron/zig into Snektron-address-spaceAndrew Kelley
There were two things to resolve here: * Snektron's branch edited Zir printing, but in master branch I moved the printing code from Zir.zig to print_zir.zig. So that just had to be moved over. * In master branch I fleshed out coerceInMemory a bit more, which caused one of Snektron's test cases to fail, so I had to add addrspace awareness to that. Once I did that the tests passed again.
2021-09-20stage2: implement comptime `@atomicRmw`Andrew Kelley
* introduce float_to_int and int_to_float AIR instructionts and implement for the LLVM backend and C backend. * Sema: implement `zirIntToFloat`. * Sema: implement `@atomicRmw` comptime evaluation - introduce `storePtrVal` for when one needs to store a Value to a pointer which is a Value, and assert it happens at comptime. * Value: introduce new functionality: - intToFloat - numberAddWrap - numberSubWrap - numberMax - numberMin - bitwiseAnd - bitwiseNand (not implemented yet) - bitwiseOr - bitwiseXor * Sema: hook up `zirBitwise` to the new Value bitwise implementations * Type: rename `isFloat` to `isRuntimeFloat` because it returns `false` for `comptime_float`.
2021-09-20Address Spaces: Restructure llvmAddressSpace a bitRobin Voetter
2021-09-20Address Spaces: Implement in LLVM codegenRobin Voetter
2021-09-20Address Spaces: Chaining testsRobin Voetter
2021-09-16stage2: implement `@setAlignStack` and 128-bit cmpxchgAndrew Kelley
* test runner is improved to respect `error.SkipZigTest` * start code is improved to `@setAlignStack(16)` before calling main() * the newly passing behavior test has a workaround for the fact that stage2 cannot yet call `std.Target.x86.featureSetHas()` at comptime. This is blocking on comptime closures. The workaround is that there is a new decl `@import("builtin").stage2_x86_cx16` which is a `bool`. * Implement `@setAlignStack`. This language feature should be re-evaluated at some point - I'll file an issue for it. * LLVM backend: apply/remove the cold attribute and noinline attribute where appropriate. * LLVM backend: loads and stores are properly annotated with alignment and volatile attributes. * LLVM backend: allocas are properly annotated with alignment. * Type: fix integers reporting wrong alignment for 256-bit integers and beyond. Once you get to 16 byte aligned, there is no further alignment for larger integers.
2021-09-15stage2: implement `@atomicRmw` and `@atomicLoad`Andrew Kelley
* langref: add some more "see also" links for atomics * Add the following AIR instructions - atomic_load - atomic_store_unordered - atomic_store_monotonic - atomic_store_release - atomic_store_seq_cst - atomic_rmw * Implement those AIR instructions in LLVM and C backends. * AstGen: make the `ty` result locations for `@atomicRmw`, `@atomicLoad`, and `@atomicStore` be `coerced_ty` to avoid unnecessary ZIR instructions when Sema will be doing the coercions redundantly. * Sema for `@atomicLoad` and `@atomicRmw` is done, however Sema for `@atomicStore` is not yet implemented. - comptime eval for `@atomicRmw` is not yet implemented. * Sema: flesh out `coerceInMemoryAllowed` a little bit more. It can now handle pointers.
2021-09-15Merge remote-tracking branch 'origin/master' into llvm13Andrew Kelley
Conflicts: * cmake/Findclang.cmake * cmake/Findlld.cmake * cmake/Findllvm.cmake In master branch, more search paths were added to these files with "12" in the path. In this commit I updated them to "13". * src/stage1/codegen.cpp * src/zig_llvm.cpp * src/zig_llvm.h In master branch, ZigLLVMBuildCmpXchg is improved to add `is_single_threaded`. However, the LLVM 13 C API has this already, and in the llvm13 branch, ZigLLVMBuildCmpXchg is deleted in favor of the C API. In this commit I updated stage2 to use the LLVM 13 C API rather than depending on an improved ZigLLVMBuildCmpXchg. Additionally, src/target.zig largestAtomicBits needed to be updated to include the new m68k ISA.
2021-09-15stage2: implement `@fence`Andrew Kelley
2021-09-14stage2: implement cmpxchg and improve comptime evalAndrew Kelley
* Implement Sema for `@cmpxchgWeak` and `@cmpxchgStrong`. Both runtime and comptime codepaths are implement. * Implement Codegen for LLVM backend and C backend. * Add LazySrcLoc.node_offset_builtin_call_argX 3...5 * Sema: rework comptime control flow. - `error.ComptimeReturn` is used to signal that a comptime function call has returned a result (stored in the Inlining struct). `analyzeCall` notices this and handles the result. - The ZIR instructions `break_inline`, `block_inline`, `condbr_inline` are now redundant and can be deleted. `break`, `block`, and `condbr` function equivalently inside a comptime scope. - The ZIR instructions `loop` and `repeat` also are modified to directly perform comptime control flow inside a comptime scope, skipping an unnecessary mechanism for analysis of runtime code. This makes Zig perform closer to an interpreter when evaluating comptime code. * Sema: zirRetErrValue looks at Sema.ret_fn_ty rather than sema.func for adding to the inferred error set. This fixes a bug for inlined/comptime function calls. * Implement ZIR printing for cmpxchg. * stage1: make cmpxchg respect --single-threaded - Our LLVM C++ API wrapper failed to expose this boolean flag before. * Fix AIR printing for struct fields showing incorrect liveness data.
2021-09-13stage2: add array_to_slice AIR instructionAndrew Kelley
2021-08-31stage2: update LLVM backend to for LLVM 13Andrew Kelley
There was some new code in master branch enumerating all the targets and a new target was added so we needed to add the glue code. This commit also introduces some build options to support experimental LLVM targets.
2021-08-31Merge pull request #9655 from nektro/stage2-remAndrew Kelley
stage2: implement runtime `%` and `@rem`
2021-08-31Merge remote-tracking branch 'origin/master' into llvm13Andrew Kelley
2021-08-31stage2: only initialize the llvm backend for the target we are building (#9659)Meghan
2021-08-30stage2: implement runtime `%` and `@rem`Meghan Denny
2021-08-28Merge remote-tracking branch 'origin/master' into llvm13Andrew Kelley
Conflicts: lib/libcxx/include/__config d57c0cc3bfeff9af297279759ec2b631e6d95140 added support for DragonFlyBSD to libc++ by updating some ifdefs. This needed to be synced with llvm13.
2021-08-19stage2: implement shr and boilerplate for shlJacob G-W
This implements it in the llvm and c backends. x86_64 will have to be a little more work.
2021-08-16update src/ to LLVM 13 rc1 APIAndrew Kelley
2021-08-12stage2 llvm backend: implement const inttoptrAndrew Kelley
2021-08-07stage2: pass some pointer testsAndrew Kelley
* New AIR instructions: ptr_add, ptr_sub, ptr_elem_val, ptr_ptr_elem_val - See the doc comments for details. * Sema: implement runtime pointer arithmetic. * Sema: implement elem_val for many-pointers. * Sema: support coercion from `*[N:s]T` to `[*]T`. * Type: isIndexable handles many-pointers.
2021-08-06stage2: fix generics with non-comptime anytype parametersAndrew Kelley
The `comptime_args` field of Fn has a clarified purpose: For generic function instantiations, there is a `TypedValue` here for each parameter of the function: * Non-comptime parameters are marked with a `generic_poison` for the value. * Non-anytype parameters are marked with a `generic_poison` for the type. Sema now has a `fn_ret_ty` field. Doc comments reproduced here: > When semantic analysis needs to know the return type of the function whose body > is being analyzed, this `Type` should be used instead of going through `func`. > This will correctly handle the case of a comptime/inline function call of a > generic function which uses a type expression for the return type. > The type will be `void` in the case that `func` is `null`. Various places in Sema are modified in accordance with this guidance. Fixed `resolveMaybeUndefVal` not returning `error.GenericPoison` when Value Tag of `generic_poison` is encountered. Fixed generic function memoization incorrect equality checking. The logic now clearly deals properly with any combination of anytype and comptime parameters. Fixed not removing generic function instantiation from the table in case a compile errors in the rest of `call` semantic analysis. This required introduction of yet another adapter which I have called `GenericRemoveAdapter`. This one is nice and simple - it's the same hash function (the same precomputed hash is passed in) but the equality function checks pointers rather than doing any logic. Inline/comptime function calls coerce each argument in accordance with the function parameter type expressions. Likewise the return type expression is evaluated and provided (see `fn_ret_ty` above). There's a new compile error "unable to monomorphize function". It's pretty unhelpful and will need to get improved in the future. It happens when a type expression in a generic function did not end up getting resolved at a callsite. This can happen, for example, if a runtime parameter is attempted to be used where it needed to be comptime known: ```zig fn foo(x: anytype) [x]u8 { _ = x; } ``` In this example, even if we pass a number such as `10` for `x`, it is not marked `comptime`, so `x` will have a runtime known value, making the return type unable to resolve. In the LLVM backend I implement cmp instructions for float types to pass some behavior tests that used floats.
2021-08-05stage2: return type expressions of generic functionsAndrew Kelley
* ZIR encoding for function instructions have a body for the return type. This lets Sema for generic functions do the same thing it does for parameters, handling `error.GenericPoison` in the evaluation of the return type by marking the function as generic. * Sema: fix missing block around the new Decl arena finalization. This led to a memory corruption. * Added some floating point support to the LLVM backend but didn't get far enough to pass any new tests.
2021-08-01stage2: implement `@truncate`Andrew Kelley
2021-07-29stage2: more principled approach to comptime referencesAndrew Kelley
* AIR no longer has a `variables` array. Instead of the `varptr` instruction, Sema emits a constant with a `decl_ref`. * AIR no longer has a `ref` instruction. There is no longer any instruction that takes a value and returns a pointer to it. If this is desired, Sema must either create an anynomous Decl and return a constant `decl_ref`, or in the case of a runtime value, emit an `alloc` instruction, `store` the value to it, and then return the `alloc`. * The `ref_val` Value Tag is eliminated. `decl_ref` should be used instead. Also added is `eu_payload_ptr` which points to the payload of an error union, given an error union pointer. In general, Sema should avoid calling `analyzeRef` if it can be helped. For example in the case of field_val and elem_val, there should never be a reason to create a temporary (alloc or decl). Recent previous commits made progress along that front. There is a new abstraction in Sema, which looks like this: var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); // here 'anon_decl.arena()` may be used const decl = try anon_decl.finish(ty, val); // decl is typically now used with `decl_ref`. This pattern is used to upgrade `ref_val` usages to `decl_ref` usages. Additional improvements: * Sema: fix source location resolution for calling convention expression. * Sema: properly report "unable to resolve comptime value" for loads of global variables. There is now a set of functions which can be called if the callee wants to obtain the Value even if the tag is `variable` (indicating comptime-known address but runtime-known value). * Sema: `coerce` resolves builtin types before checking equality. * Sema: fix `u1_type` missing from `addType`, making this type have a slightly more efficient representation in AIR. * LLVM backend: fix `genTypedValue` for tags `decl_ref` and `variable` to properly do an LLVMConstBitCast. * Remove unused parameter from `Value.toEnum`. After this commit, some test cases are no longer passing. This is due to the more principled approach to comptime references causing more anonymous decls to get sent to the linker for codegen. However, in all these cases the decls are not actually referenced by the runtime machine code. A future commit in this branch will implement garbage collection of decls so that unused decls do not get sent to the linker for codegen. This will make the tests go back to passing.
2021-07-27llvm backend: LLVMGetNamedGlobalAlias requires a null terminated stringAndrew Kelley