Skip to content

Commit f1b90b2

Browse files
committed
add method_for_inference_heuristics field to CodeInfo
1 parent 0335175 commit f1b90b2

File tree

5 files changed

+25
-11
lines changed

5 files changed

+25
-11
lines changed

base/inference.jl

+16-8
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,11 @@ function abstract_call_gf_by_type(@nospecialize(f), @nospecialize(atype), sv::In
19091909
return rettype
19101910
end
19111911

1912+
function method_for_inference_heuristics(infstate::InferenceState)
1913+
m = infstate.src.method_for_inference_heuristics
1914+
return m === nothing ? infstate.linfo.def : m
1915+
end
1916+
19121917
function abstract_call_method(method::Method, @nospecialize(f), @nospecialize(sig), sparams::SimpleVector, sv::InferenceState)
19131918
topmost = nothing
19141919
# Limit argument type tuple growth of functions:
@@ -1919,13 +1924,14 @@ function abstract_call_method(method::Method, @nospecialize(f), @nospecialize(si
19191924
infstate = sv
19201925
while !(infstate === nothing)
19211926
infstate = infstate::InferenceState
1922-
if method === infstate.linfo.def
1923-
if infstate.linfo.specTypes == sig
1924-
# avoid widening when detecting self-recursion
1925-
# TODO: merge call cycle and return right away
1926-
topmost = nothing
1927-
break
1928-
end
1927+
if method === infstate.linfo.def && infstate.linfo.specTypes == sig
1928+
# avoid widening when detecting self-recursion
1929+
# TODO: merge call cycle and return right away
1930+
topmost = nothing
1931+
break
1932+
end
1933+
working_method = method_for_inference_heuristics(infstate)
1934+
if method === working_method
19291935
if topmost === nothing
19301936
# inspect the parent of this edge,
19311937
# to see if they are the same Method as sv
@@ -1943,7 +1949,8 @@ function abstract_call_method(method::Method, @nospecialize(f), @nospecialize(si
19431949
# then check the parent link
19441950
if topmost === nothing && parent !== nothing
19451951
parent = parent::InferenceState
1946-
if parent.cached && parent.linfo.def === sv.linfo.def
1952+
parent_method = method_for_inference_heuristics(parent)
1953+
if parent.cached && parent_method === working_method
19471954
topmost = infstate
19481955
end
19491956
end
@@ -3220,6 +3227,7 @@ function typeinf_code(linfo::MethodInstance, optimize::Bool, cached::Bool,
32203227
tree.slotflags = UInt8[ 0 for i = 1:method.nargs ]
32213228
tree.slottypes = nothing
32223229
tree.ssavaluetypes = 0
3230+
tree.method_for_inference_heuristics = nothing
32233231
tree.inferred = true
32243232
tree.pure = true
32253233
tree.inlineable = true

src/jltypes.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -2044,8 +2044,9 @@ void jl_init_types(void)
20442044
jl_code_info_type =
20452045
jl_new_datatype(jl_symbol("CodeInfo"), core,
20462046
jl_any_type, jl_emptysvec,
2047-
jl_perm_symsvec(9,
2047+
jl_perm_symsvec(10,
20482048
"code",
2049+
"method_for_inference_heuristics",
20492050
"slottypes",
20502051
"ssavaluetypes",
20512052
"slotflags",
@@ -2054,17 +2055,18 @@ void jl_init_types(void)
20542055
"inlineable",
20552056
"propagate_inbounds",
20562057
"pure"),
2057-
jl_svec(9,
2058+
jl_svec(10,
20582059
jl_array_any_type,
20592060
jl_any_type,
20602061
jl_any_type,
2062+
jl_any_type,
20612063
jl_array_uint8_type,
20622064
jl_array_any_type,
20632065
jl_bool_type,
20642066
jl_bool_type,
20652067
jl_bool_type,
20662068
jl_bool_type),
2067-
0, 1, 9);
2069+
0, 1, 10);
20682070

20692071
jl_method_type =
20702072
jl_new_datatype(jl_symbol("Method"), core,

src/julia.h

+1
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ typedef struct _jl_llvm_functions_t {
229229
// This type describes a single function body
230230
typedef struct _jl_code_info_t {
231231
jl_array_t *code; // Any array of statements
232+
jl_value_t *method_for_inference_heuristics; // optional method used during inference
232233
jl_value_t *slottypes; // types of variable slots (or `nothing`)
233234
jl_value_t *ssavaluetypes; // types of ssa values (or count of them)
234235
jl_array_t *slotflags; // local var bit flags

src/method.c

+2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ static void jl_code_info_set_ast(jl_code_info_t *li, jl_expr_t *ast)
157157
jl_array_del_end(meta, na - ins);
158158
}
159159
}
160+
li->method_for_inference_heuristics = jl_nothing;
160161
jl_array_t *vinfo = (jl_array_t*)jl_exprarg(ast, 1);
161162
jl_array_t *vis = (jl_array_t*)jl_array_ptr_ref(vinfo, 0);
162163
size_t nslots = jl_array_len(vis);
@@ -225,6 +226,7 @@ JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void)
225226
(jl_code_info_t*)jl_gc_alloc(ptls, sizeof(jl_code_info_t),
226227
jl_code_info_type);
227228
src->code = NULL;
229+
src->method_for_inference_heuristics = NULL;
228230
src->slotnames = NULL;
229231
src->slotflags = NULL;
230232
src->slottypes = NULL;

src/toplevel.c

+1
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ static jl_code_info_t *expr_to_code_info(jl_value_t *expr)
548548
jl_gc_wb(src, src->slotflags);
549549
src->ssavaluetypes = jl_box_long(0);
550550
jl_gc_wb(src, src->ssavaluetypes);
551+
src->method_for_inference_heuristics = jl_nothing;
551552

552553
JL_GC_POP();
553554
return src;

0 commit comments

Comments
 (0)