Commit graph

284 commits

Author SHA1 Message Date
Veikka Tuominen
a8520fbd0f stage2: add dbg_block_{begin,end} instruction 2022-03-19 11:20:38 +02:00
John Schmidt
adfcc8851b Implement @byteSwap for vectors
Make the behavior tests for this a little more primitive to exercise as
little extra functionality as possible.
2022-03-17 18:00:48 -07:00
Andrew Kelley
7233a3324a stage2: implement @reduce
Notably, Value.eql and Value.hash are improved to treat NaN as equal to
itself, so that Type/Value can be hash map keys. Likewise float hashing
normalizes the float value before computing the hash.
2022-03-17 17:24:35 -07:00
Andrew Kelley
87779cfd93 stage2: prevent UB in the LLVM backend
* Sema: fix `zirTypeInfo` allocating with the wrong arenas for some
   stuff.
 * LLVM: split `airDbgInline` into two functions, one for each AIR tag.
   - remove the redundant copy to type_map_arena. This is the first
     thing that lowerDebugType does so this hack was probably just
     accidentally avoiding UB (which is still present prior to this
     commit).
   - don't store an inline fn inst into the di_map for the generic
     decl.
   - use a dummy function type for the debug info to avoid whatever UB
     is happening.
   - we are now ignoring the function type passed in with the
     dbg_inline_begin and dbg_inline_end.
 * behavior tests: prepare the vector tests to be enabled one at a time.

Mitigates #11199.
2022-03-17 00:00:41 -07:00
John Schmidt
c8ed813097 Implement @mulAdd for vectors 2022-03-16 20:11:05 -07:00
Andrew Kelley
d78b8c10b9 LLVM: fix slice debug info and functions
with return types that have no runtime bits
2022-03-16 17:22:16 -07:00
Andrew Kelley
1f313b3d7c LLVM: make the load function copy isByRef=true types 2022-03-16 11:52:22 -07:00
Veikka Tuominen
d83a26f068 stage2 llvm: keep track of inlined functions 2022-03-16 10:53:41 +02:00
Veikka Tuominen
0343811836 Sema: emit dbg_func around inline calls 2022-03-16 09:34:26 +02:00
Andrew Kelley
8a43d67c3b LLVM: fix LLVM assertion when slicing 2022-03-16 00:09:00 -07:00
Andrew Kelley
c3663f2617 LLVM: implement debug info for structs
This involved some significant reworking in order to introduce the
concept of "forward declarations" to the system to break dependency
loops.

The `lowerDebugType` function now takes an `enum { full, fwd }` and is moved
from `DeclGen` to `Object` so that it can be called from `flushModule`.

`DITypeMap` is now an `ArrayHashMap` instead of a `HashMap` so that we can
iterate over the entries in `flushModule` and finalize the forward decl
DITypes into full DITypes.

`DITypeMap` now stores `AnnotatedDITypePtr` values instead of
`*DIType` values. This is an abstraction around a `usize` which assumes
the pointers will be at least 2 bytes aligned and uses the least
significant bit to store whether it is forward decl or a fully resolved
debug info type.

`lowerDebugTypeImpl` is extracted out from `lowerDebugType` and it has a
mechanism for completing a forward decl DIType to a fully resolved one.
The function now contains lowering for struct types. Closes #11095.

There is a workaround for struct types which have not had
`resolveFieldTypes` called in Sema, even by the time `flushModule` is
called. This is a deficiency of Sema that should be addressed, and the
workaround removed. I think Sema needs a new mechanism to queue up type
resolution work instead of doing it in-line, so that it does not cause
false dependency loops. We already have one failing behavior test
because of a false dependency loop.
2022-03-16 00:09:00 -07:00
Veikka Tuominen
2583be7585 stage2 llvm: fix @extern 2022-03-16 00:09:00 -07:00
Cody Tapscott
480e7eec65 stage2: Fix panic on initializing comptime fields in tuple
This resolves https://github.com/ziglang/zig/issues/11159

The problem was that:
  1. We were not correctly deleting the field stores after recognizing
     that an array initializer was a comptime-known value.
  2. LLVM was not checking that the final type had no runtime bits, and
     so would generate an invalid store.

