43 Commits

Author SHA1 Message Date
jacob gw
fedc9ebd26 stage2: cbe: restore all previously passing tests! 2021-03-31 18:09:45 -07:00
Andrew Kelley
3cebaaad1c astgen: improved handling of coercion
GenZir struct now has rl_ty_inst field which tracks the result location
type (if any) a block expects all of its results to be coerced to.

Remove a redundant coercion on const local initialization with a
specified type.

Switch expressions, during elision of store_to_block_ptr instructions,
now re-purpose them to be type coercion when the block has a type in the
result location.
2021-03-31 18:05:37 -07:00
Andrew Kelley
08eedc962d Sema: fix else case code generation for switch 2021-03-31 16:17:47 -07:00
Andrew Kelley
abd06d8eab stage2: clean up RangeSet and fix swapped Sema switch logic for lhs/rhs 2021-03-31 15:39:04 -07:00
Andrew Kelley
e272c29c16 Sema: implement switch validation for ranges 2021-03-31 15:06:03 -07:00
Andrew Kelley
549af582e7 AstGen: switch expressions properly handle result locations 2021-03-30 23:57:22 -07:00
Andrew Kelley
2a1dd174cd stage2: rework AstGen for switch expressions
The switch_br ZIR instructions are now switch_block instructions. This
avoids a pointless block always surrounding a switchbr in emitted ZIR
code.

Introduce typeof_elem ZIR instruction for getting the type of the
element of a pointer value in 1 instruction.

Change typeof to be un_node, not un_tok.

Introduce switch_capture ZIR instructions for obtaining the capture
value of switch prongs.

Introduce Sema.resolveBody for when you want to extract a *Inst out of a
block and you know that there is only going to be 1 break from it.

What's not working yet: AstGen does not correctly elide
store instructions when it turns out that the result location does not
need to be used as a pointer.

Also Sema validation code for duplicate switch items is not yet
implemented.
2021-03-30 21:28:36 -07:00
Andrew Kelley
195ddab2be Sema: implement switch expressions
The logic for putting ranges into the else prong is moved from AstGen to
Sema. However, logic to emit multi-items the same as single-items cannot
be done until TZIR supports mapping multiple items to the same block of
code. This will be simple to represent when we do the upcoming TZIR memory
layout changes.

Not yet implemented in this commit is the validation of duplicate
values. The trick is going to be emitting error messages with accurate
source locations, without adding extra source nodes to the ZIR
switch instruction.

This will be done by computing the respective AST node based on the
switch node (which we do have available), only when a compile error
occurs and we need to know the source location to attach the message to.
2021-03-29 21:59:08 -07:00
Andrew Kelley
623d5f442c stage2: guidance on how to implement switch expressions
Here's what I think the ZIR should be. AstGen is not yet implemented to
match this, and the main implementation of analyzeSwitch in Sema is not
yet implemented to match it either.

Here are some example byte size reductions from master branch, with the
ZIR memory layout from this commit:

```
switch (foo) {
  a => 1,
  b => 2,
  c => 3,
  d => 4,
}
```

184 bytes (master) => 40 bytes (this branch)

```
switch (foo) {
  a, b => 1,
  c..d, e, f => 2,
  g => 3,
  else => 4,
}
```

240 bytes (master) => 80 bytes (this branch)
2021-03-28 23:12:26 -07:00
Andrew Kelley
8f469c1127 stage2: fix error sets 2021-03-28 19:40:21 -07:00
jacob gw
0005b34637 stage2: implement sema for @errorToInt and @intToError 2021-03-28 18:22:01 -07:00
Andrew Kelley
1f5617ac07 stage2: implement bitwise expr and error literals 2021-03-26 23:46:37 -07:00
Andrew Kelley
b2deaf8027 stage2: improve source locations of Decl access
* zir.Code: introduce a decls array. This is so that `decl_val` and
   `decl_ref` instructions can refer to a Decl with a u32 and therefore
   they can also store a source location. This is needed for proper
   compile error reporting.
 * astgen uses a hash map to avoid redundantly adding a Decl to the
   decls array.
 * fixed reporting "instruction illegal outside function body" instead
   of the desired message "unable to resolve comptime value".
 * astgen skips emitting dbg_stmt instructions in comptime scopes.
 * astgen has some logic to avoid adding unnecessary type coercion
   instructions for common values.
