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 {
12751275 .is_small = options.is_small,
12761276 .time_report = options.time_report,
12771277 .tsan = options.sanitize_thread,
1278 .sancov = options.fuzz,
1278 .sancov = sanCovPassEnabled(comp.config.san_cov_trace_pc_guard),
12791279 .lto = options.lto,
12801280 .asm_filename = null,
12811281 .bin_filename = options.bin_path,
......@@ -1283,19 +1283,19 @@ pub const Object = struct {
12831283 .bitcode_filename = null,
12841284 .coverage = .{
12851285 .CoverageType = .Edge,
1286 .IndirectCalls = true,
1286 .IndirectCalls = false,
12871287 .TraceBB = false,
1288 .TraceCmp = true,
1288 .TraceCmp = false,
12891289 .TraceDiv = false,
12901290 .TraceGep = false,
12911291 .Use8bitCounters = false,
12921292 .TracePC = false,
12931293 .TracePCGuard = comp.config.san_cov_trace_pc_guard,
1294 .Inline8bitCounters = true,
1294 .Inline8bitCounters = false,
12951295 .InlineBoolFlag = false,
1296 .PCTable = true,
1296 .PCTable = false,
12971297 .NoPrune = false,
1298 .StackDepth = true,
1298 .StackDepth = false,
12991299 .TraceLoads = false,
13001300 .TraceStores = false,
13011301 .CollectControlFlow = false,
......@@ -1662,6 +1662,7 @@ pub const Object = struct {
16621662 .ng = &ng,
16631663 .wip = wip,
16641664 .is_naked = fn_info.cc == .Naked,
1665 .fuzz = owner_mod.fuzz and !func_analysis.disable_instrumentation and !is_naked,
16651666 .ret_ptr = ret_ptr,
16661667 .args = args.items,
16671668 .arg_index = 0,
......@@ -1679,7 +1680,7 @@ pub const Object = struct {
16791680 defer fg.deinit();
16801681 deinit_wip = false;
16811682
1682 fg.genBody(air.getMainBody()) catch |err| switch (err) {
1683 fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
16831684 error.CodegenFail => {
16841685 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
16851686 ng.err_msg = null;
......@@ -4729,6 +4730,7 @@ pub const FuncGen = struct {
47294730 liveness: Liveness,
47304731 wip: Builder.WipFunction,
47314732 is_naked: bool,
4733 fuzz: bool,
47324734
47334735 file: Builder.Metadata,
47344736 scope: Builder.Metadata,
......@@ -4836,11 +4838,26 @@ pub const FuncGen = struct {
48364838 return o.null_opt_usize;
48374839 }
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 {
48404842 const o = self.ng.object;
48414843 const zcu = o.pt.zcu;
48424844 const ip = &zcu.intern_pool;
48434845 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 }
48444861 for (body, 0..) |inst, i| {
48454862 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
48464863
......@@ -5089,8 +5106,13 @@ pub const FuncGen = struct {
50895106 }
50905107 }
50915108
5092 fn genBodyDebugScope(self: *FuncGen, maybe_inline_func: ?InternPool.Index, body: []const Air.Inst.Index) Error!void {
5093 if (self.wip.strip) return self.genBody(body);
5109 fn genBodyDebugScope(
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
50955117 const old_file = self.file;
50965118 const old_inlined = self.inlined;
......@@ -5137,7 +5159,8 @@ pub const FuncGen = struct {
51375159 .sp_flags = .{
51385160 .Optimized = mod.optimize_mode != .Debug,
51395161 .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,
51415164 },
51425165 },
51435166 o.debug_compile_unit,
......@@ -5171,7 +5194,7 @@ pub const FuncGen = struct {
51715194 .no_location => {},
51725195 };
51735196
5174 try self.genBody(body);
5197 try self.genBody(body, coverage_point);
51755198 }
51765199
51775200 pub const CallAttr = enum {
......@@ -5881,7 +5904,7 @@ pub const FuncGen = struct {
58815904 const inst_ty = self.typeOfIndex(inst);
58825905
58835906 if (inst_ty.isNoReturn(zcu)) {
5884 try self.genBodyDebugScope(maybe_inline_func, body);
5907 try self.genBodyDebugScope(maybe_inline_func, body, .none);
58855908 return .none;
58865909 }
58875910
......@@ -5897,7 +5920,7 @@ pub const FuncGen = struct {
58975920 });
58985921 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
59025925 self.wip.cursor = .{ .block = parent_bb };
59035926
......@@ -5996,11 +6019,11 @@ pub const FuncGen = struct {
59966019
59976020 self.wip.cursor = .{ .block = then_block };
59986021 if (hint == .then_cold) _ = try self.wip.callIntrinsicAssumeCold();
5999 try self.genBodyDebugScope(null, then_body);
6022 try self.genBodyDebugScope(null, then_body, .poi);
60006023
60016024 self.wip.cursor = .{ .block = else_block };
60026025 if (hint == .else_cold) _ = try self.wip.callIntrinsicAssumeCold();
6003 try self.genBodyDebugScope(null, else_body);
6026 try self.genBodyDebugScope(null, else_body, .poi);
60046027
60056028 // No need to reset the insert cursor since this instruction is noreturn.
60066029 return .none;
......@@ -6085,7 +6108,7 @@ pub const FuncGen = struct {
60856108
60866109 fg.wip.cursor = .{ .block = return_block };
60876110 if (err_cold) _ = try fg.wip.callIntrinsicAssumeCold();
6088 try fg.genBodyDebugScope(null, body);
6111 try fg.genBodyDebugScope(null, body, .poi);
60896112
60906113 fg.wip.cursor = .{ .block = continue_block };
60916114 }
......@@ -6196,14 +6219,14 @@ pub const FuncGen = struct {
61966219 }
61976220 self.wip.cursor = .{ .block = case_block };
61986221 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);
62006223 }
62016224
62026225 const else_body = it.elseBody();
62036226 self.wip.cursor = .{ .block = else_block };
62046227 if (switch_br.getElseHint() == .cold) _ = try self.wip.callIntrinsicAssumeCold();
62056228 if (else_body.len != 0) {
6206 try self.genBodyDebugScope(null, else_body);
6229 try self.genBodyDebugScope(null, else_body, .poi);
62076230 } else {
62086231 _ = try self.wip.@"unreachable"();
62096232 }
......@@ -6222,7 +6245,7 @@ pub const FuncGen = struct {
62226245 _ = try self.wip.br(loop_block);
62236246
62246247 self.wip.cursor = .{ .block = loop_block };
6225 try self.genBodyDebugScope(null, body);
6248 try self.genBodyDebugScope(null, body, .none);
62266249
62276250 // TODO instead of this logic, change AIR to have the property that
62286251 // every block is guaranteed to end with a noreturn instruction.
......@@ -12194,3 +12217,16 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
1219412217 => unreachable,
1219512218 }
1219612219}
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};