@@ -579,17 +579,18 @@ end
579
579
580
580
# Show a single statement, code.stmts[idx]/code.code[idx], in the context of the whole IRCode/CodeInfo.
581
581
# Returns the updated value of bb_idx.
582
- # pop_new_node!(idx::Int) -> (node_idx, new_node_inst, new_node_type) may return a new
583
- # node at the current index `idx`, which is printed before the statement at index
584
- # `idx`. This function is repeatedly called until it returns `nothing`
582
+ # pop_new_node!(idx::Int; attach_after=false) -> (node_idx, new_node_inst, new_node_type)
583
+ # may return a new node at the current index `idx`, which is printed before the statement
584
+ # at index `idx`. This function is repeatedly called until it returns `nothing`.
585
+ # to iterate nodes that are to be inserted after the statement, set `attach_after=true`.
585
586
function show_ir_stmt (io:: IO , code:: Union{IRCode, CodeInfo, IncrementalCompact} , idx:: Int , config:: IRShowConfig ,
586
- used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns (nothing ))
587
+ used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns (nothing ), only_after :: Bool = false )
587
588
return show_ir_stmt (io, code, idx, config. line_info_preprinter, config. line_info_postprinter,
588
- used, cfg, bb_idx; pop_new_node!, config. bb_color)
589
+ used, cfg, bb_idx; pop_new_node!, only_after, config. bb_color)
589
590
end
590
591
591
592
function show_ir_stmt (io:: IO , code:: Union{IRCode, CodeInfo, IncrementalCompact} , idx:: Int , line_info_preprinter, line_info_postprinter,
592
- used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns (nothing ), bb_color= :light_black )
593
+ used:: BitSet , cfg:: CFG , bb_idx:: Int ; pop_new_node! = Returns (nothing ), only_after :: Bool = false , bb_color= :light_black )
593
594
stmt = _stmt (code, idx)
594
595
type = _type (code, idx)
595
596
max_bb_idx_size = length (string (length (cfg. blocks)))
@@ -609,8 +610,7 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
609
610
end
610
611
611
612
i = 1
612
- while true
613
- next = pop_new_node! (idx)
613
+ function print_indentation (final:: Bool = true )
614
614
# Compute BB guard rail
615
615
if bb_idx > length (cfg. blocks)
616
616
# If invariants are violated, print a special leader
@@ -619,7 +619,6 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
619
619
printstyled (io, " !!! " , " ─" ^ max_bb_idx_size, color= bb_color)
620
620
else
621
621
bbrange = cfg. blocks[bb_idx]. stmts
622
- bbrange = bbrange. start: bbrange. stop
623
622
# Print line info update
624
623
linestart = idx == first (bbrange) ? " " : sprint (io -> printstyled (io, " │ " , color= bb_color), context= io)
625
624
linestart *= " " ^ max_bb_idx_size
@@ -632,24 +631,20 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
632
631
bb_pad = max_bb_idx_size - length (bb_idx_str)
633
632
bb_type = length (cfg. blocks[bb_idx]. preds) <= 1 ? " ─" : " ┄"
634
633
printstyled (io, bb_idx_str, " " , bb_type, " ─" ^ bb_pad, color= bb_color)
635
- elseif next === nothing && idx == last (bbrange) # print separator
634
+ elseif final && idx == last (bbrange) # print separator
636
635
printstyled (io, " └" , " ─" ^ (1 + max_bb_idx_size), color= bb_color)
637
636
else
638
637
printstyled (io, " │ " , " " ^ max_bb_idx_size, color= bb_color)
639
638
end
640
639
end
641
640
print (io, inlining_indent, " " )
641
+ end
642
642
643
- if next === nothing
644
- if bb_idx <= length (cfg. blocks) && idx == last (bbrange)
645
- bb_idx += 1
646
- end
647
- break
648
- end
649
-
650
- # print new nodes first in the right position
651
- node_idx, new_node_inst, new_node_type = next
643
+ # first, print new nodes that are to be inserted before the current statement
644
+ function print_new_node (node; final:: Bool = true )
645
+ print_indentation (final)
652
646
647
+ node_idx, new_node_inst, new_node_type = node
653
648
@assert new_node_inst != = UNDEF # we filtered these out earlier
654
649
show_type = should_print_ssa_type (new_node_inst)
655
650
let maxlength_idx= maxlength_idx, show_type= show_type
@@ -664,43 +659,84 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
664
659
line_info_postprinter (io; type = new_node_type, used = node_idx in used, show_type, idx = node_idx)
665
660
end
666
661
println (io)
662
+ end
663
+ while (next = pop_new_node! (idx)) != = nothing
664
+ only_after || print_new_node (next; final= false )
667
665
i += 1
668
666
end
669
- if code isa CodeInfo
670
- stmt = statement_indices_to_labels (stmt, cfg)
667
+
668
+ # peek at the nodes to be inserted after the current statement
669
+ # (to determine of the statement itself is the final one)
670
+ next = pop_new_node! (idx; attach_after= true )
671
+
672
+ # then, print the current statement
673
+ # FIXME : `only_after` is hack so that we can call this function to print uncompacted
674
+ # attach-after nodes when the current node has already been compated already
675
+ if ! only_after
676
+ print_indentation (next=== nothing )
677
+ if code isa CodeInfo
678
+ stmt = statement_indices_to_labels (stmt, cfg)
679
+ end
680
+ show_type = type != = nothing && should_print_ssa_type (stmt)
681
+ print_stmt (io, idx, stmt, used, maxlength_idx, true , show_type)
682
+ if type != = nothing # ignore types for pre-inference code
683
+ if type === UNDEF
684
+ # This is an error, but can happen if passes don't update their type information
685
+ printstyled (io, " ::#UNDEF" , color= :red )
686
+ else
687
+ line_info_postprinter (io; type, used = idx in used, show_type, idx)
688
+ end
689
+ end
690
+ println (io)
671
691
end
672
- show_type = type != = nothing && should_print_ssa_type (stmt)
673
- print_stmt (io, idx, stmt, used, maxlength_idx, true , show_type)
674
- if type != = nothing # ignore types for pre-inference code
675
- if type === UNDEF
676
- # This is an error, but can happen if passes don't update their type information
677
- printstyled (io, " ::#UNDEF" , color= :red )
678
- else
679
- line_info_postprinter (io; type, used = idx in used, show_type, idx)
692
+ i += 1
693
+
694
+ # finally, print new nodes that are to be inserted after the current statement
695
+ while next != = nothing
696
+ print_new_node (next)
697
+ i += 1
698
+ next = pop_new_node! (idx; attach_after= true )
699
+ end
700
+
701
+ # increment the basic block counter
702
+ if bb_idx <= length (cfg. blocks)
703
+ bbrange = cfg. blocks[bb_idx]. stmts
704
+ if bb_idx <= length (cfg. blocks) && idx == last (bbrange)
705
+ bb_idx += 1
680
706
end
681
707
end
682
- println (io)
708
+
683
709
return bb_idx
684
710
end
685
711
686
712
function _new_nodes_iter (stmts, new_nodes, new_nodes_info, new_nodes_idx)
687
713
new_nodes_perm = filter (i -> isassigned (new_nodes. inst, i), 1 : length (new_nodes))
688
714
sort! (new_nodes_perm, by = x -> (x = new_nodes_info[x]; (x. pos, x. attach_after)))
689
- perm_idx = Ref (1 )
690
-
691
- return function get_new_node (idx:: Int )
692
- perm_idx[] <= length (new_nodes_perm) || return nothing
693
- node_idx = new_nodes_perm[perm_idx[]]
694
- if node_idx < new_nodes_idx
695
- # skip new nodes that have already been processed by incremental compact
696
- # (but don't just return nothing because there may be multiple at this pos)
697
- perm_idx[] += 1
698
- return get_new_node (idx)
715
+
716
+ # separate iterators for the nodes that are inserted before resp. after each statement
717
+ before_iter = Ref (1 )
718
+ after_iter = Ref (1 )
719
+
720
+ return function get_new_node (idx:: Int ; attach_after= false )
721
+ iter = attach_after ? after_iter : before_iter
722
+ iter[] <= length (new_nodes_perm) || return nothing
723
+ node_idx = new_nodes_perm[iter[]]
724
+
725
+ # skip nodes
726
+ while node_idx < new_nodes_idx || # already compacted
727
+ idx > new_nodes_info[node_idx]. pos || # not interested in
728
+ new_nodes_info[node_idx]. attach_after != attach_after
729
+ iter[] += 1
730
+ iter[] > length (new_nodes_perm) && return nothing
731
+ node_idx = new_nodes_perm[iter[]]
699
732
end
700
- if new_nodes_info[node_idx]. pos != idx
733
+
734
+ if new_nodes_info[node_idx]. pos != idx ||
735
+ new_nodes_info[node_idx]. attach_after != attach_after
701
736
return nothing
702
737
end
703
- perm_idx[] += 1
738
+
739
+ iter[] += 1
704
740
new_node = new_nodes[node_idx]
705
741
new_node_inst = isassigned (new_nodes. inst, node_idx) ? new_node[:inst ] : UNDEF
706
742
new_node_type = isassigned (new_nodes. type, node_idx) ? new_node[:type ] : UNDEF
@@ -877,6 +913,9 @@ function show_ir(io::IO, compact::IncrementalCompact, config::IRShowConfig=defau
877
913
while pop_new_node! (input_idx) != = nothing
878
914
count += 1
879
915
end
916
+ while pop_new_node! (input_idx; attach_after= true ) != = nothing
917
+ count += 1
918
+ end
880
919
end
881
920
882
921
result_bb = result_bbs[compact. active_result_bb]
@@ -918,6 +957,13 @@ function show_ir(io::IO, compact::IncrementalCompact, config::IRShowConfig=defau
918
957
pop_new_node! = new_nodes_iter (compact. ir, compact. new_nodes_idx)
919
958
maxssaid = length (compact. ir. stmts) + Core. Compiler. length (compact. ir. new_nodes)
920
959
let io = IOContext (io, :maxssaid => maxssaid)
960
+ # first show any new nodes to be attached after the last compacted statement
961
+ if compact. idx > 1
962
+ show_ir_stmt (io, compact. ir, compact. idx- 1 , config, used_uncompacted,
963
+ uncompacted_cfg, bb_idx; pop_new_node!, only_after= true )
964
+ end
965
+
966
+ # then show the actual uncompacted IR
921
967
show_ir_stmts (io, compact. ir, compact. idx: length (stmts), config, used_uncompacted,
922
968
uncompacted_cfg, bb_idx; pop_new_node!)
923
969
end
0 commit comments