2021-03-25 23:45:17 -07:00
Andrew Kelley
4bfcd105ef stage2: fix @compileLog. 2021-03-25 20:11:23 -07:00
Andrew Kelley
b9c5a1fdf5 astgen: fix for loop expressions
also rename the ZIR instruction `deref_node` to `load`.
2021-03-25 19:25:26 -07:00
Andrew Kelley
31023de6c4 stage2: implement inline while
Introduce "inline" variants of ZIR tags:
 * block => block_inline
 * repeat => repeat_inline
 * break => break_inline
 * condbr => condbr_inline

The inline variants perform control flow at compile-time, and they
utilize the return value of `Sema.analyzeBody`.

`analyzeBody` now returns an Index, not a Ref, which is the ZIR index of
a break instruction. This effectively communicates both the intended
break target block as well as the operand, allowing parent blocks to
find out whether they, in turn, should return the break instruction up the
call stack, or accept the operand as the block's result and continue
analyzing instructions in the block.

Additionally:
 * removed the deprecated ZIR tag `block_comptime`.
 * removed `break_void_node` so that all break instructions use the same Data.
 * zir.Code: remove the `root_start` and `root_len` fields. There is now
   implied to be a block at index 0 for the root body. This is so that
   `break_inline` has something to point at and we no longer need the
   special instruction `break_flat`.
 * implement source location byteOffset() for .node_offset_if_cond
   .node_offset_for_cond is probably redundant and can be deleted.

We don't have `comptime var` supported yet, so this commit adds a test
that at least makes sure the condition is required to be comptime known
for `inline while`.
2021-03-25 00:55:36 -07:00
Andrew Kelley
d73a4940e0 stage2: cleanups from previous commits
Change some ZIR instructions from un_tok to un_node. Idea here is to
avoid needlessly accessing the tokens array.

Go ahead and finish the catch code in orelseCatchExpr. Otherwise it
would be an easy mistake to get the scopes wrong when updating that
code and introduce a bug.

Delete a function that is now dead code.
2021-03-24 16:14:11 -07:00
Andrew Kelley
180dae4196 stage2: further cleanups regarding zir.Inst.Ref
* Introduce helper functions on Module.WipZirCode and zir.Code
 * Move some logic around
 * re-introduce ref_start_index
 * prefer usize for local variables + `@intCast` at the end.
   Empirically this is easier to optimize.
 * Avoid using mem.{bytesAsSlice,sliceAsBytes} because it incurs an
   unnecessary multiplication/division which may cause problems for the
   optimizer.
 * Use a regular enum, not packed, for `Ref`. Memory layout is
   guaranteed for enums which specify their tag type. Packed enums have
   ABI alignment of 1 byte which is too small.
2021-03-24 15:36:23 -07:00
Isaac Freund
0c601965ab
stage2: make zir.Inst.Ref a non-exhaustive enum
This provides us greatly increased type safety and prevents the common
mistake of using a zir.Inst.Ref where a zir.Inst.Index was expected or
vice-versa. It also increases the ergonomics of using the typed values
which can be directly referenced with a Ref over the previous zir.Const
approach.

The main pain point is casting between a []Ref and []u32, which could be
alleviated in the future with a new std.mem function.
2021-03-24 19:11:44 +01:00
Andrew Kelley
a1afe69395 stage2: comment out failing test cases; implement more things
* comment out the failing stage2 test cases
   (so that we can uncomment the ones that are newly passing with
   further commits)
 * Sema: implement negate, negatewrap
 * astgen: implement field access, multiline string literals, and
   character literals
 * Module: when resolving an AST node into a byte offset, use the
   main_tokens array, not the firstToken function
2021-03-23 23:13:01 -07:00
Andrew Kelley
13ced07f23 stage2: fix while loops
also start to form a plan for how inline while loops will work
2021-03-23 21:37:10 -07:00
Andrew Kelley
be673e6793 stage2: implement inttype ZIR
also add i128 and u128 to const inst list
2021-03-23 16:12:26 -07:00
Andrew Kelley
af73f79490 stage2: fix comptimeExpr and comptime function calls 2021-03-23 13:25:58 -07:00
Timon Kruiper
830143905e Sema: use correct LazySrcLoc for resolvePeerTypes 2021-03-23 11:56:06 -07:00
Andrew Kelley
d24be85be8 stage2: fix if expressions 2021-03-22 23:47:13 -07:00
Andrew Kelley
568f333681 astgen: improve the ensure_unused_result elision 2021-03-22 18:57:46 -07:00
Andrew Kelley
2f391df2a7 stage2: Sema improvements and boolean logic astgen
* add `Module.setBlockBody` and related functions
 * redo astgen for `and` and `or` to use fewer ZIR instructions and
   require less processing for comptime known values
 * Sema: rework `analyzeBody` function. See the new doc comments in this
   commit. Divides ZIR instructions up into 3 categories:
   - always noreturn
   - never noreturn
   - sometimes noreturn
