diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.h b/llvm/tools/llvm-profgen/ProfileGenerator.h --- a/llvm/tools/llvm-profgen/ProfileGenerator.h +++ b/llvm/tools/llvm-profgen/ProfileGenerator.h @@ -75,7 +75,7 @@ const SampleContextFrame &LeafLoc, uint64_t Count); void updateTotalSamples(); - StringRef getCalleeNameForOffset(uint64_t TargetOffset); + StringRef getCalleeNameForOffset(uint SourceOffset, uint64_t TargetOffset); // Used by SampleProfileWriter SampleProfileMap ProfileMap; diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -401,16 +401,22 @@ } } -StringRef ProfileGeneratorBase::getCalleeNameForOffset(uint64_t TargetOffset) { +StringRef ProfileGeneratorBase::getCalleeNameForOffset(uint SourceOffset, + uint64_t TargetOffset) { // Get the function range by branch target if it's a call branch. - auto *FRange = Binary->findFuncRangeForStartOffset(TargetOffset); + auto *TargetRange = Binary->findFuncRangeForStartOffset(TargetOffset); + if (!TargetRange) + return StringRef(); - // We won't accumulate sample count for a range whose start is not the real - // function entry such as outlined function or inner labels. - if (!FRange || !FRange->IsFuncEntry) + // If source and target are from the same function but different split ranges, + // we should ignore to accumulate callsite samples, this may be caused by + // function split optimizations. + auto *SourceRange = Binary->findFuncRangeForOffset(SourceOffset); + if (SourceRange && SourceRange->StartOffset != TargetRange->StartOffset && + SourceRange->Func == TargetRange->Func) return StringRef(); - return FunctionSamples::getCanonicalFnName(FRange->getFuncName()); + return FunctionSamples::getCanonicalFnName(TargetRange->getFuncName()); } void ProfileGenerator::populateBoundarySamplesForAllFunctions( @@ -421,7 +427,7 @@ uint64_t Count = Entry.second; assert(Count != 0 && "Unexpected zero weight branch"); - StringRef CalleeName = getCalleeNameForOffset(TargetOffset); + StringRef CalleeName = getCalleeNameForOffset(SourceOffset, TargetOffset); if (CalleeName.size() == 0) continue; // Record called target sample and its count. @@ -563,7 +569,7 @@ uint64_t Count = Entry.second; assert(Count != 0 && "Unexpected zero weight branch"); - StringRef CalleeName = getCalleeNameForOffset(TargetOffset); + StringRef CalleeName = getCalleeNameForOffset(SourceOffset, TargetOffset); if (CalleeName.size() == 0) continue; @@ -810,7 +816,7 @@ getFunctionProfileForLeafProbe(ContextStack, CallProbe); FunctionProfile.addBodySamples(CallProbe->getIndex(), 0, Count); FunctionProfile.addTotalSamples(Count); - StringRef CalleeName = getCalleeNameForOffset(TargetOffset); + StringRef CalleeName = getCalleeNameForOffset(SourceOffset, TargetOffset); if (CalleeName.size() == 0) continue; FunctionProfile.addCalledTargetSamples(CallProbe->getIndex(), 0, CalleeName, diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h --- a/llvm/tools/llvm-profgen/ProfiledBinary.h +++ b/llvm/tools/llvm-profgen/ProfiledBinary.h @@ -256,11 +256,6 @@ // Load debug info of subprograms from DWARF section. void loadSymbolsFromDWARF(ObjectFile &Obj); - // A function may be spilt into multiple non-continuous address ranges. We use - // this to set whether start offset of a function is the real entry of the - // function and also set false to the non-function label. - void setIsFuncEntry(uint64_t Offset, StringRef RangeSymName); - /// Dissassemble the text section and build various address maps. void disassemble(const ELFObjectFileBase *O); diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -309,20 +309,6 @@ ProbeDecoder.printGUID2FuncDescMap(outs()); } -void ProfiledBinary::setIsFuncEntry(uint64_t Offset, StringRef RangeSymName) { - // Note that the start offset of each ELF section can be a non-function - // symbol, we need to binary search for the start of a real function range. - auto *FuncRange = findFuncRangeForOffset(Offset); - // Skip external function symbol. - if (!FuncRange) - return; - - // Set IsFuncEntry to ture if the RangeSymName from ELF is equal to its - // DWARF-based function name. - if (!FuncRange->IsFuncEntry && FuncRange->getFuncName() == RangeSymName) - FuncRange->IsFuncEntry = true; -} - bool ProfiledBinary::dissassembleSymbol(std::size_t SI, ArrayRef Bytes, SectionSymbolsTy &Symbols, const SectionRef &Section) { @@ -420,8 +406,6 @@ if (ShowDisassembly) outs() << "\n"; - setIsFuncEntry(StartOffset, Symbols[SI].Name); - return true; }