diff --git a/src/llvm_backend.zig b/src/llvm_backend.zig index dbfe182eed..7adf15ae54 100644 --- a/src/llvm_backend.zig +++ b/src/llvm_backend.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const assert = std.debug.assert; const Allocator = std.mem.Allocator; const Compilation = @import("Compilation.zig"); const llvm = @import("llvm_bindings.zig"); @@ -433,15 +434,20 @@ pub const LLVMIRModule = struct { } fn genBreakpoint(self: *LLVMIRModule, inst: *Inst.NoOp) !?*const llvm.ValueRef { - // TODO: Store this function somewhere such that we dont have to add it again - const fn_type = llvm.TypeRef.functionType(llvm.voidType(), null, 0, false); - const func = self.llvm_module.addFunction("llvm.debugtrap", fn_type); - - // TODO: add assertion: LLVMGetIntrinsicID - _ = self.builder.buildCall(func, null, 0, ""); + const llvn_fn = self.getIntrinsic("llvm.debugtrap"); + _ = self.builder.buildCall(llvn_fn, null, 0, ""); return null; } + fn getIntrinsic(self: *LLVMIRModule, name: []const u8) *const llvm.ValueRef { + const id = llvm.lookupIntrinsicID(name.ptr, name.len); + assert(id != 0); + // TODO: add support for overload intrinsics by passing the prefix of the intrinsic + // to `lookupIntrinsicID` and then passing the correct types to + // `getIntrinsicDeclaration` + return self.llvm_module.getIntrinsicDeclaration(id, null, 0); + } + fn resolveInst(self: *LLVMIRModule, inst: *ir.Inst) !*const llvm.ValueRef { if (inst.castTag(.constant)) |const_inst| { return self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val }); @@ -514,7 +520,7 @@ pub const LLVMIRModule = struct { pub fn fail(self: *LLVMIRModule, src: usize, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @setCold(true); - std.debug.assert(self.err_msg == null); + assert(self.err_msg == null); self.err_msg = try Compilation.ErrorMsg.create(self.gpa, src, format, args); return error.CodegenFail; } diff --git a/src/llvm_bindings.zig b/src/llvm_bindings.zig index f6d53c75ba..9198cc714b 100644 --- a/src/llvm_bindings.zig +++ b/src/llvm_bindings.zig @@ -63,10 +63,16 @@ pub const ModuleRef = opaque { pub const getNamedFunction = LLVMGetNamedFunction; extern fn LLVMGetNamedFunction(*const ModuleRef, Name: [*:0]const u8) ?*const ValueRef; + pub const getIntrinsicDeclaration = LLVMGetIntrinsicDeclaration; + extern fn LLVMGetIntrinsicDeclaration(Mod: *const ModuleRef, ID: c_uint, ParamTypes: ?[*]*const TypeRef, ParamCount: usize) *const ValueRef; + pub const printToString = LLVMPrintModuleToString; extern fn LLVMPrintModuleToString(*const ModuleRef) [*:0]const u8; }; +pub const lookupIntrinsicID = LLVMLookupIntrinsicID; +extern fn LLVMLookupIntrinsicID(Name: [*]const u8, NameLen: usize) c_uint; + pub const disposeMessage = LLVMDisposeMessage; extern fn LLVMDisposeMessage(Message: [*:0]const u8) void;