Skip to content

Commit

Permalink
Create debuginfo once per module (JuliaLang#43770)
Browse files Browse the repository at this point in the history
  • Loading branch information
pchintalapudi committed Mar 4, 2022
1 parent b63ae3b commit 5db280d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 72 deletions.
56 changes: 49 additions & 7 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ Metadata *to_md_tree(jl_value_t *val, LLVMContext &ctxt) {

// --- Debug info ---

static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_debugcache_t &debuginfo, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
{
jl_datatype_t *jdt = (jl_datatype_t*)jt;
if (isboxed || !jl_is_datatype(jt) || !jdt->isconcretetype)
return jl_pvalue_dillvmt;
return debuginfo.jl_pvalue_dillvmt;
assert(jdt->layout);
DIType* _ditype = NULL;
DIType* &ditype = (ctx ? ctx->ditypes[jdt] : _ditype);
Expand All @@ -131,10 +131,10 @@ static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBui
jl_value_t *el = jl_field_type_concrete(jdt, i);
DIType *di;
if (jl_field_isptr(jdt, i))
di = jl_pvalue_dillvmt;
di = debuginfo.jl_pvalue_dillvmt;
// TODO: elseif jl_islayout_inline
else
di = _julia_type_to_di(ctx, el, dbuilder, false);
di = _julia_type_to_di(ctx, debuginfo, el, dbuilder, false);
Elements[i] = di;
}
DINodeArray ElemArray = dbuilder->getOrCreateArray(Elements);
Expand All @@ -157,14 +157,56 @@ static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBui
}
else {
// return a typealias for types with hidden content
ditype = dbuilder->createTypedef(jl_pvalue_dillvmt, tname, NULL, 0, NULL);
ditype = dbuilder->createTypedef(debuginfo.jl_pvalue_dillvmt, tname, NULL, 0, NULL);
}
return ditype;
}

static DIType *julia_type_to_di(jl_codectx_t &ctx, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
static DIType *julia_type_to_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *jt, DIBuilder *dbuilder, bool isboxed)
{
return _julia_type_to_di(&ctx.emission_context, jt, dbuilder, isboxed);
return _julia_type_to_di(&ctx.emission_context, debuginfo, jt, dbuilder, isboxed);
}

void jl_debugcache_t::initialize(Module *m) {
if (initialized) {
return;
}
initialized = true;
// add needed base debugging definitions to our LLVM environment
DIBuilder dbuilder(*m);
DIFile *julia_h = dbuilder.createFile("julia.h", "");
DICompositeType *jl_value_dillvmt = dbuilder.createStructType(nullptr,
"jl_value_t",
julia_h,
71, // At the time of this writing. Not sure if it's worth it to keep this in sync
0 * 8, // sizeof(jl_value_t) * 8,
__alignof__(void*) * 8, // __alignof__(jl_value_t) * 8,
DINode::FlagZero, // Flags
nullptr, // Derived from
nullptr); // Elements - will be corrected later

jl_pvalue_dillvmt = dbuilder.createPointerType(jl_value_dillvmt, sizeof(jl_value_t*) * 8,
__alignof__(jl_value_t*) * 8);

SmallVector<llvm::Metadata *, 1> Elts;
std::vector<Metadata*> diargs(0);
Elts.push_back(jl_pvalue_dillvmt);
dbuilder.replaceArrays(jl_value_dillvmt,
dbuilder.getOrCreateArray(Elts));

jl_ppvalue_dillvmt = dbuilder.createPointerType(jl_pvalue_dillvmt, sizeof(jl_value_t**) * 8,
__alignof__(jl_value_t**) * 8);

diargs.push_back(jl_pvalue_dillvmt); // Return Type (ret value)
diargs.push_back(jl_pvalue_dillvmt); // First Argument (function)
diargs.push_back(jl_ppvalue_dillvmt); // Second Argument (argv)
// Third argument (length(argv))
diargs.push_back(_julia_type_to_di(NULL, *this, (jl_value_t*)jl_int32_type, &dbuilder, false));

jl_di_func_sig = dbuilder.createSubroutineType(
dbuilder.getOrCreateTypeArray(diargs));
jl_di_func_null_sig = dbuilder.createSubroutineType(
dbuilder.getOrCreateTypeArray(None));
}

static Value *emit_pointer_from_objref(jl_codectx_t &ctx, Value *V)
Expand Down
95 changes: 30 additions & 65 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,20 @@ struct jl_tbaacache_t {
}
};

