llvm.org GIT mirror llvm / e0eae15
InstrProf: Handle unknown functions if they consist only of zero-regions This comes up when we generate coverage for a function but don't end up emitting the function at all - dead static functions or inline functions that aren't referenced in a particular TU, for example. In these cases we'd like to show that the function was never called, which is trivially true. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229717 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Bogner 4 years ago
3 changed file(s) with 35 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
236236 ArrayRef CounterValues = ArrayRef())
237237 : Expressions(Expressions), CounterValues(CounterValues) {}
238238
239 void setCounts(ArrayRef Counts) { CounterValues = Counts; }
240
239241 void dump(const Counter &C, llvm::raw_ostream &OS) const;
240242 void dump(const Counter &C) const { dump(C, dbgs()); }
241243
255257 /// \brief The number of times this function was executed.
256258 uint64_t ExecutionCount;
257259
258 FunctionRecord(StringRef Name, ArrayRef Filenames,
259 uint64_t ExecutionCount)
260 : Name(Name), Filenames(Filenames.begin(), Filenames.end()),
261 ExecutionCount(ExecutionCount) {}
260 FunctionRecord(StringRef Name, ArrayRef Filenames)
261 : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
262
263 void pushRegion(CounterMappingRegion Region, uint64_t Count) {
264 if (CountedRegions.empty())
265 ExecutionCount = Count;
266 CountedRegions.emplace_back(Region, Count);
267 }
262268 };
263269
264270 /// \brief Iterator over Functions, optionally filtered to a single file.
183183
184184 std::vector Counts;
185185 for (const auto &Record : CoverageReader) {
186 CounterMappingContext Ctx(Record.Expressions);
187
186188 Counts.clear();
187189 if (std::error_code EC = ProfileReader.getFunctionCounts(
188190 Record.FunctionName, Record.FunctionHash, Counts)) {
189 if (EC != instrprof_error::hash_mismatch &&
190 EC != instrprof_error::unknown_function)
191 if (EC == instrprof_error::hash_mismatch) {
192 Coverage->MismatchedFunctionCount++;
193 continue;
194 } else if (EC != instrprof_error::unknown_function)
191195 return EC;
192 Coverage->MismatchedFunctionCount++;
193 continue;
194 }
195
196 assert(Counts.size() != 0 && "Function's counts are empty");
197 FunctionRecord Function(Record.FunctionName, Record.Filenames,
198 Counts.front());
199 CounterMappingContext Ctx(Record.Expressions, Counts);
196 } else
197 Ctx.setCounts(Counts);
198
199 assert(!Record.MappingRegions.empty() && "Function has no regions");
200 FunctionRecord Function(Record.FunctionName, Record.Filenames);
200201 for (const auto &Region : Record.MappingRegions) {
201202 ErrorOr ExecutionCount = Ctx.evaluate(Region.Count);
202203 if (!ExecutionCount)
203204 break;
204 Function.CountedRegions.push_back(CountedRegion(Region, *ExecutionCount));
205 Function.pushRegion(Region, *ExecutionCount);
205206 }
206207 if (Function.CountedRegions.size() != Record.MappingRegions.size()) {
207208 Coverage->MismatchedFunctionCount++;
208208 ASSERT_EQ(CoverageSegment(11, 11, false), Segments[6]);
209209 }
210210
211 TEST_F(CoverageMappingTest, uncovered_function) {
212 readProfCounts();
213
214 addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
215 loadCoverageMapping("func", 0x1234);
216
217 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
218 std::vector Segments(Data.begin(), Data.end());
219 ASSERT_EQ(2U, Segments.size());
220 ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
221 ASSERT_EQ(CoverageSegment(3, 4, false), Segments[1]);
222 }
223
211224 } // end anonymous namespace