Skip to content

Commit 54c8ec0

Browse files
authored
Improve DebugInfo source provenance (#54)
* Misc refactors, insert internal stmt debuginfo * Add slotnames info * Refactor naming of locals for ODE codegen * Add comment * Apply DebugInfo at top-level * Remove `insert_ssa_debuginfo` setting * Marshall settings everywhere * Add maybe_insert_debuginfo * Disable crashing tests * Propagate source information for `insert_node_here!(...)` * Add source provenance to DAE/Init codegen * Use `__SOURCE__` macro for `replace_call!` * Update `replace_call!` with source information in index_lowering.jl * Default `insert_stmt_debuginfo` to `false` for reflection tools * Remove accidental code inclusion * Don't seek previous codeloc * Remove unused code * Reenable IPO tests * [DO NOT MERGE] Temporarily dev ConstructionBase for CI * Work around `invokelatest` issue * Only wrap `string` call in `try`/`catch` * Add `insert_ssa_debuginfo` setting * Minor fix * Refactor `insert_node_here` macro * Use insert_instruction! in more places * Rename `insert_node_here` macro to `insert_instruction` * `insert_instruction` -> `insert_instruction_here` Not to confuse it with the nonlocal insertion * Fixes * Undev ConstructionBase (and update) * Refactor settings construction for DAE/ODE problems * Use :call form for macrocall * Add missing argument * Remove unused package
1 parent 747b4ca commit 54c8ec0

20 files changed

+471
-397
lines changed

Manifest.toml

Lines changed: 62 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DAECompiler.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ module DAECompiler
66
using Diffractor
77
using OrderedCollections
88
using Compiler
9-
using Compiler: IRCode, IncrementalCompact, argextype, singleton_type, isexpr, widenconst
9+
using Compiler: IRCode, IncrementalCompact, DebugInfoStream, NewInstruction, argextype, singleton_type, isexpr, widenconst
1010
using Core.IR
1111
using SciMLBase
1212
using AutoHashEquals
1313
using LinearAlgebra: LinearAlgebra
1414
using InteractiveUtils: gen_call_with_extracted_types_and_kwargs
1515

16+
include("settings.jl")
1617
include("utils.jl")
1718
include("intrinsics.jl")
18-
include("settings.jl")
1919
include("analysis/utils.jl")
2020
include("analysis/lattice.jl")
2121
include("analysis/ADAnalyzer.jl")

src/analysis/flattening.jl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line)
1+
function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings)
22
list = Any[]
33
for (argn, argt) in enumerate(argtypes)
44
if isa(argt, Const)
@@ -18,22 +18,20 @@ function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line)
1818
continue
1919
end
2020
this = ntharg(argn)
21-
nthfield(i) = insert_node_here!(compact,
22-
NewInstruction(Expr(:call, getfield, this, i), Compiler.getfield_tfunc(𝕃, argextype(this, compact), Const(i)), line))
21+
nthfield(i) = @insert_instruction_here(compact, line, settings, getfield(this, i)::Compiler.getfield_tfunc(𝕃, argextype(this, compact), Const(i)))
2322
if isa(argt, PartialStruct)
24-
fields = _flatten_parameter!(𝕃, compact, argt.fields, nthfield, line)
23+
fields = _flatten_parameter!(𝕃, compact, argt.fields, nthfield, line, settings)
2524
else
26-
fields = _flatten_parameter!(𝕃, compact, fieldtypes(argt), nthfield, line)
25+
fields = _flatten_parameter!(𝕃, compact, fieldtypes(argt), nthfield, line, settings)
2726
end
2827
append!(list, fields)
2928
end
3029
end
3130
return list
3231
end
3332

34-
function flatten_parameter!(𝕃, compact, argtypes, ntharg, line)
35-
return insert_node_here!(compact,
36-
NewInstruction(Expr(:call, tuple, _flatten_parameter!(𝕃, compact, argtypes, ntharg, line)...), Tuple, line))
33+
function flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings)
34+
return @insert_instruction_here(compact, line, settings, tuple(_flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings)...)::Tuple)
3735
end
3836

