Skip to content

Commit 5c0b64b

Browse files
committed
fix compile-all / anticodegen / no-inference modes and remove any type-inferred code that isn't being used
also refactor a bit of compile=all and cache-method code to make it clearer how jl_is_cacheable_sig parallels it
1 parent 9ae4520 commit 5c0b64b

12 files changed

+318
-175
lines changed

base/docs/Docs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ include("bindings.jl")
5959
import Base.Markdown: @doc_str, MD
6060
import Base.Meta: quot, isexpr
6161
import Base: Callable
62-
import Core.Inference.CoreDocs: lazy_iterpolate
62+
import ..CoreDocs: lazy_iterpolate
6363

6464
export doc
6565

base/docs/core.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module CoreDocs
44

5-
import Core.Inference: esc, push!, getindex, current_module, unsafe_load, Csize_t
5+
import ..esc, ..push!, ..getindex, ..current_module, ..unsafe_load, ..Csize_t
66

77
function doc!(str, ex)
88
ptr = unsafe_load(Core.Intrinsics.cglobal(:jl_filename, Ptr{UInt8}))

base/inference.jl

+35-18
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ type InferenceState
7171
typegotoredo::Bool
7272
inworkq::Bool
7373
optimize::Bool
74+
needtree::Bool
7475
inferred::Bool
7576

76-
function InferenceState(linfo::LambdaInfo, optimize::Bool)
77+
function InferenceState(linfo::LambdaInfo, optimize::Bool, needtree::Bool)
7778
@assert isa(linfo.code,Array{Any,1})
7879
nslots = length(linfo.slotnames)
7980
nl = label_counter(linfo.code)+1
@@ -158,7 +159,7 @@ type InferenceState
158159
ssavalue_uses, ssavalue_init,
159160
ObjectIdDict(), #Dict{InferenceState, Vector{LineNum}}(),
160161
Vector{Tuple{InferenceState, Vector{LineNum}}}(),
161-
false, false, false, optimize, false)
162+
false, false, false, optimize, needtree, false)
162163
push!(active, frame)
163164
nactive[] += 1
164165
return frame
@@ -1473,6 +1474,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14731474
# don't call staged functions on abstract types.
14741475
# (see issues #8504, #10230)
14751476
# we can't guarantee that their type behavior is monotonic.
1477+
# XXX: this test is wrong if Types (such as DataType) are present
14761478
return (nothing, Any, false)
14771479
end
14781480
try
@@ -1485,6 +1487,8 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14851487
linfo = specialize_method(method, atypes, sparams, cached)
14861488
end
14871489

1490+
# XXX: the following logic is likely subtly broken if code.code was nothing,
1491+
# although it seems unlikely something bad (infinite recursion) will happen as a result
14881492
if linfo.inInference
14891493
# inference on this signature may be in progress,
14901494
# find the corresponding frame in the active list
@@ -1498,10 +1502,13 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14981502
end
14991503
# TODO: this assertion seems iffy
15001504
assert(frame !== nothing)
1505+
if needtree
1506+
frame.needtree = true
1507+
end
15011508
else
15021509
# inference not started yet, make a new frame for a new lambda
15031510
linfo.inInference = true
1504-
frame = InferenceState(unshare_linfo!(linfo::LambdaInfo), optimize)
1511+
frame = InferenceState(unshare_linfo!(linfo::LambdaInfo), optimize, needtree)
15051512
end
15061513
frame = frame::InferenceState
15071514

