Skip to content

Commit 55cee67

Browse files
committed
inference: improve tmerge for Conditional and Const
1 parent ee50eee commit 55cee67

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

base/compiler/typeinfer.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,14 @@ function typeinf_work(frame::InferenceState)
319319
else
320320
# general case
321321
frame.handler_at[l] = frame.cur_hand
322+
changes_else = changes
322323
if isa(condt, Conditional)
323-
changes_else = StateUpdate(condt.var, VarState(condt.elsetype, false), changes)
324-
changes = StateUpdate(condt.var, VarState(condt.vtype, false), changes)
325-
else
326-
changes_else = changes
324+
if condt.elsetype !== Any && condt.elsetype !== changes[slot_id(condt.var)]
325+
changes_else = StateUpdate(condt.var, VarState(condt.elsetype, false), changes_else)
326+
end
327+
if condt.vtype !== Any && condt.vtype !== changes[slot_id(condt.var)]
328+
changes = StateUpdate(condt.var, VarState(condt.vtype, false), changes)
329+
end
327330
end
328331
newstate_else = stupdate!(s[l], changes_else)
329332
if newstate_else !== false

base/compiler/typelimits.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,34 @@ function type_more_complex(@nospecialize(t), @nospecialize(c), sources::SimpleVe
302302
return true
303303
end
304304

305+
# pick a wider type that contains both typea and typeb,
306+
# with some limits on how "large" it can get,
307+
# but without losing too much precision in common cases
308+
# and also trying to be associative and commutative
305309
function tmerge(@nospecialize(typea), @nospecialize(typeb))
306310
typea typeb && return typeb
307311
typeb typea && return typea
312+
# type-lattice for MaybeUndef wrapper
308313
if isa(typea, MaybeUndef) || isa(typeb, MaybeUndef)
309314
return MaybeUndef(tmerge(
310315
isa(typea, MaybeUndef) ? typea.typ : typea,
311316
isa(typeb, MaybeUndef) ? typeb.typ : typeb))
312317
end
318+
# type-lattice for Conditional wrapper
319+
if isa(typea, Conditional) && isa(typeb, Const)
320+
if typeb.val === true
321+
typeb = Conditional(typea.var, Any, Union{})
322+
elseif typeb.val === false
323+
typeb = Conditional(typea.var, Union{}, Any)
324+
end
325+
end
326+
if isa(typeb, Conditional) && isa(typea, Const)
327+
if typea.val === true
328+
typea = Conditional(typeb.var, Any, Union{})
329+
elseif typea.val === false
330+
typea = Conditional(typeb.var, Union{}, Any)
331+
end
332+
end
313333
if isa(typea, Conditional) && isa(typeb, Conditional)
314334
if typea.var === typeb.var
315335
vtype = tmerge(typea.vtype, typeb.vtype)
@@ -320,6 +340,7 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
320340
end
321341
return Bool
322342
end
343+
# no special type-inference lattice, join the types
323344
typea, typeb = widenconst(typea), widenconst(typeb)
324345
typea === typeb && return typea
325346
if !(isa(typea, Type) || isa(typea, TypeVar)) ||

0 commit comments

Comments
 (0)