@@ -487,6 +487,25 @@ function DILineInfoPrinter(linetable::Vector, showtypes::Bool=false)
487487 return emit_lineinfo_update
488488end
489489
490+ # line_info_preprinter(io::IO, indent::String, idx::Int) may print relevant info
491+ # at the beginning of the line, and should at least print `indent`. It returns a
492+ # string that will be printed after the final basic-block annotation.
493+ # line_info_postprinter(io::IO, typ, used::Bool) prints the type-annotation at the end
494+ # of the statement
495+ # should_print_stmt(idx::Int) -> Bool: whether the statement at index `idx` should be
496+ # printed as part of the IR or not
497+ # bb_color: color used for printing the basic block brackets on the left
498+ struct IRShowConfig
499+ line_info_preprinter
500+ line_info_postprinter
501+ should_print_stmt
502+ bb_color:: Symbol
503+ function IRShowConfig (line_info_preprinter, line_info_postprinter= default_expr_type_printer;
504+ should_print_stmt= Returns (true ), bb_color:: Symbol = :light_black )
505+ return new (line_info_preprinter, line_info_postprinter, should_print_stmt, bb_color)
506+ end
507+ end
508+
490509struct _UNDEF
491510 global const UNDEF = _UNDEF. instance
492511end
@@ -510,7 +529,7 @@ function _type(code::CodeInfo, idx::Int)
510529 return isassigned (types, idx) ? types[idx] : UNDEF
511530end
512531
513- function statement_indices_to_labels (@nospecialize ( stmt) , cfg:: CFG )
532+ function statement_indices_to_labels (stmt, cfg:: CFG )
514533 # convert statement index to labels, as expected by print_stmt
515534 if stmt isa Expr
516535 if stmt. head === :enter && length (stmt. args) == 1 && stmt. args[1 ] isa Int
@@ -529,16 +548,17 @@ end
529548
530549# Show a single statement, code.stmts[idx]/code.code[idx], in the context of the whole IRCode/CodeInfo.
531550# Returns the updated value of bb_idx.
532- # line_info_preprinter(io::IO, indent::String, idx::Int) may print relevant info
533- # at the beginning of the line, and should at least print `indent`. It returns a
534- # string that will be printed after the final basic-block annotation.
535- # line_info_postprinter(io::IO, typ, used::Bool) prints the type-annotation at the end
536- # of the statement
537551# pop_new_node!(idx::Int) -> (node_idx, new_node_inst, new_node_type) may return a new
538552# node at the current index `idx`, which is printed before the statement at index
539553# `idx`. This function is repeatedly called until it returns `nothing`
554+ function show_ir_stmt (io:: IO , code:: Union{IRCode, CodeInfo} , idx:: Int , config:: IRShowConfig ,
555+ used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns (nothing ))
556+ return show_ir_stmt (io, code, idx, config. line_info_preprinter, config. line_info_postprinter,
557+ used, cfg, bb_idx; pop_new_node!, config. bb_color)
558+ end
559+
540560function show_ir_stmt (io:: IO , code:: Union{IRCode, CodeInfo} , idx:: Int , line_info_preprinter, line_info_postprinter,
541- used:: BitSet , cfg:: CFG , bb_idx:: Int , pop_new_node! = _ -> nothing ; bb_color= :light_black )
561+ used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns ( nothing ), bb_color= :light_black )
542562 stmt = _stmt (code, idx)
543563 type = _type (code, idx)
544564 max_bb_idx_size = length (string (length (cfg. blocks)))
@@ -653,8 +673,8 @@ function ircode_new_nodes_iter(code::IRCode)
653673 end
654674end
655675
656- # corresponds to `verbose_linetable=false`
657- function ircode_default_linfo_printer (code:: IRCode )
676+ # print only line numbers on the left, some of the method names and nesting depth on the right
677+ function inline_linfo_printer (code:: IRCode )
658678 loc_annotations, loc_methods, loc_lineno = compute_ir_line_annotations (code)
659679 max_loc_width = maximum (length, loc_annotations)
660680 max_lineno_width = maximum (length, loc_lineno)
@@ -693,10 +713,11 @@ end
693713_strip_color (s:: String ) = replace (s, r" \e\[\d +m" => " " )
694714
695715# corresponds to `verbose_linetable=true`
696- function ircode_verbose_linfo_printer (code:: IRCode , used :: BitSet )
716+ function ircode_verbose_linfo_printer (code:: IRCode )
697717 stmts = code. stmts
698718 max_depth = maximum (compute_inlining_depth (code. linetable, stmts[i][:line ]) for i in 1 : length (stmts. line))
699719 last_stack = Ref (Int[])
720+ used = stmts_used (code, false )
700721 maxlength_idx = if isempty (used)
701722 0
702723 else
@@ -733,16 +754,27 @@ function ircode_verbose_linfo_printer(code::IRCode, used::BitSet)
733754 end
734755end
735756
736- function show_ir (io:: IO , code:: IRCode , expr_type_printer= default_expr_type_printer; verbose_linetable= false )
757+ function statementidx_lineinfo_printer (f, code:: IRCode )
758+ printer = f (code. linetable)
759+ function (io:: IO , indent:: String , idx:: Int )
760+ printer (io, indent, idx > 0 ? code. stmts[idx][:line ] : typemin (Int32))
761+ end
762+ end
763+ function statementidx_lineinfo_printer (f, code:: CodeInfo )
764+ printer = f (code. linetable)
765+ function (io:: IO , indent:: String , idx:: Int )
766+ printer (io, indent, idx > 0 ? code. codelocs[idx] : typemin (Int32))
767+ end
768+ end
769+ statementidx_lineinfo_printer (code) = statementidx_lineinfo_printer (DILineInfoPrinter, code)
770+
771+ function stmts_used (code:: IRCode , warn_unset_entry= true )
737772 stmts = code. stmts
738- isempty (stmts) && return # unlikely, but avoid errors from reducing over empty sets
739773 used = BitSet ()
740- cfg = code. cfg
741774 for stmt in stmts
742775 scan_ssa_use! (push!, used, stmt[:inst ])
743776 end
744777 new_nodes = code. new_nodes. stmts
745- warn_unset_entry = true
746778 for nn in 1 : length (new_nodes)
747779 if isassigned (new_nodes. inst, nn)
748780 scan_ssa_use! (push!, used, new_nodes[nn][:inst ])
@@ -751,44 +783,42 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print
751783 warn_unset_entry = false
752784 end
753785 end
754- bb_idx = 1
755-
756- pop_new_node! = ircode_new_nodes_iter (code)
757-
758- if verbose_linetable
759- line_info_preprinter = ircode_verbose_linfo_printer (code, used)
760- else
761- line_info_preprinter = ircode_default_linfo_printer (code)
762- end
763-
764- for idx in 1 : length (stmts)
765- bb_idx = show_ir_stmt (io, code, idx, line_info_preprinter, expr_type_printer,
766- used, cfg, bb_idx, pop_new_node!; bb_color= :normal )
767- end
768- nothing
769- end
770-
771- function statementidx_lineinfo_printer (f, code:: CodeInfo )
772- printer = f (code. linetable)
773- return (io:: IO , indent:: String , idx:: Int ) -> printer (io, indent, idx > 0 ? code. codelocs[idx] : typemin (Int32))
786+ return used
774787end
775- statementidx_lineinfo_printer (code:: CodeInfo ) = statementidx_lineinfo_printer (DILineInfoPrinter, code)
776788
777- function show_ir (io :: IO , code:: CodeInfo , line_info_preprinter = statementidx_lineinfo_printer (code), line_info_postprinter = default_expr_type_printer )
789+ function stmts_used ( code:: CodeInfo )
778790 stmts = code. code
779791 used = BitSet ()
780- cfg = compute_basic_blocks (stmts)
781792 for stmt in stmts
782793 scan_ssa_use! (push!, used, stmt)
783794 end
795+ return used
796+ end
797+
798+ function default_config (code:: IRCode ; verbose_linetable= false )
799+ return IRShowConfig (verbose_linetable ? ircode_verbose_linfo_printer (code)
800+ : inline_linfo_printer (code);
801+ bb_color= :normal )
802+ end
803+ default_config (code:: CodeInfo ) = IRShowConfig (statementidx_lineinfo_printer (code))
804+
805+ function show_ir (io:: IO , code:: Union{IRCode, CodeInfo} , config:: IRShowConfig = default_config (code);
806+ pop_new_node! = code isa IRCode ? ircode_new_nodes_iter (code) : Returns (nothing ))
807+ stmts = code isa IRCode ? code. stmts : code. code
808+ used = stmts_used (code)
809+ cfg = code isa IRCode ? code. cfg : compute_basic_blocks (stmts)
784810 bb_idx = 1
785811
786812 for idx in 1 : length (stmts)
787- bb_idx = show_ir_stmt (io, code, idx, line_info_preprinter, line_info_postprinter, used, cfg, bb_idx)
813+ if config. should_print_stmt (code, idx, used)
814+ bb_idx = show_ir_stmt (io, code, idx, config, used, cfg, bb_idx; pop_new_node!)
815+ elseif bb_idx <= length (cfg. blocks) && idx == cfg. blocks[bb_idx]. stmts. stop
816+ bb_idx += 1
817+ end
788818 end
789819
790820 max_bb_idx_size = length (string (length (cfg. blocks)))
791- line_info_preprinter (io, " " ^ (max_bb_idx_size + 2 ), 0 )
821+ config . line_info_preprinter (io, " " ^ (max_bb_idx_size + 2 ), 0 )
792822 nothing
793823end
794824
0 commit comments