@@ -621,17 +621,23 @@ CtxProfAnalysis::getSelectInstrumentation(SelectInst &SI) {
621621 return nullptr ;
622622}
623623
624- template <class ProfilesTy , class ProfTy >
625- static void preorderVisit (ProfilesTy &Profiles ,
626- function_ref<void (ProfTy &)> Visitor) {
624+ template <class ProfTy >
625+ static void preorderVisitOneRoot (ProfTy &Profile ,
626+ function_ref<void (ProfTy &)> Visitor) {
627627 std::function<void (ProfTy &)> Traverser = [&](auto &Ctx) {
628628 Visitor (Ctx);
629629 for (auto &[_, SubCtxSet] : Ctx.callsites ())
630630 for (auto &[__, Subctx] : SubCtxSet)
631631 Traverser (Subctx);
632632 };
633+ Traverser (Profile);
634+ }
635+
636+ template <class ProfilesTy , class ProfTy >
637+ static void preorderVisit (ProfilesTy &Profiles,
638+ function_ref<void (ProfTy &)> Visitor) {
633639 for (auto &[_, P] : Profiles)
634- Traverser (P );
640+ preorderVisitOneRoot<ProfTy>(P, Visitor );
635641}
636642
637643void PGOContextualProfile::initIndex () {
@@ -683,40 +689,46 @@ void PGOContextualProfile::visit(ConstVisitor V, const Function *F) const {
683689const CtxProfFlatProfile PGOContextualProfile::flatten () const {
684690 CtxProfFlatProfile Flat;
685691 auto Accummulate = [](SmallVectorImpl<uint64_t > &Into,
686- const SmallVectorImpl<uint64_t > &From) {
692+ const SmallVectorImpl<uint64_t > &From,
693+ uint64_t SamplingRate) {
687694 if (Into.empty ())
688695 Into.resize (From.size ());
689696 assert (Into.size () == From.size () &&
690697 " All contexts corresponding to a function should have the exact "
691698 " same number of counters." );
692699 for (size_t I = 0 , E = Into.size (); I < E; ++I)
693- Into[I] += From[I];
700+ Into[I] += From[I] * SamplingRate ;
694701 };
695702
696- preorderVisit<const PGOCtxProfContext::CallTargetMapTy,
697- const PGOCtxProfContext>(
698- Profiles.Contexts , [&](const PGOCtxProfContext &Ctx) {
699- Accummulate (Flat[Ctx.guid ()], Ctx.counters ());
700- });
701- for (const auto &[_, RC] : Profiles.Contexts )
702- for (const auto &[G, Unh] : RC.getUnhandled ())
703- Accummulate (Flat[G], Unh);
703+ for (const auto &[_, CtxRoot] : Profiles.Contexts ) {
704+ const uint64_t SamplingFactor = CtxRoot.getTotalRootEntryCount ();
705+ preorderVisitOneRoot<const PGOCtxProfContext>(
706+ CtxRoot, [&](const PGOCtxProfContext &Ctx) {
707+ Accummulate (Flat[Ctx.guid ()], Ctx.counters (), SamplingFactor);
708+ });
709+
710+ for (const auto &[G, Unh] : CtxRoot.getUnhandled ())
711+ Accummulate (Flat[G], Unh, SamplingFactor);
712+ }
704713 for (const auto &[G, FC] : Profiles.FlatProfiles )
705- Accummulate (Flat[G], FC);
714+ Accummulate (Flat[G], FC, /* SamplingRate= */ 1 );
706715 return Flat;
707716}
708717
709718const CtxProfFlatIndirectCallProfile
710719PGOContextualProfile::flattenVirtCalls () const {
711720 CtxProfFlatIndirectCallProfile Ret;
712- preorderVisit<const PGOCtxProfContext::CallTargetMapTy,
713- const PGOCtxProfContext>(
714- Profiles.Contexts , [&](const PGOCtxProfContext &Ctx) {
715- auto &Targets = Ret[Ctx.guid ()];
716- for (const auto &[ID, SubctxSet] : Ctx.callsites ())
717- for (const auto &Subctx : SubctxSet)
718- Targets[ID][Subctx.first ] += Subctx.second .getEntrycount ();
719- });
721+ for (const auto &[_, CtxRoot] : Profiles.Contexts ) {
722+ const uint64_t TotalRootEntryCount = CtxRoot.getTotalRootEntryCount ();
723+ preorderVisitOneRoot<const PGOCtxProfContext>(
724+ CtxRoot, [&](const PGOCtxProfContext &Ctx) {
725+ auto &Targets = Ret[Ctx.guid ()];
726+ for (const auto &[ID, SubctxSet] : Ctx.callsites ())
727+ for (const auto &Subctx : SubctxSet)
728+ Targets[ID][Subctx.first ] +=
729+ Subctx.second .getEntrycount () * TotalRootEntryCount;
730+ });
731+ }
720732 return Ret;
721733}
722734
0 commit comments