open RTLabs
type node = Label.t
(** Successors of a statement *)
val statement_successors : statement -> node list
(** computes a map binding each node to its set of predecessors. The domain
is guaranteed to be equal to the domain of the input graph *)
val compute_predecessors : graph -> Label.Set.t Label.Map.t
(** computes a map binding each node to its list of predecessors. The domain
is guaranteed to be equal to the domain of the input graph *)
val compute_predecessor_lists : graph -> Label.t list Label.Map.t
(** Fills the labels of the statement with ones provided as argument. If not
enough labels are provided it raises Invalid_arguement. If more than enough
labels are provided, exceeding labels are ignored *)
val fill_labels : statement -> Label.t list -> statement
(** Given a graph and an entry point, this function deletes all unreachable
nodes *)
val dead_code_elim : graph -> node -> graph
(** [insert_in_between u g src tgt s] inserts [s] between [src] and [tgt].
[tgt] should be a successor of [src], and the provided [s] should already be
linked to [tgt]. This function just generates a new node containing [s]
and updates [src]'s links to [tgt] to be pointing to this new node.
If [src] is linked to [tgt] multiple times, all such links are updated.
The generated label is provided alongside the new graph. *)
val insert_in_between :
(unit -> node) -> graph -> node -> node -> statement -> Label.t * graph
(** [dfs_fold f g entry a] preforms a fold with function [f] and initial value
[a] doing a depth-first sweep of [g] from entry node [entry]. In particular
all unreachable nodes are ignored. *)
val dfs_fold : (node -> statement -> 'a -> 'a) -> graph -> node -> 'a -> 'a
(** [dfs_fold f g entry a] preforms an iteration of function [f] performing a
depth-first sweep of [g] from entry node [entry]. In particular
all unreachable nodes are ignored. *)
val dfs_iter : (node -> statement -> unit) -> graph -> node -> unit
(** Computes a map from register to their types in the function
TODO: are gloabl variables registers too? *)
val computes_type_map : internal_function -> AST.sig_type Register.Map.t
(** Tells what local register is directly modified by the statement, if any *)
val modified_at_stmt : statement -> Register.t option
(** [modified_at g l] is the same as [modified_at_stmt s] where [s] is the
statement in [g] at [l]. *)
val modified_at : graph -> node -> Register.t option