Module Cfg
val verbose : bool Stdlib.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 Cfg.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 Cfg.bool_test(*Check if the argument is even or odd
*)| Truth_test of Cfg.bool_test(*Check if the argument is true or false.
*)| Float_test of Cfg.float_test| Int_test of Cfg.int_test| Switch of Label.t array| Return| Raise of Lambda.raise_kind| Tailcall_self of {destination : Label.t;
}| Tailcall_func of Cfg.func_call_operation| Call_no_return of Cfg.external_call_operation| Call of Cfg.func_call_operation Cfg.with_label_after| Prim of Cfg.prim_call_operation Cfg.with_label_after
type basic_or_terminator = Cfg_intf.S.basic_or_terminator = | Basic of Cfg.basic| Terminator of Cfg.terminator
type basic_instruction_list =
Cfg.basic Cfg.instruction Oxcaml_utils.Doubly_linked_list.ttype basic_block = {mutable start : Label.t;body : Cfg.basic_instruction_list;mutable terminator : Cfg.terminator Cfg.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 -> Cfg.codegen_option listtype t = {blocks : Cfg.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 : Cfg.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:Cfg.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 ->
Cfg.tval fun_name : Cfg.t -> stringval predecessor_labels : Cfg.basic_block -> Label.t listval successor_labels :
normal:bool ->
exn:bool ->
Cfg.basic_block ->
Label.Set.texn does not account for exceptional flow from the block that goes outside of the function.
val replace_successor_labels :
Cfg.t ->
normal:bool ->
exn:bool ->
Cfg.basic_block ->
f:(Label.t -> Label.t) ->
unitval can_raise_interproc : Cfg.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 : Cfg.basic_block -> InstructionId.tval first_instruction_stack_offset : Cfg.basic_block -> intval add_block_exn : Cfg.t -> Cfg.basic_block -> unitval remove_blocks : Cfg.t -> Label.Set.t -> unitval get_block : Cfg.t -> Label.t -> Cfg.basic_block optionval get_block_exn : Cfg.t -> Label.t -> Cfg.basic_blockval iter_blocks_dfs : Cfg.t -> f:(Label.t -> Cfg.basic_block -> unit) -> unitval iter_blocks : Cfg.t -> f:(Label.t -> Cfg.basic_block -> unit) -> unitval fold_blocks :
Cfg.t ->
f:(Label.t -> Cfg.basic_block -> 'a -> 'a) ->
init:'a ->
'aval fold_body_instructions :
Cfg.t ->
f:('a -> Cfg.basic Cfg.instruction -> 'a) ->
init:'a ->
'aval register_predecessors_for_all_blocks : Cfg.t -> unitPrinting
val print_terminator :
Stdlib.Format.formatter ->
Cfg.terminator Cfg.instruction ->
unitval print_basic : Stdlib.Format.formatter -> Cfg.basic Cfg.instruction -> unitval print_instruction' :
?print_reg:(Stdlib.Format.formatter -> Reg.t -> unit) ->
Stdlib.Format.formatter ->
[ `Basic of Cfg.basic Cfg.instruction
| `Terminator of Cfg.terminator Cfg.instruction ] ->
unitval print_instruction :
Stdlib.Format.formatter ->
[ `Basic of Cfg.basic Cfg.instruction
| `Terminator of Cfg.terminator Cfg.instruction ] ->
unitval can_raise_terminator : Cfg.terminator -> boolval is_pure_terminator : Cfg.terminator -> boolval is_never_terminator : Cfg.terminator -> boolval is_return_terminator : Cfg.terminator -> boolval is_pure_basic : Cfg.basic -> boolval is_noop_move : Cfg.basic Cfg.instruction -> boolval is_alloc : Cfg.basic Cfg.instruction -> boolval is_poll : Cfg.basic Cfg.instruction -> boolval is_end_region : Cfg.basic -> boolval set_stack_offset : 'a Cfg.instruction -> int -> unitval set_live : 'a Cfg.instruction -> Reg.Set.t -> unitval dump_basic : Stdlib.Format.formatter -> Cfg.basic -> unitval dump_terminator :
?sep:string ->
Stdlib.Format.formatter ->
Cfg.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 Cfg.instructionval make_instruction_from_copy :
'a Cfg.instruction ->
desc:'b ->
id:InstructionId.t ->
?arg:Reg.t array ->
?res:Reg.t array ->
unit ->
'b Cfg.instructionval make_empty_block :
?label:Label.t ->
Cfg.terminator Cfg.instruction ->
Cfg.basic_blockval basic_block_contains_calls : Cfg.basic_block -> bool"Contains calls" in the traditional sense as used in upstream Selectgen.