@@ -2887,17 +2887,49 @@ function init_vartable!(vartable::VarTable, frame::InferenceState)
2887
2887
return vartable
2888
2888
end
2889
2889
2890
+ function update_bestguess! (interp:: AbstractInterpreter , frame:: InferenceState ,
2891
+ currstate:: VarTable , @nospecialize (rt))
2892
+ bestguess = frame. bestguess
2893
+ nargs = narguments (frame, #= include_va=# false )
2894
+ slottypes = frame. slottypes
2895
+ rt = widenreturn (rt, BestguessInfo (interp, bestguess, nargs, slottypes, currstate))
2896
+ # narrow representation of bestguess slightly to prepare for tmerge with rt
2897
+ if rt isa InterConditional && bestguess isa Const
2898
+ slot_id = rt. slot
2899
+ old_id_type = slottypes[slot_id]
2900
+ if bestguess. val === true && rt. elsetype != = Bottom
2901
+ bestguess = InterConditional (slot_id, old_id_type, Bottom)
2902
+ elseif bestguess. val === false && rt. thentype != = Bottom
2903
+ bestguess = InterConditional (slot_id, Bottom, old_id_type)
2904
+ end
2905
+ end
2906
+ # copy limitations to return value
2907
+ if ! isempty (frame. pclimitations)
2908
+ union! (frame. limitations, frame. pclimitations)
2909
+ empty! (frame. pclimitations)
2910
+ end
2911
+ if ! isempty (frame. limitations)
2912
+ rt = LimitedAccuracy (rt, copy (frame. limitations))
2913
+ end
2914
+ 𝕃ₚ = ipo_lattice (interp)
2915
+ if ! ⊑ (𝕃ₚ, rt, bestguess)
2916
+ # TODO : if bestguess isa InterConditional && !interesting(bestguess); bestguess = widenconditional(bestguess); end
2917
+ frame. bestguess = tmerge (𝕃ₚ, bestguess, rt) # new (wider) return type for frame
2918
+ return true
2919
+ else
2920
+ return false
2921
+ end
2922
+ end
2923
+
2890
2924
# make as much progress on `frame` as possible (without handling cycles)
2891
2925
function typeinf_local (interp:: AbstractInterpreter , frame:: InferenceState )
2892
2926
@assert ! is_inferred (frame)
2893
2927
frame. dont_work_on_me = true # mark that this function is currently on the stack
2894
2928
W = frame. ip
2895
- nargs = narguments (frame, #= include_va=# false )
2896
- slottypes = frame. slottypes
2897
2929
ssavaluetypes = frame. ssavaluetypes
2898
2930
bbs = frame. cfg. blocks
2899
2931
nbbs = length (bbs)
2900
- 𝕃ₚ, 𝕃ᵢ = ipo_lattice (interp), typeinf_lattice (interp)
2932
+ 𝕃ᵢ = typeinf_lattice (interp)
2901
2933
2902
2934
currbb = frame. currbb
2903
2935
if currbb != 1
@@ -2998,35 +3030,10 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
2998
3030
end
2999
3031
end
3000
3032
elseif isa (stmt, ReturnNode)
3001
- bestguess = frame. bestguess
3002
3033
rt = abstract_eval_value (interp, stmt. val, currstate, frame)
3003
- rt = widenreturn (rt, BestguessInfo (interp, bestguess, nargs, slottypes, currstate))
3004
- # narrow representation of bestguess slightly to prepare for tmerge with rt
3005
- if rt isa InterConditional && bestguess isa Const
3006
- let slot_id = rt. slot
3007
- old_id_type = slottypes[slot_id]
3008
- if bestguess. val === true && rt. elsetype != = Bottom
3009
- bestguess = InterConditional (slot_id, old_id_type, Bottom)
3010
- elseif bestguess. val === false && rt. thentype != = Bottom
3011
- bestguess = InterConditional (slot_id, Bottom, old_id_type)
3012
- end
3013
- end
3014
- end
3015
- # copy limitations to return value
3016
- if ! isempty (frame. pclimitations)
3017
- union! (frame. limitations, frame. pclimitations)
3018
- empty! (frame. pclimitations)
3019
- end
3020
- if ! isempty (frame. limitations)
3021
- rt = LimitedAccuracy (rt, copy (frame. limitations))
3022
- end
3023
- if ! ⊑ (𝕃ₚ, rt, bestguess)
3024
- # new (wider) return type for frame
3025
- bestguess = tmerge (𝕃ₚ, bestguess, rt)
3026
- # TODO : if bestguess isa InterConditional && !interesting(bestguess); bestguess = widenconditional(bestguess); end
3027
- frame. bestguess = bestguess
3034
+ if update_bestguess! (interp, frame, currstate, rt)
3028
3035
for (caller, caller_pc) in frame. cycle_backedges
3029
- if ! ( caller. ssavaluetypes[caller_pc] === Any)
3036
+ if caller. ssavaluetypes[caller_pc] != = Any
3030
3037
# no reason to revisit if that call-site doesn't affect the final result
3031
3038
push! (caller. ip, block_for_inst (caller. cfg, caller_pc))
3032
3039
end
0 commit comments