let rm_unused_locals fd =
  let oldIgnoreSizeof = !UD.ignoreSizeof in
  UD.ignoreSizeof := false;
  let used = List.fold_left (fun u s ->
    let u', d' = UD.computeDeepUseDefStmtKind s.skind in
    UD.VS.union u (UD.VS.union u' d')) UD.VS.empty fd.sbody.bstmts in
  UD.ignoreSizeof := oldIgnoreSizeof;

  let good_var vi = UD.VS.mem vi used in
  let good_locals = List.filter good_var fd.slocals in
  let remove_block_locals = object
    inherit Cil.nopCilVisitor
    method vblock b =
      b.blocals <- List.filter good_var b.blocals;
      DoChildren
  end
  in
  fd.slocals <- good_locals;
  ignore (visitCilBlock remove_block_locals fd.sbody)