mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Coverage] Refactor SIL generation for profiling
This patch moves the ownership of profiling state from SILGenProfiling to SILFunction, where it always belonged. Similarly, it moves ownership of the profile reader from SILGenModule to SILModule. The refactor sets us up to fix a few outstanding code coverage bugs and does away with sad hacks like ProfilerRAII. It also allows us to locally guarantee that a profile counter increment actually corresponds to the SILFunction at hand. That local guarantee causes a bugfix to accidentally fall out of this refactor: we now set up the profiling state for delayed functions correctly. Previously, we would set up a ProfilerRAII for the delayed function, but its counter increment would never be emitted :(. This fix constitutes the only functional change in this patch -- the rest is NFC. As a follow-up, I plan on removing some dead code in the profiling logic and fixing a few naming inconsistencies. I've left that for later to keep this patch simple.
This commit is contained in:
committed by
Vedant Kumar
parent
3fd5675235
commit
dd560d2aa6
@@ -619,3 +619,57 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) {
|
||||
emitReturnExpr(Loc, value);
|
||||
emitEpilog(Loc);
|
||||
}
|
||||
|
||||
static SILLocation getLocation(ASTNode Node) {
|
||||
if (auto *E = Node.dyn_cast<Expr *>())
|
||||
return E;
|
||||
else if (auto *S = Node.dyn_cast<Stmt *>())
|
||||
return S;
|
||||
else if (auto *D = Node.dyn_cast<Decl *>())
|
||||
return D;
|
||||
else
|
||||
llvm_unreachable("unsupported ASTNode");
|
||||
}
|
||||
|
||||
void SILGenFunction::emitProfilerIncrement(ASTNode N) {
|
||||
// Ignore functions which aren't set up for instrumentation.
|
||||
SILProfiler *SP = F.getProfiler();
|
||||
if (!SP)
|
||||
return;
|
||||
if (!SP->hasRegionCounters() || !getModule().getOptions().UseProfile.empty())
|
||||
return;
|
||||
|
||||
auto &C = B.getASTContext();
|
||||
const auto &RegionCounterMap = SP->getRegionCounterMap();
|
||||
auto CounterIt = RegionCounterMap.find(N);
|
||||
assert(CounterIt != RegionCounterMap.end() &&
|
||||
"cannot increment non-existent counter");
|
||||
|
||||
auto Int32Ty = getLoweredType(BuiltinIntegerType::get(32, C));
|
||||
auto Int64Ty = getLoweredType(BuiltinIntegerType::get(64, C));
|
||||
|
||||
SILLocation Loc = getLocation(N);
|
||||
SILValue Args[] = {
|
||||
// The intrinsic must refer to the function profiling name var, which is
|
||||
// inaccessible during SILGen. Rely on irgen to rewrite the function name.
|
||||
B.createStringLiteral(Loc, SP->getPGOFuncName(),
|
||||
StringLiteralInst::Encoding::UTF8),
|
||||
B.createIntegerLiteral(Loc, Int64Ty, SP->getPGOFuncHash()),
|
||||
B.createIntegerLiteral(Loc, Int32Ty, SP->getNumRegionCounters()),
|
||||
B.createIntegerLiteral(Loc, Int32Ty, CounterIt->second)};
|
||||
B.createBuiltin(Loc, C.getIdentifier("int_instrprof_increment"),
|
||||
SGM.Types.getEmptyTupleType(), {}, Args);
|
||||
SP->recordCounterUpdate();
|
||||
}
|
||||
|
||||
ProfileCounter SILGenFunction::loadProfilerCount(ASTNode Node) const {
|
||||
if (SILProfiler *SP = F.getProfiler())
|
||||
return SP->getExecutionCount(Node);
|
||||
return ProfileCounter();
|
||||
}
|
||||
|
||||
Optional<ASTNode> SILGenFunction::getPGOParent(ASTNode Node) const {
|
||||
if (SILProfiler *SP = F.getProfiler())
|
||||
return SP->getPGOParent(Node);
|
||||
return None;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user