aboutsummaryrefslogtreecommitdiff
path: root/src/astgen.zig
AgeCommit message (Collapse)Author
2021-03-19zir-memory-layout: astgen: literals and *, &jacob gw
this was pretty low hanging fruit
2021-03-19zir-memory-layout: astgen: fill in identifierjacob gw
2021-03-18stage2: get Module and Sema compiling againAndrew Kelley
There are some `@panic("TODO")` in there but I'm trying to get the branch to the point where collaborators can jump in. Next is to repair the seam between LazySrcLoc and codegen's expected absolute file offsets.
2021-03-17stage2: Module and Sema are compiling againAndrew Kelley
Next up is reworking the seam between the LazySrcLoc emitted by Sema and the byte offsets currently expected by codegen. And then the big one: updating astgen.zig to use the new memory layout.
2021-03-16stage2: *WIP*: rework ZIR memory layout; overhaul source locationsAndrew Kelley
The memory layout for ZIR instructions is completely reworked. See zir.zig for those changes. Some new types: * `zir.Code`: a "finished" set of ZIR instructions. Instead of allocating each instruction independently, there is now a Tag and 8 bytes of data available for all ZIR instructions. Small instructions fit within these 8 bytes; larger ones use 4 bytes for an index into `extra`. There is also `string_bytes` so that we can have 4 byte references to strings. `zir.Inst.Tag` describes how to interpret those 8 bytes of data. - This is shared by all `Block` scopes. * `Module.WipZirCode`: represents an in-progress `zir.Code`. In this structure, the arrays are mutable, and get resized as we add/delete things. There is extra state to keep track of things. This struct is stored on the stack. Once it is finished, it produces an immutable `zir.Code`, which will remain on the heap for the duration of a function's existence. - This is shared by all `GenZir` scopes. * `Sema`: represents in-progress semantic analysis of a `zir.Code`. This data is stored on the stack and is shared among all `Block` scopes. It is now the main "self" argument to everything in the file that was previously named `zir_sema.zig`. Additionally, I moved some logic that was in `Module` into here. `Module.Fn` now stores its parameter names inside the `zir.Code`, instead of inside ZIR instructions. When the TZIR memory layout reworking time comes, codegen will be able to reference this data directly instead of duplicating it. astgen.zig is (so far) almost entirely untouched, but nearly all of it will need to be reworked to adhere to this new memory layout structure. I have no benchmarks to report yet, as I am still working through compile errors and fixing various things that I broke in this branch. Overhaul of Source Locations: Previously we used `usize` everywhere to mean byte offset, but sometimes also mean other stuff. This was error prone and also made us do unnecessary work, and store unnecessary bytes in memory. Now there are more types involved into source locations, and more ways to describe a source location. * AllErrors.Message: embrace the assumption that files always have less than 2 << 32 bytes. * SrcLoc gets more complicated, to model more complicated source locations. * Introduce LazySrcLoc, which can model interesting source locations with very little stored state. Useful for avoiding doing unnecessary work when no compile errors occur. Also, previously, we had `src: usize` on every ZIR instruction. This is no longer the case. Each instruction now determines whether it even cares about source location, and if so, how that source location is stored. This requires more careful work inside `Sema`, but it results in fewer bytes stored on the heap, without compromising accuracy and power of compile error messages. Miscellaneous: * std.zig: string literals have more helpful result values for reporting errors. There is now a lower level API and a higher level API. - side note: I noticed that the string literal logic needs some love. There is some unnecessarily hacky code there. * cut & pasted some TZIR logic that was in zir.zig to ir.zig. This probably broke stuff and needs to get fixed. * Removed type/Enum.zig, type/Union.zig, and type/Struct.zig. I don't think this quite how this code will be organized. Need some more careful planning about how to implement structs, unions, enums. They need to be independent Decls, just like a top level function.
2021-03-08parser: fix parsing/rendering of a[b.. :c] slicingIsaac Freund
The modification to the grammar in the comment is in line with the grammar in the zig-spec repo. Note: checking if the previous token is a colon is insufficent to tell if a block has a label, the identifier must be checked for as well. This can be seen in sentinel terminated slicing: `foo[0..1:{}]`
2021-03-06stage2: astgen asyncVeikka Tuominen
2021-03-03astgen: fix crash looking for wrong token in error setsAndrew Kelley
Fixes a regression from #7920.
2021-03-02stage2: improve orelse implementationAndrew Kelley
* Now it supports being an lvalue (see additional lines in the test case). * Properly handles a pointer result location (see additional lines in the test case that assign the result of the orelse to a variable rather than a const). * Properly sets the result location type when possible, so that type inference of an `orelse` operand expression knows its result type.
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-25stage2: implement the error_value AST tagAndrew Kelley
2021-02-24zig fmt src/Andrew Kelley
2021-02-23zig fmt: container doc commentsIsaac Freund
2021-02-19stage2: fix a couple off by one errorsAndrew Kelley
All stage2 tests are passing again in this branch. Remaining checklist for this branch: * get the rest of the zig fmt test cases passing - re-enable the translate-c test case that is blocking on this * implement the 2 `@panic(TODO)`'s in parse.zig * use fn_proto not fn_decl for extern function declarations
2021-02-19Merge pull request #7479 from ziglang/translate-c-astVeikka Tuominen
Make translate-c use intermediate AST
2021-02-19astgen: fix remaining compile errorsAndrew Kelley
Now it builds and what remains in this branch is: * fix the stage2 compiler regressions from this branch * finish the rest of zig fmt test cases, get them passing * Merge in Vexu's translate-c AST branch & fix translate-c regressions
2021-02-18stage2: astgen: fix most of the remaining compile errorsAndrew Kelley
more progress on converting astgen to the new AST memory layout. only a few code paths left to update.
2021-02-17stage2: fix a couple more compilation errorsAndrew Kelley
2021-02-17stage2: fix some of the compilation errors in this branchAndrew Kelley
2021-02-17astgen: finish updating expressions to new mem layoutAndrew Kelley
Now all that is left is compile errors and whatever regressions this branch introduced.
2021-02-16translate-c: convert vardecl and typedefVeikka Tuominen
2021-02-15astgen: update more expression types to new mem layoutAndrew Kelley
additionally introduce a new file to centralize all the data about builtin functions that we have, including: * enum tag identifying the builtin function * number of parameters. * whether the expression may need a memory location. * whether the expression allows an lvalue (currently only true for `@field`). Now there is only one ComptimeStringMap that has this data as the value, and we dispatch on the enum tag in order to asgen the builtin function. In particular this simplifies the logic for checking the number of parameters. This removes some untested code paths from if and while, which need to be restored with #7929 in mind. After this there are only a handful left of expression types to rework to the new memory layout, and then it will be only compile errors left to solve.
2021-02-13astgen: update a handful of expression types to new mem layoutAndrew Kelley
break, continue, blocks, bit_not, negation, identifiers, string literals, integer literals, inline assembly also gave multiline string literals a different node tag from regular string literals, for code clarity and to avoid an unnecessary load from token_tags array.
2021-02-12stage2: more progress towards Module/astgen building with new mem layoutAndrew Kelley
2021-02-01stage2: reimplement switchVeikka Tuominen
2021-01-31stage2: delete astgen for switch expressionsAndrew Kelley
The astgen for switch expressions did not respect the ZIR rules of only referencing instructions that are in scope: %14 = block_comptime_flat({ %15 = block_comptime_flat({ %16 = const(TypedValue{ .ty = comptime_int, .val = 1}) }) %17 = block_comptime_flat({ %18 = const(TypedValue{ .ty = comptime_int, .val = 2}) }) }) %19 = block({ %20 = ref(%5) %21 = deref(%20) %22 = switchbr(%20, [%15, %17], { %15 => { %23 = const(TypedValue{ .ty = comptime_int, .val = 1}) %24 = store(%10, %23) %25 = const(TypedValue{ .ty = void, .val = {}}) %26 = break("label_19", %25) }, %17 => { %27 = const(TypedValue{ .ty = comptime_int, .val = 2}) %28 = store(%10, %27) %29 = const(TypedValue{ .ty = void, .val = {}}) %30 = break("label_19", %29) } }, { %31 = unreachable_safe() }, special_prong=else) }) In this snippet you can see that the comptime expr referenced %15 and %17 which are not in scope. There also was no test coverage for runtime switch expressions. Switch expressions will have to be re-introduced to follow these rules and with some test coverage. There is some usable code being deleted in this commit; it will be useful to reference when re-implementing switch later. A few more improvements to do while we're at it: * only use .ref result loc on switch target if any prongs obtain the payload with |*syntax| - this improvement should be done to if, while, and for as well. - this will remove the needless ref/deref instructions above * remove switchbr and add switch_block, which is both a block and a switch branch. - similarly we should remove loop and add loop_block. This commit introduces a "force_comptime" flag into the GenZIR scope. The main purpose of this will be to choose the "comptime" variants of certain key zir instructions, such as function calls and branches. We will be moving away from using the block_comptime_flat ZIR instruction, and eventually deleting it. This commit also contains miscellaneous fixes to this branch that bring it to the state of passing all the tests.
2021-01-31astgen: rework for loopsAndrew Kelley
2021-01-31astgen: rework whileAndrew Kelley
2021-01-31astgen: rework orelse/catchAndrew Kelley
2021-01-31astgen: rework labeled blocksAndrew Kelley
2021-01-31astgen: respect a const local's type annotationAndrew Kelley
2021-01-31astgen: const locals that end up being rvalues do not allocAndrew Kelley
Local variable declarations now detect whether the result location for the initialization expression consumes the result location as a pointer. If it does, then the local is emitted as a LocalPtr. Otherwise it is emitted as a LocalVal. This results in clean, straightforward ZIR code for semantic analysis.
2021-01-31astgen: `@as` with block_ptr result locationAndrew Kelley
2021-01-31stage2: rework astgen result locationsAndrew Kelley
Motivating test case: ```zig export fn _start() noreturn { var x: u64 = 1; var y: u32 = 2; var thing: u32 = 1; const result = if (thing == 1) x else y; exit(); } ``` The main idea here is for astgen to output ideal ZIR depending on whether or not the sub-expressions of a block consume the result location. Here, neither `x` nor `y` consume the result location of the conditional expression block, and so the ZIR should communicate the result of the condbr using break instructions, not with the result location pointer. With this commit, this is accomplished: ``` %22 = alloc_inferred() %23 = block({ %24 = const(TypedValue{ .ty = type, .val = bool}) %25 = deref(%18) %26 = const(TypedValue{ .ty = comptime_int, .val = 1}) %27 = cmp_eq(%25, %26) %28 = as(%24, %27) %29 = condbr(%28, { %30 = deref(%4) < there is no longer a store instruction here > %31 = break("label_23", %30) }, { %32 = deref(%11) < there is no longer a store instruction here > %33 = break("label_23", %32) }) }) %34 = store_to_inferred_ptr(%22, %23) <-- the store is only here %35 = resolve_inferred_alloc(%22) ``` However if the result location gets consumed, the break instructions change to break_void, and the result value is communicated only by the stores, not by the break instructions. Implementation: * The GenZIR scope that conditional branches uses now has an optional result location pointer field and a count of how many times the result location ended up being an rvalue (not consumed). * When rvalue() is called on a result location for a block, it increments this counter. After generating the branches of a block, astgen for the conditional branch checks this count and if it is 2 then the store_to_block_ptr instructions are elided and it calls rvalue() using the block result (which will account for peer type resolution on the break operands). astgen has many functions disabled until they can be reworked with these new semantics. That will be done before merging the branch. There are some new rules for astgen to follow regarding result locations and what you are allowed/required to do depending on which one is passed to expr(). See the updated doc comments of ResultLoc for details. I also changed naming conventions of stuff in this commit, sorry about that.
2021-01-30remove @TagTypeTadeo Kondrak
2021-01-19astgen: eliminate rlWrapPtr and all its callsitesAndrew Kelley
The following AST avoids unnecessary derefs now: * error set decl * field access * array access * for loops: replace ensure_indexable and deref on the len_ptr with a special purpose ZIR instruction called indexable_ptr_len. Added an error note when for loop operand is the wrong type. I also accidentally implemented `@field`.
2021-01-18stage2: rework ZIR/TZIR for optionals and error unionsAndrew Kelley
* fix wrong pointer const-ness when unwrapping optionals * allow grouped expressions and orelse as lvalues * ZIR for unwrapping optionals: no redundant deref - add notes to please don't use rlWrapPtr, this function should be deleted * catch and orelse: better ZIR for non-lvalue: no redundant deref; operate entirely on values. lvalue case still works properly. - properly propagate the result location into the target expression * Test harness: better output when tests fail due to compile errors. * TZIR: add instruction variants. These allow fewer TZIR instructions to be emitted from zir_sema. See the commit diff for per-instruction documentation. - is_null - is_non_null - is_null_ptr - is_non_null_ptr - is_err - is_err_ptr - optional_payload - optional_payload_ptr * TZIR: removed old naming convention instructions: - isnonnull - isnull - iserr - unwrap_optional * ZIR: add instruction variants. These allow fewer ZIR instructions to be emitted from astgen. See the commit diff for per-instruction documentation. - is_non_null - is_null - is_non_null_ptr - is_null_ptr - is_err - is_err_ptr - optional_payload_safe - optional_payload_unsafe - optional_payload_safe_ptr - optional_payload_unsafe_ptr - err_union_payload_safe - err_union_payload_unsafe - err_union_payload_safe_ptr - err_union_payload_unsafe_ptr - err_union_code - err_union_code_ptr * ZIR: removed old naming convention instructions: - isnonnull - isnull - iserr - unwrap_optional_safe - unwrap_optional_unsafe - unwrap_err_safe - unwrap_err_unsafe - unwrap_err_code
2021-01-18stage2: fix orelse at comptimeg-w1
There was just some untested code that did not work. .isnull -> .isnonnull and I had to add a .ref resultloc to make types match up.
2021-01-17stage2: add compile error for label redefinitionAndrew Kelley
Also fix incorrectly destroying notes. This work is based on Vexu's patch in #7555.
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-11Merge branch 'Stage2 begin implementing container types'Andrew Kelley
2021-01-05stage2: add compile log statementg-w1
2021-01-04stage2: improvements to `@setEvalBranchQuota`Andrew Kelley
* extract magic number into a constant * properly use result location casting for the operand * naming convention for ZIR instructions
2021-01-04stage2: implementation of `@setEvalBranchQuota`:g-w1
`@setEvalBranchQuota` can be called before the comptime/inline call stack is created. For example: ```zig @setEvalBranchQuota(100); comptime { while (true) {} } ``` Here we need to set the branch_quota before the comptime block creates a scope for the branch_count.
2021-01-02stage2: comptime function callsAndrew Kelley
* Function calls that happen in a comptime scope get called at compile-time. We do this by putting the parameters in place as constant values and then running regular function analysis on the body. * Added `Scope.Block.dump()` for debugging purposes. * Fixed some code to call `identifierTokenString` rather than `tokenSlice`, making it work for `@""` syntax. * Implemented `Value.copy` for big integers. Follow-up issues to tackle: * Adding compile errors to the callsite instead of the callee Decl. * Proper error notes for "called from here". - Related: #7555 * Branch quotas. * ZIR support?
2021-01-02convert more {} to {d} and {s}Andrew Kelley
2021-01-02langref: Update langref to use {s}LemonBoy
2021-01-02stage2: Use {s} instead of {} when formatting stringsLemonBoy
2021-01-01std: have std.meta.fieldInfo take an enum rather than a stringdaurnimator
2020-12-31stage2: compile error for invalid `var` typeAndrew Kelley