Skip to content

Commit

Permalink
Reduce code coverage overhead
Browse files Browse the repository at this point in the history
Reduce per-line coverage data to a boolean rather than a count. This
allows us to test if the counter is zero and only increment it if
not, thereby reducing contention in the presence of threads.
  • Loading branch information
kpamnany committed May 16, 2024
1 parent bcd9f13 commit d5dbddf
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2478,17 +2478,6 @@ JL_DLLEXPORT void jl_coverage_alloc_line(StringRef filename, int line);
JL_DLLEXPORT uint64_t *jl_coverage_data_pointer(StringRef filename, int line);
JL_DLLEXPORT uint64_t *jl_malloc_data_pointer(StringRef filename, int line);

static void visitLine(jl_codectx_t &ctx, uint64_t *ptr, Value *addend, const char *name)
{
Value *pv = ConstantExpr::getIntToPtr(
ConstantInt::get(ctx.types().T_size, (uintptr_t)ptr),
getInt64PtrTy(ctx.builder.getContext()));
Value *v = ctx.builder.CreateLoad(getInt64Ty(ctx.builder.getContext()), pv, true, name);
v = ctx.builder.CreateAdd(v, addend);
ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate,
// but it's faster this way
}

// Code coverage

static void coverageVisitLine(jl_codectx_t &ctx, StringRef filename, int line)
Expand All @@ -2497,7 +2486,21 @@ static void coverageVisitLine(jl_codectx_t &ctx, StringRef filename, int line)
return; // TODO
if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
return;
visitLine(ctx, jl_coverage_data_pointer(filename, line), ConstantInt::get(getInt64Ty(ctx.builder.getContext()), 1), "lcnt");
Value *pv = ConstantExpr::getIntToPtr(
ConstantInt::get(ctx.types().T_size, (uintptr_t)jl_coverage_data_pointer(filename, line)),
getInt64PtrTy(ctx.builder.getContext()));
Value *v = ctx.builder.CreateLoad(getInt64Ty(ctx.builder.getContext()), pv, true, "lcnt");
Value *is_zero = ctx.builder.CreateICmpEQ(v, ConstantInt::get(getInt64Ty(ctx.builder.getContext()), 0));
setName(ctx.emission_context, is_zero, "lcnt_is_zero");
BasicBlock *doIncrBB = BasicBlock::Create(ctx.builder.getContext(), "lcnt_do_incr", ctx.f);
BasicBlock *contBB = BasicBlock::Create(ctx.builder.getContext(), "lcnt_cont", ctx.f);
ctx.builder.SetInsertPoint(doIncrBB);
v = ctx.builder.CreateAdd(v, ConstantInt::get(getInt64Ty(ctx.builder.getContext()), 1));
ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate,
// but it's faster this way
ctx.builder.CreateBr(contBB);
ctx.builder.CreateCondBr(is_zero, doIncrBB, contBB);
ctx.builder.SetInsertPoint(contBB);
}

// Memory allocation log (malloc_log)
Expand All @@ -2511,7 +2514,13 @@ static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Val
Value *addend = sync
? ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync})
: ctx.builder.CreateCall(prepare_call(diff_gc_total_bytes_func), {});
visitLine(ctx, jl_malloc_data_pointer(filename, line), addend, "bytecnt");
Value *pv = ConstantExpr::getIntToPtr(
ConstantInt::get(ctx.types().T_size, (uintptr_t)jl_malloc_data_pointer(filename, line)),
getInt64PtrTy(ctx.builder.getContext()));
Value *v = ctx.builder.CreateLoad(getInt64Ty(ctx.builder.getContext()), pv, true, "bytecnt");
v = ctx.builder.CreateAdd(v, addend);
ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate,
// but it's faster this way
}

// --- constant determination ---
Expand Down

0 comments on commit d5dbddf

Please sign in to comment.