@@ -1541,8 +1548,8 @@ end
15411548
function typeinf_ext(linfo::LambdaInfo)
15421549
if isdefined(linfo, :def)
15431550
# method lambda - infer this specialization via the method cache
1544-
(code, _t, _) = typeinf_edge(linfo.def, linfo.specTypes, linfo.sparam_vals, true, true, true, linfo)
1545-
if code.inferred && linfo !== code
1551+
(code, _t, inferred) = typeinf_edge(linfo.def, linfo.specTypes, linfo.sparam_vals, true, true, true, linfo)
1552+
if inferred && code.inferred && linfo !== code
15461553
# This case occurs when the IR for a function has been deleted.
15471554
# `code` will be a newly-created LambdaInfo, and we need to copy its
15481555
# contents to the existing one to copy the info to the method cache.
@@ -1562,7 +1569,7 @@ function typeinf_ext(linfo::LambdaInfo)
15621569
else
15631570
# toplevel lambda - infer directly
15641571
linfo.inInference = true
1565-
frame = InferenceState(linfo, true)
1572+
frame = InferenceState(linfo, true, true)
15661573
typeinf_loop(frame)
15671574
@assert frame.inferred # TODO: deal with this better
15681575
return linfo
@@ -1875,7 +1882,8 @@ function isinlineable(linfo::LambdaInfo)
18751882
end
18761883
end
18771884
if !inlineable
1878-
body = Expr(:block); body.args = linfo.code
1885+
body = Expr(:block)
1886+
body.args = linfo.code
18791887
inlineable = inline_worthy(body, cost)
18801888
end
18811889
end
@@ -1903,9 +1911,6 @@ function finish(me::InferenceState)
19031911
end
19041912
type_annotate!(me.linfo, me.stmt_types, me, me.nargs)
19051913

1906-
# make sure (meta pure) is stripped from full tree
1907-
ispure = popmeta!(me.linfo.code, :pure)[1]
1908-
19091914
# run optimization passes on fulltree
19101915
if me.optimize
19111916
# This pass is required for the AST to be valid in codegen
@@ -1923,22 +1928,34 @@ function finish(me::InferenceState)
19231928
reindex_labels!(me.linfo, me)
19241929
end
19251930
widen_all_consts!(me.linfo)
1926-
1927-
# finalize and record the linfo result
1928-
me.inferred = true
1931+
# make sure (meta pure) is stripped from full tree
1932+
ispure = popmeta!(me.linfo.code, :pure)[1]
1933+
me.linfo.pure = ispure
19291934

19301935
# determine and cache inlineability
19311936
me.linfo.inlineable = isinlineable(me.linfo)
19321937

1933-
if isdefined(me.linfo, :def)
1934-
# compress code for non-toplevel thunks
1935-
compressedtree = ccall(:jl_compress_ast, Any, (Any,Any), me.linfo, me.linfo.code)
1936-
me.linfo.code = compressedtree
1938+
if !me.needtree
1939+
me.needtree = me.linfo.inlineable || ccall(:jl_is_cacheable_sig, Int32, (Any, Any, Any),
1940+
me.linfo.specTypes, me.linfo.def.sig, me.linfo.def) != 0
19371941
end
1938-
me.linfo.pure = ispure
1942+
1943+
if me.needtree
1944+
if isdefined(me.linfo, :def)
1945+
# compress code for non-toplevel thunks
1946+
compressedtree = ccall(:jl_compress_ast, Any, (Any,Any), me.linfo, me.linfo.code)
1947+
me.linfo.code = compressedtree
1948+
end
1949+
else
1950+
ccall(:jl_set_lambda_code_null, Void, (Any,), me.linfo)
1951+
me.linfo.inlineable = false
1952+
end
1953+
19391954
ccall(:jl_set_lambda_rettype, Void, (Any, Any), me.linfo, me.bestguess)
19401955
me.linfo.inferred = true
19411956
me.linfo.inInference = false
1957+
# finalize and record the linfo result
1958+
me.inferred = true
19421959

19431960
# lazy-delete the item from active for several reasons:
19441961
# efficiency, correctness, and recursion-safety

base/sysimg.jl

+16-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ eval(m,x) = Core.eval(m,x)
1212

1313
# init core docsystem
1414
import Core: @doc, @__doc__, @doc_str
15-
Core.atdoc!(Core.Inference.CoreDocs.docm)
15+
if isdefined(Core, :Inference)
16+
import Core.Inference.CoreDocs
17+
Core.atdoc!(CoreDocs.docm)
18+
end
1619

