method vstmt stm =
let viSetToDefIdSet iosh vis =
UD.VS.fold (fun vi s ->
if IH.mem iosh vi.vid then
let ios = IH.find iosh vi.vid in
RD.IOS.fold (fun io s ->
match io with None -> s
| Some i -> IS.add i s) ios s
else s) vis IS.empty
in
let check_defid i instruses iosh defid =
IS.mem defid (!usedDefsSet) &&
try
let defuses = IH.find defUseSetHash defid in
if IH.mem sidUseSetHash defid then begin
if !debug then Cilmsg.debug "siduses not empty: %a\n" d_instr i;
true
end else begin
let instruses = viSetToDefIdSet iosh instruses in
IS.fold (fun i' b ->
if not(IS.mem i' instruses) then begin
if !debug then Cilmsg.debug "i not in instruses: %a\n" d_instr i;
true
end else
let i'_uses = IH.find defUseSetHash i' in
IH.mem sidUseSetHash i' ||
if not(IS.equal i'_uses (IS.singleton defid)) then begin
IS.iter (fun iu -> match RD.getSimpRhs iu with
| Some(RD.RDExp e) ->
if !debug then Cilmsg.debug "i' had other than one use: %d: %a\n"
(IS.cardinal i'_uses) d_exp e
| Some(RD.RDCall i) ->
if !debug then Cilmsg.debug "i' had other than one use: %d: %a\n"
(IS.cardinal i'_uses) d_instr i
| None -> ()) i'_uses;
true
end else b) defuses false
end
with Not_found -> true
in
let test (i,(_,s,iosh)) =
match i with
| Call(Some(Var vi,NoOffset),{enode = Lval(Var _vf,NoOffset)},el,_l) ->
if not(!callHasNoSideEffects i) then begin
if !debug then Cilmsg.debug "found call w/ side effects: %a\n" d_instr i;
true
end else begin
if !debug then Cilmsg.debug "found call w/o side effects: %a\n" d_instr i;
(vi.vglob || (Ciltools.is_volatile_vi vi) || (el_has_volatile el) ||
let uses, defd = UD.computeUseDefInstr i in
let rec loop n =
n >= 0 &&
(check_defid i uses iosh (n+s) || loop (n-1))
in
loop (UD.VS.cardinal defd - 1) || (incr removedCount; false))
end
| Call _ -> true
| Set(lh,e,_) when compareExpStripCasts (dummy_exp (Lval lh)) e ->
false
| Set((Var vi,NoOffset),e,_) ->
vi.vglob || (Ciltools.is_volatile_vi vi) || (exp_has_volatile e) ||
let uses, defd = UD.computeUseDefInstr i in
let rec loop n =
n >= 0 &&
(check_defid i uses iosh (n+s) || loop (n-1))
in
loop (UD.VS.cardinal defd - 1) || (incr removedCount; false)
| _ -> true
in
let filter il stmdat =
match
let rd_dat_lst = RD.instrRDs il stm.sid stmdat false in
let ildatlst = List.combine [il] rd_dat_lst in
let ildatlst' = List.filter test ildatlst in
let (newil,_) = List.split ildatlst' in
newil
with
| [] -> Skip Cil_datatype.Location.unknown
| [ x ] -> x
| _ :: _ :: _ -> assert false
in
match RD.getRDs stm.sid with
None -> DoChildren
| Some(_,s,iosh) ->
match stm.skind with
Instr il ->
stm.skind <- Instr(filter il ((),s,iosh));
SkipChildren
| _ -> DoChildren