Module Cmm_helpers

bind name arg fn is equivalent to let name = arg in fn name, or simply fn arg if arg is simple enough

val bind_load : string -> Cmm.expression -> (Cmm.expression -> Cmm.expression) -> Cmm.expression

Same as bind, but also treats loads from a variable as simple

val bind_nonvar : string -> Cmm.expression -> (Cmm.expression -> Cmm.expression) -> Cmm.expression

Same as bind, but does not treat variables as simple

Headers

val caml_black : nativeint

A null header with GC bits set to black

val floatarray_tag : Debuginfo.t -> Cmm.expression

A constant equal to the tag for float arrays

val block_header : int -> int -> nativeint

block_header tag size creates a header with tag tag for a block of size size

val black_block_header : int -> int -> nativeint

Same as block_header, but with GC bits set to black

val white_closure_header : int -> nativeint

Closure headers of the given size

val black_closure_header : int -> nativeint
val infix_header : int -> nativeint

Infix header at the given offset

val float_header : nativeint

Header for a boxed float value

val floatarray_header : int -> nativeint

Header for an unboxed float array of the given size

val string_header : int -> nativeint

Header for a string (or bytes) of the given length

val boxedint32_header : nativeint

Boxed integer headers

val boxedint64_header : nativeint
val boxedintnat_header : nativeint
val closure_info : arity:int -> startenv:int -> nativeint

Closure info for a closure of given arity and distance to environment

val alloc_float_header : Debuginfo.t -> Cmm.expression

Wrappers

val alloc_floatarray_header : int -> Debuginfo.t -> Cmm.expression
val alloc_closure_header : int -> Debuginfo.t -> Cmm.expression
val alloc_infix_header : int -> Debuginfo.t -> Cmm.expression
val alloc_closure_info : arity:int -> startenv:int -> Debuginfo.t -> Cmm.expression
val alloc_boxedint32_header : Debuginfo.t -> Cmm.expression
val alloc_boxedint64_header : Debuginfo.t -> Cmm.expression
val alloc_boxedintnat_header : Debuginfo.t -> Cmm.expression

Integers

val max_repr_int : int

Minimal/maximal OCaml integer values whose backend representation fits in a regular OCaml integer

val min_repr_int : int
val int_const : Debuginfo.t -> int -> Cmm.expression

Make an integer constant from the given integer (tags the integer)

val cint_const : int -> Cmm.data_item
val targetint_const : int -> Targetint.t
val natint_const_untagged : Debuginfo.t -> Stdlib.Nativeint.t -> Cmm.expression

Make a Cmm constant holding the given nativeint value. Uses Cconst_int instead of Cconst_nativeint when possible to preserve peephole optimisations.

val add_const : Cmm.expression -> int -> Debuginfo.t -> Cmm.expression

Add an integer to the given expression

Increment/decrement of integers

val ignore_low_bit_int : Cmm.expression -> Cmm.expression

Simplify the given expression knowing its last bit will be irrelevant

val ignore_high_bit_int : Cmm.expression -> Cmm.expression

Simplify the given expression knowing its first bit will be irrelevant

Arithmetical operations on integers

Integer tagging. tag_int x = (x lsl 1) + 1

Integer untagging. untag_int x = (x asr 1)

Specific division operations for boxed integers

If-Then-Else expression mk_if_then_else dbg cond ifso_dbg ifso ifnot_dbg ifnot associates dbg to the global if-then-else expression, ifso_dbg to the then branch ifso, and ifnot_dbg to the else branch ifnot

Boolean negation

Integer and float comparison that returns int not bool

val mk_compare_floats : Debuginfo.t -> Cmm.expression -> Cmm.expression -> Cmm.expression
val create_loop : Cmm.expression -> Debuginfo.t -> Cmm.expression

Loop construction (while true do expr done). Used to be represented as Cloop.

val raise_symbol : Debuginfo.t -> string -> Cmm.expression

Exception raising

Convert a tagged integer into a raw integer with boolean meaning

Float boxing and unboxing

val unbox_float : Debuginfo.t -> Cmm.expression -> Cmm.expression

Complex number creation and access

val return_unit : Debuginfo.t -> Cmm.expression -> Cmm.expression

Make the given expression return a unit value

val remove_unit : Cmm.expression -> Cmm.expression

