@@ -44,34 +44,35 @@ let deadcode p =
44
44
let r, _ = deadcode' p in
45
45
r
46
46
47
- let inline p =
47
+ let inline ~ target p =
48
48
if Config.Flag. inline () && Config.Flag. deadcode ()
49
49
then (
50
50
let p, live_vars = deadcode' p in
51
51
if debug () then Format. eprintf " Inlining...@." ;
52
- Inline. f p live_vars)
52
+ Inline. f ~target p live_vars)
53
53
else p
54
54
55
55
let specialize_1 (p , info ) =
56
56
if debug () then Format. eprintf " Specialize...@." ;
57
57
Specialize. f ~function_arity: (fun f -> Specialize. function_arity info f) p
58
58
59
- let specialize_js (p , info ) =
59
+ let specialize_js ~ target (p , info ) =
60
60
if debug () then Format. eprintf " Specialize js...@." ;
61
- Specialize_js. f info p
61
+ Specialize_js. f ~target info p
62
62
63
63
let specialize_js_once p =
64
64
if debug () then Format. eprintf " Specialize js once...@." ;
65
65
Specialize_js. f_once p
66
66
67
- let specialize' (p , info ) =
67
+ let specialize' ~ target (p , info ) =
68
68
let p = specialize_1 (p, info) in
69
- let p = specialize_js (p, info) in
69
+ let p = specialize_js ~target (p, info) in
70
70
p, info
71
71
72
- let specialize p = fst (specialize' p)
72
+ let specialize ~ target p = fst (specialize' ~target p)
73
73
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
75
76
76
77
let flow p =
77
78
if debug () then Format. eprintf " Data flow...@." ;
@@ -143,51 +144,54 @@ let identity x = x
143
144
144
145
(* o1 *)
145
146
146
- let o1 : 'a -> 'a =
147
+ let o1 ~ target : 'a -> 'a =
147
148
print
148
149
+> tailcall
149
150
+> 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 *)
153
154
+> deadcode
154
155
+> tailcall
155
156
+> phi
156
157
+> flow
157
- +> specialize'
158
- +> eval
159
- +> inline
158
+ +> specialize' ~target
159
+ +> eval ~target
160
+ +> inline ~target
160
161
+> deadcode
161
162
+> print
162
163
+> flow
163
- +> specialize'
164
- +> eval
165
- +> inline
164
+ +> specialize' ~target
165
+ +> eval ~target
166
+ +> inline ~target
166
167
+> deadcode
167
168
+> phi
168
169
+> flow
169
- +> specialize
170
+ +> specialize ~target
170
171
+> identity
171
172
172
173
(* o2 *)
173
174
174
- let o2 : 'a -> 'a = loop 10 " o1" o1 1 +> print
175
+ let o2 ~ target : 'a -> 'a = loop 10 " o1" (o1 ~target ) 1 +> print
175
176
176
177
(* o3 *)
177
178
178
- let round1 : 'a -> 'a =
179
+ let round1 ~ target : 'a -> 'a =
179
180
print
180
181
+> tailcall
181
- +> inline (* inlining may reveal new tailcall opt *)
182
+ +> inline ~target (* inlining may reveal new tailcall opt *)
182
183
+> deadcode (* deadcode required before flow simple -> provided by constant *)
183
184
+> flow_simple (* flow simple to keep information for future tailcall opt *)
184
- +> specialize'
185
- +> eval
185
+ +> specialize' ~target
186
+ +> eval ~target
186
187
+> identity
187
188
188
- let round2 = flow +> specialize' +> eval +> deadcode +> o1
189
+ let round2 ~ target = flow +> specialize' ~target +> eval ~target +> deadcode +> o1 ~target
189
190
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
191
195
192
196
let generate
193
197
d
@@ -658,13 +662,39 @@ let configure formatter =
658
662
Code.Var. set_pretty (pretty && not (Config.Flag. shortvar () ));
659
663
Code.Var. set_stable (Config.Flag. stable_var () )
660
664
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 =
663
677
let export_runtime =
664
678
match link with
665
679
| `All | `All_from _ -> true
666
680
| `Needed | `No -> false
667
681
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 =
668
698
let deadcode_sentinal =
669
699
(* If deadcode is disabled, this field is just fresh variable *)
670
700
Code.Var. fresh_n " undef"
@@ -675,58 +705,74 @@ let full ~standalone ~wrap_with_fun ~profile ~link ~source_map formatter d p =
675
705
| O1 -> o1
676
706
| O2 -> o2
677
707
| O3 -> o3)
708
+ ~target: (target_flag target)
678
709
+> exact_calls ~deadcode_sentinal profile
679
710
+> 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)
681
715
+> map_fst deadcode'
682
716
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
696
717
if times () then Format. eprintf " Start Optimizing...@." ;
697
718
let t = Timer. make () in
698
719
let r = opt p in
699
720
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
701
739
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 =
703
741
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
705
751
in
706
752
()
707
753
708
754
let f
755
+ ~target
709
756
?(standalone = true )
710
757
?(wrap_with_fun = `Iife )
711
758
?(profile = O1 )
712
759
~link
713
760
?source_map
714
- formatter
715
761
d
716
762
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
718
764
719
765
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
721
767
722
768
let from_string ~prims ~debug s formatter =
723
769
let p, d = Parse_bytecode. from_string ~prims ~debug s in
724
770
full_no_source_map
771
+ ~formatter
725
772
~standalone: false
726
773
~wrap_with_fun: `Anonymous
727
774
~profile: O1
728
775
~link: `No
729
- formatter
730
776
d
731
777
p
732
778
0 commit comments