Skip to content
13 changes: 7 additions & 6 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static bool runtime_sym_gvs(jl_codectx_t &ctx, const char *f_lib, const char *f_
else {
std::string name = "ccalllib_";
name += llvm::sys::path::filename(f_lib);
name += std::to_string(jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1));
freshen_name(name);
runtime_lib = true;
auto &libgv = ctx.emission_context.libMapGV[f_lib];
if (libgv.first == NULL) {
Expand All @@ -104,7 +104,7 @@ static bool runtime_sym_gvs(jl_codectx_t &ctx, const char *f_lib, const char *f_
std::string name = "ccall_";
name += f_name;
name += "_";
name += std::to_string(jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1));
freshen_name(name);
auto T_pvoidfunc = getPointerTy(M->getContext());
llvmgv = new GlobalVariable(*M, T_pvoidfunc, false,
GlobalVariable::ExternalLinkage,
Expand Down Expand Up @@ -209,7 +209,7 @@ static Value *runtime_sym_lookup(
std::string gvname = "libname_";
gvname += f_name;
gvname += "_";
gvname += std::to_string(jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1));
freshen_name(gvname);
llvmgv = new GlobalVariable(*jl_Module, T_pvoidfunc, false,
GlobalVariable::ExternalLinkage,
Constant::getNullValue(T_pvoidfunc), gvname);
Expand Down Expand Up @@ -237,7 +237,8 @@ static GlobalVariable *emit_plt_thunk(
libptrgv = prepare_global_in(M, libptrgv);
llvmgv = prepare_global_in(M, llvmgv);
std::string fname;
raw_string_ostream(fname) << "jlplt_" << f_name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(fname) << "jlplt_" << f_name;
freshen_name(fname);
Function *plt = Function::Create(functype,
GlobalVariable::PrivateLinkage,
fname, M);
Expand Down Expand Up @@ -837,8 +838,8 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
std::string ir_name;
while (true) {
raw_string_ostream(ir_name)
<< (ctx.f->getName().str()) << "u"
<< jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
<< (ctx.f->getName().str()) << "u";
freshen_name(ir_name);
if (jl_Module->getFunction(ir_name) == NULL)
break;
}
Expand Down
9 changes: 6 additions & 3 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ static Constant *julia_pgv(jl_codegen_params_t &params, Module *M, const char *c
StringRef localname;
std::string gvname;
if (!gv) {
uint64_t id = jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); // TODO: use params.global_targets.size()
raw_string_ostream(gvname) << cname << id;
raw_string_ostream(gvname) << cname;
freshen_name(gvname);
localname = StringRef(gvname);
}
else {
Expand Down Expand Up @@ -491,7 +491,10 @@ Constant *literal_pointer_val_slot(jl_codegen_params_t &params, Module *M, jl_va
return julia_pgv(params, M, "jl_sym#", addr, NULL, p);
}
// something else gets just a generic name
return julia_pgv(params, M, "jl_global#", p);
std::string name;
auto dt = (jl_datatype_t *)jl_typeof(p);
raw_string_ostream(name) << "jl_global_" << jl_symbol_name(dt->name->name);
return julia_pgv(params, M, name.c_str(), p);
}

static size_t dereferenceable_size(jl_value_t *jt)
Expand Down
49 changes: 36 additions & 13 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,18 @@ static const auto &builtin_func_map() {
return *builtins;
}

static _Atomic(uint64_t) globalUniqueGeneratedNames{1};
static StringMap<uint64_t> fresh_name_map;
static std::mutex fresh_name_lock;

static void freshen_name(std::string &name)
{
uint64_t n;
{
std::lock_guard guard{fresh_name_lock};
n = fresh_name_map[name]++;
}
raw_string_ostream(name) << "_" << n;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am worried that this map could grow big. What issue are you trying to solve here? Just that the order of generation causes different names?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was an attempt at getting reasonable hit rates with the minimum amount of work; it turned out not to be worth it. The new plan is to abandon globally unique names at this stage and resolve things after code generation, but before linking.


// --- code generation ---

Expand Down Expand Up @@ -5271,7 +5282,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
else if (always_inline)
need_to_emit = true;
if (protoname.empty()) {
raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi);
freshen_name(name);
protoname = StringRef(name);
}

Expand Down Expand Up @@ -6184,10 +6196,12 @@ static std::pair<Function*, Function*> get_oc_function(jl_codectx_t &ctx, jl_met
}
else {
if (specsig) {
raw_string_ostream(name) << "j_" << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(name) << "j_" << name_from_method_instance(mi);
freshen_name(name);
protoname = StringRef(name);
}
raw_string_ostream(oc) << "j1_" << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(oc) << "j1_" << name_from_method_instance(mi);
freshen_name(name);
proto_oc = StringRef(oc);
}

Expand Down Expand Up @@ -6730,7 +6744,8 @@ static std::string get_function_name(bool specsig, bool needsparams, const char
if (unadorned_name[0] == '@')
unadorned_name++;
}
funcName << unadorned_name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
funcName << unadorned_name;
freshen_name(_funcName);
return funcName.str();
}

Expand Down Expand Up @@ -6812,7 +6827,8 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Value *theFunc, Module *
++EmittedToJLInvokes;
jl_codectx_t ctx(M->getContext(), params, codeinst);
std::string name;
raw_string_ostream(name) << "tojlinvoke" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(name) << "tojlinvoke";
freshen_name(name);
Function *f = Function::Create(ctx.types().T_jlfunc,
GlobalVariable::InternalLinkage,
name, M);
Expand Down Expand Up @@ -7111,7 +7127,8 @@ std::string emit_abi_dispatcher(Module *M, jl_codegen_params_t &params, jl_value
raw_string_ostream(gf_thunk_name) << "jfptr_" << name_from_method_instance(jl_get_ci_mi(codeinst)) << "_";
else
raw_string_ostream(gf_thunk_name) << "j_";
raw_string_ostream(gf_thunk_name) << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1) << "_gfthunk";
raw_string_ostream(gf_thunk_name) << "_gfthunk";
freshen_name(gf_thunk_name);
if (specsig)
emit_specsig_to_specsig(M, gf_thunk_name, sigt, declrt, is_opaque_closure, nargs, params,
target, sigt, codeinst ? codeinst->rettype : (jl_value_t*)jl_any_type, nullptr, nullptr);
Expand All @@ -7124,7 +7141,8 @@ std::string emit_abi_constreturn(Module *M, jl_codegen_params_t &params, jl_valu
{
bool is_opaque_closure = false;
std::string gf_thunk_name;
raw_string_ostream(gf_thunk_name) << "jconst_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(gf_thunk_name) << "jconst";
freshen_name(gf_thunk_name);
if (specsig) {
emit_specsig_to_specsig(M, gf_thunk_name, sigt, declrt, is_opaque_closure, nargs, params,
nullptr, sigt, jl_typeof(rettype_const), nullptr, rettype_const);
Expand Down Expand Up @@ -7243,7 +7261,8 @@ static Function *gen_cfun_wrapper(
bool nest = (!ff || unionall_env);

std::string funcName;
raw_string_ostream(funcName) << "jlcapi_" << name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(funcName) << "jlcapi_" << name;
freshen_name(funcName);

Module *M = into; // Safe because ctx lock is held by params
AttributeList attributes = sig.attributes;
Expand Down Expand Up @@ -8342,7 +8361,8 @@ static jl_llvm_functions_t
}();

std::string wrapName;
raw_string_ostream(wrapName) << "jfptr_" << ctx.name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(wrapName) << "jfptr_" << ctx.name;
freshen_name(wrapName);
declarations.functionObject = wrapName;
size_t nparams = jl_nparams(abi);
gen_invoke_wrapper(lam, abi, jlrettype, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context);
Expand Down Expand Up @@ -9738,13 +9758,16 @@ jl_llvm_functions_t jl_emit_codedecls(
bool specsig, needsparams;
std::tie(specsig, needsparams) = uses_specsig(get_ci_abi(codeinst), mi, codeinst->rettype, params.params->prefer_specsig);
const char *name = name_from_method_instance(mi);
if (specsig)
raw_string_ostream(decls.functionObject) << "jfptr_" << name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
if (specsig) {
raw_string_ostream(decls.functionObject) << "jfptr_" << name;
freshen_name(decls.functionObject);
}
else if (needsparams)
decls.functionObject = "jl_fptr_sparam";
else
decls.functionObject = "jl_fptr_args";
raw_string_ostream(decls.specFunctionObject) << (specsig ? "j_" : "j1_") << name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
raw_string_ostream(decls.specFunctionObject) << (specsig ? "j_" : "j1_") << name;
freshen_name(decls.specFunctionObject);
M.withModuleDo([&](Module &M) {
bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure;
if (specsig) {
Expand Down