Skip to main content

Module coverage

Module coverage 

Source
Expand description

Which IR opcodes have somewhere to go, and which do not.

Design: spec/10-backend.md section 10.2, under Coverage.

Every opcode has to be lowered by something or be a hole somebody wrote down. Without this the way a hole is found is that somebody compiles a program containing one and the selector reports that it cannot lower an instruction, which is a fine diagnostic and a bad discovery mechanism: it turns a gap in the rule set into a user’s problem rather than a failing build.

§The three answers

An opcode is lowered by a rule, or somewhere a rule cannot reach, or nowhere.

The first is the ordinary answer and the one this can check by itself. crate::term says every name a rule could be written at, the table says every name one is written at, and an opcode is covered when each of its names is in both. That is what makes this a check about widths rather than about opcodes: an add with a rule at four widths and no rule at the fifth is not covered, and would be reported here as the missing name rather than as a covered opcode.

The second is ELSEWHERE, which is not a gap. spec/10-backend.md names five of them and there are more now, and they are all the same kind of thing: an opcode whose lowering depends on something no pattern can see. Where a call’s arguments go depends on the signature, where a local lives depends on the frame, an unconditional jump is an edge and edges live on the block, and a memcpy is a run of moves whose length is a constant the pattern would have to count. A rule matches one term and can say none of that.

The third is GAPS, which is the number spec/15-testing.md section 15.8 says we keep. Each entry names why it is there and the issue that closes it, so that an opcode nobody has written a rule for is a decision somebody wrote down rather than a surprise.

WIDTHS and NAMES are the same third answer said about something smaller than an opcode. A width on WIDTHS has no names at all, so no opcode is missing a rule at it, and a name on NAMES is one width of an opcode that lowers at its other widths. Both carry the issue that closes them for the same reason GAPS does.

§What makes the lists honest

An entry that stops being true fails. An opcode on either list that a rule starts covering is a stale entry and the tests below say so by name, which is the same rule the exclusion lists in the compatibility harness are kept under: a list nothing checks is a list that only grows.

The direction this cannot check is an opcode moving from GAPS to ELSEWHERE without the list following it, because where an opcode is lowered by name is a match arm and there is nothing to ask about a match arm from here. What that costs is one line of a list going out of date; what it does not cost is a gap going unnoticed, since the opcode is still on a list and still counted.

§The other question

All of the above is about the rule set as it is written. Fired is about the rule set as it is used: which rules a compilation actually reached. A rule nothing reaches is proved and dead weight, or it is a construct the corpus does not contain and somebody should know which. The selector marks a rule as it fires it, the driver writes the marks out under -Zrule-coverage=FILE, and the harness in tamnd/rucc-compat unions those files over a corpus, which is what turns coverage of the rule set into a number. spec/20-execution-testing.md section 20.9 is the design and tamnd/rucc#261 is the work.

Structs§

Fired
Which rules fired, over one function or over a whole compilation.
Report
What a target’s rules cover, and what they do not.

Statics§

ELSEWHERE
An opcode no rule is written about, and the place that lowers it instead.
GAPS
An opcode nothing lowers, why it is here, and the issue that closes it.
NAMES
A name a rule could be written at and deliberately is not, why, and the issue that puts it back.
WIDTHS
A width no rule is written at, why, and the issue that closes it.

Functions§

report
What a table covers.
table
The rules a target lowers by, or None where no back end in this crate covers it.