@ -45,33 +45,33 @@ let bottom_up sources : target task_generator =
(* this will potentially grossly overapproximate the tasks *)
(* this will potentially grossly overapproximate the tasks *)
let remaining = ref ( count_procedures () ) in
let remaining = ref ( count_procedures () ) in
let remaining_tasks () = ! remaining in
let remaining_tasks () = ! remaining in
let g = CallGraph. create initial_call_graph_capacity in
let g = Syntactic CallGraph. create initial_call_graph_capacity in
let initialized = ref false in
let initialized = ref false in
let pending : CallGraph. Node . t list ref = ref [] in
let pending : Syntactic CallGraph. Node . t list ref = ref [] in
let scheduled = ref Typ . Procname . Set . empty in
let scheduled = ref Typ . Procname . Set . empty in
let is_empty () =
let is_empty () =
let empty = ! initialized && List . is_empty ! pending && Typ . Procname . Set . is_empty ! scheduled in
let empty = ! initialized && List . is_empty ! pending && Typ . Procname . Set . is_empty ! scheduled in
if empty then (
if empty then (
remaining := 0 ;
remaining := 0 ;
L . progress " Finished call graph scheduling, %d procs remaining (in cycles).@. "
L . progress " Finished call graph scheduling, %d procs remaining (in cycles).@. "
( CallGraph. n_procs g ) ;
( Syntactic CallGraph. n_procs g ) ;
if Config . debug_level_analysis > 0 then CallGraph. to_dotty g " cycles.dot " ;
if Config . debug_level_analysis > 0 then Syntactic CallGraph. to_dotty g " cycles.dot " ;
(* save some memory *)
(* save some memory *)
CallGraph. reset g ) ;
Syntactic CallGraph. reset g ) ;
empty
empty
in
in
let rec next_aux () =
let rec next_aux () =
match ! pending with
match ! pending with
| [] ->
| [] ->
pending := CallGraph. get_unflagged_leaves g ;
pending := Syntactic CallGraph. get_unflagged_leaves g ;
if List . is_empty ! pending then None else next_aux ()
if List . is_empty ! pending then None else next_aux ()
| n :: ns when n . flag | | not ( CallGraph. mem g n . id ) ->
| n :: ns when n . flag | | not ( Syntactic CallGraph. mem g n . id ) ->
pending := ns ;
pending := ns ;
next_aux ()
next_aux ()
| n :: ns ->
| n :: ns ->
pending := ns ;
pending := ns ;
scheduled := Typ . Procname . Set . add n . pname ! scheduled ;
scheduled := Typ . Procname . Set . add n . pname ! scheduled ;
CallGraph. flag_reachable g n . pname ;
Syntactic CallGraph. flag_reachable g n . pname ;
Some ( Procname n . pname )
Some ( Procname n . pname )
in
in
let finished = function
let finished = function
@ -80,12 +80,12 @@ let bottom_up sources : target task_generator =
| Procname pname ->
| Procname pname ->
decr remaining ;
decr remaining ;
scheduled := Typ . Procname . Set . remove pname ! scheduled ;
scheduled := Typ . Procname . Set . remove pname ! scheduled ;
CallGraph. remove_reachable g pname
Syntactic CallGraph. remove_reachable g pname
in
in
let next () =
let next () =
(* do construction here, to avoid having the call graph into forked workers *)
(* do construction here, to avoid having the call graph into forked workers *)
if not ! initialized then (
if not ! initialized then (
CallGraph. build_from_sources g sources ;
Syntactic CallGraph. build_from_sources g sources ;
initialized := true ) ;
initialized := true ) ;
next_aux ()
next_aux ()
in
in