@@ -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