authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-28 13:38:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-28 13:38:33-07:00
logd5100dc81555f0e8197d5f189b1432070e8d72dd
tree96de992b22f7cfc4bcb672892c64fb2cdf621913
parent90bce11f62aa2f246b9bce5bc49069a3faf7ec9a

stage2: fix frame_address AIR instruction

Various places were assuming different union tags. Now it is consistently a no-op instruction, just like the similar instruction ret_addr.

11 files changed, 87 insertions(+), 96 deletions(-)

src/Air.zig+4-5
......@@ -218,6 +218,9 @@ pub const Inst = struct {
218218 /// Yields the return address of the current function.
219219 /// Uses the `no_op` field.
220220 ret_addr,
221 /// Implements @frameAddress builtin.
222 /// Uses the `no_op` field.
223 frame_addr,
221224 /// Function call.
222225 /// Result type is the return type of the function being called.
223226 /// Uses the `pl_op` field with the `Call` payload. operand is the callee.
......@@ -580,10 +583,6 @@ pub const Inst = struct {
580583 /// Uses the `ty_pl` field.
581584 field_parent_ptr,
582585
583 /// Implements @frameAddress builtin.
584 /// Uses the `ty` field.
585 frame_address,
586
587586 pub fn fromCmpOp(op: std.math.CompareOperator) Tag {
588587 return switch (op) {
589588 .lt => .cmp_lt,
......@@ -943,7 +942,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
943942 .ptrtoint,
944943 .slice_len,
945944 .ret_addr,
946 .frame_address,
945 .frame_addr,
947946 => return Type.initTag(.usize),
948947
949948 .bool_to_int => return Type.initTag(.u1),
src/Liveness.zig+1-1
......@@ -317,7 +317,7 @@ fn analyzeInst(
317317 .unreach,
318318 .fence,
319319 .ret_addr,
320 .frame_address,
320 .frame_addr,
321321 => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),
322322
323323 .not,
src/Sema.zig+10-13
......@@ -9993,14 +9993,21 @@ fn zirRetAddr(
99939993 block: *Block,
99949994 extended: Zir.Inst.Extended.InstData,
99959995) CompileError!Air.Inst.Ref {
9996 const tracy = trace(@src());
9997 defer tracy.end();
9998
99999996 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
100009997 try sema.requireRuntimeBlock(block, src);
100019998 return try block.addNoOp(.ret_addr);
100029999}
1000310000
10001fn zirFrameAddress(
10002 sema: *Sema,
10003 block: *Block,
10004 extended: Zir.Inst.Extended.InstData,
10005) CompileError!Air.Inst.Ref {
10006 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10007 try sema.requireRuntimeBlock(block, src);
10008 return try block.addNoOp(.frame_addr);
10009}
10010
1000410011fn zirBuiltinSrc(
1000510012 sema: *Sema,
1000610013 block: *Block,
......@@ -11889,16 +11896,6 @@ fn zirFrame(
1188911896 return sema.fail(block, src, "TODO: Sema.zirFrame", .{});
1189011897}
1189111898
11892fn zirFrameAddress(
11893 sema: *Sema,
11894 block: *Block,
11895 extended: Zir.Inst.Extended.InstData,
11896) CompileError!Air.Inst.Ref {
11897 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
11898 try sema.requireFunctionBlock(block, src);
11899 return block.addTy(.frame_address, Type.@"usize");
11900}
11901
1190211899fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1190311900 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1190411901 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
src/arch/aarch64/CodeGen.zig+10-12
......@@ -579,7 +579,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
579579 .block => try self.airBlock(inst),
580580 .br => try self.airBr(inst),
581581 .breakpoint => try self.airBreakpoint(),
582 .ret_addr => try self.airRetAddr(),
582 .ret_addr => try self.airRetAddr(inst),
583 .frame_addr => try self.airFrameAddress(inst),
583584 .fence => try self.airFence(),
584585 .call => try self.airCall(inst),
585586 .cond_br => try self.airCondBr(inst),
......@@ -670,8 +671,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
670671 .wrap_optional => try self.airWrapOptional(inst),
671672 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
672673 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
673
674 .frame_address => try self.airFrameAddress(inst),
675674 // zig fmt: on
676675 }
677676
......@@ -1519,13 +1518,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
15191518 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
15201519}
15211520
1522fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1523 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1524 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
1525 _ = extra;
1526 return self.fail("TODO implement codegen airFrameAddress", .{});
1527}
1528
15291521fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
15301522 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
15311523 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
......@@ -2187,8 +2179,14 @@ fn airBreakpoint(self: *Self) !void {
21872179 return self.finishAirBookkeeping();
21882180}
21892181
2190fn airRetAddr(self: *Self) !void {
2191 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
2182fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
2183 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for aarch64", .{});
2184 return self.finishAir(inst, result, .{ .none, .none, .none });
2185}
2186
2187fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
2188 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for aarch64", .{});
2189 return self.finishAir(inst, result, .{ .none, .none, .none });
21922190}
21932191
21942192fn airFence(self: *Self) !void {
src/arch/arm/CodeGen.zig+10-12
......@@ -565,7 +565,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
565565 .block => try self.airBlock(inst),
566566 .br => try self.airBr(inst),
567567 .breakpoint => try self.airBreakpoint(),
568 .ret_addr => try self.airRetAddr(),
568 .ret_addr => try self.airRetAddr(inst),
569 .frame_addr => try self.airFrameAddress(inst),
569570 .fence => try self.airFence(),
570571 .call => try self.airCall(inst),
571572 .cond_br => try self.airCondBr(inst),
......@@ -656,8 +657,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
656657 .wrap_optional => try self.airWrapOptional(inst),
657658 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
658659 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
659
660 .frame_address => try self.airFrameAddress(inst),
661660 // zig fmt: on
662661 }
663662
......@@ -1274,13 +1273,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
12741273 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
12751274}
12761275
1277fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1278 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1279 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1280 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress", .{});
1281 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1282}
1283
12841276fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
12851277 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
12861278 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
......@@ -2458,8 +2450,14 @@ fn airBreakpoint(self: *Self) !void {
24582450 return self.finishAirBookkeeping();
24592451}
24602452
2461fn airRetAddr(self: *Self) !void {
2462 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
2453fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
2454 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for arm", .{});
2455 return self.finishAir(inst, result, .{ .none, .none, .none });
2456}
2457
2458fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
2459 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for arm", .{});
2460 return self.finishAir(inst, result, .{ .none, .none, .none });
24632461}
24642462
24652463fn airFence(self: *Self) !void {
src/arch/riscv64/CodeGen.zig+10-11
......@@ -550,7 +550,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
550550 .block => try self.airBlock(inst),
551551 .br => try self.airBr(inst),
552552 .breakpoint => try self.airBreakpoint(),
553 .ret_addr => try self.airRetAddr(),
553 .ret_addr => try self.airRetAddr(inst),
554 .frame_addr => try self.airFrameAddress(inst),
554555 .fence => try self.airFence(),
555556 .call => try self.airCall(inst),
556557 .cond_br => try self.airCondBr(inst),
......@@ -641,8 +642,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
641642 .wrap_optional => try self.airWrapOptional(inst),
642643 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
643644 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
644
645 .frame_address => try self.airFrameAddress(inst),
646645 // zig fmt: on
647646 }
648647 if (std.debug.runtime_safety) {
......@@ -1105,12 +1104,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
11051104 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
11061105}
11071106
1108fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1109 _ = self;
1110 _ = inst;
1111 return self.fail("TODO implement codegen airFrameAddress", .{});
1112}
1113
11141107fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
11151108 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
11161109 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
......@@ -1446,8 +1439,14 @@ fn airBreakpoint(self: *Self) !void {
14461439 return self.finishAirBookkeeping();
14471440}
14481441
1449fn airRetAddr(self: *Self) !void {
1450 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
1442fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
1443 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for riscv64", .{});
1444 return self.finishAir(inst, result, .{ .none, .none, .none });
1445}
1446
1447fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1448 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for riscv64", .{});
1449 return self.finishAir(inst, result, .{ .none, .none, .none });
14511450}
14521451
14531452fn airFence(self: *Self) !void {
src/arch/wasm/CodeGen.zig+1-1
......@@ -1683,6 +1683,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
16831683 .assembly,
16841684 .shl_sat,
16851685 .ret_addr,
1686 .frame_addr,
16861687 .clz,
16871688 .ctz,
16881689 .popcount,
......@@ -1726,7 +1727,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
17261727 .error_name,
17271728 .errunion_payload_ptr_set,
17281729 .field_parent_ptr,
1729 .frame_address,
17301730
17311731 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248
17321732 // is implemented in the frontend before implementing them here in the wasm backend.
src/arch/x86_64/CodeGen.zig+10-14
......@@ -662,7 +662,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
662662 .block => try self.airBlock(inst),
663663 .br => try self.airBr(inst),
664664 .breakpoint => try self.airBreakpoint(),
665 .ret_addr => try self.airRetAddr(),
665 .ret_addr => try self.airRetAddr(inst),
666 .frame_addr => try self.airFrameAddress(inst),
666667 .fence => try self.airFence(),
667668 .call => try self.airCall(inst),
668669 .cond_br => try self.airCondBr(inst),
......@@ -753,8 +754,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
753754 .wrap_optional => try self.airWrapOptional(inst),
754755 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
755756 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
756
757 .frame_address => try self.airFrameAddress(inst),
758757 // zig fmt: on
759758 }
760759
......@@ -1867,15 +1866,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
18671866 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
18681867}
18691868
1870fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1871 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1872 const result: MCValue = if (self.liveness.isUnused(inst))
1873 .dead
1874 else
1875 return self.fail("TODO implement airFrameAddress for {}", .{self.target.cpu.arch});
1876 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1877}
1878
18791869fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
18801870 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
18811871 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
......@@ -3138,8 +3128,14 @@ fn airBreakpoint(self: *Self) !void {
31383128 return self.finishAirBookkeeping();
31393129}
31403130
3141fn airRetAddr(self: *Self) !void {
3142 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
3131fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
3132 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for x86_64", .{});
3133 return self.finishAir(inst, result, .{ .none, .none, .none });
3134}
3135
3136fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
3137 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for x86_64", .{});
3138 return self.finishAir(inst, result, .{ .none, .none, .none });
31433139}
31443140
31453141fn airFence(self: *Self) !void {
src/codegen/c.zig+11-9
......@@ -1588,7 +1588,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
15881588 .arg => airArg(f),
15891589
15901590 .breakpoint => try airBreakpoint(f),
1591 .ret_addr => try airRetAddr(f),
1591 .ret_addr => try airRetAddr(f, inst),
1592 .frame_addr => try airFrameAddress(f, inst),
15921593 .unreach => try airUnreach(f),
15931594 .fence => try airFence(f, inst),
15941595
......@@ -1757,8 +1758,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
17571758 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
17581759 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),
17591760 .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst),
1760
1761 .frame_address => try airFrameAddress(f, inst),
17621761 // zig fmt: on
17631762 };
17641763 switch (result_value) {
......@@ -2719,12 +2718,20 @@ fn airBreakpoint(f: *Function) !CValue {
27192718 return CValue.none;
27202719}
27212720
2722fn airRetAddr(f: *Function) !CValue {
2721fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
2722 if (f.liveness.isUnused(inst)) return CValue.none;
27232723 const local = try f.allocLocal(Type.usize, .Const);
27242724 try f.object.writer().writeAll(" = zig_return_address();\n");
27252725 return local;
27262726}
27272727
2728fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
2729 if (f.liveness.isUnused(inst)) return CValue.none;
2730 const local = try f.allocLocal(Type.usize, .Const);
2731 try f.object.writer().writeAll(" = zig_frame_address();\n");
2732 return local;
2733}
2734
27282735fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
27292736 const atomic_order = f.air.instructions.items(.data)[inst].fence;
27302737 const writer = f.object.writer();
......@@ -3200,11 +3207,6 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
32003207 return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{});
32013208}
32023209
3203fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
3204 _ = inst;
3205 return f.fail("TODO: C backend: implement airFrameAddress", .{});
3206}
3207
32083210fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
32093211 if (f.liveness.isUnused(inst))
32103212 return CValue.none;
src/codegen/llvm.zig+19-17
......@@ -2135,6 +2135,7 @@ pub const FuncGen = struct {
21352135 .switch_br => try self.airSwitchBr(inst),
21362136 .breakpoint => try self.airBreakpoint(inst),
21372137 .ret_addr => try self.airRetAddr(inst),
2138 .frame_addr => try self.airFrameAddress(inst),
21382139 .call => try self.airCall(inst),
21392140 .cond_br => try self.airCondBr(inst),
21402141 .intcast => try self.airIntCast(inst),
......@@ -2214,8 +2215,6 @@ pub const FuncGen = struct {
22142215 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
22152216 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
22162217
2217 .frame_address => try self.airFrameAddress(inst),
2218
22192218 .constant => unreachable,
22202219 .const_ty => unreachable,
22212220 .unreach => self.airUnreach(inst),
......@@ -3341,16 +3340,6 @@ pub const FuncGen = struct {
33413340 return partial;
33423341 }
33433342
3344 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3345 if (self.liveness.isUnused(inst)) return null;
3346
3347 const llvm_i32 = try self.dg.llvmType(Type.initTag(.i32));
3348 const llvm_fn = self.getIntrinsic("llvm.frameaddress", &.{llvm_i32});
3349 const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{llvm_i32.constNull()}, 1, .Fast, .Auto, "");
3350 const llvm_usize = try self.dg.llvmType(Type.usize);
3351 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
3352 }
3353
33543343 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
33553344 if (self.liveness.isUnused(inst)) return null;
33563345
......@@ -4112,12 +4101,25 @@ pub const FuncGen = struct {
41124101 }
41134102
41144103 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
4115 _ = inst;
4116 const i32_zero = self.context.intType(32).constNull();
4117 const usize_llvm_ty = try self.dg.llvmType(Type.usize);
4104 if (self.liveness.isUnused(inst)) return null;
4105
4106 const llvm_i32 = self.context.intType(32);
41184107 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
4119 const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{i32_zero}, 1, .Fast, .Auto, "");
4120 return self.builder.buildPtrToInt(ptr_val, usize_llvm_ty, "");
4108 const params = [_]*const llvm.Value{llvm_i32.constNull()};
4109 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
4110 const llvm_usize = try self.dg.llvmType(Type.usize);
4111 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
4112 }
4113
4114 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
4115 if (self.liveness.isUnused(inst)) return null;
4116
4117 const llvm_i32 = self.context.intType(32);
4118 const llvm_fn = self.getIntrinsic("llvm.frameaddress", &.{llvm_i32});
4119 const params = [_]*const llvm.Value{llvm_i32.constNull()};
4120 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
4121 const llvm_usize = try self.dg.llvmType(Type.usize);
4122 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
41214123 }
41224124
41234125 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
src/print_air.zig+1-1
......@@ -171,13 +171,13 @@ const Writer = struct {
171171 .breakpoint,
172172 .unreach,
173173 .ret_addr,
174 .frame_addr,
174175 => try w.writeNoOp(s, inst),
175176
176177 .const_ty,
177178 .alloc,
178179 .ret_ptr,
179180 .arg,
180 .frame_address,
181181 => try w.writeTy(s, inst),
182182
183183 .not,