Skip to content

Commit

Permalink
add option to print inlining costs
Browse files Browse the repository at this point in the history
This allows printing inlining costs alongside optimized IR similar to
`Base.print_statement_costs`, which I found useful for debugging why
some functions are not inlined. They are highlighted green, because I
found them hard to distinguish otherwise, but I am open to suggestions
regarding formatting. This relies on JuliaLang/julia#41257, which I hope
can be backported to 1.7, so we don't have to worry about compatibility.
  • Loading branch information
simeonschaub committed Jun 23, 2021
1 parent 886f6a7 commit 630817b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 32 deletions.
6 changes: 4 additions & 2 deletions src/Cthulhu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ using .DInfo: DebugInfo
# src/reflection.jl has the tools to discover methods
# src/ui.jl provides the user facing interface to which _descend responds
##
function _descend(interp::CthulhuInterpreter, mi::MethodInstance; override::Union{Nothing, InferenceResult} = nothing, iswarn::Bool, params=current_params(), optimize::Bool=true, interruptexc::Bool=true, verbose=true, kwargs...)
function _descend(interp::CthulhuInterpreter, mi::MethodInstance; override::Union{Nothing, InferenceResult} = nothing, iswarn::Bool, params=current_params(), optimize::Bool=true, interruptexc::Bool=true, verbose=true, inline_cost::Bool=false, kwargs...)
debuginfo = DInfo.compact # default is compact debuginfo
if :debuginfo in keys(kwargs)
selected = kwargs[:debuginfo]
Expand Down Expand Up @@ -244,7 +244,7 @@ function _descend(interp::CthulhuInterpreter, mi::MethodInstance; override::Unio
preprocess_ci!(codeinf, mi, optimize, CONFIG)
callsites = find_callsites(interp, codeinf, infos, mi, slottypes, optimize; params, kwargs...)

display_CI && cthulu_typed(stdout, debuginfo_key, codeinf, rt, mi, iswarn, verbose)
display_CI && cthulu_typed(stdout, debuginfo_key, codeinf, rt, mi, iswarn, verbose, inline_cost)
display_CI = true
end

Expand Down Expand Up @@ -327,6 +327,8 @@ function _descend(interp::CthulhuInterpreter, mi::MethodInstance; override::Unio
continue
elseif toggle === :debuginfo
debuginfo = DebugInfo((Int(debuginfo) + 1) % 3)
elseif toggle === :inline_cost
inline_cost ⊻= true
elseif toggle === :highlighter
CONFIG.enable_highlighter ⊻= true
if CONFIG.enable_highlighter
Expand Down
70 changes: 41 additions & 29 deletions src/codeview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,53 +72,65 @@ function is_type_unstable(code::Union{IRCode, CodeInfo}, idx::Int, used::BitSet)
end

cthulhu_warntype(args...) = cthulhu_warntype(stdout, args...)
function cthulhu_warntype(io::IO, src, rettype, debuginfo, stable_code)
debuginfo = IRShow.debuginfo(debuginfo)
lineprinter = __debuginfo[debuginfo]
lambda_io::IOContext = io
if hasfield(typeof(src), :slotnames) && src.slotnames !== nothing
slotnames = Base.sourceinfo_slotnames(src)
lambda_io = IOContext(lambda_io, :SOURCE_SLOTNAMES => slotnames)
show_variables(io, src, slotnames)
function cthulhu_warntype(io::IO, src, rettype, debuginfo, stable_code, inline_cost=false)
if inline_cost
error("Need a MethodInstance to show inlining costs. Call `cthulhu_typed` directly instead.")
end
print(io, "Body")
InteractiveUtils.warntype_type_printer(io, rettype, true)
println(io)

should_print_stmt = (src isa IRCode || stable_code) ? Returns(true) : is_type_unstable
bb_color = (src isa IRCode && debuginfo === :compact) ? :normal : :light_black
irshow_config = IRShowConfig(
lineprinter(src), InteractiveUtils.warntype_type_printer;
should_print_stmt, bb_color,
)
show_ir(io, src, irshow_config)
cthulhu_typed(io, debuginfo, src, rettype, nothing, false, stable_code, inline_cost)
return nothing
end


function cthulu_typed(io::IO, debuginfo, src, rt, mi, iswarn, stable_code)
function cthulu_typed(io::IO, debuginfo, src, rt, mi, iswarn, stable_code, inline_cost=false)
debuginfo = IRShow.debuginfo(debuginfo)
lineprinter = __debuginfo[debuginfo]
rettype = ignorelimited(rt)
lambda_io::IOContext = io

if isa(src, Core.CodeInfo)
# we're working on pre-optimization state, need to ignore `LimitedAccuracy`
src = copy(src)
src.ssavaluetypes = ignorelimited.(src.ssavaluetypes::Vector{Any})
src.rettype = ignorelimited(src.rettype)
end

println(io)
println(io, "│ ─ $(string(Callsite(-1, MICallInfo(mi, rettype), :invoke)))")
if src.slotnames !== nothing
slotnames = Base.sourceinfo_slotnames(src)
lambda_io = IOContext(lambda_io, :SOURCE_SLOTNAMES => slotnames)
iswarn && show_variables(io, src, slotnames)
end
end

if iswarn
cthulhu_warntype(io, src, rettype, debuginfo, stable_code)
print(io, "Body")
InteractiveUtils.warntype_type_printer(io, rettype, true)
println(io)
else
bb_color = (src isa IRCode && debuginfo === :compact) ? :normal : :light_black
irshow_config = IRShowConfig(lineprinter(src); bb_color)
show_ir(io, src, irshow_config)
println(io, "│ ─ $(string(Callsite(-1, MICallInfo(mi, rettype), :invoke)))")
end
println(io)

if src isa IRCode && inline_cost
code = src isa IRCode ? src.stmts.inst : src.code
cst = Vector{Int}(undef, length(code))
params = Core.Compiler.OptimizationParams(Core.Compiler.NativeInterpreter())
maxcost = Core.Compiler.statement_costs!(cst, code, src, Any[mi.sparam_vals...], false, params)
nd = ndigits(maxcost)
_lineprinter = lineprinter(src)
function preprinter(io, linestart, idx)
str = idx > 0 ? lpad(cst[idx], nd+1) : " "^(nd+1)
str = sprint(io -> Base.printstyled(io, str; color=:green); context=:color=>true)
return str * _lineprinter(io, linestart, idx)
end
else
preprinter = lineprinter(src)
end
postprinter = iswarn ? InteractiveUtils.warntype_type_printer : IRShow.default_expr_type_printer

should_print_stmt = (iswarn || src isa IRCode || stable_code) ? Returns(true) : is_type_unstable
bb_color = (src isa IRCode && debuginfo === :compact) ? :normal : :light_black

irshow_config = IRShowConfig(preprinter, postprinter; should_print_stmt, bb_color)

show_ir(io, src, irshow_config)
return nothing
end

function show_variables(io, src, slotnames)
Expand Down
5 changes: 4 additions & 1 deletion src/ui.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function TerminalMenus.header(m::CthulhuMenu)
m.sub_menu && return ""
"""
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [o]ptimize, [w]arn, [v]erbose printing for warntype code, [d]ebuginfo, [s]yntax highlight for Source/LLVM/Native.
Toggles: [o]ptimize, [w]arn, [v]erbose printing for warntype code, [d]ebuginfo, [i]nlining costs, [s]yntax highlight for Source/LLVM/Native.
Show: [S]ource code, [A]ST, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
Advanced: dump [P]arams cache.
Expand All @@ -67,6 +67,9 @@ function TerminalMenus.keypress(m::CthulhuMenu, key::UInt32)
elseif key == UInt32('d')
m.toggle = :debuginfo
return true
elseif key == UInt32('i')
m.toggle = :inline_cost
return true
elseif key == UInt32('s')
m.toggle = :highlighter
return true
Expand Down

0 comments on commit 630817b

Please sign in to comment.