================ @@ -155,5 +155,51 @@ std::string hashBlockLoose(BinaryContext &BC, const BinaryBasicBlock &BB) { return HashString; } +/// An even looser hash of a basic block to use with stale profile matching, +/// composed of the names of a block's called functions in lexicographic order. +std::string hashBlockCalls(BinaryContext &BC, const BinaryBasicBlock &BB) { + // The hash is computed by creating a string of all lexicographically ordered + // called function names. + std::multiset<std::string> FunctionNames; + for (const MCInst &Instr : BB) { + // Skip non-call instructions. + if (!BC.MIB->isCall(Instr)) + continue; + const MCSymbol *CallSymbol = BC.MIB->getTargetSymbol(Instr); + if (!CallSymbol) ---------------- shawbyoung wrote:
It can happen in either case - e.g. call to function pointer. In any case we don't want an assertion failure - it's not "wrong" in either case for the CallSymbol to be null. For instance, in PLTCall we're replacing calls to PLT functions with indirect calls against GOT - ignoring call instructions with null CallSymbols shouldn't impact the pass' correctness. Similarly when computing CallHashes (meant to be a looser hash than opcode hash), ignoring call instructions with null CallSymbols won't impact correctness. https://github.com/llvm/llvm-project/pull/96596 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits