mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
incremental compilation bug
This commit is contained in:
parent
0f824caa4c
commit
1354b5773e
1 changed files with 56 additions and 20 deletions
|
|
@ -1275,7 +1275,7 @@ pub const Object = struct {
|
||||||
.is_small = options.is_small,
|
.is_small = options.is_small,
|
||||||
.time_report = options.time_report,
|
.time_report = options.time_report,
|
||||||
.tsan = options.sanitize_thread,
|
.tsan = options.sanitize_thread,
|
||||||
.sancov = options.fuzz,
|
.sancov = sanCovPassEnabled(comp.config.san_cov_trace_pc_guard),
|
||||||
.lto = options.lto,
|
.lto = options.lto,
|
||||||
.asm_filename = null,
|
.asm_filename = null,
|
||||||
.bin_filename = options.bin_path,
|
.bin_filename = options.bin_path,
|
||||||
|
|
@ -1283,19 +1283,19 @@ pub const Object = struct {
|
||||||
.bitcode_filename = null,
|
.bitcode_filename = null,
|
||||||
.coverage = .{
|
.coverage = .{
|
||||||
.CoverageType = .Edge,
|
.CoverageType = .Edge,
|
||||||
.IndirectCalls = true,
|
.IndirectCalls = false,
|
||||||
.TraceBB = false,
|
.TraceBB = false,
|
||||||
.TraceCmp = true,
|
.TraceCmp = false,
|
||||||
.TraceDiv = false,
|
.TraceDiv = false,
|
||||||
.TraceGep = false,
|
.TraceGep = false,
|
||||||
.Use8bitCounters = false,
|
.Use8bitCounters = false,
|
||||||
.TracePC = false,
|
.TracePC = false,
|
||||||
.TracePCGuard = comp.config.san_cov_trace_pc_guard,
|
.TracePCGuard = comp.config.san_cov_trace_pc_guard,
|
||||||
.Inline8bitCounters = true,
|
.Inline8bitCounters = false,
|
||||||
.InlineBoolFlag = false,
|
.InlineBoolFlag = false,
|
||||||
.PCTable = true,
|
.PCTable = false,
|
||||||
.NoPrune = false,
|
.NoPrune = false,
|
||||||
.StackDepth = true,
|
.StackDepth = false,
|
||||||
.TraceLoads = false,
|
.TraceLoads = false,
|
||||||
.TraceStores = false,
|
.TraceStores = false,
|
||||||
.CollectControlFlow = false,
|
.CollectControlFlow = false,
|
||||||
|
|
@ -1662,6 +1662,7 @@ pub const Object = struct {
|
||||||
.ng = &ng,
|
.ng = &ng,
|
||||||
.wip = wip,
|
.wip = wip,
|
||||||
.is_naked = fn_info.cc == .Naked,
|
.is_naked = fn_info.cc == .Naked,
|
||||||
|
.fuzz = owner_mod.fuzz and !func_analysis.disable_instrumentation and !is_naked,
|
||||||
.ret_ptr = ret_ptr,
|
.ret_ptr = ret_ptr,
|
||||||
.args = args.items,
|
.args = args.items,
|
||||||
.arg_index = 0,
|
.arg_index = 0,
|
||||||
|
|
@ -1679,7 +1680,7 @@ pub const Object = struct {
|
||||||
defer fg.deinit();
|
defer fg.deinit();
|
||||||
deinit_wip = false;
|
deinit_wip = false;
|
||||||
|
|
||||||
fg.genBody(air.getMainBody()) catch |err| switch (err) {
|
fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
|
||||||
error.CodegenFail => {
|
error.CodegenFail => {
|
||||||
try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
|
try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
|
||||||
ng.err_msg = null;
|
ng.err_msg = null;
|
||||||
|
|
@ -4729,6 +4730,7 @@ pub const FuncGen = struct {
|
||||||
liveness: Liveness,
|
liveness: Liveness,
|
||||||
wip: Builder.WipFunction,
|
wip: Builder.WipFunction,
|
||||||
is_naked: bool,
|
is_naked: bool,
|
||||||
|
fuzz: bool,
|
||||||
|
|
||||||
file: Builder.Metadata,
|
file: Builder.Metadata,
|
||||||
scope: Builder.Metadata,
|
scope: Builder.Metadata,
|
||||||
|
|
@ -4836,11 +4838,26 @@ pub const FuncGen = struct {
|
||||||
return o.null_opt_usize;
|
return o.null_opt_usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
|
fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: CoveragePoint) Error!void {
|
||||||
const o = self.ng.object;
|
const o = self.ng.object;
|
||||||
const zcu = o.pt.zcu;
|
const zcu = o.pt.zcu;
|
||||||
const ip = &zcu.intern_pool;
|
const ip = &zcu.intern_pool;
|
||||||
const air_tags = self.air.instructions.items(.tag);
|
const air_tags = self.air.instructions.items(.tag);
|
||||||
|
switch (coverage_point) {
|
||||||
|
.none => {},
|
||||||
|
.poi => if (self.fuzz) |base_ptr| {
|
||||||
|
// %0 = load i8, ptr @__sancov_gen_, align 1, !dbg !30, !nosanitize !28
|
||||||
|
// %1 = add i8 %0, 1, !dbg !30
|
||||||
|
// store i8 %1, ptr @__sancov_gen_, align 1, !dbg !30, !nosanitize !28
|
||||||
|
const ptr = try self.wip.gep(.inbounds, .i8, base_ptr, &.{
|
||||||
|
try o.builder.intValue(llvm_usize, self.nextPoiIndex()),
|
||||||
|
}, "");
|
||||||
|
const counter = try self.wip.load(.normal, .i8, ptr, .default, "");
|
||||||
|
const one = try o.builder.intValue(.i8, 1);
|
||||||
|
const counter_incremented = self.wip.bin(.add, counter, one, "");
|
||||||
|
try self.wip.store(.normal, counter_incremented, ptr, .default);
|
||||||
|
},
|
||||||
|
}
|
||||||
for (body, 0..) |inst, i| {
|
for (body, 0..) |inst, i| {
|
||||||
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
|
if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) continue;
|
||||||
|
|
||||||
|
|
@ -5089,8 +5106,13 @@ pub const FuncGen = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn genBodyDebugScope(self: *FuncGen, maybe_inline_func: ?InternPool.Index, body: []const Air.Inst.Index) Error!void {
|
fn genBodyDebugScope(
|
||||||
if (self.wip.strip) return self.genBody(body);
|
self: *FuncGen,
|
||||||
|
maybe_inline_func: ?InternPool.Index,
|
||||||
|
body: []const Air.Inst.Index,
|
||||||
|
coverage_point: CoveragePoint,
|
||||||
|
) Error!void {
|
||||||
|
if (self.wip.strip) return self.genBody(body, coverage_point);
|
||||||
|
|
||||||
const old_file = self.file;
|
const old_file = self.file;
|
||||||
const old_inlined = self.inlined;
|
const old_inlined = self.inlined;
|
||||||
|
|
@ -5137,7 +5159,8 @@ pub const FuncGen = struct {
|
||||||
.sp_flags = .{
|
.sp_flags = .{
|
||||||
.Optimized = mod.optimize_mode != .Debug,
|
.Optimized = mod.optimize_mode != .Debug,
|
||||||
.Definition = true,
|
.Definition = true,
|
||||||
.LocalToUnit = true, // TODO: we can't know this at this point, since the function could be exported later!
|
// TODO: we can't know this at this point, since the function could be exported later!
|
||||||
|
.LocalToUnit = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
o.debug_compile_unit,
|
o.debug_compile_unit,
|
||||||
|
|
@ -5171,7 +5194,7 @@ pub const FuncGen = struct {
|
||||||
.no_location => {},
|
.no_location => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.genBody(body);
|
try self.genBody(body, coverage_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CallAttr = enum {
|
pub const CallAttr = enum {
|
||||||
|
|
@ -5881,7 +5904,7 @@ pub const FuncGen = struct {
|
||||||
const inst_ty = self.typeOfIndex(inst);
|
const inst_ty = self.typeOfIndex(inst);
|
||||||
|
|
||||||
if (inst_ty.isNoReturn(zcu)) {
|
if (inst_ty.isNoReturn(zcu)) {
|
||||||
try self.genBodyDebugScope(maybe_inline_func, body);
|
try self.genBodyDebugScope(maybe_inline_func, body, .none);
|
||||||
return .none;
|
return .none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5897,7 +5920,7 @@ pub const FuncGen = struct {
|
||||||
});
|
});
|
||||||
defer assert(self.blocks.remove(inst));
|
defer assert(self.blocks.remove(inst));
|
||||||
|
|
||||||
try self.genBodyDebugScope(maybe_inline_func, body);
|
try self.genBodyDebugScope(maybe_inline_func, body, .none);
|
||||||
|
|
||||||
self.wip.cursor = .{ .block = parent_bb };
|
self.wip.cursor = .{ .block = parent_bb };
|
||||||
|
|
||||||
|
|
@ -5996,11 +6019,11 @@ pub const FuncGen = struct {
|
||||||
|
|
||||||
self.wip.cursor = .{ .block = then_block };
|
self.wip.cursor = .{ .block = then_block };
|
||||||
if (hint == .then_cold) _ = try self.wip.callIntrinsicAssumeCold();
|
if (hint == .then_cold) _ = try self.wip.callIntrinsicAssumeCold();
|
||||||
try self.genBodyDebugScope(null, then_body);
|
try self.genBodyDebugScope(null, then_body, .poi);
|
||||||
|
|
||||||
self.wip.cursor = .{ .block = else_block };
|
self.wip.cursor = .{ .block = else_block };
|
||||||
if (hint == .else_cold) _ = try self.wip.callIntrinsicAssumeCold();
|
if (hint == .else_cold) _ = try self.wip.callIntrinsicAssumeCold();
|
||||||
try self.genBodyDebugScope(null, else_body);
|
try self.genBodyDebugScope(null, else_body, .poi);
|
||||||
|
|
||||||
// No need to reset the insert cursor since this instruction is noreturn.
|
// No need to reset the insert cursor since this instruction is noreturn.
|
||||||
return .none;
|
return .none;
|
||||||
|
|
@ -6085,7 +6108,7 @@ pub const FuncGen = struct {
|
||||||
|
|
||||||
fg.wip.cursor = .{ .block = return_block };
|
fg.wip.cursor = .{ .block = return_block };
|
||||||
if (err_cold) _ = try fg.wip.callIntrinsicAssumeCold();
|
if (err_cold) _ = try fg.wip.callIntrinsicAssumeCold();
|
||||||
try fg.genBodyDebugScope(null, body);
|
try fg.genBodyDebugScope(null, body, .poi);
|
||||||
|
|
||||||
fg.wip.cursor = .{ .block = continue_block };
|
fg.wip.cursor = .{ .block = continue_block };
|
||||||
}
|
}
|
||||||
|
|
@ -6196,14 +6219,14 @@ pub const FuncGen = struct {
|
||||||
}
|
}
|
||||||
self.wip.cursor = .{ .block = case_block };
|
self.wip.cursor = .{ .block = case_block };
|
||||||
if (switch_br.getHint(case.idx) == .cold) _ = try self.wip.callIntrinsicAssumeCold();
|
if (switch_br.getHint(case.idx) == .cold) _ = try self.wip.callIntrinsicAssumeCold();
|
||||||
try self.genBodyDebugScope(null, case.body);
|
try self.genBodyDebugScope(null, case.body, .poi);
|
||||||
}
|
}
|
||||||
|
|
||||||
const else_body = it.elseBody();
|
const else_body = it.elseBody();
|
||||||
self.wip.cursor = .{ .block = else_block };
|
self.wip.cursor = .{ .block = else_block };
|
||||||
if (switch_br.getElseHint() == .cold) _ = try self.wip.callIntrinsicAssumeCold();
|
if (switch_br.getElseHint() == .cold) _ = try self.wip.callIntrinsicAssumeCold();
|
||||||
if (else_body.len != 0) {
|
if (else_body.len != 0) {
|
||||||
try self.genBodyDebugScope(null, else_body);
|
try self.genBodyDebugScope(null, else_body, .poi);
|
||||||
} else {
|
} else {
|
||||||
_ = try self.wip.@"unreachable"();
|
_ = try self.wip.@"unreachable"();
|
||||||
}
|
}
|
||||||
|
|
@ -6222,7 +6245,7 @@ pub const FuncGen = struct {
|
||||||
_ = try self.wip.br(loop_block);
|
_ = try self.wip.br(loop_block);
|
||||||
|
|
||||||
self.wip.cursor = .{ .block = loop_block };
|
self.wip.cursor = .{ .block = loop_block };
|
||||||
try self.genBodyDebugScope(null, body);
|
try self.genBodyDebugScope(null, body, .none);
|
||||||
|
|
||||||
// TODO instead of this logic, change AIR to have the property that
|
// TODO instead of this logic, change AIR to have the property that
|
||||||
// every block is guaranteed to end with a noreturn instruction.
|
// every block is guaranteed to end with a noreturn instruction.
|
||||||
|
|
@ -12194,3 +12217,16 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
|
||||||
=> unreachable,
|
=> unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sanCovPassEnabled(trace_pc_guard: bool) bool {
|
||||||
|
return trace_pc_guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CoveragePoint = enum {
|
||||||
|
/// Indicates the block is not a place of interest corresponding to
|
||||||
|
/// a source location for coverage purposes.
|
||||||
|
none,
|
||||||
|
/// Point of interest. The next instruction emitted corresponds to
|
||||||
|
/// a source location used for coverage instrumentation.
|
||||||
|
poi,
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue