Skip to content

Commit

Permalink
[ctx_prof] Handle case when no root is in this Module. (#107463)
Browse files Browse the repository at this point in the history
If none of the functions in this `Module` are roots in the contextual profile, we can't use it and should just return the `{}` case.
  • Loading branch information
mtrofin authored Sep 6, 2024
1 parent 787cd8f commit 6cb2d40
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 4 deletions.
21 changes: 17 additions & 4 deletions llvm/lib/Analysis/CtxProfAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
return {};
}

DenseSet<GlobalValue::GUID> ProfileRootsInModule;
for (const auto &F : M)
if (!F.isDeclaration())
if (auto GUID = AssignGUIDPass::getGUID(F);
MaybeCtx->find(GUID) != MaybeCtx->end())
ProfileRootsInModule.insert(GUID);

// Trim first the roots that aren't in this module.
for (auto &[RootGuid, _] : llvm::make_early_inc_range(*MaybeCtx))
if (!ProfileRootsInModule.contains(RootGuid))
MaybeCtx->erase(RootGuid);
// If none of the roots are in the module, we have no profile (for this
// module)
if (MaybeCtx->empty())
return {};

// OK, so we have a valid profile and it's applicable to roots in this module.
PGOContextualProfile Result;

for (const auto &F : M) {
Expand Down Expand Up @@ -166,10 +183,6 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
}
// If we made it this far, the Result is valid - which we mark by setting
// .Profiles.
// Trim first the roots that aren't in this module.
for (auto &[RootGuid, _] : llvm::make_early_inc_range(*MaybeCtx))
if (!Result.FuncInfo.contains(RootGuid))
MaybeCtx->erase(RootGuid);
Result.Profiles = std::move(*MaybeCtx);
return Result;
}
Expand Down
63 changes: 63 additions & 0 deletions llvm/test/Analysis/CtxProfAnalysis/load-unapplicable.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
; REQUIRES: x86_64-linux
;
; Check that, if none of the roots in the profile are defined in the module, the
; profile is treated as empty (i.e. "none provided")
;
; RUN: rm -rf %t
; RUN: split-file %s %t
; RUN: llvm-ctxprof-util fromJSON --input=%t/profile.json --output=%t/profile.ctxprofdata
; RUN: opt -passes='require<ctx-prof-analysis>,print<ctx-prof-analysis>' -ctx-profile-printer-level=everything \
; RUN: %t/example.ll -S 2>&1 | FileCheck %s

; CHECK: No contextual profile was provided
;
; This is the reference profile, laid out in the format the json formatter will
; output it from opt.
;--- profile.json
[
{
"Counters": [
9
],
"Guid": 12341
},
{
"Counters": [
5
],
"Guid": 12074870348631550642
},
{
"Callsites": [
[
{
"Counters": [
6,
7
],
"Guid": 728453322856651412
}
]
],
"Counters": [
1
],
"Guid": 11872291593386833696
}
]
;--- example.ll
declare void @bar()

define void @an_entrypoint(i32 %a) !guid !0 {
%t = icmp eq i32 %a, 0
br i1 %t, label %yes, label %no

yes:
call void @bar()
ret void
no:
ret void
}

attributes #0 = { noinline }
!0 = !{ i64 1000 }

0 comments on commit 6cb2d40

Please sign in to comment.