Skip to content

Commit 6820074

Browse files
vouillonOlivierNicole
authored andcommitted
Target-specific code
1 parent 613cbcc commit 6820074

17 files changed

+424
-214
lines changed

compiler/bin-js_of_ocaml/build_fs.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ function jsoo_create_file_extern(name,content){
7575
let pfs_fmt = Pretty_print.to_out_channel chan in
7676
let (_ : Source_map.t option) =
7777
Driver.f
78+
~target:(JavaScript pfs_fmt)
7879
~standalone:true
7980
~wrap_with_fun:`Iife
8081
~link:`Needed
81-
pfs_fmt
8282
(Parse_bytecode.Debug.create ~include_cmis:false false)
8383
code
8484
in

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,12 @@ let run
196196
in
197197
let code = Code.prepend one.code instr in
198198
Driver.f
199+
~target:(JavaScript fmt)
199200
~standalone
200201
?profile
201202
~link
202203
~wrap_with_fun
203204
?source_map
204-
fmt
205205
one.debug
206206
code
207207
| `File, fmt ->
@@ -220,12 +220,12 @@ let run
220220
let code = Code.prepend one.code instr in
221221
let res =
222222
Driver.f
223+
~target:(JavaScript fmt)
223224
~standalone
224225
?profile
225226
~link
226227
~wrap_with_fun
227228
?source_map
228-
fmt
229229
one.debug
230230
code
231231
in
@@ -285,7 +285,7 @@ let run
285285
| `None ->
286286
let prims = Linker.list_all () |> StringSet.elements in
287287
assert (List.length prims > 0);
288-
let code, uinfo = Parse_bytecode.predefined_exceptions () in
288+
let code, uinfo = Parse_bytecode.predefined_exceptions ~target:`JavaScript in
289289
let uinfo = { uinfo with primitives = uinfo.primitives @ prims } in
290290
let code : Parse_bytecode.one =
291291
{ code
@@ -331,6 +331,7 @@ let run
331331
let linkall = linkall || toplevel || dynlink in
332332
let code =
333333
Parse_bytecode.from_exe
334+
~target:`JavaScript
334335
~includes:include_dirs
335336
~include_cmis
336337
~link_info:(toplevel || dynlink)
@@ -363,6 +364,7 @@ let run
363364
let t1 = Timer.make () in
364365
let code =
365366
Parse_bytecode.from_cmo
367+
~target:`JavaScript
366368
~includes:include_dirs
367369
~include_cmis
368370
~debug:need_debug
@@ -419,6 +421,7 @@ let run
419421
let t1 = Timer.make () in
420422
let code =
421423
Parse_bytecode.from_cmo
424+
~target:`JavaScript
422425
~includes:include_dirs
423426
~include_cmis
424427
~debug:need_debug
@@ -450,6 +453,7 @@ let run
450453
let t1 = Timer.make () in
451454
let code =
452455
Parse_bytecode.from_cmo
456+
~target:`JavaScript
453457
~includes:include_dirs
454458
~include_cmis
455459
~debug:need_debug

compiler/lib/driver.ml

Lines changed: 95 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -44,34 +44,35 @@ let deadcode p =
4444
let r, _ = deadcode' p in
4545
r
4646

47-
let inline p =
47+
let inline ~target p =
4848
if Config.Flag.inline () && Config.Flag.deadcode ()
4949
then (
5050
let p, live_vars = deadcode' p in
5151
if debug () then Format.eprintf "Inlining...@.";
52-
Inline.f p live_vars)
52+
Inline.f ~target p live_vars)
5353
else p
5454

5555
let specialize_1 (p, info) =
5656
if debug () then Format.eprintf "Specialize...@.";
5757
Specialize.f ~function_arity:(fun f -> Specialize.function_arity info f) p
5858

59-
let specialize_js (p, info) =
59+
let specialize_js ~target (p, info) =
6060
if debug () then Format.eprintf "Specialize js...@.";
61-
Specialize_js.f info p
61+
Specialize_js.f ~target info p
6262

6363
let specialize_js_once p =
6464
if debug () then Format.eprintf "Specialize js once...@.";
6565
Specialize_js.f_once p
6666

67-
let specialize' (p, info) =
67+
let specialize' ~target (p, info) =
6868
let p = specialize_1 (p, info) in
69-
let p = specialize_js (p, info) in
69+
let p = specialize_js ~target (p, info) in
7070
p, info
7171

72-
let specialize p = fst (specialize' p)
72+
let specialize ~target p = fst (specialize' ~target p)
7373

74-
let eval (p, info) = if Config.Flag.staticeval () then Eval.f info p else p
74+
let eval ~target (p, info) =
75+
if Config.Flag.staticeval () then Eval.f ~target info p else p
7576

7677
let flow p =
7778
if debug () then Format.eprintf "Data flow...@.";
@@ -143,51 +144,54 @@ let identity x = x
143144

144145
(* o1 *)
145146

146-
let o1 : 'a -> 'a =
147+
let o1 ~target : 'a -> 'a =
147148
print
148149
+> tailcall
149150
+> flow_simple (* flow simple to keep information for future tailcall opt *)
150-
+> specialize'
151-
+> eval
152-
+> inline (* inlining may reveal new tailcall opt *)
151+
+> specialize' ~target
152+
+> eval ~target
153+
+> inline ~target (* inlining may reveal new tailcall opt *)
153154
+> deadcode
154155
+> tailcall
155156
+> phi
156157
+> flow
157-
+> specialize'
158-
+> eval
159-
+> inline
158+
+> specialize' ~target
159+
+> eval ~target
160+
+> inline ~target
160161
+> deadcode
161162
+> print
162163
+> flow
163-
+> specialize'
164-
+> eval
165-
+> inline
164+
+> specialize' ~target
165+
+> eval ~target
166+
+> inline ~target
166167
+> deadcode
167168
+> phi
168169
+> flow
169-
+> specialize
170+
+> specialize ~target
170171
+> identity
171172

172173
(* o2 *)
173174

174-
let o2 : 'a -> 'a = loop 10 "o1" o1 1 +> print
175+
let o2 ~target : 'a -> 'a = loop 10 "o1" (o1 ~target) 1 +> print
175176

176177
(* o3 *)
177178

178-
let round1 : 'a -> 'a =
179+
let round1 ~target : 'a -> 'a =
179180
print
180181
+> tailcall
181-
+> inline (* inlining may reveal new tailcall opt *)
182+
+> inline ~target (* inlining may reveal new tailcall opt *)
182183
+> deadcode (* deadcode required before flow simple -> provided by constant *)
183184
+> flow_simple (* flow simple to keep information for future tailcall opt *)
184-
+> specialize'
185-
+> eval
185+
+> specialize' ~target
186+
+> eval ~target
186187
+> identity
187188

188-
let round2 = flow +> specialize' +> eval +> deadcode +> o1
189+
let round2 ~target = flow +> specialize' ~target +> eval ~target +> deadcode +> o1 ~target
189190

190-
let o3 = loop 10 "tailcall+inline" round1 1 +> loop 10 "flow" round2 1 +> print
191+
let o3 ~target =
192+
loop 10 "tailcall+inline" (round1 ~target) 1
193+
+> loop 10 "flow" (round2 ~target) 1
194+
+> print
191195

192196
let generate
193197
d
@@ -658,13 +662,39 @@ let configure formatter =
658662
Code.Var.set_pretty (pretty && not (Config.Flag.shortvar ()));
659663
Code.Var.set_stable (Config.Flag.stable_var ())
660664

661-
let full ~standalone ~wrap_with_fun ~profile ~link ~source_map formatter d p =
662-
let exported_runtime = not standalone in
665+
type 'a target =
666+
| JavaScript : Pretty_print.t -> Source_map.t option target
667+
| Wasm
668+
: (Deadcode.variable_uses * Effects.in_cps * Code.program * Parse_bytecode.Debug.t)
669+
target
670+
671+
let target_flag (type a) (t : a target) =
672+
match t with
673+
| JavaScript _ -> `JavaScript
674+
| Wasm -> `Wasm
675+
676+
let link_and_pack ?(standalone = true) ?(wrap_with_fun = `Iife) ?(link = `No) p =
663677
let export_runtime =
664678
match link with
665679
| `All | `All_from _ -> true
666680
| `Needed | `No -> false
667681
in
682+
p
683+
|> link' ~export_runtime ~standalone ~link
684+
|> pack ~wrap_with_fun ~standalone
685+
|> coloring
686+
|> check_js
687+
688+
let full
689+
(type result)
690+
~(target : result target)
691+
~standalone
692+
~wrap_with_fun
693+
~profile
694+
~link
695+
~source_map
696+
d
697+
p : result =
668698
let deadcode_sentinal =
669699
(* If deadcode is disabled, this field is just fresh variable *)
670700
Code.Var.fresh_n "undef"
@@ -675,58 +705,74 @@ let full ~standalone ~wrap_with_fun ~profile ~link ~source_map formatter d p =
675705
| O1 -> o1
676706
| O2 -> o2
677707
| O3 -> o3)
708+
~target:(target_flag target)
678709
+> exact_calls ~deadcode_sentinal profile
679710
+> effects ~deadcode_sentinal
680-
+> map_fst (if Config.Flag.effects () then fun x -> x else Generate_closure.f)
711+
+> map_fst
712+
(match target with
713+
| JavaScript _ -> if Config.Flag.effects () then Fun.id else Generate_closure.f
714+
| Wasm -> Fun.id)
681715
+> map_fst deadcode'
682716
in
683-
let emit =
684-
generate
685-
d
686-
~exported_runtime
687-
~wrap_with_fun
688-
~warn_on_unhandled_effect:standalone
689-
~deadcode_sentinal
690-
+> link' ~export_runtime ~standalone ~link
691-
+> pack ~wrap_with_fun ~standalone
692-
+> coloring
693-
+> check_js
694-
+> output formatter ~source_map ()
695-
in
696717
if times () then Format.eprintf "Start Optimizing...@.";
697718
let t = Timer.make () in
698719
let r = opt p in
699720
let () = if times () then Format.eprintf " optimizations : %a@." Timer.print t in
700-
emit r
721+
match target with
722+
| JavaScript formatter ->
723+
let exported_runtime = not standalone in
724+
let emit formatter =
725+
generate
726+
d
727+
~exported_runtime
728+
~wrap_with_fun
729+
~warn_on_unhandled_effect:standalone
730+
~deadcode_sentinal
731+
+> link_and_pack ~standalone ~wrap_with_fun ~link
732+
+> output formatter ~source_map ()
733+
in
734+
let source_map = emit formatter r in
735+
source_map
736+
| Wasm ->
737+
let (p, live_vars), _, in_cps = r in
738+
live_vars, in_cps, p, d
701739

702-
let full_no_source_map ~standalone ~wrap_with_fun ~profile ~link formatter d p =
740+
let full_no_source_map ~formatter ~standalone ~wrap_with_fun ~profile ~link d p =
703741
let (_ : Source_map.t option) =
704-
full ~standalone ~wrap_with_fun ~profile ~link ~source_map:None formatter d p
742+
full
743+
~target:(JavaScript formatter)
744+
~standalone
745+
~wrap_with_fun
746+
~profile
747+
~link
748+
~source_map:None
749+
d
750+
p
705751
in
706752
()
707753

708754
let f
755+
~target
709756
?(standalone = true)
710757
?(wrap_with_fun = `Iife)
711758
?(profile = O1)
712759
~link
713760
?source_map
714-
formatter
715761
d
716762
p =
717-
full ~standalone ~wrap_with_fun ~profile ~link ~source_map formatter d p
763+
full ~target ~standalone ~wrap_with_fun ~profile ~link ~source_map d p
718764

