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