diff options
| author | Jacob G-W <jacoblevgw@gmail.com> | 2021-08-16 23:11:55 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-21 23:52:55 -0400 |
| commit | 4ac37eb484737e98269e198b31b81ee8e929b4f1 (patch) | |
| tree | 2d5e66fcd1a2f6c9f129583d2ea8f671fff4832b /src | |
| parent | f378b0adce80aa6f85d9bf6bf97172426de2c719 (diff) | |
| download | zig-4ac37eb484737e98269e198b31b81ee8e929b4f1.tar.gz zig-4ac37eb484737e98269e198b31b81ee8e929b4f1.zip | |
stage2 Air: add struct_field_ptr_index_{0..3}
Since these are very common, it will save memory.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Air.zig | 11 | ||||
| -rw-r--r-- | src/Liveness.zig | 4 | ||||
| -rw-r--r-- | src/Sema.zig | 27 | ||||
| -rw-r--r-- | src/codegen.zig | 19 | ||||
| -rw-r--r-- | src/codegen/c.zig | 28 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 14 | ||||
| -rw-r--r-- | src/codegen/wasm.zig | 15 | ||||
| -rw-r--r-- | src/print_air.zig | 4 |
8 files changed, 110 insertions, 12 deletions
diff --git a/src/Air.zig b/src/Air.zig index 81d220ba59..6e4125be44 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -264,6 +264,13 @@ pub const Inst = struct { /// Given a pointer to a struct and a field index, returns a pointer to the field. /// Uses the `ty_pl` field, payload is `StructField`. struct_field_ptr, + /// Given a pointer to a struct, returns a pointer to the field. + /// The field index is the number at the end of the name. + /// Uses `ty_op` field. + struct_field_ptr_index_0, + struct_field_ptr_index_1, + struct_field_ptr_index_2, + struct_field_ptr_index_3, /// Given a byval struct and a field index, returns the field byval. /// Uses the `ty_pl` field, payload is `StructField`. struct_field_val, @@ -510,6 +517,10 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { .wrap_errunion_payload, .wrap_errunion_err, .slice_ptr, + .struct_field_ptr_index_0, + .struct_field_ptr_index_1, + .struct_field_ptr_index_2, + .struct_field_ptr_index_3, => return air.getRefType(datas[inst].ty_op.ty), .loop, diff --git a/src/Liveness.zig b/src/Liveness.zig index f6d51e58b4..6a47bfe597 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -282,6 +282,10 @@ fn analyzeInst( .wrap_errunion_err, .slice_ptr, .slice_len, + .struct_field_ptr_index_0, + .struct_field_ptr_index_1, + .struct_field_ptr_index_2, + .struct_field_ptr_index_3, => { const o = inst_datas[inst].ty_op; return trackOperands(a, new_set, inst, main_tomb, .{ o.operand, .none, .none }); diff --git a/src/Sema.zig b/src/Sema.zig index d543b59ac0..a11bdec66d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8119,14 +8119,29 @@ fn structFieldPtr( } try sema.requireRuntimeBlock(block, src); + const tag: Air.Inst.Tag = switch (field_index) { + 0 => .struct_field_ptr_index_0, + 1 => .struct_field_ptr_index_1, + 2 => .struct_field_ptr_index_2, + 3 => .struct_field_ptr_index_3, + else => { + return block.addInst(.{ + .tag = .struct_field_ptr, + .data = .{ .ty_pl = .{ + .ty = try sema.addType(ptr_field_ty), + .payload = try sema.addExtra(Air.StructField{ + .struct_operand = struct_ptr, + .field_index = @intCast(u32, field_index), + }), + } }, + }); + }, + }; return block.addInst(.{ - .tag = .struct_field_ptr, - .data = .{ .ty_pl = .{ + .tag = tag, + .data = .{ .ty_op = .{ .ty = try sema.addType(ptr_field_ty), - .payload = try sema.addExtra(Air.StructField{ - .struct_operand = struct_ptr, - .field_index = @intCast(u32, field_index), - }), + .operand = struct_ptr, } }, }); } diff --git a/src/codegen.zig b/src/codegen.zig index ca7a04a4a0..9103c7ad17 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -855,6 +855,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .store => try self.airStore(inst), .struct_field_ptr=> try self.airStructFieldPtr(inst), .struct_field_val=> try self.airStructFieldVal(inst), + + .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), + .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), + .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2), + .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3), + .switch_br => try self.airSwitch(inst), .slice_ptr => try self.airSlicePtr(inst), .slice_len => try self.airSliceLen(inst), @@ -1592,7 +1598,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; - _ = extra; + return self.structFieldPtr(extra.struct_operand, ty_pl.ty, extra.field_index); + } + + fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + return self.structFieldPtr(ty_op.operand, ty_op.ty, index); + } + fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void { + _ = self; + _ = operand; + _ = ty; + _ = index; return self.fail("TODO implement codegen struct_field_ptr", .{}); //return self.finishAir(inst, result, .{ extra.struct_ptr, .none, .none }); } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index bc3e357827..2084b1e1ce 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -909,6 +909,12 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM .switch_br => try airSwitchBr(o, inst), .wrap_optional => try airWrapOptional(o, inst), .struct_field_ptr => try airStructFieldPtr(o, inst), + + .struct_field_ptr_index_0 => try airStructFieldPtrIndex(o, inst, 0), + .struct_field_ptr_index_1 => try airStructFieldPtrIndex(o, inst, 1), + .struct_field_ptr_index_2 => try airStructFieldPtrIndex(o, inst, 2), + .struct_field_ptr_index_3 => try airStructFieldPtrIndex(o, inst, 3), + .struct_field_val => try airStructFieldVal(o, inst), .slice_ptr => try airSliceField(o, inst, ".ptr;\n"), .slice_len => try airSliceField(o, inst, ".len;\n"), @@ -1651,15 +1657,31 @@ fn airOptionalPayload(o: *Object, inst: Air.Inst.Index) !CValue { fn airStructFieldPtr(o: *Object, inst: Air.Inst.Index) !CValue { if (o.liveness.isUnused(inst)) - return CValue.none; + // TODO this @as is needed because of a stage1 bug + return @as(CValue, CValue.none); const ty_pl = o.air.instructions.items(.data)[inst].ty_pl; const extra = o.air.extraData(Air.StructField, ty_pl.payload).data; - const writer = o.writer(); const struct_ptr = try o.resolveInst(extra.struct_operand); const struct_ptr_ty = o.air.typeOf(extra.struct_operand); + return structFieldPtr(o, inst, struct_ptr_ty, struct_ptr, extra.field_index); +} + +fn airStructFieldPtrIndex(o: *Object, inst: Air.Inst.Index, index: u8) !CValue { + if (o.liveness.isUnused(inst)) + // TODO this @as is needed because of a stage1 bug + return @as(CValue, CValue.none); + + const ty_op = o.air.instructions.items(.data)[inst].ty_op; + const struct_ptr = try o.resolveInst(ty_op.operand); + const struct_ptr_ty = o.air.typeOf(ty_op.operand); + return structFieldPtr(o, inst, struct_ptr_ty, struct_ptr, index); +} + +fn structFieldPtr(o: *Object, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue { + const writer = o.writer(); const struct_obj = struct_ptr_ty.elemType().castTag(.@"struct").?.data; - const field_name = struct_obj.fields.keys()[extra.field_index]; + const field_name = struct_obj.fields.keys()[index]; const inst_ty = o.air.typeOfIndex(inst); const local = try o.allocLocal(inst_ty, .Const); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index b80dcf0feb..d7aa2d45b3 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1037,6 +1037,11 @@ pub const FuncGen = struct { .struct_field_ptr => try self.airStructFieldPtr(inst), .struct_field_val => try self.airStructFieldVal(inst), + .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), + .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), + .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2), + .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3), + .slice_elem_val => try self.airSliceElemVal(inst), .ptr_slice_elem_val => try self.airPtrSliceElemVal(inst), .ptr_elem_val => try self.airPtrElemVal(inst), @@ -1350,6 +1355,15 @@ pub const FuncGen = struct { return self.builder.buildStructGEP(struct_ptr, field_index, ""); } + fn airStructFieldPtrIndex(self: *FuncGen, inst: Air.Inst.Index, field_index: c_uint) !?*const llvm.Value { + if (self.liveness.isUnused(inst)) + return null; + + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const struct_ptr = try self.resolveInst(ty_op.operand); + return self.builder.buildStructGEP(struct_ptr, field_index, ""); + } + fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { if (self.liveness.isUnused(inst)) return null; diff --git a/src/codegen/wasm.zig b/src/codegen/wasm.zig index 422afef9c4..bb05567236 100644 --- a/src/codegen/wasm.zig +++ b/src/codegen/wasm.zig @@ -862,6 +862,10 @@ pub const Context = struct { .ret => self.airRet(inst), .store => self.airStore(inst), .struct_field_ptr => self.airStructFieldPtr(inst), + .struct_field_ptr_index_0 => self.airStructFieldPtrIndex(inst, 0), + .struct_field_ptr_index_1 => self.airStructFieldPtrIndex(inst, 1), + .struct_field_ptr_index_2 => self.airStructFieldPtrIndex(inst, 2), + .struct_field_ptr_index_3 => self.airStructFieldPtrIndex(inst, 3), .switch_br => self.airSwitchBr(inst), .unreach => self.airUnreachable(inst), .wrap_optional => self.airWrapOptional(inst), @@ -1441,8 +1445,15 @@ pub const Context = struct { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.StructField, ty_pl.payload); const struct_ptr = self.resolveInst(extra.data.struct_operand); - - return WValue{ .local = struct_ptr.multi_value.index + @intCast(u32, extra.data.field_index) }; + return structFieldPtr(struct_ptr, extra.data.field_index); + } + fn airStructFieldPtrIndex(self: *Context, inst: Air.Inst.Index, index: u32) InnerError!WValue { + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const struct_ptr = self.resolveInst(ty_op.operand); + return structFieldPtr(struct_ptr, index); + } + fn structFieldPtr(struct_ptr: WValue, index: u32) InnerError!WValue { + return WValue{ .local = struct_ptr.multi_value.index + index }; } fn airSwitchBr(self: *Context, inst: Air.Inst.Index) InnerError!WValue { diff --git a/src/print_air.zig b/src/print_air.zig index 20badcdc31..276158f720 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -169,6 +169,10 @@ const Writer = struct { .wrap_errunion_err, .slice_ptr, .slice_len, + .struct_field_ptr_index_0, + .struct_field_ptr_index_1, + .struct_field_ptr_index_2, + .struct_field_ptr_index_3, => try w.writeTyOp(s, inst), .block, |
