Skip to content

Commit c53dc98

Browse files
author
Ian Atol
committed
SSA use count checking framework
1 parent afd24e6 commit c53dc98

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

base/compiler/ssair/ir.jl

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,27 @@ function setindex!(compact::IncrementalCompact, @nospecialize(v), idx::Int)
890890
return compact
891891
end
892892

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+
893914
getindex(view::TypesView, idx::SSAValue) = getindex(view, idx.id)
894915
function getindex(view::TypesView, idx::Int)
895916
if isa(view.ir, IncrementalCompact) && idx < view.ir.result_idx
@@ -979,11 +1000,15 @@ function renumber_ssa2!(@nospecialize(stmt), ssanums::Vector{Any}, used_ssas::Ve
9791000
urs = userefs(stmt)
9801001
for op in urs
9811002
val = op[]
982-
isa(val, OldSSAValue) || isa(val, NewSSAValue) && push!(late_fixup, result_idx)
1003+
if isa(val, OldSSAValue) || isa(val, NewSSAValue)
1004+
push!(late_fixup, result_idx)
1005+
end
9831006
if isa(val, Union{SSAValue, NewSSAValue})
9841007
val = renumber_ssa2(val, ssanums, used_ssas, new_new_used_ssas, do_rename_ssa)
9851008
end
986-
isa(val, OldSSAValue) || isa(val, NewSSAValue) && push!(late_fixup, result_idx)
1009+
if isa(val, OldSSAValue) || isa(val, NewSSAValue)
1010+
push!(late_fixup, result_idx)
1011+
end
9871012
op[] = val
9881013
end
9891014
return urs[]
@@ -1520,6 +1545,9 @@ end
15201545
function complete(compact::IncrementalCompact)
15211546
result_bbs = resize!(compact.result_bbs, compact.active_result_bb-1)
15221547
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
15231551
return IRCode(compact.ir, compact.result, cfg, compact.new_new_nodes)
15241552
end
15251553

base/compiler/utilities.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,38 @@ end
354354
@inline slot_id(s) = isa(s, SlotNumber) ? (s::SlotNumber).id :
355355
isa(s, Argument) ? (s::Argument).n : (s::TypedSlot).id
356356

357+
######################
358+
# IncrementalCompact #
359+
######################
360+
361+
# specifically meant to be used with body1 = compact.result and body2 = compact.new_new_nodes, with nvals == length(compact.used_ssas)
362+
function find_ssavalue_uses1(compact)
363+
body1, body2 = compact.result.inst, compact.new_new_nodes.stmts.inst
364+
nvals = length(compact.used_ssas)
365+
nbody1 = length(body1)
366+
nbody2 = length(body2)
367+
368+
uses = zeros(Int, nvals)
369+
function increment_uses(ssa::SSAValue)
370+
uses[ssa.id] += 1
371+
end
372+
373+
for line in 1:(nbody1 + nbody2)
374+
# index into the right body
375+
if line <= nbody1
376+
isassigned(body1, line) || continue
377+
e = body1[line]
378+
else
379+
line -= nbody1
380+
isassigned(body2, line) || continue
381+
e = body2[nline]
382+
end
383+
384+
foreachssa(increment_uses, e)
385+
end
386+
return uses
387+
end
388+
357389
###########
358390
# options #
359391
###########

test/compiler/ssair.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,17 @@ f_if_typecheck() = (if nothing; end; unsafe_load(Ptr{Int}(0)))
328328
end
329329
code_typed(foo; optimize=true)
330330

331-
code_typed(Core.Compiler.setindex!, (Core.Compiler.UseRef, Core.Compiler.NewSSAValue); optimize=true)
331+
code_typed(Core.Compiler.setindex!, (Core.Compiler.UseRef,Core.Compiler.NewSSAValue); optimize=true)
332332
end |> string
333333
cmd = `$(Base.julia_cmd()) -g 2 -e $code`
334334
stderr = IOBuffer()
335335
success(pipeline(Cmd(cmd); stdout=stdout, stderr=stderr)) && isempty(String(take!(stderr)))
336336
end
337337

338338
let
339-
function test_useref(stmt, v)
339+
function test_useref(stmt, v, op)
340340
if isa(stmt, Expr)
341-
@test any(arg -> arg === v, stmt.args)
341+
@test stmt.args[op] === v
342342
elseif isa(stmt, GotoIfNot)
343343
@test stmt.cond === v
344344
elseif isa(stmt, ReturnNode) || isa(stmt, UpsilonNode)
@@ -350,7 +350,7 @@ let
350350
elseif isa(stmt, PiNode)
351351
@test stmt.val === v && stmt.typ === typeof(stmt)
352352
elseif isa(stmt, PhiNode) || isa(stmt, PhiCNode)
353-
@test any(arg -> arg === v, stmt.values)
353+
@test stmt.values[op] === v
354354
end
355355
end
356356

@@ -364,7 +364,7 @@ let
364364
v1 = Core.Compiler.getindex(ur)
365365
# set to dummy expression and then back to itself to test `_useref_setindex!`
366366
v2 = Core.Compiler.setindex!(ur, ex)
367-
test_useref(v2, ex)
367+
test_useref(v2, ex, op)
368368
Core.Compiler.setindex!(ur, v1)
369369
@test Core.Compiler.getindex(ur) === v1
370370
it = Core.Compiler.iterate(urs, op)

0 commit comments

Comments
 (0)