summaryrefslogtreecommitdiff
path: root/asmcomp/deadcode.ml
diff options
context:
space:
mode:
authorDamien Doligez <damien.doligez-inria.fr>2014-04-28 11:49:52 +0000
committerDamien Doligez <damien.doligez-inria.fr>2014-04-28 11:49:52 +0000
commitcc25e53ad310eb32d4854a1505ac3a9a917c8368 (patch)
tree101a8f24490f8ef63c75820cfd945cc4d7f669fc /asmcomp/deadcode.ml
parente94190206fe983154d5606a448e434aec03783d0 (diff)
parentf1f362698f931494a305d48667936ffee2012b64 (diff)
downloadocaml-safe-string.tar.gz
merge trunk up to commit 14699safe-string
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/safe-string@14700 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'asmcomp/deadcode.ml')
-rw-r--r--asmcomp/deadcode.ml64
1 files changed, 64 insertions, 0 deletions
diff --git a/asmcomp/deadcode.ml b/asmcomp/deadcode.ml
new file mode 100644
index 0000000000..d3d0fcb906
--- /dev/null
+++ b/asmcomp/deadcode.ml
@@ -0,0 +1,64 @@
+(***********************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2014 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* Dead code elimination: remove pure instructions whose results are
+ not used. *)
+
+open Mach
+
+(* [deadcode i] returns a pair of an optimized instruction [i']
+ and a set of registers live "before" instruction [i]. *)
+
+let rec deadcode i =
+ match i.desc with
+ | Iend | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) | Iraise _ ->
+ (i, Reg.add_set_array i.live i.arg)
+ | Iop op ->
+ let (s, before) = deadcode i.next in
+ if Proc.op_is_pure op
+ && Reg.disjoint_set_array before i.res then begin
+ assert (Array.length i.res > 0); (* sanity check *)
+ (s, before)
+ end else begin
+ ({i with next = s}, Reg.add_set_array i.live i.arg)
+ end
+ | Iifthenelse(test, ifso, ifnot) ->
+ let (ifso', _) = deadcode ifso in
+ let (ifnot', _) = deadcode ifnot in
+ let (s, _) = deadcode i.next in
+ ({i with desc = Iifthenelse(test, ifso', ifnot'); next = s},
+ Reg.add_set_array i.live i.arg)
+ | Iswitch(index, cases) ->
+ let cases' = Array.map (fun c -> fst (deadcode c)) cases in
+ let (s, _) = deadcode i.next in
+ ({i with desc = Iswitch(index, cases'); next = s},
+ Reg.add_set_array i.live i.arg)
+ | Iloop(body) ->
+ let (body', _) = deadcode body in
+ let (s, _) = deadcode i.next in
+ ({i with desc = Iloop body'; next = s}, i.live)
+ | Icatch(nfail, body, handler) ->
+ let (body', _) = deadcode body in
+ let (handler', _) = deadcode handler in
+ let (s, _) = deadcode i.next in
+ ({i with desc = Icatch(nfail, body', handler'); next = s}, i.live)
+ | Iexit nfail ->
+ (i, i.live)
+ | Itrywith(body, handler) ->
+ let (body', _) = deadcode body in
+ let (handler', _) = deadcode handler in
+ let (s, _) = deadcode i.next in
+ ({i with desc = Itrywith(body', handler'); next = s}, i.live)
+
+let fundecl f =
+ let (new_body, _) = deadcode f.fun_body in
+ {f with fun_body = new_body}