let ok_to_replace vi curiosh sid defiosh dsid f r =
  let uses, safe = match r with
    RD.RDExp e -> (UD.computeUseExp e, exp_is_ok_replacement e)
  | RD.RDCall (Call(_,_,el,_) as i) ->
      let safe = List.fold_left (fun b e ->
        (exp_is_ok_replacement e) && b) true el in
      let u,_d = UD.computeUseDefInstr i in
      u, safe
  | _ -> Cilmsg.fatal "ok_to_replace: got non Call in RDCall."
  in
  let target_addrof = if vi.vaddrof || vi.vglob then
    (if !debug then (Cilmsg.debug "ok_to_replace: target %s had its address taken or is a global" vi.vname);
    true)
  else (if !debug then (Cilmsg.debug "ok_to_replace: target %s does not have its address taken" vi.vname);
        falsein
  let writes = if safe && not(target_addrof) then false else (time "writes_between" (writes_between f dsid) sid) in
  if (not safe || target_addrof) && writes
  then
    (if !debug then (Cilmsg.debug "ok_to_replace: replacement not safe because of pointers or addrOf");
     false)
  else let fdefs = collect_fun_defs f in
  let _ = if !debug then (Cilmsg.debug "ok_to_replace: card fdefs = %d" (UD.VS.cardinal fdefs)) in
  let _ = if !debug then (Cilmsg.debug "ok_to_replace: card uses = %d" (UD.VS.cardinal uses)) in
  verify_unmodified uses fdefs curiosh defiosh