// Basic DITypes
static DICompositeType *jl_value_dillvmt;
static DIDerivedType *jl_pvalue_dillvmt;
static DIDerivedType *jl_ppvalue_dillvmt;
static DISubroutineType *jl_di_func_sig;
static DISubroutineType *jl_di_func_null_sig;
struct jl_debugcache_t {
// Basic DITypes
DIDerivedType *jl_pvalue_dillvmt;
DIDerivedType *jl_ppvalue_dillvmt;
DISubroutineType *jl_di_func_sig;
DISubroutineType *jl_di_func_null_sig;
bool initialized;

jl_debugcache_t()
: jl_pvalue_dillvmt(nullptr), jl_ppvalue_dillvmt(nullptr),
jl_di_func_sig(nullptr), jl_di_func_null_sig(nullptr), initialized(false) {}

void initialize(Module *m);
};


// constants
Expand Down Expand Up @@ -6252,14 +6260,14 @@ static void emit_sret_roots(jl_codectx_t &ctx, bool isptr, Value *Src, Type *T,
}

static DISubroutineType *
get_specsig_di(jl_codectx_t &ctx, jl_value_t *rt, jl_value_t *sig, DIBuilder &dbuilder)
get_specsig_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *rt, jl_value_t *sig, DIBuilder &dbuilder)
{
size_t nargs = jl_nparams(sig); // TODO: if this is a Varargs function, our debug info for the `...` var may be misleading
std::vector<Metadata*> ditypes(nargs + 1);
ditypes[0] = julia_type_to_di(ctx, rt, &dbuilder, false);
ditypes[0] = julia_type_to_di(ctx, debuginfo, rt, &dbuilder, false);
for (size_t i = 0; i < nargs; i++) {
jl_value_t *jt = jl_tparam(sig, i);
ditypes[i + 1] = julia_type_to_di(ctx, jt, &dbuilder, false);
ditypes[i + 1] = julia_type_to_di(ctx, debuginfo, jt, &dbuilder, false);
}
return dbuilder.createSubroutineType(dbuilder.getOrCreateTypeArray(ditypes));
}
Expand Down Expand Up @@ -6439,6 +6447,8 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>

// allocate Function declarations and wrapper objects
Module *M = _jl_create_llvm_module(ctx.name, ctx.builder.getContext(), ctx.params, jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple());
jl_debugcache_t debuginfo;
debuginfo.initialize(M);
jl_returninfo_t returninfo = {};
Function *f = NULL;
bool has_sret = false;
Expand Down Expand Up @@ -6561,13 +6571,13 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>

