diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-12-30 22:31:56 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-12-30 21:41:02 -0800 |
| commit | 3f7d9b5fc19e4081236b3b63aebbc80e1b17f5b5 (patch) | |
| tree | a577bd97edf5d5da357d576c777861d443210aec /src/Module.zig | |
| parent | 133da8692e80532797dd91b32539cf2175280a95 (diff) | |
| download | zig-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.zig | 193 |
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 { |
