Guest User

Untitled

a guest
Feb 16th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.36 KB | None | 0 0
  1. diff -w -r -C 2 ocaml-3.12.0/bytecomp/simplif.ml ocaml-3.12.0+noleak/bytecomp/simplif.ml
  2. *** ocaml-3.12.0/bytecomp/simplif.ml 2010-01-22 13:48:24.000000000 +0100
  3. --- ocaml-3.12.0+noleak/bytecomp/simplif.ml 2011-06-09 21:10:01.332516996 +0200
  4. ***************
  5. *** 266,323 ****
  6. try
  7. !(Hashtbl.find occ v)
  8. with Not_found ->
  9. ! 0
  10. ! and incr_var v =
  11. ! try
  12. ! incr(Hashtbl.find occ v)
  13. ! with Not_found ->
  14. ! Hashtbl.add occ v (ref 1) in
  15.  
  16. ! let rec count = function
  17. ! | Lvar v -> incr_var v
  18. | Lconst cst -> ()
  19. ! | Lapply(l1, ll, _) -> count l1; List.iter count ll
  20. ! | Lfunction(kind, params, l) -> count l
  21. | Llet(str, v, Lvar w, l2) when not !Clflags.debug ->
  22. (* v will be replaced by w in l2, so each occurrence of v in l2
  23. increases w's refcount *)
  24. ! count l2;
  25. let vc = count_var v in
  26. ! begin try
  27. ! let r = Hashtbl.find occ w in r := !r + vc
  28. ! with Not_found ->
  29. ! Hashtbl.add occ w (ref vc)
  30. end
  31. | Llet(str, v, l1, l2) ->
  32. ! count l2;
  33. (* If v is unused, l1 will be removed, so don't count its variables *)
  34. ! if str = Strict || count_var v > 0 then count l1
  35. | Lletrec(bindings, body) ->
  36. ! List.iter (fun (v, l) -> count l) bindings;
  37. ! count body
  38. ! | Lprim(p, ll) -> List.iter count ll
  39. | Lswitch(l, sw) ->
  40. ! count_default sw ;
  41. ! count l;
  42. ! List.iter (fun (_, l) -> count l) sw.sw_consts;
  43. ! List.iter (fun (_, l) -> count l) sw.sw_blocks
  44. ! | Lstaticraise (i,ls) -> List.iter count ls
  45. | Lstaticcatch(l1, (i,_), l2) ->
  46. ! count l1; count l2
  47. ! | Ltrywith(l1, v, l2) -> count l1; count l2
  48. ! | Lifthenelse(l1, l2, l3) -> count l1; count l2; count l3
  49. ! | Lsequence(l1, l2) -> count l1; count l2
  50. ! | Lwhile(l1, l2) -> count l1; count l2
  51. ! | Lfor(_, l1, l2, dir, l3) -> count l1; count l2; count l3
  52. | Lassign(v, l) ->
  53. (* Lalias-bound variables are never assigned, so don't increase
  54. v's refcount *)
  55. ! count l
  56. ! | Lsend(_, m, o, ll) -> List.iter count (m::o::ll)
  57. ! | Levent(l, _) -> count l
  58. | Lifused(v, l) ->
  59. ! if count_var v > 0 then count l
  60.  
  61. ! and count_default sw = match sw.sw_failaction with
  62. | None -> ()
  63. | Some al ->
  64. --- 266,337 ----
  65. try
  66. !(Hashtbl.find occ v)
  67. + with Not_found -> 0
  68. + and incr_var bv v =
  69. + try (* bv is the set of locally bound variables, i.e. variables that can be safely inlined *)
  70. + incr (Tbl.find v bv)
  71. with Not_found ->
  72. ! try (* if the variable is not in bv, it should not be inlined. Increase its use-count by much *)
  73. ! let r = Hashtbl.find occ v in
  74. ! r := !r + 10
  75. ! with Not_found -> () (* only Llet bound variables have a use-count *)
  76. ! in
  77. ! let new_var bv v = (* add a variable both to the global table (occ) and to the locally bound variables *)
  78. ! let r = ref 0 in
  79. ! Hashtbl.add occ v r;
  80. ! Tbl.add v r bv
  81. ! in
  82.  
  83. ! let rec count bv lam =
  84. ! match lam with
  85. ! | Lvar v -> incr_var bv v
  86. | Lconst cst -> ()
  87. ! | Lapply(l1, ll, _) -> count bv l1; List.iter (count bv) ll
  88. ! | Lfunction(kind, params, l) -> count Tbl.empty l (* empty locally-bound variables for abstractions *)
  89. | Llet(str, v, Lvar w, l2) when not !Clflags.debug ->
  90. (* v will be replaced by w in l2, so each occurrence of v in l2
  91. increases w's refcount *)
  92. ! begin
  93. ! try
  94. ! let r = Hashtbl.find occ w in
  95. ! let bv' = new_var bv v in
  96. ! count bv' l2;
  97. let vc = count_var v in
  98. ! r := !r + vc
  99. ! with Not_found -> (* w is not a Llet defined variable. Don't count bv *)
  100. ! count bv l2
  101. end
  102. | Llet(str, v, l1, l2) ->
  103. ! let bv' = new_var bv v in
  104. ! count bv' l2;
  105. (* If v is unused, l1 will be removed, so don't count its variables *)
  106. ! if str = Strict || count_var v > 0 then count bv l1
  107. | Lletrec(bindings, body) ->
  108. ! List.iter (fun (v, l) -> count bv l) bindings;
  109. ! count bv body
  110. ! | Lprim(p, ll) -> List.iter (count bv) ll
  111. | Lswitch(l, sw) ->
  112. ! count_default bv sw ;
  113. ! count bv l;
  114. ! List.iter (fun (_, l) -> count bv l) sw.sw_consts;
  115. ! List.iter (fun (_, l) -> count bv l) sw.sw_blocks
  116. ! | Lstaticraise (i,ls) -> List.iter (count bv) ls
  117. | Lstaticcatch(l1, (i,_), l2) ->
  118. ! count bv l1; count bv l2
  119. ! | Ltrywith(l1, v, l2) -> count bv l1; count bv l2
  120. ! | Lifthenelse(l1, l2, l3) -> count bv l1; count bv l2; count bv l3
  121. ! | Lsequence(l1, l2) -> count bv l1; count bv l2
  122. ! | Lwhile(l1, l2) -> count Tbl.empty l1; count Tbl.empty l2 (* empty locally-bound variables for loops *)
  123. ! | Lfor(_, l1, l2, dir, l3) -> count bv l1; count bv l2;
  124. ! count Tbl.empty l3 (* empty locally-bound variables for loops *)
  125. | Lassign(v, l) ->
  126. (* Lalias-bound variables are never assigned, so don't increase
  127. v's refcount *)
  128. ! count bv l
  129. ! | Lsend(_, m, o, ll) -> List.iter (count bv) (m::o::ll)
  130. ! | Levent(l, _) -> count bv l
  131. | Lifused(v, l) ->
  132. ! if count_var v > 0 then count bv l
  133.  
  134. ! and count_default bv sw = match sw.sw_failaction with
  135. | None -> ()
  136. | Some al ->
  137. ***************
  138. *** 327,337 ****
  139. nconsts < sw.sw_numconsts && nblocks < sw.sw_numblocks
  140. then begin (* default action will occur twice in native code *)
  141. ! count al ; count al
  142. end else begin (* default action will occur once *)
  143. assert (nconsts < sw.sw_numconsts || nblocks < sw.sw_numblocks) ;
  144. ! count al
  145. end
  146. in
  147. ! count lam;
  148. (* Second pass: remove Lalias bindings of unused variables,
  149. and substitute the bindings of variables used exactly once. *)
  150. --- 341,351 ----
  151. nconsts < sw.sw_numconsts && nblocks < sw.sw_numblocks
  152. then begin (* default action will occur twice in native code *)
  153. ! count bv al ; count bv al
  154. end else begin (* default action will occur once *)
  155. assert (nconsts < sw.sw_numconsts || nblocks < sw.sw_numblocks) ;
  156. ! count bv al
  157. end
  158. in
  159. ! count Tbl.empty lam;
  160. (* Second pass: remove Lalias bindings of unused variables,
  161. and substitute the bindings of variables used exactly once. *)
  162. ***************
  163. *** 347,350 ****
  164. --- 361,378 ----
  165. end
  166. | Lconst cst as l -> l
  167. + | Lapply(Lvar v, ll, loc) ->
  168. + begin try
  169. + let lfun = Hashtbl.find subst v in
  170. + match lfun with
  171. + Lfunction(Curried, args, body) when List.length args = List.length ll ->
  172. + (* Printf.fprintf stderr "Simplif: inlining temporary function %s\n%!" (Ident.unique_name v); *)
  173. + List.fold_left2 (fun body v arg ->
  174. + Llet(Strict, v, simplif arg, body))
  175. + body args ll
  176. + | _ ->
  177. + Lapply(lfun, List.map simplif ll, loc)
  178. + with Not_found ->
  179. + Lapply(Lvar v, List.map simplif ll, loc)
  180. + end
  181. | Lapply(l1, ll, loc) -> Lapply(simplif l1, List.map simplif ll, loc)
  182. | Lfunction(kind, params, l) -> Lfunction(kind, params, simplif l)
  183. ***************
  184. *** 361,364 ****
  185. --- 389,399 ----
  186. Llet(Strict, v, Lprim(Pmakeblock(0, Mutable), [slinit]), slbody)
  187. end
  188. + | Llet(Strict, v, ((Lfunction _) as lfun), body) ->
  189. + begin match count_var v with
  190. + 0 -> simplif body
  191. + | 1 when not !Clflags.debug ->
  192. + Hashtbl.add subst v (simplif lfun); simplif body
  193. + | n -> Llet(Strict, v, simplif lfun, simplif body)
  194. + end
  195. | Llet(Alias, v, l1, l2) ->
  196. begin match count_var v with
  197. Only in ocaml-3.12.0+noleak/bytecomp: simplif.ml.orig
Add Comment
Please, Sign In to add comment