aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig24
-rw-r--r--src/codegen/llvm.zig51
-rw-r--r--src/codegen/wasm.zig1
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;