LLVM: lib/ProfileData/GCOV.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17#include "llvm/Config/llvm-config.h"
25#include
26#include
27#include <system_error>
28
29using namespace llvm;
30
34
40
43};
44
45namespace {
46struct Summary {
47 Summary(StringRef Name) : Name(Name) {}
48
49 StringRef Name;
50 uint64_t lines = 0;
51 uint64_t linesExec = 0;
52 uint64_t branches = 0;
53 uint64_t branchesExec = 0;
54 uint64_t branchesTaken = 0;
55};
56
57struct LineInfo {
58 SmallVector<const GCOVBlock *, 1> blocks;
59 uint64_t count = 0;
60 bool exists = false;
61};
62
63struct SourceInfo {
64 StringRef filename;
65 SmallString<0> displayName;
66 std::vector<std::vector<const GCOVFunction *>> startLineToFunctions;
67 std::vector lines;
68 bool ignored = false;
69 SourceInfo(StringRef filename) : filename(filename) {}
70};
71
72class Context {
73public:
75 void print(StringRef filename, StringRef gcno, StringRef gcda,
76 GCOVFile &file);
77
78private:
79 std::string getCoveragePath(StringRef filename, StringRef mainFilename) const;
80 void printFunctionDetails(const GCOVFunction &f, raw_ostream &os) const;
81 void printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
82 raw_ostream &OS) const;
83 void printSummary(const Summary &summary, raw_ostream &os) const;
84
85 void collectFunction(GCOVFunction &f, Summary &summary);
86 void collectSourceLine(SourceInfo &si, Summary *summary, LineInfo &line,
87 size_t lineNum) const;
88 void collectSource(SourceInfo &si, Summary &summary) const;
89 void annotateSource(SourceInfo &si, const GCOVFile &file, StringRef gcno,
90 StringRef gcda, raw_ostream &os) const;
91 void printSourceToIntermediate(const SourceInfo &si, raw_ostream &os) const;
92
93 const GCOV::Options &options;
94 std::vector sources;
95};
96}
97
98
99
100
101
104 return false;
106 return false;
107
110 return false;
112 buf.getWord();
113
116 while ((tag = buf.getWord())) {
117 if (!buf.readInt(length))
118 return false;
121 functions.push_back(std::make_unique(*this));
131 return false;
133 } else {
136 return false;
142 }
143 fn->srcIdx = addNormalizedPathToMap(filename);
147 for (uint32_t i = 0; i != length; ++i) {
148 buf.getWord();
149 fn->blocks.push_back(std::make_unique(i));
150 }
151 } else {
153 for (uint32_t i = 0; i != num; ++i)
154 fn->blocks.push_back(std::make_unique(i));
155 }
158 if (srcNo >= fn->blocks.size()) {
159 errs() << "unexpected block number: " << srcNo << " (in "
160 << fn->blocks.size() << ")\n";
161 return false;
162 }
166 for (uint32_t i = 0; i != e; ++i) {
169 auto arc = std::make_unique(*src, *dst, flags);
172 if (arc->onTree())
173 fn->treeArcs.push_back(std::move(arc));
174 else
175 fn->arcs.push_back(std::move(arc));
176 }
179 if (srcNo >= fn->blocks.size()) {
180 errs() << "unexpected block number: " << srcNo << " (in "
181 << fn->blocks.size() << ")\n";
182 return false;
183 }
185 for (;;) {
187 if (line)
188 Block.addLine(line);
189 else {
192 if (filename.empty())
193 break;
194 Block.addFile(addNormalizedPathToMap(filename));
195 }
196 }
197 }
200 return false;
202 }
203
205 return true;
206}
207
208
209
213 return false;
216 return false;
217 if (version != GCDAVersion) {
218 errs() << "GCOV versions do not match.\n";
219 return false;
220 }
221
223 if (!buf.readInt(GCDAChecksum))
224 return false;
225 if (checksum != GCDAChecksum) {
226 errs() << "file checksums do not match: " << checksum
227 << " != " << GCDAChecksum << "\n";
228 return false;
229 }
233 while ((tag = buf.getWord())) {
234 if (!buf.readInt(length))
235 return false;
246 if (length == 0)
247 continue;
248 if (length < 2 || !buf.readInt(ident))
249 return false;
251 uint32_t linenoChecksum, cfgChecksum = 0;
252 buf.readInt(linenoChecksum);
254 buf.readInt(cfgChecksum);
256 fn = It->second;
260 << format(": checksum mismatch, (%u, %u) != (%u, %u)\n",
263 return false;
264 }
265 }
269 expected *= 4;
270 if (length != expected) {
273 ": GCOV_TAG_COUNTER_ARCS mismatch, got %u, expected %u\n",
274 length, expected);
275 return false;
276 }
277 for (std::unique_ptr &arc : fn->arcs) {
279 return false;
280 arc->src.count += arc->count;
281 }
282
283 if (fn->blocks.size() >= 2) {
288 sink.addDstEdge(arc.get());
290 fn->treeArcs.push_back(std::move(arc));
291
294 for (size_t i = fn->treeArcs.size() - 1; i; --i)
295 fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count;
296 }
297 }
300 return false;
302 }
303
304 return true;
305}
306
311
312#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
313
315#endif
316
317unsigned GCOVFile::addNormalizedPathToMap(StringRef filename) {
318
321 filename = P.str();
322
324 if (r.second)
325 filenames.emplace_back(filename);
326
327 return r.first->second;
328}
329
331
332
333
334
339 do {
340 if (Name.starts_with("_Z")) {
341
344 free(res);
345 break;
346 }
347 }
349 } while (false);
350 }
352}
354
355
356
358 return blocks.front()->getCount();
359}
360
364
365
366
367
368
369
370
371
373 struct Elem {
376 bool inDst;
377 size_t i = 0;
379 };
380
382 stack.push_back({v, pred, false});
383 for (;;) {
384 Elem &u = stack.back();
385
386
387 if (u.i == 0 && .insert(&u.v).second) {
389 if (stack.empty())
390 break;
391 continue;
392 }
393 if (u.i < u.v.pred.size()) {
394 GCOVArc *e = u.v.pred[u.i++];
395 if (e != u.pred) {
396 if (e->onTree())
397 stack.push_back({e->src, e, false});
398 else
399 u.excess += e->count;
400 }
401 } else if (u.i < u.v.pred.size() + u.v.succ.size()) {
402 GCOVArc *e = u.v.succ[u.i++ - u.v.pred.size()];
403 if (e != u.pred) {
404 if (e->onTree())
405 stack.push_back({e->dst, e, true});
406 else
407 u.excess -= e->count;
408 }
409 } else {
411 if (static_cast<int64_t>(excess) < 0)
412 excess = -excess;
413 if (u.pred)
414 u.pred->count = excess;
415 bool inDst = u.inDst;
417 if (stack.empty())
418 break;
419 stack.back().excess += inDst ? -excess : excess;
420 }
421 }
422}
423
428 Block->print(OS);
429}
430
431#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
432
434#endif
435
436
437
438
439
440
441
443 OS << "Block : " << number << " Counter : " << count << "\n";
444 if (.empty()) {
445 OS << "\tSource Edges : ";
447 OS << Edge->src.number << " (" << Edge->count << "), ";
448 OS << "\n";
449 }
450 if (.empty()) {
451 OS << "\tDestination Edges : ";
454 OS << '*';
455 OS << Edge->dst.number << " (" << Edge->count << "), ";
456 }
457 OS << "\n";
458 }
461 OS << "\tFile: " << loc.srcIdx << ": ";
463 OS << (N) << ",";
464 OS << "\n";
465 }
466 }
467}
468
469#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
470
472#endif
473
476 std::vector<std::pair<GCOVBlock *, size_t>> &stack) {
478 size_t i;
479 stack.clear();
480 stack.emplace_back(src, 0);
481 src->incoming = (GCOVArc *)1;
482 for (;;) {
483 std::tie(u, i) = stack.back();
484 if (i == u->succ.size()) {
485 u->traversable = false;
486 stack.pop_back();
487 if (stack.empty())
488 break;
489 continue;
490 }
491 ++stack.back().second;
493
494
495
496 if (succ->cycleCount == 0 || ->dst.traversable || &succ->dst == u)
497 continue;
498 if (succ->dst.incoming == nullptr) {
500 stack.emplace_back(&succ->dst, 0);
501 continue;
502 }
505 minCount = std::min(minCount, v->incoming->cycleCount);
506 v = &v->incoming->src;
507 if (v == &succ->dst)
508 break;
509 }
510 succ->cycleCount -= minCount;
512 v->incoming->cycleCount -= minCount;
513 v = &v->incoming->src;
514 if (v == &succ->dst)
515 break;
516 }
517 return minCount;
518 }
519 return 0;
520}
521
522
523
524
525
527 std::vector<std::pair<GCOVBlock *, size_t>> stack;
529 for (;;) {
530
531 for (const auto *b : blocks) {
534 }
535 d = 0;
538 if (b->traversable && (d = augmentOneCycle(b, stack)) > 0)
539 break;
540 }
541 if (d == 0)
542 break;
544 }
545
546
547 for (const auto *b : blocks) {
548 assert(!b->traversable);
549 (void)b;
550 }
552}
553
554
555
556
557
558
560 if (!dividend || !divisor)
561 return 0;
562 dividend *= 100;
563 return dividend < divisor ? 1 : dividend / divisor;
564}
565
566
567
568
570 if (!Numerator)
571 return 0;
572 if (Numerator == Divisor)
573 return 100;
574
575 uint8_t Res = (Numerator * 100 + Divisor / 2) / Divisor;
576 if (Res == 0)
577 return 1;
578 if (Res == 100)
579 return 99;
580 return Res;
581}
582
583namespace {
584struct formatBranchInfo {
585 formatBranchInfo(const GCOV::Options &Options, uint64_t Count, uint64_t Total)
587
588 void print(raw_ostream &OS) const {
590 OS << "never executed";
591 else if (Options.BranchCount)
592 OS << "taken " << Count;
593 else
595 }
596
597 const GCOV::Options &Options;
600};
601
603 FBI.print(OS);
604 return OS;
605}
606
607class LineConsumer {
608 std::unique_ptr Buffer;
609 StringRef Remaining;
610
611public:
612 LineConsumer() = default;
613 LineConsumer(StringRef Filename) {
614
615
616 ErrorOr<std::unique_ptr> BufferOrErr =
618 false);
619 if (std::error_code EC = BufferOrErr.getError()) {
621 Remaining = "";
622 } else {
623 Buffer = std::move(BufferOrErr.get());
624 Remaining = Buffer->getBuffer();
625 }
626 }
627 bool empty() { return Remaining.empty(); }
628 void printNext(raw_ostream &OS, uint32_t LineNum) {
629 StringRef Line;
631 Line = "/*EOF*/";
632 else
633 std::tie(Line, Remaining) = Remaining.split("\n");
634 OS << format("%5u:", LineNum) << Line << "\n";
635 }
636};
637}
638
639
640
642 if (!PreservePaths)
644
645
646
647
650 for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) {
651 if (*I != '/')
652 continue;
653
654 if (I - S == 1 && *S == '.') {
655
656 } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') {
657
658 Result.append("^#");
659 } else {
660 if (S < I)
661
662 Result.append(S, I);
663
664 Result.push_back('#');
665 }
666 S = I + 1;
667 }
668
669 if (S < I)
670 Result.append(S, I);
671 return std::string(Result);
672}
673
674std::string Context::getCoveragePath(StringRef filename,
677
678
679
680 return std::string(filename);
681
682 std::string CoveragePath;
683 if (options.LongFileNames && filename != mainFilename)
684 CoveragePath =
687 if (options.HashFilenames) {
688 MD5 Hasher;
691 Hasher.final(Result);
692 CoveragePath += "##" + std::string(Result.digest());
693 }
694 CoveragePath += ".gcov";
695 return CoveragePath;
696}
697
698void Context::collectFunction(GCOVFunction &f, Summary &summary) {
699 SourceInfo &si = sources[f.srcIdx];
700 if (f.startLine >= si.startLineToFunctions.size())
701 si.startLineToFunctions.resize(f.startLine + 1);
702 si.startLineToFunctions[f.startLine].push_back(&f);
705 for (const GCOVBlock &b : f.blocksRange()) {
706 if (b.locations.empty())
707 continue;
709 SourceInfo &locSource = sources[loc.srcIdx];
711 if (maxLineNum >= locSource.lines.size())
712 locSource.lines.resize(maxLineNum + 1);
713 for (uint32_t lineNum : loc.lines) {
714 LineInfo &line = locSource.lines[lineNum];
715 line.exists = true;
716 line.count += b.count;
718 if (f.srcIdx == loc.srcIdx) {
719 if (lines.insert(lineNum).second)
720 ++summary.lines;
721 if (b.count && linesExec.insert(lineNum).second)
722 ++summary.linesExec;
723 }
724 }
725 }
726 }
727}
728
729void Context::collectSourceLine(SourceInfo &si, Summary *summary,
730 LineInfo &line, size_t lineNum) const {
731 uint64_t count = 0;
732 for (const GCOVBlock *b : line.blocks) {
733 if (b->number == 0) {
734
735
736
737
738 for (const GCOVArc *arc : b->succ)
740 } else {
741
742 for (const GCOVArc *arc : b->pred)
745 }
748 }
749
751 line.count = count;
752 if (line.exists) {
753 ++summary->lines;
754 if (line.count != 0)
755 ++summary->linesExec;
756 }
757
759 for (const GCOVBlock *b : line.blocks) {
760 if (b->getLastLine() != lineNum)
761 continue;
762 int branches = 0, execBranches = 0, takenBranches = 0;
763 for (const GCOVArc *arc : b->succ) {
766 ++execBranches;
767 if (arc->count != 0)
768 ++takenBranches;
769 }
771 summary->branches += branches;
772 summary->branchesExec += execBranches;
773 summary->branchesTaken += takenBranches;
774 }
775 }
776}
777
778void Context::collectSource(SourceInfo &si, Summary &summary) const {
779 size_t lineNum = 0;
780 for (LineInfo &line : si.lines) {
781 collectSourceLine(si, &summary, line, lineNum);
782 ++lineNum;
783 }
784}
785
786void Context::annotateSource(SourceInfo &si, const GCOVFile &file,
789 auto source =
790 options.Intermediate ? LineConsumer() : LineConsumer(si.filename);
791
792 os << " -: 0:Source:" << si.displayName << '\n';
793 os << " -: 0:Graph:" << gcno << '\n';
794 os << " -: 0:Data:" << gcda << '\n';
795 os << " -: 0:Runs:" << file.runCount << '\n';
797 os << " -: 0:Programs:" << file.programCount << '\n';
798
799 for (size_t lineNum = 1; !source.empty(); ++lineNum) {
800 if (lineNum >= si.lines.size()) {
801 os << " -:";
802 source.printNext(os, lineNum);
803 continue;
804 }
805
806 const LineInfo &line = si.lines[lineNum];
807 if (options.BranchInfo && lineNum < si.startLineToFunctions.size())
808 for (const auto *f : si.startLineToFunctions[lineNum])
809 printFunctionDetails(*f, os);
810 if (!line.exists)
811 os << " -:";
812 else if (line.count == 0)
813 os << " #####:";
814 else
815 os << format("%9" PRIu64 ":", line.count);
816 source.printNext(os, lineNum);
817
818 uint32_t blockIdx = 0, edgeIdx = 0;
819 for (const GCOVBlock *b : line.blocks) {
820 if (b->getLastLine() != lineNum)
821 continue;
823 if (b->getCount() == 0)
824 os << " $$$:";
825 else
826 os << format("%9" PRIu64 ":", b->count);
827 os << format("%5u-block %2u\n", lineNum, blockIdx++);
828 }
829 if (options.BranchInfo) {
830 size_t NumEdges = b->succ.size();
831 if (NumEdges > 1)
832 printBranchInfo(*b, edgeIdx, os);
833 else if (options.UncondBranch && NumEdges == 1) {
834 uint64_t count = b->succ[0]->count;
835 os << format("unconditional %2u ", edgeIdx++)
836 << formatBranchInfo(options, count, count) << '\n';
837 }
838 }
839 }
840 }
841}
842
843void Context::printSourceToIntermediate(const SourceInfo &si,
845 os << "file:" << si.filename << '\n';
846 for (const auto &fs : si.startLineToFunctions)
848 os << "function:" << f->startLine << ',' << f->getEntryCount() << ','
849 << f->getName(options.Demangle) << '\n';
850 for (size_t lineNum = 1, size = si.lines.size(); lineNum < size; ++lineNum) {
851 const LineInfo &line = si.lines[lineNum];
852 if (line.blocks.empty())
853 continue;
854
855
856
857 os << "lcount:" << lineNum << ',' << line.count << '\n';
858
860 continue;
861 for (const GCOVBlock *b : line.blocks) {
862 if (b->succ.size() < 2 || b->getLastLine() != lineNum)
863 continue;
864 for (const GCOVArc *arc : b->succ) {
865 const char *type =
866 b->getCount() ? arc->count ? "taken" : "nottaken" : "notexec";
867 os << "branch:" << lineNum << ',' << type << '\n';
868 }
869 }
870 }
871}
872
876 sources.emplace_back(filename);
877 SourceInfo &si = sources.back();
878 si.displayName = si.filename;
879 if (.SourcePrefix.empty() &&
881 "") &&
882 !si.displayName.empty()) {
883
884
886 si.displayName.erase(si.displayName.begin());
887 else
888 si.displayName = si.filename;
889 }
891 si.ignored = true;
892 }
893
897 collectFunction(f, summary);
899 os << "Function '" << summary.Name << "'\n";
900 printSummary(summary, os);
901 os << '\n';
902 }
903 }
904
905 for (SourceInfo &si : sources) {
906 if (si.ignored)
907 continue;
908 Summary summary(si.displayName);
909 collectSource(si, summary);
910
911
912 std::string gcovName = getCoveragePath(si.filename, filename);
913 if (.UseStdout) {
914 os << "File '" << summary.Name << "'\n";
915 printSummary(summary, os);
917 os << "Creating '" << gcovName << "'\n";
918 os << '\n';
919 }
920
922 continue;
923 std::optional<raw_fd_ostream> os;
924 if (.UseStdout) {
925 std::error_code ec;
927 if (ec) {
928 errs() << ec.message() << '\n';
929 continue;
930 }
931 }
932 annotateSource(si, file, gcno, gcda,
934 }
935
937
938
940 std::error_code ec;
942 if (ec) {
943 errs() << ec.message() << '\n';
944 return;
945 }
946
947 for (const SourceInfo &si : sources)
948 printSourceToIntermediate(si, os);
949 }
950}
951
952void Context::printFunctionDetails(const GCOVFunction &f,
954 const uint64_t entryCount = f.getEntryCount();
955 uint32_t blocksExec = 0;
956 const GCOVBlock &exitBlock = f.getExitBlock();
957 uint64_t exitCount = 0;
958 for (const GCOVArc *arc : exitBlock.pred)
959 exitCount += arc->count;
960 for (const GCOVBlock &b : f.blocksRange())
961 if (b.number != 0 && &b != &exitBlock && b.getCount())
962 ++blocksExec;
963
964 os << "function " << f.getName(options.Demangle) << " called " << entryCount
966 << "% blocks executed "
968}
969
970
971void Context::printBranchInfo(const GCOVBlock &Block, uint32_t &edgeIdx,
973 uint64_t total = 0;
975 total += arc->count;
977 os << format("branch %2u ", edgeIdx++)
978 << formatBranchInfo(options, arc->count, total) << '\n';
979}
980
981void Context::printSummary(const Summary &summary, raw_ostream &os) const {
982 os << format("Lines executed:%.2f%% of %" PRIu64 "\n",
983 double(summary.linesExec) * 100 / summary.lines, summary.lines);
984 if (options.BranchInfo) {
985 if (summary.branches == 0) {
986 os << "No branches\n";
987 } else {
988 os << format("Branches executed:%.2f%% of %" PRIu64 "\n",
989 double(summary.branchesExec) * 100 / summary.branches,
990 summary.branches);
991 os << format("Taken at least once:%.2f%% of %" PRIu64 "\n",
992 double(summary.branchesTaken) * 100 / summary.branches,
993 summary.branches);
994 }
995 os << "No calls\n";
996 }
997}
998
1001 Context fi(options);
1002 fi.print(filename, gcno, gcda, file);
1003}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
arc branch ARC finalize branches
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
bbsections Prepares for basic block by splitting functions into clusters of basic blocks
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths)
Convert a path to a gcov filename.
Definition GCOV.cpp:641
static uint32_t formatPercentage(uint64_t dividend, uint64_t divisor)
Definition GCOV.cpp:559
static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor)
Definition GCOV.cpp:569
@ GCOV_TAG_LINES
Definition GCOV.cpp:38
@ GCOV_TAG_COUNTER_ARCS
Definition GCOV.cpp:39
@ GCOV_TAG_PROGRAM_SUMMARY
Definition GCOV.cpp:42
@ GCOV_ARC_FALLTHROUGH
Definition GCOV.cpp:33
@ GCOV_TAG_OBJECT_SUMMARY
Definition GCOV.cpp:41
@ GCOV_ARC_ON_TREE
Definition GCOV.cpp:32
@ GCOV_TAG_ARCS
Definition GCOV.cpp:37
@ GCOV_TAG_FUNCTION
Definition GCOV.cpp:35
@ GCOV_TAG_BLOCKS
Definition GCOV.cpp:36
static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU, OptimizationRemarkEmitter *ORE)
When an instruction is found to only be used outside of the loop, this function moves it to the exit ...
dot regions Print regions of function to dot file(with no function bodies)"
This file defines the SmallSet class.
unify loop Fixup each natural loop to have a single exit block
std::error_code getError() const
GCOVBlock - Collects block information.
static LLVM_ABI uint64_t getCyclesCount(const BlockVector &blocks)
Definition GCOV.cpp:526
void addDstEdge(GCOVArc *Edge)
SmallVector< GCOVBlockLocation > locations
void addSrcEdge(GCOVArc *Edge)
LLVM_ABI void print(raw_ostream &OS) const
collectLineCounts - Collect line counts.
Definition GCOV.cpp:442
SmallVector< const GCOVBlock *, 1 > BlockVector
static LLVM_ABI uint64_t augmentOneCycle(GCOVBlock *src, std::vector< std::pair< GCOVBlock *, size_t > > &stack)
Definition GCOV.cpp:475
SmallVector< GCOVArc *, 2 > pred
LLVM_ABI void dump() const
dump - Dump GCOVBlock content to dbgs() for debugging purposes.
Definition GCOV.cpp:471
SmallVector< GCOVArc *, 2 > succ
GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific read operations.
bool readInt(uint32_t &Val)
DataExtractor::Cursor cursor
bool readInt64(uint64_t &Val)
bool readGCOVVersion(GCOV::GCOVVersion &version)
readGCOVVersion - Read GCOV version.
bool readString(StringRef &str)
bool readGCNOFormat()
readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
bool readGCDAFormat()
readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
GCOVFile - Collects coverage information for one pair of coverage file (.gcno and ....
SmallVector< std::unique_ptr< GCOVFunction >, 16 > functions
LLVM_ABI void print(raw_ostream &OS) const
Definition GCOV.cpp:307
GCOV::GCOVVersion version
std::vector< std::string > filenames
LLVM_ABI void dump() const
dump - Dump GCOVFile content to dbgs() for debugging purposes.
Definition GCOV.cpp:314
std::map< uint32_t, GCOVFunction * > identToFunction
StringMap< unsigned > filenameToIdx
LLVM_ABI bool readGCNO(GCOVBuffer &Buffer)
readGCNO - Read GCNO buffer.
Definition GCOV.cpp:102
LLVM_ABI bool readGCDA(GCOVBuffer &Buffer)
readGCDA - Read GCDA buffer.
Definition GCOV.cpp:210
GCOVFunction - Collects function information.
LLVM_ABI uint64_t getEntryCount() const
getEntryCount - Get the number of times the function was called by retrieving the entry block's count...
Definition GCOV.cpp:357
SmallVector< std::unique_ptr< GCOVArc >, 0 > treeArcs
LLVM_ABI StringRef getName(bool demangle) const
Definition GCOV.cpp:335
LLVM_ABI void dump() const
dump - Dump GCOVFunction content to dbgs() for debugging purposes.
Definition GCOV.cpp:433
LLVM_ABI void propagateCounts(const GCOVBlock &v, GCOVArc *pred)
Definition GCOV.cpp:372
SmallVector< std::unique_ptr< GCOVBlock >, 0 > blocks
LLVM_ABI GCOVBlock & getExitBlock() const
Definition GCOV.cpp:361
LLVM_ABI StringRef getFilename() const
Definition GCOV.cpp:353
DenseSet< const GCOVBlock * > visited
SmallString< 0 > demangled
LLVM_ABI void print(raw_ostream &OS) const
Definition GCOV.cpp:424
iterator_range< BlockIterator > blocksRange() const
SmallVector< std::unique_ptr< GCOVArc >, 0 > arcs
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
LLVM_ABI bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI void gcovOneInput(const GCOV::Options &options, StringRef filename, StringRef gcno, StringRef gcda, GCOVFile &file)
Definition GCOV.cpp:999
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
LLVM_ABI bool onTree() const
Definition GCOV.cpp:330
Represent file of lines same with block_location_info in gcc.
SmallVector< uint32_t, 4 > lines
A struct for passing gcov options between functions.