Skip to content

Commit 615a7ba

Browse files
authored
Merge pull request #22678 from JuliaLang/jn/cgctx-globals
only store JIT function names, not full prototypes
2 parents ea61ec6 + 3ec5dc0 commit 615a7ba

9 files changed

+266
-295
lines changed

src/cgutils.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,39 @@ static Instruction *tbaa_decorate(MDNode *md, Instruction *load_or_store)
88
return load_or_store;
99
}
1010

11+
static Function *function_proto(Function *F, Module *M = nullptr)
12+
{
13+
// Copy the declaration characteristics of the Function (not the body)
14+
Function *NewF = Function::Create(F->getFunctionType(),
15+
Function::ExternalLinkage,
16+
F->getName(),
17+
M);
18+
19+
// Declarations are not allowed to have personality routines, but
20+
// copyAttributesFrom sets them anyway. Temporarily unset the personality
21+
// routine from `F`, since copying it and then resetting is more expensive
22+
// as well as introducing an extra use from this unowned function, which
23+
// can cause crashes in the LLVMContext's global destructor.
24+
llvm::Constant *OldPersonalityFn = nullptr;
25+
if (F->hasPersonalityFn()) {
26+
OldPersonalityFn = F->getPersonalityFn();
27+
F->setPersonalityFn(nullptr);
28+
}
29+
30+
// FunctionType does not include any attributes. Copy them over manually
31+
// as codegen may make decisions based on the presence of certain attributes
32+
NewF->copyAttributesFrom(F);
33+
34+
if (OldPersonalityFn)
35+
F->setPersonalityFn(OldPersonalityFn);
36+
37+
// DLLImport only needs to be set for the shadow module
38+
// it just gets annoying in the JIT
39+
NewF->setDLLStorageClass(GlobalValue::DefaultStorageClass);
40+
41+
return NewF;
42+
}
43+
1144
#define prepare_call(Callee) prepare_call_in(jl_Module, (Callee))
1245
static Value *prepare_call_in(Module *M, Value *Callee)
1346
{

src/codegen.cpp

+208-235
Large diffs are not rendered by default.

src/debuginfo.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ class JuliaJITEventListener: public JITEventListener
374374
if (linfo->compile_traced)
375375
triggered_linfos.push_back(linfo);
376376
linfo_in_flight.erase(linfo_it);
377-
Function *F = (Function*)linfo->functionObjectsDecls.functionObject;
378-
if (!linfo->fptr && F && F->getName().equals(sName)) {
377+
const char *F = linfo->functionObjectsDecls.functionObject;
378+
if (!linfo->fptr && F && sName.equals(F)) {
379379
int jlcall_api = jl_jlcall_api(F);
380380
if (linfo->inferred || jlcall_api != 1) {
381381
linfo->jlcall_api = jlcall_api;

src/jitlayers.cpp

+10-11
Original file line numberDiff line numberDiff line change
@@ -761,9 +761,9 @@ static void jl_add_to_ee(std::unique_ptr<Module> m)
761761
jl_ExecutionEngine->addModule(std::move(m));
762762
}
763763

764-
void jl_finalize_function(Function *F)
764+
void jl_finalize_function(StringRef F)
765765
{
766-
std::unique_ptr<Module> m(module_for_fname.lookup(F->getName()));
766+
std::unique_ptr<Module> m(module_for_fname.lookup(F));
767767
if (m) {
768768
jl_merge_recursive(m.get(), m.get());
769769
jl_add_to_ee(std::move(m));
@@ -802,27 +802,26 @@ static void jl_merge_recursive(Module *m, Module *collector)
802802

803803
// see if any of the functions needed by F are still WIP
804804
static StringSet<> incomplete_fname;
805-
static bool jl_can_finalize_function(StringRef F, SmallSet<Module*, 16> &known)
805+
static bool can_finalize_function(StringRef F, SmallSet<Module*, 16> &known)
806806
{
807807
if (incomplete_fname.find(F) != incomplete_fname.end())
808808
return false;
809809
Module *M = module_for_fname.lookup(F);
810-
if (M && known.insert(M).second)
811-
{
810+
if (M && known.insert(M).second) {
812811
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
813812
Function *F = &*I;
814813
if (F->isDeclaration() && !isIntrinsicFunction(F)) {
815-
if (!jl_can_finalize_function(F->getName(), known))
814+
if (!can_finalize_function(F->getName(), known))
816815
return false;
817816
}
818817
}
819818
}
820819
return true;
821820
}
822-
bool jl_can_finalize_function(Function *F)
821+
bool jl_can_finalize_function(StringRef F)
823822
{
824823
SmallSet<Module*, 16> known;
825-
return jl_can_finalize_function(F->getName(), known);
824+
return can_finalize_function(F, known);
826825
}
827826

828827
// let the JIT know this function is a WIP
@@ -1164,13 +1163,13 @@ void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char
11641163
imaging_mode = false;
11651164
}
11661165

1167-
extern "C" int32_t jl_assign_functionID(void *function)
1166+
extern "C" int32_t jl_assign_functionID(const char *fname)
11681167
{
11691168
// give the function an index in the constant lookup table
11701169
assert(imaging_mode);
1171-
if (function == NULL)
1170+
if (fname == NULL)
11721171
return 0;
1173-
jl_sysimg_fvars.push_back(shadow_output->getNamedValue(((Function*)function)->getName()));
1172+
jl_sysimg_fvars.push_back(shadow_output->getNamedValue(fname));
11741173
return jl_sysimg_fvars.size();
11751174
}
11761175

src/jitlayers.h

+2-34
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ void* jl_get_globalvar(GlobalVariable *gv);
4949
GlobalVariable *jl_get_global_for(const char *cname, void *addr, Module *M);
5050
void jl_add_to_shadow(Module *m);
5151
void jl_init_function(Function *f);
52-
bool jl_can_finalize_function(Function *F);
53-
void jl_finalize_function(Function *F);
52+
bool jl_can_finalize_function(StringRef F);
53+
void jl_finalize_function(StringRef F);
5454
void jl_finalize_module(Module *m, bool shadow);
5555

5656
// Connect Modules via prototypes, each owned by module `M`
@@ -69,38 +69,6 @@ static inline GlobalVariable *global_proto(GlobalVariable *G, Module *M = NULL)
6969
return proto;
7070
}
7171

72-
static inline Function *function_proto(Function *F, Module *M = NULL)
73-
{
74-
// Copy the declaration characteristics of the Function (not the body)
75-
Function *NewF = Function::Create(F->getFunctionType(),
76-
Function::ExternalLinkage,
77-
F->getName(), M);
78-
79-
// Declarations are not allowed to have personality routines, but
80-
// copyAttributesFrom sets them anyway. Temporarily unset the personality
81-
// routine from `F`, since copying it and then resetting is more expensive
82-
// as well as introducing an extra use from this unowned function, which
83-
// can cause crashes in the LLVMContext's global destructor.
84-
llvm::Constant *OldPersonalityFn = nullptr;
85-
if (F->hasPersonalityFn()) {
86-
OldPersonalityFn = F->getPersonalityFn();
87-
F->setPersonalityFn(nullptr);
88-
}
89-
90-
// FunctionType does not include any attributes. Copy them over manually
91-
// as codegen may make decisions based on the presence of certain attributes
92-
NewF->copyAttributesFrom(F);
93-
94-
if (OldPersonalityFn)
95-
F->setPersonalityFn(OldPersonalityFn);
96-
97-
// DLLImport only needs to be set for the shadow module
98-
// it just gets annoying in the JIT
99-
NewF->setDLLStorageClass(GlobalValue::DefaultStorageClass);
100-
101-
return NewF;
102-
}
103-
10472
static inline GlobalVariable *prepare_global_in(Module *M, GlobalVariable *G)
10573
{
10674
if (G->getParent() == M)

src/julia.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ JL_EXTENSION typedef struct {
206206
} jl_generic_fptr_t;
207207

208208
typedef struct _jl_llvm_functions_t {
209-
void *functionObject; // jlcall llvm Function
210-
void *specFunctionObject; // specialized llvm Function
209+
const char *functionObject; // jlcall llvm Function name
210+
const char *specFunctionObject; // specialized llvm Function name
211211
} jl_llvm_functions_t;
212212

213213
// This type describes a single function body
@@ -287,10 +287,8 @@ typedef struct _jl_method_instance_t {
287287
jl_fptr_t fptr; // jlcall entry point with api specified by jlcall_api
288288
jl_fptr_t unspecialized_ducttape; // if template can't be compiled due to intrinsics, an un-inferred fptr may get stored here, jlcall_api = 1
289289

290-
// On the old JIT, handles to all Functions generated for this linfo
291-
// For the new JITs, handles to declarations in the shadow module
292-
// with the same name as the generated functions for this linfo, suitable
293-
// for referencing in LLVM IR
290+
// names of declarations in the JIT,
291+
// suitable for referencing in LLVM IR
294292
jl_llvm_functions_t functionObjectsDecls;
295293
} jl_method_instance_t;
296294

src/julia_internal.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ jl_svec_t *jl_perm_symsvec(size_t n, ...);
312312
jl_value_t *jl_gc_realloc_string(jl_value_t *s, size_t sz);
313313

314314
jl_code_info_t *jl_type_infer(jl_method_instance_t **li, size_t world, int force);
315-
jl_generic_fptr_t jl_generate_fptr(jl_method_instance_t *li, void *F, size_t world);
315+
jl_generic_fptr_t jl_generate_fptr(jl_method_instance_t *li, const char *F, size_t world);
316316
jl_llvm_functions_t jl_compile_linfo(
317317
jl_method_instance_t **pli,
318318
jl_code_info_t *src,
@@ -332,7 +332,7 @@ STATIC_INLINE jl_value_t *jl_compile_method_internal(jl_generic_fptr_t *fptr,
332332
if (__unlikely(fptr->fptr == NULL || fptr->jlcall_api == 0)) {
333333
size_t world = jl_get_ptls_states()->world_age;
334334
// first see if it likely needs to be compiled
335-
void *F = meth->functionObjectsDecls.functionObject;
335+
const char *F = meth->functionObjectsDecls.functionObject;
336336
if (!F) // ask codegen to try to turn it into llvm code
337337
F = jl_compile_for_dispatch(&meth, world).functionObject;
338338
if (meth->jlcall_api == 2)
@@ -616,8 +616,8 @@ static inline void jl_set_gc_and_wait(void)
616616

617617
void jl_dump_native(const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len);
618618
int32_t jl_get_llvm_gv(jl_value_t *p);
619-
int32_t jl_assign_functionID(/*llvm::Function*/void *function);
620-
int32_t jl_jlcall_api(/*llvm::Function*/const void *function);
619+
int32_t jl_assign_functionID(const char *fname);
620+
int32_t jl_jlcall_api(const char *fname);
621621
// the first argument to jl_idtable_rehash is used to return a value
622622
// make sure it is rooted if it is used after the function returns
623623
JL_DLLEXPORT jl_array_t *jl_idtable_rehash(jl_array_t *a, size_t newsz);

src/method.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ STATIC_INLINE jl_value_t *jl_call_staged(jl_svec_t *sparam_vals, jl_method_insta
244244
fptr.jlcall_api = generator->jlcall_api;
245245
if (__unlikely(fptr.fptr == NULL || fptr.jlcall_api == 0)) {
246246
size_t world = generator->def.method->min_world;
247-
void *F = jl_compile_linfo(&generator, (jl_code_info_t*)generator->inferred, world, &jl_default_cgparams).functionObject;
247+
const char *F = jl_compile_linfo(&generator, (jl_code_info_t*)generator->inferred, world, &jl_default_cgparams).functionObject;
248248
fptr = jl_generate_fptr(generator, F, world);
249249
}
250250
assert(jl_svec_len(generator->def.method->sparam_syms) == jl_svec_len(sparam_vals));

test/inference.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,9 @@ let f, m
859859
end
860860

861861
# issue #22290
862-
f22290() = return nothing
862+
f22290() = return 3
863863
for i in 1:3
864-
ir = sprint(io->code_llvm(io, f22290, Tuple{}))
864+
ir = sprint(io -> code_llvm(io, f22290, Tuple{}))
865865
@test contains(ir, "julia_f22290")
866866
end
867867

0 commit comments

Comments
 (0)