diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 24 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 51 | ||||
| -rw-r--r-- | src/codegen/wasm.zig | 1 |
3 files changed, 42 insertions, 34 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index a8ec677753..826b73317c 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -262,6 +262,7 @@ pub const DeclGen = struct { .one => try writer.writeAll("1"), .decl_ref => { const decl = val.castTag(.decl_ref).?.data; + decl.alive = true; // Determine if we must pointer cast. assert(decl.has_tv); @@ -281,21 +282,7 @@ pub const DeclGen = struct { const decl = val.castTag(.extern_fn).?.data; try writer.print("{s}", .{decl.name}); }, - else => switch (t.ptrSize()) { - .Slice => unreachable, - .Many => unreachable, - .One => { - var arena = std.heap.ArenaAllocator.init(dg.module.gpa); - defer arena.deinit(); - - const elem_ty = t.elemType(); - const elem_val = try val.pointerDeref(&arena.allocator); - - try writer.writeAll("&"); - try dg.renderValue(writer, elem_ty, elem_val); - }, - .C => unreachable, - }, + else => unreachable, }, }, .Array => { @@ -421,6 +408,7 @@ pub const DeclGen = struct { .one => try writer.writeAll("1"), .decl_ref => { const decl = val.castTag(.decl_ref).?.data; + decl.alive = true; // Determine if we must pointer cast. assert(decl.has_tv); @@ -433,11 +421,13 @@ pub const DeclGen = struct { } }, .function => { - const func = val.castTag(.function).?.data; - try writer.print("{s}", .{func.owner_decl.name}); + const decl = val.castTag(.function).?.data.owner_decl; + decl.alive = true; + try writer.print("{s}", .{decl.name}); }, .extern_fn => { const decl = val.castTag(.extern_fn).?.data; + decl.alive = true; try writer.print("{s}", .{decl.name}); }, else => unreachable, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 0e9a572bea..961ed7ee99 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -673,17 +673,21 @@ pub const DeclGen = struct { } fn genTypedValue(self: *DeclGen, tv: TypedValue) error{ OutOfMemory, CodegenFail }!*const llvm.Value { - const llvm_type = try self.llvmType(tv.ty); - - if (tv.val.isUndef()) + if (tv.val.isUndef()) { + const llvm_type = try self.llvmType(tv.ty); return llvm_type.getUndef(); + } switch (tv.ty.zigTypeTag()) { - .Bool => return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(), + .Bool => { + const llvm_type = try self.llvmType(tv.ty); + return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(); + }, .Int => { var bigint_space: Value.BigIntSpace = undefined; const bigint = tv.val.toBigInt(&bigint_space); + const llvm_type = try self.llvmType(tv.ty); if (bigint.eqZero()) return llvm_type.constNull(); if (bigint.limbs.len != 1) { @@ -698,12 +702,17 @@ pub const DeclGen = struct { .Pointer => switch (tv.val.tag()) { .decl_ref => { const decl = tv.val.castTag(.decl_ref).?.data; + decl.alive = true; const val = try self.resolveGlobalDecl(decl); + const llvm_type = try self.llvmType(tv.ty); return val.constBitCast(llvm_type); }, .variable => { - const variable = tv.val.castTag(.variable).?.data; - const val = try self.resolveGlobalDecl(variable.owner_decl); + const decl = tv.val.castTag(.variable).?.data.owner_decl; + decl.alive = true; + const val = try self.resolveGlobalDecl(decl); + const llvm_var_type = try self.llvmType(tv.ty); + const llvm_type = llvm_var_type.pointerType(0); return val.constBitCast(llvm_type); }, .slice => { @@ -783,6 +792,7 @@ pub const DeclGen = struct { .decl_ref => tv.val.castTag(.decl_ref).?.data, else => unreachable, }; + fn_decl.alive = true; return self.resolveLlvmFunction(fn_decl); }, .ErrorSet => { @@ -903,9 +913,7 @@ pub const FuncGen = struct { return self.dg.genTypedValue(.{ .ty = self.air.typeOf(inst), .val = val }); } const inst_index = Air.refToIndex(inst).?; - if (self.func_inst_table.get(inst_index)) |value| return value; - - return self.todo("implement global llvm values (or the value is not in the func_inst_table table)", .{}); + return self.func_inst_table.get(inst_index).?; } fn genBody(self: *FuncGen, body: []const Air.Inst.Index) error{ OutOfMemory, CodegenFail }!void { @@ -966,8 +974,8 @@ pub const FuncGen = struct { .struct_field_ptr => try self.airStructFieldPtr(inst), .struct_field_val => try self.airStructFieldVal(inst), - .slice_elem_val => try self.airSliceElemVal(inst, false), - .ptr_slice_elem_val => try self.airSliceElemVal(inst, true), + .slice_elem_val => try self.airSliceElemVal(inst), + .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst), .optional_payload => try self.airOptionalPayload(inst, false), .optional_payload_ptr => try self.airOptionalPayload(inst, true), @@ -1170,11 +1178,20 @@ pub const FuncGen = struct { return self.builder.buildExtractValue(operand, index, ""); } - fn airSliceElemVal( - self: *FuncGen, - inst: Air.Inst.Index, - operand_is_ptr: bool, - ) !?*const llvm.Value { + fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + if (self.liveness.isUnused(inst)) + return null; + + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const lhs = try self.resolveInst(bin_op.lhs); + const rhs = try self.resolveInst(bin_op.rhs); + const base_ptr = self.builder.buildExtractValue(lhs, 0, ""); + const indices: [1]*const llvm.Value = .{rhs}; + const ptr = self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); + return self.builder.buildLoad(ptr, ""); + } + + fn airPtrSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { if (self.liveness.isUnused(inst)) return null; @@ -1182,7 +1199,7 @@ pub const FuncGen = struct { const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); - const base_ptr = if (!operand_is_ptr) lhs else ptr: { + const base_ptr = ptr: { const index_type = self.context.intType(32); const indices: [2]*const llvm.Value = .{ index_type.constNull(), diff --git a/src/codegen/wasm.zig b/src/codegen/wasm.zig index 37cc6bc59c..2f1632e0fc 100644 --- a/src/codegen/wasm.zig +++ b/src/codegen/wasm.zig @@ -1016,6 +1016,7 @@ pub const Context = struct { .Pointer => { if (val.castTag(.decl_ref)) |payload| { const decl = payload.data; + decl.alive = true; // offset into the offset table within the 'data' section const ptr_width = self.target.cpu.arch.ptrBitWidth() / 8; |