2021-03-22 17:29:56 -07:00
Isaac Freund
9f0b9b8da1
stage2: remove all async related code
The current plan is to avoid using async and related features in the
stage2 compiler so that we can bootstrap before implementing them.

Having this untested and incomplete code in the codebase increases
friction while working on stage2, in particular when preforming
larger refactors such as the current zir memory layout rework.

Therefore remove all async related code, leaving only error messages
in astgen.
2021-03-23 00:23:41 +01:00
Isaac Freund
f3770dcc30
astgen: implement pointer types 2021-03-22 16:03:00 +01:00
Andrew Kelley
5769c963e0 Sema: implement arithmetic 2021-03-21 19:23:12 -07:00
Andrew Kelley
07c204393f Sema: no explicit coercion needed for inline asm args
These are now done with result locations.
2021-03-21 17:55:31 -07:00
Isaac Freund
310a44d5be zir: add negate/negate_wrap, implement astgen
These were previously implemented as a sub/sub_wrap instruction with a
lhs of 0. Making this separate instructions however allows us to save
some memory as there is no need to store a lhs.
2021-03-21 20:32:39 +01:00
Andrew Kelley
7598a00f34 stage2: fix memory management of ZIR code
* free Module.Fn ZIR code when destroying the owner Decl
 * unreachable_safe and unreachable_unsafe are collapsed into one ZIR
   instruction with a safety flag.
 * astgen: emit an unreachable instruction for unreachable literals
 * don't forget to call deinit on ZIR code
 * astgen: implement some builtin functions
2021-03-20 22:40:08 -07:00
Andrew Kelley
8bad5dfa72 astgen: implement inline assembly 2021-03-20 21:48:35 -07:00
Andrew Kelley
260c610708 ZIR: move some un_tok tags to un_node instead
Idea here is to prefer un_node to un_tok in order to avoid unnecessary
calls to `tree.firstToken`.
2021-03-20 17:18:44 -07:00
Andrew Kelley
50010447bd astgen: implement function calls 2021-03-20 17:09:06 -07:00
Andrew Kelley
56677f2f2d astgen: support blocks
We are now passing this test:

```zig
export fn _start() noreturn {}
```

```
test.zig:1:30: error: expected noreturn, found void
```

I ran into an issue where we get an integer overflow trying to compute
node index offsets from the containing Decl. The problem is that the
parser adds the Decl node after adding the child nodes. For some things,
it is easy to reserve the node index and then set it later, however, for
this case, it is not a trivial code change, because depending on tokens
after parsing the decl determines whether we want to add a new node or
not.

Possible strategies here:

1. Rework the parser code to make sure that Decl nodes are before
   children nodes in the AST node array.

2. Use signed integers for Decl node offsets.

3. Just flip the order of subtraction and addition. Expect Decl Node
   index to be greater than children Node indexes.

I opted for (3) because it seems like the simplest thing to do. We'll
want to unify the logic for computing the offsets though because if the
logic gets repeated, it will probably get repeated wrong.
2021-03-19 23:15:18 -07:00
Andrew Kelley
bd2154da3d stage2: the code is compiling again
(with a lot of things commented out)
2021-03-18 22:48:28 -07:00
Andrew Kelley
b2682237db stage2: get Module and Sema compiling again
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-18 22:19:28 -07:00
Andrew Kelley
66245ac834 stage2: Module and Sema are compiling again
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-17 22:54:56 -07:00
Andrew Kelley
38b3d4b00a stage2: work through some compile errors in Module and Sema 2021-03-17 00:56:08 -07:00
jacob gw
e430f3f7e0 zir-memory-layout: fix @setEvalBranchQuota
also make emitBackwardBranch fail correctly
2021-03-16 14:47:54 -07:00
Andrew Kelley
099af0e008 stage2: rename zir_sema.zig to Sema.zig 2021-03-16 00:04:17 -07:00