Skip to content

Commit 7ca0f0d

Browse files
codegen: Remove literal_static_pointer_val from literal_pointer_val implementation (#50632)
This eliminates most of the literal pointers outside of ccalls and directly JIT-ted code, except instead of adding names we instead just use imaging mode and fix up the visualization in `jl_get_llvmf_defn`.
1 parent 207c09a commit 7ca0f0d

File tree

6 files changed

+42
-47
lines changed

6 files changed

+42
-47
lines changed

src/aotcompile.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,13 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
356356
JL_GC_POP();
357357

358358
// process the globals array, before jl_merge_module destroys them
359-
std::vector<std::string> gvars(params.globals.size());
360-
data->jl_value_to_llvm.resize(params.globals.size());
359+
std::vector<std::string> gvars(params.global_targets.size());
360+
data->jl_value_to_llvm.resize(params.global_targets.size());
361361
StringSet<> gvars_names;
362362
DenseSet<GlobalValue *> gvars_set;
363363

364364
size_t idx = 0;
365-
for (auto &global : params.globals) {
365+
for (auto &global : params.global_targets) {
366366
gvars[idx] = global.second->getName().str();
367367
assert(gvars_set.insert(global.second).second && "Duplicate gvar in params!");
368368
assert(gvars_names.insert(gvars[idx]).second && "Duplicate gvar name in params!");
@@ -2123,11 +2123,28 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, siz
21232123
Function *F = NULL;
21242124
if (m) {
21252125
// if compilation succeeded, prepare to return the result
2126-
// For imaging mode, global constants are currently private without initializer
2127-
// which isn't legal. Convert them to extern linkage so that the code can compile
2128-
// and will better match what's actually in sysimg.
2129-
for (auto &global : output.globals)
2130-
global.second->setLinkage(GlobalValue::ExternalLinkage);
2126+
// Similar to jl_link_global from jitlayers.cpp,
2127+
// so that code_llvm shows similar codegen to the jit
2128+
for (auto &global : output.global_targets) {
2129+
if (jl_options.image_codegen) {
2130+
global.second->setLinkage(GlobalValue::ExternalLinkage);
2131+
} else {
2132+
auto p = literal_static_pointer_val(global.first, global.second->getValueType());
2133+
Type *elty;
2134+
if (p->getType()->isOpaquePointerTy()) {
2135+
elty = PointerType::get(output.getContext(), 0);
2136+
} else {
2137+
elty = p->getType()->getNonOpaquePointerElementType();
2138+
}
2139+
// For pretty printing, when LLVM inlines the global initializer into its loads
2140+
auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, m.getModuleUnlocked());
2141+
global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType()));
2142+
global.second->setConstant(true);
2143+
global.second->setLinkage(GlobalValue::PrivateLinkage);
2144+
global.second->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
2145+
global.second->setVisibility(GlobalValue::DefaultVisibility);
2146+
}
2147+
}
21312148
assert(!verifyLLVMIR(*m.getModuleUnlocked()));
21322149
if (optimize) {
21332150
#ifndef JL_USE_NEW_PM

src/ccall.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2092,8 +2092,9 @@ jl_cgval_t function_sig_t::emit_a_ccall(
20922092
}
20932093
else if (symarg.fptr != NULL) {
20942094
++LiteralCCalls;
2095-
Type *funcptype = PointerType::get(functype, 0);
2095+
Type *funcptype = functype->getPointerTo(0);
20962096
llvmf = literal_static_pointer_val((void*)(uintptr_t)symarg.fptr, funcptype);
2097+
setName(ctx.emission_context, llvmf, "ccall_fptr");
20972098
if (ctx.emission_context.imaging)
20982099
jl_printf(JL_STDERR,"WARNING: literal address used in ccall for %s; code cannot be statically compiled\n", symarg.f_name);
20992100
}

src/cgutils.cpp

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,12 @@ static Constant *julia_pgv(jl_codectx_t &ctx, const char *cname, void *addr)
330330
// emit a GlobalVariable for a jl_value_t named "cname"
331331
// store the name given so we can reuse it (facilitating merging later)
332332
// so first see if there already is a GlobalVariable for this address
333-
GlobalVariable* &gv = ctx.global_targets[addr];
333+
GlobalVariable* &gv = ctx.emission_context.global_targets[addr];
334334
Module *M = jl_Module;
335335
StringRef localname;
336336
std::string gvname;
337337
if (!gv) {
338-
uint64_t id = ctx.emission_context.imaging ? jl_atomic_fetch_add(&globalUniqueGeneratedNames, 1) : ctx.global_targets.size();
338+
uint64_t id = ctx.emission_context.imaging ? jl_atomic_fetch_add(&globalUniqueGeneratedNames, 1) : ctx.emission_context.global_targets.size();
339339
raw_string_ostream(gvname) << cname << id;
340340
localname = StringRef(gvname);
341341
}
@@ -391,16 +391,6 @@ static Constant *literal_pointer_val_slot(jl_codectx_t &ctx, jl_value_t *p)
391391
{
392392
// emit a pointer to a jl_value_t* which will allow it to be valid across reloading code
393393
// also, try to give it a nice name for gdb, for easy identification
394-
if (!ctx.emission_context.imaging) {
395-
// TODO: this is an optimization, but is it useful or premature
396-
// (it'll block any attempt to cache these, but can be simply deleted)
397-
Module *M = jl_Module;
398-
GlobalVariable *gv = new GlobalVariable(
399-
*M, ctx.types().T_pjlvalue, true, GlobalVariable::PrivateLinkage,
400-
literal_static_pointer_val(p, ctx.types().T_pjlvalue));
401-
gv->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
402-
return gv;
403-
}
404394
if (JuliaVariable *gv = julia_const_gv(p)) {
405395
// if this is a known special object, use the existing GlobalValue
406396
return prepare_global_in(jl_Module, gv);
@@ -513,8 +503,6 @@ static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p)
513503
{
514504
if (p == NULL)
515505
return Constant::getNullValue(ctx.types().T_pjlvalue);
516-
if (!ctx.emission_context.imaging)
517-
return literal_static_pointer_val(p, ctx.types().T_pjlvalue);
518506
Value *pgv = literal_pointer_val_slot(ctx, p);
519507
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
520508
auto load = ai.decorateInst(maybe_mark_load_dereferenceable(
@@ -530,8 +518,6 @@ static Value *literal_pointer_val(jl_codectx_t &ctx, jl_binding_t *p)
530518
// emit a pointer to any jl_value_t which will be valid across reloading code
531519
if (p == NULL)
532520
return Constant::getNullValue(ctx.types().T_pjlvalue);
533-
if (!ctx.emission_context.imaging)
534-
return literal_static_pointer_val(p, ctx.types().T_pjlvalue);
535521
// bindings are prefixed with jl_bnd#
536522
jl_globalref_t *gr = p->globalref;
537523
Value *pgv = gr ? julia_pgv(ctx, "jl_bnd#", gr->name, gr->mod, p) : julia_pgv(ctx, "jl_bnd#", p);
@@ -575,17 +561,12 @@ static Value *julia_binding_gv(jl_codectx_t &ctx, jl_binding_t *b)
575561
{
576562
// emit a literal_pointer_val to a jl_binding_t
577563
// binding->value are prefixed with *
578-
if (ctx.emission_context.imaging) {
579-
jl_globalref_t *gr = b->globalref;
580-
Value *pgv = gr ? julia_pgv(ctx, "*", gr->name, gr->mod, b) : julia_pgv(ctx, "*jl_bnd#", b);
581-
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
582-
auto load = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, pgv, Align(sizeof(void*))));
583-
setName(ctx.emission_context, load, pgv->getName());
584-
return load;
585-
}
586-
else {
587-
return literal_static_pointer_val(b, ctx.types().T_pjlvalue);
588-
}
564+
jl_globalref_t *gr = b->globalref;
565+
Value *pgv = gr ? julia_pgv(ctx, "*", gr->name, gr->mod, b) : julia_pgv(ctx, "*jl_bnd#", b);
566+
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
567+
auto load = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_pjlvalue, pgv, Align(sizeof(void*))));
568+
setName(ctx.emission_context, load, pgv->getName());
569+
return load;
589570
}
590571

591572
// --- mapping between julia and llvm types ---
@@ -1130,8 +1111,8 @@ static Value *emit_typeof(jl_codectx_t &ctx, const jl_cgval_t &p, bool maybenull
11301111
p.typ,
11311112
counter);
11321113
auto emit_unboxty = [&] () -> Value* {
1133-
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
11341114
if (ctx.emission_context.imaging) {
1115+
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
11351116
Value *datatype = ai.decorateInst(ctx.builder.CreateAlignedLoad(expr_type, datatype_or_p, Align(sizeof(void*))));
11361117
setName(ctx.emission_context, datatype, "typetag");
11371118
return justtag ? datatype : track_pjlvalue(ctx, datatype);

src/codegen.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,8 +1608,6 @@ class jl_codectx_t {
16081608
IRBuilder<> builder;
16091609
jl_codegen_params_t &emission_context;
16101610
llvm::MapVector<jl_code_instance_t*, jl_codegen_call_target_t> call_targets;
1611-
std::map<void*, GlobalVariable*> &global_targets;
1612-
std::map<std::tuple<jl_code_instance_t*, bool>, GlobalVariable*> &external_calls;
16131611
Function *f = NULL;
16141612
// local var info. globals are not in here.
16151613
std::vector<jl_varinfo_t> slots;
@@ -1654,8 +1652,6 @@ class jl_codectx_t {
16541652
: builder(llvmctx),
16551653
emission_context(params),
16561654
call_targets(),
1657-
global_targets(params.globals),
1658-
external_calls(params.external_fns),
16591655
world(params.world),
16601656
use_cache(params.cache),
16611657
external_linkage(params.external_linkage),
@@ -4318,7 +4314,7 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos
43184314
GlobalVariable::ExternalLinkage,
43194315
Constant::getNullValue(TheCallee->getType()),
43204316
namep);
4321-
ctx.external_calls[std::make_tuple(fromexternal, true)] = GV;
4317+
ctx.emission_context.external_fns[std::make_tuple(fromexternal, true)] = GV;
43224318
}
43234319
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
43244320
TheCallee = ai.decorateInst(ctx.builder.CreateAlignedLoad(TheCallee->getType(), GV, Align(sizeof(void*))));
@@ -4388,7 +4384,7 @@ static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty
43884384
GlobalVariable::ExternalLinkage,
43894385
Constant::getNullValue(pfunc),
43904386
namep);
4391-
ctx.external_calls[std::make_tuple(fromexternal, false)] = GV;
4387+
ctx.emission_context.external_fns[std::make_tuple(fromexternal, false)] = GV;
43924388
}
43934389
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
43944390
theFptr = ai.decorateInst(ctx.builder.CreateAlignedLoad(pfunc, GV, Align(sizeof(void*))));

src/jitlayers.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static jl_callptr_t _jl_compile_codeinst(
214214
if (!params.imaging) {
215215
StringMap<orc::ThreadSafeModule*> NewExports;
216216
StringMap<void*> NewGlobals;
217-
for (auto &global : params.globals) {
217+
for (auto &global : params.global_targets) {
218218
NewGlobals[global.second->getName()] = global.first;
219219
}
220220
for (auto &def : emitted) {
@@ -243,7 +243,7 @@ static jl_callptr_t _jl_compile_codeinst(
243243
assert(Queued.empty() && Stack.empty() && !M);
244244
}
245245
} else {
246-
jl_jit_globals(params.globals);
246+
jl_jit_globals(params.global_targets);
247247
auto main = std::move(emitted[codeinst].first);
248248
for (auto &def : emitted) {
249249
if (def.first != codeinst) {
@@ -372,7 +372,7 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
372372
success = false;
373373
}
374374
if (success && p == NULL) {
375-
jl_jit_globals(params.globals);
375+
jl_jit_globals(params.global_targets);
376376
assert(params.workqueue.empty());
377377
if (params._shared_module)
378378
jl_ExecutionEngine->addModule(orc::ThreadSafeModule(std::move(params._shared_module), params.tsctx));

src/jitlayers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ typedef struct _jl_codegen_params_t {
207207
typedef StringMap<GlobalVariable*> SymMapGV;
208208
// outputs
209209
std::vector<std::pair<jl_code_instance_t*, jl_codegen_call_target_t>> workqueue;
210-
std::map<void*, GlobalVariable*> globals;
210+
std::map<void*, GlobalVariable*> global_targets;
211211
std::map<std::tuple<jl_code_instance_t*,bool>, GlobalVariable*> external_fns;
212212
std::map<jl_datatype_t*, DIType*> ditypes;
213213
std::map<jl_datatype_t*, Type*> llvmtypes;

0 commit comments

Comments
 (0)