aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
AgeCommit message (Collapse)Author
2021-08-04stage2 generics improvements: anytype and param type exprsAndrew Kelley
AstGen result locations now have a `coerced_ty` tag which is the same as `ty` except it assumes that Sema will do a coercion, so it does not redundantly add an `as` instruction into the ZIR code. This results in cleaner ZIR and about a 14% reduction of ZIR bytes. param and param_comptime ZIR instructions now have a block body for their type expressions. This allows Sema to skip evaluation of the block in the case that the parameter is comptime-provided. It also allows a new mechanism to function: when evaluating type expressions of generic functions, if it would depend on another parameter, it returns `error.GenericPoison` which bubbles up and then is caught by the param/param_comptime instruction and then handled. This allows parameters to be evaluated independently so that the type info for functions which have comptime or anytype parameters will still have types populated for parameters that do not depend on values of previous parameters (because evaluation of their param blocks will return successfully instead of `error.GenericPoison`). It also makes iteration over the block that contains function parameters slightly more efficient since it now only contains the param instructions. Finally, it fixes the case where a generic function type expression contains a function prototype. Formerly, this situation would cause shared state to clobber each other; now it is in a proper tree structure so that can't happen. This fix also required adding a field to Sema `comptime_args_fn_inst` to make sure that the `comptime_args` field passed into Sema is applied to the correct `func` instruction. Source location for `node_offset_asm_ret_ty` is fixed; it was pointing at the asm output name rather than the return type as intended. Generic function instantiation is fixed, notably with respect to parameter type expressions that depend on previous parameters, and with respect to types which must be always comptime-known. This involves passing all the comptime arguments at a callsite of a generic function, and allowing the generic function semantic analysis to coerce the values to the proper types (since it has access to the evaluated parameter type expressions) and then decide based on the type whether the parameter is runtime known or not. In the case of explicitly marked `comptime` parameters, there is a check at the semantic analysis of the `call` instruction. Semantic analysis of `call` instructions does type coercion on the arguments, which is needed both for generic functions and to make up for using `coerced_ty` result locations (mentioned above). Tasks left in this branch: * Implement the memoization table. * Add test coverage. * Improve error reporting and source locations for compile errors.
2021-08-01stage2: implement `@truncate`Andrew Kelley
2021-07-29stage2: garbage collect unused anon declsAndrew Kelley
After this change, the frontend and backend cooperate to keep track of which Decls are actually emitted into the machine code. When any backend sees a `decl_ref` Value, it must mark the corresponding Decl `alive` field to true. This prevents unused comptime data from spilling into the output object files. For example, if you do an `inline for` loop, previously, any intermediate value calculations would have gone into the object file. Now they are garbage collected immediately after the owner Decl has its machine code generated. In the frontend, when it is time to send a Decl to the linker, if it has not been marked "alive" then it is deleted instead. Additional improvements: * Resolve type ABI layouts after successful semantic analysis of a Decl. This is needed so that the backend has access to struct fields. * Sema: fix incorrect logic in resolveMaybeUndefVal. It should return "not comptime known" instead of a compile error for global variables. * `Value.pointerDeref` now returns `null` in the case that the pointer deref cannot happen at compile-time. This is true for global variables, for example. Another example is if a comptime known pointer has a hard coded address value. * Binary arithmetic sets the requireRuntimeBlock source location to the lhs_src or rhs_src as appropriate instead of on the operator node. * Fix LLVM codegen for slice_elem_val which had the wrong logic for when the operand was not a pointer. As noted in the comment in the implementation of deleteUnusedDecl, a future improvement will be to rework the frontend/linker interface to remove the frontend's responsibility of calling allocateDeclIndexes. I discovered some issues with the plan9 linker backend that are related to this, and worked around them for now.
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-27stage2: implement `@boolToInt`Andrew Kelley
This is the first commit in which some behavior tests are passing for both stage1 and stage2.
2021-07-27llvm backend: LLVMGetNamedGlobalAlias requires a null terminated stringAndrew Kelley
2021-07-27stage2: `zig test` now works with the LLVM backendAndrew Kelley
Frontend improvements: * When compiling in `zig test` mode, put a task on the work queue to analyze the main package root file. Normally, start code does `_ = import("root");` to make Zig analyze the user's code, however in the case of `zig test`, the root source file is the test runner. Without this change, no tests are picked up. * In the main pipeline, once semantic analysis is finished, if there are no compile errors, populate the `test_functions` Decl with the set of test functions picked up from semantic analysis. * Value: add `array` and `slice` Tags. LLVM backend improvements: * Fix incremental updates of globals. Previously the value of a global would not get replaced with a new value. * Fix LLVM type of arrays. They were incorrectly sending the ABI size as the element count. * Remove the FuncGen parameter from genTypedValue. This function is for generating global constants and there is no function available when it is being called. - The `ref_val` case is now commented out. I'd like to eliminate `ref_val` as one of the possible Value Tags. Instead it should always be done via `decl_ref`. * Implement constant value generation for slices, arrays, and structs. * Constant value generation for functions supports the `decl_ref` tag.
2021-07-26stage2: improvements towards `zig test`Andrew Kelley
* Add AIR instruction: struct_field_val - This is part of an effort to eliminate the AIR instruction `ref`. - It's implemented for C backend and LLVM backend so far. * Rename `resolvePossiblyUndefinedValue` to `resolveMaybeUndefVal` just to save some columns on long lines. * Sema: add `fieldVal` alongside `fieldPtr` (renamed from `namedFieldPtr`). This is part of an effort to eliminate the AIR instruction `ref`. The idea is to avoid unnecessary loads, stores, stack usage, and IR instructions, by paying a DRY cost. LLVM backend improvements: * internal linkage vs exported linkage is implemented, along with aliases. There is an issue with incremental updates due to missing LLVM API for deleting aliases; see the relevant comment in this commit. - `updateDeclExports` is hooked up to the LLVM backend now. * Fix usage of `Type.tag() == .noreturn` rather than calling `isNoReturn()`. * Properly mark global variables as mutable/constant. * Fix llvm type generation of function pointers * Fix codegen for calls of function pointers * Implement llvm type generation of error unions and error sets. * Implement AIR instructions: addwrap, subwrap, mul, mulwrap, div, bit_and, bool_and, bit_or, bool_or, xor, struct_field_ptr, struct_field_val, unwrap_errunion_err, add for floats, sub for floats. After this commit, `zig test` on a file with `test "example" {}` correctly generates and executes a test binary. However the `test_functions` slice is undefined and just happens to be going into the .bss section, causing the length to be 0. The next step towards `zig test` will be replacing the `test_functions` Decl Value with the set of test function pointers, before it is sent to linker/codegen.
2021-07-25stage2 llvm backend improvements working towards `zig test`Andrew Kelley
* properly set global variables to const if they are not a global variable. * implement global variable initializations. * initial implementation of llvmType() for structs and functions. * implement genTypedValue for variable tags * implement more AIR instructions: varptr, slice_ptr, slice_len, slice_elem_val, ptr_slice_elem_val, unwrap_errunion_payload, unwrap_errunion_payload_ptr, unwrap_errunion_err, unwrap_errunion_err_ptr.
2021-07-25stage2 llvm backend: implement llvmType for error union and slicesAndrew Kelley
2021-07-25stage2 llvm backend: DeclGen and DeclFn have context fieldAndrew Kelley
instead of a context() accessor method.
2021-07-25stage2 llvm backend: rename getLLVMType to llvmTypeAndrew Kelley
2021-07-24stage2 llvm backend: implement assembly and ptrtointAndrew Kelley
These AIR instructions are the next blockers for `zig test` to work for this backend. After this commit, the "hello world" x86_64 test case passes for the LLVM backend as well.
2021-07-22add -femit-llvm-bc CLI option and implement itAndrew Kelley
* Added doc comments for `std.Target.ObjectFormat` enum * `std.Target.oFileExt` is removed because it is incorrect for Plan-9 targets. Instead, use `std.Target.ObjectFormat.fileExt` and pass a CPU architecture. * Added `Compilation.Directory.joinZ` for when a null byte is desired. * Improvements to `Compilation.create` logic for computing `use_llvm` and reporting errors in contradictory flags. `-femit-llvm-ir` and `-femit-llvm-bc` will now imply `-fLLVM`. * Fix compilation when passing `.bc` files on the command line. * Improvements to the stage2 LLVM backend: - cleaned up error messages and error reporting. Properly bubble up some errors rather than dumping to stderr; others turn into panics. - properly call ZigLLVMCreateTargetMachine and ZigLLVMTargetMachineEmitToFile and implement calculation of the respective parameters (cpu features, code model, abi name, lto, tsan, etc). - LLVM module verification only runs in debug builds of the compiler - use LLVMDumpModule rather than printToString because in the case that we incorrectly pass a null pointer to LLVM it may crash during dumping the module and having it partially printed is helpful in this case. - support -femit-asm, -fno-emit-bin, -femit-llvm-ir, -femit-llvm-bc - Support LLVM backend when used with Mach-O and WASM linkers.
2021-07-20stage2: fix compile errors in LLVM backendAndrew Kelley
2021-07-20stage2: fix AIR not instruction (see prev commit)Andrew Kelley
2021-07-20stage2: update LLVM backend to new AIR memory layoutAndrew Kelley
Also fix compile errors when not using -Dskip-non-native
2021-07-20stage2: Air and Liveness are passed ephemerallyAndrew Kelley
to the link infrastructure, instead of being stored with Module.Fn. This moves towards a strategy to make more efficient use of memory by not storing Air or Liveness data in the Fn struct, but computing it on demand, immediately sending it to the backend, and then immediately freeing it. Backends which want to defer codegen until flush() such as SPIR-V must move the Air/Liveness data upon `updateFunc` being called and keep track of that data in the backend implementation itself.
2021-07-20stage2: rework AIR memory layoutAndrew Kelley
This commit changes the AIR file and the documentation of the memory layout. The actual work of modifying the surrounding code (in Sema and codegen) is not yet done.
2021-07-08initial plan9 boilerplatejacob gw
The code now compiles and fails with Plan9ObjectFormatUnimplemented
2021-06-21fix code broken from previous commitJacob G-W
2021-06-03Breaking hash map changes for 0.8.0Martin Wickham
- hash/eql functions moved into a Context object - *Context functions pass an explicit context - *Adapted functions pass specialized keys and contexts - new getPtr() function returns a pointer to value - remove functions renamed to fetchRemove - new remove functions return bool - removeAssertDiscard deleted, use assert(remove(...)) instead - Keys and values are stored in separate arrays - Entry is now {*K, *V}, the new KV is {K, V} - BufSet/BufMap functions renamed to match other set/map types - fixed iterating-while-modifying bug in src/link/C.zig
2021-05-22stage2: rename ir.zig to air.zigAndrew Kelley
We've settled on the nomenclature for the artifacts the compiler pipeline produces: 1. Tokens 2. AST (Abstract Syntax Tree) 3. ZIR (Zig Intermediate Representation) 4. AIR (Analyzed Intermediate Representation) 5. Machine Code Renaming `ir` identifiers to `air` will come with the inevitable air-memory-layout branch that I plan to start after the 0.8.0 release.
2021-05-13AstGen: fix elision of store_to_block_ptr for condbrAndrew Kelley
2021-04-28stage2: semaDecl properly analyzes the decl blockAndrew Kelley
Also flattened out Decl TypedValue fields into ty, val, has_tv and add relevant fields to Decl for alignment and link section.
2021-04-11Merge remote-tracking branch 'origin/master' into llvm12Michael Dusan
2021-04-04LLVM sub-arch triple: remove TODO commentAndrew Kelley
See #6542 for more details. Upon investigation, this change is not needed.
2021-04-02Merge remote-tracking branch 'origin/master' into llvm12Andrew Kelley
2021-03-28Merge remote-tracking branch 'origin/master' into llvm12Andrew Kelley
2021-03-23stage2: handle void value in genRet in LLVM backendTimon Kruiper
2021-03-23stage2: rename fail to todo in LLVM backendTimon Kruiper
This way we don't have to pass src to every function and we can simply use the first node as the lazy source location for all the todo errors.
2021-03-20stage2: restructure LLVM backendTimon Kruiper
The LLVM backend is now structured into 3 different structs, namely Object, DeclGen and FuncGen. Object represents an object that is generated by the LLVM backend. DeclGen is responsible for generating a decl and FuncGen is responsible for generating llvm instructions from tzir in a function.
2021-03-19llvm backend: use new srclocjacob gw
this allows to compile with ninja
2021-03-16stage2 llvm bindings: use correct type for LLVMBool for ABI compatTadeo Kondrak
2021-03-04Merge remote-tracking branch 'origin/master' into llvm12Andrew Kelley
Syncing with master branch because I want to re-run update_clang_options.zig in the llvm12 branch.
2021-03-02stage2: add support for optionals in the LLVM backendTimon Kruiper
We can now codegen optionals! This includes the following instructions: - is_null - is_null_ptr - is_non_null - is_non_null_ptr - optional_payload - optional_payload_ptr - br_void Also includes a test for optionals.
2021-02-27std.Target.Abi: add gnuilp32Michael Dusan
2021-02-27std.Target: add powerpcleAndrew Kelley
2021-02-25Merge remote-tracking branch 'origin/master' into llvm12Andrew Kelley
Conflicts: * src/clang.zig * src/llvm.zig - this file got moved to src/llvm/bindings.zig in master branch so I had to put the new LLVM arch/os enum tags into it. * lib/std/target.zig, src/stage1/target.cpp - haiku had an inconsistency with its default target ABI, gnu vs eabi. In this commit we make it gnu in both places to match the latest changes by @hoanga. * src/translate_c.zig
2021-01-19SPIR-V: Add glsl450 and vulkan spir-v operating system definitionsRobin Voetter
2021-01-16stage2: implement error notes and regress -femit-zirAndrew Kelley
* Implement error notes - note: other symbol exported here - note: previous else prong is here - note: previous '_' prong is here * Add Compilation.CObject.ErrorMsg. This object properly converts to AllErrors.Message when the time comes. * Add Compilation.CObject.failure_retryable. Properly handles out-of-memory and other transient failures. * Introduce Module.SrcLoc which has not only a byte offset but also references the file which the byte offset applies to. * Scope.Block now contains both a pointer to the "owner" Decl and the "source" Decl. As an example, during inline function call, the "owner" will be the Decl of the caller and the "source" will be the Decl of the callee. * Module.ErrorMsg now sports a `file_scope` field so that notes can refer to source locations in a file other than the parent error message. * Some instances where a `*Scope` was stored, now store a `*Scope.Container`. * Some methods in the `Scope` namespace were moved to the more specific type, since there was only an implementation for one particular tag. - `removeDecl` moved to `Scope.Container` - `destroy` moved to `Scope.File` * Two kinds of Scope deleted: - zir_module - decl * astgen: properly use DeclVal / DeclRef. DeclVal was incorrectly changed to be a reference; this commit fixes it. Fewer ZIR instructions processed as a result. - declval_in_module is renamed to declval - previous declval ZIR instruction is deleted; it was only for .zir files. * Test harness: friendlier diagnostics when an unexpected set of errors is encountered. * zir_sema: fix analyzeInstBlockFlat by properly calling resolvingInst on the last zir instruction in the block. Compile log implementation: * Write to a buffer rather than directly to stderr. * Only keep track of 1 callsite per Decl. * No longer mutate the ZIR Inst struct data. * "Compile log statement found" errors are only emitted when there are no other compile errors. -femit-zir and support for .zir source files is regressed. If we wanted to support this again, outputting .zir would need to be done as yet another backend rather than in the haphazard way it was previously implemented. For parsing .zir, it was implemented previously in a way that was not helpful for debugging. We need tighter integration with the test harness for it to be useful; so clearly a rewrite is needed. Given that a rewrite is needed, and it was getting in the way of progress and organization of the rest of stage2, I regressed the feature.
2021-01-10stage2: add support for loops in LLVM backendTimon Kruiper
A simple `while(true) {}` loop generates the following LLVMIR: ``` define i32 @main() { Entry: br label %Loop Loop: ; preds = %Loop, %Entry br label %Loop } ``` Also implement TZIR printing for loops and add a corresponding test.
2021-01-09Merge pull request #7725 from FireFox317/even-more-llvmAndrew Kelley
stage2: initial implementation of control flow in LLVM backend + TZIR printing
2021-01-08stage2: add initial impl of control flow in LLVM backendTimon Kruiper
The following TZIR instrutions have been implemented in the backend: - all cmp operators (lt, lte, gt, gte, eq, neq) - block - br - condbr The following LLVMIR is generated for a simple assert function: ``` define void @assert(i1 %0) { Entry: %1 = alloca i1, align 1 store i1 %0, i1* %1, align 1 %2 = load i1, i1* %1, align 1 %3 = xor i1 %2, true br i1 %3, label %Then, label %Else Then: ; preds = %Entry call void @llvm.debugtrap() unreachable Else: ; preds = %Entry br label %Block Block: ; preds = %Else ret void } ``` See tests for more examples.
2021-01-07Reduce use of deprecated IO typesJay Petacat
Related: #4917
2021-01-06stage2: rename and move files related to LLVM backendTimon Kruiper
2020-12-28stage2: add initial impl of LLVM backend in self-hosted compilerTimon Kruiper
2020-12-16Update zig_llvm.cpp and other bitsJakub Konka
Include updates to corresponding zig sources llvm commit b2851aea80e5a8f0cfd6c3c5a56a6b00fb28c6b6
2020-10-12Rename .macosx to .macosVignesh Rajagopalan
2020-09-21rename src-self-hosted/ to src/Andrew Kelley