Skip to content

Commit 4348f4f

Browse files
committed
coverage. Add option to keep order of counter mapping regions from frontend
1 parent 3845814 commit 4348f4f

File tree

3 files changed

+102
-22
lines changed

3 files changed

+102
-22
lines changed

llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ class CoverageMappingWriter {
4242
ArrayRef<unsigned> VirtualFileMapping;
4343
ArrayRef<CounterExpression> Expressions;
4444
MutableArrayRef<CounterMappingRegion> MappingRegions;
45+
bool KeepMappingOrder;
4546

4647
public:
4748
CoverageMappingWriter(ArrayRef<unsigned> VirtualFileMapping,
4849
ArrayRef<CounterExpression> Expressions,
49-
MutableArrayRef<CounterMappingRegion> MappingRegions)
50+
MutableArrayRef<CounterMappingRegion> MappingRegions,
51+
bool KeepMappingOrder = false)
5052
: VirtualFileMapping(VirtualFileMapping), Expressions(Expressions),
51-
MappingRegions(MappingRegions) {}
53+
MappingRegions(MappingRegions), KeepMappingOrder(KeepMappingOrder) {}
5254

5355
/// Write encoded coverage mapping data to the given output stream.
5456
void write(raw_ostream &OS);

llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp

+19-16
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,25 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
161161

162162
// Sort the regions in an ascending order by the file id and the starting
163163
// location. Sort by region kinds to ensure stable order for tests.
164-
llvm::stable_sort(MappingRegions, [](const CounterMappingRegion &LHS,
165-
const CounterMappingRegion &RHS) {
166-
if (LHS.FileID != RHS.FileID)
167-
return LHS.FileID < RHS.FileID;
168-
if (LHS.startLoc() != RHS.startLoc())
169-
return LHS.startLoc() < RHS.startLoc();
170-
171-
// Put `Decision` before `Expansion`.
172-
auto getKindKey = [](CounterMappingRegion::RegionKind Kind) {
173-
return (Kind == CounterMappingRegion::MCDCDecisionRegion
174-
? 2 * CounterMappingRegion::ExpansionRegion - 1
175-
: 2 * Kind);
176-
};
177-
178-
return getKindKey(LHS.Kind) < getKindKey(RHS.Kind);
179-
});
164+
if (!KeepMappingOrder) {
165+
llvm::stable_sort(MappingRegions, [](const CounterMappingRegion &LHS,
166+
const CounterMappingRegion &RHS) {
167+
if (LHS.FileID != RHS.FileID)
168+
return LHS.FileID < RHS.FileID;
169+
170+
if (LHS.startLoc() != RHS.startLoc())
171+
return LHS.startLoc() < RHS.startLoc();
172+
173+
// Put `Decision` before `Expansion`.
174+
auto getKindKey = [](CounterMappingRegion::RegionKind Kind) {
175+
return (Kind == CounterMappingRegion::MCDCDecisionRegion
176+
? 2 * CounterMappingRegion::ExpansionRegion - 1
177+
: 2 * Kind);
178+
};
179+
180+
return getKindKey(LHS.Kind) < getKindKey(RHS.Kind);
181+
});
182+
}
180183

181184
// Write out the fileid -> filename mapping.
182185
encodeULEB128(VirtualFileMapping.size(), OS);

llvm/unittests/ProfileData/CoverageMappingTest.cpp

+79-4
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,16 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
221221
InputFunctions.back().Expressions.push_back(CE);
222222
}
223223

224-
std::string writeCoverageRegions(InputFunctionCoverageData &Data) {
224+
std::string writeCoverageRegions(InputFunctionCoverageData &Data,
225+
bool KeepMappingsOrder) {
225226
SmallVector<unsigned, 8> FileIDs(Data.ReverseVirtualFileMapping.size());
226227
for (const auto &E : Data.ReverseVirtualFileMapping)
227228
FileIDs[E.second] = E.first;
228229
std::string Coverage;
229230
llvm::raw_string_ostream OS(Coverage);
230-
CoverageMappingWriter(FileIDs, Data.Expressions, Data.Regions).write(OS);
231+
CoverageMappingWriter(FileIDs, Data.Expressions, Data.Regions,
232+
KeepMappingsOrder)
233+
.write(OS);
231234
return OS.str();
232235
}
233236

@@ -245,10 +248,12 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
245248
EXPECT_THAT_ERROR(Reader.read(), Succeeded());
246249
}
247250

