aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted/codegen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-07-14 18:27:51 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-07-14 18:27:51 -0400
commit4d920cee6e8be2f2ae2cfd9067358c65b977568a (patch)
tree2c04de6151b7448dec9958d0a91234ea0ba9a15d /src-self-hosted/codegen.zig
parentda3acacc14331a6be33445c3bfd204e2cccabddd (diff)
parent28c3d4809bc6d497ac81892bc7eb03b95d8c2b32 (diff)
downloadzig-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.zig59
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);
+}