diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-22 15:12:22 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-22 15:35:35 -0700 |
| commit | 069c83d58cebba88275ee76ba01fabcd8e964573 (patch) | |
| tree | ab7e52f307bd23869e2461189383522dc64f42de /src | |
| parent | 86b92809635607ff357ce96902e2aaf83c3fd029 (diff) | |
| download | zig-069c83d58cebba88275ee76ba01fabcd8e964573.tar.gz zig-069c83d58cebba88275ee76ba01fabcd8e964573.zip | |
stage2: change `@bitCast` to always be by-value
After a discussion about language specs, this seems like the best way to
go, because it's simpler to reason about both for humans and compilers.
The `bitcast_result_ptr` ZIR instruction is no longer needed.
This commit also implements writing enums, arrays, and vectors to
virtual memory at compile-time.
This unlocked some more of compiler-rt being able to build, which
in turn unlocks saturating arithmetic behavior tests.
There was also a memory leak in the comptime closure system which is now
fixed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 57 | ||||
| -rw-r--r-- | src/Module.zig | 1 | ||||
| -rw-r--r-- | src/Sema.zig | 7 | ||||
| -rw-r--r-- | src/Zir.zig | 6 | ||||
| -rw-r--r-- | src/print_zir.zig | 1 | ||||
| -rw-r--r-- | src/value.zig | 21 |
6 files changed, 42 insertions, 51 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index e67ae6cddf..64cc60ecf5 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -276,17 +276,30 @@ fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zi return expr(gz, scope, coerced_type_rl, type_node); } +fn reachableTypeExpr( + gz: *GenZir, + scope: *Scope, + type_node: Ast.Node.Index, + reachable_node: Ast.Node.Index, +) InnerError!Zir.Inst.Ref { + const prev_force_comptime = gz.force_comptime; + gz.force_comptime = true; + defer gz.force_comptime = prev_force_comptime; + + return reachableExpr(gz, scope, coerced_type_rl, type_node, reachable_node); +} + /// Same as `expr` but fails with a compile error if the result type is `noreturn`. fn reachableExpr( gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index, - src_node: Ast.Node.Index, + reachable_node: Ast.Node.Index, ) InnerError!Zir.Inst.Ref { const result_inst = try expr(gz, scope, rl, node); if (gz.refIsNoReturn(result_inst)) { - return gz.astgen.failNodeNotes(src_node, "unreachable code", .{}, &[_]u32{ + return gz.astgen.failNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{ try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}), }); } @@ -2040,7 +2053,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .as_node, .bit_and, .bitcast, - .bitcast_result_ptr, .bit_or, .block, .block_inline, @@ -7160,42 +7172,13 @@ fn bitCast( lhs: Ast.Node.Index, rhs: Ast.Node.Index, ) InnerError!Zir.Inst.Ref { - const astgen = gz.astgen; - const dest_type = try typeExpr(gz, scope, lhs); - switch (rl) { - .none, .discard, .ty, .coerced_ty => { - const operand = try expr(gz, scope, .none, rhs); - const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ - .lhs = dest_type, - .rhs = operand, - }); - return rvalue(gz, rl, result, node); - }, - .ref => { - return astgen.failNode(node, "cannot take address of `@bitCast` result", .{}); - }, - .ptr, .inferred_ptr => |result_ptr| { - return bitCastRlPtr(gz, scope, node, dest_type, result_ptr, rhs); - }, - .block_ptr => |block| { - return bitCastRlPtr(gz, scope, node, dest_type, block.rl_ptr, rhs); - }, - } -} - -fn bitCastRlPtr( - gz: *GenZir, - scope: *Scope, - node: Ast.Node.Index, - dest_type: Zir.Inst.Ref, - result_ptr: Zir.Inst.Ref, - rhs: Ast.Node.Index, -) InnerError!Zir.Inst.Ref { - const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{ + const dest_type = try reachableTypeExpr(gz, scope, lhs, node); + const operand = try reachableExpr(gz, scope, .none, rhs, node); + const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ .lhs = dest_type, - .rhs = result_ptr, + .rhs = operand, }); - return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs); + return rvalue(gz, rl, result, node); } fn typeOf( diff --git a/src/Module.zig b/src/Module.zig index 58a5a50698..8677be224f 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -317,6 +317,7 @@ pub const WipCaptureScope = struct { assert(!self.finalized); // use a temp to avoid unintentional aliasing due to RLS const tmp = try self.scope.captures.clone(self.perm_arena); + self.scope.captures.deinit(self.gpa); self.scope.captures = tmp; self.finalized = true; } diff --git a/src/Sema.zig b/src/Sema.zig index 1826d03559..166b668731 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -513,7 +513,6 @@ pub fn analyzeBody( .bit_not => try sema.zirBitNot(block, inst), .bit_or => try sema.zirBitwise(block, inst, .bit_or), .bitcast => try sema.zirBitcast(block, inst), - .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst), .suspend_block => try sema.zirSuspendBlock(block, inst), .bool_not => try sema.zirBoolNot(block, inst), .bool_br_and => try sema.zirBoolBr(block, inst, false), @@ -1385,12 +1384,6 @@ pub fn resolveInstValue( }; } -fn zirBitcastResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const src = inst_data.src(); - return sema.fail(block, src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); -} - fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); diff --git a/src/Zir.zig b/src/Zir.zig index b21d12e33e..5b3da74f97 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -240,10 +240,6 @@ pub const Inst = struct { /// Reinterpret the memory representation of a value as a different type. /// Uses the pl_node field with payload `Bin`. bitcast, - /// A typed result location pointer is bitcasted to a new result location pointer. - /// The new result location pointer has an inferred type. - /// Uses the pl_node field with payload `Bin`. - bitcast_result_ptr, /// Bitwise NOT. `~` /// Uses `un_node`. bit_not, @@ -977,7 +973,6 @@ pub const Inst = struct { .as_node, .bit_and, .bitcast, - .bitcast_result_ptr, .bit_or, .block, .block_inline, @@ -1235,7 +1230,6 @@ pub const Inst = struct { .as_node = .pl_node, .bit_and = .pl_node, .bitcast = .pl_node, - .bitcast_result_ptr = .pl_node, .bit_not = .un_node, .bit_or = .pl_node, .block = .pl_node, diff --git a/src/print_zir.zig b/src/print_zir.zig index 0bbd7e1655..d7cb0a082d 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -349,7 +349,6 @@ const Writer = struct { .reduce, .atomic_load, .bitcast, - .bitcast_result_ptr, .vector_type, .maximum, .minimum, diff --git a/src/value.zig b/src/value.zig index d4a5e6bbeb..3a4cdb1438 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1015,6 +1015,14 @@ pub const Value = extern union { const bits = ty.intInfo(target).bits; bigint.writeTwosComplement(buffer, bits, target.cpu.arch.endian()); }, + .Enum => { + var enum_buffer: Payload.U64 = undefined; + const int_val = val.enumToInt(ty, &enum_buffer); + var bigint_buffer: BigIntSpace = undefined; + const bigint = int_val.toBigInt(&bigint_buffer); + const bits = ty.intInfo(target).bits; + bigint.writeTwosComplement(buffer, bits, target.cpu.arch.endian()); + }, .Float => switch (ty.floatBits(target)) { 16 => return floatWriteToMemory(f16, val.toFloat(f16), target, buffer), 32 => return floatWriteToMemory(f32, val.toFloat(f32), target, buffer), @@ -1022,6 +1030,19 @@ pub const Value = extern union { 128 => return floatWriteToMemory(f128, val.toFloat(f128), target, buffer), else => unreachable, }, + .Array, .Vector => { + const len = ty.arrayLen(); + const elem_ty = ty.childType(); + const elem_size = elem_ty.abiSize(target); + var elem_i: usize = 0; + var elem_value_buf: ElemValueBuffer = undefined; + var buf_off: usize = 0; + while (elem_i < len) : (elem_i += 1) { + const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf); + writeToMemory(elem_val, elem_ty, target, buffer[buf_off..]); + buf_off += elem_size; + } + }, else => @panic("TODO implement writeToMemory for more types"), } } |