Remove a trailing unit return if any

Blocks

val field_address : Cmm.expression -> int -> Debuginfo.t -> Cmm.expression

field_address ptr n dbg returns an expression for the address of the nth field of the block pointed to by ptr

get_field_gen mut ptr n dbg returns an expression for the access to the nth field of the block pointed to by ptr

set_field ptr n newval init dbg returns an expression for setting the nth field of the block pointed to by ptr to newval

Load a block's header

val get_header_without_profinfo : Cmm.expression -> Debuginfo.t -> Cmm.expression

Same as get_header, but also set all profiling bits of the header are to 0 (if profiling is enabled)

Load a block's tag

Load a block's size

Arrays

val wordsize_shift : int
val numfloat_shift : int
val is_addr_array_hdr : Cmm.expression -> Debuginfo.t -> Cmm.expression

Check whether the given array is an array of regular OCaml values (as opposed to unboxed floats), from its header or pointer

val is_addr_array_ptr : Cmm.expression -> Debuginfo.t -> Cmm.expression
val addr_array_length_shifted : Cmm.expression -> Debuginfo.t -> Cmm.expression

Get the length of an array from its header Shifts by one bit less than necessary, keeping one of the GC colour bits, to save an operation when returning the length as a caml integer or when comparing it to a caml integer. Assumes the header does not have any profiling info (as returned by get_header_without_profinfo)

val float_array_length_shifted : Cmm.expression -> Debuginfo.t -> Cmm.expression

For array_indexing ?typ log2size ptr ofs dbg : Produces a pointer to the element of the array ptr on the position ofs with the given element log2size log2 element size. ofs is given as a tagged int expression. The optional ?typ argument is the C-- type of the result. By default, it is Addr, meaning we are constructing a derived pointer into the heap. If we know the pointer is outside the heap (this is the case for bigarray indexing), we give type Int instead.

Array loads and stores unboxed_float_array_ref and float_array_ref differ in the boxing of the result; float_array_set takes an unboxed float

val unboxed_float_array_ref : Cmm.expression -> Cmm.expression -> Debuginfo.t -> Cmm.expression

Strings

val string_length : Cmm.expression -> Debuginfo.t -> Cmm.expression
val bigstring_length : Cmm.expression -> Debuginfo.t -> Cmm.expression

Objects

Lookup a method by its hash, using caml_get_public_method Arguments :

  • obj : the object from which to lookup
  • tag : the hash of the method name, as a tagged integer

Lookup a method by its offset in the method table Arguments :

  • obj : the object from which to lookup
  • lab : the position of the required method in the object's method array, as a tagged integer

Lookup and call a method using the method cache Arguments :

  • obj : the object from which to lookup
  • tag : the hash of the method name, as a tagged integer
  • cache : the method cache array
  • pos : the position of the cache entry in the cache array
  • args : the additional arguments to the method call

Allocations

val make_alloc : Debuginfo.t -> int -> Cmm.expression list -> Cmm.expression

Allocate a block of regular values with the given tag

val make_float_alloc : Debuginfo.t -> int -> Cmm.expression list -> Cmm.expression

Allocate a block of unboxed floats with the given tag

Bounds checking

val make_checkbound : Debuginfo.t -> Cmm.expression list -> Cmm.expression

Generate a Ccheckbound term

check_bound safety access_size dbg length a2 k prefixes expression k with a check that reading access_size bits starting at position a2 in a string/bytes value of length length is within bounds, unless safety is Unsafe.

Sys.opaque_identity

Generic application functions

val apply_function_sym : int -> string

Get the symbol for the generic application with n arguments, and ensure its presence in the set of defined symbols

val curry_function_sym : int -> string

If n is positive, get the symbol for the generic currying wrapper with n arguments, and ensure its presence in the set of defined symbols. Otherwise, do the same for the generic tuple wrapper with -n arguments.

Bigarrays

bigarray_get unsafe kind layout b args dbg

  • unsafe : if true, do not insert bound checks
  • kind : see Lambda.bigarray_kind
  • layout : see Lambda.bigarray_layout
  • b : the bigarray to load from
  • args : a list of tagged integer expressions, corresponding to the indices in the respective dimensions
  • dbg : debugging information

