let compute_pdg_for_f kf =
let pdg = BuildPdg.create kf in
let f_locals, f_stmts =
if !Db.Value.use_spec_instead_of_definition kf then [], []
else let f = Kernel_function.get_definition kf in
f.slocals, f.sbody.bstmts
in
let init_state =
let _ = BuildPdg.process_entry_point pdg f_stmts in
let formals = Kernel_function.get_formals kf in
BuildPdg.process_declarations pdg formals f_locals
in
let froms = match f_stmts with
| [] ->
let state = init_state in
BuildPdg.store_last_state pdg state ;
let froms = !Db.From.get kf in
Some (froms)
| start :: stmts ->
let ctrl_dpds_infos = CtrlDpds.compute kf in
let module Computer = Computer (struct
let current_pdg = pdg
let ctrl_dpds_infos = ctrl_dpds_infos
end)
in
let module Compute = Dataflow.ForwardsDataFlow(Computer) in
if Db.Value.is_reachable_stmt start then
begin
let init_state = Computer.computeFirstPredecessor start init_state in
Computer.StmtStartData.add start.sid init_state ;
let rec add acc l = match l with [] -> acc
| s::tl ->
Computer.StmtStartData.add s.sid BuildPdg.empty_state;
add (s::acc) tl
in
let starts = add [start] (ctrl_no_preds stmts) in
Compute.compute starts ;
None
end
else
raise
(Err_Bot
(Printf.sprintf "unreachable entry point (sid:%d, function %s)"
start.sid (Kernel_function.get_name kf)))
in
let pdg = BuildPdg.finalize_pdg pdg froms in
pdg