This also adds several test cases for related bugs, just to check these
in for later work.
2022-03-15 17:01:16 -07:00
Andrew Kelley
1adb15098c LLVM: clean up airUnaryOp to call callFloatUnary
and make callFloatUnary support vectors. I tried to make it use
getIntrinsic, but that resulted in tripping `assert(id != 0)`.
2022-03-14 21:43:57 -07:00
Andrew Kelley
2f92d1a026 stage2: fixups for topolarity-comptime-memory-reinterp branch
* don't store `has_well_defined_layout` in memory.
 * remove struct `hasWellDefinedLayout` logic. it's just
   `layout != .Auto`. This means we only need one implementation, in
   Type.
 * fix some of the cases being wrong in `hasWellDefinedLayout`, such as
   optional pointers.
 * move `tag_ty_inferred` field into a position that makes it more
   obvious how the struct layout will be done. Also we don't have a
   compiler that intelligently moves fields around so this layout is
   better.
 * Sema: don't `resolveTypeLayout` in `zirCoerceResultPtr` unless
   necessary.
 * Rename `ComptimePtrLoadKit` `target` field to `pointee` to avoid
   confusion with `target`.
2022-03-14 21:43:03 -07:00
Cody Tapscott
1f76b4c6b8 stage2 llvm: Respect container type when lowering parent pointers
We need to make sure that we bitcast our pointers correctly before
we use get_element_ptr to compute the offset for the parent
pointer.

This also includes a small fix-up for a problem where ptrs to const
i64/u64 were not using the correct type in >1-level decl chains
(where we call lowerParentPtr recursively)
2022-03-14 21:42:43 -07:00
Cody Tapscott
bbd750ff05 stage2: Add container_ty/elem_ty to elem_ptr, field_ptr, *_payload_ptr Values 2022-03-14 21:42:42 -07:00
Andrew Kelley
a2a5d3c288
Merge pull request #11167 from mitchellh/codegen-arrays
stage2: codegen of arrays should use type length, not value length
2022-03-15 00:40:32 -04:00
William Sengir
c757f19790 stage2: add debug info for globals in the LLVM backend
LLVM backend: generate DIGlobalVariable's for non-function globals and
rename linkage names when exporting functions and globals.

zig_llvm.cpp: add some wrappers to convert a handful of DI classes
into DINode's since DIGlobalVariable is not a DIScope like the others.

zig_llvm.cpp: add some wrappers to allow replacing the LinkageName of
DISubprogram and DIGlobalVariable.

zig_llvm.cpp: fix DI class mixup causing nonsense reinterpret_cast.

The end result is that GDB is now usable since you now no longer need
to manually cast every global nor fully qualify every export.
2022-03-15 00:38:20 -04:00
Mitchell Hashimoto
a859f94644
stage2: LLVM codegen of arrays should use type length, not value length
It is possible for the value length to be longer than the type because
we allow in-memory coercing of types such as `[5:0]u8` to `[5]u8`. In
such a case, the value length is 6 but the type length if 5.

The `.repeated` value type already got this right, so this is extending
similar logic out to `.aggregate` and `.bytes`. Both scenarios are
tested in behavior tests.

Fixes #11165
2022-03-14 17:41:12 -07:00
Andrew Kelley
5ea94e7715 stage2: rework Value storage of structs and arrays
Now they both use `Value.Tag.aggregate`.

Additionally the LLVM backend now has implemented lowering of
tuple values.
2022-03-14 12:28:52 -07:00
Andrew Kelley
7a477a1110 LLVM: fix int_to_float signedness detection
It was checking if the result (float) type was a signed int rather than
checking the operand (integer) type.
2022-03-14 00:11:46 -07:00
Andrew Kelley
eeaaefb925 LLVM: fix debug info for local vars
Previously we incorrectly used the pointer type as the debug info type.
2022-03-14 00:11:46 -07:00
Andrew Kelley
0bc9635490 stage2: add debug info for locals in the LLVM backend
Adds 2 new AIR instructions:
 * dbg_var_ptr
 * dbg_var_val

Sema no longer emits dbg_stmt AIR instructions when strip=true.

LLVM backend: fixed lowerPtrToVoid when calling ptrAlignment on
the element type is problematic.

LLVM backend: fixed alloca instructions improperly getting debug
location annotated, causing chaotic debug info behavior.

zig_llvm.cpp: fixed incorrect bindings for a function that should use
unsigned integers for line and column.

A bunch of C test cases regressed because the new dbg_var AIR
instructions caused their operands to be alive, exposing latent bugs.
Mostly it's just a problem that the C backend lowers mutable
and const slices to the same C type, so we need to represent that in the
C backend instead of printing two duplicate typedefs.
2022-03-13 03:41:31 -04:00
Veikka Tuominen
487ee79ec9 stage2 llvm: do not use getIntrinsic for airFrameAddress
getIntrinsic gets the return type wrong so we have to add the function manually
2022-03-12 12:33:32 +02:00
Andrew Kelley
f6b479b81d LLVM: use hasRuntimeBitsIgnoreComptime instead of hasRuntimeBits
LLVM codegen doesn't care whether types are comptime or not. Comptime
types aren't supposed to make it to codegen anyway.
2022-03-11 22:48:35 -07:00
Andrew Kelley
491e3ba6b1 LLVM: fix debug info for pointers to void 2022-03-11 21:00:07 -07:00
Veikka Tuominen
cba68090a6 stage2: implement @shuffle at runtime 2022-03-11 13:12:32 +02:00
Andrew Kelley
078037ab9b stage2: passing threadlocal tests for x86_64-linux
* use the real start code for LLVM backend with x86_64-linux
   - there is still a check for zig_backend after initializing the TLS
     area to skip some stuff.
 * introduce new AIR instructions and implement them for the LLVM
   backend. They are the same as `call` except with a modifier.
   - call_always_tail
   - call_never_tail
   - call_never_inline
 * LLVM backend calls hasRuntimeBitsIgnoringComptime in more places to
   avoid unnecessarily depending on comptimeOnly being resolved for some
   types.
 * LLVM backend: remove duplicate code for setting linkage and value
   name. The canonical place for this is in `updateDeclExports`.
 * LLVM backend: do some assembly template massaging to make `%%`
   rendered as `%`. More hacks will be needed to make inline assembly
   catch up with stage1.
2022-03-11 00:04:42 -07:00
Veikka Tuominen
673fafc231 stage2 llvm: implement lowerParentPtr for int_{u,i}64 2022-03-10 19:52:03 +02:00
Andrew Kelley
f736cde397 Sema: implement pointer to tuple to pointer to array coercion
This involved an LLVM backend fix for the aggregate_init instruction.
2022-03-09 18:49:37 -07:00
Andrew Kelley
fb4ad37e0b LLVM: fix memory leak of debug type names
This required adjusting `Type.nameAlloc` to be used with a
general-purpose allocator and added `Type.nameAllocArena` for the arena
use case (avoids allocation sometimes).
2022-03-08 15:03:03 -07:00
Andrew Kelley
874b51d8d4 LLVM: add debug info for opaque, vector, and tuples
Also fix UAF of Type memory in the di_type_map.
2022-03-08 14:58:54 -07:00
Andrew Kelley
1046ead0cc LLVM: no longer store args into alloca instructions
Previously, we did this so that we could insert a debug variable
declaration intrinsic on the alloca. But there is a dbg.value intrinsic
for declaring variables that are values.
2022-03-08 14:58:53 -07:00
Andrew Kelley
7cea8f063f LLVM: add debug info for parameters 2022-03-08 14:58:53 -07:00
Andrew Kelley
ba566eed76 LLVM: fix not handling dbg_stmt relative line
Also make `namespaceToDebugScope` behave correctly for file-level
structs. Instead of being inside their own scope, they use the file
scope.
2022-03-08 14:58:53 -07:00
Andrew Kelley
3654ec8770 LLVM: add debug type lowering for ptr, slice, opaque, optional
also fix issue with memoization and recursiveness.
2022-03-08 14:58:53 -07:00
Andrew Kelley
40c0bdd385 LLVM: memoize debug types and add enum debug types 2022-03-08 14:58:53 -07:00
Andrew Kelley
0d24bc7da0 LLVM: add DISubprogram and DIType lowering; handle dbg_stmt 2022-03-08 14:58:53 -07:00
Andrew Kelley
c6160fa3a5 LLVM: add compile unit to debug info
This commit also adds a bunch of bindings for debug info.
2022-03-08 14:58:53 -07:00
Andrew Kelley
71b8760d3b stage2: rework @mulAdd
* mul_add AIR instruction: use `pl_op` instead of `ty_pl`. The type is
   always the same as the operand; no need to waste bytes redundantly
   storing the type.
 * AstGen: use coerced_ty for all the operands except for one which we
   use to communicate the type.
 * Sema: use the correct source location for requireRuntimeBlock in
   handling of `@mulAdd`.
 * native backends: handle liveness even for the functions that are
   TODO.
 * C backend: implement `@mulAdd`. It lowers to libc calls.
 * LLVM backend: make `@mulAdd` handle all float types.
   - improved fptrunc and fpext to handle f80 with compiler-rt calls.
 * Value.mulAdd: handle all float types and use the `@mulAdd` builtin.
 * behavior tests: revert the changes to testing `@mulAdd`. These
   changes broke the test coverage, making it only tested at
   compile-time.

