diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-05-09 15:20:08 +0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-05-22 21:15:25 -0400 |
| commit | e8236551abdb7bb74811e5e9dc9890cb2abbd269 (patch) | |
| tree | a7cdaddfb3e7b5cd3f760b682e6ded775a68bfc5 /src/codegen | |
| parent | 1c636e2564e2fc2e8e4b6b1edbc782592ee3d2d7 (diff) | |
| download | zig-e8236551abdb7bb74811e5e9dc9890cb2abbd269.tar.gz zig-e8236551abdb7bb74811e5e9dc9890cb2abbd269.zip | |
stage2: Move BlockData out of ir.Inst.Block
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 18 | ||||
| -rw-r--r-- | src/codegen/wasm.zig | 22 |
2 files changed, 21 insertions, 19 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index cc73b6cad9..55c9c5b641 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -33,6 +33,11 @@ pub const CValue = union(enum) { decl_ref: *Decl, }; +const BlockData = struct { + block_id: usize, + result: CValue, +}; + pub const CValueMap = std.AutoHashMap(*Inst, CValue); pub const TypedefMap = std.HashMap(Type, struct { name: []const u8, rendered: []u8 }, Type.hash, Type.eql, std.hash_map.default_max_load_percentage); @@ -83,6 +88,7 @@ pub const Object = struct { gpa: *mem.Allocator, code: std.ArrayList(u8), value_map: CValueMap, + blocks: std.AutoHashMapUnmanaged(*ir.Inst.Block, BlockData) = .{}, next_arg_index: usize = 0, next_local_index: usize = 0, next_block_index: usize = 0, @@ -939,8 +945,6 @@ fn genBlock(o: *Object, inst: *Inst.Block) !CValue { o.next_block_index += 1; const writer = o.writer(); - // store the block id in relocs.capacity as it is not used for anything else in the C backend. - inst.codegen.relocs.capacity = block_id; const result = if (inst.base.ty.tag() != .void and !inst.base.isUnused()) blk: { // allocate a location for the result const local = try o.allocLocal(inst.base.ty, .Mut); @@ -948,7 +952,11 @@ fn genBlock(o: *Object, inst: *Inst.Block) !CValue { break :blk local; } else CValue{ .none = {} }; - inst.codegen.mcv = @bitCast(@import("../codegen.zig").AnyMCValue, result); + try o.blocks.putNoClobber(o.gpa, inst, .{ + .block_id = block_id, + .result = result, + }); + try genBody(o, inst.body); try o.indent_writer.insertNewline(); // label must be followed by an expression, add an empty one. @@ -957,7 +965,7 @@ fn genBlock(o: *Object, inst: *Inst.Block) !CValue { } fn genBr(o: *Object, inst: *Inst.Br) !CValue { - const result = @bitCast(CValue, inst.block.codegen.mcv); + const result = o.blocks.get(inst.block).?.result; const writer = o.writer(); // If result is .none then the value of the block is unused. @@ -973,7 +981,7 @@ fn genBr(o: *Object, inst: *Inst.Br) !CValue { } fn genBrVoid(o: *Object, block: *Inst.Block) !CValue { - try o.writer().print("goto zig_block_{d};\n", .{block.codegen.relocs.capacity}); + try o.writer().print("goto zig_block_{d};\n", .{o.blocks.get(block).?.block_id}); return CValue.none; } diff --git a/src/codegen/wasm.zig b/src/codegen/wasm.zig index 40be7bc618..36b131e9b1 100644 --- a/src/codegen/wasm.zig +++ b/src/codegen/wasm.zig @@ -14,7 +14,6 @@ const Inst = ir.Inst; const Type = @import("../type.zig").Type; const Value = @import("../value.zig").Value; const Compilation = @import("../Compilation.zig"); -const AnyMCValue = @import("../codegen.zig").AnyMCValue; const LazySrcLoc = Module.LazySrcLoc; const link = @import("../link.zig"); const TypedValue = @import("../TypedValue.zig"); @@ -29,8 +28,6 @@ const WValue = union(enum) { constant: *Inst, /// Offset position in the list of bytecode instructions code_offset: usize, - /// The label of the block, used by breaks to find its relative distance - block_idx: u32, /// Used for variables that create multiple locals on the stack when allocated /// such as structs and optionals. multi_value: u32, @@ -492,6 +489,8 @@ pub const Context = struct { gpa: *mem.Allocator, /// Table to save `WValue`'s generated by an `Inst` values: ValueTable, + /// Mapping from *Inst.Block to block ids + blocks: std.AutoArrayHashMapUnmanaged(*Inst.Block, u32) = .{}, /// `bytes` contains the wasm bytecode belonging to the 'code' section. code: ArrayList(u8), /// Contains the generated function type bytecode for the current function @@ -521,6 +520,7 @@ pub const Context = struct { pub fn deinit(self: *Context) void { self.values.deinit(self.gpa); + self.blocks.deinit(self.gpa); self.locals.deinit(self.gpa); self.* = undefined; } @@ -590,7 +590,6 @@ pub const Context = struct { fn emitWValue(self: *Context, val: WValue) InnerError!void { const writer = self.code.writer(); switch (val) { - .block_idx => unreachable, // block_idx cannot be referenced .multi_value => unreachable, // multi_value can never be written directly, and must be accessed individually .none, .code_offset => {}, // no-op .local => |idx| { @@ -968,13 +967,9 @@ pub const Context = struct { const block_ty = try self.genBlockType(block.base.src, block.base.ty); try self.startBlock(.block, block_ty, null); - block.codegen = .{ - // we don't use relocs, so using `relocs` is illegal behaviour. - .relocs = undefined, - // Here we set the current block idx, so breaks know the depth to jump - // to when breaking out. - .mcv = @bitCast(AnyMCValue, WValue{ .block_idx = self.block_depth }), - }; + // Here we set the current block idx, so breaks know the depth to jump + // to when breaking out. + try self.blocks.putNoClobber(self.gpa, block, self.block_depth); try self.genBody(block.body); try self.endBlock(); @@ -1091,10 +1086,9 @@ pub const Context = struct { try self.emitWValue(operand); } - // every block contains a `WValue` with its block index. + // We map every block to its block index. // We then determine how far we have to jump to it by substracting it from current block depth - const wvalue = @bitCast(WValue, br.block.codegen.mcv); - const idx: u32 = self.block_depth - wvalue.block_idx; + const idx: u32 = self.block_depth - self.blocks.get(br.block).?; const writer = self.code.writer(); try writer.writeByte(wasm.opcode(.br)); try leb.writeULEB128(writer, idx); |
