Project

General

Profile

Revision e8c0f452

View differences:

src/causality.ml
229 229

  
230 230
  let get_callee expr =
231 231
    match expr.expr_desc with
232
    | Expr_appl (id, args, _) -> id, expr_list_of_expr args
233
    | _ -> assert false
232
    | Expr_appl (id, args, _) -> Some (id, expr_list_of_expr args)
233
    | _ -> None
234 234

  
235 235
  let get_calls prednode eqs =
236 236
    let deps =
......
248 248
	| Node nd ->
249 249
	  (*Format.eprintf "Computing deps of node %s@.@?" nd.node_id; *)
250 250
	  let accu = add_vertices [nd.node_id] accu in
251
	  let deps = List.map (fun e -> fst (get_callee e)) (get_calls (fun _ -> true) nd.node_eqs) in
251
	  let deps = List.map (fun e -> fst (desome (get_callee e))) (get_calls (fun _ -> true) nd.node_eqs) in
252 252
	   (*Format.eprintf "%a@.@?" (Utils.fprintf_list ~sep:"@." Format.pp_print_string) deps; *)
253 253
	  add_edges [nd.node_id] deps accu
254 254
	| _ -> assert false (* should not happen *)
src/liveness.ml
114 114
    Format.fprintf fmt "}@."
115 115
  end
116 116

  
117

  
118
(* Reuse policy:
119
   - could reuse variables with the same type exactly only (simple).
120
   - reusing variables with different types would involve:
121
     - either dirty castings
122
     - or complex inclusion expression (for instance: array <-> array cell, struct <-> struct field) to be able to reuse only some parts of structured data.
123
     ... it seems too complex and potentially unsafe
124
   - for node instance calls: output variables could NOT reuse input variables, 
125
     even if inputs become dead, because the correctness would depend on the scheduling
126
     of the callee (so, the compiling strategy could NOT be modular anymore).
127
   - once a policy is set, we need to:
128
     - replace each variable by its reuse alias.
129
     - simplify resulting equations, as we may now have:
130
        x = x;                     --> ;           for scalar vars
131
       or:
132
        x = &{ f1 = x->f1; f2 = t; } --> x->f2 = t;   for struct vars
133
     - such simplifications are, until now, only expressible at the C source level...
134
 *)
135

  
117 136
(* Replaces [v] by [v'] in set [s] *)
118 137
let replace_in_set s v v' =
119 138
  if ISet.mem v s then ISet.add v' (ISet.remove v s) else s
......
123 142
 Hashtbl.iter (fun k dead -> Hashtbl.replace death k (replace_in_set dead v v')) death
124 143

  
125 144
let find_compatible_local node var dead =
126
 Format.eprintf "find_compatible_local %s %s@." node.node_id var;
145
 (*Format.eprintf "find_compatible_local %s %s@." node.node_id var;*)
127 146
  let typ = (Corelang.node_var var node).var_type in
147
  let eq_var = node_eq var node in
148
  let inputs =
149
    match NodeDep.get_callee eq_var.eq_rhs with
150
    | None           -> []
151
    | Some (_, args) -> List.fold_right (fun e r -> match e.expr_desc with Expr_ident id -> id::r | _ -> r) args [] in
152
  let filter v =
153
       ISet.mem v.var_id dead
154
    && Typing.eq_ground typ v.var_type
155
    && not (List.mem v.var_id inputs) in
128 156
  try
129
    Some ((List.find (fun v -> ISet.mem v.var_id dead && Typing.eq_ground typ v.var_type) node.node_locals).var_id)
157
    Some ((List.find filter node.node_locals).var_id)
130 158
  with Not_found -> None
131 159

  
132 160
let reuse_policy node sort death =
src/machine_code.ml
414 414
	  then
415 415
	    (accu, node_eqs_remainder)
416 416
	  else
417
	    if   List.exists (fun vdecl -> vdecl.var_id = v) nd.node_locals
417
	    (*if   List.exists (fun vdecl -> vdecl.var_id = v) nd.node_locals
418 418
	      || List.exists (fun vdecl -> vdecl.var_id = v) nd.node_outputs
419
	    then
419
	    then*)
420 420
	      let eq_v, remainder = find_eq v node_eqs_remainder in
421 421
	      eq_v::accu, remainder
422
	    (* else it is a constant value, checked during typing phase *)
422
	    (* else it is a constant value, checked during typing phase
423 423
	    else	 
424
	      accu, node_eqs_remainder
424
	      accu, node_eqs_remainder *)
425 425
      ) 
426 426
      ([], split_eqs) 
427 427
      sch 
......
462 462
  }
463 463

  
464 464

  
465
let translate_prog decls = 
465
let translate_prog decls =
466 466
  let nodes = get_nodes decls in 
467 467
   (* What to do with Imported/Sensor/Actuators ? *)
468 468
   (*arrow_machine ::*)  List.map translate_decl nodes
src/scheduling.ml
98 98
    !sorted
99 99
  end
100 100

  
101
(* Removes global constants from [node] schedule [sch] *)
102
let remove_consts node sch =
103
  let filter v = 
104
       List.exists (fun vdecl -> vdecl.var_id = v) node.node_locals
105
    || List.exists (fun vdecl -> vdecl.var_id = v) node.node_outputs in
106
  List.filter filter sch
101 107

  
102
let schedule_node n  =
108
let schedule_node n =
103 109
  try
104 110
    let eq_equiv = ExprDep.node_eq_equiv n in
105 111
    let eq_equiv v1 v2 =
......
109 115
    let n', g = global_dependency n in
110 116
    Log.report ~level:5 (fun fmt -> Format.eprintf "dependency graph for node %s: %a" n'.node_id pp_dep_graph g);
111 117
    let gg = IdentDepGraph.copy g in
112
    let sort = topological_sort eq_equiv g in
118
    let sort = remove_consts n (topological_sort eq_equiv g) in
113 119

  
114 120
    let death = Liveness.death_table n gg sort in
115 121
    Log.report ~level:5 (fun fmt -> Format.eprintf "death table for node %s: %a" n'.node_id Liveness.pp_death_table death);
116
(*
122

  
117 123
    let reuse = Liveness.reuse_policy n sort death in
118 124
    Log.report ~level:5 (fun fmt -> Format.eprintf "reuse policy for node %s: %a" n'.node_id Liveness.pp_reuse_policy reuse);
119
*)
125
 
120 126
    n', sort
121 127
(* let sorted = TopologicalDepGraph.fold (fun x res -> if ExprDep.is_instance_var x then res else x::res) g []*)
122 128
  with (Causality.Cycle v) as exc ->

Also available in: Unified diff