diff --git a/llvm/test/tools/llvm-profgen/inline-force-dwarf.test b/llvm/test/tools/llvm-profgen/inline-force-dwarf.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-profgen/inline-force-dwarf.test @@ -0,0 +1,38 @@ +; RUN: llvm-profgen --format=text --ignore-stack-samples --use-dwarf-correlation --perfscript=%S/Inputs/inline-cs-pseudoprobe.perfscript --binary=%S/Inputs/inline-cs-pseudoprobe.perfbin --output=%t --profile-summary-cold-count=0 +; RUN: FileCheck %s --input-file %t + +; CHECK: main:295:0 +; CHECK-NEXT: 0: 0 +; CHECK-NEXT: 2: 0 +; CHECK-NEXT: 1: foo:295 +; CHECK-NEXT: 2: 14 +; CHECK-NEXT: 3: 15 +; CHECK-NEXT: 4: 0 +; CHECK-NEXT: 3: bar:84 +; CHECK-NEXT: 1: 14 + + +; clang -O3 -fexperimental-new-pass-manager -fuse-ld=lld -fpseudo-probe-for-profiling +; -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -Xclang -mdisable-tail-calls +; -g test.c -o a.out + +#include + +int bar(int x, int y) { + if (x % 3) { + return x - y; + } + return x + y; +} + +void foo() { + int s, i = 0; + while (i++ < 4000 * 4000) + if (i % 91) s = bar(i, s); else s += 30; + printf("sum is %d\n", s); +} + +int main() { + foo(); + return 0; +} diff --git a/llvm/test/tools/llvm-profgen/inline-noprobe.test b/llvm/test/tools/llvm-profgen/inline-noprobe.test --- a/llvm/test/tools/llvm-profgen/inline-noprobe.test +++ b/llvm/test/tools/llvm-profgen/inline-noprobe.test @@ -1,7 +1,11 @@ ; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/inline-noprobe.perfscript --binary=%S/Inputs/inline-noprobe.perfbin --output=%t --skip-symbolization ; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-RAW-PROFILE +; RUN: llvm-profgen --format=text --use-dwarf-correlation --perfscript=%S/Inputs/inline-noprobe.perfscript --binary=%S/Inputs/inline-noprobe.perfbin --output=%t --skip-symbolization +; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-RAW-PROFILE ; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/inline-noprobe.perfscript --binary=%S/Inputs/inline-noprobe.perfbin --output=%t ; RUN: FileCheck %s --input-file %t --check-prefix=CHECK +; RUN: llvm-profgen --format=text --use-dwarf-correlation --perfscript=%S/Inputs/inline-noprobe.perfscript --binary=%S/Inputs/inline-noprobe.perfbin --output=%t +; RUN: FileCheck %s --input-file %t --check-prefix=CHECK CHECK: main:669:0 CHECK: 0: 0 diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -12,22 +12,22 @@ #define DEBUG_TYPE "perf-reader" -static cl::opt ShowMmapEvents("show-mmap-events", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, - cl::desc("Print binary load events.")); - -cl::opt SkipSymbolization("skip-symbolization", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, +cl::opt SkipSymbolization("skip-symbolization", cl::init(false), + cl::ZeroOrMore, cl::desc("Dump the unsymbolized profile to the " "output file. It will show unwinder " "output for CS profile generation.")); -cl::opt UseOffset("use-offset", cl::ReallyHidden, cl::init(true), - cl::ZeroOrMore, - cl::desc("Work with `--skip-symbolization` to dump the " - "offset instead of virtual address.")); -cl::opt - IgnoreStackSamples("ignore-stack-samples", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, + +static cl::opt ShowMmapEvents("show-mmap-events", cl::init(false), + cl::ZeroOrMore, + cl::desc("Print binary load events.")); + +static cl::opt + UseOffset("use-offset", cl::init(true), cl::ZeroOrMore, + cl::desc("Work with `--skip-symbolization` to dump the " + "offset instead of virtual address.")); +static cl::opt + IgnoreStackSamples("ignore-stack-samples", cl::init(false), cl::ZeroOrMore, cl::desc("Ignore call stack samples for hybrid samples " "and produce context-insensitive profile.")); 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 @@ -22,22 +22,27 @@ using namespace llvm; using namespace sampleprof; -cl::opt ShowDisassemblyOnly("show-disassembly-only", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, +cl::opt ShowDisassemblyOnly("show-disassembly-only", cl::init(false), + cl::ZeroOrMore, cl::desc("Print disassembled code.")); -cl::opt ShowSourceLocations("show-source-locations", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, +cl::opt ShowSourceLocations("show-source-locations", cl::init(false), + cl::ZeroOrMore, cl::desc("Print source locations.")); -cl::opt ShowCanonicalFnName("show-canonical-fname", cl::ReallyHidden, - cl::init(false), cl::ZeroOrMore, - cl::desc("Print canonical function name.")); +static cl::opt + ShowCanonicalFnName("show-canonical-fname", cl::init(false), cl::ZeroOrMore, + cl::desc("Print canonical function name.")); -cl::opt ShowPseudoProbe( - "show-pseudo-probe", cl::ReallyHidden, cl::init(false), cl::ZeroOrMore, +static cl::opt ShowPseudoProbe( + "show-pseudo-probe", cl::init(false), cl::ZeroOrMore, cl::desc("Print pseudo probe section and disassembled info.")); +static cl::opt UseDwarfCorrelation( + "use-dwarf-correlation", cl::init(false), cl::ZeroOrMore, + cl::desc("Use dwarf for profile correlation even when binary contains " + "pseudo probe.")); + static cl::list DisassembleFunctions( "disassemble-functions", cl::CommaSeparated, cl::desc("List of functions to print disassembly for. Accept demangled " @@ -271,6 +276,9 @@ } void ProfiledBinary::decodePseudoProbe(const ELFObjectFileBase *Obj) { + if (UseDwarfCorrelation) + return; + StringRef FileName = Obj->getFileName(); for (section_iterator SI = Obj->section_begin(), SE = Obj->section_end(); SI != SE; ++SI) {