3937
# Needs to match flatten_arguments!
@@ -76,7 +74,7 @@ struct TransformedArg
7674
TransformedArg(@nospecialize(arg), new_offset::Int, new_eqoffset::Int) = new(arg, new_offset, new_eqoffset)
7775
end
7876

79-
function flatten_argument!(compact::Compiler.IncrementalCompact, @nospecialize(argt), offset::Int, eqoffset::Int, argtypes::Vector{Any})::TransformedArg
77+
function flatten_argument!(compact::Compiler.IncrementalCompact, settings::Settings, @nospecialize(argt), offset::Int, eqoffset::Int, argtypes::Vector{Any})::TransformedArg
8078
@assert !isa(argt, Incidence) && !isa(argt, Eq)
8179
if isa(argt, Const)
8280
return TransformedArg(argt.val, offset, eqoffset)
@@ -86,28 +84,32 @@ function flatten_argument!(compact::Compiler.IncrementalCompact, @nospecialize(a
8684
push!(argtypes, argt)
8785
return TransformedArg(Argument(offset+1), offset+1, eqoffset)
8886
elseif argt === equation
89-
ssa = insert_node_here!(compact, NewInstruction(Expr(:invoke, nothing, InternalIntrinsics.external_equation), Eq(eqoffset+1), compact[Compiler.OldSSAValue(1)][:line]))
87+
line = compact[Compiler.OldSSAValue(1)][:line]
88+
ssa = @insert_instruction_here(compact, line, settings, (:invoke)(nothing, InternalIntrinsics.external_equation)::Eq(eqoffset+1))
9089
return TransformedArg(ssa, offset, eqoffset+1)
9190
elseif isabstracttype(argt) || ismutabletype(argt) || (!isa(argt, DataType) && !isa(argt, PartialStruct))
92-
ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line]))
91+
line = compact[Compiler.OldSSAValue(1)][:line]
92+
ssa = @insert_instruction_here(compact, line, settings, error("Cannot IPO model arg type $argt")::Union{})
9393
return TransformedArg(ssa, -1, eqoffset)
9494
else
9595
if !isa(argt, PartialStruct) && Base.datatype_fieldcount(argt) === nothing
96-
ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line]))
96+
line = compact[Compiler.OldSSAValue(1)][:line]
97+
ssa = @insert_instruction_here(compact, line, settings, error("Cannot IPO model arg type $argt")::Union{})
9798
return TransformedArg(ssa, -1, eqoffset)
9899
end
99-
(args, _, offset) = flatten_arguments!(compact, isa(argt, PartialStruct) ? argt.fields : collect(Any, fieldtypes(argt)), offset, eqoffset, argtypes)
100+
(args, _, offset) = flatten_arguments!(compact, settings, isa(argt, PartialStruct) ? argt.fields : collect(Any, fieldtypes(argt)), offset, eqoffset, argtypes)
100101
offset == -1 && return TransformedArg(ssa, -1, eqoffset)
101102
this = Expr(:new, isa(argt, PartialStruct) ? argt.typ : argt, args...)
102-
ssa = insert_node_here!(compact, NewInstruction(this, argt, compact[Compiler.OldSSAValue(1)][:line]))
103+
line = compact[Compiler.OldSSAValue(1)][:line]
104+
ssa = @insert_instruction_here(compact, line, settings, this::argt)
103105
return TransformedArg(ssa, offset, eqoffset)
104106
end
105107
end
106108

107-
function flatten_arguments!(compact::Compiler.IncrementalCompact, argtypes::Vector{Any}, offset::Int=0, eqoffset::Int=0, new_argtypes::Vector{Any} = Any[])
109+
function flatten_arguments!(compact::Compiler.IncrementalCompact, settings::Settings, argtypes::Vector{Any}, offset::Int=0, eqoffset::Int=0, new_argtypes::Vector{Any} = Any[])
108110
args = Any[]
109111
for argt in argtypes
110-
(; ssa, offset, eqoffset) = flatten_argument!(compact, argt, offset, eqoffset, new_argtypes)
112+
(; ssa, offset, eqoffset) = flatten_argument!(compact, settings, argt, offset, eqoffset, new_argtypes)
111113
offset == -1 && break
112114
push!(args, ssa)
113115
end