1720
include("exports.jl")
1821

@@ -61,6 +64,12 @@ include("refpointer.jl")
6164
include("checked.jl")
6265
importall .Checked
6366

67+
# Symbol constructors
68+
if !isdefined(Core, :Inference)
69+
Symbol(s::String) = Symbol(s.data)
70+
Symbol(a::Array{UInt8,1}) =
71+
ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int32), a, length(a))
72+
end
6473
# vararg Symbol constructor
6574
Symbol(x...) = Symbol(string(x...))
6675

@@ -129,6 +138,11 @@ include("osutils.jl")
129138
include("c.jl")
130139
include("sysinfo.jl")
131140

141+
if !isdefined(Core, :Inference)
142+
include("docs/core.jl")
143+
Core.atdoc!(CoreDocs.docm)
144+
end
145+
132146
# Core I/O
133147
include("io.jl")
134148
include("iostream.jl")
@@ -350,7 +364,7 @@ include("docs/basedocs.jl")
350364
include("markdown/Markdown.jl")
351365
include("docs/Docs.jl")
352366
using .Docs, .Markdown
353-
Docs.loaddocs(Core.Inference.CoreDocs.DOCS)
367+
isdefined(Core, :Inference) && Docs.loaddocs(Core.Inference.CoreDocs.DOCS)
354368

355369
function __init__()
356370
# Base library init

src/alloc.c

-12
Original file line numberDiff line numberDiff line change
@@ -520,18 +520,6 @@ JL_DLLEXPORT jl_lambda_info_t *jl_get_specialized(jl_method_t *m, jl_tupletype_t
520520
new_linfo->specTypes = types;
521521
new_linfo->def = m;
522522
new_linfo->sparam_vals = sp;
523-
524-
if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_OFF ||
525-
jl_options.compile_enabled == JL_OPTIONS_COMPILE_MIN) {
526-
// copy fptr from the template method definition
527-
new_linfo->fptr = linfo->fptr;
528-
new_linfo->jlcall_api = linfo->jlcall_api;
529-
if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_OFF && new_linfo->fptr == NULL) {
530-
jl_printf(JL_STDERR,"code missing for ");
531-
jl_static_show(JL_STDERR, (jl_value_t*)new_linfo);
532-
jl_printf(JL_STDERR, " sysimg may not have been built with --compile=all\n");
533-
}
534-
}
535523
}
536524
else {
537525
new_linfo = jl_instantiate_staged(m, types, sp);

src/anticodegen.c

+12-14
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,42 @@ int globalUnique = 0;
99

1010
#define UNAVAILABLE { jl_errorf("%s: not available in this build of Julia", __func__); }
1111

12-
void jl_dump_bitcode(char *fname, const char *sysimg_data, size_t sysimg_len) UNAVAILABLE
12+
void jl_dump_native(const char *bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len) UNAVAILABLE
1313
void jl_dump_objfile(char *fname, int jit_model, const char *sysimg_data, size_t sysimg_len) UNAVAILABLE
1414
int32_t jl_get_llvm_gv(jl_value_t *p) UNAVAILABLE
1515
void jl_write_malloc_log(void) UNAVAILABLE
1616
void jl_write_coverage_data(void) UNAVAILABLE
1717
void jl_generate_fptr(jl_lambda_info_t *li) UNAVAILABLE
18-
void jl_compile_linfo(jl_lambda_info_t *li, void *cyclectx) UNAVAILABLE
18+
void jl_compile_linfo(jl_lambda_info_t *li) UNAVAILABLE
1919

2020
JL_DLLEXPORT void jl_clear_malloc_data(void) UNAVAILABLE
2121
JL_DLLEXPORT void jl_extern_c(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) UNAVAILABLE
2222
JL_DLLEXPORT void *jl_function_ptr(jl_function_t *f, jl_value_t *rt, jl_value_t *argt) UNAVAILABLE
2323
JL_DLLEXPORT const jl_value_t *jl_dump_function_asm(void *f, int raw_mc) UNAVAILABLE
2424
JL_DLLEXPORT const jl_value_t *jl_dump_function_ir(void *f, uint8_t strip_ir_metadata, uint8_t dump_module) UNAVAILABLE
2525

26-
JL_DLLEXPORT void *jl_LLVMCreateDisasm(const char *, void *, int, void*, void*) UNAVAILABLE
27-
JL_DLLEXPORT size_t jl_LLVMDisasmInstruction(void *DC, uint8_t *, uint64_t, uint64_t PC, char *, size_t) UNAVAILABLE
26+
JL_DLLEXPORT void *jl_LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, void *GetOpInfo, void *SymbolLookUp) UNAVAILABLE
27+
JL_DLLEXPORT size_t jl_LLVMDisasmInstruction(void *DC, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize) UNAVAILABLE
2828

