Repository: JuliaLang/julia
File: Compiler/src/typeutils.jl (Julia)

Code before:
    n = length(groups)
    for i = 1:n
        argᵢ = fargs[i]
        if argᵢ isa SlotNumber || argᵢ isa SSAValue
            for j in 1:i-1
                if fargs[j] === argᵢ
                    groups[i] = groups[j]
                    break
                end
            end
        end
    end
    return groups
end

# Detect additional aliasing from `MustAlias` lattice elements in `argtypes`:
# two positions with the same `(slot, ssadef, fldidx)` must refer to the same value.
function merge_mustalias_groups!(groups::Vector{Int}, argtypes::Vector{Any})
    n = length(groups)
    for i = 1:n
        groups[i] == i || continue # already a follower
        tᵢ = argtypes[i]
        tᵢ isa MustAlias || continue
        for j in 1:i-1
            groups[j] == j || continue # only match against leaders
            tⱼ = argtypes[j]
            tⱼ isa MustAlias || continue
            if tᵢ.slot == tⱼ.slot && tᵢ.ssadef == tⱼ.ssadef && tᵢ.fldidx == tⱼ.fldidx
                # Merge: make j the leader for i, and re-point any
                # existing followers of i to j as well
                for k in i:n
                    if groups[k] == i
                        groups[k] = j
                    end
                end
                break
            end
        end
    end
    return groups
end

# Gives a cost function over the effort to switch a tuple-union representation
# as a cartesian product, relative to the size of the original representation.
# Thus, we count the longest element as being roughly invariant to being inside
# or outside of the Tuple/Union nesting, though somewhat more expensive to be
# outside than inside because the representation is larger (because and it
# informs the callee whether any splitting is possible).
function unionsplitcost(𝕃::AbstractLattice, argtypes::Union{SimpleVector,Vector{Any}};
                        fargs::Union{Nothing,Vector{Any}}=nothing)
    na = length(argtypes)

Review comment (suggestion):
When you guys get older and have as bad eyes as I do now, you'll seriously regret using identifiers like tᵢ and tⱼ for being virtually indistinguishable unless you zoom in a lot. (I also don't get what these offer over `ti` or `t_i` -- but you do you, I am just a grumpy old man on the sidelines ;-) )

Code after:
    for i = 1:length(groups)
        arg_i = fargs[i]
        if arg_i isa SlotNumber || arg_i isa SSAValue
            for j in 1:i-1
                if fargs[j] === arg_i
                    groups[i] = groups[j]
                    break
                end
            end
        end
    end
    return groups
end

# Detect additional aliasing from `MustAlias` lattice elements in `argtypes`:
# two positions with the same `(slot, ssadef, fldidx)` must refer to the same value.
function merge_mustalias_groups!(groups::Vector{Int}, argtypes::Vector{Any})
    for i = 1:length(groups)
        groups[i] == i || continue # already a follower
        ti = argtypes[i]
        ti isa MustAlias || continue
        for j in 1:i-1
            groups[j] == j || continue # only match against leaders
            tj = argtypes[j]
            tj isa MustAlias || continue
            if ti.slot == tj.slot && ti.ssadef == tj.ssadef && ti.fldidx == tj.fldidx
                # Merge: make j the leader for i, and re-point any
                # existing followers of i to j as well
                for k in i:length(groups)
                    if groups[k] == i
                        groups[k] = j
                    end
                end
                break
            end
        end
    end
    return groups
end

# Gives a cost function over the effort to switch a tuple-union representation
# as a cartesian product, relative to the size of the original representation.
# Thus, we count the longest element as being roughly invariant to being inside
# or outside of the Tuple/Union nesting, though somewhat more expensive to be
# outside than inside because the representation is larger (because and it
# informs the callee whether any splitting is possible).
function unionsplitcost(𝕃::AbstractLattice, argtypes::Union{SimpleVector,Vector{Any}};
                        fargs::Union{Nothing,Vector{Any}}=nothing)
    na = length(argtypes)
    groups = compute_alias_groups(na, fargs, argtypes isa Vector{Any} ? argtypes : nothing)
    nu = 1