@@ -21,15 +21,13 @@ function Base.show(io::IO, cfg::CFG)
21
21
end
22
22
23
23
function print_stmt (io:: IO , idx:: Int , @nospecialize (stmt), used:: BitSet , maxlength_idx:: Int , color:: Bool , show_type:: Bool )
24
+ indent = maxlength_idx + 4
24
25
if idx in used
25
- idx_s = string (idx)
26
- pad = " " ^ (maxlength_idx - length (idx_s) + 1 )
27
- print (io, " %" , idx_s, pad, " = " )
26
+ pad = " " ^ (maxlength_idx - length (string (idx)) + 1 )
27
+ print (io, " %" , idx, pad, " = " )
28
28
else
29
- print (io, " " ^ (maxlength_idx + 4 ) )
29
+ print (io, " " ^ indent )
30
30
end
31
- # TODO : `indent` is supposed to be the full width of the leader for correct alignment
32
- indent = 16
33
31
if ! color && stmt isa PiNode
34
32
# when the outer context is already colored (yellow, for pending nodes), don't use the usual coloring printer
35
33
print (io, " π (" )
@@ -316,145 +314,6 @@ end
316
314
317
315
Base. show (io:: IO , code:: IRCode ) = show_ir (io, code)
318
316
319
-
320
- lineinfo_disabled (io:: IO , linestart:: String , lineidx:: Int32 ) = " "
321
-
322
- function DILineInfoPrinter (linetable:: Vector )
323
- context = LineInfoNode[]
324
- context_depth = Ref (0 )
325
- indent (s:: String ) = s^ (max (context_depth[], 1 ) - 1 )
326
- function emit_lineinfo_update (io:: IO , linestart:: String , lineidx:: Int32 )
327
- # internal configuration options:
328
- collapse = true
329
- indent_all = true
330
- # convert lineidx to a vector
331
- lineidx == 0 && return indent_all ? indent (" │" ) : " " # just skip over lines with no debug info at all
332
- DI = LineInfoNode[]
333
- while lineidx != 0
334
- entry = linetable[lineidx]:: LineInfoNode
335
- push! (DI, entry)
336
- lineidx = entry. inlined_at
337
- end
338
- nframes = length (DI)
339
- nctx = 0
340
- pop_skips = 0
341
- # compute the size of the matching prefix in the inlining information stack
342
- for i = 1 : min (length (context), nframes)
343
- CtxLine = context[i]
344
- FrameLine = DI[nframes - i + 1 ]
345
- CtxLine === FrameLine || break
346
- nctx = i
347
- end
348
- update_line_only = false
349
- if collapse && 0 < nctx
350
- # check if we're adding more frames with the same method name,
351
- # if so, drop all existing calls to it from the top of the context
352
- # AND check if instead the context was previously printed that way
353
- # but now has removed the recursive frames
354
- let method = context[nctx]. method
355
- if (nctx < nframes && DI[nframes - nctx]. method === method) ||
356
- (nctx < length (context) && context[nctx + 1 ]. method === method)
357
- update_line_only = true
358
- while nctx > 0 && context[nctx]. method === method
359
- nctx -= 1
360
- end
361
- end
362
- end
363
- end
364
- # examine what frames we're returning from
365
- if nctx < length (context)
366
- # compute the new inlining depth
367
- if collapse
368
- npops = 1
369
- let Prev = context[nctx + 1 ]. method
370
- for i = (nctx + 2 ): length (context)
371
- Next = context[i]. method
372
- Prev === Next || (npops += 1 )
373
- Prev = Next
374
- end
375
- end
376
- else
377
- npops = length (context) - nctx
378
- end
379
- # look at the first non-matching element to see if we are only changing the line number
380
- if ! update_line_only && nctx < nframes
381
- let CtxLine = context[nctx + 1 ],
382
- FrameLine = DI[nframes - nctx]
383
- if CtxLine. file == FrameLine. file &&
384
- CtxLine. method == FrameLine. method &&
385
- CtxLine. mod == FrameLine. mod
386
- update_line_only = true
387
- end
388
- end
389
- end
390
- resize! (context, nctx)
391
- update_line_only && (npops -= 1 )
392
- if npops > 0
393
- context_depth[] -= npops
394
- print (io, linestart, indent (" │" ), " ┘" ^ npops, " \n " )
395
- end
396
- end
397
- # see what change we made to the outermost line number
398
- if update_line_only
399
- frame = DI[nframes - nctx]
400
- nctx += 1
401
- push! (context, frame)
402
- if frame. line != typemax (frame. line) && frame. line != 0
403
- print (io, linestart, indent (" │" ), " @ " , frame. file, " :" , frame. line, " within `" , frame. method, " '" )
404
- if collapse
405
- method = frame. method
406
- while nctx < nframes
407
- frame = DI[nframes - nctx]
408
- frame. method === method || break
409
- nctx += 1
410
- push! (context, frame)
411
- print (io, " @ " , frame. file, " :" , frame. line)
412
- end
413
- end
414
- print (io, " \n " )
415
- end
416
- end
417
- # now print the rest of the new frames
418
- while nctx < nframes
419
- frame = DI[nframes - nctx]
420
- print (io, linestart, indent (" │" ))
421
- nctx += 1
422
- push! (context, frame)
423
- context_depth[] += 1
424
- nctx != 1 && print (io, " ┌" )
425
- print (io, " @ " , frame. file)
426
- if frame. line != typemax (frame. line) && frame. line != 0
427
- print (io, " :" , frame. line)
428
- end
429
- print (io, " within `" , frame. method, " '" )
430
- if collapse
431
- method = frame. method
432
- while nctx < nframes
433
- frame = DI[nframes - nctx]
434
- frame. method === method || break
435
- nctx += 1
436
- push! (context, frame)
437
- print (io, " @ " , frame. file, " :" , frame. line)
438
- end
439
- end
440
- print (io, " \n " )
441
- end
442
- # FOR DEBUGGING `collapse`:
443
- # let Prev = context[1].method,
444
- # depth2 = 1
445
- # for i = 2:nctx
446
- # Next = context[i].method
447
- # (collapse && Prev === Next) || (depth2 += 1)
448
- # Prev = Next
449
- # end
450
- # @assert context_depth[] == depth2
451
- # end
452
- return indent_all ? indent (" │" ) : " "
453
- end
454
- return emit_lineinfo_update
455
- end
456
-
457
-
458
317
function show_ir (io:: IO , code:: IRCode , expr_type_printer= default_expr_type_printer; verbose_linetable= false )
459
318
cols = displaysize (io)[2 ]
460
319
used = BitSet ()
@@ -606,7 +465,7 @@ function show_ir(io::IO, code::IRCode, expr_type_printer=default_expr_type_print
606
465
end
607
466
end
608
467
609
- function show_ir (io:: IO , code:: CodeInfo , line_info_preprinter = DILineInfoPrinter (code . linetable), line_info_postprinter = default_expr_type_printer )
468
+ function show_ir (io:: IO , code:: CodeInfo , expr_type_printer = default_expr_type_printer; verbose_linetable = false )
610
469
cols = displaysize (io)[2 ]
611
470
used = BitSet ()
612
471
stmts = code. code
@@ -624,6 +483,14 @@ function show_ir(io::IO, code::CodeInfo, line_info_preprinter=DILineInfoPrinter(
624
483
maxused = maximum (used)
625
484
maxlength_idx = length (string (maxused))
626
485
end
486
+ if ! verbose_linetable
487
+ (loc_annotations, loc_methods, loc_lineno) = compute_ir_line_annotations (code)
488
+ max_loc_width = maximum (length (str) for str in loc_annotations)
489
+ max_lineno_width = maximum (length (str) for str in loc_lineno)
490
+ max_method_width = maximum (length (str) for str in loc_methods)
491
+ end
492
+ max_depth = maximum (compute_inlining_depth (code. linetable, line) for line in code. codelocs)
493
+ last_stack = []
627
494
for idx in eachindex (stmts)
628
495
if ! isassigned (stmts, idx)
629
496
# This is invalid, but do something useful rather
@@ -632,24 +499,63 @@ function show_ir(io::IO, code::CodeInfo, line_info_preprinter=DILineInfoPrinter(
632
499
continue
633
500
end
634
501
stmt = stmts[idx]
502
+ # Compute BB guard rail
635
503
bbrange = cfg. blocks[bb_idx]. stmts
636
504
bbrange = bbrange. first: bbrange. last
637
- # Print line info update
638
- linestart = idx == first (bbrange) ? " " : sprint (io -> printstyled (io, " │ " , color = :light_black ), context = io )
639
- linestart *= " " ^ max_bb_idx_size
640
- inlining_indent = line_info_preprinter (io, linestart, code . codelocs[idx] )
641
- # Compute BB guard rail
505
+ bb_idx_str = string (bb_idx)
506
+ bb_pad = max_bb_idx_size - length (bb_idx_str )
507
+ bb_type = length (cfg . blocks[bb_idx] . preds) <= 1 ? " ─ " : " ┄ "
508
+ bb_start_str = string (bb_idx_str, " " , bb_type, " ─ " ^ bb_pad, " " )
509
+ bb_guard_rail_cont = string ( " │ " , " " ^ max_bb_idx_size)
642
510
if idx == first (bbrange)
643
- bb_idx_str = string (bb_idx)
644
- bb_pad = max_bb_idx_size - length (bb_idx_str)
645
- bb_type = length (cfg. blocks[bb_idx]. preds) <= 1 ? " ─" : " ┄"
646
- printstyled (io, bb_idx_str, " " , bb_type, " ─" ^ bb_pad, color= :light_black )
647
- elseif idx == last (bbrange) # print separator
648
- printstyled (io, " └" , " ─" ^ (1 + max_bb_idx_size), color= :light_black )
511
+ bb_guard_rail = bb_start_str
512
+ else
513
+ bb_guard_rail = bb_guard_rail_cont
514
+ end
515
+ # Print linetable information
516
+ if verbose_linetable
517
+ stack = compute_loc_stack (code. linetable, code. codelocs[idx])
518
+ # We need to print any stack frames that did not exist in the last stack
519
+ ndepth = max (1 , length (stack))
520
+ rail = string (" " ^ (max_depth+ 1 - ndepth), " │" ^ ndepth)
521
+ start_column = cols - max_depth - 10
522
+ for (i, x) in enumerate (stack)
523
+ if i > length (last_stack) || last_stack[i] != x
524
+ entry = code. linetable[x]
525
+ printstyled (io, " \e [$(start_column) G$(rail) \e [1G" , color = :light_black )
526
+ print (io, bb_guard_rail)
527
+ ssa_guard = " " ^ (maxlength_idx + 4 + (i - 1 ))
528
+ entry_label = " $(ssa_guard)$(entry. method) at $(entry. file) :$(entry. line) "
529
+ hline = string (" ─" ^ (start_column- length (entry_label)- length (bb_guard_rail)+ max_depth- i), " ┐" )
530
+ printstyled (io, string (entry_label, hline), " \n " ; color= :light_black )
531
+ bb_guard_rail = bb_guard_rail_cont
532
+ end
533
+ end
534
+ printstyled (io, " \e [$(start_column) G$(rail) \e [1G" , color = :light_black )
535
+ last_stack = stack
649
536
else
650
- printstyled (io, " │ " , " " ^ max_bb_idx_size, color= :light_black )
537
+ annotation = loc_annotations[idx]
538
+ loc_method = loc_methods[idx]
539
+ lineno = loc_lineno[idx]
540
+ # Print location information right aligned. If the line below is too long, it'll overwrite this,
541
+ # but that's what we want.
542
+ if get (io, :color , false )
543
+ method_start_column = cols - max_method_width - max_loc_width - 2
544
+ filler = " " ^ (max_loc_width- length (annotation))
545
+ printstyled (io, " \e [$(method_start_column) G$(annotation)$(filler)$(loc_method) \e [1G" , color = :light_black )
546
+ end
547
+ printstyled (io, lineno, " " ^ (max_lineno_width- length (lineno)+ 1 ); color = :light_black )
548
+ end
549
+ idx != last (bbrange) && print (io, bb_guard_rail)
550
+ if idx == last (bbrange) # print separator
551
+ if idx == first (bbrange)
552
+ print (io, bb_start_str)
553
+ elseif idx == last (bbrange)
554
+ print (io, " └" , " ─" ^ (1 + max_bb_idx_size), " " )
555
+ else
556
+ print (io, " │ " , " " ^ max_bb_idx_size)
557
+ end
651
558
end
652
- print (io, inlining_indent, " " )
653
559
if idx == last (bbrange)
654
560
bb_idx += 1
655
561
end
@@ -676,7 +582,7 @@ function show_ir(io::IO, code::CodeInfo, line_info_preprinter=DILineInfoPrinter(
676
582
printstyled (io, " ::#UNDEF" , color= :red )
677
583
elseif show_type
678
584
typ = types[idx]
679
- line_info_postprinter (io, typ, idx in used)
585
+ expr_type_printer (io, typ, idx in used)
680
586
end
681
587
end
682
588
println (io)
0 commit comments