DISubroutineType *subrty;
if (jl_options.debug_level <= 1) {
subrty = jl_di_func_null_sig;
subrty = debuginfo.jl_di_func_null_sig;
}
else if (!specsig) {
subrty = jl_di_func_sig;
subrty = debuginfo.jl_di_func_sig;
}
else {
subrty = get_specsig_di(ctx, jlrettype, lam->specTypes, dbuilder);
subrty = get_specsig_di(ctx, debuginfo, jlrettype, lam->specTypes, dbuilder);
}
SP = dbuilder.createFunction(CU
,dbgFuncName // Name
Expand Down Expand Up @@ -6599,7 +6609,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
topfile, // File
toplineno == -1 ? 0 : toplineno, // Line
// Variable type
julia_type_to_di(ctx, varinfo.value.typ, &dbuilder, false),
julia_type_to_di(ctx, debuginfo, varinfo.value.typ, &dbuilder, false),
AlwaysPreserve, // May be deleted if optimized out
DINode::FlagZero); // Flags (TODO: Do we need any)
}
Expand All @@ -6610,7 +6620,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
has_sret + nreq + 1, // Argument number (1-based)
topfile, // File
toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function)
julia_type_to_di(ctx, ctx.slots[ctx.vaSlot].value.typ, &dbuilder, false),
julia_type_to_di(ctx, debuginfo, ctx.slots[ctx.vaSlot].value.typ, &dbuilder, false),
AlwaysPreserve, // May be deleted if optimized out
DINode::FlagZero); // Flags (TODO: Do we need any)
}
Expand All @@ -6625,7 +6635,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
jl_symbol_name(s), // Variable name
topfile, // File
toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function)
julia_type_to_di(ctx, varinfo.value.typ, &dbuilder, false), // Variable type
julia_type_to_di(ctx, debuginfo, varinfo.value.typ, &dbuilder, false), // Variable type
AlwaysPreserve, // May be deleted if optimized out
DINode::FlagZero // Flags (TODO: Do we need any)
);
Expand Down Expand Up @@ -6714,7 +6724,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
varinfo.value = mark_julia_slot(lv, jt, NULL, ctx.tbaa(), ctx.tbaa().tbaa_stack);
alloc_def_flag(ctx, varinfo);
if (ctx.debug_enabled && varinfo.dinfo) {
assert((Metadata*)varinfo.dinfo->getType() != jl_pvalue_dillvmt);
assert((Metadata*)varinfo.dinfo->getType() != debuginfo.jl_pvalue_dillvmt);
dbuilder.insertDeclare(lv, varinfo.dinfo, dbuilder.createExpression(),
topdebugloc,
ctx.builder.GetInsertBlock());
Expand All @@ -6732,7 +6742,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
varinfo.boxroot = av;
if (ctx.debug_enabled && varinfo.dinfo) {
DIExpression *expr;
if ((Metadata*)varinfo.dinfo->getType() == jl_pvalue_dillvmt) {
if ((Metadata*)varinfo.dinfo->getType() == debuginfo.jl_pvalue_dillvmt) {
expr = dbuilder.createExpression();
}
else {
Expand Down Expand Up @@ -6855,7 +6865,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
addr.push_back(llvm::dwarf::DW_OP_deref);
addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
addr.push_back((i - 1) * sizeof(void*));
if ((Metadata*)vi.dinfo->getType() != jl_pvalue_dillvmt)
if ((Metadata*)vi.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
addr.push_back(llvm::dwarf::DW_OP_deref);
dbuilder.insertDeclare(pargArray, vi.dinfo, dbuilder.createExpression(addr),
topdebugloc,
Expand Down Expand Up @@ -6896,7 +6906,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
Value *parg;
if (theArg.ispointer()) {
parg = theArg.V;
if ((Metadata*)vi.dinfo->getType() != jl_pvalue_dillvmt)
if ((Metadata*)vi.dinfo->getType() != debuginfo.jl_pvalue_dillvmt)
addr.push_back(llvm::dwarf::DW_OP_deref);
}
else {
Expand Down Expand Up @@ -7034,7 +7044,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
,fname // LinkageName
,difile // File
,0 // LineNo
,jl_di_func_null_sig // Ty
,debuginfo.jl_di_func_null_sig // Ty
,0 // ScopeLine
,DINode::FlagZero // Flags
,DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized // SPFlags
Expand Down Expand Up @@ -8000,48 +8010,6 @@ static JuliaVariable *julia_const_gv(jl_value_t *val)
return nullptr;
}

static void init_julia_llvm_env(Module *m)
{
// every variable or function mapped in this function must be
// exported from libjulia, to support static compilation

// add needed base debugging definitions to our LLVM environment
DIBuilder dbuilder(*m);
DIFile *julia_h = dbuilder.createFile("julia.h", "");
jl_value_dillvmt = dbuilder.createStructType(nullptr,
"jl_value_t",
julia_h,
71, // At the time of this writing. Not sure if it's worth it to keep this in sync
0 * 8, // sizeof(jl_value_t) * 8,
__alignof__(void*) * 8, // __alignof__(jl_value_t) * 8,
DINode::FlagZero, // Flags
nullptr, // Derived from
nullptr); // Elements - will be corrected later

jl_pvalue_dillvmt = dbuilder.createPointerType(jl_value_dillvmt, sizeof(jl_value_t*) * 8,
__alignof__(jl_value_t*) * 8);

SmallVector<llvm::Metadata *, 1> Elts;
std::vector<Metadata*> diargs(0);
Elts.push_back(jl_pvalue_dillvmt);
dbuilder.replaceArrays(jl_value_dillvmt,
dbuilder.getOrCreateArray(Elts));

jl_ppvalue_dillvmt = dbuilder.createPointerType(jl_pvalue_dillvmt, sizeof(jl_value_t**) * 8,
__alignof__(jl_value_t**) * 8);

diargs.push_back(jl_pvalue_dillvmt); // Return Type (ret value)
diargs.push_back(jl_pvalue_dillvmt); // First Argument (function)
diargs.push_back(jl_ppvalue_dillvmt); // Second Argument (argv)
// Third argument (length(argv))
diargs.push_back(_julia_type_to_di(NULL, (jl_value_t*)jl_int32_type, &dbuilder, false));

jl_di_func_sig = dbuilder.createSubroutineType(
dbuilder.getOrCreateTypeArray(diargs));
jl_di_func_null_sig = dbuilder.createSubroutineType(
dbuilder.getOrCreateTypeArray(None));
}

static void init_jit_functions(void)
{
add_named_global(jlstack_chk_guard_var, &__stack_chk_guard);
Expand Down Expand Up @@ -8303,9 +8271,6 @@ extern "C" JL_DLLEXPORT void jl_init_codegen_impl(void)
jl_init_jit();
init_jit_functions();

Module *m = _jl_create_llvm_module("julia", *jl_ExecutionEngine->getContext().getContext(), &jl_default_cgparams, jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple());
init_julia_llvm_env(m);

jl_init_intrinsic_functions_codegen();
}

Expand Down

0 comments on commit 5db280d

Please sign in to comment.