authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-27 15:26:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-27 15:26:47-07:00
log1354b5773e508f9605c506e602abbec3a3b9b866
tree4242cce81f7bfbcdfd8a12fe46712d94657d21a8
parent0f824caa4cc0e16a8529318a5bb7e84795367002

incremental compilation bug


1 files changed, 56 insertions(+), 20 deletions(-)

src/codegen/llvm.zig+56-20
...@@ -1275,7 +1275,7 @@ pub const Object = struct {...@@ -1275,7 +1275,7 @@ pub const Object = struct {
1275 .is_small = options.is_small,1275 .is_small = options.is_small,
1276 .time_report = options.time_report,1276 .time_report = options.time_report,
1277 .tsan = options.sanitize_thread,1277 .tsan = options.sanitize_thread,
1278 .sancov = options.fuzz,1278 .sancov = sanCovPassEnabled(comp.config.san_cov_trace_pc_guard),
1279 .lto = options.lto,1279 .lto = options.lto,
1280 .asm_filename = null,1280 .asm_filename = null,
1281 .bin_filename = options.bin_path,1281 .bin_filename = options.bin_path,
...@@ -1283,19 +1283,19 @@ pub const Object = struct {...@@ -1283,19 +1283,19 @@ pub const Object = struct {
1283 .bitcode_filename = null,1283 .bitcode_filename = null,
1284 .coverage = .{1284 .coverage = .{
1285 .CoverageType = .Edge,1285 .CoverageType = .Edge,
1286 .IndirectCalls = true,1286 .IndirectCalls = false,
1287 .TraceBB = false,1287 .TraceBB = false,
1288 .TraceCmp = true,1288 .TraceCmp = false,
1289 .TraceDiv = false,1289 .TraceDiv = false,
1290 .TraceGep = false,1290 .TraceGep = false,
1291 .Use8bitCounters = false,1291 .Use8bitCounters = false,
1292 .TracePC = false,1292 .TracePC = false,
1293 .TracePCGuard = comp.config.san_cov_trace_pc_guard,1293 .TracePCGuard = comp.config.san_cov_trace_pc_guard,
1294 .Inline8bitCounters = true,1294 .Inline8bitCounters = false,
1295 .InlineBoolFlag = false,1295 .InlineBoolFlag = false,
1296 .PCTable = true,1296 .PCTable = false,
1297 .NoPrune = false,1297 .NoPrune = false,
1298 .StackDepth = true,1298 .StackDepth = false,
1299 .TraceLoads = false,1299 .TraceLoads = false,
1300 .TraceStores = false,1300 .TraceStores = false,
1301 .CollectControlFlow = false,1301 .CollectControlFlow = false,
...@@ -1662,6 +1662,7 @@ pub const Object = struct {...@@ -1662,6 +1662,7 @@ pub const Object = struct {
1662 .ng = &ng,1662 .ng = &ng,
1663 .wip = wip,1663 .wip = wip,
1664 .is_naked = fn_info.cc == .Naked,1664 .is_naked = fn_info.cc == .Naked,
1665 .fuzz = owner_mod.fuzz and !func_analysis.disable_instrumentation and !is_naked,
1665 .ret_ptr = ret_ptr,1666 .ret_ptr = ret_ptr,
1666 .args = args.items,1667 .args = args.items,
1667 .arg_index = 0,1668 .arg_index = 0,
...@@ -1679,7 +1680,7 @@ pub const Object = struct {...@@ -1679,7 +1680,7 @@ pub const Object = struct {
1679 defer fg.deinit();1680 defer fg.deinit();
1680 deinit_wip = false;1681 deinit_wip = false;
16811682
1682 fg.genBody(air.getMainBody()) catch |err| switch (err) {1683 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
1683 error.CodegenFail => {1684 error.CodegenFail => {
1684 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);1685 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
1685 ng.err_msg = null;1686 ng.err_msg = null;
...@@ -4729,6 +4730,7 @@ pub const FuncGen = struct {...@@ -4729,6 +4730,7 @@ pub const FuncGen = struct {
4729 liveness: Liveness,4730 liveness: Liveness,
4730 wip: Builder.WipFunction,4731 wip: Builder.WipFunction,
4731 is_naked: bool,4732 is_naked: bool,
4733 fuzz: bool,
47324734
4733 file: Builder.Metadata,4735 file: Builder.Metadata,
4734 scope: Builder.Metadata,4736 scope: Builder.Metadata,
...@@ -4836,11 +4838,26 @@ pub const FuncGen = struct {...@@ -4836,11 +4838,26 @@ pub const FuncGen = struct {
4836 return o.null_opt_usize;4838 return o.null_opt_usize;
4837 }4839 }
48384840
4839 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4841 fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: CoveragePoint) Error!void {
4840 const o = self.ng.object;4842 const o = self.ng.object;
4841 const zcu = o.pt.zcu;4843 const zcu = o.pt.zcu;
4842 const ip = &zcu.intern_pool;4844 const ip = &zcu.intern_pool;
4843 const air_tags = self.air.instructions.items(.tag);4845 const air_tags = self.air.instructions.items(.tag);
4846 switch (coverage_point) {
4847 .none => {},
4848 .poi => if (self.fuzz) |base_ptr| {
4849 // %0 = load i8, ptr @__sancov_gen_, align 1, !dbg !30, !nosanitize !28
4850 // %1 = add i8 %0, 1, !dbg !30
4851 // store i8 %1, ptr @__sancov_gen_, align 1, !dbg !30, !nosanitize !28
4852 const ptr = try self.wip.gep(.inbounds, .i8, base_ptr, &.{
4853 try o.builder.intValue(llvm_usize, self.nextPoiIndex()),
4854 }, "");
4855 const counter = try self.wip.load(.normal, .i8, ptr, .default, "");
4856 const one = try o.builder.intValue(.i8, 1);
4857 const counter_incremented = self.wip.bin(.add, counter, one, "");
4858 try self.wip.store(.normal, counter_incremented, ptr, .default);
4859 },
4860 }
4844 for (body, 0..) |inst, i| {4861 for (body, 0..) |inst, i| {
4845 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;4862 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
48464863
...@@ -5089,8 +5106,13 @@ pub const FuncGen = struct {...@@ -5089,8 +5106,13 @@ pub const FuncGen = struct {
5089 }5106 }
5090 }5107 }
50915108
5092 fn genBodyDebugScope(self: *FuncGen, maybe_inline_func: ?InternPool.Index, body: []const Air.Inst.Index) Error!void {5109 fn genBodyDebugScope(
5093 if (self.wip.strip) return self.genBody(body);5110 self: *FuncGen,
5111 maybe_inline_func: ?InternPool.Index,
5112 body: []const Air.Inst.Index,
5113 coverage_point: CoveragePoint,
5114 ) Error!void {
5115 if (self.wip.strip) return self.genBody(body, coverage_point);
50945116
5095 const old_file = self.file;5117 const old_file = self.file;
5096 const old_inlined = self.inlined;5118 const old_inlined = self.inlined;
...@@ -5137,7 +5159,8 @@ pub const FuncGen = struct {...@@ -5137,7 +5159,8 @@ pub const FuncGen = struct {
5137 .sp_flags = .{5159 .sp_flags = .{
5138 .Optimized = mod.optimize_mode != .Debug,5160 .Optimized = mod.optimize_mode != .Debug,
5139 .Definition = true,5161 .Definition = true,
5140 .LocalToUnit = true, // TODO: we can't know this at this point, since the function could be exported later!5162 // TODO: we can't know this at this point, since the function could be exported later!
5163 .LocalToUnit = true,
5141 },5164 },
5142 },5165 },
5143 o.debug_compile_unit,5166 o.debug_compile_unit,
...@@ -5171,7 +5194,7 @@ pub const FuncGen = struct {...@@ -5171,7 +5194,7 @@ pub const FuncGen = struct {
5171 .no_location => {},5194 .no_location => {},
5172 };5195 };
51735196
5174 try self.genBody(body);5197 try self.genBody(body, coverage_point);
5175 }5198 }
51765199
5177 pub const CallAttr = enum {5200 pub const CallAttr = enum {
...@@ -5881,7 +5904,7 @@ pub const FuncGen = struct {...@@ -5881,7 +5904,7 @@ pub const FuncGen = struct {
5881 const inst_ty = self.typeOfIndex(inst);5904 const inst_ty = self.typeOfIndex(inst);
58825905
5883 if (inst_ty.isNoReturn(zcu)) {5906 if (inst_ty.isNoReturn(zcu)) {
5884 try self.genBodyDebugScope(maybe_inline_func, body);5907 try self.genBodyDebugScope(maybe_inline_func, body, .none);
5885 return .none;5908 return .none;
5886 }5909 }
58875910
...@@ -5897,7 +5920,7 @@ pub const FuncGen = struct {...@@ -5897,7 +5920,7 @@ pub const FuncGen = struct {
5897 });5920 });
5898 defer assert(self.blocks.remove(inst));5921 defer assert(self.blocks.remove(inst));
58995922
5900 try self.genBodyDebugScope(maybe_inline_func, body);5923 try self.genBodyDebugScope(maybe_inline_func, body, .none);
59015924
5902 self.wip.cursor = .{ .block = parent_bb };5925 self.wip.cursor = .{ .block = parent_bb };
59035926
...@@ -5996,11 +6019,11 @@ pub const FuncGen = struct {...@@ -5996,11 +6019,11 @@ pub const FuncGen = struct {
59966019
5997 self.wip.cursor = .{ .block = then_block };6020 self.wip.cursor = .{ .block = then_block };
5998 if (hint == .then_cold) _ = try self.wip.callIntrinsicAssumeCold();6021 if (hint == .then_cold) _ = try self.wip.callIntrinsicAssumeCold();
5999 try self.genBodyDebugScope(null, then_body);6022 try self.genBodyDebugScope(null, then_body, .poi);
60006023
6001 self.wip.cursor = .{ .block = else_block };6024 self.wip.cursor = .{ .block = else_block };
6002 if (hint == .else_cold) _ = try self.wip.callIntrinsicAssumeCold();6025 if (hint == .else_cold) _ = try self.wip.callIntrinsicAssumeCold();
6003 try self.genBodyDebugScope(null, else_body);6026 try self.genBodyDebugScope(null, else_body, .poi);
60046027
6005 // No need to reset the insert cursor since this instruction is noreturn.6028 // No need to reset the insert cursor since this instruction is noreturn.
6006 return .none;6029 return .none;
...@@ -6085,7 +6108,7 @@ pub const FuncGen = struct {...@@ -6085,7 +6108,7 @@ pub const FuncGen = struct {
60856108
6086 fg.wip.cursor = .{ .block = return_block };6109 fg.wip.cursor = .{ .block = return_block };
6087 if (err_cold) _ = try fg.wip.callIntrinsicAssumeCold();6110 if (err_cold) _ = try fg.wip.callIntrinsicAssumeCold();
6088 try fg.genBodyDebugScope(null, body);6111 try fg.genBodyDebugScope(null, body, .poi);
60896112
6090 fg.wip.cursor = .{ .block = continue_block };6113 fg.wip.cursor = .{ .block = continue_block };
6091 }6114 }
...@@ -6196,14 +6219,14 @@ pub const FuncGen = struct {...@@ -6196,14 +6219,14 @@ pub const FuncGen = struct {
6196 }6219 }
6197 self.wip.cursor = .{ .block = case_block };6220 self.wip.cursor = .{ .block = case_block };
6198 if (switch_br.getHint(case.idx) == .cold) _ = try self.wip.callIntrinsicAssumeCold();6221 if (switch_br.getHint(case.idx) == .cold) _ = try self.wip.callIntrinsicAssumeCold();
6199 try self.genBodyDebugScope(null, case.body);6222 try self.genBodyDebugScope(null, case.body, .poi);
6200 }6223 }
62016224
6202 const else_body = it.elseBody();6225 const else_body = it.elseBody();
6203 self.wip.cursor = .{ .block = else_block };6226 self.wip.cursor = .{ .block = else_block };
6204 if (switch_br.getElseHint() == .cold) _ = try self.wip.callIntrinsicAssumeCold();6227 if (switch_br.getElseHint() == .cold) _ = try self.wip.callIntrinsicAssumeCold();
6205 if (else_body.len != 0) {6228 if (else_body.len != 0) {
6206 try self.genBodyDebugScope(null, else_body);6229 try self.genBodyDebugScope(null, else_body, .poi);
6207 } else {6230 } else {
6208 _ = try self.wip.@"unreachable"();6231 _ = try self.wip.@"unreachable"();
6209 }6232 }
...@@ -6222,7 +6245,7 @@ pub const FuncGen = struct {...@@ -6222,7 +6245,7 @@ pub const FuncGen = struct {
6222 _ = try self.wip.br(loop_block);6245 _ = try self.wip.br(loop_block);
62236246
6224 self.wip.cursor = .{ .block = loop_block };6247 self.wip.cursor = .{ .block = loop_block };
6225 try self.genBodyDebugScope(null, body);6248 try self.genBodyDebugScope(null, body, .none);
62266249
6227 // TODO instead of this logic, change AIR to have the property that6250 // TODO instead of this logic, change AIR to have the property that
6228 // every block is guaranteed to end with a noreturn instruction.6251 // every block is guaranteed to end with a noreturn instruction.
...@@ -12194,3 +12217,16 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {...@@ -12194,3 +12217,16 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
12194 => unreachable,12217 => unreachable,
12195 }12218 }
12196}12219}
12220
12221fn sanCovPassEnabled(trace_pc_guard: bool) bool {
12222 return trace_pc_guard;
12223}
12224
12225const CoveragePoint = enum {
12226 /// Indicates the block is not a place of interest corresponding to
12227 /// a source location for coverage purposes.
12228 none,
12229 /// Point of interest. The next instruction emitted corresponds to
12230 /// a source location used for coverage instrumentation.
12231 poi,
12232};