248-
void writeAndReadCoverageRegions(bool EmitFilenames = true) {
251+
void writeAndReadCoverageRegions(bool EmitFilenames = true,
252+
bool KeepMappingsOrder = false) {
249253
OutputFunctions.resize(InputFunctions.size());
250254
for (unsigned I = 0; I < InputFunctions.size(); ++I) {
251-
std::string Regions = writeCoverageRegions(InputFunctions[I]);
255+
std::string Regions =
256+
writeCoverageRegions(InputFunctions[I], KeepMappingsOrder);
252257
readCoverageRegions(Regions, OutputFunctions[I]);
253258
OutputFunctions[I].Name = InputFunctions[I].Name;
254259
OutputFunctions[I].Hash = InputFunctions[I].Hash;
@@ -316,6 +321,76 @@ TEST_P(CoverageMappingTest, basic_write_read) {
316321
}
317322
}
318323

324+
TEST_P(CoverageMappingTest, SortMappings) {
325+
startFunction("func", 0x1234);
326+
addMCDCDecisionCMR(3, 2, "file", 7, 1, 7, 12);
327+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 0, {-1, 1},
328+
"file", 7, 2, 7, 9);
329+
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 1, {-1, -1},
330+
"file", 7, 11, 7, 12);
331+
addMCDCDecisionCMR(7, 3, "file", 7, 2, 7, 9);
332+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(5), 0, {-1, 1},
333+
"file", 7, 2, 7, 3);
334+
addMCDCBranchCMR(Counter::getCounter(6), Counter::getCounter(7), 1, {-1, 2},
335+
"file", 7, 5, 7, 6);
336+
addMCDCBranchCMR(Counter::getCounter(8), Counter::getCounter(9), 2, {-1, -1},
337+
"file", 7, 8, 7, 9);
338+
339+
const std::vector<CounterMappingRegion> MappingsBeforeSourt =
340+
InputFunctions.back().Regions;
341+
writeAndReadCoverageRegions(true, false);
342+
ASSERT_EQ(1u, InputFunctions.size());
343+
ASSERT_EQ(1u, OutputFunctions.size());
344+
const auto &Input = MappingsBeforeSourt;
345+
const auto &Output = OutputFunctions.back().Regions;
346+
347+
size_t N = ArrayRef(Input).size();
348+
llvm::SmallVector<std::tuple<size_t, size_t>> SortedMap = {
349+
{0, 0}, {3, 1}, {1, 2}, {4, 3}, {5, 4}, {6, 5}, {2, 6}};
350+
ASSERT_EQ(N, Output.size());
351+
for (const auto &[InputIdx, OutputIdx] : SortedMap) {
352+
ASSERT_EQ(Input[InputIdx].Count, Output[OutputIdx].Count);
353+
ASSERT_EQ(Input[InputIdx].FileID, Output[OutputIdx].FileID);
354+
ASSERT_EQ(Input[InputIdx].startLoc(), Output[OutputIdx].startLoc());
355+
ASSERT_EQ(Input[InputIdx].endLoc(), Output[OutputIdx].endLoc());
356+
ASSERT_EQ(Input[InputIdx].Kind, Output[OutputIdx].Kind);
357+
}
358+
}
359+
360+
TEST_P(CoverageMappingTest, SkipMappingSorting) {
361+
startFunction("func", 0x1234);
362+
addMCDCDecisionCMR(3, 2, "file", 7, 1, 7, 12);
363+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 0, {-1, 1},
364+
"file", 7, 2, 7, 9);
365+
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 1, {-1, -1},
366+
"file", 7, 11, 7, 12);
367+
addMCDCDecisionCMR(7, 3, "file", 7, 2, 7, 9);
368+
addMCDCBranchCMR(Counter::getCounter(4), Counter::getCounter(5), 0, {-1, 1},
369+
"file", 7, 2, 7, 3);
370+
addMCDCBranchCMR(Counter::getCounter(6), Counter::getCounter(7), 1, {-1, 2},
371+
"file", 7, 5, 7, 6);
372+
addMCDCBranchCMR(Counter::getCounter(8), Counter::getCounter(9), 2, {-1, -1},
373+
"file", 7, 8, 7, 9);
374+
375+
const std::vector<CounterMappingRegion> MappingsBeforeSourt =
376+
InputFunctions.back().Regions;
377+
writeAndReadCoverageRegions(true, true);
378+
ASSERT_EQ(1u, InputFunctions.size());
379+
ASSERT_EQ(1u, OutputFunctions.size());
380+
const auto &Input = MappingsBeforeSourt;
381+
const auto &Output = OutputFunctions.back().Regions;
382+
383+
size_t N = ArrayRef(Input).size();
384+
ASSERT_EQ(N, Output.size());
385+
for (size_t I = 0; I < N; ++I) {
386+
ASSERT_EQ(Input[I].Count, Output[I].Count);
387+
ASSERT_EQ(Input[I].FileID, Output[I].FileID);
388+
ASSERT_EQ(Input[I].startLoc(), Output[I].startLoc());
389+
ASSERT_EQ(Input[I].endLoc(), Output[I].endLoc());
390+
ASSERT_EQ(Input[I].Kind, Output[I].Kind);
391+
}
392+
}
393+
319394
TEST_P(CoverageMappingTest, correct_deserialize_for_more_than_two_files) {
320395
const char *FileNames[] = {"bar", "baz", "foo"};
321396
static const unsigned N = std::size(FileNames);

0 commit comments

Comments
 (0)