719765
let f' ?(standalone = true) ?(wrap_with_fun = `Iife) ?(profile = O1) ~link formatter d p =
720-
full_no_source_map ~standalone ~wrap_with_fun ~profile ~link formatter d p
766+
full_no_source_map ~formatter ~standalone ~wrap_with_fun ~profile ~link d p
721767

722768
let from_string ~prims ~debug s formatter =
723769
let p, d = Parse_bytecode.from_string ~prims ~debug s in
724770
full_no_source_map
771+
~formatter
725772
~standalone:false
726773
~wrap_with_fun:`Anonymous
727774
~profile:O1
728775
~link:`No
729-
formatter
730776
d
731777
p
732778

compiler/lib/driver.mli

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,22 @@
2020

2121
type profile
2222

23+
type 'a target =
24+
| JavaScript : Pretty_print.t -> Source_map.t option target
25+
| Wasm
26+
: (Deadcode.variable_uses * Effects.in_cps * Code.program * Parse_bytecode.Debug.t)
27+
target
28+
2329
val f :
24-
?standalone:bool
30+
target:'result target
31+
-> ?standalone:bool
2532
-> ?wrap_with_fun:[ `Iife | `Anonymous | `Named of string ]
2633
-> ?profile:profile
2734
-> link:[ `All | `All_from of string list | `Needed | `No ]
2835
-> ?source_map:Source_map.t
29-
-> Pretty_print.t
3036
-> Parse_bytecode.Debug.t
3137
-> Code.program
32-
-> Source_map.t option
38+
-> 'result
3339

3440
val f' :
3541
?standalone:bool
@@ -48,6 +54,13 @@ val from_string :
4854
-> Pretty_print.t
4955
-> unit
5056

57+
val link_and_pack :
58+
?standalone:bool
59+
-> ?wrap_with_fun:[ `Iife | `Anonymous | `Named of string ]
60+
-> ?link:[ `All | `All_from of string list | `Needed | `No ]
61+
-> Javascript.statement_list
62+
-> Javascript.statement_list
63+
5164
val configure : Pretty_print.t -> unit
5265

5366
val profiles : (int * profile) list

0 commit comments

Comments
 (0)