@@ -129,50 +129,62 @@ YAMLProfileWriter::convertPseudoProbeDesc(const MCPseudoProbeDecoder &Decoder) {
129129  return  {Desc, InlineTree};
130130}
131131
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 ));
132+ void  YAMLProfileWriter::BlockProbeCtx::addBlockProbe (
133+     const  InlineTreeMapTy &Map, const  MCDecodedPseudoProbe &Probe,
134+     uint32_t  ProbeOffset) {
135+   auto  It = Map.find (Probe.getInlineTreeNode ());
136+   if  (It == Map.end ())
137+     return ;
138+   auto  NodeId = It->second ;
139+   uint32_t  Index = Probe.getIndex ();
140+   if  (Probe.isCall ())
141+     CallProbes[ProbeOffset] =
142+         Call{Index, NodeId, Probe.isIndirectCall (), false };
143+   else 
144+     NodeToProbes[NodeId].emplace_back (Index);
145+ }
146+ 
147+ void  YAMLProfileWriter::BlockProbeCtx::finalize (
148+     yaml::bolt::BinaryBasicBlockProfile &YamlBB) {
149+   //  Hash block probes by vector
150+   struct  ProbeHasher  {
151+     size_t  operator ()(const  ArrayRef<uint64_t > Probes) const  {
152+       return  llvm::hash_combine_range (Probes);
139153    }
140154  };
141155
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);
156+   //  Check identical block probes and merge them
157+   std::unordered_map<std::vector<uint64_t >, std::vector<uint32_t >, ProbeHasher>
158+       ProbesToNodes;
159+   for  (auto  &[NodeId, Probes] : NodeToProbes) {
160+     llvm::sort (Probes);
161+     ProbesToNodes[Probes].emplace_back (NodeId);
152162  }
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 );
163+   for  (auto  &[Probes, Nodes] : ProbesToNodes) {
164+     llvm::sort (Nodes);
165+     YamlBB.PseudoProbes .emplace_back (
166+         yaml::bolt::PseudoProbeInfo{Probes, Nodes});
167+   }
168+   for  (yaml::bolt::CallSiteInfo &CSI : YamlBB.CallSites ) {
169+     auto  It = CallProbes.find (CSI.Offset );
170+     if  (It == CallProbes.end ())
171+       continue ;
172+     Call &Probe = It->second ;
173+     CSI.Probe  = Probe.Id ;
174+     CSI.InlineTreeNode  = Probe.Node ;
175+     CSI.Indirect  = Probe.Indirect ;
176+     Probe.Used  = true ;
177+   }
178+   for  (const  auto  &[Offset, Probe] : CallProbes) {
179+     if  (Probe.Used )
180+       continue ;
181+     yaml::bolt::CallSiteInfo CSI;
182+     CSI.Offset  = Offset;
183+     CSI.Probe  = Probe.Id ;
184+     CSI.InlineTreeNode  = Probe.Node ;
185+     CSI.Indirect  = Probe.Indirect ;
186+     YamlBB.CallSites .emplace_back (CSI);
174187  }
175-   return  YamlProbes;
176188}
177189
178190std::tuple<std::vector<yaml::bolt::InlineTreeNode>,
@@ -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