29.01.2014 Views

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

SHOW MORE
SHOW LESS

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.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!