Module Cfg
val verbose : bool refinclude module type of struct include Cfg_intf.S end
type func_call_operation = Cfg_intf.S.func_call_operation = | Indirect of Cmm.symbol list option| Direct of Cmm.symbol
type external_call_operation = Cfg_intf.S.external_call_operation = {func_symbol : string;alloc : bool;effects : Cmm.effects;ty_res : Cmm.machtype;ty_args : Cmm.exttype list;stack_ofs : int;stack_align : Cmm.stack_align;
}type prim_call_operation = Cfg_intf.S.prim_call_operation = | External of external_call_operation| Probe of {}
type bool_test = Cfg_intf.S.bool_test = {ifso : Label.t;(*if test is true goto
*)ifsolabelifnot : Label.t;(*if test is false goto
*)ifnotlabel
}type int_test = Cfg_intf.S.int_test = {lt : Label.t;(*if x < y (resp. x < n) goto
*)ltlabeleq : Label.t;(*if x = y (resp. x = n) goto
*)eqlabelgt : Label.t;(*if x > y (resp. x > n) goto
*)gtlabelis_signed : Scalar.Signedness.t;imm : int option;
}int_test represents all possible outcomes of a comparison between two integers. When imm field is None, compare variables x and y, specified by the arguments of the enclosing instruction. When imm field is Some n, compare variable x and immediate n. This corresponds to Mach.Iinttest and Mach.Iinttest_imm in the compiler.
type float_test = Cfg_intf.S.float_test = {width : Cmm.float_width;lt : Label.t;eq : Label.t;gt : Label.t;uo : Label.t;(*if at least one of x or y is NaN
*)
}float_test represents possible outcomes of comparison between arguments x and y of type float. It is not enough to check "=,<,>" because possible outcomes of comparison include "unordered" (see e.g. x86-64 emitter) when the arguments involve NaNs.
type 'a instruction = 'a Cfg_intf.S.instruction = {desc : 'a;id : InstructionId.t;mutable arg : Reg.t array;mutable res : Reg.t array;mutable dbg : Debuginfo.t;mutable fdo : Fdo_info.t;mutable live : Reg.Set.t;mutable stack_offset : int;mutable available_before : Reg_availability_set.t;mutable available_across : Reg_availability_set.t;(*The availability sets will be set to
*)Unreachableprior to the availability analysis having run.
}type basic = Cfg_intf.S.basic = | Op of Operation.t| Reloadretaddr(*This instruction loads the return address from a predefined hidden address (e.g. bottom of the current frame) and stores it in a special hidden register. It can use standard registers for that purpose. They are defined in
*)Proc.destroyed_at_reloadretaddr.| Pushtrap of {lbl_handler : Label.t;
}| Poptrap of {lbl_handler : Label.t;
}| Prologue| Epilogue| Stack_check of {}
type terminator = Cfg_intf.S.terminator = | Never| Always of Label.t| Parity_test of bool_test(*Check if the argument is even or odd
*)| Truth_test of bool_test(*Check if the argument is true or false.
*)| Float_test of float_test| Int_test of int_test| Switch of Label.t array| Return| Raise of Lambda.raise_kind| Tailcall_self of {destination : Label.t;
}| Tailcall_func of func_call_operation| Call_no_return of external_call_operation| Invalid of {message : string;stack_ofs : int;stack_align : Cmm.stack_align;label_after : Label.t Option.t;
}| Call of func_call_operation with_label_after| Prim of prim_call_operation with_label_after
type basic_or_terminator = Cfg_intf.S.basic_or_terminator = | Basic of basic| Terminator of terminator
type basic_instruction_list =
basic instruction Oxcaml_utils.Doubly_linked_list.ttype basic_block = {mutable start : Label.t;body : basic_instruction_list;mutable terminator : terminator instruction;mutable predecessors : Label.Set.t;(*All predecessors, both normal and exceptional paths.
*)mutable stack_offset : int;(*Stack offset of the start of the block. Used for emitting adjust trap on edges from one block to the next.
*)mutable exn : Label.t option;(*All possible handlers of a raise that (1) can be triggered either by an explicit raise, or instructions such as calls and allocations, that appear(s) in this block; and (2) are within the same function.
*)exnsis a subset of the trap handler block labels of the cfg.mutable can_raise : bool;(*Does this block contain any instruction that can raise, such as a call, bounds check, allocation, or an explicit
*)raise?mutable is_trap_handler : bool;(*Is this block a trap handler (i.e. is it an exn successor of another block) or not?
*)mutable cold : bool;
}type codegen_option = | Reduce_code_size| No_CSE| Use_linscan_regalloc| Use_regalloc of Clflags.Register_allocator.t| Use_regalloc_param of string list| Cold| Assume_zero_alloc of {strict : bool;never_returns_normally : bool;never_raises : bool;loc : Location.t;
}| Check_zero_alloc of {strict : bool;loc : Location.t;custom_error_msg : string option;
}
val of_cmm_codegen_option : Cmm.codegen_option list -> codegen_option listtype t = {blocks : basic_block Label.Tbl.t;(*Map from labels to blocks
*)fun_name : string;(*Function name, used for printing messages
*)fun_args : Reg.t array;(*Function arguments. When Cfg is constructed from Linear, this information is not needed (Linear.fundecl does not have fun_args field) and
*)fun_argsis an empty array as a dummy value.fun_codegen_options : codegen_option list;(*Code generation options passed from Cmm.
*)fun_dbg : Debuginfo.t;(*Dwarf debug info for function entry.
*)entry_label : Label.t;(*This label must be the first in all layouts of this cfg.
*)fun_contains_calls : bool;(*Precomputed during selection and poll insertion.
*)fun_num_stack_slots : int Stack_class.Tbl.t;(*Precomputed at register allocation time
*)fun_poll : Lambda.poll_attribute;next_instruction_id : InstructionId.sequence;fun_ret_type : Cmm.machtype;(*Function return type. As in
*)fun_args, this value is not used when starting from Linear.mutable allowed_to_be_irreducible : bool;mutable register_locations_are_set : bool;
}Control Flow Graph of a function.
val create :
fun_name:string ->
fun_args:Reg.t array ->
fun_codegen_options:codegen_option list ->
fun_dbg:Debuginfo.t ->
fun_contains_calls:bool ->
fun_num_stack_slots:int Stack_class.Tbl.t ->
fun_poll:Lambda.poll_attribute ->
next_instruction_id:InstructionId.sequence ->
fun_ret_type:Cmm.machtype ->
allowed_to_be_irreducible:bool ->
tval fun_name : t -> stringval predecessor_labels : basic_block -> Label.t listval successor_labels : normal:bool -> exn:bool -> basic_block -> Label.Set.texn does not account for exceptional flow from the block that goes outside of the function.
val replace_successor_labels :
t ->
normal:bool ->
exn:bool ->
basic_block ->
f:(Label.t -> Label.t) ->
unitval can_raise_interproc : basic_block -> boolReturns true iff the passed block raises an exn that is not handled in this function, can_raise_interproc implies can_raise but not necessarily vice versa.
val first_instruction_id : basic_block -> InstructionId.tval first_instruction_stack_offset : basic_block -> intval add_block_exn : t -> basic_block -> unitval remove_blocks : t -> Label.Set.t -> unitval get_block : t -> Label.t -> basic_block optionval get_block_exn : t -> Label.t -> basic_blockval iter_blocks_dfs : t -> f:(Label.t -> basic_block -> unit) -> unitval iter_blocks : t -> f:(Label.t -> basic_block -> unit) -> unitval fold_blocks : t -> f:(Label.t -> basic_block -> 'a -> 'a) -> init:'a -> 'aval fold_body_instructions :
t ->
f:('a -> basic instruction -> 'a) ->
init:'a ->
'aval register_predecessors_for_all_blocks : t -> unitPrinting
val print_terminator : Format.formatter -> terminator instruction -> unitval print_basic : Format.formatter -> basic instruction -> unitval print_instruction' :
?print_reg:(Format.formatter -> Reg.t -> unit) ->
Format.formatter ->
[ `Basic of basic instruction | `Terminator of terminator instruction ] ->
unitval print_instruction :
Format.formatter ->
[ `Basic of basic instruction | `Terminator of terminator instruction ] ->
unitval can_raise_terminator : terminator -> boolval is_pure_terminator : terminator -> boolval is_never_terminator : terminator -> boolval is_return_terminator : terminator -> boolval is_pure_basic : basic -> boolval is_noop_move : basic instruction -> boolval is_alloc : basic instruction -> boolval is_poll : basic instruction -> boolval is_end_region : basic -> boolval set_stack_offset : 'a instruction -> int -> unitval set_live : 'a instruction -> Reg.Set.t -> unitval dump_basic : Format.formatter -> basic -> unitval dump_terminator : ?sep:string -> Format.formatter -> terminator -> unitval make_instruction :
desc:'a ->
?arg:Reg.t array ->
?res:Reg.t array ->
?dbg:Debuginfo.t ->
?fdo:Fdo_info.t ->
?live:Reg.Set.t ->
stack_offset:int ->
id:InstructionId.t ->
?available_before:Reg_availability_set.t ->
?available_across:Reg_availability_set.t ->
unit ->
'a instructionval make_instruction_from_copy :
'a instruction ->
desc:'b ->
id:InstructionId.t ->
?arg:Reg.t array ->
?res:Reg.t array ->
unit ->
'b instructionval make_empty_block : ?label:Label.t -> terminator instruction -> basic_blockval basic_block_contains_calls : basic_block -> bool"Contains calls" in the traditional sense as used in upstream Selectgen.
val equal_func_call_operation :
func_call_operation ->
func_call_operation ->
boolval equal_external_call_operation :
external_call_operation ->
external_call_operation ->
boolval equal_prim_call_operation :
prim_call_operation ->
prim_call_operation ->
boolval equal_terminator : terminator -> terminator -> bool