413 Commits

Author SHA1 Message Date
Thomas Ives
51efd553ae C backend: Improve lowering of Zig types to C types
1. Changed Zig pointers to functions to be typedef'd so then we can
   treat them the same as other types.

2. Distinguished between const slices (zig_L prefix) and mut slices
   (zig_M prefix).

3. Changed lowering of Zig "const pointers" (e.g. *const u8) to to C
   "pointers to const" (e.g. const char *) rather than C "const
   pointers" (e.g.  char * const)

4. Ensured that all typedefs are "linked" even if the decl doesn't
   require any forward declarations

5. Added test that exercises function pointer type rendering

6. Changed .slice_ptr instruction to allocate pointer local rather than
   a uintptr_t local
2021-11-10 12:39:47 -05:00
Andrew Kelley
cb785b9c6b Sema: implement coerce_result_ptr for optionals
New AIR instruction: `optional_payload_ptr_set`
It's like `optional_payload_ptr` except it sets the non-null bit.

When storing to the payload via a result location that is an optional,
`optional_payload_ptr_set` is now emitted. There is a new algorithm in
`zirCoerceResultPtr` which stores a dummy value through the result
pointer into a temporary block, and then pops off the AIR instructions
from the temporary block in order to determine how to transform the
result location pointer in case any in-between coercions need to happen.

