self-hosted: adding a fn to an llvm module
This commit is contained in:
61
src-self-hosted/codegen.zig
Normal file
61
src-self-hosted/codegen.zig
Normal file
@@ -0,0 +1,61 @@
|
||||
const std = @import("std");
|
||||
// TODO codegen pretends that Module is renamed to Build because I plan to
|
||||
// do that refactor at some point
|
||||
const Build = @import("module.zig").Module;
|
||||
// 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(build: *Build, fn_val: *Value.Fn, code: *ir.Code) !void {
|
||||
fn_val.base.ref();
|
||||
defer fn_val.base.deref(build);
|
||||
defer code.destroy(build.a());
|
||||
|
||||
const llvm_handle = try build.event_loop_local.getAnyLlvmContext();
|
||||
defer llvm_handle.release(build.event_loop_local);
|
||||
|
||||
const context = llvm_handle.node.data;
|
||||
|
||||
const module = llvm.ModuleCreateWithNameInContext(build.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 cunit = CompilationUnit{
|
||||
.build = build,
|
||||
.module = module,
|
||||
.builder = builder,
|
||||
.context = context,
|
||||
.lock = event.Lock.init(build.loop),
|
||||
};
|
||||
|
||||
try renderToLlvmModule(&cunit, fn_val, code);
|
||||
|
||||
if (build.verbose_llvm_ir) {
|
||||
llvm.DumpModule(cunit.module);
|
||||
}
|
||||
}
|
||||
|
||||
pub const CompilationUnit = struct {
|
||||
build: *Build,
|
||||
module: llvm.ModuleRef,
|
||||
builder: llvm.BuilderRef,
|
||||
context: llvm.ContextRef,
|
||||
lock: event.Lock,
|
||||
|
||||
fn a(self: *CompilationUnit) *std.mem.Allocator {
|
||||
return self.build.a();
|
||||
}
|
||||
};
|
||||
|
||||
pub fn renderToLlvmModule(cunit: *CompilationUnit, 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(cunit);
|
||||
const llvm_fn = llvm.AddFunction(cunit.module, fn_val.symbol_name.ptr(), llvm_fn_type);
|
||||
}
|
||||
Reference in New Issue
Block a user