Module Low_level.Access_fold

Ordered read-only Low_level traversal. Every policy decision is mandatory. Statements are visited before children and after their reads; Seq is left-to-right. Tile_mma descends through its equivalent fallback. A Prune skips children AND the after hook. Hooks may prune Tile_mma or Scan_loop when the consumer treats them as opaque.

Visit discarded operands is structural; Skip follows rendering. Gated operands are visited in source order (both Where arms), never combined as a cost bound. Skip gated operands skips the entire subtree, including hoisted definitions: it is NOT an execution floor. Consumers with branch algebras can prune scalars and supply their own reduction. Scope bodies reset gated because definitions hoist, while preserving statement guards. Dead-loop bodies visited structurally carry live=false; this does not evaluate constant guards or perform cleanup's placement-dependent setter elimination.

Scan init assignments precede the body; rotation assignments follow it. With scan_implicit = Skip, init expressions are still visited but synthetic Set_local events are absent. Scans must satisfy validate_scan_loops (in particular nonempty ranges). The fold visits a loop body once, not once per iteration; rotation events describe value dependencies rather than simulating simultaneous assignment. implicit identifies synthetic statements and their descendants; scope_depth counts Local_scope bodies.

type visit =
  1. | Visit
  2. | Skip
type guards =
  1. | Track
  2. | Ignore
type implicit =
  1. | Explicit
  2. | Scan_init
  3. | Scan_rotate
type policy = {
  1. discarded_operands : visit;
  2. gated_operands : visit;
  3. dead_loops : visit;
  4. local_scopes : visit;
  5. guards : guards;
  6. scan_implicit : visit;
}
type context = {
  1. live : Base.bool;
  2. guards : scalar_arg Base.list;
  3. gated : Base.bool;
  4. scope_depth : Base.int;
  5. implicit : implicit;
}
type 'a descent =
  1. | Continue of 'a
  2. | Prune of 'a
type 'a hooks = {
  1. statement : context -> 'a -> t -> 'a descent;
  2. scalar : context -> 'a -> scalar_t -> 'a descent;
  3. after_statement : context -> 'a -> t -> 'a;
  4. after_scalar : context -> 'a -> scalar_t -> 'a;
}
val hooks : Base.unit -> 'a hooks
val fold : policy:policy -> hooks:'a hooks -> init:'a -> t -> 'a