Skip to content

compile: make more efficient by discarding internal names #56702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,10 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
});
egal_set method_roots;
jl_codegen_params_t params(ctxt, std::move(target_info.first), std::move(target_info.second));
if (!llvmmod)
params.getContext().setDiscardValueNames(true);
params.params = cgparams;
params.imaging_mode = imaging;
params.debug_level = cgparams->debug_info_level;
params.external_linkage = _external_linkage;
params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
JL_GC_PUSH3(&params.temporary_roots, &method_roots.list, &method_roots.keyset);
Expand Down Expand Up @@ -1697,6 +1698,7 @@ static SmallVector<AOTOutputs, 16> add_output(Module &M, TargetMachine &TM, Stri
for (unsigned i = 0; i < threads; i++) {
std::function<void()> func = [&, i]() {
LLVMContext ctx;
ctx.setDiscardValueNames(true);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(ctx);
#endif
Expand Down Expand Up @@ -1908,6 +1910,7 @@ void jl_dump_native_impl(void *native_code,
if (z) {
JL_TIMING(NATIVE_AOT, NATIVE_Sysimg);
LLVMContext Context;
Context.setDiscardValueNames(true);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(Context);
#endif
Expand Down Expand Up @@ -2055,6 +2058,7 @@ void jl_dump_native_impl(void *native_code,
{
JL_TIMING(NATIVE_AOT, NATIVE_Metadata);
LLVMContext Context;
Context.setDiscardValueNames(true);
#if JL_LLVM_VERSION < 170000
SetOpaquePointer(Context);
#endif
Expand Down Expand Up @@ -2256,7 +2260,6 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_
// output.imaging = true;
// This would also be nice, but it seems to cause OOMs on the windows32 builder
// To get correct names in the IR this needs to be at least 2
output.debug_level = params.debug_info_level;
output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
JL_GC_PUSH1(&output.temporary_roots);
auto decls = jl_emit_code(m, mi, src, output);
Expand Down
10 changes: 8 additions & 2 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar

// generate a temporary module that contains our IR
std::unique_ptr<Module> Mod;
bool shouldDiscardValueNames = ctx.builder.getContext().shouldDiscardValueNames();
Function *f;
if (entry == NULL) {
// we only have function IR, which we should put in a function
Expand Down Expand Up @@ -878,7 +879,9 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
<< jl_string_data(ir) << "\n}";

SMDiagnostic Err = SMDiagnostic();
ctx.builder.getContext().setDiscardValueNames(false);
Mod = parseAssemblyString(ir_stream.str(), Err, ctx.builder.getContext());
ctx.builder.getContext().setDiscardValueNames(shouldDiscardValueNames);

// backwards compatibility: support for IR with integer pointers
if (!Mod) {
Expand Down Expand Up @@ -911,8 +914,9 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
<< jl_string_data(ir) << "\n}";

SMDiagnostic Err = SMDiagnostic();
Mod =
parseAssemblyString(compat_ir_stream.str(), Err, ctx.builder.getContext());
ctx.builder.getContext().setDiscardValueNames(false);
Mod = parseAssemblyString(compat_ir_stream.str(), Err, ctx.builder.getContext());
ctx.builder.getContext().setDiscardValueNames(shouldDiscardValueNames);
}

if (!Mod) {
Expand All @@ -932,7 +936,9 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar

if (jl_is_string(ir)) {
SMDiagnostic Err = SMDiagnostic();
ctx.builder.getContext().setDiscardValueNames(false);
Mod = parseAssemblyString(jl_string_data(ir), Err, ctx.builder.getContext());
ctx.builder.getContext().setDiscardValueNames(shouldDiscardValueNames);
if (!Mod) {
std::string message = "Failed to parse LLVM assembly: \n";
raw_string_ostream stream(message);
Expand Down
27 changes: 12 additions & 15 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,31 +167,29 @@ void setName(jl_codegen_params_t &params, Value *V, const Twine &Name)
// is not checking that setName is only called for non-folded instructions (e.g. folded bitcasts
// and 0-byte geps), which can result in information loss on the renamed instruction.
assert((isa<Constant>(V) || isa<Instruction>(V)) && "Should only set names on instructions!");
if (params.debug_level >= 2 && !isa<Constant>(V)) {
if (!isa<Constant>(V)) {
V->setName(Name);
}
}

void maybeSetName(jl_codegen_params_t &params, Value *V, const Twine &Name)
{
// To be used when we may get an Instruction or something that is not an instruction i.e Constants/Arguments
if (params.debug_level >= 2 && isa<Instruction>(V)) {
if (isa<Instruction>(V))
V->setName(Name);
}
}

void setName(jl_codegen_params_t &params, Value *V, std::function<std::string()> GetName)
{
assert((isa<Constant>(V) || isa<Instruction>(V)) && "Should only set names on instructions!");
if (params.debug_level >= 2 && !isa<Constant>(V)) {
if (!params.getContext().shouldDiscardValueNames() && !isa<Constant>(V))
V->setName(Twine(GetName()));
}
}

void setNameWithField(jl_codegen_params_t &params, Value *V, std::function<StringRef()> GetObjName, jl_datatype_t *jt, unsigned idx, const Twine &suffix)
{
assert((isa<Constant>(V) || isa<Instruction>(V)) && "Should only set names on instructions!");
if (params.debug_level >= 2 && !isa<Constant>(V)) {
if (!params.getContext().shouldDiscardValueNames() && !isa<Constant>(V)) {
if (jl_is_tuple_type(jt)){
V->setName(Twine(GetObjName()) + "[" + Twine(idx + 1) + "]"+ suffix);
return;
Expand Down Expand Up @@ -8312,7 +8310,7 @@ static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, Value
if (f == NULL) {
f = Function::Create(ftype, GlobalVariable::ExternalLinkage, name, M);
jl_init_function(f, ctx.emission_context.TargetTriple);
if (ctx.emission_context.debug_level >= 2) {
if (ctx.emission_context.params->debug_info_level >= 2) {
ios_t sigbuf;
ios_mem(&sigbuf, 0);
jl_static_show_func_sig((JL_STREAM*) &sigbuf, sig);
Expand Down Expand Up @@ -8421,7 +8419,7 @@ static jl_llvm_functions_t
bool toplevel = false;
ctx.module = jl_is_method(lam->def.method) ? lam->def.method->module : lam->def.module;
ctx.linfo = lam;
ctx.name = TSM.getModuleUnlocked()->getModuleIdentifier().data();
ctx.name = name_from_method_instance(lam);
size_t nreq = src->nargs;
int va = src->isva;
ctx.nargs = nreq;
Expand Down Expand Up @@ -8475,7 +8473,7 @@ static jl_llvm_functions_t
// jl_printf(JL_STDERR, "\n*** compiling %s at %s:%d\n\n",
// jl_symbol_name(ctx.name), ctx.file.str().c_str(), toplineno);

bool debug_enabled = ctx.emission_context.debug_level != 0;
bool debug_enabled = ctx.emission_context.params->debug_info_level != 0;
if (dbgFuncName.empty()) // Should never happen anymore?
debug_enabled = false;

Expand Down Expand Up @@ -8551,15 +8549,14 @@ static jl_llvm_functions_t
// allocate Function declarations and wrapper objects
//Safe because params holds ctx lock
Module *M = TSM.getModuleUnlocked();
M->addModuleFlag(Module::Warning, "julia.debug_level", ctx.emission_context.debug_level);
jl_debugcache_t debugcache;
debugcache.initialize(M);
jl_returninfo_t returninfo = {};
Function *f = NULL;
bool has_sret = false;
if (specsig) { // assumes !va and !needsparams
SmallVector<const char*,0> ArgNames(0);
if (ctx.emission_context.debug_level >= 2) {
if (!M->getContext().shouldDiscardValueNames()) {
ArgNames.resize(ctx.nargs, "");
for (int i = 0; i < ctx.nargs; i++) {
jl_sym_t *argname = slot_symbol(ctx, i);
Expand Down Expand Up @@ -8626,7 +8623,7 @@ static jl_llvm_functions_t
declarations.functionObject = needsparams ? "jl_fptr_sparam" : "jl_fptr_args";
}

if (ctx.emission_context.debug_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) {
if (!params.getContext().shouldDiscardValueNames() && ctx.emission_context.params->debug_info_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) {
ios_t sigbuf;
ios_mem(&sigbuf, 0);
jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)lam->specTypes);
Expand Down Expand Up @@ -8681,7 +8678,7 @@ static jl_llvm_functions_t
if (debug_enabled) {
topfile = dbuilder.createFile(ctx.file, ".");
DISubroutineType *subrty;
if (ctx.emission_context.debug_level <= 1)
if (ctx.emission_context.params->debug_info_level <= 1)
subrty = debugcache.jl_di_func_null_sig;
else if (!specsig)
subrty = debugcache.jl_di_func_sig;
Expand All @@ -8702,7 +8699,7 @@ static jl_llvm_functions_t
);
topdebugloc = DILocation::get(ctx.builder.getContext(), toplineno, 0, SP, NULL);
f->setSubprogram(SP);
if (ctx.emission_context.debug_level >= 2) {
if (ctx.emission_context.params->debug_info_level >= 2) {
const bool AlwaysPreserve = true;
// Go over all arguments and local variables and initialize their debug information
for (i = 0; i < nreq; i++) {
Expand Down Expand Up @@ -10156,7 +10153,7 @@ jl_llvm_functions_t jl_emit_codeinst(
if (// keep code when keeping everything
!(JL_DELETE_NON_INLINEABLE) ||
// aggressively keep code when debugging level >= 2
// note that this uses the global jl_options.debug_level, not the local emission_ctx.debug_level
// note that this uses the global jl_options.debug_level, not the local emission_ctx.debug_info_level
jl_options.debug_level > 1) {
// update the stored code
if (inferred != (jl_value_t*)src) {
Expand Down
7 changes: 4 additions & 3 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,9 +690,9 @@ static void jl_emit_codeinst_to_jit(
JL_TIMING(CODEINST_COMPILE, CODEINST_COMPILE);
// emit the code in LLVM IR form to the new context
jl_codegen_params_t params(std::make_unique<LLVMContext>(), jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); // Locks the context
params.getContext().setDiscardValueNames(true);
params.cache = true;
params.imaging_mode = imaging_default();
params.debug_level = jl_options.debug_level;
orc::ThreadSafeModule result_m =
jl_create_ts_module(name_from_method_instance(codeinst->def), params.tsctx, params.DL, params.TargetTriple);
params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
Expand Down Expand Up @@ -795,9 +795,10 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
Module *M = into->getModuleUnlocked();
jl_codegen_params_t params(into->getContext(), M->getDataLayout(), Triple(M->getTargetTriple()));
params.imaging_mode = imaging_default();
params.debug_level = jl_options.debug_level;
if (pparams == NULL)
if (pparams == NULL) {
M->getContext().setDiscardValueNames(true);
pparams = &params;
}
assert(pparams->tsctx.getContext() == into->getContext().getContext());
const char *name = jl_generate_ccallable(wrap(into), sysimg, declrt, sigt, *pparams);
if (!sysimg) {
Expand Down
1 change: 0 additions & 1 deletion src/jitlayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ struct jl_codegen_params_t {
bool cache = false;
bool external_linkage = false;
bool imaging_mode;
int debug_level;
bool use_swiftcc = true;
jl_codegen_params_t(orc::ThreadSafeContext ctx, DataLayout DL, Triple triple)
: tsctx(std::move(ctx)),
Expand Down
21 changes: 6 additions & 15 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1944,36 +1944,27 @@ void LateLowerGCFrame::CleanupWriteBarriers(Function &F, State *S, const SmallVe
if (CFGModified) {
*CFGModified = true;
}
auto DebugInfoMeta = F.getParent()->getModuleFlag("julia.debug_level");
int debug_info = 1;
if (DebugInfoMeta != nullptr) {
debug_info = cast<ConstantInt>(cast<ConstantAsMetadata>(DebugInfoMeta)->getValue())->getZExtValue();
}

IRBuilder<> builder(CI);
builder.SetCurrentDebugLocation(CI->getDebugLoc());
auto parBits = builder.CreateAnd(EmitLoadTag(builder, T_size, parent), GC_OLD_MARKED);
setName(parBits, "parent_bits", debug_info);
auto parOldMarked = builder.CreateICmpEQ(parBits, ConstantInt::get(T_size, GC_OLD_MARKED));
setName(parOldMarked, "parent_old_marked", debug_info);
auto parBits = builder.CreateAnd(EmitLoadTag(builder, T_size, parent), GC_OLD_MARKED, "parent_bits");
auto parOldMarked = builder.CreateICmpEQ(parBits, ConstantInt::get(T_size, GC_OLD_MARKED), "parent_old_marked");
auto mayTrigTerm = SplitBlockAndInsertIfThen(parOldMarked, CI, false);
builder.SetInsertPoint(mayTrigTerm);
setName(mayTrigTerm->getParent(), "may_trigger_wb", debug_info);
mayTrigTerm->getParent()->setName("may_trigger_wb");
Value *anyChldNotMarked = NULL;
for (unsigned i = 1; i < CI->arg_size(); i++) {
Value *child = CI->getArgOperand(i);
Value *chldBit = builder.CreateAnd(EmitLoadTag(builder, T_size, child), GC_MARKED);
setName(chldBit, "child_bit", debug_info);
Value *chldNotMarked = builder.CreateICmpEQ(chldBit, ConstantInt::get(T_size, 0),"child_not_marked");
setName(chldNotMarked, "child_not_marked", debug_info);
Value *chldBit = builder.CreateAnd(EmitLoadTag(builder, T_size, child), GC_MARKED, "child_bit");
Value *chldNotMarked = builder.CreateICmpEQ(chldBit, ConstantInt::get(T_size, 0), "child_not_marked");
anyChldNotMarked = anyChldNotMarked ? builder.CreateOr(anyChldNotMarked, chldNotMarked) : chldNotMarked;
}
assert(anyChldNotMarked); // handled by all_of test above
MDBuilder MDB(parent->getContext());
SmallVector<uint32_t, 2> Weights{1, 9};
auto trigTerm = SplitBlockAndInsertIfThen(anyChldNotMarked, mayTrigTerm, false,
MDB.createBranchWeights(Weights));
setName(trigTerm->getParent(), "trigger_wb", debug_info);
trigTerm->getParent()->setName("trigger_wb");
builder.SetInsertPoint(trigTerm);
if (CI->getCalledOperand() == write_barrier_func) {
builder.CreateCall(getOrDeclare(jl_intrinsics::queueGCRoot), parent);
Expand Down
7 changes: 0 additions & 7 deletions src/llvm-pass-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,3 @@ namespace jl_well_known {
return addGCAllocAttributes(allocTypedFunc);
});
}

void setName(llvm::Value *V, const llvm::Twine &Name, int debug_info)
{
if (debug_info >= 2 && !llvm::isa<llvm::Constant>(V)) {
V->setName(Name);
}
}