github ↗
docs menu

Module Tolk.Decomp_op

Operations as the operations a target has.

Code generation lowers the operations a target lacks, and some it has, to cheaper ones: floor divisions to truncating ones, divisions by constants to multiplications and shifts, the Op.t.Threefry hash to integer arithmetic, and comparisons, negations and fused multiply-adds to the forms renderers expect. A target states its operations as a set of Op.t, the keys of its renderer's code_for_op.

Integer division

#val fast_idiv : Renderer.t -> Ops.t -> Bigint.t -> Ops.t option

fast_idiv r x d is x divided by the positive constant d, rounding towards zero, as a multiplication and a right shift: (x * m) >> s, for x's values from 0 to its upper bound. It shifts the powers of two out of d first when the product would overflow x's type, and otherwise computes in the next wider integer type if r supports it (Renderer.supported_dtypes). It is const_like x 0 if x's upper bound is below d, and None if d is not positive, x can be negative, or no such computation fits.

Threefry

#val threefry2x32 : Ops.t -> Ops.t -> Ops.t

threefry2x32 x key is the Threefry-2x32 hash of the Dtype.t.Uint64 counter x under key, with 20 rounds, as 32-bit additions, rotations and exclusive ors: the two 32-bit words of the result, high word second, in a Dtype.t.Uint64.

Patterns

#val simplifying_patterns : Op.Set.t -> (unit, Ops.t) Ops.Pattern_matcher.t

simplifying_patterns ops lowers, for a target with the operations ops:

  • a floor division (Op.t.Div) of an integer by a power of two, read in the integer's type, to a right shift if ops has Op.t.Shr, and any other to a truncating division (Op.t.Truncdiv), corrected where the operands' signs can differ and the divisor is not 0, by which the quotient is 0;
  • a floor remainder (Op.t.Mod) of an integer by a power of two, read in the integer's type, to a mask if ops has Op.t.And, and any other to a truncating remainder (Op.t.Truncmod), corrected where the operands' signs can differ;
  • Op.t.Threefry to threefry2x32 if ops lacks it.

A division or remainder of a committed integer reads a weak constant divisor in the integer's type, here and in late_patterns: on int8, a divisor of 128 is -128.

A set equal to an earlier call's gives that call's matcher.

#val late_patterns : disable_fast_idiv:bool -> Op.Set.t -> (Renderer.t, Ops.t) Ops.Pattern_matcher.t

late_patterns ~disable_fast_idiv ops rewrites, for a target with the operations ops and rendered by the context:

  • a minimum of a minimum against one value c, or a maximum of a maximum, each a selection of its comparison's operands, to one selection: the inner one where it picks c where its comparison is false, at a tie or a NaN, or where the two pick alike, and otherwise the selection of the inner one's other operand v that picks c there, where (v < c) v c for minima and where (c < v) v c for maxima;
  • Op.t.Max to a comparison and a selection if ops lacks it and has Op.t.Cmplt;
  • the conjunction of two negated booleans to the negated disjunction if ops has Op.t.Or;
  • a multiplication of an integer by a power of two, read modulo 2 to the integer's width, to a left shift if ops has Op.t.Shl: the shift is below the width, as on int32 x * 2^32 is x * 0;
  • if ops has Op.t.Shr, a truncating division of an integer by a power of two, read in the integer's type, to a right shift, rounding negative dividends up first; and, unless disable_fast_idiv, a truncating division or remainder by any other constant with fast_idiv where it applies;
  • multiplications by -1 to Op.t.Neg, and additions of a negation to Op.t.Sub, if ops has them;
  • if ops has Op.t.Cmplt, negated comparisons of signed integers with constants to comparisons, x * -1 < y * c to y * -c < x, x * -1 < c to -c < x, and c1 < x && x < c2 to x == c1 + 1 when it is the one integer between;
  • negated Op.t.Cmpeq to Op.t.Cmpne if ops has it;
  • a * b + c, and (x << n) + c, to Op.t.Mulacc if ops has it;
  • if ops has Op.t.Fdiv, reciprocals to a division of 1.0.

Arguments equal to those of an earlier call give that call's matcher.