let lvh_handle_inst i lvh =
  if (!ignore_inst) i then lvh else
  match i with
    Set(lv,e,_) -> begin
      match lv with
      | (Mem _, _) -> begin
          LvExpHash.replace lvh lv e;
          lvh_kill_mem lvh;
          lvh_kill_addrof_or_global lvh;
          lvh
      end
      | _ when not (exp_is_volatile e) -> begin
          (* ignore x = x *)
          if compareExpStripCasts (dummy_exp (Lval lv)) e then lvh
          else begin
            LvExpHash.replace lvh lv e;
            lvh_kill_lval lvh lv;
            lvh
          end
      end
      | _ -> begin (* e is volatile *)
          (* must remove mapping for lv *)
          if !debug then Cilmsg.debug "lvh_handle_inst: %a is volatile. killing %a"
            d_exp e d_lval lv;
          LvExpHash.remove lvh lv;
          lvh_kill_lval lvh lv;
          lvh
      end
    end
  | Call(Some lv,_,_,_) -> begin
      LvExpHash.remove lvh lv;
      lvh_kill_lval lvh lv;
      if not((!ignore_call) i) then begin
        lvh_kill_mem lvh;
        lvh_kill_addrof_or_global lvh
      end;
      lvh
  end
  | Call(_,_,_,_) -> begin
      if not((!ignore_call) i) then begin
        lvh_kill_mem lvh;
        lvh_kill_addrof_or_global lvh;
      end;
      lvh
  end
  | Asm(_,_,_,_,_,_) -> begin
      let _,d = UD.computeUseDefInstr i in
      UD.VS.iter (fun vi ->
        lvh_kill_vi lvh vi) d;
      lvh
  end
  | Code_annot _ | Skip _ -> lvh