aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.zig
AgeCommit message (Collapse)Author
2021-01-06stage2: rename and move files related to LLVM backendTimon Kruiper
2021-01-06stage2: make use of `llvm.Context` in LLVM backendTimon Kruiper
This for example allows for multiple LLVM instances to run in parallel. Also rename some functions in llvm_bindings.zig. Fixes #7688
2021-01-06stage2: hoist alloca instructions to top of function in LLVM backendTimon Kruiper
This way the generated code only has to setup the stack size at the beginning of a function and this improves codegen. Fixes #7689 ``` fn foo() void {} export fn hello(z: i8) void { var x: i16 = undefined; foo(); var y: i32 = 1; y += z; } ``` llvm-ir: ``` define void @hello(i8 %0) { Entry: %1 = alloca i8, align 1 %2 = alloca i16, align 2 %3 = alloca i32, align 4 store i8 %0, i8* %1, align 1 %4 = load i8, i8* %1, align 1 store i16 undef, i16* %2, align 2 call void @foo() store i32 1, i32* %3, align 4 %5 = load i32, i32* %3, align 4 %6 = sext i8 %4 to i32 %7 = add nsw i32 %5, %6 store i32 %7, i32* %3, align 4 ret void } ```
2021-01-06stage2: rename `*const llvm.ValueRef` to `*const llvm.Value` in LLVM backendTimon Kruiper
The same has been done for all the other LLVM types.
2021-01-06stage2: add initial impl for generating global decls in LLVM backendTimon Kruiper
Also adds support for extern functions, simple pointer and simple array types and values. A simple hello world now compiles: `zig build-exe example.zig -fLLVM -lc` ``` extern fn puts(s: [*:0]const u8) c_int; export fn main() c_int { _ = puts("hello world!"); return 0; } ```
2021-01-03stage2: Output the LLVM object files in the cache directoryTimon Kruiper
Also make sure to properly free everything.
2021-01-03stage2: add support for integers in LLVM backendTimon Kruiper
Also adds support for simple operators, like add and subtract. The intcast and bitcast instruction also have been implemented. Linking with libc also works, so we can now generate working executables! `zig build-exe example.zig -fLLVM -lc`: ``` fn add(a: i32, b: i32) i32 { return a + b; } export fn main() c_int { var a: i32 = -5; const x = add(a, 7); var y = add(2, 0); y -= x; return y; } ```
2021-01-03stage2: make use of proper LLVM intrinsic APIs in LLVM backendTimon Kruiper
2021-01-03stage2: implement argument passing and returning in LLVM backendTimon Kruiper
Furthermore add the Not instruction. The following now works: ``` export fn _start() noreturn { var x: bool = true; var other: bool = foo(x); exit(); } fn foo(cond: bool) bool { return !cond; } fn exit() noreturn { unreachable; } ```
2021-01-03stage2: Add code generation for Load instruction in LLVM backendTimon Kruiper
The following now works: ``` export fn _start() noreturn { var x: bool = true; var y: bool = x; exit(); } fn exit() noreturn { unreachable; } ```
2021-01-03stage2: implement register allocation in LLVM self-hosted backendTimon Kruiper
A HashMap has been added which store the LLVM values used in a function. Together with the alloc and store instructions the following now works: ``` export fn _start() noreturn { var x: bool = true; exit(); } fn exit() noreturn { unreachable; } ```
2021-01-03stage2: clear `err_msg` after it has been added to `module.failed_decls`Timon Kruiper
2021-01-02stage2: re-use ZIR for comptime and inline callsAndrew Kelley
Instead of freeing ZIR after semantic analysis, we keep it around so that it can be used for comptime calls, inline calls, and generic function calls. ZIR memory is now managed by the Decl arena. Debug dump() functions are conditionally compiled; only available in Debug builds of the compiler. Add a test for an inline function call.
2021-01-02stage2: implement function call inlining in the frontendAndrew Kelley
* remove the -Ddump-zir thing. that's handled through --verbose-ir * rework Fn to have an is_inline flag without requiring any more memory on the heap per function. * implement a rough first version of dumping typed zir (tzir) which is a lot more helpful for debugging than what we had before. We don't have a way to parse it though. * keep track of whether the inline-ness of a function changes because if it does we have to go update callsites. * add compile error for inline and export used together. inline function calls and comptime function calls are implemented the same way. A block instruction is set up to capture the result, and then a scope is set up that has a flag for is_comptime and some state if the scope is being inlined. when analyzing `ret` instructions, zig looks for inlining state in the scope, and if found, treats `ret` as a `break` instruction instead, with the target block being the one set up at the inline callsite. Follow-up items: * Complete out the debug TZIR dumping code. * Don't redundantly generate ZIR for each inline/comptime function call. Instead we should add a new state enum tag to Fn. * comptime and inlining branch quotas. * Add more test cases.
2021-01-02Remove some unwanted changesLemonBoy
Leftovers after a long rebase.
2020-12-30stage2: rework Value Payload layoutAndrew Kelley
This is the same as the previous commit but for Value instead of Type. Add `Value.castTag` and note that it is preferable to call than `Value.cast`. This matches other abstractions in the codebase. Added a convenience function `Value.Tag.create` which really cleans up the callsites of creating `Value` objects. `Value` tags can now share payload types. This is in preparation for another improvement that I want to do.
2020-12-28stage2: add initial implementation of func arguments in LLVM backendTimon Kruiper
The following works: ``` export fn _start() noreturn { assert(true); exit(); } fn assert(cond: bool) void {} fn exit() noreturn { unreachable; } ```
2020-12-28stage2: refactor (simplify) code structure of `llvm_backend.zig`Timon Kruiper
2020-12-28stage2: add initial impl of LLVM backend in self-hosted compilerTimon Kruiper