let translate_instruction (i : LTL.instruction) : LIN.instruction =
match i with
| LTL.INewFrame _ ->
LIN.INewFrame
| LTL.IDeleteFrame _ ->
LIN.IDeleteFrame
| LTL.IGetStack (r, slot, _) ->
LIN.IGetStack (r, slot)
| LTL.ISetStack (slot, r, _) ->
LIN.ISetStack (slot, r)
| LTL.IConst (r, i, _) ->
LIN.IConst (r, i)
| LTL.IUnOp (op, r1, r2, _) ->
LIN.IUnOp (op, r1, r2)
| LTL.IBinOp (op, r, r1, r2, _) ->
LIN.IBinOp (op, r, r1, r2)
| LTL.ICall (callee, _) ->
LIN.ICall callee
| LTL.ILoad (r1, r2, o, _) ->
LIN.ILoad (r1, r2, o)
| LTL.IStore (r1, o, r2, _) ->
LIN.IStore (r1, o, r2)
| LTL.IGoto _ ->
assert false
| LTL.IUnBranch (cond, r, l1, _) ->
LIN.IUnBranch (cond, r, l1)
| LTL.IBinBranch (cond, r1, r2, l1, _) ->
LIN.IBinBranch (cond, r1, r2, l1)
| LTL.IReturn ->
LIN.IReturn
| LTL.ITailCall callee ->
LIN.ITailCall callee
let translate entry graph =
let visited, required, instructions =
ref Label.Set.empty, ref (Label.Set.singleton entry), ref []
in
let module V = Ltl2linI.Visit (struct
let fetch label =
Label.Map.find label graph
let translate_instruction =
translate_instruction
let generate instruction =
instructions := instruction :: !instructions
let require label =
required := Label.Set.add label !required
let mark label =
visited := Label.Set.add label !visited
let marked label =
Label.Set.mem label !visited
end) in
V.visit entry;
List.filter (function
| LIN.ILabel l ->
Label.Set.mem l !required
| _ ->
true
) (List.rev !instructions)
let translate_procedure proc =
let entry, graph = Branch.compress proc.LTL.entry proc.LTL.graph in
{
LIN.formals = proc.LTL.formals;
LIN.locals = proc.LTL.locals;
LIN.code = translate entry graph
}
let translate_program (p : LTL.program) : LIN.program =
{
LIN.globals = p.LTL.globals;
LIN.defs = StringMap.map translate_procedure p.LTL.defs
}