Theory Traversal
subsection ‹Control-flow Graph Traversal›
theory
Traversal
imports
IRGraph
begin
type_synonym Seen = "ID set"
text ‹
nextEdge helps determine which node to traverse next by returning the first successor
edge that isn't in the set of already visited nodes.
If there is not an appropriate successor, None is returned instead.
›
fun nextEdge :: "Seen ⇒ ID ⇒ IRGraph ⇒ ID option" where
"nextEdge seen nid g =
(let nids = (filter (λnid'. nid' ∉ seen) (successors_of (kind g nid))) in
(if length nids > 0 then Some (hd nids) else None))"
text ‹
pred determines which node, if any, acts as the predecessor of another.
Merge nodes represent a special case where-in the predecessor exists as
an input edge of the merge node, to simplify the traversal we treat only
the first input end node as the predecessor, ignoring that multiple nodes
may act as a successor.
For all other nodes, the predecessor is the first element of the predecessors set.
Note that in a well-formed graph there should only be one element in the predecessor set.›
fun pred :: "IRGraph ⇒ ID ⇒ ID option" where
"pred g nid = (case kind g nid of
(MergeNode ends _ _) ⇒ Some (hd ends) |
_ ⇒
(if IRGraph.predecessors g nid = {}
then None else
Some (hd (sorted_list_of_set (IRGraph.predecessors g nid)))
)
)"
text ‹
Here we try to implement a generic fork of the control-flow traversal algorithm
that was initially implemented for the ConditionalElimination phase
›
type_synonym 'a TraversalState = "(ID × Seen × 'a)"
inductive Step
:: "('a TraversalState ⇒ 'a) ⇒ IRGraph ⇒ 'a TraversalState ⇒ 'a TraversalState option ⇒ bool"
for sa g where
"⟦kind g nid = BeginNode nid';
nid ∉ seen;
seen' = {nid} ∪ seen;
Some ifcond = pred g nid;
kind g ifcond = IfNode cond t f;
analysis' = sa (nid, seen, analysis)⟧
⟹ Step sa g (nid, seen, analysis) (Some (nid', seen', analysis'))" |
"⟦kind g nid = EndNode;
nid ∉ seen;
seen' = {nid} ∪ seen;
nid' = any_usage g nid;
analysis' = sa (nid, seen, analysis)⟧
⟹ Step sa g (nid, seen, analysis) (Some (nid', seen', analysis'))" |
"⟦¬(is_EndNode (kind g nid));
¬(is_BeginNode (kind g nid));
nid ∉ seen;
seen' = {nid} ∪ seen;
Some nid' = nextEdge seen' nid g;
analysis' = sa (nid, seen, analysis)⟧
⟹ Step sa g (nid, seen, analysis) (Some (nid', seen', analysis'))" |
"⟦¬(is_EndNode (kind g nid));
¬(is_BeginNode (kind g nid));
nid ∉ seen;
seen' = {nid} ∪ seen;
None = nextEdge seen' nid g⟧
⟹ Step sa g (nid, seen, analysis) None" |
"⟦nid ∈ seen⟧ ⟹ Step sa g (nid, seen, analysis) None"
code_pred (modes: i ⇒ i ⇒ i ⇒ o ⇒ bool) Step .
end