37 Commits

Author SHA1 Message Date
joachimschmidt557
3ea603c82a stage2 ARM: implement ptr_add, ptr_sub for all element sizes
Also reduces slice_elem_val to ptr_add, simplifying the implementation
2022-03-08 10:54:08 +01:00
joachimschmidt557
a06e9eca45
stage2 AArch64: add more slice support
* airSlice
* airArrayToSlice
* and initial support for airSlicePtr and co
2022-03-05 11:31:51 +01:00
Jakub Konka
3ec74a1cd8 codegen: handle elem_ptr when lowering to memory
* x64: handle storing from-to non-stack memory
2022-03-02 20:04:34 -05:00
Andrew Kelley
1c8a86f063 Sema: detect comptime-known union initializations
Follow a similar pattern as we already do for validate_array_init and
validate_struct_init.

I threw in a bit of behavior test cleanup on top of it.
2022-03-02 17:28:39 -07:00
Jakub Konka
ec54ceee6d
Merge pull request #11016 from ziglang/x64-more-codegen 2022-03-01 09:14:23 +01:00
Andrew Kelley
157f66ec07 Sema: fix pointer type hash and equality functions
Several issues with pointer types are fixed:

Prior to this commit, Zig would not canonicalize a pointer type with
an explicit alignment to alignment=0 if it matched the pointee ABI
alignment. In order to fix this, `Type.ptr` now takes a Target
parameter. I also moved the host_size canonicalization to `Type.ptr`
since target is now available. Similarly, is_allowzero in the case of
C pointers is now treated as a canonicalization done by the function
rather than a precondition.

in-memory coercion for pointers now properly checks ABI alignment
of pointee types instead of incorrectly treating the 0 value as an
alignment.

Type equality is completely reworked based on the tag() rather than the
zigTypeTag(). It's still semantically based on zigTypeTag() but that
knowledge is implied rather than dictating the control flow of the
logic. Importantly, this fixes cases for opaques, structs, tuples,
enums, and unions, where type equality was incorrectly returning based
on whether the tag() values were equal.

Additionally, pointer type equality now takes into account alignment.
Because we canonicalize non-zero alignment which equals pointee type ABI
alignment to alignment=0, this now can be a simple integer comparison.

Type hashing is implemented for pointers and floats. Array types now
additionally hash their sentinels.

This regressed some behavior tests that were passing but only because
of bugs regarding type equality.

The C backend has a noticeable problem with lowering differently-aligned
pointers (particularly slices) as the same type, causing C compilation
errors due to duplicate declarations.
2022-02-28 19:22:16 -07:00
Jakub Konka
cfbc3537ef x64: pass more behavior tests 2022-02-28 23:20:05 +01:00
joachimschmidt557
1bf8da19e1
stage2 ARM: implement slice and array_to_slice 2022-02-27 21:38:56 +01:00
joachimschmidt557
91fbcf7093
stage2 ARM: enable more behavior tests 2022-02-27 21:38:56 +01:00
Andrew Kelley
6249a24e81 stage2: integer-backed packed structs
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.
2022-02-23 23:59:25 -07:00
Jakub Konka
25e4b16e25 Port more behavior tests 2022-02-22 21:57:42 +01:00
Jakub Konka
97c25fb8d0 x64: implement array_elem_val when array is stored in memory 2022-02-18 09:14:15 +01:00
Jakub Konka
abfaf8382b x64: implement array_elem_val when array fits in register 2022-02-18 09:14:15 +01:00
Jakub Konka
78e6f9c44c x64: fix ptr_add
However, still missing is taking into account pointer alignment
when performing arithmetic.
2022-02-16 14:13:06 +01:00
joachimschmidt557
22895f5616
stage2 AArch64: Enable behavior testing 2022-02-14 22:33:01 +01:00
Andrew Kelley
c349191b75 organize behavior tests
moving towards disabling failing tests on an individual basis
2022-02-12 21:13:07 -07:00
Jakub Konka
eb70f6e8d7
Merge pull request #10638 from Luukdegram/wasm-refactor
Stage2: wasm - Refactor lowering constants
2022-01-20 20:26:09 +01:00
Jakub Konka
df6c0067b2 stage2: fix passing arguments on the stack
* push the arguments in reverse order
* add logic for pushing args of any abi size to stack - very similar to
  `genSetStack` however, uses `.rsp` as the base register
* increment and decrement `.rsp` if we called a function with args on
  the stack in `airCall`