bigarray_set unsafe kind layout b args newval dbg Same as bigarray_get, with newval the value being assigned

Operations on 32-bit integers

low_32 _ x is a value which agrees with x on at least the low 32 bits

val sign_extend_32 : Debuginfo.t -> Cmm.expression -> Cmm.expression

Sign extend from 32 bits to the word size

val zero_extend_32 : Debuginfo.t -> Cmm.expression -> Cmm.expression

Zero extend from 32 bits to the word size

Boxed numbers

val caml_nativeint_ops : string

Global symbols for the ops field of boxed integers

val caml_int32_ops : string
val caml_int64_ops : string

Box a given integer, without sharing of constants

Unbox a given boxed integer

Used to prepare 32-bit integers on 64-bit platforms for a lsr operation

val unaligned_load_16 : Cmm.expression -> Cmm.expression -> Debuginfo.t -> Cmm.expression
val unaligned_load_32 : Cmm.expression -> Cmm.expression -> Debuginfo.t -> Cmm.expression
val unaligned_load_64 : Cmm.expression -> Cmm.expression -> Debuginfo.t -> Cmm.expression

Raw memory accesses

unaligned_set size ptr idx newval dbg

unaligned_load size ptr idx dbg

box_sized size dbg exp

Primitives

type unary_primitive = Cmm.expression -> Debuginfo.t -> Cmm.expression
val floatfield : int -> unary_primitive

Return the n-th field of a float array (or float-only record), as an unboxed float

val int_as_pointer : unary_primitive

Int_as_pointer primitive

Raise primitive

val negint : unary_primitive

Unary negation of an OCaml integer

val offsetint : int -> unary_primitive

Add a constant number to an OCaml integer

val offsetref : int -> unary_primitive

Add a constant number to an OCaml integer reference

val arraylength : Lambda.array_kind -> unary_primitive

Return the length of the array argument, as an OCaml integer

Byte swap primitive Operates on Cmm integers (unboxed values)

val bswap16 : unary_primitive

16-bit byte swap primitive Operates on Cmm integers (untagged integers)

type binary_primitive = Cmm.expression -> Cmm.expression -> Debuginfo.t -> Cmm.expression
type assignment_kind =
  1. | Caml_modify
  2. | Caml_initialize
  3. | Simple

setfield offset value_is_ptr init ptr value dbg

setfloatfield offset init ptr value dbg value is expected to be an unboxed floating point number

val add_int_caml : binary_primitive

Operations on OCaml integers

val sub_int_caml : binary_primitive
val mul_int_caml : binary_primitive
val div_int_caml : Lambda.is_safe -> binary_primitive
val mod_int_caml : Lambda.is_safe -> binary_primitive
val and_int_caml : binary_primitive
val or_int_caml : binary_primitive
val xor_int_caml : binary_primitive
val lsl_int_caml : binary_primitive
val lsr_int_caml : binary_primitive
val asr_int_caml : binary_primitive

Strings, Bytes and Bigstrings

val stringref_unsafe : binary_primitive

Regular string/bytes access. Args: string/bytes, index

val stringref_safe : binary_primitive

Load by chunk from string/bytes, bigstring. Args: string, index

Arrays

val arrayref_unsafe : Lambda.array_kind -> binary_primitive

Array access. Args: array, index

val arrayref_safe : Lambda.array_kind -> binary_primitive

Same as setfield, except the offset is one of the arguments. Args: pointer (structure/array/...), index, value

val bytesset_unsafe : ternary_primitive

Set the byte at the given offset to the given value. Args: bytes, index, value

val bytesset_safe : ternary_primitive
val arrayset_unsafe : Lambda.array_kind -> ternary_primitive

Set the element at the given index in the given array to the given value. WARNING: if kind is Pfloatarray, then value is expected to be an _unboxed_ float. Otherwise, it is expected to be a regular caml value, including in the case where the array contains floats. Args: array, index, value

val arrayset_safe : Lambda.array_kind -> ternary_primitive

Set a chunk of data in the given bytes or bigstring structure. See also string_load and bigstring_load. Note: value is expected to be an unboxed number of the given size. Args: pointer, index, value

Switch

transl_isout h arg dbg

val make_switch : Cmm.expression -> int array -> (Cmm.expression * Debuginfo.t) array -> Debuginfo.t -> Cmm.expression

