forked from ocaml/ocaml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linear.ml
92 lines (80 loc) · 3.02 KB
/
linear.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. *)
(* *)
(* All rights reserved. This file is distributed under the terms of *)
(* the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)
open Mach
(* Transformation of Mach code into a list of pseudo-instructions. *)
type label = Cmm.label
type instruction =
{ mutable desc: instruction_desc;
mutable next: instruction;
arg: Reg.t array;
res: Reg.t array;
dbg: Debuginfo.t;
live: Reg.Set.t }
and instruction_desc =
| Lprologue
| Lend
| Lop of Mach.operation
| Lreloadretaddr
| Lreturn
| Llabel of label
| Lbranch of label
| Lcondbranch of Mach.test * label
| Lcondbranch3 of label option * label option * label option
| Lswitch of label array
| Lentertrap
| Ladjust_trap_depth of { delta_traps : int; }
| Lpushtrap of { lbl_handler : label; }
| Lpoptrap
| Lraise of Lambda.raise_kind
let has_fallthrough = function
| Lreturn | Lbranch _ | Lswitch _ | Lraise _
| Lop Itailcall_ind | Lop (Itailcall_imm _) -> false
| _ -> true
type fundecl =
{ fun_name: string;
fun_args: Reg.Set.t;
fun_body: instruction;
fun_fast: bool;
fun_dbg : Debuginfo.t;
fun_tailrec_entry_point_label : label;
fun_contains_nontail_calls: bool;
fun_num_stack_slots: int array;
fun_frame_required: bool;
fun_extra_stack_used: int
}
(* Invert a test *)
let invert_integer_test = function
Isigned cmp -> Isigned(Cmm.negate_integer_comparison cmp)
| Iunsigned cmp -> Iunsigned(Cmm.negate_integer_comparison cmp)
let invert_test = function
Itruetest -> Ifalsetest
| Ifalsetest -> Itruetest
| Iinttest(cmp) -> Iinttest(invert_integer_test cmp)
| Iinttest_imm(cmp, n) -> Iinttest_imm(invert_integer_test cmp, n)
| Ifloattest(cmp) -> Ifloattest(Cmm.negate_float_comparison cmp)
| Ieventest -> Ioddtest
| Ioddtest -> Ieventest
(* The "end" instruction *)
let rec end_instr =
{ desc = Lend;
next = end_instr;
arg = [||];
res = [||];
dbg = Debuginfo.none;
live = Reg.Set.empty }
(* Cons an instruction (live, debug empty) *)
let instr_cons d a r n =
{ desc = d; next = n; arg = a; res = r;
dbg = Debuginfo.none; live = Reg.Set.empty }