let compute_ctrl_info pdg ctrl_part used_stmts =
let module CtrlComputer = Computer (struct let states = ctrl_part end) in
let module CtrlCompute = Dataflow.Backwards(CtrlComputer) in
let seen = Stmt.Hashtbl.create 50 in
let rec add_node_ctrl_nodes new_stmts node =
let ctrl_nodes = !Db.Pdg.direct_ctrl_dpds pdg node in
List.fold_left add_ctrl_node new_stmts ctrl_nodes
and add_ctrl_node new_stmts ctrl_node =
debug2 "[zones] add ctrl node %a@." PdgTypes.Node.pretty ctrl_node;
match PdgTypes.Node.stmt ctrl_node with
| None ->
add_node_ctrl_nodes new_stmts ctrl_node
| Some stmt ->
debug2 "[zones] node %a is stmt %d@."
PdgTypes.Node.pretty ctrl_node stmt.sid;
if Stmt.Hashtbl.mem seen stmt then new_stmts
else
let ctrl_zone = match stmt.skind with
| Switch (exp,_,_,_) | If (exp,_,_,_) -> Data.exp_zone stmt exp
| _ -> Data.bottom
in Ctx.add ctrl_part stmt ctrl_zone;
Stmt.Hashtbl.add seen stmt ();
debug2 "[zones] add ctrl zone %a at stmt %d@."
Data.pretty ctrl_zone stmt.sid;
stmt::new_stmts
and add_stmt_ctrl new_stmts stmt =
debug1 "[zones] add ctrl of stmt %d@." stmt.sid;
if Stmt.Hashtbl.mem seen stmt then new_stmts
else begin
Stmt.Hashtbl.add seen stmt ();
match !Db.Pdg.find_simple_stmt_nodes pdg stmt with
| [] -> []
| n::_ -> add_node_ctrl_nodes new_stmts n
end
in
let rec add_stmts_ctrl stmts all_used_stmts =
let all_used_stmts = stmts @ all_used_stmts in
let new_stmts = List.fold_left add_stmt_ctrl [] stmts in
let preds = List.fold_left (fun acc s -> s.preds @ acc) [] new_stmts in
if preds <> [] then CtrlCompute.compute preds;
let used_stmts = CtrlComputer.get_and_reset_used_stmts () in
if used_stmts = [] then all_used_stmts
else add_stmts_ctrl used_stmts all_used_stmts
in
add_stmts_ctrl used_stmts []