module type ForwardsTransfer = sig
.. end
Interface to provide for a backward dataflow analysis.
val name : string
For debugging purposes, the name of the analysis
val debug : bool Pervasives.ref
Whether to turn on debugging
type
t
The type of the data we compute for each block start. May be
imperative.
val copy : t -> t
Make a deep copy of the data.
val pretty : Format.formatter -> t -> unit
Pretty-print the state.
val computeFirstPredecessor : Cil_types.stmt -> t -> t
Given the first value for a predecessors, compute the value to be set
for the block.
val combinePredecessors : Cil_types.stmt ->
old:t ->
t -> t option
Take some old data for the start of a statement, and some new data for the
same point. Return None if the combination is identical to the old
data. Otherwise, compute the combination, and return it.
val doInstr : Cil_types.stmt ->
Cil_types.instr ->
t -> t Dataflow.action
The (forwards) transfer function for an instruction. The
(Cil.CurrentLoc.get ())
is set before calling this. The default action
is to continue with the state unchanged. stmt
is the statement
englobing instr
.
val doGuard : Cil_types.stmt ->
Cil_types.exp ->
t ->
t Dataflow.guardaction *
t Dataflow.guardaction
Generate the successors th, el
to an If statement assuming the given
expression is respectively nonzero and zero. Analyses that don't need
guard information can return GDefault, GDefault; this is equivalent to
returning GUse of the input. A return value of GUnreachable indicates
that this half of the branch will not be taken and should not be explored.
This will be called once per If. stmt
is the corresponding If
statement FYI only.
val doStmt : Cil_types.stmt ->
t ->
t Dataflow.stmtaction
The (forwards) transfer function for a statement. The (Cil.CurrentLoc.get
())
* is set before calling this. The default action is to do the
instructions * in this statement, if applicable, and continue with the
successors.
val filterStmt : Cil_types.stmt -> bool
Whether to put this statement in the worklist. This is called when a block
would normally be put in the worklist.
val stmt_can_reach : Cil_types.stmt -> Cil_types.stmt -> bool
Must return true
if ther is a path in the control-flow graph of the
function from the first statement to the second. Used to choose a "good"
node in the worklist. Suggested use is let stmt_can_reach =
Stmts_graph.stmt_can_reach kf
, where kf
is the kernel_function
being analyzed; let stmt_can_reach _ _ = true
is also correct,
albeit less efficient
val doEdge : Cil_types.stmt ->
Cil_types.stmt -> t -> t
what to do when following the edge between the two given statements.
Can default to identity if nothing special is required.
module StmtStartData: Dataflow.StmtStartData
with type data = t
For each statement id, the data at the start.