rocq/backend/IrTerm.v
The checked IR back as Prolog terms: the encoders of the syntax of Syntax.v, the inverse of Transport.v's decoders, so that the backend can print an instruction as the very term the Prolog compiler printed it as (nanofilabi − termsFILE).
Each encoder writes the one term its decoder reads its value from: when the decoder reads a term t as x, the encoder writes x as t, and the decoder reads that as x again. No decoder reads one value from two terms, so there is no spelling to choose.
The encoders are total, but not every value of the syntax has a term. What is written for a value that no term decodes to:
Toof a label that is itselfpoll(L)is writtenpoll(L), which reads back asPollof L (enc_target);- a
RawStoreof widthpis writtenraw_store(p, ...), which the decoder refuses: a pointer store israw_store_pointer(enc_inst); ExtF,FloatToIntandIntToFloatat a class ir.pl has no such op for are written as terms that are not ops, which the decoder refuses (enc_op).
The examples at the end check both directions, by computation, on terms the Prolog compiler printed for nanofil/tests/filc.
Values and the small tables
As ir.pl writes a value: tmp(N), const(N) or global(S).
As ir.pl writes the bound a half check tests: upper or lower.
As ir.pl writes a narrow integer type: sw, uw, sh, uh, sb or ub.
As ir.pl writes one memory effect of a raw pointer load or store: aux_read, lower_resolve, address_read, atomic_read, aux_ensure, lower_barrier, rooted_reload, lower_write, address_write or atomic_write.
As ir.pl writes the Effects of a raw pointer load or store: the list of its effects, in order.
Ops
As ir.pl writes an Op: an atom such as add or ptoi, or a compound such as cmp(Cond, K), ext(T), alloc(Align), check(Lo, Hi, Rights, Align), check_ahead(Lo, Hi, Rights, Align, AHi), half_check(Bound, Lo, Hi, Rights, Align), span_test(Lo, Hi), limit(Size), check_local(Name, Off, Bytes, Rights, Align), raw_load(T, Off) or raw_load_pointer(Off, Effects).
A float widening is ext(s) or ext(d), naming its source class; a float to an integer is stosi, stoui, dtosi, dtoui, xtosi or xtoui, and an integer to a float swtof, uwtof, sltof or ultof. Those are all the conversions ir.pl has. At any other class ExtF k is written ext(K), and FloatToInt k sg and IntToFloat k sg are written float_to_int(K, Sg) and int_to_float(K, Sg), Sg being signed or unsigned: none of them is an op, and the decoder refuses each.
Instructions
As ir.pl writes a flight's Lower: none or lower(V).
As ir.pl writes one result of a call, the temporary d of class k: result(tmp(D), K).
As ir.pl writes a call's Res: void, result(tmp(D), K), or tuple([result(tmp(D1), K1), result(tmp(D2), K2)]).
As ir.pl writes a call's argument, the class first: arg(K, V).
As ir.pl writes a call's arguments: the list of them.
As ir.pl writes an instruction: let(tmp(D), K, Op, Args), flight(tmp(D), Op, Args, Lower), raw_store(Width, Off, Value, Addr), raw_store_pointer(Off, Value, Addr, Effects), call(Res, Callee, Args), raw_call(Res, Callee, Args), local_alloc(Name, Size), loc(File, Line) or touch(tmp(Q)).
A RawStore of the width Wp is written raw_store(p, ...), which is not an instruction of the IR (a pointer store is raw_store_pointer) and which the decoder refuses.
Jumps and phis
As ir.pl writes the jump that ends a block: goto(L), branch(V, L1, L2), ret(V), rets([V1, V2]), ret or unreachable.
Examples
The decoder dec reads the term t, and the encoder enc writes what it read as t again. Then dec also reads what enc wrote as the same value, since that is t: one statement checks both directions.
The decoder dec reads back each value of xs from the term the encoder enc writes for it.
Every class is read back from eclass's atom for it.
Proof 2 steps Qed
Both rights are read back.
Proof 2 steps Qed
Both bounds are read back.
Proof 2 steps Qed
Every narrow type is read back.
Proof 2 steps Qed
Every load type is read back.
Proof 3 steps Qed
Every condition is read back.
Proof 2 steps Qed
Every effect is read back.
Proof 2 steps Qed
Every width is read back.
Proof 2 steps Qed
Every value is read back.
Proof 2 steps Qed
The two effect lists of a pointer load, and the empty one.
Proof 1 step Qed
Every op that is an atom, the float conversions among them.
Proof 1 step Qed
Every op that is a compound, one or two of each.
Proof 1 step Qed
The conversions ir.pl does not have are refused, each one.
Proof 1 step Qed
A raw store of a pointer is refused, and a label poll(l) reads back as a poll edge.
Proof 1 step Qed
let(tmp(chk0), a, check(0, 8, write, 1), [tmp(p)]): a check.
Proof 1 step Qed
let(tmp(chk0), a, check_local(x, 0, 1, read, 1), []): a check of a named local, which reads no argument.
Proof 1 step Qed
let(tmp(a), l, raw_load(sb, 0), [tmp(chk3)]): a raw load.
Proof 1 step Qed
let(tmp(back), p, raw_load_pointer(0, [aux_read, lower_resolve, address_read]), [tmp(chk2)]): a raw pointer load.
Proof 1 step Qed
let(tmp(c), w, cmp(eq, w), [tmp(k), const(1)]): a comparison.
Proof 1 step Qed
let(tmp(b), d, ext(s), [tmp(a)]): a float widening.
Proof 1 step Qed
let(tmp(kl), l, ext(sw), [tmp(k)]): an integer extension.
Proof 1 step Qed
let(tmp(r), w, dtosi, [tmp(b)]): a float to an integer.
Proof 1 step Qed
let(tmp(base), p, copy, [global(g)]): a symbol's address.
Proof 1 step Qed
raw_store(l, 0, const(-2), tmp(chk0)): a raw store.
Proof 1 step Qed
raw_store_pointer(0, tmp(obj), tmp(chk1), [aux_ensure, lower_barrier, rooted_reload, lower_write, address_write]): a raw pointer store.
Proof 1 step Qed
flight(tmp(q), add, [address(tmp(p)), const(8)], lower(tmp(p))): a flight with a lower.
Proof 1 step Qed
flight(tmp(f), copy, [tmp(i)], none): a flight without one.
Proof 1 step Qed
call(void, global(churn), []): a call with no result.
Proof 1 step Qed
call(result(tmp(p), p), global(make), [arg(l, tmp(v))]): a call with one result.
Proof 1 step Qed
call(tuple([result(tmp(c), l), result(tmp(d), l)]), global(two), [arg(l, tmp(a))]): a call with a tuple of results.
Proof 1 step Qed
raw_call(result(tmp(a), s), tmp(chk0), [arg(s, const(1069547520))]): a call of a proven function.
Proof 1 step Qed
raw_call(tuple([result(tmp(g), l), result(tmp(h), l)]), tmp(chk2), [arg(l, tmp(x))]): one with a tuple of results.
Proof 1 step Qed
local_alloc(x, 13): a named local.
Proof 1 step Qed
loc('basic.c', 12): a source position.
Proof 1 step Qed
branch(tmp(c), poll(fill), sum): a branch, one edge polling.
Proof 1 step Qed
goto(poll(loop)): a goto that polls.
Proof 1 step Qed
goto(end): a plain goto.
Proof 1 step Qed
ret(const(1)): a return of one value.
Proof 1 step Qed
rets([tmp(n), tmp(m)]): a return of a tuple.
Proof 1 step Qed
ret: a return from a void function.
Proof 1 step Qed
unreachable.
Proof 1 step Qed
phi(tmp(i), w, [start-const(0), fill-tmp(i1)]): a phi of two edges.