Skip to content

Commit 339fd99

Browse files
committed
use #53739
1 parent c8e7e11 commit 339fd99

File tree

1 file changed

+38
-45
lines changed

1 file changed

+38
-45
lines changed

base/compiler/optimize.jl

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -527,53 +527,17 @@ function any_stmt_may_throw(ir::IRCode, bb::Int)
527527
return false
528528
end
529529

530-
mutable struct LazyAugmentedDomtrees
531-
const ir::IRCode
532-
cfg::CFG
533-
domtree::DomTree
534-
postdomtree::PostDomTree
535-
LazyAugmentedDomtrees(ir::IRCode) = new(ir)
536-
end
537-
538-
function get!(lazyagdomtrees::LazyAugmentedDomtrees, sym::Symbol)
539-
isdefined(lazyagdomtrees, sym) && return getfield(lazyagdomtrees, sym)
540-
if sym === :cfg
541-
return lazyagdomtrees.cfg = construct_augmented_cfg(lazyagdomtrees.ir)
542-
elseif sym === :domtree
543-
return lazyagdomtrees.domtree = construct_domtree(get!(lazyagdomtrees, :cfg))
544-
elseif sym === :postdomtree
545-
return lazyagdomtrees.postdomtree = construct_postdomtree(get!(lazyagdomtrees, :cfg))
546-
else
547-
error("invalid field access")
548-
end
549-
end
550-
551-
function construct_augmented_cfg(ir::IRCode)
552-
cfg = copy(ir.cfg)
553-
# Add a virtual basic block to represent the single exit
554-
push!(cfg.blocks, BasicBlock(StmtRange(0:-1)))
555-
for bb = 1:(length(cfg.blocks)-1)
556-
terminator = ir[SSAValue(last(cfg.blocks[bb].stmts))][:stmt]
557-
if terminator isa ReturnNode
558-
cfg_insert_edge!(cfg, bb, length(cfg.blocks))
559-
end
560-
end
561-
return cfg
562-
end
563-
564-
visit_conditional_successors(callback, ir::IRCode, bb::Int) =
565-
visit_conditional_successors(callback, construct_postdomtree(construct_augmented_cfg(ir)), ir, bb)
566-
visit_conditional_successors(callback, lazyagdomtrees::LazyAugmentedDomtrees, ir::IRCode, bb::Int) =
567-
visit_conditional_successors(callback, get!(lazyagdomtrees, :postdomtree), ir, bb)
568-
function visit_conditional_successors(callback, postdomtree::PostDomTree, ir::IRCode, bb::Int)
530+
visit_conditional_successors(callback, ir::IRCode, bb::Int) = # used for test
531+
visit_conditional_successors(callback, LazyPostDomtree(ir), ir, bb)
532+
function visit_conditional_successors(callback, lazypostdomtree::LazyPostDomtree, ir::IRCode, bb::Int)
569533
visited = BitSet((bb,))
570534
worklist = Int[bb]
571535
while !isempty(worklist)
572536
thisbb = popfirst!(worklist)
573537
for succ in ir.cfg.blocks[thisbb].succs
574538
succ in visited && continue
575539
push!(visited, succ)
576-
if postdominates(postdomtree, succ, bb)
540+
if postdominates(get!(lazypostdomtree), succ, bb)
577541
# this successor is not conditional, so no need to visit it further
578542
continue
579543
elseif callback(succ)
@@ -586,12 +550,40 @@ function visit_conditional_successors(callback, postdomtree::PostDomTree, ir::IR
586550
return false
587551
end
588552

553+
struct AugmentedDomtree
554+
cfg::CFG
555+
domtree::DomTree
556+
end
557+
558+
mutable struct LazyAugmentedDomtree
559+
const ir::IRCode
560+
agdomtree::AugmentedDomtree
561+
LazyAugmentedDomtree(ir::IRCode) = new(ir)
562+
end
563+
564+
function get!(lazyagdomtree::LazyAugmentedDomtree)
565+
isdefined(lazyagdomtree, :agdomtree) && return lazyagdomtree.agdomtree
566+
ir = lazyagdomtree.ir
567+
cfg = copy(ir.cfg)
568+
# Add a virtual basic block to represent the exit
569+
push!(cfg.blocks, BasicBlock(StmtRange(0:-1)))
570+
for bb = 1:(length(cfg.blocks)-1)
571+
terminator = ir[SSAValue(last(cfg.blocks[bb].stmts))][:stmt]
572+
if isa(terminator, ReturnNode) && isdefined(terminator, :val)
573+
cfg_insert_edge!(cfg, bb, length(cfg.blocks))
574+
end
575+
end
576+
domtree = construct_domtree(cfg)
577+
return lazyagdomtree.agdomtree = AugmentedDomtree(cfg, domtree)
578+
end
579+
589580
mutable struct PostOptAnalysisState
590581
const result::InferenceResult
591582
const ir::IRCode
592583
const inconsistent::BitSetBoundedMinPrioritySet
593584
const tpdum::TwoPhaseDefUseMap
594-
const lazyagdomtrees::LazyAugmentedDomtrees
585+
const lazypostdomtree::LazyPostDomtree
586+
const lazyagdomtree::LazyAugmentedDomtree
595587
const ea_analysis_pending::Vector{Int}
596588
all_retpaths_consistent::Bool
597589
all_effect_free::Bool
@@ -602,8 +594,9 @@ mutable struct PostOptAnalysisState
602594
function PostOptAnalysisState(result::InferenceResult, ir::IRCode)
603595
inconsistent = BitSetBoundedMinPrioritySet(length(ir.stmts))
604596
tpdum = TwoPhaseDefUseMap(length(ir.stmts))
605-
lazyagdomtrees = LazyAugmentedDomtrees(ir)
606-
return new(result, ir, inconsistent, tpdum, lazyagdomtrees, Int[],
597+
lazypostdomtree = LazyPostDomtree(ir)
598+
lazyagdomtree = LazyAugmentedDomtree(ir)
599+
return new(result, ir, inconsistent, tpdum, lazypostdomtree, lazyagdomtree, Int[],
607600
true, true, nothing, true, true, false)
608601
end
609602
end
@@ -843,13 +836,13 @@ function ((; sv)::ScanStmt)(inst::Instruction, lstmt::Int, bb::Int)
843836
# inconsistent region.
844837
if !sv.result.ipo_effects.terminates
845838
sv.all_retpaths_consistent = false
846-
elseif visit_conditional_successors(sv.lazyagdomtrees, sv.ir, bb) do succ::Int
839+
elseif visit_conditional_successors(sv.lazypostdomtree, sv.ir, bb) do succ::Int
847840
return any_stmt_may_throw(sv.ir, succ)
848841
end
849842
# check if this `GotoIfNot` leads to conditional throws, which taints consistency
850843
sv.all_retpaths_consistent = false
851844
else
852-
cfg, domtree = get!(sv.lazyagdomtrees, :cfg), get!(sv.lazyagdomtrees, :domtree)
845+
(; cfg, domtree) = get!(sv.lazyagdomtree)
853846
for succ in iterated_dominance_frontier(cfg, BlockLiveness(sv.ir.cfg.blocks[bb].succs, nothing), domtree)
854847
if succ == length(cfg.blocks)
855848
# Phi node in the virtual exit -> We have a conditional

0 commit comments

Comments
 (0)