Fix relocation selection for foo-. on mips.
[oota-llvm.git] / lib / ProfileData / CoverageMapping.cpp
1 //=-- CoverageMapping.cpp - Code coverage mapping support ---------*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for clang's and llvm's instrumentation based
11 // code coverage.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/ProfileData/CoverageMapping.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/SmallBitVector.h"
19 #include "llvm/ProfileData/CoverageMappingReader.h"
20 #include "llvm/ProfileData/InstrProfReader.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/ManagedStatic.h"
24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/raw_ostream.h"
26
27 using namespace llvm;
28 using namespace coverage;
29
30 #define DEBUG_TYPE "coverage-mapping"
31
32 Counter CounterExpressionBuilder::get(const CounterExpression &E) {
33   auto It = ExpressionIndices.find(E);
34   if (It != ExpressionIndices.end())
35     return Counter::getExpression(It->second);
36   unsigned I = Expressions.size();
37   Expressions.push_back(E);
38   ExpressionIndices[E] = I;
39   return Counter::getExpression(I);
40 }
41
42 void CounterExpressionBuilder::extractTerms(
43     Counter C, int Sign, SmallVectorImpl<std::pair<unsigned, int>> &Terms) {
44   switch (C.getKind()) {
45   case Counter::Zero:
46     break;
47   case Counter::CounterValueReference:
48     Terms.push_back(std::make_pair(C.getCounterID(), Sign));
49     break;
50   case Counter::Expression:
51     const auto &E = Expressions[C.getExpressionID()];
52     extractTerms(E.LHS, Sign, Terms);
53     extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign,
54                  Terms);
55     break;
56   }
57 }
58
59 Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {
60   // Gather constant terms.
61   llvm::SmallVector<std::pair<unsigned, int>, 32> Terms;
62   extractTerms(ExpressionTree, +1, Terms);
63
64   // If there are no terms, this is just a zero. The algorithm below assumes at
65   // least one term.
66   if (Terms.size() == 0)
67     return Counter::getZero();
68
69   // Group the terms by counter ID.
70   std::sort(Terms.begin(), Terms.end(),
71             [](const std::pair<unsigned, int> &LHS,
72                const std::pair<unsigned, int> &RHS) {
73     return LHS.first < RHS.first;
74   });
75
76   // Combine terms by counter ID to eliminate counters that sum to zero.
77   auto Prev = Terms.begin();
78   for (auto I = Prev + 1, E = Terms.end(); I != E; ++I) {
79     if (I->first == Prev->first) {
80       Prev->second += I->second;
81       continue;
82     }
83     ++Prev;
84     *Prev = *I;
85   }
86   Terms.erase(++Prev, Terms.end());
87
88   Counter C;
89   // Create additions. We do this before subtractions to avoid constructs like
90   // ((0 - X) + Y), as opposed to (Y - X).
91   for (auto Term : Terms) {
92     if (Term.second <= 0)
93       continue;
94     for (int I = 0; I < Term.second; ++I)
95       if (C.isZero())
96         C = Counter::getCounter(Term.first);
97       else
98         C = get(CounterExpression(CounterExpression::Add, C,
99                                   Counter::getCounter(Term.first)));
100   }
101
102   // Create subtractions.
103   for (auto Term : Terms) {
104     if (Term.second >= 0)
105       continue;
106     for (int I = 0; I < -Term.second; ++I)
107       C = get(CounterExpression(CounterExpression::Subtract, C,
108                                 Counter::getCounter(Term.first)));
109   }
110   return C;
111 }
112
113 Counter CounterExpressionBuilder::add(Counter LHS, Counter RHS) {
114   return simplify(get(CounterExpression(CounterExpression::Add, LHS, RHS)));
115 }
116
117 Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS) {
118   return simplify(
119       get(CounterExpression(CounterExpression::Subtract, LHS, RHS)));
120 }
121
122 void CounterMappingContext::dump(const Counter &C,
123                                  llvm::raw_ostream &OS) const {
124   switch (C.getKind()) {
125   case Counter::Zero:
126     OS << '0';
127     return;
128   case Counter::CounterValueReference:
129     OS << '#' << C.getCounterID();
130     break;
131   case Counter::Expression: {
132     if (C.getExpressionID() >= Expressions.size())
133       return;
134     const auto &E = Expressions[C.getExpressionID()];
135     OS << '(';
136     dump(E.LHS, OS);
137     OS << (E.Kind == CounterExpression::Subtract ? " - " : " + ");
138     dump(E.RHS, OS);
139     OS << ')';
140     break;
141   }
142   }
143   if (CounterValues.empty())
144     return;
145   ErrorOr<int64_t> Value = evaluate(C);
146   if (!Value)
147     return;
148   OS << '[' << *Value << ']';
149 }
150
151 ErrorOr<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
152   switch (C.getKind()) {
153   case Counter::Zero:
154     return 0;
155   case Counter::CounterValueReference:
156     if (C.getCounterID() >= CounterValues.size())
157       return std::make_error_code(std::errc::argument_out_of_domain);
158     return CounterValues[C.getCounterID()];
159   case Counter::Expression: {
160     if (C.getExpressionID() >= Expressions.size())
161       return std::make_error_code(std::errc::argument_out_of_domain);
162     const auto &E = Expressions[C.getExpressionID()];
163     ErrorOr<int64_t> LHS = evaluate(E.LHS);
164     if (!LHS)
165       return LHS;
166     ErrorOr<int64_t> RHS = evaluate(E.RHS);
167     if (!RHS)
168       return RHS;
169     return E.Kind == CounterExpression::Subtract ? *LHS - *RHS : *LHS + *RHS;
170   }
171   }
172   llvm_unreachable("Unhandled CounterKind");
173 }
174
175 void FunctionRecordIterator::skipOtherFiles() {
176   while (Current != Records.end() && !Filename.empty() &&
177          Filename != Current->Filenames[0])
178     ++Current;
179   if (Current == Records.end())
180     *this = FunctionRecordIterator();
181 }
182
183 /// Get the function name from the record, removing the filename prefix if
184 /// necessary.
185 static StringRef getFuncNameWithoutPrefix(const CoverageMappingRecord &Record) {
186   StringRef FunctionName = Record.FunctionName;
187   if (Record.Filenames.empty())
188     return FunctionName;
189   StringRef Filename = sys::path::filename(Record.Filenames[0]);
190   if (FunctionName.startswith(Filename))
191     FunctionName = FunctionName.drop_front(Filename.size() + 1);
192   return FunctionName;
193 }
194
195 ErrorOr<std::unique_ptr<CoverageMapping>>
196 CoverageMapping::load(CoverageMappingReader &CoverageReader,
197                       IndexedInstrProfReader &ProfileReader) {
198   auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
199
200   std::vector<uint64_t> Counts;
201   for (const auto &Record : CoverageReader) {
202     CounterMappingContext Ctx(Record.Expressions);
203
204     Counts.clear();
205     if (std::error_code EC = ProfileReader.getFunctionCounts(
206             Record.FunctionName, Record.FunctionHash, Counts)) {
207       if (EC == instrprof_error::hash_mismatch) {
208         Coverage->MismatchedFunctionCount++;
209         continue;
210       } else if (EC != instrprof_error::unknown_function)
211         return EC;
212       Counts.assign(Record.MappingRegions.size(), 0);
213     }
214     Ctx.setCounts(Counts);
215
216     assert(!Record.MappingRegions.empty() && "Function has no regions");
217
218     FunctionRecord Function(getFuncNameWithoutPrefix(Record), Record.Filenames);
219     for (const auto &Region : Record.MappingRegions) {
220       ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
221       if (!ExecutionCount)
222         break;
223       Function.pushRegion(Region, *ExecutionCount);
224     }
225     if (Function.CountedRegions.size() != Record.MappingRegions.size()) {
226       Coverage->MismatchedFunctionCount++;
227       continue;
228     }
229
230     Coverage->Functions.push_back(std::move(Function));
231   }
232
233   return std::move(Coverage);
234 }
235
236 ErrorOr<std::unique_ptr<CoverageMapping>>
237 CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename,
238                       Triple::ArchType Arch) {
239   auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
240   if (std::error_code EC = CounterMappingBuff.getError())
241     return EC;
242   auto CoverageReaderOrErr =
243       BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
244   if (std::error_code EC = CoverageReaderOrErr.getError())
245     return EC;
246   auto CoverageReader = std::move(CoverageReaderOrErr.get());
247   auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
248   if (auto EC = ProfileReaderOrErr.getError())
249     return EC;
250   auto ProfileReader = std::move(ProfileReaderOrErr.get());
251   return load(*CoverageReader, *ProfileReader);
252 }
253
254 namespace {
255 /// \brief Distributes functions into instantiation sets.
256 ///
257 /// An instantiation set is a collection of functions that have the same source
258 /// code, ie, template functions specializations.
259 class FunctionInstantiationSetCollector {
260   typedef DenseMap<std::pair<unsigned, unsigned>,
261                    std::vector<const FunctionRecord *>> MapT;
262   MapT InstantiatedFunctions;
263
264 public:
265   void insert(const FunctionRecord &Function, unsigned FileID) {
266     auto I = Function.CountedRegions.begin(), E = Function.CountedRegions.end();
267     while (I != E && I->FileID != FileID)
268       ++I;
269     assert(I != E && "function does not cover the given file");
270     auto &Functions = InstantiatedFunctions[I->startLoc()];
271     Functions.push_back(&Function);
272   }
273
274   MapT::iterator begin() { return InstantiatedFunctions.begin(); }
275
276   MapT::iterator end() { return InstantiatedFunctions.end(); }
277 };
278
279 class SegmentBuilder {
280   std::vector<CoverageSegment> Segments;
281   SmallVector<const CountedRegion *, 8> ActiveRegions;
282
283   /// Start a segment with no count specified.
284   void startSegment(unsigned Line, unsigned Col) {
285     DEBUG(dbgs() << "Top level segment at " << Line << ":" << Col << "\n");
286     Segments.emplace_back(Line, Col, /*IsRegionEntry=*/false);
287   }
288
289   /// Start a segment with the given Region's count.
290   void startSegment(unsigned Line, unsigned Col, bool IsRegionEntry,
291                     const CountedRegion &Region) {
292     if (Segments.empty())
293       Segments.emplace_back(Line, Col, IsRegionEntry);
294     CoverageSegment S = Segments.back();
295     // Avoid creating empty regions.
296     if (S.Line != Line || S.Col != Col) {
297       Segments.emplace_back(Line, Col, IsRegionEntry);
298       S = Segments.back();
299     }
300     DEBUG(dbgs() << "Segment at " << Line << ":" << Col);
301     // Set this region's count.
302     if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) {
303       DEBUG(dbgs() << " with count " << Region.ExecutionCount);
304       Segments.back().setCount(Region.ExecutionCount);
305     }
306     DEBUG(dbgs() << "\n");
307   }
308
309   /// Start a segment for the given region.
310   void startSegment(const CountedRegion &Region) {
311     startSegment(Region.LineStart, Region.ColumnStart, true, Region);
312   }
313
314   /// Pop the top region off of the active stack, starting a new segment with
315   /// the containing Region's count.
316   void popRegion() {
317     const CountedRegion *Active = ActiveRegions.back();
318     unsigned Line = Active->LineEnd, Col = Active->ColumnEnd;
319     ActiveRegions.pop_back();
320     if (ActiveRegions.empty())
321       startSegment(Line, Col);
322     else
323       startSegment(Line, Col, false, *ActiveRegions.back());
324   }
325
326 public:
327   /// Build a list of CoverageSegments from a sorted list of Regions.
328   std::vector<CoverageSegment> buildSegments(ArrayRef<CountedRegion> Regions) {
329     const CountedRegion *PrevRegion = nullptr;
330     for (const auto &Region : Regions) {
331       // Pop any regions that end before this one starts.
332       while (!ActiveRegions.empty() &&
333              ActiveRegions.back()->endLoc() <= Region.startLoc())
334         popRegion();
335       if (PrevRegion && PrevRegion->startLoc() == Region.startLoc() &&
336           PrevRegion->endLoc() == Region.endLoc()) {
337         if (Region.Kind == coverage::CounterMappingRegion::CodeRegion)
338           Segments.back().addCount(Region.ExecutionCount);
339       } else {
340         // Add this region to the stack.
341         ActiveRegions.push_back(&Region);
342         startSegment(Region);
343       }
344       PrevRegion = &Region;
345     }
346     // Pop any regions that are left in the stack.
347     while (!ActiveRegions.empty())
348       popRegion();
349     return Segments;
350   }
351 };
352 }
353
354 std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
355   std::vector<StringRef> Filenames;
356   for (const auto &Function : getCoveredFunctions())
357     Filenames.insert(Filenames.end(), Function.Filenames.begin(),
358                      Function.Filenames.end());
359   std::sort(Filenames.begin(), Filenames.end());
360   auto Last = std::unique(Filenames.begin(), Filenames.end());
361   Filenames.erase(Last, Filenames.end());
362   return Filenames;
363 }
364
365 static SmallBitVector gatherFileIDs(StringRef SourceFile,
366                                     const FunctionRecord &Function) {
367   SmallBitVector FilenameEquivalence(Function.Filenames.size(), false);
368   for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I)
369     if (SourceFile == Function.Filenames[I])
370       FilenameEquivalence[I] = true;
371   return FilenameEquivalence;
372 }
373
374 static Optional<unsigned> findMainViewFileID(StringRef SourceFile,
375                                              const FunctionRecord &Function) {
376   SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
377   SmallBitVector FilenameEquivalence = gatherFileIDs(SourceFile, Function);
378   for (const auto &CR : Function.CountedRegions)
379     if (CR.Kind == CounterMappingRegion::ExpansionRegion &&
380         FilenameEquivalence[CR.FileID])
381       IsNotExpandedFile[CR.ExpandedFileID] = false;
382   IsNotExpandedFile &= FilenameEquivalence;
383   int I = IsNotExpandedFile.find_first();
384   if (I == -1)
385     return None;
386   return I;
387 }
388
389 static Optional<unsigned> findMainViewFileID(const FunctionRecord &Function) {
390   SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
391   for (const auto &CR : Function.CountedRegions)
392     if (CR.Kind == CounterMappingRegion::ExpansionRegion)
393       IsNotExpandedFile[CR.ExpandedFileID] = false;
394   int I = IsNotExpandedFile.find_first();
395   if (I == -1)
396     return None;
397   return I;
398 }
399
400 /// Sort a nested sequence of regions from a single file.
401 template <class It> static void sortNestedRegions(It First, It Last) {
402   std::sort(First, Last,
403             [](const CountedRegion &LHS, const CountedRegion &RHS) {
404     if (LHS.startLoc() == RHS.startLoc())
405       // When LHS completely contains RHS, we sort LHS first.
406       return RHS.endLoc() < LHS.endLoc();
407     return LHS.startLoc() < RHS.startLoc();
408   });
409 }
410
411 static bool isExpansion(const CountedRegion &R, unsigned FileID) {
412   return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
413 }
414
415 CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) {
416   CoverageData FileCoverage(Filename);
417   std::vector<coverage::CountedRegion> Regions;
418
419   for (const auto &Function : Functions) {
420     auto MainFileID = findMainViewFileID(Filename, Function);
421     if (!MainFileID)
422       continue;
423     auto FileIDs = gatherFileIDs(Filename, Function);
424     for (const auto &CR : Function.CountedRegions)
425       if (FileIDs.test(CR.FileID)) {
426         Regions.push_back(CR);
427         if (isExpansion(CR, *MainFileID))
428           FileCoverage.Expansions.emplace_back(CR, Function);
429       }
430   }
431
432   sortNestedRegions(Regions.begin(), Regions.end());
433   DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
434   FileCoverage.Segments = SegmentBuilder().buildSegments(Regions);
435
436   return FileCoverage;
437 }
438
439 std::vector<const FunctionRecord *>
440 CoverageMapping::getInstantiations(StringRef Filename) {
441   FunctionInstantiationSetCollector InstantiationSetCollector;
442   for (const auto &Function : Functions) {
443     auto MainFileID = findMainViewFileID(Filename, Function);
444     if (!MainFileID)
445       continue;
446     InstantiationSetCollector.insert(Function, *MainFileID);
447   }
448
449   std::vector<const FunctionRecord *> Result;
450   for (const auto &InstantiationSet : InstantiationSetCollector) {
451     if (InstantiationSet.second.size() < 2)
452       continue;
453     Result.insert(Result.end(), InstantiationSet.second.begin(),
454                   InstantiationSet.second.end());
455   }
456   return Result;
457 }
458
459 CoverageData
460 CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) {
461   auto MainFileID = findMainViewFileID(Function);
462   if (!MainFileID)
463     return CoverageData();
464
465   CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
466   std::vector<coverage::CountedRegion> Regions;
467   for (const auto &CR : Function.CountedRegions)
468     if (CR.FileID == *MainFileID) {
469       Regions.push_back(CR);
470       if (isExpansion(CR, *MainFileID))
471         FunctionCoverage.Expansions.emplace_back(CR, Function);
472     }
473
474   sortNestedRegions(Regions.begin(), Regions.end());
475   DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n");
476   FunctionCoverage.Segments = SegmentBuilder().buildSegments(Regions);
477
478   return FunctionCoverage;
479 }
480
481 CoverageData
482 CoverageMapping::getCoverageForExpansion(const ExpansionRecord &Expansion) {
483   CoverageData ExpansionCoverage(
484       Expansion.Function.Filenames[Expansion.FileID]);
485   std::vector<coverage::CountedRegion> Regions;
486   for (const auto &CR : Expansion.Function.CountedRegions)
487     if (CR.FileID == Expansion.FileID) {
488       Regions.push_back(CR);
489       if (isExpansion(CR, Expansion.FileID))
490         ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function);
491     }
492
493   sortNestedRegions(Regions.begin(), Regions.end());
494   DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID
495                << "\n");
496   ExpansionCoverage.Segments = SegmentBuilder().buildSegments(Regions);
497
498   return ExpansionCoverage;
499 }
500
501 namespace {
502 class CoverageMappingErrorCategoryType : public std::error_category {
503   const char *name() const LLVM_NOEXCEPT override { return "llvm.coveragemap"; }
504   std::string message(int IE) const override {
505     auto E = static_cast<coveragemap_error>(IE);
506     switch (E) {
507     case coveragemap_error::success:
508       return "Success";
509     case coveragemap_error::eof:
510       return "End of File";
511     case coveragemap_error::no_data_found:
512       return "No coverage data found";
513     case coveragemap_error::unsupported_version:
514       return "Unsupported coverage format version";
515     case coveragemap_error::truncated:
516       return "Truncated coverage data";
517     case coveragemap_error::malformed:
518       return "Malformed coverage data";
519     }
520     llvm_unreachable("A value of coveragemap_error has no message.");
521   }
522 };
523 }
524
525 static ManagedStatic<CoverageMappingErrorCategoryType> ErrorCategory;
526
527 const std::error_category &llvm::coveragemap_category() {
528   return *ErrorCategory;
529 }