|
| 1 | +# TODO: We should unify this function with _make_argument_lattice_elem to ensure consistency |
| 2 | +function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line) |
| 3 | + list = Any[] |
| 4 | + for (argn, argt) in enumerate(argtypes) |
| 5 | + if isa(argt, Const) |
| 6 | + continue |
| 7 | + elseif Base.issingletontype(argt) |
| 8 | + continue |
| 9 | + elseif Base.isprimitivetype(argt) || isa(argt, Incidence) |
| 10 | + push!(list, ntharg(argn)) |
| 11 | + elseif isa(argt, Type) && argt <: Intrinsics.AbstractScope |
| 12 | + continue |
| 13 | + elseif isabstracttype(argt) || ismutabletype(argt) || (!isa(argt, DataType) && !isa(argt, PartialStruct)) |
| 14 | + continue |
| 15 | + else |
| 16 | + if !isa(argt, PartialStruct) && Base.datatype_fieldcount(argt) === nothing |
| 17 | + continue |
| 18 | + end |
| 19 | + this = ntharg(argn) |
| 20 | + nthfield(i) = insert_node_here!(compact, |
| 21 | + NewInstruction(Expr(:call, getfield, this, i), Compiler.getfield_tfunc(𝕃, argextype(this, compact), Const(i)), line)) |
| 22 | + if isa(argt, PartialStruct) |
| 23 | + fields = _flatten_parameter!(𝕃, compact, argt.fields, nthfield, line) |
| 24 | + else |
| 25 | + fields = _flatten_parameter!(𝕃, compact, fieldtypes(argt), nthfield, line) |
| 26 | + end |
| 27 | + append!(list, fields) |
| 28 | + end |
| 29 | + end |
| 30 | + return list |
| 31 | +end |
| 32 | + |
| 33 | +function flatten_parameter!(𝕃, compact, argtypes, ntharg, line) |
| 34 | + return insert_node_here!(compact, |
| 35 | + NewInstruction(Expr(:call, tuple, _flatten_parameter!(𝕃, compact, argtypes, ntharg, line)...), Tuple, line)) |
| 36 | +end |
| 37 | + |
| 38 | +# Needs to match flatten_arguments! |
| 39 | +function process_template_arg!(𝕃, coeffs, eq_mapping, applied_scopes, argt, template_argt, offset=0) |
| 40 | + if isa(template_argt, Const) |
| 41 | + @assert isa(argt, Const) && argt.val === template_argt.val |
| 42 | + return offset |
| 43 | + elseif Base.issingletontype(template_argt) |
| 44 | + @assert isa(template_argt, Type) && argt.instance === template_argt.instance |
| 45 | + return offset |
| 46 | + elseif Base.isprimitivetype(template_argt) |
| 47 | + coeffs[offset+1] = argt |
| 48 | + return offset + 1 |
| 49 | + elseif isabstracttype(template_argt) || ismutabletype(template_argt) || (!isa(template_argt, DataType) && !isa(template_argt, PartialStruct)) |
| 50 | + return offset |
| 51 | + else |
| 52 | + if !isa(template_argt, PartialStruct) && Base.datatype_fieldcount(template_argt) === nothing |
| 53 | + return offset |
| 54 | + end |
| 55 | + template_fields = isa(template_argt, PartialStruct) ? template_argt.fields : collect(fieldtypes(template_argt)) |
| 56 | + return process_template!(𝕃, coeffs, eq_mapping, applied_scopes, Any[Compiler.getfield_tfunc(𝕃, argt, Const(i)) for i = 1:length(template_fields)], template_fields, offset) |
| 57 | + end |
| 58 | +end |
| 59 | + |
| 60 | +function process_template!(𝕃, coeffs, eq_mapping, applied_scopes, argtypes, template_argtypes, offset=0) |
| 61 | + @assert length(argtypes) == length(template_argtypes) |
| 62 | + for (i, template_arg) in enumerate(template_argtypes) |
| 63 | + offset = process_template_arg!(𝕃, coeffs, eq_mapping, applied_scopes, argtypes[i], template_arg, offset) |
| 64 | + end |
| 65 | + return offset |
| 66 | +end |
| 67 | + |
| 68 | +function flatten_argument!(compact::Compiler.IncrementalCompact, argt, offset, argtypes::Vector{Any})::Pair{Any, Int} |
| 69 | + @assert !isa(argt, Incidence) |
| 70 | + if isa(argt, Const) |
| 71 | + return Pair{Any, Int}(argt.val, offset) |
| 72 | + elseif Base.issingletontype(argt) |
| 73 | + return Pair{Any, Int}(argt.instance, offset) |
| 74 | + elseif Base.isprimitivetype(argt) |
| 75 | + push!(argtypes, argt) |
| 76 | + return Pair{Any, Int}(Argument(offset+1), offset+1) |
| 77 | + elseif isabstracttype(argt) || ismutabletype(argt) || (!isa(argt, DataType) && !isa(argt, PartialStruct)) |
| 78 | + ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line])) |
| 79 | + return Pair{Any, Int}(ssa, offset) |
| 80 | + else |
| 81 | + if !isa(argt, PartialStruct) && Base.datatype_fieldcount(argt) === nothing |
| 82 | + ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line])) |
| 83 | + return Pair{Any, Int}(ssa, offset) |
| 84 | + end |
| 85 | + (args, _, offset) = flatten_arguments!(compact, isa(argt, PartialStruct) ? argt.fields : fieldtypes(argt), offset, argtypes) |
| 86 | + this = Expr(:new, isa(argt, PartialStruct) ? argt.typ : argt, args...) |
| 87 | + ssa = insert_node_here!(compact, NewInstruction(this, argt, compact[Compiler.OldSSAValue(1)][:line])) |
| 88 | + return Pair{Any, Int}(ssa, offset) |
| 89 | + end |
| 90 | +end |
| 91 | + |
| 92 | +function flatten_arguments!(compact::Compiler.IncrementalCompact, argtypes, offset=0, new_argtypes::Vector{Any} = Any[]) |
| 93 | + args = Any[] |
| 94 | + for argt in argtypes |
| 95 | + (ssa, offset) = flatten_argument!(compact, argt, offset, new_argtypes) |
| 96 | + push!(args, ssa) |
| 97 | + end |
| 98 | + return (args, new_argtypes, offset) |
| 99 | +end |
0 commit comments