kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

ir_eval.h (3211B)


      1 #ifndef KIT_CG_IR_EVAL_H
      2 #define KIT_CG_IR_EVAL_H
      3 
      4 /* Width-aware integer constant-fold core: the single definition of the
      5  * arithmetic semantics that several layers used to transcribe in lockstep
      6  * (cg/fold.c's api_try_fold_int_*, opt/pass_o2.c's gvn_fold_*, and the
      7  * width/convert helpers in opt/pass_combine.c + pass_simplify.c).
      8  *
      9  * Dependency-light by design: it pulls in only cg/cgtarget.h (for the BinOp /
     10  * UnOp / CmpOp / ConvKind op tags and the integer typedefs) and operates on
     11  * plain (op tag, width-in-bits, i64 bit-patterns). It knows NOTHING about
     12  * Compiler, cg/internal.h, or the optimizer's IR types, so BOTH the semantic
     13  * codegen (cg/) and the optimizer (opt/) can include it.
     14  *
     15  * Each caller keeps its own TYPE-SELECTION policy (which types are foldable,
     16  * how a width is derived from a type, where div/rem faults live): this header
     17  * shares only the value arithmetic once a width has been chosen. `width` is the
     18  * scalar bit width (1..64); the eval entry points return 0 for op tags they do
     19  * not evaluate, leaving *out untouched. */
     20 
     21 #include "cg/cgtarget.h"
     22 
     23 /* Low `width` bits set (width>=64 -> all ones). */
     24 u64 kit_ir_width_mask(u32 width);
     25 
     26 /* `v` masked to its low `width` bits. */
     27 u64 kit_ir_mask_width(u64 v, u32 width);
     28 
     29 /* `v` interpreted as a `width`-bit value, sign-extended to a full i64. */
     30 i64 kit_ir_sign_extend_width(u64 v, u32 width);
     31 
     32 /* Fold an integer binop at the given width. Operands are masked to `width`
     33  * first; the wrapping result is masked back to `width`. Shifts mask the count
     34  * to (width-1). Returns 1 and stores the masked result for the wrapping
     35  * arithmetic/bitwise/shift ops; returns 0 (and leaves *out untouched) for
     36  * div/rem/float/anything else — those stay with their owning caller. */
     37 int kit_ir_eval_binop(BinOp op, u32 width, i64 a, i64 b, i64* out);
     38 
     39 /* Fold an integer unop at the given width (NEG/NOT/BNOT). Returns 1 and stores
     40  * the masked result, or 0 for unhandled tags. */
     41 int kit_ir_eval_unop(UnOp op, u32 width, i64 a, i64* out);
     42 
     43 /* Fold an integer compare at the given width. Operands are masked to `width`;
     44  * signed predicates compare the sign-extended values. Returns 1 and stores the
     45  * 0/1 boolean for the 10 integer predicates, or 0 for the FP predicates. */
     46 int kit_ir_eval_cmp(CmpOp op, u32 width, i64 a, i64 b, i64* out);
     47 
     48 /* Fold a bit-preserving integer/pointer convert from `src_width` to `dst_width`
     49  * bits (TRUNC / ZEXT / SEXT / BITCAST). BITCAST requires equal widths. Returns
     50  * 1 and stores the converted constant (masked to `dst_width`); returns 0 for
     51  * the float-domain conversions, which reinterpret the bits and must not fold
     52  * this way. */
     53 int kit_ir_eval_convert(ConvKind k, u32 src_width, u32 dst_width, i64 src,
     54                         i64* out);
     55 
     56 /* Integer commutativity: the binops/compares whose operands may be swapped
     57  * without changing the integer result. (FP commutativity is intentionally NOT
     58  * unified here: callers that fold FP keep their own predicate, since NaN
     59  * payloads and ordered/unordered routing can make operand order observable.) */
     60 int kit_ir_binop_is_commutative_int(BinOp op);
     61 int kit_ir_cmp_is_commutative_int(CmpOp op);
     62 
     63 #endif /* KIT_CG_IR_EVAL_H */