@@ -381,6 +381,9 @@ struct UndefToken end; const UNDEF_TOKEN = UndefToken()
381381 isdefined (stmt, :val ) || return OOB_TOKEN
382382 op == 1 || return OOB_TOKEN
383383 return stmt. val
384+ elseif isa (stmt, Union{SSAValue, NewSSAValue})
385+ op == 1 || return OOB_TOKEN
386+ return stmt
384387 elseif isa (stmt, UpsilonNode)
385388 isdefined (stmt, :val ) || return OOB_TOKEN
386389 op == 1 || return OOB_TOKEN
430433 elseif isa (stmt, ReturnNode)
431434 op == 1 || throw (BoundsError ())
432435 stmt = typeof (stmt)(v)
436+ elseif isa (stmt, Union{SSAValue, NewSSAValue})
437+ op == 1 || throw (BoundsError ())
438+ stmt = v
433439 elseif isa (stmt, UpsilonNode)
434440 op == 1 || throw (BoundsError ())
435441 stmt = typeof (stmt)(v)
457463
458464function userefs (@nospecialize (x))
459465 relevant = (isa (x, Expr) && is_relevant_expr (x)) ||
460- isa (x, GotoIfNot) || isa (x, ReturnNode) ||
466+ isa (x, GotoIfNot) || isa (x, ReturnNode) || isa (x, SSAValue) || isa (x, NewSSAValue) ||
461467 isa (x, PiNode) || isa (x, PhiNode) || isa (x, PhiCNode) || isa (x, UpsilonNode)
462468 return UseRefIterator (x, relevant)
463469end
@@ -480,50 +486,10 @@ end
480486
481487# This function is used from the show code, which may have a different
482488# `push!`/`used` type since it's in Base.
483- function scan_ssa_use! (push!, used, @nospecialize (stmt))
484- if isa (stmt, SSAValue)
485- push! (used, stmt. id)
486- end
487- for useref in userefs (stmt)
488- val = useref[]
489- if isa (val, SSAValue)
490- push! (used, val. id)
491- end
492- end
493- end
489+ scan_ssa_use! (push!, used, @nospecialize (stmt)) = foreachssa (ssa -> push! (used, ssa. id), stmt)
494490
495491# Manually specialized copy of the above with push! === Compiler.push!
496- function scan_ssa_use! (used:: IdSet , @nospecialize (stmt))
497- if isa (stmt, SSAValue)
498- push! (used, stmt. id)
499- end
500- for useref in userefs (stmt)
501- val = useref[]
502- if isa (val, SSAValue)
503- push! (used, val. id)
504- end
505- end
506- end
507-
508- function ssamap (f, @nospecialize (stmt))
509- urs = userefs (stmt)
510- for op in urs
511- val = op[]
512- if isa (val, SSAValue)
513- op[] = f (val)
514- end
515- end
516- return urs[]
517- end
518-
519- function foreachssa (f, @nospecialize (stmt))
520- for op in userefs (stmt)
521- val = op[]
522- if isa (val, SSAValue)
523- f (val)
524- end
525- end
526- end
492+ scan_ssa_use! (used:: IdSet , @nospecialize (stmt)) = foreachssa (ssa -> push! (used, ssa. id), stmt)
527493
528494function insert_node! (ir:: IRCode , pos:: Int , inst:: NewInstruction , attach_after:: Bool = false )
529495 node = add! (ir. new_nodes, pos, attach_after)
@@ -751,20 +717,13 @@ end
751717
752718function count_added_node! (compact:: IncrementalCompact , @nospecialize (v))
753719 needs_late_fixup = false
754- if isa (v, SSAValue)
755- compact. used_ssas[v. id] += 1
756- elseif isa (v, NewSSAValue)
757- compact. new_new_used_ssas[v. id] += 1
758- needs_late_fixup = true
759- else
760- for ops in userefs (v)
761- val = ops[]
762- if isa (val, SSAValue)
763- compact. used_ssas[val. id] += 1
764- elseif isa (val, NewSSAValue)
765- compact. new_new_used_ssas[val. id] += 1
766- needs_late_fixup = true
767- end
720+ for ops in userefs (v)
721+ val = ops[]
722+ if isa (val, SSAValue)
723+ compact. used_ssas[val. id] += 1
724+ elseif isa (val, NewSSAValue)
725+ compact. new_new_used_ssas[val. id] += 1
726+ needs_late_fixup = true
768727 end
769728 end
770729 return needs_late_fixup
@@ -931,6 +890,27 @@ function setindex!(compact::IncrementalCompact, @nospecialize(v), idx::Int)
931890 return compact
932891end
933892
893+ __set_check_ssa_counts (onoff:: Bool ) = __check_ssa_counts__[] = onoff
894+ const __check_ssa_counts__ = fill (false )
895+
896+ function _oracle_check (compact:: IncrementalCompact )
897+ observed_used_ssas = Core. Compiler. find_ssavalue_uses1 (compact)
898+ for i = 1 : length (observed_used_ssas)
899+ if observed_used_ssas[i] != compact. used_ssas[i]
900+ return observed_used_ssas
901+ end
902+ end
903+ return nothing
904+ end
905+
906+ function oracle_check (compact:: IncrementalCompact )
907+ maybe_oracle_used_ssas = _oracle_check (compact)
908+ if maybe_oracle_used_ssas != = nothing
909+ @eval Main (compact = $ compact; oracle_used_ssas = $ maybe_oracle_used_ssas)
910+ error (" Oracle check failed, inspect Main.compact and Main.oracle_used_ssas" )
911+ end
912+ end
913+
934914getindex (view:: TypesView , idx:: SSAValue ) = getindex (view, idx. id)
935915function getindex (view:: TypesView , idx:: Int )
936916 if isa (view. ir, IncrementalCompact) && idx < view. ir. result_idx
@@ -1425,7 +1405,6 @@ function iterate(compact::IncrementalCompact, (idx, active_bb)::Tuple{Int, Int}=
14251405 # result_idx is not, incremented, but that's ok and expected
14261406 compact. result[old_result_idx] = compact. ir. stmts[idx]
14271407 result_idx = process_node! (compact, old_result_idx, compact. ir. stmts[idx], idx, idx, active_bb, true )
1428- stmt_if_any = old_result_idx == result_idx ? nothing : compact. result[old_result_idx][:inst ]
14291408 compact. result_idx = result_idx
14301409 if idx == last (bb. stmts) && ! attach_after_stmt_after (compact, idx)
14311410 finish_current_bb! (compact, active_bb, old_result_idx)
@@ -1464,11 +1443,7 @@ function maybe_erase_unused!(
14641443 callback (val)
14651444 end
14661445 if effect_free
1467- if isa (stmt, SSAValue)
1468- kill_ssa_value (stmt)
1469- else
1470- foreachssa (kill_ssa_value, stmt)
1471- end
1446+ foreachssa (kill_ssa_value, stmt)
14721447 inst[:inst ] = nothing
14731448 return true
14741449 end
@@ -1570,6 +1545,9 @@ end
15701545function complete (compact:: IncrementalCompact )
15711546 result_bbs = resize! (compact. result_bbs, compact. active_result_bb- 1 )
15721547 cfg = CFG (result_bbs, Int[first (result_bbs[i]. stmts) for i in 2 : length (result_bbs)])
1548+ if __check_ssa_counts__[]
1549+ oracle_check (compact)
1550+ end
15731551 return IRCode (compact. ir, compact. result, cfg, compact. new_new_nodes)
15741552end
15751553
0 commit comments