Project

General

Profile

Revision bb2ca5f4 src/liveness.ml

View differences:

src/liveness.ml
184 184
let replace_in_death_table death v v' =
185 185
 Hashtbl.iter (fun k dead -> Hashtbl.replace death k (replace_in_set dead v v')) death
186 186

  
187
let find_compatible_local node var dead =
187
let find_compatible_local node var dead death disjoint policy =
188 188
 (*Format.eprintf "find_compatible_local %s %s %a@." node.node_id var pp_iset dead;*)
189 189
  let typ = (get_node_var var node).var_type in
190 190
  let eq_var = get_node_eq var node in
191
  let locals = node.node_locals in
191 192
  let aliasable_inputs =
192 193
    match NodeDep.get_callee eq_var.eq_rhs with
193 194
    | None           -> []
194 195
    | Some (_, args) -> List.fold_right (fun e r -> match e.expr_desc with Expr_ident id -> id::r | _ -> r) args [] in
195
  let filter v =
196
  let filter base (v : var_decl) =
196 197
    let res =
197
       ISet.mem v.var_id dead
198
       base v
198 199
    && Typing.eq_ground typ v.var_type
199
    && not (Types.is_address_type v.var_type  && List.mem v.var_id aliasable_inputs) in
200
    && not (Types.is_address_type v.var_type && List.mem v.var_id aliasable_inputs) in
200 201
    begin
201 202
      (*Format.eprintf "filter %a = %s@." Printers.pp_var_name v (if res then "true" else "false");*)
202 203
      res
203 204
    end in
205
(*Format.eprintf "reuse %s@." var;*)
204 206
  try
205
    Some ((List.find filter node.node_locals).var_id)
206
  with Not_found -> None
207
    let disj = Hashtbl.find disjoint var in
208
    let reuse = List.find (filter (fun v -> ISet.mem v.var_id disj && not (ISet.mem v.var_id dead))) locals in
209
(*Format.eprintf "reuse %s by %s@." var reuse.var_id;*)
210
    Disjunction.replace_in_disjoint_map disjoint var reuse.var_id;
211
(*Format.eprintf "new disjoint:%a@." Disjunction.pp_disjoint_map disjoint;*)
212
    Hashtbl.add policy var reuse.var_id
213
  with Not_found ->
214
  try
215
    let reuse = List.find (filter (fun v -> ISet.mem v.var_id dead)) locals in
216
(*Format.eprintf "reuse %s by %s@." var reuse.var_id;*)
217
    replace_in_death_table death var reuse.var_id;
218
(*Format.eprintf "new death:%a@." pp_death_table death;*)
219
    Hashtbl.add policy var reuse.var_id
220
  with Not_found -> ()
207 221

  
208
let reuse_policy node sort death =
222
(* the reuse policy seeks to use less local variables
223
   by replacing local variables, applying the rules
224
   in the following order:
225
    1) use another clock disjoint still live variable,
226
       with the greatest possible disjoint clock
227
    2) reuse a dead variable
228
   For the sake of safety, we replace variables by others:
229
    - with the same type
230
    - not aliasable (i.e. address type)
231
*)
232
let reuse_policy node sort death disjoint =
209 233
  let dead = ref ISet.empty in
210 234
  let policy = Hashtbl.create 23 in
211 235
  let sort = ref sort in
......
216 240
      begin
217 241
	dead := ISet.union (Hashtbl.find death head) !dead;
218 242
      end;
219
    (match find_compatible_local node head !dead with
220
    | None   -> ()
221
    | Some l -> replace_in_death_table death head l; Hashtbl.add policy head l);
243
    find_compatible_local node head !dead death disjoint policy;
222 244
    sort := List.tl !sort;
223 245
  done;
224 246
  policy

Also available in: Unified diff