Skip to content

Commit 121b735

Browse files
davidpichardiefacebook-github-bot
authored andcommitted
More powerful version of Instrs.map_changed
Summary: Introducing a generalization of map_changed that can now use a context on each instruction. The context is computed with the previous instructions in the collection. Reviewed By: skcho, jvillard Differential Revision: D20669993 fbshipit-source-id: 58fdee1d9
1 parent a1a3c55 commit 121b735

File tree

3 files changed

+34
-27
lines changed

3 files changed

+34
-27
lines changed

infer/src/IR/Instrs.ml

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,41 @@ let of_rev_list l = NotReversed (Array.of_list_rev l)
7070

7171
let filter_map (NotReversed instrs) ~f = NotReversed (Array.filter_map instrs ~f)
7272

73-
let map_changed =
74-
let aux_changed arr ~f i =
75-
for i = i to Array.length arr - 1 do
76-
Array.unsafe_get arr i |> f |> Array.unsafe_set arr i
77-
done ;
78-
arr
73+
let map_and_fold =
74+
let rec aux_changed arr ~f current i =
75+
if i >= Array.length arr then arr
76+
else
77+
let e = Array.unsafe_get arr i in
78+
let next, e' = f current e in
79+
Array.unsafe_set arr i e' ;
80+
aux_changed arr ~f next (i + 1)
7981
in
80-
let rec aux_unchanged ~equal arr ~f i =
82+
let rec aux_unchanged arr ~f current i =
8183
if i >= Array.length arr then arr
8284
else
8385
let e = Array.unsafe_get arr i in
84-
let e' = f e in
85-
if equal e e' then aux_unchanged ~equal arr ~f (i + 1)
86+
let next, e' = f current e in
87+
if phys_equal e e' then aux_unchanged arr ~f next (i + 1)
8688
else
8789
let arr = Array.copy arr in
8890
Array.unsafe_set arr i e' ;
89-
aux_changed arr ~f (i + 1)
91+
aux_changed arr ~f next (i + 1)
9092
in
91-
fun ~equal (NotReversed instrs as t) ~f ->
92-
let instrs' = aux_unchanged ~equal instrs ~f 0 in
93+
fun (NotReversed instrs as t) ~f ~init ->
94+
let instrs' = aux_unchanged instrs ~f init 0 in
9395
if phys_equal instrs instrs' then t else NotReversed instrs'
9496

9597

96-
let concat_map_changed ~equal (NotReversed instrs as t) ~f =
98+
let map (NotReversed _instrs as t) ~f =
99+
let f () e = ((), f e) in
100+
map_and_fold t ~f ~init:()
101+
102+
103+
let concat_map (NotReversed instrs as t) ~f =
97104
let instrs' = Array.concat_map ~f instrs in
98105
if
99106
Int.equal (Array.length instrs) (Array.length instrs')
100-
&& Array.for_all2_exn ~f:equal instrs instrs'
107+
&& Array.for_all2_exn ~f:phys_equal instrs instrs'
101108
then t
102109
else NotReversed instrs'
103110

infer/src/IR/Instrs.mli

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@ val of_rev_list : Sil.instr list -> not_reversed_t
2727

2828
val filter_map : not_reversed_t -> f:(Sil.instr -> Sil.instr option) -> not_reversed_t
2929

30-
val map_changed :
31-
equal:(Sil.instr -> Sil.instr -> bool)
32-
-> not_reversed_t
33-
-> f:(Sil.instr -> Sil.instr)
34-
-> not_reversed_t
35-
36-
val concat_map_changed :
37-
equal:(Sil.instr -> Sil.instr -> bool)
38-
-> not_reversed_t
39-
-> f:(Sil.instr -> Sil.instr array)
40-
-> not_reversed_t
30+
val map : not_reversed_t -> f:(Sil.instr -> Sil.instr) -> not_reversed_t
31+
(** replace every instruction [instr] with [f instr]. Preserve physical equality. **)
32+
33+
val map_and_fold :
34+
not_reversed_t -> f:('a -> Sil.instr -> 'a * Sil.instr) -> init:'a -> not_reversed_t
35+
(** replace every instruction [instr] with [snd (f context instr)]. The context is computed by
36+
folding [f] on [init] and previous instructions (before [instr]) in the collection. Preserve
37+
physical equality. **)
38+
39+
val concat_map : not_reversed_t -> f:(Sil.instr -> Sil.instr array) -> not_reversed_t
40+
(** replace every instruction [instr] with the list [f instr]. Preserve physical equality. **)
4141

4242
val reverse_order : not_reversed_t -> reversed t
4343

infer/src/IR/Procdesc.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ module Node = struct
246246

247247
(** Map and replace the instructions to be executed *)
248248
let replace_instrs node ~f =
249-
let instrs' = Instrs.map_changed ~equal:phys_equal node.instrs ~f:(f node) in
249+
let instrs' = Instrs.map node.instrs ~f:(f node) in
250250
if phys_equal instrs' node.instrs then false
251251
else (
252252
node.instrs <- instrs' ;
@@ -255,7 +255,7 @@ module Node = struct
255255

256256
(** Like [replace_instrs], but 1 instr gets replaced by 0, 1, or more instructions. *)
257257
let replace_instrs_by node ~f =
258-
let instrs' = Instrs.concat_map_changed ~equal:phys_equal node.instrs ~f:(f node) in
258+
let instrs' = Instrs.concat_map node.instrs ~f:(f node) in
259259
if phys_equal instrs' node.instrs then false
260260
else (
261261
node.instrs <- instrs' ;

0 commit comments

Comments
 (0)