* add logic for recovering args from the caller's stack in the callee
2022-01-19 20:21:00 +01:00
Luuk de Gram
9615d7aee7
wasm: Refactor storing values.
Due to the new structure of lowerConstant, we can now simplify the logic in a lot of situations.
- We no longer have to check the `WValue`'s tag to determine how to load/store a value.
- We can now provide simple memcopy's for aggregate types.
- Constants are now memoized, meaning we do no longer lower constants on each callsite.
2022-01-19 20:01:23 +01:00
Jakub Konka
8201939d7f stage2: implement airArrayElemVal 2022-01-18 18:55:02 +01:00
Andrew Kelley
4d05f2ae5f remove zig_is_stage2 from @import("builtin")
Instead use the standarized option for communicating the
zig compiler backend at comptime, which is `zig_backend`. This was
introduced in commit 1c24ef0d0b09a12a1fe98056f2fc04de78a82df3.
2022-01-17 21:55:49 -07:00
Jakub Konka
ab204f81b0 stage2: return error.SkipZigTest in unsupported behavior tests 2022-01-17 20:30:44 +01:00
Andrew Kelley
336d0c97fe stage2: detection of comptime array literals
Introduce `validate_array_init_comptime`, similar to
`validate_struct_init_comptime` introduced in
713d2a9b3883942491b40738245232680877cc66.

`zirValidateArrayInit` is improved to detect comptime array literals and
emit AIR accordingly. This code is very similar to the changes
introduced in that same commit for `zirValidateStructInit`.

The C backend needed some improvements to continue passing the same set
of tests:
 * `resolveInst` for arrays now will add a local `static const` with the
   array value and so then `elem_val` instructions reference that local.
   It memoizes accesses using `value_map`, which is changed to use
   `Air.Inst.Ref` as the key rather than `Air.Inst.Index`.
 * This required a mechanism for writing to a "header" which is lines
   that appear at the beginning of a function body, before everything
   else.
 * dbg_stmt output comments rather than `#line` directives.
   TODO comment reproduced here:

We need to re-evaluate whether to emit these or not. If we naively emit
these directives, the output file will report bogus line numbers because
every newline after the #line directive adds one to the line.
We also don't print the filename yet, so the output is strictly unhelpful.
If we wanted to go this route, we would need to go all the way and not output
newlines until the next dbg_stmt occurs.
Perhaps an additional compilation option is in order?