2929
void jl_init_codegen(void) { }
3030
void jl_fptr_to_llvm(jl_fptr_t fptr, jl_lambda_info_t *lam, int specsig)
3131
{
3232
if (!specsig)
3333
lam->fptr = fptr;
3434
}
35-
void jl_getFunctionInfo(char **name, char **filename, size_t *line,
36-
char **inlinedat_file, size_t *inlinedat_line, jl_lambda_info_t **outer_linfo,
37-
size_t pointer, int *fromC, int skipC, int skipInline)
35+
36+
int jl_getFunctionInfo(jl_frame_t **frames, uintptr_t pointer, int skipC, int noInline)
3837
{
39-
*name = NULL;
40-
*line = -1;
41-
*filename = NULL;
42-
*inlinedat_file = NULL;
43-
*inlinedat_line = -1;
44-
*outer_linfo = NULL;
45-
*fromC = 0;
38+
return 0;
4639
}
4740

4841
jl_value_t *jl_static_eval(jl_value_t *ex, void *ctx_, jl_module_t *mod,
4942
jl_lambda_info_t *li, int sparams, int allow_alloc)
5043
{
5144
return NULL;
5245
}
46+
47+
void jl_register_fptrs(uint64_t sysimage_base, void **fptrs, jl_lambda_info_t **linfos, size_t n)
48+
{
49+
(void)sysimage_base; (void)fptrs; (void)linfos; (void)n;
50+
}

src/codegen.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -870,11 +870,8 @@ static void to_function(jl_lambda_info_t *li)
870870
// if not inlineable, code won't be needed again
871871
if (JL_DELETE_NON_INLINEABLE &&
872872
li->def && li->inferred && !li->inlineable &&
873-
li != li->def->lambda_template && !jl_options.outputji) {
874-
li->code = jl_nothing;
875-
li->ssavaluetypes = jl_box_long(jl_array_len(li->ssavaluetypes)); jl_gc_wb(li, li->ssavaluetypes);
876-
li->slotflags = NULL;
877-
li->slotnames = NULL;
873+
li != li->def->lambda_template && !imaging_mode) {
874+
jl_set_lambda_code_null(li);
878875
}
879876

880877
// done compiling: restore global state

src/disasm.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static int OpInfoLookup(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t Si
233233
default: return 0; // Cannot handle input address size
234234
}
235235
int skipC = 0;
236-
jl_frame_t *frame;
236+
jl_frame_t *frame = NULL;
237237
jl_getFunctionInfo(&frame, pointer, skipC, 1);
238238
char *name = frame->func_name;
239239
free(frame->file_name);

src/dump.c

+2
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,8 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos, jl_value_t **loc)
12671267
// builtin types are not serialized, so their caches aren't
12681268
// explicitly saved. so we reconstruct the caches of builtin
12691269
// parametric types here.
1270+
// XXX: need to make sure to serialize all leaftypes in this cache
1271+
// that were referenced from compiled code
12701272
jl_array_ptr_1d_push(datatype_list, (jl_value_t*)dt);
12711273
}
12721274
}

0 commit comments

Comments
 (0)