1c572e92cSDiego Novillo //=-- SampleProf.cpp - Sample profiling format support --------------------===// 2c572e92cSDiego Novillo // 3c572e92cSDiego Novillo // The LLVM Compiler Infrastructure 4c572e92cSDiego Novillo // 5c572e92cSDiego Novillo // This file is distributed under the University of Illinois Open Source 6c572e92cSDiego Novillo // License. See LICENSE.TXT for details. 7c572e92cSDiego Novillo // 8c572e92cSDiego Novillo //===----------------------------------------------------------------------===// 9c572e92cSDiego Novillo // 10c572e92cSDiego Novillo // This file contains common definitions used in the reading and writing of 11c572e92cSDiego Novillo // sample profile data. 12c572e92cSDiego Novillo // 13c572e92cSDiego Novillo //===----------------------------------------------------------------------===// 14c572e92cSDiego Novillo 15c572e92cSDiego Novillo #include "llvm/ProfileData/SampleProf.h" 16c572e92cSDiego Novillo #include "llvm/Support/ErrorHandling.h" 17c572e92cSDiego Novillo #include "llvm/Support/ManagedStatic.h" 18c572e92cSDiego Novillo 194b6bdb53SDiego Novillo using namespace llvm::sampleprof; 20c572e92cSDiego Novillo using namespace llvm; 21c572e92cSDiego Novillo 22c572e92cSDiego Novillo namespace { 23c572e92cSDiego Novillo class SampleProfErrorCategoryType : public std::error_category { 24c572e92cSDiego Novillo const char *name() const LLVM_NOEXCEPT override { return "llvm.sampleprof"; } 25c572e92cSDiego Novillo std::string message(int IE) const override { 26c572e92cSDiego Novillo sampleprof_error E = static_cast<sampleprof_error>(IE); 27c572e92cSDiego Novillo switch (E) { 28c572e92cSDiego Novillo case sampleprof_error::success: 29c572e92cSDiego Novillo return "Success"; 30c572e92cSDiego Novillo case sampleprof_error::bad_magic: 314f823667SNathan Slingerland return "Invalid sample profile data (bad magic)"; 32c572e92cSDiego Novillo case sampleprof_error::unsupported_version: 334f823667SNathan Slingerland return "Unsupported sample profile format version"; 34c572e92cSDiego Novillo case sampleprof_error::too_large: 35c572e92cSDiego Novillo return "Too much profile data"; 36c572e92cSDiego Novillo case sampleprof_error::truncated: 37c572e92cSDiego Novillo return "Truncated profile data"; 38c572e92cSDiego Novillo case sampleprof_error::malformed: 394f823667SNathan Slingerland return "Malformed sample profile data"; 40d5336ae2SDiego Novillo case sampleprof_error::unrecognized_format: 414f823667SNathan Slingerland return "Unrecognized sample profile encoding format"; 42760c5a8fSDiego Novillo case sampleprof_error::unsupported_writing_format: 43760c5a8fSDiego Novillo return "Profile encoding format unsupported for writing operations"; 44760c5a8fSDiego Novillo case sampleprof_error::truncated_name_table: 45760c5a8fSDiego Novillo return "Truncated function name table"; 463376a787SDiego Novillo case sampleprof_error::not_implemented: 473376a787SDiego Novillo return "Unimplemented feature"; 48*48dd080cSNathan Slingerland case sampleprof_error::counter_overflow: 49*48dd080cSNathan Slingerland return "Counter overflow"; 50c572e92cSDiego Novillo } 51c572e92cSDiego Novillo llvm_unreachable("A value of sampleprof_error has no message."); 52c572e92cSDiego Novillo } 53c572e92cSDiego Novillo }; 54f00654e3SAlexander Kornienko } 55c572e92cSDiego Novillo 56c572e92cSDiego Novillo static ManagedStatic<SampleProfErrorCategoryType> ErrorCategory; 57c572e92cSDiego Novillo 58c572e92cSDiego Novillo const std::error_category &llvm::sampleprof_category() { 59c572e92cSDiego Novillo return *ErrorCategory; 60c572e92cSDiego Novillo } 614b6bdb53SDiego Novillo 62ba920be4SDiego Novillo void LineLocation::print(raw_ostream &OS) const { 63ba920be4SDiego Novillo OS << LineOffset; 64ba920be4SDiego Novillo if (Discriminator > 0) 65ba920be4SDiego Novillo OS << "." << Discriminator; 66ba920be4SDiego Novillo } 67ba920be4SDiego Novillo 68ba920be4SDiego Novillo raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, 69ba920be4SDiego Novillo const LineLocation &Loc) { 70ba920be4SDiego Novillo Loc.print(OS); 71ba920be4SDiego Novillo return OS; 72ba920be4SDiego Novillo } 73ba920be4SDiego Novillo 74ba920be4SDiego Novillo void LineLocation::dump() const { print(dbgs()); } 75ba920be4SDiego Novillo 76ba920be4SDiego Novillo void CallsiteLocation::print(raw_ostream &OS) const { 77ba920be4SDiego Novillo LineLocation::print(OS); 78ba920be4SDiego Novillo OS << ": inlined callee: " << CalleeName; 79ba920be4SDiego Novillo } 80ba920be4SDiego Novillo 81ba920be4SDiego Novillo void CallsiteLocation::dump() const { print(dbgs()); } 82ba920be4SDiego Novillo 83ba920be4SDiego Novillo inline raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, 84ba920be4SDiego Novillo const CallsiteLocation &Loc) { 85ba920be4SDiego Novillo Loc.print(OS); 86ba920be4SDiego Novillo return OS; 87ba920be4SDiego Novillo } 88ba920be4SDiego Novillo 898e415a82SDiego Novillo /// \brief Print the sample record to the stream \p OS indented by \p Indent. 908e415a82SDiego Novillo void SampleRecord::print(raw_ostream &OS, unsigned Indent) const { 918e415a82SDiego Novillo OS << NumSamples; 928e415a82SDiego Novillo if (hasCalls()) { 934b6bdb53SDiego Novillo OS << ", calls:"; 948e415a82SDiego Novillo for (const auto &I : getCallTargets()) 954b6bdb53SDiego Novillo OS << " " << I.first() << ":" << I.second; 964b6bdb53SDiego Novillo } 974b6bdb53SDiego Novillo OS << "\n"; 984b6bdb53SDiego Novillo } 998e415a82SDiego Novillo 100ba920be4SDiego Novillo void SampleRecord::dump() const { print(dbgs(), 0); } 101ba920be4SDiego Novillo 102ba920be4SDiego Novillo raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, 103ba920be4SDiego Novillo const SampleRecord &Sample) { 104ba920be4SDiego Novillo Sample.print(OS, 0); 105ba920be4SDiego Novillo return OS; 106ba920be4SDiego Novillo } 107ba920be4SDiego Novillo 1088e415a82SDiego Novillo /// \brief Print the samples collected for a function on stream \p OS. 1098e415a82SDiego Novillo void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const { 1108e415a82SDiego Novillo OS << TotalSamples << ", " << TotalHeadSamples << ", " << BodySamples.size() 1118e415a82SDiego Novillo << " sampled lines\n"; 1128e415a82SDiego Novillo 113379cc5e7SDiego Novillo OS.indent(Indent); 114379cc5e7SDiego Novillo if (BodySamples.size() > 0) { 115379cc5e7SDiego Novillo OS << "Samples collected in the function's body {\n"; 116ef548d29SDiego Novillo SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples); 117ef548d29SDiego Novillo for (const auto &SI : SortedBodySamples.get()) { 118379cc5e7SDiego Novillo OS.indent(Indent + 2); 119ef548d29SDiego Novillo OS << SI->first << ": " << SI->second; 1208e415a82SDiego Novillo } 121379cc5e7SDiego Novillo OS.indent(Indent); 122379cc5e7SDiego Novillo OS << "}\n"; 123379cc5e7SDiego Novillo } else { 124379cc5e7SDiego Novillo OS << "No samples collected in the function's body\n"; 125379cc5e7SDiego Novillo } 1268e415a82SDiego Novillo 127379cc5e7SDiego Novillo OS.indent(Indent); 128379cc5e7SDiego Novillo if (CallsiteSamples.size() > 0) { 129379cc5e7SDiego Novillo OS << "Samples collected in inlined callsites {\n"; 130ef548d29SDiego Novillo SampleSorter<CallsiteLocation, FunctionSamples> SortedCallsiteSamples( 131ef548d29SDiego Novillo CallsiteSamples); 132ef548d29SDiego Novillo for (const auto &CS : SortedCallsiteSamples.get()) { 133379cc5e7SDiego Novillo OS.indent(Indent + 2); 134ef548d29SDiego Novillo OS << CS->first << ": "; 135379cc5e7SDiego Novillo CS->second.print(OS, Indent + 4); 136379cc5e7SDiego Novillo } 137379cc5e7SDiego Novillo OS << "}\n"; 138379cc5e7SDiego Novillo } else { 139379cc5e7SDiego Novillo OS << "No inlined callsites in this function\n"; 1404b6bdb53SDiego Novillo } 1414b6bdb53SDiego Novillo } 142ba920be4SDiego Novillo 143ba920be4SDiego Novillo raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, 144ba920be4SDiego Novillo const FunctionSamples &FS) { 145ba920be4SDiego Novillo FS.print(OS); 146ba920be4SDiego Novillo return OS; 147ba920be4SDiego Novillo } 148ba920be4SDiego Novillo 149ba920be4SDiego Novillo void FunctionSamples::dump(void) const { print(dbgs(), 0); } 150