| 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,9 +310,14 @@ pub const Inst = struct { |
| 310 | call_never_tail, | 310 | call_never_tail, |
| 311 | /// Same as `call` except with the `never_inline` attribute. | 311 | /// Same as `call` except with the `never_inline` attribute. |
| 312 | call_never_inline, | 312 | call_never_inline, |
| 313 | /// Async function call. | 313 | /// Async function call, using a provided frame pointer. |
| 314 | /// Uses `ty_pl` field with the `AsyncCall` payload. | 314 | /// Uses `pl_op` field with the `AsyncCall` payload. operand is the callee. |
| 315 | /// Result type is always void. | ||
| 315 | call_async, | 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 | /// Count leading zeroes of an integer according to its representation in twos complement. | 321 | /// Count leading zeroes of an integer according to its representation in twos complement. |
| 317 | /// Result type will always be an unsigned integer big enough to fit the answer. | 322 | /// Result type will always be an unsigned integer big enough to fit the answer. |
| 318 | /// Uses the `ty_op` field. | 323 | /// Uses the `ty_op` field. |
| ... | @@ -1076,6 +1081,11 @@ pub const Call = struct { | ... | @@ -1076,6 +1081,11 @@ pub const Call = struct { |
| 1076 | /// Trailing is a list of `Inst.Ref` for every `args_len`. | 1081 | /// Trailing is a list of `Inst.Ref` for every `args_len`. |
| 1077 | pub const AsyncCall = struct { | 1082 | pub const AsyncCall = struct { |
| 1078 | frame_ptr: Inst.Ref, | 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 | callee: Inst.Ref, | 1089 | callee: Inst.Ref, |
| 1080 | args_len: u32, | 1090 | args_len: u32, |
| 1081 | }; | 1091 | }; |
| ... | @@ -1350,7 +1360,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1350,7 +1360,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1350 | .ptr_add, | 1360 | .ptr_add, |
| 1351 | .ptr_sub, | 1361 | .ptr_sub, |
| 1352 | .try_ptr, | 1362 | .try_ptr, |
| 1353 | .call_async, | 1363 | .call_async_alloc, |
| 1354 | => return air.getRefType(datas[inst].ty_pl.ty), | 1364 | => return air.getRefType(datas[inst].ty_pl.ty), |
| 1355 | 1365 | ||
| 1356 | .interned => return ip.typeOf(datas[inst].interned).toType(), | 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,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1429 | .set_err_return_trace, | 1439 | .set_err_return_trace, |
| 1430 | .vector_store_elem, | 1440 | .vector_store_elem, |
| 1431 | .c_va_end, | 1441 | .c_va_end, |
| 1442 | .call_async, | ||
| 1432 | => return Type.void, | 1443 | => return Type.void, |
| 1433 | 1444 | ||
| 1434 | .int_from_ptr, | 1445 | .int_from_ptr, |
| ... | @@ -1595,6 +1606,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1595,6 +1606,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1595 | .call_never_tail, | 1606 | .call_never_tail, |
| 1596 | .call_never_inline, | 1607 | .call_never_inline, |
| 1597 | .call_async, | 1608 | .call_async, |
| 1609 | .call_async_alloc, | ||
| 1598 | .cond_br, | 1610 | .cond_br, |
| 1599 | .switch_br, | 1611 | .switch_br, |
| 1600 | .@"try", | 1612 | .@"try", |
src/Liveness.zig+63-18| ... | @@ -484,15 +484,25 @@ pub fn categorizeOperand( | ... | @@ -484,15 +484,25 @@ pub fn categorizeOperand( |
| 484 | const inst_data = air_datas[inst].pl_op; | 484 | const inst_data = air_datas[inst].pl_op; |
| 485 | const callee = inst_data.operand; | 485 | const callee = inst_data.operand; |
| 486 | const extra = air.extraData(Air.Call, inst_data.payload); | 486 | const extra = air.extraData(Air.Call, inst_data.payload); |
| 487 | const frame_ptr: Air.Inst.Ref = .none; | ||
| 487 | const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]); | 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 | .call_async => { | 491 | .call_async => { |
| 491 | const inst_data = air_datas[inst].ty_pl; | 492 | const inst_data = air_datas[inst].pl_op; |
| 492 | const extra = air.extraData(Air.AsyncCall, inst_data.payload); | 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 | const callee = extra.data.callee; | 502 | const callee = extra.data.callee; |
| 503 | const frame_ptr: Air.Inst.Ref = .none; | ||
| 494 | const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]); | 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 | .select => { | 507 | .select => { |
| 498 | const pl_op = air_datas[inst].pl_op; | 508 | const pl_op = air_datas[inst].pl_op; |
| ... | @@ -661,21 +671,37 @@ pub fn categorizeOperand( | ... | @@ -661,21 +671,37 @@ pub fn categorizeOperand( |
| 661 | } | 671 | } |
| 662 | } | 672 | } |
| 663 | 673 | ||
| 664 | fn categorizeOperandCall( | 674 | pub fn categorizeOperandCall( |
| 665 | l: Liveness, | 675 | l: Liveness, |
| 666 | inst: Air.Inst.Index, | 676 | inst: Air.Inst.Index, |
| 667 | operand_ref: Air.Inst.Ref, | 677 | operand_ref: Air.Inst.Ref, |
| 678 | frame_ptr: Air.Inst.Ref, | ||
| 668 | callee: Air.Inst.Ref, | 679 | callee: Air.Inst.Ref, |
| 669 | args: []const Air.Inst.Ref, | 680 | args: []const Air.Inst.Ref, |
| 670 | ) OperandCategory { | 681 | ) OperandCategory { |
| 671 | if (args.len + 1 <= bpi - 1) { | 682 | const total = args.len + 1 + @intFromBool(frame_ptr != .none); |
| 672 | if (callee == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write); | 683 | if (total <= bpi - 1) { |
| 673 | for (args, 0..) |arg, i| { | 684 | var op_index: OperandInt = 0; |
| 674 | if (arg == operand_ref) return matchOperandSmallIndex(l, inst, @intCast(i + 1), .write); | 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 | return .write; | 695 | return .write; |
| 677 | } | 696 | } |
| 678 | var bt = l.iterateBigTomb(inst); | 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 | if (bt.feed()) { | 705 | if (bt.feed()) { |
| 680 | if (callee == operand_ref) return .tomb; | 706 | if (callee == operand_ref) return .tomb; |
| 681 | } else { | 707 | } else { |
| ... | @@ -1122,18 +1148,28 @@ fn analyzeInst( | ... | @@ -1122,18 +1148,28 @@ fn analyzeInst( |
| 1122 | }, | 1148 | }, |
| 1123 | 1149 | ||
| 1124 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { | 1150 | .call, .call_always_tail, .call_never_tail, .call_never_inline => { |
| 1125 | const inst_data = inst_datas[inst].pl_op; | 1151 | const pl_op = inst_datas[inst].pl_op; |
| 1126 | const callee = inst_data.operand; | 1152 | const callee = pl_op.operand; |
| 1127 | const extra = a.air.extraData(Air.Call, inst_data.payload); | 1153 | const frame_ptr: Air.Inst.Ref = .none; |
| 1154 | const extra = a.air.extraData(Air.Call, pl_op.payload); | ||
| 1128 | const args: []const Air.Inst.Ref = @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]); | 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 | .call_async => { | 1158 | .call_async => { |
| 1132 | const inst_data = inst_datas[inst].ty_pl; | 1159 | const inst_data = inst_datas[inst].pl_op; |
| 1133 | const extra = a.air.extraData(Air.AsyncCall, inst_data.payload); | 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 | const callee = extra.data.callee; | 1169 | const callee = extra.data.callee; |
| 1170 | const frame_ptr: Air.Inst.Ref = .none; | ||
| 1135 | const args: []const Air.Inst.Ref = @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]); | 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 | .select => { | 1174 | .select => { |
| 1139 | const pl_op = inst_datas[inst].pl_op; | 1175 | const pl_op = inst_datas[inst].pl_op; |
| ... | @@ -1267,24 +1303,33 @@ fn analyzeInstCall( | ... | @@ -1267,24 +1303,33 @@ fn analyzeInstCall( |
| 1267 | comptime pass: LivenessPass, | 1303 | comptime pass: LivenessPass, |
| 1268 | data: *LivenessPassData(pass), | 1304 | data: *LivenessPassData(pass), |
| 1269 | inst: Air.Inst.Index, | 1305 | inst: Air.Inst.Index, |
| 1306 | frame_ptr: Air.Inst.Ref, | ||
| 1270 | callee: Air.Inst.Ref, | 1307 | callee: Air.Inst.Ref, |
| 1271 | args: []const Air.Inst.Ref, | 1308 | args: []const Air.Inst.Ref, |
| 1272 | ) Allocator.Error!void { | 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 | var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); | 1312 | var buf = [1]Air.Inst.Ref{.none} ** (bpi - 1); |
| 1275 | buf[0] = callee; | 1313 | var op_index: OperandInt = 0; |
| 1276 | @memcpy(buf[1..][0..args.len], args); | 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 | return analyzeOperands(a, pass, data, inst, buf); | 1321 | return analyzeOperands(a, pass, data, inst, buf); |
| 1278 | } | 1322 | } |
| 1279 | 1323 | ||
| 1280 | var big = try AnalyzeBigOperands(pass).init(a, data, inst, args.len + 1); | 1324 | var big = try AnalyzeBigOperands(pass).init(a, data, inst, args.len + 1); |
| 1281 | defer big.deinit(); | 1325 | defer big.deinit(); |
| 1326 | if (frame_ptr != .none) try big.feed(frame_ptr); | ||
| 1327 | try big.feed(callee); | ||
| 1282 | var i: usize = args.len; | 1328 | var i: usize = args.len; |
| 1283 | while (i > 0) { | 1329 | while (i > 0) { |
| 1284 | i -= 1; | 1330 | i -= 1; |
| 1285 | try big.feed(args[i]); | 1331 | try big.feed(args[i]); |
| 1286 | } | 1332 | } |
| 1287 | try big.feed(callee); | ||
| 1288 | return big.finish(); | 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,8 +350,24 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 350 | try self.verifyInst(inst); | 350 | try self.verifyInst(inst); |
| 351 | }, | 351 | }, |
| 352 | .call_async => { | 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 | const ty_pl = data[inst].ty_pl; | 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 | const args: []const Air.Inst.Ref = @ptrCast( | 371 | const args: []const Air.Inst.Ref = @ptrCast( |
| 356 | self.air.extra[extra.end..][0..extra.data.args_len], | 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,18 +7299,16 @@ fn addAsyncCallInst( |
| 7299 | ) Allocator.Error!Air.Inst.Ref { | 7299 | ) Allocator.Error!Air.Inst.Ref { |
| 7300 | const mod = sema.mod; | 7300 | const mod = sema.mod; |
| 7301 | const ptr_frame_ty = try mod.singleMutPtrType(try mod.asyncFrameType(callee_fn)); | 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 | const ptr_frame_ty_ref = try sema.addType(ptr_frame_ty); | 7302 | const ptr_frame_ty_ref = try sema.addType(ptr_frame_ty); |
| 7304 | try sema.air_extra.ensureUnusedCapacity( | 7303 | try sema.air_extra.ensureUnusedCapacity( |
| 7305 | sema.gpa, | 7304 | sema.gpa, |
| 7306 | @typeInfo(Air.AsyncCall).Struct.fields.len + args.len, | 7305 | @typeInfo(Air.AsyncCall).Struct.fields.len + args.len, |
| 7307 | ); | 7306 | ); |
| 7308 | const call_inst = try block.addInst(.{ | 7307 | const call_inst = try block.addInst(.{ |
| 7309 | .tag = .call_async, | 7308 | .tag = .call_async_alloc, |
| 7310 | .data = .{ .ty_pl = .{ | 7309 | .data = .{ .ty_pl = .{ |
| 7311 | .ty = ptr_frame_ty_ref, | 7310 | .ty = ptr_frame_ty_ref, |
| 7312 | .payload = sema.addExtraAssumeCapacity(Air.AsyncCall{ | 7311 | .payload = sema.addExtraAssumeCapacity(Air.AsyncCallAlloc{ |
| 7313 | .frame_ptr = frame_ptr, | ||
| 7314 | .callee = callee, | 7312 | .callee = callee, |
| 7315 | .args_len = @intCast(args.len), | 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,6 +820,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 820 | .call_never_tail => try self.airCall(inst, .never_tail), | 820 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 821 | .call_never_inline => try self.airCall(inst, .never_inline), | 821 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 822 | .call_async => try self.airCall(inst, .async_kw), | 822 | .call_async => try self.airCall(inst, .async_kw), |
| 823 | .call_async_alloc => try self.airCall(inst, .async_kw), | ||
| 823 | 824 | ||
| 824 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), | 825 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 825 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), | 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,6 +804,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 804 | .call_never_tail => try self.airCall(inst, .never_tail), | 804 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 805 | .call_never_inline => try self.airCall(inst, .never_inline), | 805 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 806 | .call_async => try self.airCall(inst, .async_kw), | 806 | .call_async => try self.airCall(inst, .async_kw), |
| 807 | .call_async_alloc => try self.airCall(inst, .async_kw), | ||
| 807 | 808 | ||
| 808 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), | 809 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 809 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), | 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,6 +639,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 639 | .call_never_tail => try self.airCall(inst, .never_tail), | 639 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 640 | .call_never_inline => try self.airCall(inst, .never_inline), | 640 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 641 | .call_async => try self.airCall(inst, .async_kw), | 641 | .call_async => try self.airCall(inst, .async_kw), |
| 642 | .call_async_alloc => try self.airCall(inst, .async_kw), | ||
| 642 | 643 | ||
| 643 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), | 644 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 644 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), | 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,6 +652,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 652 | .call_never_tail => try self.airCall(inst, .never_tail), | 652 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 653 | .call_never_inline => try self.airCall(inst, .never_inline), | 653 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 654 | .call_async => try self.airCall(inst, .async_kw), | 654 | .call_async => try self.airCall(inst, .async_kw), |
| 655 | .call_async_alloc => try self.airCall(inst, .async_kw), | ||
| 655 | 656 | ||
| 656 | .atomic_store_unordered => @panic("TODO try self.airAtomicStore(inst, .Unordered)"), | 657 | .atomic_store_unordered => @panic("TODO try self.airAtomicStore(inst, .Unordered)"), |
| 657 | .atomic_store_monotonic => @panic("TODO try self.airAtomicStore(inst, .Monotonic)"), | 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,6 +1931,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1931 | .call_never_tail => func.airCall(inst, .never_tail), | 1931 | .call_never_tail => func.airCall(inst, .never_tail), |
| 1932 | .call_never_inline => func.airCall(inst, .never_inline), | 1932 | .call_never_inline => func.airCall(inst, .never_inline), |
| 1933 | .call_async => func.airCall(inst, .async_kw), | 1933 | .call_async => func.airCall(inst, .async_kw), |
| 1934 | .call_async_alloc => func.airCall(inst, .async_kw), | ||
| 1934 | 1935 | ||
| 1935 | .is_err => func.airIsErr(inst, .i32_ne), | 1936 | .is_err => func.airIsErr(inst, .i32_ne), |
| 1936 | .is_non_err => func.airIsErr(inst, .i32_eq), | 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,6 +1902,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1902 | .call_never_tail => try self.airCall(inst, .never_tail), | 1902 | .call_never_tail => try self.airCall(inst, .never_tail), |
| 1903 | .call_never_inline => try self.airCall(inst, .never_inline), | 1903 | .call_never_inline => try self.airCall(inst, .never_inline), |
| 1904 | .call_async => try self.airCall(inst, .async_kw), | 1904 | .call_async => try self.airCall(inst, .async_kw), |
| 1905 | .call_async_alloc => try self.airCall(inst, .async_kw), | ||
| 1905 | 1906 | ||
| 1906 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), | 1907 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 1907 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), | 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,6 +3001,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3001 | .call_never_tail => try airCall(f, inst, .never_tail), | 3001 | .call_never_tail => try airCall(f, inst, .never_tail), |
| 3002 | .call_never_inline => try airCall(f, inst, .never_inline), | 3002 | .call_never_inline => try airCall(f, inst, .never_inline), |
| 3003 | .call_async => try airCall(f, inst, .async_kw), | 3003 | .call_async => try airCall(f, inst, .async_kw), |
| 3004 | .call_async_alloc => try airCall(f, inst, .async_kw), | ||
| 3004 | 3005 | ||
| 3005 | .float_from_int, | 3006 | .float_from_int, |
| 3006 | .int_from_float, | 3007 | .int_from_float, |
src/codegen/llvm.zig+12-7| ... | @@ -3035,12 +3035,11 @@ pub const Object = struct { | ... | @@ -3035,12 +3035,11 @@ pub const Object = struct { |
| 3035 | const llvm_struct_ty = o.context.structCreateNamed(name); | 3035 | const llvm_struct_ty = o.context.structCreateNamed(name); |
| 3036 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | 3036 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls |
| 3037 | 3037 | ||
| 3038 | return lowerAsyncFrameType(o, func, llvm_struct_ty); | 3038 | if (func.isAsync()) { |
| 3039 | //if (func.isAsync()) { | 3039 | return lowerAsyncFrameType(o, func, llvm_struct_ty); |
| 3040 | // return lowerAsyncFrameType(o, func, llvm_struct_ty); | 3040 | } else { |
| 3041 | //} else { | 3041 | @panic("lower llvm @Frame() type of non-async function"); |
| 3042 | // @panic("lower llvm @Frame() type of non-async function"); | 3042 | } |
| 3043 | //} | ||
| 3044 | }, | 3043 | }, |
| 3045 | .AnyFrame => return o.context.pointerType(0), | 3044 | .AnyFrame => return o.context.pointerType(0), |
| 3046 | } | 3045 | } |
| ... | @@ -4522,6 +4521,7 @@ pub const FuncGen = struct { | ... | @@ -4522,6 +4521,7 @@ pub const FuncGen = struct { |
| 4522 | .call_always_tail => try self.airCall(inst, .AlwaysTail), | 4521 | .call_always_tail => try self.airCall(inst, .AlwaysTail), |
| 4523 | .call_never_tail => try self.airCall(inst, .NeverTail), | 4522 | .call_never_tail => try self.airCall(inst, .NeverTail), |
| 4524 | .call_never_inline => try self.airCall(inst, .NeverInline), | 4523 | .call_never_inline => try self.airCall(inst, .NeverInline), |
| 4524 | .call_async_alloc => try self.airCallAsyncAlloc(inst), | ||
| 4525 | .call_async => try self.airCallAsync(inst), | 4525 | .call_async => try self.airCallAsync(inst), |
| 4526 | 4526 | ||
| 4527 | .ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0), | 4527 | .ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0), |
| ... | @@ -4990,7 +4990,12 @@ pub const FuncGen = struct { | ... | @@ -4990,7 +4990,12 @@ pub const FuncGen = struct { |
| 4990 | 4990 | ||
| 4991 | fn airCallAsync(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 4991 | fn airCallAsync(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 4992 | _ = inst; | 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 | fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { | 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,6 +330,7 @@ const Writer = struct { |
| 330 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), | 330 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), |
| 331 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), | 331 | .vector_store_elem => try w.writeVectorStoreElem(s, inst), |
| 332 | .call_async => try w.writeCallAsync(s, inst), | 332 | .call_async => try w.writeCallAsync(s, inst), |
| 333 | .call_async_alloc => try w.writeCallAsyncAlloc(s, inst), | ||
| 333 | 334 | ||
| 334 | .dbg_block_begin, .dbg_block_end => {}, | 335 | .dbg_block_begin, .dbg_block_end => {}, |
| 335 | 336 | ||
| ... | @@ -705,11 +706,20 @@ const Writer = struct { | ... | @@ -705,11 +706,20 @@ const Writer = struct { |
| 705 | } | 706 | } |
| 706 | 707 | ||
| 707 | fn writeCallAsync(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 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 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | 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 | const callee = extra.data.callee; | 720 | const callee = extra.data.callee; |
| 721 | const frame_ptr: Air.Inst.Ref = .none; | ||
| 711 | const args: []const Air.Inst.Ref = @ptrCast(w.air.extra[extra.end..][0..extra.data.args_len]); | 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 | return finishWriteCall(w, s, inst, frame_ptr, callee, args); | 723 | return finishWriteCall(w, s, inst, frame_ptr, callee, args); |
| 714 | } | 724 | } |
| 715 | 725 |