make_switch arg cases actions dbg : Generate a Cswitch construct, or optimize as a static table lookup when possible.

val transl_int_switch : Debuginfo.t -> Cmm.expression -> int -> int -> (int * Cmm.expression) list -> Cmm.expression -> Cmm.expression

transl_int_switch loc arg low high cases default

val transl_switch_clambda : Debuginfo.t -> Cmm.expression -> int array -> Cmm.expression array -> Cmm.expression

transl_switch_clambda loc arg index cases

val strmatch_compile : Debuginfo.t -> Cmm.expression -> Cmm.expression option -> (string * Cmm.expression) list -> Cmm.expression

strmatch_compile dbg arg default cases

Closures and function applications

val ptr_offset : Cmm.expression -> int -> Debuginfo.t -> Cmm.expression

Adds a constant offset to a pointer (for infix access)

val direct_apply : string -> Cmm.expression list -> Debuginfo.t -> Cmm.expression

Direct application of a function via a symbol

Generic application of a function to one or several arguments. The mutable_flag argument annotates the loading of the code pointer from the closure. The Cmmgen code uses a mutable load by default, with a special case when the load is from (the first function of) the currently defined closure.

Method call : send kind met obj args dbg

  • met is a method identifier, which can be a hashed variant or an index in obj's method table, depending on kind
  • obj is the object whose method is being called
  • args is the extra arguments to the method call (Note: I'm not aware of any way for the frontend to generate any arguments other than the cache and cache position)

Generic Cmm fragments

val generic_functions : bool -> Cmx_format.unit_infos list -> Cmm.phrase list

Generate generic functions

val placeholder_dbg : unit -> Debuginfo.t
val placeholder_fun_dbg : human_name:string -> Debuginfo.t
val entry_point : string list -> Cmm.phrase

Entry point

val global_table : string list -> Cmm.phrase

Generate the caml_globals table

val reference_symbols : string list -> Cmm.phrase

Add references to the given symbols

val globals_map : (string * Stdlib.Digest.t option * Stdlib.Digest.t option * string list) list -> Cmm.phrase

Generate the caml_globals_map structure, as a marshalled string constant

val frame_table : string list -> Cmm.phrase

Generate the caml_frametable table, referencing the frametables from the given compilation units

val data_segment_table : string list -> Cmm.phrase

Generate the tables for data and code positions respectively of the given compilation units

val code_segment_table : string list -> Cmm.phrase
val predef_exception : int -> string -> Cmm.phrase

Generate data for a predefined exception

val plugin_header : (Cmx_format.unit_infos * Stdlib.Digest.t) list -> Cmm.phrase

Emit constant symbols

val cdefine_symbol : (string * Cmmgen_state.is_global) -> Cmm.data_item list

Produce the data_item list corresponding to a symbol definition

val emit_block : (string * Cmmgen_state.is_global) -> nativeint -> Cmm.data_item list -> Cmm.data_item list

emit_block symb white_header cont prepends to cont the header and symbol for the block. cont must already contain the fields of the block (and may contain additional data items afterwards).

val emit_float_constant : (string * Cmmgen_state.is_global) -> float -> Cmm.data_item list -> Cmm.data_item list

Emit specific kinds of constant blocks as data items

val emit_string_constant : (string * Cmmgen_state.is_global) -> string -> Cmm.data_item list -> Cmm.data_item list
val emit_int32_constant : (string * Cmmgen_state.is_global) -> int32 -> Cmm.data_item list -> Cmm.data_item list
val emit_int64_constant : (string * Cmmgen_state.is_global) -> int64 -> Cmm.data_item list -> Cmm.data_item list
val emit_nativeint_constant : (string * Cmmgen_state.is_global) -> nativeint -> Cmm.data_item list -> Cmm.data_item list
val emit_float_array_constant : (string * Cmmgen_state.is_global) -> float list -> Cmm.data_item list -> Cmm.data_item list
val fundecls_size : Clambda.ufunction list -> int
val emit_constant_closure : (string * Cmmgen_state.is_global) -> Clambda.ufunction list -> Cmm.data_item list -> Cmm.data_item list -> Cmm.data_item list
val emit_preallocated_blocks : Clambda.preallocated_block list -> Cmm.phrase list -> Cmm.phrase list