Skip to content

Commit

Permalink
Track the module during inlining
Browse files Browse the repository at this point in the history
Compute per-statement `in_user_code` to support user code only logging mode
with inlining on.
  • Loading branch information
yuyichao committed Sep 4, 2016
1 parent 5bf3668 commit 671c5a2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
14 changes: 12 additions & 2 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2741,8 +2741,18 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
else
linfo.def.line
end
unshift!(stmts, Expr(:meta, :push_loc, linfo.def.file,
linfo.def.name, line))
# Check if we are switching module, which is necessary to catch user
# code inlined into `Base` with `--code-coverage=user`.
# Assume we are inlining directly into `enclosing` instead of another
# function inlined in it
mod = linfo.def.module
if mod === sv.mod
unshift!(stmts, Expr(:meta, :push_loc, linfo.def.file,
linfo.def.name, line))
else
unshift!(stmts, Expr(:meta, :push_loc, linfo.def.file,
linfo.def.name, line, mod))
end
push!(stmts, Expr(:meta, :pop_loc))
elseif !isempty(stmts)
if all(inlining_ignore, stmts)
Expand Down
50 changes: 35 additions & 15 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4038,12 +4038,8 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
ctx.f = f;

// step 5. set up debug info context and create first basic block
bool in_user_code = !jl_is_submodule(ctx.module, jl_base_module) &&
!jl_is_submodule(ctx.module, jl_core_module);
bool do_coverage = jl_options.code_coverage == JL_LOG_ALL ||
(jl_options.code_coverage == JL_LOG_USER && in_user_code);
bool do_malloc_log = jl_options.malloc_log == JL_LOG_ALL ||
(jl_options.malloc_log == JL_LOG_USER && in_user_code);
int coverage_mode = jl_options.code_coverage;
int malloc_log_mode = jl_options.malloc_log;
StringRef filename = "<missing>";
StringRef dbgFuncName = ctx.name;
int toplineno = -1;
Expand Down Expand Up @@ -4073,8 +4069,8 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
ctx.debug_enabled = true;
if (dbgFuncName.empty()) {
// special value: if function name is empty, disable debug info
do_coverage = false;
do_malloc_log = false;
coverage_mode = JL_LOG_NONE;
malloc_log_mode = JL_LOG_NONE;
//dbgFuncName = filename; // for testing, uncomment this line
ctx.debug_enabled = !dbgFuncName.empty();
}
Expand Down Expand Up @@ -4483,6 +4479,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
DISubprogram *sp;
StringRef file;
ssize_t line;
bool in_user_code;
};
#else
struct DbgState {
Expand All @@ -4499,6 +4496,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
bool is_inbounds;
bool loc_changed;
bool is_poploc;
bool in_user_code;
};
std::vector<StmtProp> stmtprops(stmtslen);
std::vector<DbgState> DI_stack;
Expand All @@ -4511,7 +4509,12 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
inbounds |= inbounds_stack[sz - 2];
return inbounds;
};
StmtProp cur_prop{topdebugloc, filename, toplineno, false, true, false};
StmtProp cur_prop{topdebugloc, filename, toplineno,
false, true, false, false};
if (coverage_mode != JL_LOG_NONE || malloc_log_mode) {
cur_prop.in_user_code = (!jl_is_submodule(ctx.module, jl_base_module) &&
!jl_is_submodule(ctx.module, jl_core_module));
}
for (i = 0; i < stmtslen; i++) {
cur_prop.loc_changed = false;
cur_prop.is_poploc = false;
Expand Down Expand Up @@ -4565,7 +4568,8 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
if (ctx.debug_enabled)
new_file = dbuilder.createFile(new_filename, ".");
DI_stack.push_back({cur_prop.loc, SP,
cur_prop.file, cur_prop.line});
cur_prop.file, cur_prop.line,
cur_prop.in_user_code});
const char *inl_name = "";
int inlined_func_lineno = 0;
if (jl_array_len(expr->args) > 2) {
Expand All @@ -4577,6 +4581,12 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
inlined_func_lineno = jl_unbox_int32(arg);
else if (jl_is_int64(arg))
inlined_func_lineno = jl_unbox_int64(arg);
else if (jl_is_module(arg)) {
jl_module_t *mod = (jl_module_t*)arg;
cur_prop.in_user_code =
(!jl_is_submodule(mod, jl_base_module) &&
!jl_is_submodule(mod, jl_core_module));
}
}
}
else {
Expand Down Expand Up @@ -4615,6 +4625,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
cur_prop.loc = DI.loc;
cur_prop.file = DI.file;
cur_prop.line = DI.line;
cur_prop.in_user_code = DI.in_user_code;
DI_stack.pop_back();
cur_prop.loc_changed = true;
}
Expand Down Expand Up @@ -4712,10 +4723,19 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
return bb;
};

auto do_coverage = [&] (bool in_user_code) {
return (coverage_mode == JL_LOG_ALL ||
(coverage_mode == JL_LOG_USER && in_user_code));
};
auto do_malloc_log = [&] (bool in_user_code) {
return (malloc_log_mode == JL_LOG_ALL ||
(malloc_log_mode == JL_LOG_USER && in_user_code));
};

// If the first expresion changes the line number, we need to visit
// the start of the function. This can happen when the first line is
// a inlined function call.
if (stmtprops[0].loc_changed && do_coverage) {
if (stmtprops[0].loc_changed && do_coverage(stmtprops[0].in_user_code)) {
if (ctx.debug_enabled)
builder.SetCurrentDebugLocation(topdebugloc);
coverageVisitLine(filename, toplineno);
Expand All @@ -4727,7 +4747,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
if (ctx.debug_enabled)
builder.SetCurrentDebugLocation(props.loc);
// Disable coverage for pop_loc, it doesn't start a new expression
if (do_coverage && !props.is_poploc) {
if (do_coverage(props.in_user_code) && !props.is_poploc) {
coverageVisitLine(props.file, props.line);
}
}
Expand Down Expand Up @@ -4763,7 +4783,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
else { // undef return type
retval = NULL;
}
if (do_malloc_log && props.line != -1)
if (do_malloc_log(props.in_user_code) && props.line != -1)
mallocVisitLine(props.file, props.line);
if (type_is_ghost(retty) || ctx.sret)
builder.CreateRetVoid();
Expand All @@ -4782,7 +4802,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
jl_value_t *cond = args[0];
int lname = jl_unbox_long(args[1]);
Value *isfalse = emit_condition(cond, "if", &ctx);
if (do_malloc_log && props.line != -1)
if (do_malloc_log(props.in_user_code) && props.line != -1)
mallocVisitLine(props.file, props.line);
BasicBlock *ifso = BasicBlock::Create(jl_LLVMContext, "if", f);
BasicBlock *ifnot = handle_label(lname, false);
Expand Down Expand Up @@ -4824,7 +4844,7 @@ static std::unique_ptr<Module> emit_function(jl_lambda_info_t *lam, jl_llvm_func
}
else {
emit_stmtpos(stmt, &ctx);
if (do_malloc_log && props.line != -1) {
if (do_malloc_log(props.in_user_code) && props.line != -1) {
mallocVisitLine(props.file, props.line);
}
}
Expand Down

0 comments on commit 671c5a2

Please sign in to comment.