`Value.elemValue` is improved to support `elem_ptr` values.
2022-01-13 22:13:44 -07:00
drew
2f53406ad8
CBE; implement airLoad and airStore for arrays (#10452)
Effectively a small continuation of #10152

This allows the for.zig behavior tests to pass. Unfortunately to fully test everything I had to move a lot of behavior tests from array.zig; most of them now pass (sorry @rainbowbismuth!)

I'm also conflicted on how I store constants into arrays because it's kind of stupid; array's can't be re-initialized using the same syntax, so instead of initializing each element, a new array is made which is copied into the destination. This also required that renderValue can't emit string literals for byte arrays given that they need to always have an extra byte for the NULL terminator, meaning that strings are no longer grep-able in the output.
2021-12-30 15:19:12 -05:00
Andrew Kelley
85d4c8620f Sema: implement array coercion 2021-12-27 22:06:23 -07:00
Andrew Kelley
7f70c27e9d stage2: more division support
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-21 19:05:26 -07:00
Andrew Kelley
0d4a94f32f stage2: improve handling of 0-bit types and arrays
* Make `alloc` AIR instructions call `resolveTypeLayout`.
 * `Sema.zirResolveInferredAlloc` now calls `requireRuntimeBlock` in the
   case that it operates on a non-comptime instruction.
 * `Type.abiSize` and `Type.abiAlignment` now return 0 for `void`
 * Sema: implement `resolveTypeFields` for unions.
 * LLVM Backend: support `ptr_elem_ptr` when the element type is 0-bit.
 * Type: improve `abiAlignment` implementation for structs to properly
   handle fields with non-default alignment.
 * Value: implement hashing array, vector, and structs.
2021-10-13 21:20:38 -07:00
Andrew Kelley
a3104a4a78 stage2: fix comptime stores and sentinel-terminated arrays
* 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-12 21:38:46 -07:00
Andrew Kelley
6d6cf59847 stage2: support nested structs and arrays and sret
* 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-11 11:39:12 -07:00
Andrew Kelley
3df19b765d AstGen: make array literals work like struct literals
Now, array literals will emit a coerce_result_ptr ZIR instruction just
like struct literals do. This makes for another passing behavior test case.
2021-10-07 16:01:13 -07:00
Andrew Kelley
76335bc7ba stage2: implement array literal with explicit type
New ZIR instruction: elem_ptr_imm
This saves some memory for array literals since the element indexes are
communicated as immediate values rather than as references to other ZIR
instructions.
2021-10-07 15:27:05 -07:00
Jacob G-W
83dcd9f038 stage2: emit Value.repeated for ** where the array size is one
This takes advantage of the repeated value.
2021-10-01 16:46:28 -04:00
g-w1
5e7406bdd9
stage2: implement array_init instruction (#9843)
* stage2: array mul support more types of operands
* stage2: array cat support more types of operands
* print_zir: print array_init
* stage2: implement Sema for array_init
2021-09-30 18:31:27 -04:00
Andrew Kelley
97d69e3352 stage2: add array_to_slice AIR instruction 2021-09-13 21:37:11 -07:00
Andrew Kelley
0cd361219c stage2: field type expressions support referencing locals
The big change in this commit is making `semaDecl` resolve the fields if
the Decl ends up being a struct or union. It needs to do this while
the `Sema` is still in scope, because it will have the resolved AIR
instructions that the field type expressions possibly reference. We do
this after the decl is populated and set to `complete` so that a `Decl`
may reference itself.

Everything else is fixes and improvements to make the test suite pass
again after making this change.

 * New AIR instruction: `ptr_elem_ptr`
   - Implemented for LLVM backend
 * New Type tag: `type_info` which represents `std.builtin.TypeInfo`. It
   is used by AstGen for the operand type of `@Type`.
 * ZIR instruction `set_float_mode` uses `coerced_ty` to avoid
   superfluous `as` instruction on operand.
 * ZIR instruction `Type` uses `coerced_ty` to properly handle result
   location type of operand.

 * Fix two instances of `enum_nonexhaustive` Value Tag not handled
   properly - it should generally be handled the same as `enum_full`.
 * Fix struct and union field resolution not copying Type and Value
   objects into its Decl arena.
 * Fix enum tag value resolution discarding the ZIR=>AIR instruction map
   for the child Sema, when they still needed to be accessed.
 * Fix `zirResolveInferredAlloc` use-after-free in the AIR instructions
   data array.
 * Fix `elemPtrArray` not respecting const/mutable attribute of pointer
   in the result type.
 * Fix LLVM backend crashing when `updateDeclExports` is called before
   `updateDecl`/`updateFunc` (which is, according to the API, perfectly
   legal for the frontend to do).
 * Fix LLVM backend handling element pointer of pointer-to-array. It
   needed another index in the GEP otherwise LLVM saw the wrong type.
 * Fix LLVM test cases not returning 0 from main, causing test failures.
   Fixes a regression introduced in
   6a5094872f10acc629543cc7f10533b438d0283a.

 * Implement comptime shift-right.
 * Implement `@Type` for integers and `@TypeInfo` for integers.
 * Implement union initialization syntax.
 * Implement `zirFieldType` for unions.
 * Implement `elemPtrArray` for a runtime-known operand.

 * Make `zirLog2IntType` support RHS of shift being `comptime_int`. In
   this case it returns `comptime_int`.

The motivating test case for this commit was originally:

```zig
test "example" {
    var l: List(10) = undefined;
    l.array[1] = 1;
}

fn List(comptime L: usize) type {
    var T = u8;
    return struct {
        array: [L]T,
    };
}
```

However I changed it to:

```zig
test "example" {
    var l: List = undefined;
    l.array[1] = 1;
}

const List = blk: {
    const T = [10]u8;
    break :blk struct {
        array: T,
    };
};
```

Which ended up being a similar, smaller problem. The former test case
will require a similar solution in the implementation of comptime
function calls - checking if the result of the function call is a struct
or union, and using the child `Sema` before it is destroyed to resolve
the fields.
2021-08-20 15:41:57 -07:00
Andrew Kelley
5619ce2406 Merge remote-tracking branch 'origin/master' into stage2-whole-file-astgen
Conflicts:
 * doc/langref.html.in
 * lib/std/enums.zig
 * lib/std/fmt.zig
 * lib/std/hash/auto_hash.zig
 * lib/std/math.zig
 * lib/std/mem.zig
 * lib/std/meta.zig
 * test/behavior/alignof.zig
 * test/behavior/bitcast.zig
 * test/behavior/bugs/1421.zig
 * test/behavior/cast.zig
 * test/behavior/ptrcast.zig
 * test/behavior/type_info.zig
 * test/behavior/vector.zig

Master branch added `try` to a bunch of testing function calls, and some
lines also had changed how to refer to the native architecture and other
`@import("builtin")` stuff.
2021-05-08 14:45:21 -07:00
Andrew Kelley
4307436b99 move behavior tests from test/stage1/ to test/
And fix test cases to make them pass. This is in preparation for
starting to pass behavior tests with self-hosted.
2021-04-29 15:54:04 -07:00