src/analysis/refiner.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ of structural incidence information.
77
"""
88
struct StructuralRefiner <: Compiler.AbstractInterpreter
99
world::UInt
10+
settings::Settings
1011
var_to_diff::DiffGraph
1112
varkinds::Vector{Intrinsics.VarKind}
1213
varclassification::Vector{VarEqClassification}
@@ -51,7 +52,7 @@ Compiler.cache_owner(::StructuralRefiner) = StructureCache()
5152
end
5253

5354
callee_codeinst = invokee::CodeInstance
54-
callee_result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(interp))
55+
callee_result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(interp), interp.settings)
5556

5657
if isa(callee_result, UncompilableIPOResult) || isa(callee_result.extended_rt, Const) || isa(callee_result.extended_rt, Type)
5758
# If this is uncompilable, we will be notfiying the user in the outer loop - here we just ignore it

src/analysis/structural.jl

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ function find_matching_ci(predicate, mi::MethodInstance, world::UInt)
1616
return nothing
1717
end
1818

19-
function structural_analysis!(ci::CodeInstance, world::UInt)
19+
function structural_analysis!(ci::CodeInstance, world::UInt, settings::Settings)
2020
# Check if we have aleady done this work - if so return the cached result
2121
result_ci = find_matching_ci(ci->ci.owner == StructureCache(), ci.def, world)
2222
if result_ci !== nothing
2323
return result_ci.inferred
2424
end
2525

26-
result = _structural_analysis!(ci, world)
26+
result = _structural_analysis!(ci, world, settings)
2727
# TODO: The world bounds might have been narrowed
2828
cache_dae_ci!(ci, result, nothing, nothing, StructureCache())
2929

@@ -40,7 +40,7 @@ struct EqVarState
4040
eq_callee_mapping
4141
end
4242

43-
function _structural_analysis!(ci::CodeInstance, world::UInt)
43+
function _structural_analysis!(ci::CodeInstance, world::UInt, settings::Settings)
4444
# Variables
4545
var_to_diff = DiffGraph(0)
4646
varclassification = VarEqClassification[]
@@ -83,7 +83,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
8383
compact = IncrementalCompact(ir)
8484
old_argtypes = copy(ir.argtypes)
8585
empty!(ir.argtypes)
86-
(arg_replacements, new_argtypes, nexternalargvars, nexternaleqs) = flatten_arguments!(compact, old_argtypes, 0, 0, ir.argtypes)
86+
(arg_replacements, new_argtypes, nexternalargvars, nexternaleqs) = flatten_arguments!(compact, settings, old_argtypes, 0, 0, ir.argtypes)
8787
if nexternalargvars == -1
8888
return UncompilableIPOResult(warnings, UnsupportedIRException("Unhandled argument types", Compiler.finish(compact)))
8989
end
@@ -98,7 +98,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
9898
argtypes = Any[Incidence(new_argtypes[i], i) for i = 1:nexternalargvars]
9999

100100
# Allocate variable and equation numbers of any incoming arguments
101-
refiner = StructuralRefiner(world, var_to_diff, varkinds, varclassification, eqkinds, eqclassification)
101+
refiner = StructuralRefiner(world, settings, var_to_diff, varkinds, varclassification, eqkinds, eqclassification)
102102
nexternalargvars = length(var_to_diff)
103103

104104
# Go through the IR, annotating each intrinsic with an appropriate taint
@@ -337,7 +337,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
337337
if isa(info, MappingInfo)
338338
(; result, mapping) = info
339339
else
340-
result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(refiner))
340+
result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(refiner), settings)
341341

342342
if isa(result, UncompilableIPOResult)
343343
# TODO: Stack trace?
@@ -360,9 +360,9 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
360360
# Rewrite to flattened ABI
361361
compact[SSAValue(i)] = nothing
362362
compact.result_idx -= 1
363-
new_args = _flatten_parameter!(Compiler.optimizer_lattice(refiner), compact, callee_codeinst.inferred.ir.argtypes, arg->stmt.args[arg+1], line)
363+
new_args = _flatten_parameter!(Compiler.optimizer_lattice(refiner), compact, callee_codeinst.inferred.ir.argtypes, arg->stmt.args[arg+1], line, settings)
364364

365-
new_call = insert_node_here!(compact,
365+
new_call = insert_instruction_here!(compact, settings, @__SOURCE__,
366366
NewInstruction(Expr(:invoke, (StructuralSSARef(compact.result_idx), callee_codeinst), new_args...), stmtype, info, line, stmtflags))
367367
compact.ssa_rename[compact.idx - 1] = new_call
368368

@@ -386,8 +386,8 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
386386
line = ret_stmt_inst[:line]
387387
Compiler.delete_inst_here!(compact)
388388

389-
(new_ret, ultimate_rt) = rewrite_ipo_return!(Compiler.typeinf_lattice(refiner), compact, line, ret_stmt.val, ultimate_rt, eqvars)
390-
insert_node_here!(compact, NewInstruction(ReturnNode(new_ret), ultimate_rt, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
389+
(new_ret, ultimate_rt) = rewrite_ipo_return!(Compiler.typeinf_lattice(refiner), compact, line, settings, ret_stmt.val, ultimate_rt, eqvars)
390+
insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(ReturnNode(new_ret), ultimate_rt, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true)
391391
elseif isa(ultimate_rt, Type)
392392
# If we don't have any internal variables (in which case we might have to to do a more aggressive rewrite), strengthen the incidence
393393
# by demoting to full incidence over the argument variables. Incidence is not allowed to propagate through global mutable state, so
@@ -415,7 +415,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt)
415415
warnings)
416416
end
417417

418-
function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultimate_rt::Any, eqvars::EqVarState)
418+
function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, settings, ssa, ultimate_rt::Any, eqvars::EqVarState)
419419
if isa(ultimate_rt, Eq)
420420
return Pair{Any, Any}(ssa, ultimate_rt)
421421
end
@@ -425,22 +425,23 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim
425425
new_types = Any[]
426426
for i = 1:length(ultimate_rt.fields)
427427
ssa_type = Compiler.getfield_tfunc(𝕃, ultimate_rt, Const(i))
428-
ssa_field = insert_node_here!(compact,
429-
NewInstruction(Expr(:call, getfield, variable), ssa_type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
428+
ssa_field = insert_instruction_here!(compact, settings, @__SOURCE__,
429+
NewInstruction(Expr(:call, getfield, variable), ssa_type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true)
430430

431-
(new_field, new_type) = rewrite_ipo_return!(𝕃, compact, line, ssa_field, ssa_type, eqvars)
431+
(new_field, new_type) = rewrite_ipo_return!(𝕃, compact, line, settings, ssa_field, ssa_type, eqvars)
432432
push!(new_fields, new_field)
433433
push!(new_types, new_type)
434434
end
435435
newT = Compiler.PartialStruct(ultimate_rt.typ, new_types)
436436
if widenconst(ultimate_rt) <: Tuple
437-
retssa = insert_node_here!(compact,
438-
NewInstruction(Expr(:call, tuple, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
437+
retssa = insert_instruction_here!(compact, settings, @__SOURCE__,
438+
NewInstruction(Expr(:call, tuple, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true)
439439
else
440-
T = insert_node_here!(compact,
441-
NewInstruction(Expr(:call, typeof, ssa), Type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
442-
retssa = insert_node_here!(compact,
443-
NewInstruction(Expr(:new, T, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
440+
T = insert_instruction_here!(compact, settings, @__SOURCE__,
441+
NewInstruction(Expr(:call, typeof, ssa), Type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true)
442+
443+
retssa = insert_instruction_here!(compact, settings, @__SOURCE__,
444+
NewInstruction(Expr(:new, T, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true)
444445
end
445446
return Pair{Any, Any}(retssa, newT)
446447
end
@@ -453,8 +454,8 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim
453454
push!(eqvars.varclassification, External)
454455
push!(eqvars.varkinds, Intrinsics.Continuous)
455456

456-
new_var_ssa = insert_node_here!(compact,
457-
NewInstruction(Expr(:invoke, nothing, variable), Incidence(nonlinrepl), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
457+
new_var_ssa = insert_instruction_here!(compact, settings, @__SOURCE__,
458+
NewInstruction(Expr(:invoke, nothing, variable), Incidence(nonlinrepl), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true)
458459

459460
eq_incidence = ultimate_rt - Incidence(nonlinrepl)
460461
push!(eqvars.total_incidence, eq_incidence)
@@ -463,14 +464,14 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim
463464
push!(eqvars.eqkinds, Intrinsics.Always)
464465
new_eq = length(eqvars.total_incidence)
465466

466-
new_eq_ssa = insert_node_here!(compact,
467-
NewInstruction(Expr(:invoke, nothing, equation), Eq(new_eq), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
467+
new_eq_ssa = insert_instruction_here!(compact, settings, @__SOURCE__,
468+
NewInstruction(Expr(:invoke, nothing, equation), Eq(new_eq), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true)
468469

469-
eq_val_ssa = insert_node_here!(compact,
470-
NewInstruction(Expr(:call, InternalIntrinsics.assign_var, new_var_ssa, ssa), eq_incidence, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
470+
eq_val_ssa = insert_instruction_here!(compact, settings, @__SOURCE__,
471+
NewInstruction(Expr(:call, InternalIntrinsics.assign_var, new_var_ssa, ssa), eq_incidence, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true)
471472

472-
eq_call_ssa = insert_node_here!(compact,
473-
NewInstruction(Expr(:invoke, nothing, new_eq_ssa, eq_val_ssa), Nothing, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true)
473+
eq_call_ssa = insert_instruction_here!(compact, settings, @__SOURCE__,
474+
NewInstruction(Expr(:invoke, nothing, new_eq_ssa, eq_val_ssa), Nothing, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true)
474475

475476
T = widenconst(ultimate_rt)
476477
# TODO: We don't have a way to express that the return value is directly this variable for arbitrary types

src/interface.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function factory_gen(@nospecialize(fT), settings::Settings, world::UInt = Base.g
1111
ci = ad_typeinf(world, Tuple{fT}; force_inline_all=settings.force_inline_all, edges=Core.svec(factory_mi))
1212

1313
# Perform or lookup DAECompiler specific analysis for this system.
14-
result = structural_analysis!(ci, world)
14+
result = structural_analysis!(ci, world, settings)
1515

1616
if isa(result, UncompilableIPOResult)
1717
if isa(result.error, FunctionErrorsException)
@@ -58,17 +58,18 @@ function factory_gen(@nospecialize(fT), settings::Settings, world::UInt = Base.g
5858
end
5959

6060
# Generate the IR implementation of `factory`, returning the DAEFunction/ODEFunction
61+
slotnames = nothing
6162
if settings.mode in (DAE, DAENoInit)
62-
ir_factory = dae_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == DAE ? init_key : nothing)
63+
ir_factory, slotnames = dae_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == DAE ? init_key : nothing)
6364
elseif settings.mode in (ODE, ODENoInit)
64-
ir_factory = ode_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == ODE ? init_key : nothing)
65+
ir_factory, slotnames = ode_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == ODE ? init_key : nothing)
6566
elseif settings.mode == InitUncompress
6667
ir_factory = init_uncompress_gen(result, ci, init_key, diff_key, world, settings)
6768
else
6869
return :(error("Unknown generation mode: $(settings.mode)"))
6970
end
7071

71-
src = ir_to_src(ir_factory, settings)
72+
src = ir_to_src(ir_factory, settings; slotnames)
7273
src.ssavaluetypes = length(src.code)
7374
src.min_world = @atomic ci.min_world
7475
src.max_world = @atomic ci.max_world
@@ -107,5 +108,6 @@ function refresh()
107108
$(Expr(:meta, :generated_only))
108109
$(Expr(:meta, :generated, factory_gen))
109110
end
111+
return nothing
110112
end
111113
refresh()

0 commit comments

Comments
 (0)