[RFC] Integrating SingleByteCoverage with Branch Coverage

I’m proposing changes to integrate SingleByteCoverage with Branch coverage. SingleByteCoverage, introduced in #75425, currently suppresses Branch coverage. I’ve tested a prototype with good results.

Cc: @evodius96 @gulfemsavrun @ellishg

Overview of SingleByteCoverage

SingleByteCoverage uses binary counters set to False (0xFF, initial value) and True (0x00) to save on instruction bytes. It avoids using CounterExpr and suppresses Branch coverage. This works well on manycore builders, where using 64-bit counters is very difficult.

SingleByteCoverage and CounterExpr

The current implementation of SingleByteCoverage avoids CounterExpr. However, CounterExpr::Add is still available because counters can be handled as if their upper limit is 1, but CounterExpr::Subtract is unavailable. Most subtractions happen in BranchRegions, so extra counters are needed for False paths.

Counter expressions from non-SingleByteCoverage can be used by replacing and removing CounterExpr::Subtract.

Proposed Plan

  1. Introduce “CounterPair” for BranchRegions on RegionCounterMap.
  2. Add more counters for False paths.
  3. By enabling CounterExpr, introduce a new option or rewind parts of the current implementation.

Additional Ideas

Reducing Counters more with FalsePath

Example:

C0++; // ParentCnt
if (Cond)
  C1++; // TruePath
else
  C2++; // FalsePath, (C0 - C1)

Replace (C0 - C1) with C2, and apply C0 = (C1 + C2). We can remove C0 if all instances in a function can be replaced. This isn’t always possible.

Selective Counter Activation

BranchRegion flags are exclusive between TruePath and FalsePath. An intrinsic for selective flag setting could help:

Counter[Cond ? TrueIdx : FalseIdx] = true;

If TruePath is replaced with CounterExpr, use:

if (!Cond) Counter[FalseIdx] = true;

This works better with conditional-counter-update mode.

Using MC/DC Test Vectors

As mentioned in 79629, binary counters are equivalent to MC/DC test vectors, which can be used to reduce counter numbers in MC/DC mode.

Thank you.

P.S. I’ll attend the devmtg2024.

1 Like

I will also be at devmtg2024

1 Like

I’m very supportive of this proposal, and thanks for looking into this @chapuni. I’ll be in the Developers’ Meeting as well. We should definitely catch up with all the recent development and the current progress in instrumentation and coverage in general.

1 Like

Not to drift off topic, but if you’re actively working in this area, are there architectural changes we could make to coverage that would make it easy to carry all these benefits over to Rust? IIUC single byte coverage is ABI incompatible with classic coverage, and this presents challenges for Chromium’s use of code coverage.

cc @hansw2000 @ayzhao

I’ve pushed some NFC requests as the preparation.

I’ve pushed almost all requests. I know I have to add more tests.

This is the merged all-in-one branch.

This is a preparation.

They are actual updates.

Please take a look. Feedbacks are welcome.
Thanks.

I added llvm-cov tests for singlebytecoverage. I think my changes are ready for commit.

I’ve created the index into #113115.