[AI] light internal refactoring of the scheduler

Summary: This simplifies the code and helps later diffs.

Reviewed By: skcho

Differential Revision: D21154064

fbshipit-source-id: d00359423
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent 401ecc2406
commit 60184a5e73

@ -149,9 +149,8 @@ module AbstractInterpreterCommon (TransferFunctions : TransferFunctions.SIL) = s
L.d_printfln_escaped "%t" pp_all L.d_printfln_escaped "%t" pp_all
let exec_instrs ~pp_instr proc_data node node_id ~visit_count pre inv_map = let exec_instrs ~pp_instr proc_data node pre =
let instrs = CFG.instrs node in let instrs = CFG.instrs node in
let post =
if Config.write_html then L.d_printfln_escaped "PRE STATE:@\n@[%a@]@\n" Domain.pp pre ; if Config.write_html then L.d_printfln_escaped "PRE STATE:@\n@[%a@]@\n" Domain.pp pre ;
let compute_post pre instr = let compute_post pre instr =
AnalysisState.set_instr instr ; AnalysisState.set_instr instr ;
@ -169,20 +168,18 @@ module AbstractInterpreterCommon (TransferFunctions : TransferFunctions.SIL) = s
Error (exn, backtrace, instr) Error (exn, backtrace, instr)
in in
if Config.write_html then dump_html ~pp_instr pre instr result ; if Config.write_html then dump_html ~pp_instr pre instr result ;
result match result with
in | Ok post ->
(* hack to ensure that we call `exec_instr` on a node even if it has no instructions *) post
let instrs = if Instrs.is_empty instrs then Instrs.singleton Sil.skip_instr else instrs in
Container.fold_result ~fold:Instrs.fold ~init:pre instrs ~f:compute_post
in
match post with
| Ok astate_post ->
InvariantMap.add node_id {State.pre; post= astate_post; visit_count} inv_map
| Error (exn, backtrace, instr) -> | Error (exn, backtrace, instr) ->
if not !logged_error then ( if not !logged_error then (
L.internal_error "In instruction %a@\n" (Sil.pp_instr ~print_types:true Pp.text) instr ; L.internal_error "In instruction %a@\n" (Sil.pp_instr ~print_types:true Pp.text) instr ;
logged_error := true ) ; logged_error := true ) ;
Caml.Printexc.raise_with_backtrace exn backtrace Caml.Printexc.raise_with_backtrace exn backtrace
in
(* hack to ensure that we call `exec_instr` on a node even if it has no instructions *)
let instrs = if Instrs.is_empty instrs then Instrs.singleton Sil.skip_instr else instrs in
Instrs.fold ~f:compute_post ~init:pre instrs
(* Note on narrowing operations: we defines the narrowing operations simply to take a smaller one. (* Note on narrowing operations: we defines the narrowing operations simply to take a smaller one.
@ -190,9 +187,18 @@ module AbstractInterpreterCommon (TransferFunctions : TransferFunctions.SIL) = s
let exec_node ~pp_instr ({ProcData.summary} as proc_data) node ~is_loop_head ~is_narrowing let exec_node ~pp_instr ({ProcData.summary} as proc_data) node ~is_loop_head ~is_narrowing
astate_pre inv_map = astate_pre inv_map =
let node_id = Node.id node in let node_id = Node.id node in
let update_inv_map pre ~visit_count = let update_inv_map inv_map new_pre old_state_opt =
let inv_map' = exec_instrs ~pp_instr proc_data node node_id ~visit_count pre inv_map in let new_post = exec_instrs ~pp_instr proc_data node new_pre in
(inv_map', DidNotReachFixPoint) let new_visit_count =
match old_state_opt with
| None ->
VisitCount.first_time
| Some {State.visit_count; _} ->
VisitCount.succ ~pdesc:(Summary.get_proc_desc summary) visit_count
in
InvariantMap.add node_id
{State.pre= new_pre; post= new_post; visit_count= new_visit_count}
inv_map
in in
let inv_map, converged = let inv_map, converged =
if InvariantMap.mem node_id inv_map then if InvariantMap.mem node_id inv_map then
@ -218,14 +224,10 @@ module AbstractInterpreterCommon (TransferFunctions : TransferFunctions.SIL) = s
"Terminate narrowing because old and new states are not comparable at %a:%a@." "Terminate narrowing because old and new states are not comparable at %a:%a@."
Procname.pp (Summary.get_proc_name summary) Node.pp_id node_id ; Procname.pp (Summary.get_proc_name summary) Node.pp_id node_id ;
(inv_map, ReachedFixPoint) ) (inv_map, ReachedFixPoint) )
else else (update_inv_map inv_map new_pre (Some old_state), DidNotReachFixPoint)
let visit_count' =
VisitCount.succ ~pdesc:(Summary.get_proc_desc summary) old_state.State.visit_count
in
update_inv_map new_pre ~visit_count:visit_count'
else else
(* first time visiting this node *) (* first time visiting this node *)
update_inv_map astate_pre ~visit_count:VisitCount.first_time (update_inv_map inv_map astate_pre None, DidNotReachFixPoint)
in in
( match converged with ( match converged with
| ReachedFixPoint -> | ReachedFixPoint ->

Loading…
Cancel
Save