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

29.01.2014 Views

CHAPTER 3. DATAFLOW ANALYSIS 30 let instrOddEvens (il : instr list) (vml : varmap list) : varmap list list = let proc one hil i = match hil with | [ ] → (varmap list handle inst i vml) :: hil | vml' :: rst as l → (varmap list handle inst i vml') :: l in il | > L.fold left proc one [vml] |> L.tl |> L.rev Now that we can get the state on entry to statements and instructions, we can make a special visitor class such that when we inherit from it, the resulting visitor will have the current OddEven state available in every method. The vmlVisitorClass class inherits from nopCilVisitor. When visiting a statement, if the statement is a list of instructions, it uses instrOddEvens to store the entry states into a mutable instance eld state list. If the statement is not an instruction list, it uses getOddEvens to put the state on entry to the statement into another mutable instance eld current state. When an instruction is visited, it takes the head of state list, writes it to current state, and removes the rst state of state list. The visitor also adds a method get cur vml(), which returns current state. Inheriting from this visitor will cause the state found by the analysis on entry to a statement or an instruction to be available in the vstmt and vinst methods of the inheriting class. Classes inheriting from vmlVisitorClass must call super#vstmt and super#vinst if they override vstmt or vinst respectively. To get the current state, inheriting classes can call self#get cur vml. Additionally, when passing an inheritor of vmlVisitorClass to a function requiring a nopCilVisitor, we must do an up-cast because of the additional method get cur vml(). See the function evenOddAnalysis below. class vmlVisitorClass = object(self) inherit nopCilVisitor val mutable sid = − 1 val mutable state list = [ ] val mutable current state = None method vstmt stm = sid ← stm.sid; begin match getOddEvens sid with | None → current state ← None | Some vml → begin match stm.skind with | Instr il → current state ← None; state list ← instrOddEvens il vml | → current state ← None end end;

CHAPTER 3. DATAFLOW ANALYSIS 31 DoChildren method vinst i = try let data = L.hd state list in current state ← Some(data); state list ← L.tl state list; DoChildren with Failure "hd" → DoChildren method get cur vml () = match current state with | None → getOddEvens sid | Some vml → Some vml end The class varUseReporterClass inherits from vmlVisitorClass. Whenever it visits a variable use, it emits the oekind it nds for it in the current state as given by super#get cur vml(). class varUseReporterClass = object(self) inherit vmlVisitorClass as super method vvrbl (vi : varinfo) = match self#get cur vml () with | None → SkipChildren | Some vml → begin if L.mem assoc vi.vid vml then begin let vm = (vi.vid, L.assoc vi.vid vml) in E.log "%a: %a\n" d loc (!currentLoc) varmap list pretty [vm] end; SkipChildren end end The function evenOddAnalysis computes the OddEven analysis. It then invokes the varUseReporter visitor. Note that we have to coerce our visitor to a nopCilVisitor because we added the get cur vml() method. let evenOddAnalysis (fd : fundec) (loc : location) : unit = computeOddEven fd; let vis = ((new varUseReporterClass) :> nopCilVisitor) in ignore(visitCilFunction vis fd) The tut3 function is the entry point to this module. It applies evenOddAnalysis to all functions. let tut3 (f : file) : unit = iterGlobals f (onlyFunctions evenOddAnalysis)

CHAPTER 3. DATAFLOW ANALYSIS 31<br />

DoChildren<br />

method vinst i =<br />

try let data = L.hd state list in<br />

current state ← Some(data);<br />

state list ← L.tl state list;<br />

DoChildren<br />

with Failure "hd" → DoChildren<br />

method get cur vml () =<br />

match current state with<br />

| None → getOddEvens sid<br />

| Some vml → Some vml<br />

end<br />

The class varUseReporterClass inherits from vmlVisitorClass. Whenever it visits a variable use,<br />

it emits the oekind it nds for it in the current state as given by super#get cur vml().<br />

class varUseReporterClass = object(self)<br />

inherit vmlVisitorClass as super<br />

method vvrbl (vi : varinfo) =<br />

match self#get cur vml () with<br />

| None → SkipChildren<br />

| Some vml → begin<br />

if L.mem assoc vi.vid vml then begin<br />

let vm = (vi.vid, L.assoc vi.vid vml) in<br />

E.log "%a: %a\n" d loc (!currentLoc) varmap list pretty [vm]<br />

end;<br />

SkipChildren<br />

end<br />

end<br />

The function evenOddAnalysis computes the OddEven analysis. It then invokes the varUseReporter<br />

visitor. Note that we have to coerce our visitor to a nopCilVisitor because we added the<br />

get cur vml() method.<br />

let evenOddAnalysis (fd : fundec) (loc : location) : unit =<br />

computeOddEven fd;<br />

let vis = ((new varUseReporterClass) :> nopCilVisitor) in<br />

ignore(visitCilFunction vis fd)<br />

The tut3 function is the entry point to this module. It applies evenOddAnalysis to all functions.<br />

let tut3 (f : file) : unit =<br />

iterGlobals f (onlyFunctions evenOddAnalysis)

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

Saved successfully!

Ooh no, something went wrong!