-
Notifications
You must be signed in to change notification settings - Fork 37
/
main.ml
241 lines (227 loc) · 7.68 KB
/
main.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
(*
Copyright (c) 2011, Julien Verlaguet
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
3. Neither the name of Julien Verlaguet nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
open Lexing
let run s =
(* Printf.printf "Running: %s\n" s ; flush stdout ; *)
let code = Sys.command s in
if code <> 0
then (Printf.fprintf stderr "Error (%d): couldn't run %s\n" code s ;
exit 2)
else ()
let remove fnl =
List.iter (
fun s ->
ignore (run ("rm "^s))
) fnl
let opt x bc =
run ("cp "^bc^" "^bc^"_in");
run (Global.opt ^" "^x^" "^bc^"_in > "^bc);
run ("rm "^bc^"_in");
bc
let check_suffix fn =
if Filename.check_suffix fn ".lml" ||
Filename.check_suffix fn ".lmli" then
()
else begin
Printf.fprintf stderr "Wrong suffix: %s\n" fn ;
exit 2
end
let make_libname s =
let dir = Filename.dirname s in
let name = Filename.basename s in
if not (Filename.check_suffix name ".lmli")
then begin
Printf.fprintf stderr "Error: expected an lmli extension not \"%s\"\n"
name ;
exit 2
end ;
assert (String.length name > 3) ;
if String.sub name 0 3 <> "lib"
then begin
Printf.fprintf stderr
"Error: expected a name that starts with lib not \"%s\"\n"
name ;
exit 2
end ;
Filename.chop_suffix (Filename.concat dir name) ".lmli"
let add_link cmd s =
if Filename.check_suffix s ".lmli"
then
let dir = Filename.dirname s in
let base = Filename.basename s in
let lname = Filename.chop_suffix base ".lmli" in
let lname = String.sub lname 3 (String.length lname - 3) in
let cmd = cmd ^ " -L" ^ dir ^ " -l" ^ lname ^ " " in
cmd
else cmd
let parse acc fn =
if not (Sys.file_exists fn)
then (Printf.fprintf stderr "Couldn't find %s\n" fn ; exit 2) ;
check_suffix fn ;
Pos.file := fn ;
let ic = open_in fn in
let lb = Lexing.from_channel ic in
try
let mdl = Parser.program Lexer.token lb in
let acc = mdl @ acc in
close_in ic ;
acc
with
| Lexer.Lexical_error _ -> Error.lexing_error lb
| Parsing.Parse_error -> Error.syntax_error lb
let output_interface o fn =
Pos.file := fn;
if Filename.check_suffix fn "lml"
then
let ic = open_in fn in
let lb = Lexing.from_channel ic in
try
Lexer.interface o 0 true lb ;
close_in ic
with
| Lexer.Lexical_error _ -> Error.lexing_error lb
else ()
let _ =
let space n s = String.make n ' ' ^ s in
let module_l = ref [] in
let dump_llst = ref false in
let dump_est = ref false in
let dump_as = ref false in
let dump_ist = ref false in
let bounds = ref false in
let no_stdlib = ref false in
let no_opt = ref false in
let root = ref "" in
let lib = ref "" in
let oname = ref "a.out" in
let print_int = ref false in
let eval = ref false in
Arg.parse
["-root", Arg.String (fun s -> root := s),
space 10 "specifies the root module";
"-bounds", Arg.Unit (fun () -> bounds := true),
space 8 "show unchecked bounds";
"-llst", Arg.Unit (fun () -> dump_llst := true),
space 10 "internal";
"-est", Arg.Unit (fun () -> dump_est := true),
space 11 "internal";
"-asm", Arg.Unit (fun () -> dump_as := true),
space 11 "internal";
"-ist", Arg.Unit (fun () -> dump_ist := true),
space 11 "internal" ;
"-no-stdlib", Arg.Unit (fun () -> no_stdlib := true),
space 5 "excludes standard library";
"-no-opt", Arg.Unit (fun () -> no_opt := true),
space 8 "disables optimizations" ;
"-i", Arg.Unit (fun () -> print_int := true),
space 13 "print interface and exit" ;
"-o", Arg.String (fun s -> oname := s),
space 13 "outputs executable" ;
"-lib", Arg.String (fun s -> lib := s),
space 11 "creates a library" ;
"-eval", Arg.Unit (fun () -> eval := true),
space 10 "evaluates the main";
]
(fun x -> module_l := x :: !module_l)
(Printf.sprintf "%s files" Sys.argv.(0)) ;
if !print_int then
let o = output_string stdout in
List.iter (output_interface o) !module_l ; exit 0
else () ;
let base = if !lib = "" then !oname else make_libname !lib in
let ast = List.fold_left parse [] !module_l in
let ast = if !no_stdlib then ast else parse ast Global.stdlib in
let root_id, nast = Naming.program !root ast in
NastCheck.program nast ;
let neast = NastExpand.program nast in
NeastCheck.program neast ;
let types, tast = Typing.program neast in
let stast = StastOfTast.program types tast in
StastCheck.program stast ;
RecordCheck.program stast ;
LinearCheck.program stast ;
let benv = BoundCheck.program !bounds stast in
flush stderr ;
let ist = IstOfStast.program benv stast in
let ist = ExtractFuns.program ist in
let ist = IstTail.program ist in
if !lib = "" && !root = ""
then (Printf.fprintf stderr "Root node missing !\n" ; exit 2) ;
if !eval
then (Eval.program root_id ist; exit 0);
if !dump_ist then
IstPp.program ist;
let est = EstOfIst.program ist in
let est = EstCompile.program est in
let est = EstNormalizePatterns.program est in
if !dump_est then
EstPp.program est ;
let llst = LlstOfEst.program est in
let llst = LlstOptim.inline llst in
let llst = LlstFree.program llst in
let llst = LlstOptim.program llst in
if !dump_llst then
LlstPp.program llst ;
let bc = Emit.program base !root !no_opt !dump_as llst in
let bc = opt "-internalize" bc in
let bc = opt "-mem2reg" bc in
let bc = opt "-tailduplicate" bc in
let bc = opt "-inline" bc in
let bc = opt "-always-inline" bc in
let bc = opt "-break-crit-edges" bc in
let bc = opt "-live-values" bc in
let bc = opt "-lda" bc in
let bc = opt "-ipsccp" bc in
let bc = opt "-ipconstprop" bc in
let bc = opt "-tailcallelim" bc in
let bc = opt "-O3" bc in
let cmd = Global.llc ^ Global.llc_opts in
let cmd = cmd ^ bc in
run cmd ;
let asm = base ^ ".s" in
let obj = base ^ ".o" in
let cmd = Global.cc ^ " -c " ^ asm ^ " -o " ^ obj in
run cmd ;
if !lib <> ""
then
let clib = base ^ ".a" in
run (Global.ar ^ " rs " ^ clib ^ " " ^ obj) ;
let oc = open_out (base ^ ".lmli") in
let o = output_string oc in
List.iter (output_interface o) !module_l ;
close_out oc
else begin
let cmd = Global.cc ^ " " ^ obj ^ " -o " ^ base in
let cmd =
if !no_stdlib then cmd else
cmd ^ " -L"^Global.stdlibdir ^ " -lliml" in
let cmd = List.fold_left add_link cmd !module_l in
let cmd = cmd^" -lm -lpthread" in
run cmd
end ;
remove [bc ; asm ; obj]