@@ -87,10 +87,6 @@ YAMLProfileWriter::convertPseudoProbeDesc(const MCPseudoProbeDecoder &Decoder) {
8787 yaml::bolt::ProfilePseudoProbeDesc Desc;
8888 InlineTreeDesc InlineTree;
8989
90- for (const MCDecodedPseudoProbeInlineTree &TopLev :
91- Decoder.getDummyInlineRoot ().getChildren ())
92- InlineTree.TopLevelGUIDToInlineTree [TopLev.Guid ] = &TopLev;
93-
9490 for (const auto &FuncDesc : Decoder.getGUID2FuncDescMap ())
9591 ++InlineTree.HashIdxMap [FuncDesc.FuncHash ];
9692
@@ -129,64 +125,80 @@ YAMLProfileWriter::convertPseudoProbeDesc(const MCPseudoProbeDecoder &Decoder) {
129125 return {Desc, InlineTree};
130126}
131127
132- std::vector<yaml::bolt::PseudoProbeInfo>
133- YAMLProfileWriter::convertNodeProbes (NodeIdToProbes &NodeProbes) {
134- struct BlockProbeInfoHasher {
135- size_t operator ()(const yaml::bolt::PseudoProbeInfo &BPI) const {
136- return llvm::hash_combine (llvm::hash_combine_range (BPI.BlockProbes ),
137- llvm::hash_combine_range (BPI.CallProbes ),
138- llvm::hash_combine_range (BPI.IndCallProbes ));
128+ void YAMLProfileWriter::BlockProbeCtx::addBlockProbe (
129+ const InlineTreeMapTy &Map, const MCDecodedPseudoProbe &Probe,
130+ uint32_t ProbeOffset) {
131+ auto It = Map.find (Probe.getInlineTreeNode ());
132+ if (It == Map.end ())
133+ return ;
134+ auto NodeId = It->second ;
135+ uint32_t Index = Probe.getIndex ();
136+ if (Probe.isCall ())
137+ CallProbes[ProbeOffset] =
138+ Call{Index, NodeId, Probe.isIndirectCall (), false };
139+ else
140+ NodeToProbes[NodeId].emplace_back (Index);
141+ }
142+
143+ void YAMLProfileWriter::BlockProbeCtx::finalize (
144+ yaml::bolt::BinaryBasicBlockProfile &YamlBB) {
145+ // Hash block probes by vector
146+ struct ProbeHasher {
147+ size_t operator ()(const ArrayRef<uint64_t > Probes) const {
148+ return llvm::hash_combine_range (Probes);
139149 }
140150 };
141151
142- // Check identical BlockProbeInfo structs and merge them
143- std::unordered_map<yaml::bolt::PseudoProbeInfo, std::vector<uint32_t >,
144- BlockProbeInfoHasher>
145- BPIToNodes;
146- for (auto &[NodeId, Probes] : NodeProbes) {
147- yaml::bolt::PseudoProbeInfo BPI;
148- BPI.BlockProbes = std::vector (Probes[0 ].begin (), Probes[0 ].end ());
149- BPI.IndCallProbes = std::vector (Probes[1 ].begin (), Probes[1 ].end ());
150- BPI.CallProbes = std::vector (Probes[2 ].begin (), Probes[2 ].end ());
151- BPIToNodes[BPI].push_back (NodeId);
152+ // Check identical block probes and merge them
153+ std::unordered_map<std::vector<uint64_t >, std::vector<uint32_t >, ProbeHasher>
154+ ProbesToNodes;
155+ for (auto &[NodeId, Probes] : NodeToProbes) {
156+ llvm::sort (Probes);
157+ ProbesToNodes[Probes].emplace_back (NodeId);
152158 }
153-
154- auto handleMask = [](const auto &Ids, auto &Vec, auto &Mask) {
155- for (auto Id : Ids)
156- if (Id > 64 )
157- Vec.emplace_back (Id);
158- else
159- Mask |= 1ull << (Id - 1 );
160- };
161-
162- // Add to YAML with merged nodes/block mask optimizations
163- std::vector<yaml::bolt::PseudoProbeInfo> YamlProbes;
164- YamlProbes.reserve (BPIToNodes.size ());
165- for (const auto &[BPI, Nodes] : BPIToNodes) {
166- auto &YamlBPI = YamlProbes.emplace_back (yaml::bolt::PseudoProbeInfo ());
167- YamlBPI.CallProbes = BPI.CallProbes ;
168- YamlBPI.IndCallProbes = BPI.IndCallProbes ;
169- if (Nodes.size () == 1 )
170- YamlBPI.InlineTreeIndex = Nodes.front ();
171- else
172- YamlBPI.InlineTreeNodes = Nodes;
173- handleMask (BPI.BlockProbes , YamlBPI.BlockProbes , YamlBPI.BlockMask );
159+ for (auto &[Probes, Nodes] : ProbesToNodes) {
160+ llvm::sort (Nodes);
161+ YamlBB.PseudoProbes .emplace_back (
162+ yaml::bolt::PseudoProbeInfo{Probes, Nodes});
163+ }
164+ for (yaml::bolt::CallSiteInfo &CSI : YamlBB.CallSites ) {
165+ auto It = CallProbes.find (CSI.Offset );
166+ if (It == CallProbes.end ())
167+ continue ;
168+ Call &Probe = It->second ;
169+ CSI.Probe = Probe.Id ;
170+ CSI.InlineTreeNode = Probe.Node ;
171+ CSI.Indirect = Probe.Indirect ;
172+ Probe.Used = true ;
173+ }
174+ for (const auto &[Offset, Probe] : CallProbes) {
175+ if (Probe.Used )
176+ continue ;
177+ yaml::bolt::CallSiteInfo CSI;
178+ CSI.Offset = Offset;
179+ CSI.Probe = Probe.Id ;
180+ CSI.InlineTreeNode = Probe.Node ;
181+ CSI.Indirect = Probe.Indirect ;
182+ YamlBB.CallSites .emplace_back (CSI);
174183 }
175- return YamlProbes;
176184}
177185
178186std::tuple<std::vector<yaml::bolt::InlineTreeNode>,
179187 YAMLProfileWriter::InlineTreeMapTy>
180188YAMLProfileWriter::convertBFInlineTree (const MCPseudoProbeDecoder &Decoder,
181189 const InlineTreeDesc &InlineTree,
182- uint64_t GUID ) {
190+ const BinaryFunction &BF ) {
183191 DenseMap<const MCDecodedPseudoProbeInlineTree *, uint32_t > InlineTreeNodeId;
184192 std::vector<yaml::bolt::InlineTreeNode> YamlInlineTree;
185- auto It = InlineTree.TopLevelGUIDToInlineTree .find (GUID);
186- if (It == InlineTree.TopLevelGUIDToInlineTree .end ())
193+ uint64_t Addr = BF.getAddress ();
194+ uint64_t Size = BF.getSize ();
195+ auto Probes = Decoder.getAddress2ProbesMap ().find (Addr, Addr + Size);
196+ if (Probes.empty ())
187197 return {YamlInlineTree, InlineTreeNodeId};
188- const MCDecodedPseudoProbeInlineTree *Root = It->second ;
189- assert (Root && " Malformed TopLevelGUIDToInlineTree" );
198+ const MCDecodedPseudoProbe &Probe = *Probes.begin ();
199+ const MCDecodedPseudoProbeInlineTree *Root = Probe.getInlineTreeNode ();
200+ while (Root->hasInlineSite ())
201+ Root = (const MCDecodedPseudoProbeInlineTree *)Root->Parent ;
190202 uint32_t Index = 0 ;
191203 uint32_t PrevParent = 0 ;
192204 uint32_t PrevGUIDIdx = 0 ;
@@ -230,7 +242,7 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
230242 DenseMap<const MCDecodedPseudoProbeInlineTree *, uint32_t > InlineTreeNodeId;
231243 if (PseudoProbeDecoder && BF.getGUID ()) {
232244 std::tie (YamlBF.InlineTree , InlineTreeNodeId) =
233- convertBFInlineTree (*PseudoProbeDecoder, InlineTree, BF. getGUID () );
245+ convertBFInlineTree (*PseudoProbeDecoder, InlineTree, BF);
234246 }
235247
236248 BinaryFunction::BasicBlockOrderType Order;
@@ -343,12 +355,13 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS,
343355 const AddressProbesMap &ProbeMap =
344356 PseudoProbeDecoder->getAddress2ProbesMap ();
345357 const uint64_t FuncAddr = BF.getAddress ();
346- const std::pair<uint64_t , uint64_t > &BlockRange =
347- BB->getInputAddressRange ();
348- const std::pair<uint64_t , uint64_t > BlockAddrRange = {
349- FuncAddr + BlockRange.first , FuncAddr + BlockRange.second };
350- auto Probes = ProbeMap.find (BlockAddrRange.first , BlockAddrRange.second );
351- YamlBB.PseudoProbes = writeBlockProbes (Probes, InlineTreeNodeId);
358+ auto [Start, End] = BB->getInputAddressRange ();
359+ Start += FuncAddr;
360+ End += FuncAddr;
361+ BlockProbeCtx Ctx;
362+ for (const MCDecodedPseudoProbe &Probe : ProbeMap.find (Start, End))
363+ Ctx.addBlockProbe (InlineTreeNodeId, Probe, Probe.getAddress () - Start);
364+ Ctx.finalize (YamlBB);
352365 }
353366
354367 YamlBF.Blocks .emplace_back (YamlBB);
0 commit comments