A CIL Tutorial - Department of Computer Science - ETH Zürich
A CIL Tutorial - Department of Computer Science - ETH Zürich
A CIL Tutorial - Department of Computer Science - ETH Zürich
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
CHAPTER 9. TYPE QUALIFIER INFERENCE 76<br />
The function findColorNodes invokes the nodeColorFinder visitor on the le f with the graph g.<br />
let findColoredNodes (f : file) (g : graph) : unit =<br />
let vis = new nodeColorFinder g in<br />
visitCilFile vis f<br />
The function colors equal ensures that every color <strong>of</strong> c1 is somewhere in c2 and that every color<br />
<strong>of</strong> c2 is somewhere in c1. That is it checks that the lists have the same elements.<br />
let colors equal (c1 : colors) (c2 : colors) : bool =<br />
L.for all (fun c → L.mem c c2) c1 ∧<br />
L.for all (fun c → L.mem c c1) c2<br />
Now that the graph has been seeded by a few type qualiers, we can see where else in the graph<br />
they must ow. We'll accomplish this by doing the following. First, we put all the nodes in the<br />
graph into a queue. Then, for each node that we pop o the queue, we'll nd the least-upper-bound<br />
<strong>of</strong> the qualier on the node itself along with the qualiers on the nodes for incoming edges; these are<br />
the types that it must include. If the least-upper-bound qualier is dierent, we'll assign the new<br />
qualier to the node, and then add the nodes on outgoing edges to the end <strong>of</strong> the queue. When the<br />
qualier lattice has nite height, as it does here, we can be sure that the algorithm will terminate.<br />
The function enqueueNodes places each <strong>of</strong> the nodes in our graph on a queue and returns the<br />
queue.<br />
let enqueueNodes (g : graph) : int Q.t =<br />
let q = Q.create () in<br />
A.iteri (fun i → Q.add i q) g;<br />
q<br />
The function processNode folds over the incoming edges <strong>of</strong> a node, computing the least-upperbound<br />
<strong>of</strong> the types on the origin nodes. If the result is dierent from the starting type, it adds the<br />
new type to the graph and return true. Otherwise it returns false.<br />
let processNode (g : graph) (id : int) : bool =<br />
let c' =<br />
L.fold left (fun c id' → list union c g.(id').ncolors)<br />
g.(id).ncolors g.(id).incoming<br />
in<br />
if ¬(colors equal g.(id).ncolors c') then begin<br />
g.(id).ncolors ← c';<br />
true<br />
end else false<br />
The function processQueue applies processNode to each node <strong>of</strong> the graph g on queue q. If<br />
processNode for some node returns true, it adds the destinations <strong>of</strong> the node's outgoing edges to<br />
the end <strong>of</strong> the queue.