diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 077a1f105d3d8..f62ee303d5b78 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -304,30 +304,47 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}}) # Ok, do the inlining here spec = item.spec::ResolvedInliningSpec + sparam_vals = item.mi.sparam_vals + def = item.mi.def::Method inline_cfg = spec.ir.cfg stmt = compact.result[idx][:inst] linetable_offset::Int32 = length(linetable) # Append the linetable of the inlined function to our line table inlined_at = Int(compact.result[idx][:line]) - for entry in spec.ir.linetable - push!(linetable, LineInfoNode(entry.module, entry.method, entry.file, entry.line, - (entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at))) + topline::Int32 = linetable_offset + Int32(1) + coverage = coverage_enabled(def.module) + push!(linetable, LineInfoNode(def.module, def.name, def.file, Int(def.line), inlined_at)) + oldlinetable = spec.ir.linetable + for oldline in 1:length(oldlinetable) + entry = oldlinetable[oldline] + newentry = LineInfoNode(entry.module, entry.method, entry.file, entry.line, + (entry.inlined_at > 0 ? entry.inlined_at + linetable_offset + (oldline == 1) : inlined_at)) + if oldline == 1 + # check for a duplicate on the first iteration (likely true) + if newentry === linetable[topline] + continue + else + linetable_offset += 1 + end + end + push!(linetable, newentry) + end + if coverage && spec.ir.stmts[1][:line] + linetable_offset != topline + insert_node_here!(compact, NewInstruction(Expr(:code_coverage_effect), Nothing, topline)) end - (; def, sparam_vals) = item.mi nargs_def = def.nargs::Int32 isva = nargs_def > 0 && def.isva sig = def.sig if isva - vararg = mk_tuplecall!(compact, argexprs[nargs_def:end], compact.result[idx][:line]) + vararg = mk_tuplecall!(compact, argexprs[nargs_def:end], topline) argexprs = Any[argexprs[1:(nargs_def - 1)]..., vararg] end - mi = item.mi - is_opaque = isa(mi.def, Method) && mi.def.is_for_opaque_closure + is_opaque = def.is_for_opaque_closure if is_opaque # Replace the first argument by a load of the capture environment argexprs[1] = insert_node_here!(compact, NewInstruction(Expr(:call, GlobalRef(Core, :getfield), argexprs[1], QuoteNode(:captures)), - spec.ir.argtypes[1], compact.result[idx][:line])) + spec.ir.argtypes[1], topline)) end flag = compact.result[idx][:flag] boundscheck_idx = boundscheck diff --git a/test/testhelpers/coverage_file.info b/test/testhelpers/coverage_file.info index 9b4b1c1f2f96e..8319dfc34ad1d 100644 --- a/test/testhelpers/coverage_file.info +++ b/test/testhelpers/coverage_file.info @@ -9,9 +9,9 @@ DA:11,1 DA:12,1 DA:14,0 DA:17,1 -DA:19,1 +DA:19,2 DA:20,1 DA:22,1 -LH:10 -LF:13 +LH:12 +LF:14 end_of_record diff --git a/test/testhelpers/coverage_file.info.bad b/test/testhelpers/coverage_file.info.bad index 44e33a9df68c7..1855eea0270fd 100644 --- a/test/testhelpers/coverage_file.info.bad +++ b/test/testhelpers/coverage_file.info.bad @@ -10,7 +10,7 @@ DA:12,1 DA:14,0 DA:17,1 DA:18,0 -DA:19,1 +DA:19,2 DA:20,1 DA:22,1 DA:1234,0