Improved f80 support:
 * std.math.fma handles f80
 * move fma functions from freestanding libc to compiler-rt
   - add __fmax and fmal
   - make __fmax and fmaq only exported when they don't alias fmal.
   - make their linkage weak just like the rest of compiler-rt symbols.
 * removed `longDoubleIsF128` and replaced it with `longDoubleIs` which
   takes a type as a parameter. The implementation is now more accurate
   and handles more targets. Similarly, in stage2 the function
   CTypes.sizeInBits is more accurate for long double for more targets.
2022-03-06 16:11:39 -07:00
John Schmidt
6637335981 stage2: implement @mulAdd for scalar floats 2022-03-06 15:36:56 -07:00
Luuk de Gram
6d84f22fa0 stage2: Fix wasm linker for llvm backend
This fixes 2 entrypoints within the self-hosted wasm linker that would be called
for the llvm backend, whereas we should simply call into the llvm backend to perform such action.
i.e. not allocate a decl index when we have an llvm object, and when flushing a module,
we should be calling it on llvm's object, rather than have the wasm linker perform the operation.

Also, this fixes the wasm intrinsics for wasm.memory.size and wasm.memory.grow.
Lastly, this commit ensures that when an extern function is being resolved, we tell LLVM how
to import such function.
2022-03-06 14:17:36 -05:00
Andrew Kelley
e532b0c0b5 stage2: cleanups to wasm memory intrinsics
* AIR: use pl_op instead of ty_pl for wasm_memory_size. No need to
   store the type because the type is always `u32`.
 * AstGen: use coerced_ty for `@wasmMemorySize` and `@wasmMemoryGrow`
   and do the coercions in Sema.
 * Sema: use more accurate source locations for errors.
 * Provide more information in the compiler error message.
 * Codegen: use liveness data to avoid lowering unused
   `@wasmMemorySize`.
 * LLVM backend: add implementation
   - I wasn't able to test it because we are hitting a linker error for
     `-target wasm32-wasi -fLLVM`.
 * C backend: use `zig_unimplemented()` instead of silently doing wrong
   behavior for these builtins.
 * behavior tests: branch only on stage2_arch for inclusion of the
   wasm.zig file. We would change it to `builtin.cpu.arch` but that is
   causing a compiler crash on some backends.
2022-03-03 18:31:55 -07:00
Luuk de Gram
21f0503c01 Update behavior tests 2022-03-03 16:33:46 -07:00
Luuk de Gram
43cb19ea4d wasm: Implement @wasmMemoryGrow builtin
Similarly to the other wasm builtin, this implements the grow variation where the memory
index is a comptime known value. The operand as well as the result are runtime values.
This also verifies during semantic analysis the target we're building for is wasm, or else
emits a compilation error. This means that other backends do not have to handle this AIR instruction,
other than the wasm and LLVM backends.
2022-03-03 16:33:46 -07:00
Luuk de Gram
ec4c30ae48 wasm: Implement @wasmMemorySize() builtin
This implements the `wasmMemorySize` builtin, in Sema and the Wasm backend.
The Stage2 implementation differs from stage1 in the way that `index` must be a comptime value.
The stage1 variant is incorrect, as the index is part of the instruction encoding, and therefore,
cannot be a runtime value.
2022-03-03 16:33:46 -07:00
Cody Tapscott
85610a9aff stage2 llvm: Lower 0-bit field-ptr as ptr-to-void 2022-03-03 13:08:14 -07:00
Andrew Kelley
b33f3b23c9 LLVM: fix lowering of unions and switches
`Module.Union.getLayout` now additionally returns a `padding` field
which tells how many bytes are between the final field end offset and
the ending offset of the union. This is used by the LLVM backend to
explicitly insert padding.

LLVM backend: lowering of unions now inserts additional padding so that
LLVM's internals will agree on the ABI size to match what ABI size zig
wants unions to be. This is an alternative to calling LLVMABISizeOfType
and LLVMABIAlignmentOfType which end up crashing when recursive struct
definitions come into play. We no longer ever call these two functions
and the bindings are deleted to avoid future footgun firings.

LLVM backend: lowering of unions now represents untagged unions
consistently. Before it was tripping an assertion.

LLVM backend: switch cases call inttoptr on the case items and condition
if necessary. Prevents tripping an LLVM assertion.

After this commit, we are no longer tripping over any LLVM assertions.
2022-03-03 01:19:49 -07:00
Andrew Kelley
220708e7c3 LLVM: aggregate_init supports structs
in addition to tuples
2022-03-02 13:35:15 -07:00