29 Commits

Author SHA1 Message Date
Andrew Kelley
7efca2e6f5 Merge remote-tracking branch 'origin/master' into llvm13 2021-08-31 18:44:15 -07:00
Meghan
50c6b6cc66
stage2: only initialize the llvm backend for the target we are building (#9659) 2021-08-31 13:50:09 -04:00
Andrew Kelley
6aeab0f323 Merge remote-tracking branch 'origin/master' into llvm13
Conflicts:
   lib/libcxx/include/__config

d57c0cc3bfeff9af297279759ec2b631e6d95140 added support for DragonFlyBSD
to libc++ by updating some ifdefs. This needed to be synced with llvm13.
2021-08-28 12:41:24 -07:00
Jacob G-W
2e6ce11eb2 stage2: implement shr and boilerplate for shl
This implements it in the llvm and c backends.
x86_64 will have to be a little more work.
2021-08-19 16:18:40 -04:00
Andrew Kelley
2f599b655b update src/ to LLVM 13 rc1 API 2021-08-16 01:11:10 -07:00
Andrew Kelley
6eecc4af99 stage2 llvm backend: implement const inttoptr 2021-08-12 10:48:54 -07:00
Andrew Kelley
f81b2531cb stage2: pass some pointer tests
* New AIR instructions: ptr_add, ptr_sub, ptr_elem_val, ptr_ptr_elem_val
   - See the doc comments for details.
 * Sema: implement runtime pointer arithmetic.
 * Sema: implement elem_val for many-pointers.
 * Sema: support coercion from `*[N:s]T` to `[*]T`.
 * Type: isIndexable handles many-pointers.
2021-08-07 15:46:53 -07:00
Andrew Kelley
ede76f4fe3 stage2: fix generics with non-comptime anytype parameters
The `comptime_args` field of Fn has a clarified purpose:
For generic function instantiations, there is a `TypedValue` here
for each parameter of the function:
 * Non-comptime parameters are marked with a `generic_poison` for the value.
 * Non-anytype parameters are marked with a `generic_poison` for the type.

Sema now has a `fn_ret_ty` field. Doc comments reproduced here:
> When semantic analysis needs to know the return type of the function whose body
> is being analyzed, this `Type` should be used instead of going through `func`.
> This will correctly handle the case of a comptime/inline function call of a
> generic function which uses a type expression for the return type.
> The type will be `void` in the case that `func` is `null`.
Various places in Sema are modified in accordance with this guidance.

Fixed `resolveMaybeUndefVal` not returning `error.GenericPoison` when
Value Tag of `generic_poison` is encountered.

Fixed generic function memoization incorrect equality checking. The
logic now clearly deals properly with any combination of anytype and
comptime parameters.

Fixed not removing generic function instantiation from the table in case
a compile errors in the rest of `call` semantic analysis. This required
introduction of yet another adapter which I have called
`GenericRemoveAdapter`. This one is nice and simple - it's the same hash
function (the same precomputed hash is passed in) but the equality
function checks pointers rather than doing any logic.

Inline/comptime function calls coerce each argument in accordance with
the function parameter type expressions. Likewise the return type
expression is evaluated and provided (see `fn_ret_ty` above).

There's a new compile error "unable to monomorphize function". It's
pretty unhelpful and will need to get improved in the future. It happens
when a type expression in a generic function did not end up getting
resolved at a callsite. This can happen, for example, if a runtime
parameter is attempted to be used where it needed to be comptime known:

```zig
fn foo(x: anytype) [x]u8 { _ = x; }
```

In this example, even if we pass a number such as `10` for `x`, it is
not marked `comptime`, so `x` will have a runtime known value, making
the return type unable to resolve.

In the LLVM backend I implement cmp instructions for float types to pass
some behavior tests that used floats.
2021-08-06 16:24:39 -07:00
Andrew Kelley
c03a04a589 stage2: return type expressions of generic functions
* ZIR encoding for function instructions have a body for the return
   type. This lets Sema for generic functions do the same thing it does
   for parameters, handling `error.GenericPoison` in the evaluation of
   the return type by marking the function as generic.

 * Sema: fix missing block around the new Decl arena finalization. This
   led to a memory corruption.

 * Added some floating point support to the LLVM backend but didn't get
   far enough to pass any new tests.
2021-08-05 19:19:19 -07:00
Andrew Kelley
ddf14323ea stage2: implement @truncate 2021-08-01 16:13:58 -07:00
Andrew Kelley
a5c6e51f03 stage2: more principled approach to comptime references
* AIR no longer has a `variables` array. Instead of the `varptr`
   instruction, Sema emits a constant with a `decl_ref`.
 * AIR no longer has a `ref` instruction. There is no longer any
   instruction that takes a value and returns a pointer to it. If this
   is desired, Sema must either create an anynomous Decl and return a
   constant `decl_ref`, or in the case of a runtime value, emit an
   `alloc` instruction, `store` the value to it, and then return the
   `alloc`.
 * The `ref_val` Value Tag is eliminated. `decl_ref` should be used
   instead. Also added is `eu_payload_ptr` which points to the payload
   of an error union, given an error union pointer.

In general, Sema should avoid calling `analyzeRef` if it can be helped.
For example in the case of field_val and elem_val, there should never be
a reason to create a temporary (alloc or decl). Recent previous commits
made progress along that front.

There is a new abstraction in Sema, which looks like this:

    var anon_decl = try block.startAnonDecl();
    defer anon_decl.deinit();
    // here 'anon_decl.arena()` may be used
    const decl = try anon_decl.finish(ty, val);
    // decl is typically now used with `decl_ref`.

This pattern is used to upgrade `ref_val` usages to `decl_ref` usages.

Additional improvements:

 * Sema: fix source location resolution for calling convention
   expression.
 * Sema: properly report "unable to resolve comptime value" for loads of
   global variables. There is now a set of functions which can be
   called if the callee wants to obtain the Value even if the tag is
   `variable` (indicating comptime-known address but runtime-known value).
 * Sema: `coerce` resolves builtin types before checking equality.
 * Sema: fix `u1_type` missing from `addType`, making this type have a
   slightly more efficient representation in AIR.
 * LLVM backend: fix `genTypedValue` for tags `decl_ref` and `variable`
   to properly do an LLVMConstBitCast.
 * Remove unused parameter from `Value.toEnum`.

After this commit, some test cases are no longer passing. This is due to
the more principled approach to comptime references causing more
anonymous decls to get sent to the linker for codegen. However, in all
these cases the decls are not actually referenced by the runtime machine
code. A future commit in this branch will implement garbage collection
of decls so that unused decls do not get sent to the linker for codegen.
This will make the tests go back to passing.
2021-07-29 15:59:51 -07:00
Andrew Kelley
66e5920dc3 llvm backend: LLVMGetNamedGlobalAlias requires a null terminated string 2021-07-27 15:47:25 -07:00
Andrew Kelley
a8e964eadd stage2: zig test now works with the LLVM backend
Frontend improvements:

 * When compiling in `zig test` mode, put a task on the work queue to
   analyze the main package root file. Normally, start code does
   `_ = import("root");` to make Zig analyze the user's code, however in
   the case of `zig test`, the root source file is the test runner.
   Without this change, no tests are picked up.
 * In the main pipeline, once semantic analysis is finished, if there
   are no compile errors, populate the `test_functions` Decl with the
   set of test functions picked up from semantic analysis.
 * Value: add `array` and `slice` Tags.

LLVM backend improvements:

 * Fix incremental updates of globals. Previously the
   value of a global would not get replaced with a new value.
 * Fix LLVM type of arrays. They were incorrectly sending
   the ABI size as the element count.
 * Remove the FuncGen parameter from genTypedValue. This function is for
   generating global constants and there is no function available when
   it is being called.
   - The `ref_val` case is now commented out. I'd like to eliminate
     `ref_val` as one of the possible Value Tags. Instead it should
     always be done via `decl_ref`.
 * Implement constant value generation for slices, arrays, and structs.
 * Constant value generation for functions supports the `decl_ref` tag.
2021-07-27 14:19:53 -07:00
Andrew Kelley
31a59c229c stage2: improvements towards zig test
* Add AIR instruction: struct_field_val
   - This is part of an effort to eliminate the AIR instruction `ref`.
   - It's implemented for C backend and LLVM backend so far.
 * Rename `resolvePossiblyUndefinedValue` to `resolveMaybeUndefVal` just
   to save some columns on long lines.
 * Sema: add `fieldVal` alongside `fieldPtr` (renamed from
   `namedFieldPtr`). This is part of an effort to eliminate the AIR
   instruction `ref`. The idea is to avoid unnecessary loads, stores,
   stack usage, and IR instructions, by paying a DRY cost.

LLVM backend improvements:

 * internal linkage vs exported linkage is implemented, along with
   aliases. There is an issue with incremental updates due to missing
   LLVM API for deleting aliases; see the relevant comment in this commit.
   - `updateDeclExports` is hooked up to the LLVM backend now.
 * Fix usage of `Type.tag() == .noreturn` rather than calling `isNoReturn()`.
 * Properly mark global variables as mutable/constant.
 * Fix llvm type generation of function pointers
 * Fix codegen for calls of function pointers
 * Implement llvm type generation of error unions and error sets.
 * Implement AIR instructions: addwrap, subwrap, mul, mulwrap, div,
   bit_and, bool_and, bit_or, bool_or, xor, struct_field_ptr,
   struct_field_val, unwrap_errunion_err, add for floats, sub for
   floats.

After this commit, `zig test` on a file with `test "example" {}`
correctly generates and executes a test binary. However the
`test_functions` slice is undefined and just happens to be going into
the .bss section, causing the length to be 0. The next step towards
`zig test` will be replacing the `test_functions` Decl Value with the
set of test function pointers, before it is sent to linker/codegen.
2021-07-26 19:27:49 -07:00
Andrew Kelley
14d8a1c10d stage2 llvm backend improvements working towards zig test
* properly set global variables to const if they are not a global
   variable.
 * implement global variable initializations.
 * initial implementation of llvmType() for structs and functions.
 * implement genTypedValue for variable tags
 * implement more AIR instructions: varptr, slice_ptr, slice_len,
   slice_elem_val, ptr_slice_elem_val, unwrap_errunion_payload,
   unwrap_errunion_payload_ptr, unwrap_errunion_err,
   unwrap_errunion_err_ptr.
2021-07-25 22:38:50 -07:00
Andrew Kelley
c3d10dbda1 stage2 llvm backend: implement llvmType for error union and slices 2021-07-25 19:06:48 -07:00
Andrew Kelley
b87105c921 stage2 llvm backend: implement assembly and ptrtoint
These AIR instructions are the next blockers for `zig test` to work for
this backend.

After this commit, the "hello world" x86_64 test case passes for the
LLVM backend as well.
2021-07-24 23:54:20 -07:00
Andrew Kelley
a5fb28070f add -femit-llvm-bc CLI option and implement it
* Added doc comments for `std.Target.ObjectFormat` enum
 * `std.Target.oFileExt` is removed because it is incorrect for Plan-9
   targets. Instead, use `std.Target.ObjectFormat.fileExt` and pass a
   CPU architecture.
 * Added `Compilation.Directory.joinZ` for when a null byte is desired.
 * Improvements to `Compilation.create` logic for computing `use_llvm`
   and reporting errors in contradictory flags. `-femit-llvm-ir` and
   `-femit-llvm-bc` will now imply `-fLLVM`.
 * Fix compilation when passing `.bc` files on the command line.
 * Improvements to the stage2 LLVM backend:
   - cleaned up error messages and error reporting. Properly bubble up
     some errors rather than dumping to stderr; others turn into panics.
   - properly call ZigLLVMCreateTargetMachine and
     ZigLLVMTargetMachineEmitToFile and implement calculation of the
     respective parameters (cpu features, code model, abi name, lto,
     tsan, etc).
   - LLVM module verification only runs in debug builds of the compiler
   - use LLVMDumpModule rather than printToString because in the case
     that we incorrectly pass a null pointer to LLVM it may crash during
     dumping the module and having it partially printed is helpful in
     this case.
   - support -femit-asm, -fno-emit-bin, -femit-llvm-ir, -femit-llvm-bc
   - Support LLVM backend when used with Mach-O and WASM linkers.
2021-07-22 19:51:32 -07:00
Jakub Konka
0e15205521 Remove mention of lldMachO from the project
including:
* finding lldMachO in CMake config
* punting `ld64.lld` to LLD linker
* providing bindings to LLD linker
2021-06-29 23:38:19 +02:00
Veikka Tuominen
e63ff4f1c1 add ast-check flag to zig fmt, fix found bugs 2021-06-14 00:16:40 +03:00
Andrew Kelley
b85ef2300f Merge remote-tracking branch 'origin/master' into llvm12 2021-03-28 21:42:56 -07:00
Tadeo Kondrak
e8aa6f90d6
stage2 llvm bindings: use correct type for LLVMBool for ABI compat 2021-03-16 17:05:36 -06:00
Tadeo Kondrak
277b01a089
stage2 llvm bindings: rename LLVMBool to Bool 2021-03-14 22:32:26 -06:00
Andrew Kelley
bccef44196 Merge remote-tracking branch 'origin/master' into llvm12
Syncing with master branch because I want to re-run
update_clang_options.zig in the llvm12 branch.
2021-03-04 18:23:11 -07:00
Timon Kruiper
d4ec0279d3 stage2: add support for optionals in the LLVM backend
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-03-02 19:02:55 -07:00
Andrew Kelley
0b58b61799 Merge remote-tracking branch 'origin/master' into llvm12
Conflicts:
 * src/clang.zig
 * src/llvm.zig
   - this file got moved to src/llvm/bindings.zig in master branch so I
     had to put the new LLVM arch/os enum tags into it.
 * lib/std/target.zig, src/stage1/target.cpp
   - haiku had an inconsistency with its default target ABI, gnu vs
     eabi. In this commit we make it gnu in both places to match the
     latest changes by @hoanga.
 * src/translate_c.zig
2021-02-25 21:04:23 -07:00
Andrew Kelley
0d4b6ac741 add LTO support
The CLI gains -flto and -fno-lto options to override the default.
However, the cool thing about this is that the defaults are great! In
general when you use build-exe in release mode, Zig will enable LTO if
it would work and it would help.

zig cc supports detecting and honoring the -flto and -fno-lto flags as
well. The linkWithLld functions are improved to all be the same with
regards to copying the artifact instead of trying to pass single objects
through LLD with -r. There is possibly a future improvement here as
well; see the respective TODOs.

stage1 is updated to support outputting LLVM bitcode instead of machine
code when lto is enabled. This allows LLVM to optimize across the Zig and
C/C++ code boundary.

closes #2845
2021-01-23 18:18:07 -07:00
Timon Kruiper
56c059077c stage2: add initial impl of control flow in LLVM backend
The following TZIR instrutions have been implemented in the backend:
- all cmp operators (lt, lte, gt, gte, eq, neq)
- block
- br
- condbr

The following LLVMIR is generated for a simple assert function:
```
define void @assert(i1 %0) {
Entry:
  %1 = alloca i1, align 1
  store i1 %0, i1* %1, align 1
  %2 = load i1, i1* %1, align 1
  %3 = xor i1 %2, true
  br i1 %3, label %Then, label %Else

Then:                                             ; preds = %Entry
  call void @llvm.debugtrap()
  unreachable

Else:                                             ; preds = %Entry
  br label %Block

Block:                                            ; preds = %Else
  ret void
}
```

See tests for more examples.
2021-01-08 19:30:52 +01:00
Timon Kruiper
b1cfa923be stage2: rename and move files related to LLVM backend 2021-01-06 10:52:20 +01:00