| author | |
| committer | |
| log | a6eb83bd1b7739156ab01e3fc55588f67d924daa |
| tree | c89741b3b0e9fdfa1433031eab13e611634b5e1f |
| parent | e70c34cdb7ea7d9b7b6feddb2d8e6194ed1188a4 |
This is for async calls that also act as an alloca. This helps avoid
unnecessarily complicated machinery for the simple case of
`var a = async b();`.
The `call_async` instruction has a frame pointer and returns void
always, which will be used for the other form: `a = async b();`.13 files changed, 128 insertions(+), 35 deletions(-)
src/Air.zig+15-3| ... | ... | @@ -310,9 +310,14 @@ pub const Inst = struct { |
| 310 | 310 | call_never_tail, |
| 311 | 311 | /// Same as `call` except with the `never_inline` attribute. |
| 312 | 312 | call_never_inline, |
| 313 | /// Async function call. | |
| 314 | /// Uses `ty_pl` field with the `AsyncCall` payload. | |
| 313 | /// Async function call, using a provided frame pointer. | |
| 314 | /// Uses `pl_op` field with the `AsyncCall` payload. operand is the callee. | |
| 315 | /// Result type is always void. | |
| 315 | 316 | call_async, |
| 317 | /// Async function call, which allocates the frame for the callee on the stack. | |
| 318 | /// This instruction also acts as an alloc. | |
| 319 | /// Uses `ty_pl` field with the `AsyncCallAlloc` payload. | |
| 320 | call_async_alloc, | |
| 316 | 321 | /// Count leading zeroes of an integer according to its representation in twos complement. |
| 317 | 322 | /// Result type will always be an unsigned integer big enough to fit the answer. |
| 318 | 323 | /// Uses the `ty_op` field. |
| ... | ... | @@ -1076,6 +1081,11 @@ pub const Call = struct { |
| 1076 | 1081 | /// Trailing is a list of `Inst.Ref` for every `args_len`. |
| 1077 | 1082 | pub const AsyncCall = struct { |
| 1078 | 1083 | frame_ptr: Inst.Ref, |
| 1084 | args_len: u32, | |
| 1085 | }; | |
| 1086 | ||
| 1087 | /// Trailing is a list of `Inst.Ref` for every `args_len`. | |
| 1088 | pub const AsyncCallAlloc = struct { | |
| 1079 | 1089 | callee: Inst.Ref, |
| 1080 | 1090 | args_len: u32, |
| 1081 | 1091 | }; |
| ... | ... | @@ -1350,7 +1360,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1350 | 1360 | .ptr_add, |
| 1351 | 1361 | .ptr_sub, |
| 1352 | 1362 | .try_ptr, |
| 1353 | .call_async, | |
| 1363 | .call_async_alloc, | |
| 1354 | 1364 | => return air.getRefType(datas[inst].ty_pl.ty), |
| 1355 | 1365 | |
| 1356 | 1366 | .interned => return ip.typeOf(datas[inst].interned).toType(), |
| ... | ... | @@ -1429,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1429 | 1439 | .set_err_return_trace, |
| 1430 | 1440 | .vector_store_elem, |
| 1431 | 1441 | .c_va_end, |
| 1442 | .call_async, | |
| 1432 | 1443 | => return Type.void, |
| 1433 | 1444 | |
| 1434 | 1445 | .int_from_ptr, |
| ... | ... | @@ -1595,6 +1606,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1595 | 1606 | .call_never_tail, |
| 1596 | 1607 | .call_never_inline, |
| 1597 | 1608 | .call_async, |
| 1609 | .call_async_alloc, | |
| 1598 | 1610 | .cond_br, |
| 1599 | 1611 | .switch_br, |
| 1600 | 1612 | .@"try", |
src/Liveness.zig+63-18| ... | ... | @@ -484,15 +484,25 @@ pub fn categorizeOperand( |
| 484 | 484 | const inst_data = air_datas[inst].pl_op; |
| 485 | 485 | const callee = inst_data.operand; |
| 486 | 486 | const extra = air.extraData(Air.Call, inst_data.payload); |
| 487 | const frame_ptr: Air.Inst.Ref = .none; | |
| 487 | 488 | const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]); |
| 488 | return categorizeOperandCall(l, inst, operand_ref, callee, args); | |
| 489 | return categorizeOperandCall(l, inst, operand_ref, frame_ptr, callee, args); | |
| 489 | 490 | }, |
| 490 | 491 | .call_async => { |
| 491 | const inst_data = air_datas[inst].ty_pl; | |
| 492 | const inst_data = air_datas[inst].pl_op; | |
| 492 | 493 | const extra = air.extraData(Air.AsyncCall, inst_data.payload); |
| 494 | const callee = inst_data.operand; | |
| 495 | const frame_ptr = extra.data.frame_ptr; | |
| 496 | const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]); | |
| 497 | return categorizeOperandCall(l, inst, operand_ref, frame_ptr, callee, args); | |
| 498 | }, | |
| 499 | .call_async_alloc => { | |
| 500 | const inst_data = air_datas[inst].ty_pl; | |
| 501 | const extra = air.extraData(Air.AsyncCallAlloc, inst_data.payload); | |
| 493 | 502 | const callee = extra.data.callee; |
| 503 | const frame_ptr: Air.Inst.Ref = .none; | |
| 494 | 504 | const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]); |
| 495 | return categorizeOperandCall(l, inst, operand_ref, callee, args); | |
| 505 | return categorizeOperandCall(l, inst, operand_ref, frame_ptr, callee, args); | |
| 496 | 506 | }, |
| 497 | 507 | .select => { |
| 498 | 508 | const pl_op = air_datas[inst].pl_op; |
| ... | ... | @@ -661,21 +671,37 @@ pub fn categorizeOperand( |
| 661 | 671 | } |
| 662 | 672 | } |
| 663 | 673 | |
| 664 | fn categorizeOperandCall( | |
| 674 | pub fn categorizeOperandCall( | |
| 665 | 675 | l: Liveness, |
| 666 | 676 | inst: Air.Inst.Index, |
| 667 | 677 | operand_ref: Air.Inst.Ref, |
| 678 | frame_ptr: Air.Inst.Ref, | |
| 668 | 679 | callee: Air.Inst.Ref, |
| 669 | 680 | args: []const Air.Inst.Ref, |
| 670 | 681 | ) OperandCategory { |
| 671 | if (args.len + 1 <= bpi - 1) { | |
| 672 | if (callee == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write); | |
| 673 | for (args, 0..) |arg, i| { | |
| 674 | if (arg == operand_ref) return matchOperandSmallIndex(l, inst, @intCast(i + 1), .write); | |
| 682 | const total = args.len + 1 + @intFromBool(frame_ptr != .none); | |
| 683 | if (total <= bpi - 1) { | |
| 684 | var op_index: OperandInt = 0; | |
| 685 | if (frame_ptr != .none) { | |
| 686 | if (frame_ptr == operand_ref) return matchOperandSmallIndex(l, inst, op_index, .write); | |
| 687 | op_index += 1; | |
| 688 | } | |
| 689 | if (callee == operand_ref) return matchOperandSmallIndex(l, inst, op_index, .write); | |
| 690 | ||
| 691 | for (args) |arg| { | |
| 692 | op_index += 1; | |
| 693 | if (arg == operand_ref) return matchOperandSmallIndex(l, inst, op_index, .write); | |
| 675 | 694 | } |
| 676 | 695 | return .write; |
| 677 | 696 | } |
| 678 | 697 | var bt = l.iterateBigTomb(inst); |
| 698 | if (frame_ptr != .none) { | |
| 699 | if (bt.feed()) { | |
| 700 | if (frame_ptr == operand_ref) return .tomb; | |
| 701 | } else { | |
| 702 | if (frame_ptr == operand_ref) return .write; | |
| 703 | } | |
| 704 | } | |
| 679 | 705 | if (bt.feed()) { |
| 680 | 706 | if (callee == operand_ref) return .tomb; |
| 681 | 707 | } else { |
| ... | ... | @@ -1122,18 +1148,28 @@ fn analyzeInst( |
| 1122 | 1148 | }, |
| 1123 | 1149 | |
| 1124 | 1150 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { |
| 1125 | const inst_data = inst_datas[inst].pl_op; | |
| 1126 | const callee = inst_data.operand; | |
| 1127 | const extra = a.air.extraData(Air.Call, inst_data.payload); | |
| 1151 | const pl_op = inst_datas[inst].pl_op; | |
| 1152 | const callee = pl_op.operand; | |
| 1153 | const frame_ptr: Air.Inst.Ref = .none; | |
| 1154 | const extra = a.air.extraData(Air.Call, pl_op.payload); | |
| 1128 | 1155 | const args: []const Air.Inst.Ref = @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]); |
| 1129 | return analyzeInstCall(a, pass, data, inst, callee, args); | |
| 1156 | return analyzeInstCall(a, pass, data, inst, frame_ptr, callee, args); | |
| 1130 | 1157 | }, |
| 1131 | 1158 | .call_async => { |
| 1132 | const inst_data = inst_datas[inst].ty_pl; | |
| 1159 | const inst_data = inst_datas[inst].pl_op; | |
| 1133 | 1160 | const extra = a.air.extraData(Air.AsyncCall, inst_data.payload); |
| 1161 | const callee = inst_data.operand; | |
| 1162 | const args: []const Air.Inst.Ref = @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]); | |
| 1163 | const frame_ptr = extra.data.frame_ptr; | |
| 1164 | return analyzeInstCall(a, pass, data, inst, frame_ptr, callee, args); | |
| 1165 | }, | |
| 1166 | .call_async_alloc => { | |
| 1167 | const ty_pl = inst_datas[inst].ty_pl; | |
| 1168 | const extra = a.air.extraData(Air.AsyncCallAlloc, ty_pl.payload); | |
| 1134 | 1169 | const callee = extra.data.callee; |
| 1170 | const frame_ptr: Air.Inst.Ref = .none; | |
| 1135 | 1171 | const args: []const Air.Inst.Ref = @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]); |
| 1136 | return analyzeInstCall(a, pass, data, inst, callee, args); | |
| 1172 | return analyzeInstCall(a, pass, data, inst, frame_ptr, callee, args); | |
| 1137 | 1173 | }, |
| 1138 | 1174 | .select => { |
| 1139 | 1175 | const pl_op = inst_datas[inst].pl_op; |
| ... | ... | @@ -1267,24 +1303,33 @@ fn analyzeInstCall( |
| 1267 | 1303 | comptime pass: LivenessPass, |
| 1268 | 1304 | data: *LivenessPassData(pass), |
| 1269 | 1305 | inst: Air.Inst.Index, |
| 1306 | frame_ptr: Air.Inst.Ref, | |
| 1270 | 1307 | callee: Air.Inst.Ref, |
| 1271 | 1308 | args: []const Air.Inst.Ref, |
| 1272 | 1309 | ) Allocator.Error!void { |
| 1273 | if (args.len + 1 <= bpi - 1) { | |
| 1310 | const total = args.len + 1 + @intFromBool(frame_ptr != .none); | |
| 1311 | if (total <= bpi - 1) { | |
| 1274 | 1312 | var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); |
| 1275 | buf[0] = callee; | |
| 1276 | @memcpy(buf[1..][0..args.len], args); | |
| 1313 | var op_index: OperandInt = 0; | |
| 1314 | if (frame_ptr != .none) { | |
| 1315 | buf[op_index] = frame_ptr; | |
| 1316 | op_index += 1; | |
| 1317 | } | |
| 1318 | buf[op_index] = callee; | |
| 1319 | op_index += 1; | |
| 1320 | @memcpy(buf[op_index..][0..args.len], args); | |
| 1277 | 1321 | return analyzeOperands(a, pass, data, inst, buf); |
| 1278 | 1322 | } |
| 1279 | 1323 | |
| 1280 | 1324 | var big = try AnalyzeBigOperands(pass).init(a, data, inst, args.len + 1); |
| 1281 | 1325 | defer big.deinit(); |
| 1326 | if (frame_ptr != .none) try big.feed(frame_ptr); | |
| 1327 | try big.feed(callee); | |
| 1282 | 1328 | var i: usize = args.len; |
| 1283 | 1329 | while (i > 0) { |
| 1284 | 1330 | i -= 1; |
| 1285 | 1331 | try big.feed(args[i]); |
| 1286 | 1332 | } |
| 1287 | try big.feed(callee); | |
| 1288 | 1333 | return big.finish(); |
| 1289 | 1334 | } |
| 1290 | 1335 |
src/Liveness/Verify.zig+17-1| ... | ... | @@ -350,8 +350,24 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 350 | 350 | try self.verifyInst(inst); |
| 351 | 351 | }, |
| 352 | 352 | .call_async => { |
| 353 | const pl_op = data[inst].pl_op; | |
| 354 | const extra = self.air.extraData(Air.AsyncCall, pl_op.payload); | |
| 355 | const args: []const Air.Inst.Ref = @ptrCast( | |
| 356 | self.air.extra[extra.end..][0..extra.data.args_len], | |
| 357 | ); | |
| 358 | const callee = pl_op.operand; | |
| 359 | ||
| 360 | var bt = self.liveness.iterateBigTomb(inst); | |
| 361 | try self.verifyOperand(inst, extra.data.frame_ptr, bt.feed()); | |
| 362 | try self.verifyOperand(inst, callee, bt.feed()); | |
| 363 | for (args) |arg| { | |
| 364 | try self.verifyOperand(inst, arg, bt.feed()); | |
| 365 | } | |
| 366 | try self.verifyInst(inst); | |
| 367 | }, | |
| 368 | .call_async_alloc => { | |
| 353 | 369 | const ty_pl = data[inst].ty_pl; |
| 354 | const extra = self.air.extraData(Air.AsyncCall, ty_pl.payload); | |
| 370 | const extra = self.air.extraData(Air.AsyncCallAlloc, ty_pl.payload); | |
| 355 | 371 | const args: []const Air.Inst.Ref = @ptrCast( |
| 356 | 372 | self.air.extra[extra.end..][0..extra.data.args_len], |
| 357 | 373 | ); |
src/Sema.zig+2-4| ... | ... | @@ -7299,18 +7299,16 @@ fn addAsyncCallInst( |
| 7299 | 7299 | ) Allocator.Error!Air.Inst.Ref { |
| 7300 | 7300 | const mod = sema.mod; |
| 7301 | 7301 | const ptr_frame_ty = try mod.singleMutPtrType(try mod.asyncFrameType(callee_fn)); |
| 7302 | const frame_ptr = try block.addTy(.alloc, ptr_frame_ty); | |
| 7303 | 7302 | const ptr_frame_ty_ref = try sema.addType(ptr_frame_ty); |
| 7304 | 7303 | try sema.air_extra.ensureUnusedCapacity( |
| 7305 | 7304 | sema.gpa, |
| 7306 | 7305 | @typeInfo(Air.AsyncCall).Struct.fields.len + args.len, |
| 7307 | 7306 | ); |
| 7308 | 7307 | const call_inst = try block.addInst(.{ |
| 7309 | .tag = .call_async, | |
| 7308 | .tag = .call_async_alloc, | |
| 7310 | 7309 | .data = .{ .ty_pl = .{ |
| 7311 | 7310 | .ty = ptr_frame_ty_ref, |
| 7312 | .payload = sema.addExtraAssumeCapacity(Air.AsyncCall{ | |
| 7313 | .frame_ptr = frame_ptr, | |
| 7311 | .payload = sema.addExtraAssumeCapacity(Air.AsyncCallAlloc{ | |
| 7314 | 7312 | .callee = callee, |
| 7315 | 7313 | .args_len = @intCast(args.len), |
| 7316 | 7314 | }), |
src/arch/aarch64/CodeGen.zig+1| ... | ... | @@ -820,6 +820,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 820 | 820 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 821 | 821 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 822 | 822 | .call_async => try self.airCall(inst, .async_kw), |
| 823 | .call_async_alloc => try self.airCall(inst, .async_kw), | |
| 823 | 824 | |
| 824 | 825 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 825 | 826 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), |
src/arch/arm/CodeGen.zig+1| ... | ... | @@ -804,6 +804,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 804 | 804 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 805 | 805 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 806 | 806 | .call_async => try self.airCall(inst, .async_kw), |
| 807 | .call_async_alloc => try self.airCall(inst, .async_kw), | |
| 807 | 808 | |
| 808 | 809 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 809 | 810 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), |
src/arch/riscv64/CodeGen.zig+1| ... | ... | @@ -639,6 +639,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 639 | 639 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 640 | 640 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 641 | 641 | .call_async => try self.airCall(inst, .async_kw), |
| 642 | .call_async_alloc => try self.airCall(inst, .async_kw), | |
| 642 | 643 | |
| 643 | 644 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 644 | 645 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), |
src/arch/sparc64/CodeGen.zig+1| ... | ... | @@ -652,6 +652,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 652 | 652 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 653 | 653 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 654 | 654 | .call_async => try self.airCall(inst, .async_kw), |
| 655 | .call_async_alloc => try self.airCall(inst, .async_kw), | |
| 655 | 656 | |
| 656 | 657 | .atomic_store_unordered => @panic("TODO try self.airAtomicStore(inst, .Unordered)"), |
| 657 | 658 | .atomic_store_monotonic => @panic("TODO try self.airAtomicStore(inst, .Monotonic)"), |
src/arch/wasm/CodeGen.zig+1| ... | ... | @@ -1931,6 +1931,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1931 | 1931 | .call_never_tail => func.airCall(inst, .never_tail), |
| 1932 | 1932 | .call_never_inline => func.airCall(inst, .never_inline), |
| 1933 | 1933 | .call_async => func.airCall(inst, .async_kw), |
| 1934 | .call_async_alloc => func.airCall(inst, .async_kw), | |
| 1934 | 1935 | |
| 1935 | 1936 | .is_err => func.airIsErr(inst, .i32_ne), |
| 1936 | 1937 | .is_non_err => func.airIsErr(inst, .i32_eq), |
src/arch/x86_64/CodeGen.zig+1| ... | ... | @@ -1902,6 +1902,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1902 | 1902 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 1903 | 1903 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 1904 | 1904 | .call_async => try self.airCall(inst, .async_kw), |
| 1905 | .call_async_alloc => try self.airCall(inst, .async_kw), | |
| 1905 | 1906 | |
| 1906 | 1907 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 1907 | 1908 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), |
src/codegen/c.zig+1| ... | ... | @@ -3001,6 +3001,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3001 | 3001 | .call_never_tail => try airCall(f, inst, .never_tail), |
| 3002 | 3002 | .call_never_inline => try airCall(f, inst, .never_inline), |
| 3003 | 3003 | .call_async => try airCall(f, inst, .async_kw), |
| 3004 | .call_async_alloc => try airCall(f, inst, .async_kw), | |
| 3004 | 3005 | |
| 3005 | 3006 | .float_from_int, |
| 3006 | 3007 | .int_from_float, |
src/codegen/llvm.zig+12-7| ... | ... | @@ -3035,12 +3035,11 @@ pub const Object = struct { |
| 3035 | 3035 | const llvm_struct_ty = o.context.structCreateNamed(name); |
| 3036 | 3036 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls |
| 3037 | 3037 | |
| 3038 | return lowerAsyncFrameType(o, func, llvm_struct_ty); | |
| 3039 | //if (func.isAsync()) { | |
| 3040 | // return lowerAsyncFrameType(o, func, llvm_struct_ty); | |
| 3041 | //} else { | |
| 3042 | // @panic("lower llvm @Frame() type of non-async function"); | |
| 3043 | //} | |
| 3038 | if (func.isAsync()) { | |
| 3039 | return lowerAsyncFrameType(o, func, llvm_struct_ty); | |
| 3040 | } else { | |
| 3041 | @panic("lower llvm @Frame() type of non-async function"); | |
| 3042 | } | |
| 3044 | 3043 | }, |
| 3045 | 3044 | .AnyFrame => return o.context.pointerType(0), |
| 3046 | 3045 | } |
| ... | ... | @@ -4522,6 +4521,7 @@ pub const FuncGen = struct { |
| 4522 | 4521 | .call_always_tail => try self.airCall(inst, .AlwaysTail), |
| 4523 | 4522 | .call_never_tail => try self.airCall(inst, .NeverTail), |
| 4524 | 4523 | .call_never_inline => try self.airCall(inst, .NeverInline), |
| 4524 | .call_async_alloc => try self.airCallAsyncAlloc(inst), | |
| 4525 | 4525 | .call_async => try self.airCallAsync(inst), |
| 4526 | 4526 | |
| 4527 | 4527 | .ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0), |
| ... | ... | @@ -4990,7 +4990,12 @@ pub const FuncGen = struct { |
| 4990 | 4990 | |
| 4991 | 4991 | fn airCallAsync(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 4992 | 4992 | _ = inst; |
| 4993 | return self.todo("lower async call", .{}); | |
| 4993 | return self.todo("lower call_async", .{}); | |
| 4994 | } | |
| 4995 | ||
| 4996 | fn airCallAsyncAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | |
| 4997 | _ = inst; | |
| 4998 | return self.todo("lower call_async_alloc", .{}); | |
| 4994 | 4999 | } |
| 4995 | 5000 | |
| 4996 | 5001 | fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
src/print_air.zig+12-2| ... | ... | @@ -330,6 +330,7 @@ const Writer = struct { |
| 330 | 330 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), |
| 331 | 331 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), |
| 332 | 332 | .call_async => try w.writeCallAsync(s, inst), |
| 333 | .call_async_alloc => try w.writeCallAsyncAlloc(s, inst), | |
| 333 | 334 | |
| 334 | 335 | .dbg_block_begin, .dbg_block_end => {}, |
| 335 | 336 | |
| ... | ... | @@ -705,11 +706,20 @@ const Writer = struct { |
| 705 | 706 | } |
| 706 | 707 | |
| 707 | 708 | fn writeCallAsync(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 709 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | |
| 710 | const extra = w.air.extraData(Air.AsyncCall, pl_op.payload); | |
| 711 | const callee = pl_op.operand; | |
| 712 | const frame_ptr = extra.data.frame_ptr; | |
| 713 | const args: []const Air.Inst.Ref = @ptrCast(w.air.extra[extra.end..][0..extra.data.args_len]); | |
| 714 | return finishWriteCall(w, s, inst, frame_ptr, callee, args); | |
| 715 | } | |
| 716 | ||
| 717 | fn writeCallAsyncAlloc(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 708 | 718 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; |
| 709 | const extra = w.air.extraData(Air.AsyncCall, ty_pl.payload); | |
| 719 | const extra = w.air.extraData(Air.AsyncCallAlloc, ty_pl.payload); | |
| 710 | 720 | const callee = extra.data.callee; |
| 721 | const frame_ptr: Air.Inst.Ref = .none; | |
| 711 | 722 | const args: []const Air.Inst.Ref = @ptrCast(w.air.extra[extra.end..][0..extra.data.args_len]); |
| 712 | const frame_ptr = extra.data.frame_ptr; | |
| 713 | 723 | return finishWriteCall(w, s, inst, frame_ptr, callee, args); |
| 714 | 724 | } |
| 715 | 725 |