Fixes a couple of behavior tests regarding optionals.
2021-11-09 23:01:35 -07:00
Zen1th
6869bc9ff8
stage2: Add support for floats in the C backend (#10059)
* Implement float type
* Fix int and float undefined value
* Handle NaN constants, preserving bit pattern
2021-11-09 18:56:01 -05:00
Emily Bellows
684d9532c5 C backend: restore handling of .NoReturn in function signature 2021-11-08 14:23:55 -05:00
Emily Bellows
e3d638a49e C backend: while, struct tests, better undefined global handling
1. Function signatures that return a no member struct return void
2. Undefined var decls don't get a value generated for them
3. Don't generate bitcast code if the result isn't used, since
   bitcast is a pure function. Right now struct handling code
   generates some weird unused bitcast AIR, and this optimization
   side steps that issue.
2021-11-08 14:23:55 -05:00
Ryan Liptak
e97feb96e4 Replace ArrayList.init/ensureTotalCapacity pairs with initCapacity
Because ArrayList.initCapacity uses 'precise' capacity allocation, this should save memory on average, and definitely will save memory in cases where ArrayList is used where a regular allocated slice could have also be used.
2021-11-04 14:54:25 -04:00
Emily Bellows
674932e503 C backend: implement ?void, and other zero sized types 2021-11-02 12:45:29 -04:00
Ryan Liptak
70ef9bc75c Fix ensureTotalCapacity calls that should be ensureUnusedCapacity calls
If these functions are called more than once, then the array list would no longer be guaranteed to have enough capacity during the appendAssumeCapacity calls. With ensureUnusedCapacity, they will always be guaranteed to have enough capacity regardless of how many times the function is called.
2021-11-01 15:08:41 -04:00
Emily Bellows
969bcb6a59 C backend: implement signed trunc 2021-10-30 16:09:55 -04:00
Andrew Kelley
d6067db062 stage2: implement @popCount for non-vectors 2021-10-29 17:49:02 -07:00
Andrew Kelley
bbe4a9fa99 C backend: implement trunc for unsigned non-pow2 ints 2021-10-28 18:33:13 -07:00
Andrew Kelley
98009a2f66 C backend: implement trunc instruction
Note that there is not any test coverage yet for integer
truncation involving non-power-of-two integers.
2021-10-28 17:41:45 -07:00
Andrew Kelley
5479c0f9ac C backend: fix @boolToInt 2021-10-28 17:33:05 -07:00
Andrew Kelley
c59ee3157f C backend: fix ptrtoint and wrap_errunion_err 2021-10-28 17:05:17 -07:00
Andrew Kelley
d2f9646d98 C backend: fix enough that zig test works
* test_functions: properly add dependencies of the array on test
   functions and test names so that the order comes out correctly.
 * fix lowering of struct literals to add parentheses around the type
   name.
 * omit const qualifier in slices because otherwise slices cannot be
   reassigned even when they are local variables.
 * special case pointer to functions and double pointer to functions in
   renderTypeAndName. This code will need to be cleaned up but for now
   it helps us make progress on other C backend stuff.
 * fix slice element access to lower to `.ptr[` instead of `[`.
 * airSliceElemVal: respect volatile slices
2021-10-28 15:59:14 -07:00
Andrew Kelley
3af9731600 stage2: implement runtime pointer access to global constants
The main problem that motivated these changes is that global constants
which are referenced by pointer would not be emitted into the binary.
This happened because `semaDecl` did not add `codegen_decl` tasks for
global constants, instead relying on the constant values being copied as
necessary. However when the global constants are referenced by pointer,
they need to be sent to the linker to be emitted.

After making global const arrays, structs, and unions get emitted, this
uncovered a latent issue: the anonymous decls that they referenced would
get garbage collected (via `deleteUnusedDecl`) even though they would
later be referenced by the global const.

In order to solve this problem, I introduced `anon_work_queue` which is
the same as `work_queue` except a lower priority. The `codegen_decl`
task for anon decls goes into the `anon_work_queue` ensuring that the
owner decl gets a chance to mark its anon decls as alive before they are
possibly deleted.

This caused a few regressions, which I made the judgement call to add
workarounds for. Two steps forward, one step back, is still progress.

The regressions were:
 * Two behavior tests having to do with unions. These tests were
   intentionally exercising the LLVM constant value lowering, however,
   due to the bug with garbage collection that was fixed in this commit,
   the LLVM code was not getting exercised, and union types/values were
   not implemented correctly, due to me forgetting that LLVM does not
   allow bitcasting aggregate values.
   - This is worked around by allowing those 2 test cases to regress,
     moving them to the "passing for stage1 only" section.
 * The test-stage2 test cases (in test/cases/*) for non-LLVM backends
   previously did not have any calls to lower struct values, but now
   they do. The code that was there was just `@panic("TODO")`. I
   replaced that code with a stub that generates the wrong value. This
   is an intentional miscompilation that will obviously need to get
   fixed before any struct behavior tests pass. None of the current
   tests we have exercise loading any values from these global const
   structs, so there is not a problem until we try to improve these
   backends.
2021-10-26 22:41:19 -07:00
Andrew Kelley
11a60e8779 stage2 LLVM backend: fix bitcast
Properly handle when the operand type, the result type, or both, are
by-ref values.
2021-10-26 16:43:18 -07:00
Andrew Kelley
c6b3d06535 Sema: improved C pointers and casting
* C pointer types always have allowzero set to true but they omit the
   word allowzero when printed.
 * Implement coercion from C pointers to other pointers.
 * Implement in-memory coercion for slices and pointer-like optionals.
 * Make slicing a C pointer drop the allowzero bit.
 * Value representation for pointer-like optionals is now allowed to use
   pointer tag values in addition to the `opt_payload` tag.
2021-10-26 13:46:27 -07:00
Andrew Kelley
df198ea60e
Merge pull request #10034 from Snektron/stage2-slice
stage2: slice and optional improvements
2021-10-25 19:41:19 -04:00
Robin Voetter
21bf3b8066 stage2: runtime c pointer null comparison 2021-10-26 01:24:14 +02:00
Andrew Kelley
30d01c8fea
Merge pull request #9874 from leecannon/frame_pointer
Make omiting frame pointer independent of build mode
2021-10-25 19:15:17 -04:00
Robin Voetter
4eb7b28700 stage2: generate correct constants for zero-sized arrays 2021-10-25 20:41:15 +02:00
LemonBoy
811766e1cf stage1/stage2: Simplify divTrunc impl
According to the documentation, `divTrunc` is "Truncated division.
Rounds toward zero". Lower it as a straightforward fdiv + trunc sequence
to make it behave as expected with mixed positive/negative operands.

Closes #10001
2021-10-24 17:11:43 +02:00
Andrew Kelley
22b4c9e1a9 stage2: implement more C pointer Sema and comptime ptr arith 2021-10-23 19:47:32 -07:00
Andrew Kelley
6aeb6bcc84 stage2: LLVM backend: fix optional_payload instructions
They previously did not respect the optional type layout, but now they
do.
2021-10-22 23:35:46 -07:00
Andrew Kelley
01c1f41520 stage2: slice and alignment fixes
* Fix backend using wrong union field of the slice instruction.
 * LLVM backend properly sets alignment on global variables.
 * Sema: add coercion for *T to *[1]T
 * Sema: pointers to Decls with explicit alignment now have alignment
   metadata in them.
2021-10-22 17:12:12 -07:00
Andrew Kelley
b24e9b6347 Sema: fix a couple use-after-free bugs
Also switch to the more efficient encoding of the bitcast instruction
when the destination type is anyerror in 2 common cases.

LLVM backend: fix using the wrong type as the optional payload type in
the `wrap_optional` AIR instruction.
2021-10-22 16:23:34 -07:00
Andrew Kelley
6cd14f051d stage2: LLVM backend: add a missing setUnnamedAddr
for anonymous constants
2021-10-21 23:22:31 -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
Robin Voetter
09c7d5aebc stage2: elemPtr for slices
* Restructure elemPtr a bit
* New AIR instruction: slice_elem_ptr, which returns a pointer to an element of a slice
* Value: adapt elemPtr to work on slices
2021-10-21 16:24:18 +02:00
Robin Voetter
84876fec58 stage2: remove ptr_ptr_elem_val and ptr_slice_elem_val 2021-10-21 16:24:18 +02:00
Andrew Kelley
a0e195120d stage2: implement slicing
* 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-20 21:45:11 -07:00
Andrew Kelley
8b734380f9 stage2: LLVM backend: fix decls sometimes not marked alive
Without this they could get incorrectly garbage collected.
2021-10-20 16:42:43 -07:00
Andrew Kelley
361217bda2 stage2: fix inline assembly with expression output
Thanks @g-w1 for the print_air.zig implementation for inline assembly. I
copied it and slightly modified it from your open pull request.
2021-10-20 15:34:10 -07:00
Andrew Kelley
ed2a5081e1 stage2: LLVM backend: implement switch_br 2021-10-20 14:10:37 -07:00
Andrew Kelley
2192d404d5 stage2: wasm: implement struct_field_val 2021-10-19 19:20:31 -07:00
Andrew Kelley
e4c437f23b stage2: implement union member access as enum tag 2021-10-19 19:03:20 -07:00
Robin Voetter
6329f4e47a stage2: union field value 2021-10-20 03:44:02 +02:00
Robin Voetter
05c5c99a95 stage2: air ptr_slice_len_ptr and ptr_slice_ptr_ptr 2021-10-20 03:44:02 +02:00
Jakub Konka
372e9709ad macho: fix LLVM codepaths in self-hosted linker
* do not add linkage scope to aliased exported symbols - this is
  not respected on macOS
* special-case `MachO.openPath` in `link.File.openPath` as on macOS
  we always link with zld
* redirect to `MachO.flushObject` when linking relocatable objects
  in MachO linker whereas move the entire linking logic into
  `MachO.flushModule`
2021-10-19 20:39:42 +02:00
Andrew Kelley
ad17108bdd
Merge pull request #9960 from Snektron/bit-not
Some not and vector stuff
2021-10-17 21:59:10 -04:00
Andrew Kelley
e9d1e5e533 stage2: LLVM backend: lower constant field/elem ptrs 2021-10-17 17:02:20 -07:00
Andrew Kelley
07691db3ae stage2: fix handling of error unions as return type
* LLVM backend: fix phi instruction not respecting `isByRef`
   - Also fix `is_non_null` not respecting `isByRef`
 * Type: implement abiSize for error unions
2021-10-17 15:36:12 -07:00
Andrew Kelley
6534f2ef4f stage2: implement error wrapping
* Sema: fix returned operands not coercing to the function return type
   in some cases.
   - When returning an error or an error union from a function with an
     inferred error set, it will now populate the inferred error set.
   - Implement error set coercion for the common case of inferred error
     set to inferred error set, without forcing a full resolution.
 * LLVM backend: update instruction lowering that handles error unions
   to respect `isByRef`.
   - Also implement `wrap_err_union_err`.
2021-10-17 14:55:32 -07:00
Robin Voetter
fd838584bf stage2: vector constants 2021-10-17 20:33:04 +02:00
Robin Voetter
d193ba9843 stage2: array->vector coercion 2021-10-17 20:33:04 +02:00
Lee Cannon
b5be01a597 stage2 codegen 2021-10-16 21:55:51 +01:00
Lee Cannon
023e4b9fed stage2 - add llvm bindings to create attributes with string values 2021-10-16 21:55:51 +01:00
Andrew Kelley
4d6d6977b0 stage2: fixes to extern variables
* Relax compile error for "unable to export type foo" to allow
   integers, structs, arrays, and floats. This will need to be further
   improved to do the same checks as we do for C ABI struct field types.
 * LLVM backend: fix extern variables
 * LLVM backend: implement AIR instruction `wrap_err_union_payload`
2021-10-16 12:26:06 -07:00
Andrew Kelley
682cdeceaa stage2: optional comparison and 0-bit payloads
* Sema: implement peer type resolution for optionals and null.
 * Rename `Module.optionalType` to `Type.optional`.
 * LLVM backend: re-use anonymous values. This is especially useful when
   isByRef()=true because it means re-using the same generated LLVM globals.
 * LLVM backend: rework the implementation of is_null and is_non_null
   AIR instructions. Generate slightly better LLVM code, and also fix
   the behavior for optionals whose payload type is 0-bit.
 * LLVM backend: improve `cmp` AIR instruction lowering to support
   pointer-like optionals.
 * `Value`: implement support for equality-checking optionals.
2021-10-15 18:37:09 -07:00