@@ -45,9 +45,6 @@ class YAMLProfileReader : public ProfileReaderBase {
4545 using ProfileLookupMap =
4646 DenseMap<uint32_t , yaml::bolt::BinaryFunctionProfile *>;
4747
48- using GUIDInlineTreeMap =
49- std::unordered_map<uint64_t , const MCDecodedPseudoProbeInlineTree *>;
50-
5148 // / A class for matching binary functions in functions in the YAML profile.
5249 // / First, a call graph is constructed for both profiled and binary functions.
5350 // / Then functions are hashed based on the names of their callee/caller
@@ -110,51 +107,40 @@ class YAMLProfileReader : public ProfileReaderBase {
110107 // (profile) (binary)
111108 // | blocks ^
112109 // v |
113- // yaml::bolt:: BinaryBasicBlockProfile ~= FlowBlock
114- // ||| probes ^ (majority vote)
115- // v ||| BBPseudoProbeToBlock
116- // yaml::bolt:: PseudoProbeInfo MCDecodedPseudoProbe
110+ // BinaryBasicBlockProfile BasicBlock
111+ // | probes ^
112+ // v | address
113+ // PseudoProbeInfo MCDecodedPseudoProbe
117114 // | InlineTreeIndex ^
118115 // v | probe id
119116 // [ profile node id (uint32_t) -> MCDecodedPseudoProbeInlineTree *]
120117 // InlineTreeNodeMapTy
121- class InlineTreeNodeMapTy {
122- DenseMap<uint32_t , const MCDecodedPseudoProbeInlineTree *> Map;
123-
124- void mapInlineTreeNode (uint32_t ProfileNodeIdx,
125- const MCDecodedPseudoProbeInlineTree *BinaryNode) {
126- auto Res = Map.try_emplace (ProfileNodeIdx, BinaryNode);
127- assert (Res.second &&
128- " Duplicate mapping from profile node index to binary inline tree" );
129- (void )Res;
130- }
131-
132- public:
133- // / Returns matched InlineTree * for a given profile inline_tree_id.
134- const MCDecodedPseudoProbeInlineTree *
135- getInlineTreeNode (uint32_t ProfileInlineTreeNodeId) const {
136- auto It = Map.find (ProfileInlineTreeNodeId);
137- if (It == Map.end ())
138- return nullptr ;
139- return It->second ;
140- }
118+ using InlineTreeNodeMapTy =
119+ std::vector<const MCDecodedPseudoProbeInlineTree *>;
141120
142- // Match up \p YamlInlineTree with binary inline tree rooted at \p Root.
143- // Return the number of matched nodes.
144- //
145- // This function populates the mapping from profile inline tree node id to a
146- // corresponding binary MCDecodedPseudoProbeInlineTree node.
147- size_t matchInlineTrees (
148- const MCPseudoProbeDecoder &Decoder,
149- const std::vector<yaml::bolt::InlineTreeNode> &YamlInlineTree,
150- const MCDecodedPseudoProbeInlineTree *Root);
151- };
152-
153- // Partial probe matching specification: matched inline tree and corresponding
154- // BinaryFunctionProfile
121+ // Match up \p YamlInlineTree with binary inline tree rooted at \p Root.
122+ // Return the number of matched nodes.
123+ //
124+ // This function populates the \p Map indexed by \p YamlInlineTree from
125+ // profile inline tree node id to a corresponding binary
126+ // MCDecodedPseudoProbeInlineTree node on a successful match or nullptr.
127+ size_t matchInlineTreesImpl (
128+ BinaryFunction &BF, yaml::bolt::BinaryFunctionProfile &YamlBF,
129+ const MCDecodedPseudoProbeInlineTree &Root, uint32_t RootIdx,
130+ ArrayRef<yaml::bolt::InlineTreeNode> YamlInlineTree,
131+ MutableArrayRef<const MCDecodedPseudoProbeInlineTree *> Map, float Scale);
132+
133+ // / Support mapping the profile to the same binary function more than once.
134+ // / The index is used to check and prevent recursive (backtracking) matches.
135+ // / The value is a node map and scale factor, used to downscale outlined
136+ // / profile when inlining it into the function.
137+ using RootIdxToMapTy =
138+ std::map<uint32_t , std::pair<InlineTreeNodeMapTy, float >>;
139+ // / Probe matching specification: map from \p BinaryFunctionProfile to the
140+ // / partial match specification \p RootIdxToMapTy.
155141 using ProbeMatchSpec =
156- std::pair<InlineTreeNodeMapTy ,
157- std::reference_wrapper<yaml::bolt::BinaryFunctionProfile> >;
142+ std::unordered_map< const yaml::bolt::BinaryFunctionProfile * ,
143+ RootIdxToMapTy >;
158144
159145private:
160146 // / Adjustments for basic samples profiles (without LBR).
@@ -183,18 +169,43 @@ class YAMLProfileReader : public ProfileReaderBase {
183169 // / Map a common LTO prefix to a set of binary functions.
184170 StringMap<std::unordered_set<BinaryFunction *>> LTOCommonNameFunctionMap;
185171
172+ // / For pseudo probe function matching.
173+ // / Set of profile GUIDs.
174+ std::unordered_set<uint64_t > YamlGUIDs;
175+ // / Map binary function GUID to binary function.
176+ std::unordered_multimap<uint64_t , BinaryFunction *> GUIDToBF;
177+
186178 // / Function names in profile.
187179 StringSet<> ProfileFunctionNames;
188180
189181 // / BinaryFunction pointers indexed by YamlBP functions.
190182 std::vector<BinaryFunction *> ProfileBFs;
191183
192- // Pseudo probe function GUID to inline tree node
193- GUIDInlineTreeMap TopLevelGUIDToInlineTree;
194-
195184 // Mapping from a binary function to its partial match specification
196185 // (YAML profile and its inline tree mapping to binary).
197- DenseMap<BinaryFunction *, std::vector<ProbeMatchSpec>> BFToProbeMatchSpecs;
186+ DenseMap<BinaryFunction *, ProbeMatchSpec> BFToProbeMatchSpecs;
187+
188+ // / Pseudo probe matching stats.
189+ struct {
190+ // Inline tree root mismatch causes.
191+ uint64_t MismatchingRootGUID{0 };
192+ uint64_t MismatchingRootHash{0 };
193+ // Inline tree internal node mismatch causes.
194+ uint64_t MismatchingNodeHash{0 };
195+ uint64_t MissingProfileNode{0 };
196+ // Incomplete profile causes.
197+ uint64_t MissingCallProbe{0 };
198+ uint64_t MissingCallee{0 };
199+ uint64_t MissingInlineTree{0 };
200+ uint64_t TotalCallSites{0 };
201+ uint64_t MissingCallCount{0 };
202+ uint64_t TotalCallCount{0 };
203+ // Total matched stats.
204+ uint64_t MatchedRoots{0 };
205+ uint64_t MatchedNodes{0 };
206+ uint64_t AttemptedNodes{0 };
207+ uint64_t AttemptedRoots{0 };
208+ } ProbeMatchingStats;
198209
199210 // / Populate \p Function profile with the one supplied in YAML format.
200211 bool parseFunctionProfile (BinaryFunction &Function,
@@ -207,7 +218,7 @@ class YAMLProfileReader : public ProfileReaderBase {
207218 // / Infer function profile from stale data (collected on older binaries).
208219 bool inferStaleProfile (BinaryFunction &Function,
209220 const yaml::bolt::BinaryFunctionProfile &YamlBF,
210- const ArrayRef< ProbeMatchSpec> ProbeMatchSpecs);
221+ const ProbeMatchSpec & ProbeMatchSpecs);
211222
212223 // / Initialize maps for profile matching.
213224 void buildNameMaps (BinaryContext &BC);
@@ -242,6 +253,18 @@ class YAMLProfileReader : public ProfileReaderBase {
242253 ProfiledFunctions.emplace (&BF);
243254 }
244255
256+ // / Return a top-level binary inline tree node for a given \p BF
257+ const MCDecodedPseudoProbeInlineTree *
258+ lookupTopLevelNode (const BinaryFunction &BF);
259+
260+ // / Match up \p BF binary inline trees starting at root or \p Node if set, and
261+ // / \p YamlBF profile starting at \p NodeIdx and record the mapping in
262+ // / BFToProbeMatchSpecs.
263+ void matchInlineTrees (BinaryFunction &BF,
264+ const MCDecodedPseudoProbeInlineTree *Node,
265+ yaml::bolt::BinaryFunctionProfile &YamlBF,
266+ uint32_t NodeIdx, float Scale);
267+
245268 // / Check if the profile uses an event with a given \p Name.
246269 bool usesEvent (StringRef Name) const ;
247270};
0 commit comments