From 101a8c559566c9a08a458c8859e0bcd50328fd5d Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 3 Jul 2023 20:17:58 +0000 Subject: [PATCH 1/2] Extend ifelse lifting to regular SROA --- base/compiler/ssair/passes.jl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 9a312bec8f202..42e1f747974a3 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -563,6 +563,12 @@ function lift_comparison!(::typeof(isdefined), compact::IncrementalCompact, lift_comparison_leaves!(isdefined_tfunc, compact, val, cmp, lifting_cache, idx, 𝕃ₒ) end +function phi_or_ifelse_predecessors(@nospecialize(def), compact::IncrementalCompact) + isa(def, PhiNode) && return def.values + is_known_call(def, Core.ifelse, compact) && return def.args[3:4] + return nothing +end + function lift_comparison_leaves!(@specialize(tfunc), compact::IncrementalCompact, @nospecialize(val), @nospecialize(cmp), lifting_cache::IdDict{Pair{AnySSAValue, Any}, AnySSAValue}, idx::Int, @@ -573,12 +579,8 @@ function lift_comparison_leaves!(@specialize(tfunc), end isa(typeconstraint, Union) || return # bail out if there won't be a good chance for lifting - predecessors = function (@nospecialize(def), compact::IncrementalCompact) - isa(def, PhiNode) && return def.values - is_known_call(def, Core.ifelse, compact) && return def.args[3:4] - return nothing - end - leaves, visited_philikes = collect_leaves(compact, val, typeconstraint, 𝕃ₒ, predecessors) + + leaves, visited_philikes = collect_leaves(compact, val, typeconstraint, 𝕃ₒ, phi_or_ifelse_predecessors) length(leaves) ≤ 1 && return # bail out if we don't have multiple leaves # check if we can evaluate the comparison for each one of the leaves @@ -1093,11 +1095,10 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing) end # perform SROA on immutable structs here on - field = try_compute_fieldidx_stmt(compact, stmt, struct_typ) field === nothing && continue - leaves, visited_philikes = collect_leaves(compact, val, struct_typ, 𝕃ₒ) + leaves, visited_philikes = collect_leaves(compact, val, struct_typ, 𝕃ₒ, phi_or_ifelse_predecessors) isempty(leaves) && continue lifted_result = lift_leaves(compact, field, leaves, 𝕃ₒ) From 87fe6e1a346e1e8aad0cd0c7365f6669960f7ebf Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Mon, 3 Jul 2023 21:16:17 +0000 Subject: [PATCH 2/2] Fix oracle violation This is a pre-existing bug, but was exposed by my improvements to SROA. --- base/compiler/ssair/ir.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/compiler/ssair/ir.jl b/base/compiler/ssair/ir.jl index 5c6751c1e1dda..a1a6bf3b15546 100644 --- a/base/compiler/ssair/ir.jl +++ b/base/compiler/ssair/ir.jl @@ -879,6 +879,9 @@ function insert_node!(compact::IncrementalCompact, @nospecialize(before), newins return os end elseif isa(before, NewSSAValue) + # As above, new_new_nodes must get counted. We don't visit them during our compact, + # so they're immediately considered reified. + count_added_node!(compact, newinst.stmt) # TODO: This is incorrect and does not maintain ordering among the new nodes before_entry = compact.new_new_nodes.info[-before.id] newline = something(newinst.line, compact.new_new_nodes.stmts[-before.id][:line])