@@ -725,8 +725,7 @@ static uint64_t computeStackId(const memprof::Frame &Frame) {
725725
726726// Helper to generate a single hash id for a given callstack, used for emitting
727727// matching statistics and useful for uniquing such statistics across modules.
728- static uint64_t
729- computeFullStackId (const std::vector<memprof::Frame> &CallStack) {
728+ static uint64_t computeFullStackId (ArrayRef<Frame> CallStack) {
730729 llvm::HashBuilder<llvm::TruncatedBLAKE3<8 >, llvm::endianness::little>
731730 HashBuilder;
732731 for (auto &F : CallStack)
@@ -968,20 +967,16 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
968967 // Build maps of the location hash to all profile data with that leaf location
969968 // (allocation info and the callsites).
970969 std::map<uint64_t , std::set<const AllocationInfo *>> LocHashToAllocInfo;
971- // A thin wrapper around ArrayRef<Frame> to facilitate std::set<CallStackRef>.
972- struct CallStackRef : public ArrayRef <Frame> {
973- CallStackRef (ArrayRef<Frame> CS, unsigned Pos)
974- : ArrayRef<Frame>(CS.drop_front(Pos)) {}
975- // std::set requires std::less.
976- bool operator <(const CallStackRef &R) const {
977- const CallStackRef &L = *this ;
978- return std::make_pair (L.data (), L.size ()) <
979- std::make_pair (R.data (), R.size ());
970+ // A hash function for std::unordered_set<ArrayRef<Frame>> to work.
971+ struct CallStackHash {
972+ size_t operator ()(ArrayRef<Frame> CS) const {
973+ return computeFullStackId (CS);
980974 }
981975 };
982976 // For the callsites we need to record slices of the frame array (see comments
983977 // below where the map entries are added).
984- std::map<uint64_t , std::set<CallStackRef>> LocHashToCallSites;
978+ std::map<uint64_t , std::unordered_set<ArrayRef<Frame>, CallStackHash>>
979+ LocHashToCallSites;
985980 for (auto &AI : MemProfRec->AllocSites ) {
986981 NumOfMemProfAllocContextProfiles++;
987982 // Associate the allocation info with the leaf frame. The later matching
@@ -998,7 +993,8 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
998993 unsigned Idx = 0 ;
999994 for (auto &StackFrame : CS) {
1000995 uint64_t StackId = computeStackId (StackFrame);
1001- LocHashToCallSites[StackId].emplace (CS, Idx++);
996+ LocHashToCallSites[StackId].insert (
997+ ArrayRef<Frame>(CS).drop_front (Idx++));
1002998 ProfileHasColumns |= StackFrame.Column ;
1003999 // Once we find this function, we can stop recording.
10041000 if (StackFrame.Function == FuncGUID)
@@ -1038,7 +1034,7 @@ readMemprof(Module &M, Function &F, IndexedInstrProfReader *MemProfReader,
10381034 // and another callsite).
10391035 std::map<uint64_t , std::set<const AllocationInfo *>>::iterator
10401036 AllocInfoIter;
1041- std::map< uint64_t , std::set<CallStackRef>> ::iterator CallSitesIter;
1037+ decltype (LocHashToCallSites) ::iterator CallSitesIter;
10421038 for (const DILocation *DIL = I.getDebugLoc (); DIL != nullptr ;
10431039 DIL = DIL->getInlinedAt ()) {
10441040 // Use C++ linkage name if possible. Need to compile with
0 commit comments