44# structs/constants #
55# ####################
66
7- # N.B.: Const/PartialStruct are defined in Core, to allow them to be used
7+ # N.B.: Const/PartialStruct/InterConditional are defined in Core, to allow them to be used
88# inside the global code cache.
99#
1010# # The type of a value might be constant
1818# end
1919import Core: Const, PartialStruct
2020
21-
2221# The type of this value might be Bool.
2322# However, to enable a limited amount of back-propagagation,
2423# we also keep some information about how this Bool value was created.
@@ -45,6 +44,18 @@ struct Conditional
4544 end
4645end
4746
47+ # # Similar to `Conditional`, but conveys inter-procedural constraints imposed on call arguments.
48+ # # This is separate from `Conditional` to catch logic errors: the lattice element name is InterConditional
49+ # # while processing a call, then Conditional everywhere else. Thus InterConditional does not appear in
50+ # # CompilerTypes—these type's usages are disjoint—though we define the lattice for InterConditional.
51+ # struct InterConditional
52+ # slot::Int
53+ # vtype
54+ # elsetype
55+ # end
56+ import Core: InterConditional
57+ const AnyConditional = Union{Conditional,InterConditional}
58+
4859struct PartialTypeVar
4960 tv:: TypeVar
5061 # N.B.: Currently unused, but would allow turning something back
@@ -101,11 +112,10 @@ const CompilerTypes = Union{MaybeUndef, Const, Conditional, NotFound, PartialStr
101112# lattice logic #
102113# ################
103114
104- function issubconditional (a:: Conditional , b:: Conditional )
105- avar = a. var
106- bvar = b. var
107- if (isa (avar, Slot) && isa (bvar, Slot) && slot_id (avar) === slot_id (bvar)) ||
108- (isa (avar, SSAValue) && isa (bvar, SSAValue) && avar === bvar)
115+ # `Conditional` and `InterConditional` are valid in opposite contexts
116+ # (i.e. local inference and inter-procedural call), as such they will never be compared
117+ function issubconditional (a:: C , b:: C ) where {C<: AnyConditional }
118+ if is_same_conditionals (a, b)
109119 if a. vtype ⊑ b. vtype
110120 if a. elsetype ⊑ b. elsetype
111121 return true
@@ -115,8 +125,13 @@ function issubconditional(a::Conditional, b::Conditional)
115125 return false
116126end
117127
118- maybe_extract_const_bool (c:: Const ) = isa (c. val, Bool) ? c. val : nothing
119- function maybe_extract_const_bool (c:: Conditional )
128+ is_same_conditionals (a:: Conditional , b:: Conditional ) = slot_id (a. var) === slot_id (b. var)
129+ is_same_conditionals (a:: InterConditional , b:: InterConditional ) = a. slot === b. slot
130+
131+ is_lattice_bool (@nospecialize (typ)) = typ != = Bottom && typ ⊑ Bool
132+
133+ maybe_extract_const_bool (c:: Const ) = (val = c. val; isa (val, Bool)) ? val : nothing
134+ function maybe_extract_const_bool (c:: AnyConditional )
120135 (c. vtype === Bottom && ! (c. elsetype === Bottom)) && return false
121136 (c. elsetype === Bottom && ! (c. vtype === Bottom)) && return true
122137 nothing
@@ -145,14 +160,14 @@ function ⊑(@nospecialize(a), @nospecialize(b))
145160 b === Union{} && return false
146161 @assert ! isa (a, TypeVar) " invalid lattice item"
147162 @assert ! isa (b, TypeVar) " invalid lattice item"
148- if isa (a, Conditional )
149- if isa (b, Conditional )
163+ if isa (a, AnyConditional )
164+ if isa (b, AnyConditional )
150165 return issubconditional (a, b)
151166 elseif isa (b, Const) && isa (b. val, Bool)
152167 return maybe_extract_const_bool (a) === b. val
153168 end
154169 a = Bool
155- elseif isa (b, Conditional )
170+ elseif isa (b, AnyConditional )
156171 return false
157172 end
158173 if isa (a, PartialStruct)
@@ -226,7 +241,7 @@ function is_lattice_equal(@nospecialize(a), @nospecialize(b))
226241 return a ⊑ b && b ⊑ a
227242end
228243
229- widenconst (c:: Conditional ) = Bool
244+ widenconst (c:: AnyConditional ) = Bool
230245function widenconst (c:: Const )
231246 if isa (c. val, Type)
232247 if isvarargtype (c. val)
260275@inline schanged (@nospecialize (n), @nospecialize (o)) = (n != = o) && (o === NOT_FOUND || (n != = NOT_FOUND && ! issubstate (n, o)))
261276
262277widenconditional (@nospecialize typ) = typ
263- function widenconditional (typ:: Conditional )
278+ function widenconditional (typ:: AnyConditional )
264279 if typ. vtype === Union{}
265280 return Const (false )
266281 elseif typ. elsetype === Union{}
0 commit comments