Module Sarek_ppx_lib.Sarek_tailrec_pragma

Pragma-Based Inlining

val max_inlined_nodes : int

Maximum number of AST nodes allowed after inlining. Prevents code explosion from exponential recursion like fib.

val count_nodes : Sarek_typed_ast.texpr -> int

Count AST nodes in an expression

val parse_sarek_inline_pragma : string list -> int option

Parse pragma options to extract sarek.inline depth. Returns Some depth for "sarek.inline N", None otherwise.

val is_unroll_pragma : string list -> bool

Check if pragma is an unroll pragma

Substitute a variable in an expression with another expression

val substitute_recursive_calls : string -> Sarek_typed_ast.tparam list -> Sarek_typed_ast.texpr -> Sarek_typed_ast.texpr -> Sarek_typed_ast.texpr

Substitute all occurrences of a recursive call with the function body. This is one step of mechanical inlining.

IMPORTANT: We do NOT recurse into the substituted body - that happens in the next inlining round. This ensures we do exactly N rounds of inlining.

Instead of creating let-bindings (which generate statement expressions that OpenCL doesn't support), we directly substitute parameter values into the body.

val inline_with_pragma : string -> Sarek_typed_ast.tparam list -> Sarek_typed_ast.texpr -> int -> (Sarek_typed_ast.texpr, string) Stdlib.result

Inline a recursive function N times using pragma "sarek.inline N". Returns Ok new_expr if successful, Error message if failed.

Note: After inlining, some calls may remain syntactically present but they will be in dead code branches (e.g., after the base case condition). We emit a warning but allow the code to proceed, trusting the GPU compiler to eliminate dead code.