| author | |
| committer | |
| log | aa688567f556f9d24cae25f087adf90d96f6906f |
| tree | 80482843f4312873cc980e02fce787a0db47e45a |
| parent | 671c2acf47d17551266f3760698181c83cd96090 |
This prevents the possibility of not emitting a `.dbg_inline_end`
instruction and reduces the allocation requirements of the backends.
Closes #1909315 files changed, 414 insertions(+), 345 deletions(-)
src/Air.zig+11-14| ... | ... | @@ -443,12 +443,9 @@ pub const Inst = struct { |
| 443 | 443 | /// Result type is always void. |
| 444 | 444 | /// Uses the `dbg_stmt` field. |
| 445 | 445 | dbg_stmt, |
| 446 | /// Marks the start of an inline call. | |
| 447 | /// Uses the `ty_fn` field. | |
| 448 | dbg_inline_begin, | |
| 449 | /// Marks the end of an inline call. | |
| 450 | /// Uses the `ty_fn` field. | |
| 451 | dbg_inline_end, | |
| 446 | /// A block that represents an inlined function call. | |
| 447 | /// Uses the `ty_pl` field. Payload is `DbgInlineBlock`. | |
| 448 | dbg_inline_block, | |
| 452 | 449 | /// Marks the beginning of a local variable. The operand is a pointer pointing |
| 453 | 450 | /// to the storage for the variable. The local may be a const or a var. |
| 454 | 451 | /// Result type is always void. |
| ... | ... | @@ -1051,10 +1048,6 @@ pub const Inst = struct { |
| 1051 | 1048 | // Index into a different array. |
| 1052 | 1049 | payload: u32, |
| 1053 | 1050 | }, |
| 1054 | ty_fn: struct { | |
| 1055 | ty: Ref, | |
| 1056 | func: InternPool.Index, | |
| 1057 | }, | |
| 1058 | 1051 | br: struct { |
| 1059 | 1052 | block_inst: Index, |
| 1060 | 1053 | operand: Ref, |
| ... | ... | @@ -1117,6 +1110,12 @@ pub const Block = struct { |
| 1117 | 1110 | body_len: u32, |
| 1118 | 1111 | }; |
| 1119 | 1112 | |
| 1113 | /// Trailing is a list of instruction indexes for every `body_len`. | |
| 1114 | pub const DbgInlineBlock = struct { | |
| 1115 | func: InternPool.Index, | |
| 1116 | body_len: u32, | |
| 1117 | }; | |
| 1118 | ||
| 1120 | 1119 | /// Trailing is a list of `Inst.Ref` for every `args_len`. |
| 1121 | 1120 | pub const Call = struct { |
| 1122 | 1121 | args_len: u32, |
| ... | ... | @@ -1371,6 +1370,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1371 | 1370 | |
| 1372 | 1371 | .assembly, |
| 1373 | 1372 | .block, |
| 1373 | .dbg_inline_block, | |
| 1374 | 1374 | .struct_field_ptr, |
| 1375 | 1375 | .struct_field_val, |
| 1376 | 1376 | .slice_elem_ptr, |
| ... | ... | @@ -1448,8 +1448,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1448 | 1448 | |
| 1449 | 1449 | .breakpoint, |
| 1450 | 1450 | .dbg_stmt, |
| 1451 | .dbg_inline_begin, | |
| 1452 | .dbg_inline_end, | |
| 1453 | 1451 | .dbg_var_ptr, |
| 1454 | 1452 | .dbg_var_val, |
| 1455 | 1453 | .store, |
| ... | ... | @@ -1606,8 +1604,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1606 | 1604 | .@"try", |
| 1607 | 1605 | .try_ptr, |
| 1608 | 1606 | .dbg_stmt, |
| 1609 | .dbg_inline_begin, | |
| 1610 | .dbg_inline_end, | |
| 1607 | .dbg_inline_block, | |
| 1611 | 1608 | .dbg_var_ptr, |
| 1612 | 1609 | .dbg_var_val, |
| 1613 | 1610 | .ret, |
src/Liveness.zig+25-14| ... | ... | @@ -327,8 +327,6 @@ pub fn categorizeOperand( |
| 327 | 327 | .trap, |
| 328 | 328 | .breakpoint, |
| 329 | 329 | .dbg_stmt, |
| 330 | .dbg_inline_begin, | |
| 331 | .dbg_inline_end, | |
| 332 | 330 | .unreach, |
| 333 | 331 | .ret_addr, |
| 334 | 332 | .frame_addr, |
| ... | ... | @@ -604,9 +602,19 @@ pub fn categorizeOperand( |
| 604 | 602 | .assembly => { |
| 605 | 603 | return .complex; |
| 606 | 604 | }, |
| 607 | .block => { | |
| 608 | const extra = air.extraData(Air.Block, air_datas[@intFromEnum(inst)].ty_pl.payload); | |
| 609 | const body: []const Air.Inst.Index = @ptrCast(air.extra[extra.end..][0..extra.data.body_len]); | |
| 605 | .block, .dbg_inline_block => |tag| { | |
| 606 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | |
| 607 | const body: []const Air.Inst.Index = @ptrCast(switch (tag) { | |
| 608 | inline .block, .dbg_inline_block => |comptime_tag| body: { | |
| 609 | const extra = air.extraData(switch (comptime_tag) { | |
| 610 | .block => Air.Block, | |
| 611 | .dbg_inline_block => Air.DbgInlineBlock, | |
| 612 | else => unreachable, | |
| 613 | }, ty_pl.payload); | |
| 614 | break :body air.extra[extra.end..][0..extra.data.body_len]; | |
| 615 | }, | |
| 616 | else => unreachable, | |
| 617 | }); | |
| 610 | 618 | |
| 611 | 619 | if (body.len == 1 and air_tags[@intFromEnum(body[0])] == .cond_br) { |
| 612 | 620 | // Peephole optimization for "panic-like" conditionals, which have |
| ... | ... | @@ -963,8 +971,6 @@ fn analyzeInst( |
| 963 | 971 | .ret_ptr, |
| 964 | 972 | .breakpoint, |
| 965 | 973 | .dbg_stmt, |
| 966 | .dbg_inline_begin, | |
| 967 | .dbg_inline_end, | |
| 968 | 974 | .fence, |
| 969 | 975 | .ret_addr, |
| 970 | 976 | .frame_addr, |
| ... | ... | @@ -1235,7 +1241,15 @@ fn analyzeInst( |
| 1235 | 1241 | return big.finish(); |
| 1236 | 1242 | }, |
| 1237 | 1243 | |
| 1238 | .block => return analyzeInstBlock(a, pass, data, inst), | |
| 1244 | inline .block, .dbg_inline_block => |comptime_tag| { | |
| 1245 | const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl; | |
| 1246 | const extra = a.air.extraData(switch (comptime_tag) { | |
| 1247 | .block => Air.Block, | |
| 1248 | .dbg_inline_block => Air.DbgInlineBlock, | |
| 1249 | else => unreachable, | |
| 1250 | }, ty_pl.payload); | |
| 1251 | return analyzeInstBlock(a, pass, data, inst, ty_pl.ty, @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len])); | |
| 1252 | }, | |
| 1239 | 1253 | .loop => return analyzeInstLoop(a, pass, data, inst), |
| 1240 | 1254 | |
| 1241 | 1255 | .@"try" => return analyzeInstCondBr(a, pass, data, inst, .@"try"), |
| ... | ... | @@ -1369,12 +1383,9 @@ fn analyzeInstBlock( |
| 1369 | 1383 | comptime pass: LivenessPass, |
| 1370 | 1384 | data: *LivenessPassData(pass), |
| 1371 | 1385 | inst: Air.Inst.Index, |
| 1386 | ty: Air.Inst.Ref, | |
| 1387 | body: []const Air.Inst.Index, | |
| 1372 | 1388 | ) !void { |
| 1373 | const inst_datas = a.air.instructions.items(.data); | |
| 1374 | const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl; | |
| 1375 | const extra = a.air.extraData(Air.Block, ty_pl.payload); | |
| 1376 | const body: []const Air.Inst.Index = @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len]); | |
| 1377 | ||
| 1378 | 1389 | const gpa = a.gpa; |
| 1379 | 1390 | |
| 1380 | 1391 | // We actually want to do `analyzeOperands` *first*, since our result logically doesn't |
| ... | ... | @@ -1403,7 +1414,7 @@ fn analyzeInstBlock( |
| 1403 | 1414 | |
| 1404 | 1415 | // If the block is noreturn, block deaths not only aren't useful, they're impossible to |
| 1405 | 1416 | // find: there could be more stuff alive after the block than before it! |
| 1406 | if (!a.intern_pool.isNoReturn(ty_pl.ty.toType().ip_index)) { | |
| 1417 | if (!a.intern_pool.isNoReturn(ty.toType().toIntern())) { | |
| 1407 | 1418 | // The block kills the difference in the live sets |
| 1408 | 1419 | const block_scope = data.block_scopes.get(inst).?; |
| 1409 | 1420 | const num_deaths = data.live_set.count() - block_scope.live_set.count(); |
src/Liveness/Verify.zig+14-7| ... | ... | @@ -29,7 +29,7 @@ const LiveMap = std.AutoHashMapUnmanaged(Air.Inst.Index, void); |
| 29 | 29 | |
| 30 | 30 | fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 31 | 31 | const ip = self.intern_pool; |
| 32 | const tag = self.air.instructions.items(.tag); | |
| 32 | const tags = self.air.instructions.items(.tag); | |
| 33 | 33 | const data = self.air.instructions.items(.data); |
| 34 | 34 | for (body) |inst| { |
| 35 | 35 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) { |
| ... | ... | @@ -37,7 +37,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 37 | 37 | continue; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | switch (tag[@intFromEnum(inst)]) { | |
| 40 | switch (tags[@intFromEnum(inst)]) { | |
| 41 | 41 | // no operands |
| 42 | 42 | .arg, |
| 43 | 43 | .alloc, |
| ... | ... | @@ -46,8 +46,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 46 | 46 | .ret_ptr, |
| 47 | 47 | .breakpoint, |
| 48 | 48 | .dbg_stmt, |
| 49 | .dbg_inline_begin, | |
| 50 | .dbg_inline_end, | |
| 51 | 49 | .fence, |
| 52 | 50 | .ret_addr, |
| 53 | 51 | .frame_addr, |
| ... | ... | @@ -431,11 +429,20 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 431 | 429 | } |
| 432 | 430 | try self.verifyInst(inst); |
| 433 | 431 | }, |
| 434 | .block => { | |
| 432 | .block, .dbg_inline_block => |tag| { | |
| 435 | 433 | const ty_pl = data[@intFromEnum(inst)].ty_pl; |
| 436 | 434 | const block_ty = ty_pl.ty.toType(); |
| 437 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 438 | const block_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 435 | const block_body: []const Air.Inst.Index = @ptrCast(switch (tag) { | |
| 436 | inline .block, .dbg_inline_block => |comptime_tag| body: { | |
| 437 | const extra = self.air.extraData(switch (comptime_tag) { | |
| 438 | .block => Air.Block, | |
| 439 | .dbg_inline_block => Air.DbgInlineBlock, | |
| 440 | else => unreachable, | |
| 441 | }, ty_pl.payload); | |
| 442 | break :body self.air.extra[extra.end..][0..extra.data.body_len]; | |
| 443 | }, | |
| 444 | else => unreachable, | |
| 445 | }); | |
| 439 | 446 | const block_liveness = self.liveness.getBlock(inst); |
| 440 | 447 | |
| 441 | 448 | var orig_live = try self.live.clone(self.gpa); |
src/Sema.zig+89-66| ... | ... | @@ -5939,6 +5939,7 @@ fn resolveBlockBody( |
| 5939 | 5939 | if (child_block.is_comptime) { |
| 5940 | 5940 | return sema.resolveInlineBody(child_block, body, body_inst); |
| 5941 | 5941 | } else { |
| 5942 | assert(sema.air_instructions.items(.tag)[@intFromEnum(merges.block_inst)] == .block); | |
| 5942 | 5943 | var need_debug_scope = false; |
| 5943 | 5944 | child_block.need_debug_scope = &need_debug_scope; |
| 5944 | 5945 | if (sema.analyzeBodyInner(child_block, body)) |_| { |
| ... | ... | @@ -6002,18 +6003,44 @@ fn resolveAnalyzedBlock( |
| 6002 | 6003 | assert(child_block.instructions.items.len != 0); |
| 6003 | 6004 | assert(sema.typeOf(child_block.instructions.items[child_block.instructions.items.len - 1].toRef()).isNoReturn(mod)); |
| 6004 | 6005 | |
| 6006 | const block_tag = sema.air_instructions.items(.tag)[@intFromEnum(merges.block_inst)]; | |
| 6007 | switch (block_tag) { | |
| 6008 | .block => {}, | |
| 6009 | .dbg_inline_block => assert(need_debug_scope), | |
| 6010 | else => unreachable, | |
| 6011 | } | |
| 6005 | 6012 | if (merges.results.items.len == 0) { |
| 6006 | // No need for a block instruction. We can put the new instructions | |
| 6007 | // directly into the parent block. | |
| 6008 | if (need_debug_scope) { | |
| 6009 | // The code following this block is unreachable, as the block has no | |
| 6010 | // merges, so we don't necessarily need to emit this as an AIR block. | |
| 6011 | // However, we need a block *somewhere* to make the scoping correct, | |
| 6012 | // so forward this request to the parent block. | |
| 6013 | if (parent_block.need_debug_scope) |ptr| ptr.* = true; | |
| 6014 | } | |
| 6015 | try parent_block.instructions.appendSlice(gpa, child_block.instructions.items); | |
| 6016 | return child_block.instructions.items[child_block.instructions.items.len - 1].toRef(); | |
| 6013 | switch (block_tag) { | |
| 6014 | .block => { | |
| 6015 | // No need for a block instruction. We can put the new instructions | |
| 6016 | // directly into the parent block. | |
| 6017 | if (need_debug_scope) { | |
| 6018 | // The code following this block is unreachable, as the block has no | |
| 6019 | // merges, so we don't necessarily need to emit this as an AIR block. | |
| 6020 | // However, we need a block *somewhere* to make the scoping correct, | |
| 6021 | // so forward this request to the parent block. | |
| 6022 | if (parent_block.need_debug_scope) |ptr| ptr.* = true; | |
| 6023 | } | |
| 6024 | try parent_block.instructions.appendSlice(gpa, child_block.instructions.items); | |
| 6025 | return child_block.instructions.items[child_block.instructions.items.len - 1].toRef(); | |
| 6026 | }, | |
| 6027 | .dbg_inline_block => { | |
| 6028 | // Create a block containing all instruction from the body. | |
| 6029 | try parent_block.instructions.append(gpa, merges.block_inst); | |
| 6030 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len + | |
| 6031 | child_block.instructions.items.len); | |
| 6032 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6033 | .ty = .noreturn_type, | |
| 6034 | .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{ | |
| 6035 | .func = child_block.inlining.?.func, | |
| 6036 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6037 | }), | |
| 6038 | } }; | |
| 6039 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); | |
| 6040 | return merges.block_inst.toRef(); | |
| 6041 | }, | |
| 6042 | else => unreachable, | |
| 6043 | } | |
| 6017 | 6044 | } |
| 6018 | 6045 | if (merges.results.items.len == 1) { |
| 6019 | 6046 | // If the `break` is trailing, we may be able to elide the AIR block here |
| ... | ... | @@ -6036,14 +6063,30 @@ fn resolveAnalyzedBlock( |
| 6036 | 6063 | if (try sema.resolveValue(merges.results.items[0])) |result_val| { |
| 6037 | 6064 | // Create a block containing all instruction from the body. |
| 6038 | 6065 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 6039 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | |
| 6040 | child_block.instructions.items.len); | |
| 6041 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6042 | .ty = .void_type, | |
| 6043 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | |
| 6044 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6045 | }), | |
| 6046 | } }; | |
| 6066 | switch (block_tag) { | |
| 6067 | .block => { | |
| 6068 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | |
| 6069 | child_block.instructions.items.len); | |
| 6070 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6071 | .ty = .void_type, | |
| 6072 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | |
| 6073 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6074 | }), | |
| 6075 | } }; | |
| 6076 | }, | |
| 6077 | .dbg_inline_block => { | |
| 6078 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len + | |
| 6079 | child_block.instructions.items.len); | |
| 6080 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6081 | .ty = .void_type, | |
| 6082 | .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{ | |
| 6083 | .func = child_block.inlining.?.func, | |
| 6084 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6085 | }), | |
| 6086 | } }; | |
| 6087 | }, | |
| 6088 | else => unreachable, | |
| 6089 | } | |
| 6047 | 6090 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); |
| 6048 | 6091 | // Rewrite the break to just give value {}; the value is |
| 6049 | 6092 | // comptime-known and will be returned directly. |
| ... | ... | @@ -6079,14 +6122,30 @@ fn resolveAnalyzedBlock( |
| 6079 | 6122 | return sema.failWithOwnedErrorMsg(child_block, msg); |
| 6080 | 6123 | } |
| 6081 | 6124 | const ty_inst = Air.internedToRef(resolved_ty.toIntern()); |
| 6082 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | |
| 6083 | child_block.instructions.items.len); | |
| 6084 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6085 | .ty = ty_inst, | |
| 6086 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | |
| 6087 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6088 | }), | |
| 6089 | } }; | |
| 6125 | switch (block_tag) { | |
| 6126 | .block => { | |
| 6127 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | |
| 6128 | child_block.instructions.items.len); | |
| 6129 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6130 | .ty = ty_inst, | |
| 6131 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | |
| 6132 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6133 | }), | |
| 6134 | } }; | |
| 6135 | }, | |
| 6136 | .dbg_inline_block => { | |
| 6137 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).Struct.fields.len + | |
| 6138 | child_block.instructions.items.len); | |
| 6139 | sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ | |
| 6140 | .ty = ty_inst, | |
| 6141 | .payload = sema.addExtraAssumeCapacity(Air.DbgInlineBlock{ | |
| 6142 | .func = child_block.inlining.?.func, | |
| 6143 | .body_len = @intCast(child_block.instructions.items.len), | |
| 6144 | }), | |
| 6145 | } }; | |
| 6146 | }, | |
| 6147 | else => unreachable, | |
| 6148 | } | |
| 6090 | 6149 | sema.air_extra.appendSliceAssumeCapacity(@ptrCast(child_block.instructions.items)); |
| 6091 | 6150 | // Now that the block has its type resolved, we need to go back into all the break |
| 6092 | 6151 | // instructions, and insert type coercion on the operands. |
| ... | ... | @@ -7379,7 +7438,6 @@ fn analyzeCall( |
| 7379 | 7438 | .needed_comptime_reason = "function being called at comptime must be comptime-known", |
| 7380 | 7439 | .block_comptime_reason = comptime_reason, |
| 7381 | 7440 | }); |
| 7382 | const prev_fn_index = sema.func_index; | |
| 7383 | 7441 | const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { |
| 7384 | 7442 | .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{ |
| 7385 | 7443 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), |
| ... | ... | @@ -7415,9 +7473,10 @@ fn analyzeCall( |
| 7415 | 7473 | // set to in the `Block`. |
| 7416 | 7474 | // This block instruction will be used to capture the return value from the |
| 7417 | 7475 | // inlined function. |
| 7476 | const need_debug_scope = !is_comptime_call and !block.is_typeof and !block.ownerModule().strip; | |
| 7418 | 7477 | const block_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); |
| 7419 | 7478 | try sema.air_instructions.append(gpa, .{ |
| 7420 | .tag = .block, | |
| 7479 | .tag = if (need_debug_scope) .dbg_inline_block else .block, | |
| 7421 | 7480 | .data = undefined, |
| 7422 | 7481 | }); |
| 7423 | 7482 | // This one is shared among sub-blocks within the same callee, but not |
| ... | ... | @@ -7584,10 +7643,7 @@ fn analyzeCall( |
| 7584 | 7643 | } |
| 7585 | 7644 | |
| 7586 | 7645 | new_fn_info.return_type = sema.fn_ret_ty.toIntern(); |
| 7587 | const new_func_resolved_ty = try mod.funcType(new_fn_info); | |
| 7588 | 7646 | if (!is_comptime_call and !block.is_typeof) { |
| 7589 | try emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin); | |
| 7590 | ||
| 7591 | 7647 | const zir_tags = sema.code.instructions.items(.tag); |
| 7592 | 7648 | for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) { |
| 7593 | 7649 | .param, .param_comptime => { |
| ... | ... | @@ -7626,21 +7682,9 @@ fn analyzeCall( |
| 7626 | 7682 | error.ComptimeReturn => break :result inlining.comptime_result, |
| 7627 | 7683 | else => |e| return e, |
| 7628 | 7684 | }; |
| 7629 | break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, false); | |
| 7685 | break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, need_debug_scope); | |
| 7630 | 7686 | }; |
| 7631 | 7687 | |
| 7632 | if (!is_comptime_call and !block.is_typeof and | |
| 7633 | sema.typeOf(result).zigTypeTag(mod) != .NoReturn) | |
| 7634 | { | |
| 7635 | try emitDbgInline( | |
| 7636 | block, | |
| 7637 | module_fn_index, | |
| 7638 | prev_fn_index, | |
| 7639 | mod.funcOwnerDeclPtr(sema.func_index).ty, | |
| 7640 | .dbg_inline_end, | |
| 7641 | ); | |
| 7642 | } | |
| 7643 | ||
| 7644 | 7688 | if (should_memoize and is_comptime_call) { |
| 7645 | 7689 | const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined); |
| 7646 | 7690 | const result_interned = try result_val.intern2(sema.fn_ret_ty, mod); |
| ... | ... | @@ -8207,27 +8251,6 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 8207 | 8251 | } |
| 8208 | 8252 | } |
| 8209 | 8253 | |
| 8210 | fn emitDbgInline( | |
| 8211 | block: *Block, | |
| 8212 | old_func: InternPool.Index, | |
| 8213 | new_func: InternPool.Index, | |
| 8214 | new_func_ty: Type, | |
| 8215 | tag: Air.Inst.Tag, | |
| 8216 | ) CompileError!void { | |
| 8217 | if (block.ownerModule().strip) return; | |
| 8218 | ||
| 8219 | // Recursive inline call; no dbg_inline needed. | |
| 8220 | if (old_func == new_func) return; | |
| 8221 | ||
| 8222 | _ = try block.addInst(.{ | |
| 8223 | .tag = tag, | |
| 8224 | .data = .{ .ty_fn = .{ | |
| 8225 | .ty = Air.internedToRef(new_func_ty.toIntern()), | |
| 8226 | .func = new_func, | |
| 8227 | } }, | |
| 8228 | }); | |
| 8229 | } | |
| 8230 | ||
| 8231 | 8254 | fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8232 | 8255 | const mod = sema.mod; |
| 8233 | 8256 | const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type; |
src/arch/aarch64/CodeGen.zig+13-12| ... | ... | @@ -747,7 +747,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 747 | 747 | .frame_addr => try self.airFrameAddress(inst), |
| 748 | 748 | .fence => try self.airFence(), |
| 749 | 749 | .cond_br => try self.airCondBr(inst), |
| 750 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 751 | 750 | .fptrunc => try self.airFptrunc(inst), |
| 752 | 751 | .fpext => try self.airFpext(inst), |
| 753 | 752 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -805,14 +804,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 805 | 804 | .@"try" => try self.airTry(inst), |
| 806 | 805 | .try_ptr => try self.airTryPtr(inst), |
| 807 | 806 | |
| 807 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 808 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 808 | 809 | .dbg_var_ptr, |
| 809 | 810 | .dbg_var_val, |
| 810 | 811 | => try self.airDbgVar(inst), |
| 811 | 812 | |
| 812 | .dbg_inline_begin, | |
| 813 | .dbg_inline_end, | |
| 814 | => try self.airDbgInline(inst), | |
| 815 | ||
| 816 | 813 | .call => try self.airCall(inst, .auto), |
| 817 | 814 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 818 | 815 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -4621,13 +4618,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4621 | 4618 | return self.finishAirBookkeeping(); |
| 4622 | 4619 | } |
| 4623 | 4620 | |
| 4624 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 4625 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 4621 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 4626 | 4622 | const mod = self.bin_file.comp.module.?; |
| 4627 | const func = mod.funcInfo(ty_fn.func); | |
| 4623 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 4624 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 4625 | const func = mod.funcInfo(extra.data.func); | |
| 4628 | 4626 | // TODO emit debug info for function change |
| 4629 | 4627 | _ = func; |
| 4630 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 4628 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4631 | 4629 | } |
| 4632 | 4630 | |
| 4633 | 4631 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -5042,6 +5040,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { |
| 5042 | 5040 | } |
| 5043 | 5041 | |
| 5044 | 5042 | fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 5043 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 5044 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 5045 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 5046 | } | |
| 5047 | ||
| 5048 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | |
| 5045 | 5049 | try self.blocks.putNoClobber(self.gpa, inst, .{ |
| 5046 | 5050 | // A block is a setup to be able to jump to the end. |
| 5047 | 5051 | .relocs = .{}, |
| ... | ... | @@ -5054,9 +5058,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 5054 | 5058 | }); |
| 5055 | 5059 | defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); |
| 5056 | 5060 | |
| 5057 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 5058 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 5059 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 5060 | 5061 | // TODO emit debug info lexical block |
| 5061 | 5062 | try self.genBody(body); |
| 5062 | 5063 |
src/arch/arm/CodeGen.zig+13-12| ... | ... | @@ -733,7 +733,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 733 | 733 | .frame_addr => try self.airFrameAddress(inst), |
| 734 | 734 | .fence => try self.airFence(), |
| 735 | 735 | .cond_br => try self.airCondBr(inst), |
| 736 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 737 | 736 | .fptrunc => try self.airFptrunc(inst), |
| 738 | 737 | .fpext => try self.airFpext(inst), |
| 739 | 738 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -791,14 +790,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 791 | 790 | .@"try" => try self.airTry(inst), |
| 792 | 791 | .try_ptr => try self.airTryPtr(inst), |
| 793 | 792 | |
| 793 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 794 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 794 | 795 | .dbg_var_ptr, |
| 795 | 796 | .dbg_var_val, |
| 796 | 797 | => try self.airDbgVar(inst), |
| 797 | 798 | |
| 798 | .dbg_inline_begin, | |
| 799 | .dbg_inline_end, | |
| 800 | => try self.airDbgInline(inst), | |
| 801 | ||
| 802 | 799 | .call => try self.airCall(inst, .auto), |
| 803 | 800 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 804 | 801 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -4574,13 +4571,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4574 | 4571 | return self.finishAirBookkeeping(); |
| 4575 | 4572 | } |
| 4576 | 4573 | |
| 4577 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 4578 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 4574 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 4579 | 4575 | const mod = self.bin_file.comp.module.?; |
| 4580 | const func = mod.funcInfo(ty_fn.func); | |
| 4576 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 4577 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 4578 | const func = mod.funcInfo(extra.data.func); | |
| 4581 | 4579 | // TODO emit debug info for function change |
| 4582 | 4580 | _ = func; |
| 4583 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 4581 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4584 | 4582 | } |
| 4585 | 4583 | |
| 4586 | 4584 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -4973,6 +4971,12 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { |
| 4973 | 4971 | } |
| 4974 | 4972 | |
| 4975 | 4973 | fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4974 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 4975 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 4976 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4977 | } | |
| 4978 | ||
| 4979 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | |
| 4976 | 4980 | try self.blocks.putNoClobber(self.gpa, inst, .{ |
| 4977 | 4981 | // A block is a setup to be able to jump to the end. |
| 4978 | 4982 | .relocs = .{}, |
| ... | ... | @@ -4985,9 +4989,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 4985 | 4989 | }); |
| 4986 | 4990 | defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); |
| 4987 | 4991 | |
| 4988 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 4989 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 4990 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 4991 | 4992 | // TODO emit debug info lexical block |
| 4992 | 4993 | try self.genBody(body); |
| 4993 | 4994 |
src/arch/riscv64/CodeGen.zig+13-13| ... | ... | @@ -566,7 +566,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 566 | 566 | .frame_addr => try self.airFrameAddress(inst), |
| 567 | 567 | .fence => try self.airFence(), |
| 568 | 568 | .cond_br => try self.airCondBr(inst), |
| 569 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 570 | 569 | .fptrunc => try self.airFptrunc(inst), |
| 571 | 570 | .fpext => try self.airFpext(inst), |
| 572 | 571 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -624,14 +623,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 624 | 623 | .@"try" => @panic("TODO"), |
| 625 | 624 | .try_ptr => @panic("TODO"), |
| 626 | 625 | |
| 626 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 627 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 627 | 628 | .dbg_var_ptr, |
| 628 | 629 | .dbg_var_val, |
| 629 | 630 | => try self.airDbgVar(inst), |
| 630 | 631 | |
| 631 | .dbg_inline_begin, | |
| 632 | .dbg_inline_end, | |
| 633 | => try self.airDbgInline(inst), | |
| 634 | ||
| 635 | 632 | .call => try self.airCall(inst, .auto), |
| 636 | 633 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 637 | 634 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -1881,13 +1878,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1881 | 1878 | return self.finishAirBookkeeping(); |
| 1882 | 1879 | } |
| 1883 | 1880 | |
| 1884 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 1885 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 1881 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 1886 | 1882 | const mod = self.bin_file.comp.module.?; |
| 1887 | const func = mod.funcInfo(ty_fn.func); | |
| 1883 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 1884 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 1885 | const func = mod.funcInfo(extra.data.func); | |
| 1888 | 1886 | // TODO emit debug info for function change |
| 1889 | 1887 | _ = func; |
| 1890 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 1888 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 1891 | 1889 | } |
| 1892 | 1890 | |
| 1893 | 1891 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -2060,6 +2058,12 @@ fn jump(self: *Self, index: usize) !void { |
| 2060 | 2058 | } |
| 2061 | 2059 | |
| 2062 | 2060 | fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 2061 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 2062 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 2063 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 2064 | } | |
| 2065 | ||
| 2066 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | |
| 2063 | 2067 | try self.blocks.putNoClobber(self.gpa, inst, .{ |
| 2064 | 2068 | // A block is a setup to be able to jump to the end. |
| 2065 | 2069 | .relocs = .{}, |
| ... | ... | @@ -2071,10 +2075,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 2071 | 2075 | .mcv = MCValue{ .none = {} }, |
| 2072 | 2076 | }); |
| 2073 | 2077 | defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); |
| 2074 | ||
| 2075 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 2076 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 2077 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 2078 | 2078 | // TODO emit debug info lexical block |
| 2079 | 2079 | try self.genBody(body); |
| 2080 | 2080 |
src/arch/sparc64/CodeGen.zig+13-12| ... | ... | @@ -579,7 +579,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 579 | 579 | .frame_addr => @panic("TODO try self.airFrameAddress(inst)"), |
| 580 | 580 | .fence => try self.airFence(inst), |
| 581 | 581 | .cond_br => try self.airCondBr(inst), |
| 582 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 583 | 582 | .fptrunc => @panic("TODO try self.airFptrunc(inst)"), |
| 584 | 583 | .fpext => @panic("TODO try self.airFpext(inst)"), |
| 585 | 584 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -637,14 +636,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 637 | 636 | .@"try" => try self.airTry(inst), |
| 638 | 637 | .try_ptr => @panic("TODO try self.airTryPtr(inst)"), |
| 639 | 638 | |
| 639 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 640 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 640 | 641 | .dbg_var_ptr, |
| 641 | 642 | .dbg_var_val, |
| 642 | 643 | => try self.airDbgVar(inst), |
| 643 | 644 | |
| 644 | .dbg_inline_begin, | |
| 645 | .dbg_inline_end, | |
| 646 | => try self.airDbgInline(inst), | |
| 647 | ||
| 648 | 645 | .call => try self.airCall(inst, .auto), |
| 649 | 646 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 650 | 647 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -1127,6 +1124,12 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 1127 | 1124 | } |
| 1128 | 1125 | |
| 1129 | 1126 | fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 1127 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 1128 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 1129 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 1130 | } | |
| 1131 | ||
| 1132 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | |
| 1130 | 1133 | try self.blocks.putNoClobber(self.gpa, inst, .{ |
| 1131 | 1134 | // A block is a setup to be able to jump to the end. |
| 1132 | 1135 | .relocs = .{}, |
| ... | ... | @@ -1139,9 +1142,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 1139 | 1142 | }); |
| 1140 | 1143 | defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa); |
| 1141 | 1144 | |
| 1142 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 1143 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 1144 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 1145 | 1145 | // TODO emit debug info lexical block |
| 1146 | 1146 | try self.genBody(body); |
| 1147 | 1147 | |
| ... | ... | @@ -1652,13 +1652,14 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 1652 | 1652 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1653 | 1653 | } |
| 1654 | 1654 | |
| 1655 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 1656 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 1655 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 1657 | 1656 | const mod = self.bin_file.comp.module.?; |
| 1658 | const func = mod.funcInfo(ty_fn.func); | |
| 1657 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 1658 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 1659 | const func = mod.funcInfo(extra.data.func); | |
| 1659 | 1660 | // TODO emit debug info for function change |
| 1660 | 1661 | _ = func; |
| 1661 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 1662 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 1662 | 1663 | } |
| 1663 | 1664 | |
| 1664 | 1665 | fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
src/arch/wasm/CodeGen.zig+29-25| ... | ... | @@ -1910,16 +1910,11 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1910 | 1910 | .@"try" => func.airTry(inst), |
| 1911 | 1911 | .try_ptr => func.airTryPtr(inst), |
| 1912 | 1912 | |
| 1913 | // TODO | |
| 1914 | .dbg_inline_begin, | |
| 1915 | .dbg_inline_end, | |
| 1916 | => func.finishAir(inst, .none, &.{}), | |
| 1917 | ||
| 1913 | .dbg_stmt => func.airDbgStmt(inst), | |
| 1914 | .dbg_inline_block => func.airDbgInlineBlock(inst), | |
| 1918 | 1915 | .dbg_var_ptr => func.airDbgVar(inst, true), |
| 1919 | 1916 | .dbg_var_val => func.airDbgVar(inst, false), |
| 1920 | 1917 | |
| 1921 | .dbg_stmt => func.airDbgStmt(inst), | |
| 1922 | ||
| 1923 | 1918 | .call => func.airCall(inst, .auto), |
| 1924 | 1919 | .call_always_tail => func.airCall(inst, .always_tail), |
| 1925 | 1920 | .call_never_tail => func.airCall(inst, .never_tail), |
| ... | ... | @@ -3476,12 +3471,14 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 { |
| 3476 | 3471 | } |
| 3477 | 3472 | |
| 3478 | 3473 | fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3479 | const mod = func.bin_file.base.comp.module.?; | |
| 3480 | 3474 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3481 | const block_ty = ty_pl.ty.toType(); | |
| 3482 | const wasm_block_ty = genBlockType(block_ty, mod); | |
| 3483 | 3475 | const extra = func.air.extraData(Air.Block, ty_pl.payload); |
| 3484 | const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]); | |
| 3476 | try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len])); | |
| 3477 | } | |
| 3478 | ||
| 3479 | fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void { | |
| 3480 | const mod = func.bin_file.base.comp.module.?; | |
| 3481 | const wasm_block_ty = genBlockType(block_ty, mod); | |
| 3485 | 3482 | |
| 3486 | 3483 | // if wasm_block_ty is non-empty, we create a register to store the temporary value |
| 3487 | 3484 | const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: { |
| ... | ... | @@ -6472,7 +6469,27 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6472 | 6469 | func.finishAir(inst, result, &.{ty_op.operand}); |
| 6473 | 6470 | } |
| 6474 | 6471 | |
| 6475 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void { | |
| 6472 | fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | |
| 6473 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); | |
| 6474 | ||
| 6475 | const dbg_stmt = func.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; | |
| 6476 | try func.addInst(.{ .tag = .dbg_line, .data = .{ | |
| 6477 | .payload = try func.addExtra(Mir.DbgLineColumn{ | |
| 6478 | .line = dbg_stmt.line, | |
| 6479 | .column = dbg_stmt.column, | |
| 6480 | }), | |
| 6481 | } }); | |
| 6482 | func.finishAir(inst, .none, &.{}); | |
| 6483 | } | |
| 6484 | ||
| 6485 | fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | |
| 6486 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 6487 | const extra = func.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 6488 | // TODO | |
| 6489 | try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len])); | |
| 6490 | } | |
| 6491 | ||
| 6492 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { | |
| 6476 | 6493 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); |
| 6477 | 6494 | |
| 6478 | 6495 | const mod = func.bin_file.base.comp.module.?; |
| ... | ... | @@ -6497,19 +6514,6 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 6497 | 6514 | func.finishAir(inst, .none, &.{}); |
| 6498 | 6515 | } |
| 6499 | 6516 | |
| 6500 | fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) !void { | |
| 6501 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); | |
| 6502 | ||
| 6503 | const dbg_stmt = func.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; | |
| 6504 | try func.addInst(.{ .tag = .dbg_line, .data = .{ | |
| 6505 | .payload = try func.addExtra(Mir.DbgLineColumn{ | |
| 6506 | .line = dbg_stmt.line, | |
| 6507 | .column = dbg_stmt.column, | |
| 6508 | }), | |
| 6509 | } }); | |
| 6510 | func.finishAir(inst, .none, &.{}); | |
| 6511 | } | |
| 6512 | ||
| 6513 | 6517 | fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6514 | 6518 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6515 | 6519 | const err_union = try func.resolveInst(pl_op.operand); |
src/arch/x86_64/CodeGen.zig+24-12| ... | ... | @@ -58,6 +58,7 @@ bin_file: *link.File, |
| 58 | 58 | debug_output: DebugInfoOutput, |
| 59 | 59 | target: *const std.Target, |
| 60 | 60 | owner: Owner, |
| 61 | inline_func: InternPool.Index, | |
| 61 | 62 | mod: *Package.Module, |
| 62 | 63 | err_msg: ?*ErrorMsg, |
| 63 | 64 | args: []MCValue, |
| ... | ... | @@ -820,6 +821,7 @@ pub fn generate( |
| 820 | 821 | .bin_file = bin_file, |
| 821 | 822 | .debug_output = debug_output, |
| 822 | 823 | .owner = .{ .func_index = func_index }, |
| 824 | .inline_func = func_index, | |
| 823 | 825 | .err_msg = null, |
| 824 | 826 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 825 | 827 | .va_info = undefined, // populated after `resolveCallingConventionValues` |
| ... | ... | @@ -987,6 +989,7 @@ pub fn generateLazy( |
| 987 | 989 | .bin_file = bin_file, |
| 988 | 990 | .debug_output = debug_output, |
| 989 | 991 | .owner = .{ .lazy_sym = lazy_sym }, |
| 992 | .inline_func = undefined, | |
| 990 | 993 | .err_msg = null, |
| 991 | 994 | .args = undefined, |
| 992 | 995 | .va_info = undefined, |
| ... | ... | @@ -2042,7 +2045,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2042 | 2045 | .frame_addr => try self.airFrameAddress(inst), |
| 2043 | 2046 | .fence => try self.airFence(inst), |
| 2044 | 2047 | .cond_br => try self.airCondBr(inst), |
| 2045 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 2046 | 2048 | .fptrunc => try self.airFptrunc(inst), |
| 2047 | 2049 | .fpext => try self.airFpext(inst), |
| 2048 | 2050 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -2098,14 +2100,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2098 | 2100 | .@"try" => try self.airTry(inst), |
| 2099 | 2101 | .try_ptr => try self.airTryPtr(inst), |
| 2100 | 2102 | |
| 2103 | .dbg_stmt => try self.airDbgStmt(inst), | |
| 2104 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 2101 | 2105 | .dbg_var_ptr, |
| 2102 | 2106 | .dbg_var_val, |
| 2103 | 2107 | => try self.airDbgVar(inst), |
| 2104 | 2108 | |
| 2105 | .dbg_inline_begin, | |
| 2106 | .dbg_inline_end, | |
| 2107 | => try self.airDbgInline(inst), | |
| 2108 | ||
| 2109 | 2109 | .call => try self.airCall(inst, .auto), |
| 2110 | 2110 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 2111 | 2111 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -12962,14 +12962,23 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 12962 | 12962 | self.finishAirBookkeeping(); |
| 12963 | 12963 | } |
| 12964 | 12964 | |
| 12965 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 12966 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 12965 | fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 12966 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 12967 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 12968 | const old_inline_func = self.inline_func; | |
| 12969 | defer self.inline_func = old_inline_func; | |
| 12970 | self.inline_func = extra.data.func; | |
| 12967 | 12971 | _ = try self.addInst(.{ |
| 12968 | 12972 | .tag = .pseudo, |
| 12969 | 12973 | .ops = .pseudo_dbg_inline_func, |
| 12970 | .data = .{ .func = ty_fn.func }, | |
| 12974 | .data = .{ .func = extra.data.func }, | |
| 12975 | }); | |
| 12976 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 12977 | _ = try self.addInst(.{ | |
| 12978 | .tag = .pseudo, | |
| 12979 | .ops = .pseudo_dbg_inline_func, | |
| 12980 | .data = .{ .func = old_inline_func }, | |
| 12971 | 12981 | }); |
| 12972 | self.finishAirBookkeeping(); | |
| 12973 | 12982 | } |
| 12974 | 12983 | |
| 12975 | 12984 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -13407,6 +13416,12 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { |
| 13407 | 13416 | } |
| 13408 | 13417 | |
| 13409 | 13418 | fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 13419 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 13420 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 13421 | try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 13422 | } | |
| 13423 | ||
| 13424 | fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void { | |
| 13410 | 13425 | // A block is a setup to be able to jump to the end. |
| 13411 | 13426 | const inst_tracking_i = self.inst_tracking.count(); |
| 13412 | 13427 | self.inst_tracking.putAssumeCapacityNoClobber(inst, InstTracking.init(.unreach)); |
| ... | ... | @@ -13415,9 +13430,6 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 13415 | 13430 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); |
| 13416 | 13431 | const liveness = self.liveness.getBlock(inst); |
| 13417 | 13432 | |
| 13418 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 13419 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | |
| 13420 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 13421 | 13433 | // TODO emit debug info lexical block |
| 13422 | 13434 | try self.genBody(body); |
| 13423 | 13435 |
src/codegen/c.zig+18-19| ... | ... | @@ -2554,9 +2554,9 @@ pub fn genTypeDecl( |
| 2554 | 2554 | .suffix, |
| 2555 | 2555 | .{}, |
| 2556 | 2556 | ); |
| 2557 | try writer.writeAll("; // "); | |
| 2557 | try writer.writeAll("; /* "); | |
| 2558 | 2558 | try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer); |
| 2559 | try writer.writeByte('\n'); | |
| 2559 | try writer.writeAll(" */\n"); | |
| 2560 | 2560 | }, |
| 2561 | 2561 | |
| 2562 | 2562 | .anon_struct, |
| ... | ... | @@ -3215,7 +3215,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3215 | 3215 | .assembly => try airAsm(f, inst), |
| 3216 | 3216 | .block => try airBlock(f, inst), |
| 3217 | 3217 | .bitcast => try airBitcast(f, inst), |
| 3218 | .dbg_stmt => try airDbgStmt(f, inst), | |
| 3219 | 3218 | .intcast => try airIntCast(f, inst), |
| 3220 | 3219 | .trunc => try airTrunc(f, inst), |
| 3221 | 3220 | .int_from_bool => try airIntFromBool(f, inst), |
| ... | ... | @@ -3259,13 +3258,9 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3259 | 3258 | .@"try" => try airTry(f, inst), |
| 3260 | 3259 | .try_ptr => try airTryPtr(f, inst), |
| 3261 | 3260 | |
| 3262 | .dbg_var_ptr, | |
| 3263 | .dbg_var_val, | |
| 3264 | => try airDbgVar(f, inst), | |
| 3265 | ||
| 3266 | .dbg_inline_begin, | |
| 3267 | .dbg_inline_end, | |
| 3268 | => try airDbgInline(f, inst), | |
| 3261 | .dbg_stmt => try airDbgStmt(f, inst), | |
| 3262 | .dbg_inline_block => try airDbgInlineBlock(f, inst), | |
| 3263 | .dbg_var_ptr, .dbg_var_val => try airDbgVar(f, inst), | |
| 3269 | 3264 | |
| 3270 | 3265 | .call => try airCall(f, inst, .auto), |
| 3271 | 3266 | .call_always_tail => .none, |
| ... | ... | @@ -4497,15 +4492,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4497 | 4492 | return .none; |
| 4498 | 4493 | } |
| 4499 | 4494 | |
| 4500 | fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 4501 | const ty_fn = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 4495 | fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 4502 | 4496 | const mod = f.object.dg.module; |
| 4497 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 4498 | const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 4499 | const owner_decl = mod.funcOwnerDeclPtr(extra.data.func); | |
| 4503 | 4500 | const writer = f.object.writer(); |
| 4504 | const owner_decl = mod.funcOwnerDeclPtr(ty_fn.func); | |
| 4505 | try writer.print("/* dbg func:{s} */\n", .{ | |
| 4506 | mod.intern_pool.stringToSlice(owner_decl.name), | |
| 4507 | }); | |
| 4508 | return .none; | |
| 4501 | try writer.writeAll("/* "); | |
| 4502 | try owner_decl.renderFullyQualifiedName(mod, writer); | |
| 4503 | try writer.writeAll(" */ "); | |
| 4504 | return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4509 | 4505 | } |
| 4510 | 4506 | |
| 4511 | 4507 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | ... | @@ -4522,10 +4518,13 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4522 | 4518 | } |
| 4523 | 4519 | |
| 4524 | 4520 | fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4525 | const mod = f.object.dg.module; | |
| 4526 | 4521 | const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4527 | 4522 | const extra = f.air.extraData(Air.Block, ty_pl.payload); |
| 4528 | const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]); | |
| 4523 | return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4524 | } | |
| 4525 | ||
| 4526 | fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue { | |
| 4527 | const mod = f.object.dg.module; | |
| 4529 | 4528 | const liveness_block = f.liveness.getBlock(inst); |
| 4530 | 4529 | |
| 4531 | 4530 | const block_id: usize = f.next_block_index; |
src/codegen/llvm.zig+93-101| ... | ... | @@ -4762,11 +4762,7 @@ pub const FuncGen = struct { |
| 4762 | 4762 | file: Builder.Metadata, |
| 4763 | 4763 | scope: Builder.Metadata, |
| 4764 | 4764 | |
| 4765 | inlined: std.ArrayListUnmanaged(struct { | |
| 4766 | base_line: u32, | |
| 4767 | location: Builder.DebugLocation, | |
| 4768 | scope: Builder.Metadata, | |
| 4769 | }) = .{}, | |
| 4765 | inlined: Builder.DebugLocation = .no_location, | |
| 4770 | 4766 | |
| 4771 | 4767 | base_line: u32, |
| 4772 | 4768 | prev_dbg_line: c_uint, |
| ... | ... | @@ -4811,7 +4807,6 @@ pub const FuncGen = struct { |
| 4811 | 4807 | |
| 4812 | 4808 | fn deinit(self: *FuncGen) void { |
| 4813 | 4809 | self.wip.deinit(); |
| 4814 | self.inlined.deinit(self.gpa); | |
| 4815 | 4810 | self.func_inst_table.deinit(self.gpa); |
| 4816 | 4811 | self.blocks.deinit(self.gpa); |
| 4817 | 4812 | } |
| ... | ... | @@ -5107,8 +5102,7 @@ pub const FuncGen = struct { |
| 5107 | 5102 | |
| 5108 | 5103 | .unreach => try self.airUnreach(inst), |
| 5109 | 5104 | .dbg_stmt => try self.airDbgStmt(inst), |
| 5110 | .dbg_inline_begin => try self.airDbgInlineBegin(inst), | |
| 5111 | .dbg_inline_end => try self.airDbgInlineEnd(inst), | |
| 5105 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 5112 | 5106 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 5113 | 5107 | .dbg_var_val => try self.airDbgVarVal(inst), |
| 5114 | 5108 | |
| ... | ... | @@ -5126,17 +5120,81 @@ pub const FuncGen = struct { |
| 5126 | 5120 | } |
| 5127 | 5121 | } |
| 5128 | 5122 | |
| 5129 | fn genBodyDebugScope(self: *FuncGen, body: []const Air.Inst.Index) Error!void { | |
| 5123 | fn genBodyDebugScope(self: *FuncGen, maybe_inline_func: ?InternPool.Index, body: []const Air.Inst.Index) Error!void { | |
| 5130 | 5124 | if (self.wip.strip) return self.genBody(body); |
| 5125 | ||
| 5126 | const old_file = self.file; | |
| 5127 | const old_inlined = self.inlined; | |
| 5128 | const old_base_line = self.base_line; | |
| 5131 | 5129 | const old_scope = self.scope; |
| 5130 | defer if (maybe_inline_func) |_| { | |
| 5131 | self.wip.debug_location = self.inlined; | |
| 5132 | self.file = old_file; | |
| 5133 | self.inlined = old_inlined; | |
| 5134 | self.base_line = old_base_line; | |
| 5135 | }; | |
| 5136 | defer self.scope = old_scope; | |
| 5137 | ||
| 5138 | if (maybe_inline_func) |inline_func| { | |
| 5139 | const o = self.dg.object; | |
| 5140 | const zcu = o.module; | |
| 5141 | ||
| 5142 | const func = zcu.funcInfo(inline_func); | |
| 5143 | const decl_index = func.owner_decl; | |
| 5144 | const decl = zcu.declPtr(decl_index); | |
| 5145 | const namespace = zcu.namespacePtr(decl.src_namespace); | |
| 5146 | const owner_mod = namespace.file_scope.mod; | |
| 5147 | ||
| 5148 | self.file = try o.getDebugFile(namespace.file_scope); | |
| 5149 | ||
| 5150 | const line_number = decl.src_line + 1; | |
| 5151 | self.inlined = self.wip.debug_location; | |
| 5152 | ||
| 5153 | const fqn = try decl.fullyQualifiedName(zcu); | |
| 5154 | ||
| 5155 | const is_internal_linkage = !zcu.decl_exports.contains(decl_index); | |
| 5156 | const fn_ty = try zcu.funcType(.{ | |
| 5157 | .param_types = &.{}, | |
| 5158 | .return_type = .void_type, | |
| 5159 | }); | |
| 5160 | ||
| 5161 | self.scope = try o.builder.debugSubprogram( | |
| 5162 | self.file, | |
| 5163 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), | |
| 5164 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)), | |
| 5165 | line_number, | |
| 5166 | line_number + func.lbrace_line, | |
| 5167 | try o.lowerDebugType(fn_ty), | |
| 5168 | .{ | |
| 5169 | .di_flags = .{ .StaticMember = true }, | |
| 5170 | .sp_flags = .{ | |
| 5171 | .Optimized = owner_mod.optimize_mode != .Debug, | |
| 5172 | .Definition = true, | |
| 5173 | .LocalToUnit = is_internal_linkage, | |
| 5174 | }, | |
| 5175 | }, | |
| 5176 | o.debug_compile_unit, | |
| 5177 | ); | |
| 5178 | ||
| 5179 | self.base_line = decl.src_line; | |
| 5180 | const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder); | |
| 5181 | self.wip.debug_location = .{ | |
| 5182 | .location = .{ | |
| 5183 | .line = line_number, | |
| 5184 | .column = 0, | |
| 5185 | .scope = self.scope, | |
| 5186 | .inlined_at = inlined_at_location, | |
| 5187 | }, | |
| 5188 | }; | |
| 5189 | } | |
| 5190 | ||
| 5132 | 5191 | self.scope = try self.dg.object.builder.debugLexicalBlock( |
| 5133 | old_scope, | |
| 5192 | self.scope, | |
| 5134 | 5193 | self.file, |
| 5135 | 5194 | self.prev_dbg_line, |
| 5136 | 5195 | self.prev_dbg_column, |
| 5137 | 5196 | ); |
| 5138 | 5197 | try self.genBody(body); |
| 5139 | self.scope = old_scope; | |
| 5140 | 5198 | } |
| 5141 | 5199 | |
| 5142 | 5200 | pub const CallAttr = enum { |
| ... | ... | @@ -5820,15 +5878,23 @@ pub const FuncGen = struct { |
| 5820 | 5878 | } |
| 5821 | 5879 | |
| 5822 | 5880 | fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 5823 | const o = self.dg.object; | |
| 5824 | const mod = o.module; | |
| 5825 | 5881 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5826 | 5882 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 5827 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 5883 | return self.lowerBlock(inst, null, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 5884 | } | |
| 5885 | ||
| 5886 | fn lowerBlock( | |
| 5887 | self: *FuncGen, | |
| 5888 | inst: Air.Inst.Index, | |
| 5889 | maybe_inline_func: ?InternPool.Index, | |
| 5890 | body: []const Air.Inst.Index, | |
| 5891 | ) !Builder.Value { | |
| 5892 | const o = self.dg.object; | |
| 5893 | const mod = o.module; | |
| 5828 | 5894 | const inst_ty = self.typeOfIndex(inst); |
| 5829 | 5895 | |
| 5830 | 5896 | if (inst_ty.isNoReturn(mod)) { |
| 5831 | try self.genBodyDebugScope(body); | |
| 5897 | try self.genBodyDebugScope(maybe_inline_func, body); | |
| 5832 | 5898 | return .none; |
| 5833 | 5899 | } |
| 5834 | 5900 | |
| ... | ... | @@ -5844,7 +5910,7 @@ pub const FuncGen = struct { |
| 5844 | 5910 | }); |
| 5845 | 5911 | defer assert(self.blocks.remove(inst)); |
| 5846 | 5912 | |
| 5847 | try self.genBodyDebugScope(body); | |
| 5913 | try self.genBodyDebugScope(maybe_inline_func, body); | |
| 5848 | 5914 | |
| 5849 | 5915 | self.wip.cursor = .{ .block = parent_bb }; |
| 5850 | 5916 | |
| ... | ... | @@ -5903,10 +5969,10 @@ pub const FuncGen = struct { |
| 5903 | 5969 | _ = try self.wip.brCond(cond, then_block, else_block); |
| 5904 | 5970 | |
| 5905 | 5971 | self.wip.cursor = .{ .block = then_block }; |
| 5906 | try self.genBodyDebugScope(then_body); | |
| 5972 | try self.genBodyDebugScope(null, then_body); | |
| 5907 | 5973 | |
| 5908 | 5974 | self.wip.cursor = .{ .block = else_block }; |
| 5909 | try self.genBodyDebugScope(else_body); | |
| 5975 | try self.genBodyDebugScope(null, else_body); | |
| 5910 | 5976 | |
| 5911 | 5977 | // No need to reset the insert cursor since this instruction is noreturn. |
| 5912 | 5978 | return .none; |
| ... | ... | @@ -5987,7 +6053,7 @@ pub const FuncGen = struct { |
| 5987 | 6053 | _ = try fg.wip.brCond(is_err, return_block, continue_block); |
| 5988 | 6054 | |
| 5989 | 6055 | fg.wip.cursor = .{ .block = return_block }; |
| 5990 | try fg.genBodyDebugScope(body); | |
| 6056 | try fg.genBodyDebugScope(null, body); | |
| 5991 | 6057 | |
| 5992 | 6058 | fg.wip.cursor = .{ .block = continue_block }; |
| 5993 | 6059 | } |
| ... | ... | @@ -6060,13 +6126,13 @@ pub const FuncGen = struct { |
| 6060 | 6126 | } |
| 6061 | 6127 | |
| 6062 | 6128 | self.wip.cursor = .{ .block = case_block }; |
| 6063 | try self.genBodyDebugScope(case_body); | |
| 6129 | try self.genBodyDebugScope(null, case_body); | |
| 6064 | 6130 | } |
| 6065 | 6131 | |
| 6066 | 6132 | self.wip.cursor = .{ .block = else_block }; |
| 6067 | 6133 | const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]); |
| 6068 | 6134 | if (else_body.len != 0) { |
| 6069 | try self.genBodyDebugScope(else_body); | |
| 6135 | try self.genBodyDebugScope(null, else_body); | |
| 6070 | 6136 | } else { |
| 6071 | 6137 | _ = try self.wip.@"unreachable"(); |
| 6072 | 6138 | } |
| ... | ... | @@ -6085,7 +6151,7 @@ pub const FuncGen = struct { |
| 6085 | 6151 | _ = try self.wip.br(loop_block); |
| 6086 | 6152 | |
| 6087 | 6153 | self.wip.cursor = .{ .block = loop_block }; |
| 6088 | try self.genBodyDebugScope(body); | |
| 6154 | try self.genBodyDebugScope(null, body); | |
| 6089 | 6155 | |
| 6090 | 6156 | // TODO instead of this logic, change AIR to have the property that |
| 6091 | 6157 | // every block is guaranteed to end with a noreturn instruction. |
| ... | ... | @@ -6592,96 +6658,22 @@ pub const FuncGen = struct { |
| 6592 | 6658 | self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1); |
| 6593 | 6659 | self.prev_dbg_column = @intCast(dbg_stmt.column + 1); |
| 6594 | 6660 | |
| 6595 | const inlined_at_location = if (self.inlined.getLastOrNull()) |inlined| | |
| 6596 | try inlined.location.toMetadata(self.wip.builder) | |
| 6597 | else | |
| 6598 | .none; | |
| 6599 | ||
| 6600 | 6661 | self.wip.debug_location = .{ |
| 6601 | 6662 | .location = .{ |
| 6602 | 6663 | .line = self.prev_dbg_line, |
| 6603 | 6664 | .column = self.prev_dbg_column, |
| 6604 | 6665 | .scope = self.scope, |
| 6605 | .inlined_at = inlined_at_location, | |
| 6666 | .inlined_at = try self.inlined.toMetadata(self.wip.builder), | |
| 6606 | 6667 | }, |
| 6607 | 6668 | }; |
| 6608 | 6669 | |
| 6609 | 6670 | return .none; |
| 6610 | 6671 | } |
| 6611 | 6672 | |
| 6612 | fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | |
| 6613 | const o = self.dg.object; | |
| 6614 | const zcu = o.module; | |
| 6615 | ||
| 6616 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 6617 | const func = zcu.funcInfo(ty_fn.func); | |
| 6618 | const decl_index = func.owner_decl; | |
| 6619 | const decl = zcu.declPtr(decl_index); | |
| 6620 | const namespace = zcu.namespacePtr(decl.src_namespace); | |
| 6621 | const owner_mod = namespace.file_scope.mod; | |
| 6622 | ||
| 6623 | self.file = try o.getDebugFile(namespace.file_scope); | |
| 6624 | ||
| 6625 | const line_number = decl.src_line + 1; | |
| 6626 | try self.inlined.append(self.gpa, .{ | |
| 6627 | .location = self.wip.debug_location, | |
| 6628 | .scope = self.scope, | |
| 6629 | .base_line = self.base_line, | |
| 6630 | }); | |
| 6631 | ||
| 6632 | const fqn = try decl.fullyQualifiedName(zcu); | |
| 6633 | ||
| 6634 | const is_internal_linkage = !zcu.decl_exports.contains(decl_index); | |
| 6635 | const fn_ty = try zcu.funcType(.{ | |
| 6636 | .param_types = &.{}, | |
| 6637 | .return_type = .void_type, | |
| 6638 | }); | |
| 6639 | ||
| 6640 | self.scope = try o.builder.debugSubprogram( | |
| 6641 | self.file, | |
| 6642 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(decl.name)), | |
| 6643 | try o.builder.metadataString(zcu.intern_pool.stringToSlice(fqn)), | |
| 6644 | line_number, | |
| 6645 | line_number + func.lbrace_line, | |
| 6646 | try o.lowerDebugType(fn_ty), | |
| 6647 | .{ | |
| 6648 | .di_flags = .{ .StaticMember = true }, | |
| 6649 | .sp_flags = .{ | |
| 6650 | .Optimized = owner_mod.optimize_mode != .Debug, | |
| 6651 | .Definition = true, | |
| 6652 | .LocalToUnit = is_internal_linkage, | |
| 6653 | }, | |
| 6654 | }, | |
| 6655 | o.debug_compile_unit, | |
| 6656 | ); | |
| 6657 | ||
| 6658 | self.base_line = decl.src_line; | |
| 6659 | const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder); | |
| 6660 | self.wip.debug_location = .{ | |
| 6661 | .location = .{ | |
| 6662 | .line = line_number, | |
| 6663 | .column = 0, | |
| 6664 | .scope = self.scope, | |
| 6665 | .inlined_at = inlined_at_location, | |
| 6666 | }, | |
| 6667 | }; | |
| 6668 | return .none; | |
| 6669 | } | |
| 6670 | ||
| 6671 | fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { | |
| 6672 | const o = self.dg.object; | |
| 6673 | ||
| 6674 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 6675 | ||
| 6676 | const mod = o.module; | |
| 6677 | const decl = mod.funcOwnerDeclPtr(ty_fn.func); | |
| 6678 | self.file = try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope); | |
| 6679 | ||
| 6680 | const old = self.inlined.pop(); | |
| 6681 | self.scope = old.scope; | |
| 6682 | self.base_line = old.base_line; | |
| 6683 | self.wip.debug_location = old.location; | |
| 6684 | return .none; | |
| 6673 | fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | |
| 6674 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | |
| 6675 | const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload); | |
| 6676 | return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 6685 | 6677 | } |
| 6686 | 6678 | |
| 6687 | 6679 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
src/codegen/spirv.zig+19-24| ... | ... | @@ -208,6 +208,7 @@ pub const Object = struct { |
| 208 | 208 | false => .{ .unstructured = .{} }, |
| 209 | 209 | }, |
| 210 | 210 | .current_block_label = undefined, |
| 211 | .base_line = decl.src_line, | |
| 211 | 212 | }; |
| 212 | 213 | defer decl_gen.deinit(); |
| 213 | 214 | |
| ... | ... | @@ -321,9 +322,8 @@ const DeclGen = struct { |
| 321 | 322 | /// The code (prologue and body) for the function we are currently generating code for. |
| 322 | 323 | func: SpvModule.Fn = .{}, |
| 323 | 324 | |
| 324 | /// Stack of the base offsets of the current decl, which is what `dbg_stmt` is relative to. | |
| 325 | /// This is a stack to keep track of inline functions. | |
| 326 | base_line_stack: std.ArrayListUnmanaged(u32) = .{}, | |
| 325 | /// The base offset of the current decl, which is what `dbg_stmt` is relative to. | |
| 326 | base_line: u32, | |
| 327 | 327 | |
| 328 | 328 | /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message. |
| 329 | 329 | /// Memory is owned by `module.gpa`. |
| ... | ... | @@ -401,7 +401,6 @@ const DeclGen = struct { |
| 401 | 401 | self.wip_pointers.deinit(self.gpa); |
| 402 | 402 | self.control_flow.deinit(self.gpa); |
| 403 | 403 | self.func.deinit(self.gpa); |
| 404 | self.base_line_stack.deinit(self.gpa); | |
| 405 | 404 | } |
| 406 | 405 | |
| 407 | 406 | /// Return the target which we are currently compiling for. |
| ... | ... | @@ -1959,8 +1958,6 @@ const DeclGen = struct { |
| 1959 | 1958 | |
| 1960 | 1959 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; |
| 1961 | 1960 | |
| 1962 | try self.base_line_stack.append(self.gpa, decl.src_line); | |
| 1963 | ||
| 1964 | 1961 | if (decl.val.getFunction(mod)) |_| { |
| 1965 | 1962 | assert(decl.ty.zigTypeTag(mod) == .Fn); |
| 1966 | 1963 | const fn_info = mod.typeToFunc(decl.ty).?; |
| ... | ... | @@ -2317,8 +2314,7 @@ const DeclGen = struct { |
| 2317 | 2314 | .unreach, .trap => return self.airUnreach(), |
| 2318 | 2315 | |
| 2319 | 2316 | .dbg_stmt => return self.airDbgStmt(inst), |
| 2320 | .dbg_inline_begin => return self.airDbgInlineBegin(inst), | |
| 2321 | .dbg_inline_end => return self.airDbgInlineEnd(inst), | |
| 2317 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | |
| 2322 | 2318 | .dbg_var_ptr, .dbg_var_val => return self.airDbgVar(inst), |
| 2323 | 2319 | |
| 2324 | 2320 | .unwrap_errunion_err => try self.airErrUnionErr(inst), |
| ... | ... | @@ -4311,6 +4307,12 @@ const DeclGen = struct { |
| 4311 | 4307 | } |
| 4312 | 4308 | |
| 4313 | 4309 | fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4310 | const inst_datas = self.air.instructions.items(.data); | |
| 4311 | const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload); | |
| 4312 | return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 4313 | } | |
| 4314 | ||
| 4315 | fn lowerBlock(self: *DeclGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) !?IdRef { | |
| 4314 | 4316 | // In AIR, a block doesn't really define an entry point like a block, but |
| 4315 | 4317 | // more like a scope that breaks can jump out of and "return" a value from. |
| 4316 | 4318 | // This cannot be directly modelled in SPIR-V, so in a block instruction, |
| ... | ... | @@ -4320,10 +4322,6 @@ const DeclGen = struct { |
| 4320 | 4322 | |
| 4321 | 4323 | const mod = self.module; |
| 4322 | 4324 | const ty = self.typeOfIndex(inst); |
| 4323 | const inst_datas = self.air.instructions.items(.data); | |
| 4324 | const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload); | |
| 4325 | const body: []const Air.Inst.Index = | |
| 4326 | @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]); | |
| 4327 | 4325 | const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod); |
| 4328 | 4326 | |
| 4329 | 4327 | const cf = switch (self.control_flow) { |
| ... | ... | @@ -5157,25 +5155,22 @@ const DeclGen = struct { |
| 5157 | 5155 | const decl = mod.declPtr(self.decl_index); |
| 5158 | 5156 | const path = decl.getFileScope(mod).sub_file_path; |
| 5159 | 5157 | const src_fname_id = try self.spv.resolveSourceFileName(path); |
| 5160 | const base_line = self.base_line_stack.getLast(); | |
| 5161 | 5158 | try self.func.body.emit(self.spv.gpa, .OpLine, .{ |
| 5162 | 5159 | .file = src_fname_id, |
| 5163 | .line = base_line + dbg_stmt.line + 1, | |
| 5160 | .line = self.base_line + dbg_stmt.line + 1, | |
| 5164 | 5161 | .column = dbg_stmt.column + 1, |
| 5165 | 5162 | }); |
| 5166 | 5163 | } |
| 5167 | 5164 | |
| 5168 | fn airDbgInlineBegin(self: *DeclGen, inst: Air.Inst.Index) !void { | |
| 5165 | fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | |
| 5169 | 5166 | const mod = self.module; |
| 5170 | const fn_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 5171 | const decl_index = mod.funcInfo(fn_ty.func).owner_decl; | |
| 5172 | const decl = mod.declPtr(decl_index); | |
| 5173 | try self.base_line_stack.append(self.gpa, decl.src_line); | |
| 5174 | } | |
| 5175 | ||
| 5176 | fn airDbgInlineEnd(self: *DeclGen, inst: Air.Inst.Index) !void { | |
| 5177 | _ = inst; | |
| 5178 | _ = self.base_line_stack.pop(); | |
| 5167 | const inst_datas = self.air.instructions.items(.data); | |
| 5168 | const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload); | |
| 5169 | const decl = mod.funcOwnerDeclPtr(extra.data.func); | |
| 5170 | const old_base_line = self.base_line; | |
| 5171 | defer self.base_line = old_base_line; | |
| 5172 | self.base_line = decl.src_line; | |
| 5173 | return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len])); | |
| 5179 | 5174 | } |
| 5180 | 5175 | |
| 5181 | 5176 | fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void { |
src/print_air.zig+23-14| ... | ... | @@ -260,7 +260,7 @@ const Writer = struct { |
| 260 | 260 | .c_va_copy, |
| 261 | 261 | => try w.writeTyOp(s, inst), |
| 262 | 262 | |
| 263 | .block => try w.writeBlock(s, inst), | |
| 263 | .block, .dbg_inline_block => try w.writeBlock(s, tag, inst), | |
| 264 | 264 | |
| 265 | 265 | .loop => try w.writeLoop(s, inst), |
| 266 | 266 | |
| ... | ... | @@ -292,7 +292,6 @@ const Writer = struct { |
| 292 | 292 | .assembly => try w.writeAssembly(s, inst), |
| 293 | 293 | .dbg_stmt => try w.writeDbgStmt(s, inst), |
| 294 | 294 | |
| 295 | .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst), | |
| 296 | 295 | .aggregate_init => try w.writeAggregateInit(s, inst), |
| 297 | 296 | .union_init => try w.writeUnionInit(s, inst), |
| 298 | 297 | .br => try w.writeBr(s, inst), |
| ... | ... | @@ -367,17 +366,34 @@ const Writer = struct { |
| 367 | 366 | try w.writeOperand(s, inst, 0, ty_op.operand); |
| 368 | 367 | } |
| 369 | 368 | |
| 370 | fn writeBlock(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 369 | fn writeBlock(w: *Writer, s: anytype, tag: Air.Inst.Tag, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 371 | 370 | const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 372 | const extra = w.air.extraData(Air.Block, ty_pl.payload); | |
| 373 | const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]); | |
| 371 | try w.writeType(s, ty_pl.ty.toType()); | |
| 372 | const body: []const Air.Inst.Index = @ptrCast(switch (tag) { | |
| 373 | inline .block, .dbg_inline_block => |comptime_tag| body: { | |
| 374 | const extra = w.air.extraData(switch (comptime_tag) { | |
| 375 | .block => Air.Block, | |
| 376 | .dbg_inline_block => Air.DbgInlineBlock, | |
| 377 | else => unreachable, | |
| 378 | }, ty_pl.payload); | |
| 379 | switch (comptime_tag) { | |
| 380 | .block => {}, | |
| 381 | .dbg_inline_block => { | |
| 382 | try s.writeAll(", "); | |
| 383 | try w.writeInstRef(s, Air.internedToRef(extra.data.func), false); | |
| 384 | }, | |
| 385 | else => unreachable, | |
| 386 | } | |
| 387 | break :body w.air.extra[extra.end..][0..extra.data.body_len]; | |
| 388 | }, | |
| 389 | else => unreachable, | |
| 390 | }); | |
| 391 | if (w.skip_body) return s.writeAll(", ..."); | |
| 374 | 392 | const liveness_block = if (w.liveness) |liveness| |
| 375 | 393 | liveness.getBlock(inst) |
| 376 | 394 | else |
| 377 | 395 | Liveness.BlockSlices{ .deaths = &.{} }; |
| 378 | 396 | |
| 379 | try w.writeType(s, ty_pl.ty.toType()); | |
| 380 | if (w.skip_body) return s.writeAll(", ..."); | |
| 381 | 397 | try s.writeAll(", {\n"); |
| 382 | 398 | const old_indent = w.indent; |
| 383 | 399 | w.indent += 2; |
| ... | ... | @@ -661,13 +677,6 @@ const Writer = struct { |
| 661 | 677 | try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); |
| 662 | 678 | } |
| 663 | 679 | |
| 664 | fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 665 | const ty_fn = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; | |
| 666 | const func_index = ty_fn.func; | |
| 667 | const owner_decl = w.module.funcOwnerDeclPtr(func_index); | |
| 668 | try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)}); | |
| 669 | } | |
| 670 | ||
| 671 | 680 | fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 672 | 681 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 673 | 682 | try w.writeOperand(s, inst, 0, pl_op.operand); |
test/behavior/switch.zig+17| ... | ... | @@ -913,3 +913,20 @@ test "switch prong captures range" { |
| 913 | 913 | S.a(&arr, 5); |
| 914 | 914 | try expect(arr[5] == 5); |
| 915 | 915 | } |
| 916 | ||
| 917 | test "prong with inline call to unreachable" { | |
| 918 | const U = union(enum) { | |
| 919 | void: void, | |
| 920 | bool: bool, | |
| 921 | ||
| 922 | inline fn unreach() noreturn { | |
| 923 | unreachable; | |
| 924 | } | |
| 925 | }; | |
| 926 | var u: U = undefined; | |
| 927 | u = .{ .bool = true }; | |
| 928 | switch (u) { | |
| 929 | .void => U.unreach(), | |
| 930 | .bool => |ok| try expect(ok), | |
| 931 | } | |
| 932 | } |