aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-12-30 22:31:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-12-30 21:41:02 -0800
commit3f7d9b5fc19e4081236b3b63aebbc80e1b17f5b5 (patch)
treea577bd97edf5d5da357d576c777861d443210aec /src/Module.zig
parent133da8692e80532797dd91b32539cf2175280a95 (diff)
downloadzig-3f7d9b5fc19e4081236b3b63aebbc80e1b17f5b5.tar.gz
zig-3f7d9b5fc19e4081236b3b63aebbc80e1b17f5b5.zip
stage2: rework Value Payload layout
This is the same as the previous commit but for Value instead of Type. Add `Value.castTag` and note that it is preferable to call than `Value.cast`. This matches other abstractions in the codebase. Added a convenience function `Value.Tag.create` which really cleans up the callsites of creating `Value` objects. `Value` tags can now share payload types. This is in preparation for another improvement that I want to do.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig193
1 files changed, 83 insertions, 110 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 3e937fe49b..ca0718c3d5 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1092,16 +1092,12 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
tvm.deinit(self.gpa);
}
- const value_payload = try decl_arena.allocator.create(Value.Payload.ExternFn);
- value_payload.* = .{ .decl = decl };
+ const fn_val = try Value.Tag.extern_fn.create(&decl_arena.allocator, decl);
decl_arena_state.* = decl_arena.state;
decl.typed_value = .{
.most_recent = .{
- .typed_value = .{
- .ty = fn_type,
- .val = Value.initPayload(&value_payload.base),
- },
+ .typed_value = .{ .ty = fn_type, .val = fn_val },
.arena = decl_arena_state,
},
};
@@ -1187,7 +1183,10 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
.analysis = .{ .queued = fn_zir },
.owner_decl = decl,
};
- fn_payload.* = .{ .func = new_func };
+ fn_payload.* = .{
+ .base = .{ .tag = .function },
+ .data = new_func,
+ };
var prev_type_has_bits = false;
var type_changed = true;
@@ -1375,7 +1374,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
}
const new_variable = try decl_arena.allocator.create(Var);
- const var_payload = try decl_arena.allocator.create(Value.Payload.Variable);
new_variable.* = .{
.owner_decl = decl,
.init = var_info.val orelse undefined,
@@ -1383,14 +1381,14 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
.is_mutable = is_mutable,
.is_threadlocal = is_threadlocal,
};
- var_payload.* = .{ .variable = new_variable };
+ const var_val = try Value.Tag.variable.create(&decl_arena.allocator, new_variable);
decl_arena_state.* = decl_arena.state;
decl.typed_value = .{
.most_recent = .{
.typed_value = .{
.ty = var_info.ty,
- .val = Value.initPayload(&var_payload.base),
+ .val = var_val,
},
.arena = decl_arena_state,
},
@@ -2232,52 +2230,43 @@ pub fn constBool(self: *Module, scope: *Scope, src: usize, v: bool) !*Inst {
}
pub fn constIntUnsigned(self: *Module, scope: *Scope, src: usize, ty: Type, int: u64) !*Inst {
- const int_payload = try scope.arena().create(Value.Payload.Int_u64);
- int_payload.* = .{ .int = int };
-
return self.constInst(scope, src, .{
.ty = ty,
- .val = Value.initPayload(&int_payload.base),
+ .val = try Value.Tag.int_u64.create(scope.arena(), int),
});
}
pub fn constIntSigned(self: *Module, scope: *Scope, src: usize, ty: Type, int: i64) !*Inst {
- const int_payload = try scope.arena().create(Value.Payload.Int_i64);
- int_payload.* = .{ .int = int };
-
return self.constInst(scope, src, .{
.ty = ty,
- .val = Value.initPayload(&int_payload.base),
+ .val = try Value.Tag.int_i64.create(scope.arena(), int),
});
}
pub fn constIntBig(self: *Module, scope: *Scope, src: usize, ty: Type, big_int: BigIntConst) !*Inst {
- const val_payload = if (big_int.positive) blk: {
+ if (big_int.positive) {
if (big_int.to(u64)) |x| {
return self.constIntUnsigned(scope, src, ty, x);
} else |err| switch (err) {
error.NegativeIntoUnsigned => unreachable,
error.TargetTooSmall => {}, // handled below
}
- const big_int_payload = try scope.arena().create(Value.Payload.IntBigPositive);
- big_int_payload.* = .{ .limbs = big_int.limbs };
- break :blk &big_int_payload.base;
- } else blk: {
+ return self.constInst(scope, src, .{
+ .ty = ty,
+ .val = try Value.Tag.int_big_positive.create(scope.arena(), big_int.limbs),
+ });
+ } else {
if (big_int.to(i64)) |x| {
return self.constIntSigned(scope, src, ty, x);
} else |err| switch (err) {
error.NegativeIntoUnsigned => unreachable,
error.TargetTooSmall => {}, // handled below
}
- const big_int_payload = try scope.arena().create(Value.Payload.IntBigNegative);
- big_int_payload.* = .{ .limbs = big_int.limbs };
- break :blk &big_int_payload.base;
- };
-
- return self.constInst(scope, src, .{
- .ty = ty,
- .val = Value.initPayload(val_payload),
- });
+ return self.constInst(scope, src, .{
+ .ty = ty,
+ .val = try Value.Tag.int_big_negative.create(scope.arena(), big_int.limbs),
+ });
+ }
}
pub fn createAnonymousDecl(
@@ -2346,26 +2335,20 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn
if (decl_tv.val.tag() == .variable) {
return self.analyzeVarRef(scope, src, decl_tv);
}
- const ty = try self.simplePtrType(scope, src, decl_tv.ty, false, .One);
- const val_payload = try scope.arena().create(Value.Payload.DeclRef);
- val_payload.* = .{ .decl = decl };
-
return self.constInst(scope, src, .{
- .ty = ty,
- .val = Value.initPayload(&val_payload.base),
+ .ty = try self.simplePtrType(scope, src, decl_tv.ty, false, .One),
+ .val = try Value.Tag.decl_ref.create(scope.arena(), decl),
});
}
fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst {
- const variable = tv.val.cast(Value.Payload.Variable).?.variable;
+ const variable = tv.val.castTag(.variable).?.data;
const ty = try self.simplePtrType(scope, src, tv.ty, variable.is_mutable, .One);
if (!variable.is_mutable and !variable.is_extern) {
- const val_payload = try scope.arena().create(Value.Payload.RefVal);
- val_payload.* = .{ .val = variable.init };
return self.constInst(scope, src, .{
.ty = ty,
- .val = Value.initPayload(&val_payload.base),
+ .val = try Value.Tag.ref_val.create(scope.arena(), variable.init),
});
}
@@ -3107,17 +3090,11 @@ pub fn intAdd(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
result_bigint.add(lhs_bigint, rhs_bigint);
const result_limbs = result_bigint.limbs[0..result_bigint.len];
- const val_payload = if (result_bigint.positive) blk: {
- const val_payload = try allocator.create(Value.Payload.IntBigPositive);
- val_payload.* = .{ .limbs = result_limbs };
- break :blk &val_payload.base;
- } else blk: {
- const val_payload = try allocator.create(Value.Payload.IntBigNegative);
- val_payload.* = .{ .limbs = result_limbs };
- break :blk &val_payload.base;
- };
-
- return Value.initPayload(val_payload);
+ if (result_bigint.positive) {
+ return Value.Tag.int_big_positive.create(allocator, result_limbs);
+ } else {
+ return Value.Tag.int_big_negative.create(allocator, result_limbs);
+ }
}
pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
@@ -3135,85 +3112,81 @@ pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
result_bigint.sub(lhs_bigint, rhs_bigint);
const result_limbs = result_bigint.limbs[0..result_bigint.len];
- const val_payload = if (result_bigint.positive) blk: {
- const val_payload = try allocator.create(Value.Payload.IntBigPositive);
- val_payload.* = .{ .limbs = result_limbs };
- break :blk &val_payload.base;
- } else blk: {
- const val_payload = try allocator.create(Value.Payload.IntBigNegative);
- val_payload.* = .{ .limbs = result_limbs };
- break :blk &val_payload.base;
- };
-
- return Value.initPayload(val_payload);
+ if (result_bigint.positive) {
+ return Value.Tag.int_big_positive.create(allocator, result_limbs);
+ } else {
+ return Value.Tag.int_big_negative.create(allocator, result_limbs);
+ }
}
-pub fn floatAdd(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: Value, rhs: Value) !Value {
- var bit_count = switch (float_type.tag()) {
- .comptime_float => 128,
- else => float_type.floatBits(self.getTarget()),
- };
-
- const allocator = scope.arena();
- const val_payload = switch (bit_count) {
- 16 => {
- return self.fail(scope, src, "TODO Implement addition for soft floats", .{});
+pub fn floatAdd(
+ self: *Module,
+ scope: *Scope,
+ float_type: Type,
+ src: usize,
+ lhs: Value,
+ rhs: Value,
+) !Value {
+ const arena = scope.arena();
+ switch (float_type.tag()) {
+ .f16 => {
+ @panic("TODO add __trunctfhf2 to compiler-rt");
+ //const lhs_val = lhs.toFloat(f16);
+ //const rhs_val = rhs.toFloat(f16);
+ //return Value.Tag.float_16.create(arena, lhs_val + rhs_val);
},
- 32 => blk: {
+ .f32 => {
const lhs_val = lhs.toFloat(f32);
const rhs_val = rhs.toFloat(f32);
- const val_payload = try allocator.create(Value.Payload.Float_32);
- val_payload.* = .{ .val = lhs_val + rhs_val };
- break :blk &val_payload.base;
+ return Value.Tag.float_32.create(arena, lhs_val + rhs_val);
},
- 64 => blk: {
+ .f64 => {
const lhs_val = lhs.toFloat(f64);
const rhs_val = rhs.toFloat(f64);
- const val_payload = try allocator.create(Value.Payload.Float_64);
- val_payload.* = .{ .val = lhs_val + rhs_val };
- break :blk &val_payload.base;
+ return Value.Tag.float_64.create(arena, lhs_val + rhs_val);
},
- 128 => {
- return self.fail(scope, src, "TODO Implement addition for big floats", .{});
+ .f128, .comptime_float, .c_longdouble => {
+ const lhs_val = lhs.toFloat(f128);
+ const rhs_val = rhs.toFloat(f128);
+ return Value.Tag.float_128.create(arena, lhs_val + rhs_val);
},
else => unreachable,
- };
-
- return Value.initPayload(val_payload);
+ }
}
-pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs: Value, rhs: Value) !Value {
- var bit_count = switch (float_type.tag()) {
- .comptime_float => 128,
- else => float_type.floatBits(self.getTarget()),
- };
-
- const allocator = scope.arena();
- const val_payload = switch (bit_count) {
- 16 => {
- return self.fail(scope, src, "TODO Implement substraction for soft floats", .{});
+pub fn floatSub(
+ self: *Module,
+ scope: *Scope,
+ float_type: Type,
+ src: usize,
+ lhs: Value,
+ rhs: Value,
+) !Value {
+ const arena = scope.arena();
+ switch (float_type.tag()) {
+ .f16 => {
+ @panic("TODO add __trunctfhf2 to compiler-rt");
+ //const lhs_val = lhs.toFloat(f16);
+ //const rhs_val = rhs.toFloat(f16);
+ //return Value.Tag.float_16.create(arena, lhs_val - rhs_val);
},
- 32 => blk: {
+ .f32 => {
const lhs_val = lhs.toFloat(f32);
const rhs_val = rhs.toFloat(f32);
- const val_payload = try allocator.create(Value.Payload.Float_32);
- val_payload.* = .{ .val = lhs_val - rhs_val };
- break :blk &val_payload.base;
+ return Value.Tag.float_32.create(arena, lhs_val - rhs_val);
},
- 64 => blk: {
+ .f64 => {
const lhs_val = lhs.toFloat(f64);
const rhs_val = rhs.toFloat(f64);
- const val_payload = try allocator.create(Value.Payload.Float_64);
- val_payload.* = .{ .val = lhs_val - rhs_val };
- break :blk &val_payload.base;
+ return Value.Tag.float_64.create(arena, lhs_val - rhs_val);
},
- 128 => {
- return self.fail(scope, src, "TODO Implement substraction for big floats", .{});
+ .f128, .comptime_float, .c_longdouble => {
+ const lhs_val = lhs.toFloat(f128);
+ const rhs_val = rhs.toFloat(f128);
+ return Value.Tag.float_128.create(arena, lhs_val - rhs_val);
},
else => unreachable,
- };
-
- return Value.initPayload(val_payload);
+ }
}
pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mutable: bool, size: std.builtin.TypeInfo.Pointer.Size) Allocator.Error!Type {