|  |  | @ -127,16 +127,22 @@ module Node = struct | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   type node = t |  |  |  |   type node = t | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   let pp_id f id = F.pp_print_int f id | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   let pp f node = pp_id f (get_id node) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   module NodeSet = Caml.Set.Make (struct |  |  |  |   module NodeSet = Caml.Set.Make (struct | 
			
		
	
		
		
			
				
					
					|  |  |  |     type t = node |  |  |  |     type t = node | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     let compare = compare |  |  |  |     let compare = compare | 
			
		
	
		
		
			
				
					
					|  |  |  |   end) |  |  |  |   end) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   module IdMap = Caml.Map.Make (struct |  |  |  |   module IdMap = PrettyPrintable.MakePPMap (struct | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     type t = id |  |  |  |     type t = id | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     let compare = compare_id |  |  |  |     let compare = compare_id | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let pp = pp_id | 
			
		
	
		
		
			
				
					
					|  |  |  |   end) |  |  |  |   end) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   let get_exn node = node.exn |  |  |  |   let get_exn node = node.exn | 
			
		
	
	
		
		
			
				
					|  |  | @ -191,10 +197,6 @@ module Node = struct | 
			
		
	
		
		
			
				
					
					|  |  |  |     fun start_node ~f -> find ~f NodeSet.empty [start_node] |  |  |  |     fun start_node ~f -> find ~f NodeSet.empty [start_node] | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   let pp_id f id = F.pp_print_int f id |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let pp f node = pp_id f (get_id node) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let get_distance_to_exit node = node.dist_exit |  |  |  |   let get_distance_to_exit node = node.dist_exit | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   (** Append the instructions to the list of instructions to execute *) |  |  |  |   (** Append the instructions to the list of instructions to execute *) | 
			
		
	
	
		
		
			
				
					|  |  | @ -398,13 +400,15 @@ type t = | 
			
		
	
		
		
			
				
					
					|  |  |  |   ; mutable nodes_num: int  (** number of nodes *) |  |  |  |   ; mutable nodes_num: int  (** number of nodes *) | 
			
		
	
		
		
			
				
					
					|  |  |  |   ; mutable start_node: Node.t  (** start node of this procedure *) |  |  |  |   ; mutable start_node: Node.t  (** start node of this procedure *) | 
			
		
	
		
		
			
				
					
					|  |  |  |   ; mutable exit_node: Node.t  (** exit node of this procedure *) |  |  |  |   ; mutable exit_node: Node.t  (** exit node of this procedure *) | 
			
		
	
		
		
			
				
					
					|  |  |  |   ; mutable loop_heads: NodeSet.t option  (** loop head nodes of this procedure *) } |  |  |  |   ; mutable loop_heads: NodeSet.t option  (** loop head nodes of this procedure *) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   ; mutable wto: Node.t WeakTopologicalOrder.Partition.t option | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         (** weak topological order of this procedure *) } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | let from_proc_attributes attributes = |  |  |  | let from_proc_attributes attributes = | 
			
		
	
		
		
			
				
					
					|  |  |  |   let pname = attributes.ProcAttributes.proc_name in |  |  |  |   let pname = attributes.ProcAttributes.proc_name in | 
			
		
	
		
		
			
				
					
					|  |  |  |   let start_node = Node.dummy pname in |  |  |  |   let start_node = Node.dummy pname in | 
			
		
	
		
		
			
				
					
					|  |  |  |   let exit_node = Node.dummy pname in |  |  |  |   let exit_node = Node.dummy pname in | 
			
		
	
		
		
			
				
					
					|  |  |  |   {attributes; nodes= []; nodes_num= 0; start_node; exit_node; loop_heads= None} |  |  |  |   {attributes; nodes= []; nodes_num= 0; start_node; exit_node; loop_heads= None; wto= None} | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | (** Compute the distance of each node to the exit node, if not computed already *) |  |  |  | (** Compute the distance of each node to the exit node, if not computed already *) | 
			
		
	
	
		
		
			
				
					|  |  | @ -570,35 +574,52 @@ let node_set_succs_exn pdesc (node : Node.t) succs exn = | 
			
		
	
		
		
			
				
					
					|  |  |  |       set_succs_exn_base node succs exn |  |  |  |       set_succs_exn_base node succs exn | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | (** Get loop heads for widening. |  |  |  | module PreProcCfg = struct | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     It collects all target nodes of back-edges in a depth-first |  |  |  |   type nonrec t = t | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     traversal. |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     *) |  |  |  |   let fold_succs _cfg n ~init ~f = n |> Node.get_succs |> List.fold ~init ~f | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | let get_loop_heads pdesc = |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let rec set_loop_head_rec visited heads wl = |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     match wl with |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     | [] -> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         heads |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     | (n, ancester) :: wl' -> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if NodeSet.mem n visited then |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           if NodeSet.mem n ancester then set_loop_head_rec visited (NodeSet.add n heads) wl' |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           else set_loop_head_rec visited heads wl' |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           let ancester = NodeSet.add n ancester in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           let succs = List.append (Node.get_succs n) (Node.get_exn n) in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           let works = List.map ~f:(fun m -> (m, ancester)) succs in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           set_loop_head_rec (NodeSet.add n visited) heads (List.append works wl') |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let start_wl = [(get_start_node pdesc, NodeSet.empty)] in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let lh = set_loop_head_rec NodeSet.empty NodeSet.empty start_wl in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   pdesc.loop_heads <- Some lh ; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   lh |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   let start_node = get_start_node | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   module Node = struct | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     type t = Node.t | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     type id = Node.id | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     let id = Node.get_id | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     module IdMap = IdMap | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   end | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | end | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | module WTO = WeakTopologicalOrder.Bourdoncle_SCC (PreProcCfg) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | let get_wto pdesc = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   match pdesc.wto with | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   | Some wto -> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       wto | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   | None -> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       let wto = WTO.make pdesc in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       pdesc.wto <- Some wto ; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       wto | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | (** Get loop heads for widening. *) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | let get_loop_heads pdesc = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   match pdesc.loop_heads with | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   | Some lh -> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       lh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   | None -> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       let wto = get_wto pdesc in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       let lh = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         WeakTopologicalOrder.Partition.fold_heads wto ~init:NodeSet.empty ~f:(fun acc head -> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             NodeSet.add head acc ) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       pdesc.loop_heads <- Some lh ; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       lh | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | let is_loop_head pdesc (node : Node.t) = |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   let lh = match pdesc.loop_heads with Some lh -> lh | None -> get_loop_heads pdesc in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   NodeSet.mem node lh |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | let is_loop_head pdesc (node : Node.t) = NodeSet.mem node (get_loop_heads pdesc) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | let pp_modify_in_block fmt modify_in_block = |  |  |  | let pp_modify_in_block fmt modify_in_block = | 
			
		
	
		
		
			
				
					
					|  |  |  |   if modify_in_block then Format.pp_print_string fmt "(__block)" else () |  |  |  |   if modify_in_block then Format.pp_print_string fmt "(__block)" else () | 
			
		
	
	
		
		
			
				
					|  |  | 
 |