diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-07-14 18:27:51 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-07-14 18:27:51 -0400 |
| commit | 4d920cee6e8be2f2ae2cfd9067358c65b977568a (patch) | |
| tree | 2c04de6151b7448dec9958d0a91234ea0ba9a15d /src-self-hosted/codegen.zig | |
| parent | da3acacc14331a6be33445c3bfd204e2cccabddd (diff) | |
| parent | 28c3d4809bc6d497ac81892bc7eb03b95d8c2b32 (diff) | |
| download | zig-4d920cee6e8be2f2ae2cfd9067358c65b977568a.tar.gz zig-4d920cee6e8be2f2ae2cfd9067358c65b977568a.zip | |
Merge remote-tracking branch 'origin/master' into llvm7
Diffstat (limited to 'src-self-hosted/codegen.zig')
| -rw-r--r-- | src-self-hosted/codegen.zig | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig new file mode 100644 index 0000000000..a07485e74e --- /dev/null +++ b/src-self-hosted/codegen.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +const Compilation = @import("compilation.zig").Compilation; +// we go through llvm instead of c for 2 reasons: +// 1. to avoid accidentally calling the non-thread-safe functions +// 2. patch up some of the types to remove nullability +const llvm = @import("llvm.zig"); +const ir = @import("ir.zig"); +const Value = @import("value.zig").Value; +const Type = @import("type.zig").Type; +const event = std.event; + +pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) !void { + fn_val.base.ref(); + defer fn_val.base.deref(comp); + defer code.destroy(comp.a()); + + const llvm_handle = try comp.event_loop_local.getAnyLlvmContext(); + defer llvm_handle.release(comp.event_loop_local); + + const context = llvm_handle.node.data; + + const module = llvm.ModuleCreateWithNameInContext(comp.name.ptr(), context) orelse return error.OutOfMemory; + defer llvm.DisposeModule(module); + + const builder = llvm.CreateBuilderInContext(context) orelse return error.OutOfMemory; + defer llvm.DisposeBuilder(builder); + + var ofile = ObjectFile{ + .comp = comp, + .module = module, + .builder = builder, + .context = context, + .lock = event.Lock.init(comp.loop), + }; + + try renderToLlvmModule(&ofile, fn_val, code); + + if (comp.verbose_llvm_ir) { + llvm.DumpModule(ofile.module); + } +} + +pub const ObjectFile = struct { + comp: *Compilation, + module: llvm.ModuleRef, + builder: llvm.BuilderRef, + context: llvm.ContextRef, + lock: event.Lock, + + fn a(self: *ObjectFile) *std.mem.Allocator { + return self.comp.a(); + } +}; + +pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code) !void { + // TODO audit more of codegen.cpp:fn_llvm_value and port more logic + const llvm_fn_type = try fn_val.base.typeof.getLlvmType(ofile); + const llvm_fn = llvm.AddFunction(ofile.module, fn_val.symbol_name.ptr(), llvm_fn_type); +} |
