11(* Copyright (C) 2015 - 2016 Bloomberg Finance L.P.
2- * Copyright (C) 2017 - Hongbo Zhang, Authors of ReScript
2+ * Copyright (C) 2017 - Hongbo Zhang, Authors of ReScript
33 * This program is free software: you can redistribute it and/or modify
44 * it under the terms of the GNU Lesser General Public License as published by
55 * the Free Software Foundation, either version 3 of the License, or
1717 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1919 * GNU Lesser General Public License for more details.
20- *
20+ *
2121 * You should have received a copy of the GNU Lesser General Public License
2222 * along with this program; if not, write to the Free Software
2323 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
3232
3333
3434(*
35- let add_required_modules ( x : Ident.t list) (meta : Lam_stats.t) =
35+ let add_required_modules ( x : Ident.t list) (meta : Lam_stats.t) =
3636 let meta_require_modules = meta.required_modules in
37- List.iter (fun x -> add meta_require_modules (Lam_module_ident.of_ml x)) x
37+ List.iter (fun x -> add meta_require_modules (Lam_module_ident.of_ml x)) x
3838*)
3939
4040
@@ -45,13 +45,11 @@ let refine_let ~kind param (arg : Lam.t) (l : Lam.t) : Lam.t =
4545 | Lam_primitive. Pmakeblock _ -> true
4646 | _ -> false
4747 in
48- (* Helper for spotting RHS expressions that are safe to inline everywhere.
49- These are the obviously pure shapes where substituting the original value
50- cannot introduce extra work or side effects. *)
51- let is_alias_candidate (lam : Lam.t ) =
48+ let is_safe_to_inline (lam : Lam.t ) =
5249 match lam with
5350 | Lvar _ | Lconst _ -> true
54- | Lprim { primitive = Psome_not_nest ; _ } -> true
51+ | Lprim { primitive = Psome_not_nest ; args = [inner]; _ } ->
52+ Lam_analysis. no_side_effects inner
5553 | Lprim { primitive = Pfield (_ , Fld_module _ ); args = [ (Lglobal_module _ | Lvar _ ) ]; _ } -> true
5654 | _ -> false
5755 in
@@ -74,7 +72,7 @@ let refine_let ~kind param (arg : Lam.t) (l : Lam.t) : Lam.t =
7472 rewrite to `someFn(value)` as long as the callee does not capture `x`.
7573 This removes the temporary binding while preserving the call semantics. *)
7674 Lam. apply fn [arg] ap_info ~ap_transformed_jsx
77- | (Strict | StrictOpt ), arg , _ when is_alias_candidate arg ->
75+ | (Strict | StrictOpt ), arg , _ when is_safe_to_inline arg ->
7876 (* `Strict` and `StrictOpt` bindings both evaluate the RHS immediately
7977 (with `StrictOpt` allowing later elimination if unused). When that RHS
8078 is pure — `{ let x = Some(value); ... }`, `{ let x = 3; ... }`, or a module
@@ -96,15 +94,15 @@ let refine_let ~kind param (arg : Lam.t) (l : Lam.t) : Lam.t =
9694 | kind , _ , _ ->
9795 Lam. let_ kind param arg l
9896
99- let alias_ident_or_global (meta : Lam_stats.t ) (k :Ident.t ) (v :Ident.t )
97+ let alias_ident_or_global (meta : Lam_stats.t ) (k :Ident.t ) (v :Ident.t )
10098 (v_kind : Lam_id_kind.t ) =
101- (* treat rec as Strict, k is assigned to v
99+ (* treat rec as Strict, k is assigned to v
102100 {[ let k = v ]}
103101 *)
104- match v_kind with
102+ match v_kind with
105103 | NA ->
106- begin
107- match Hash_ident. find_opt meta.ident_tbl v with
104+ begin
105+ match Hash_ident. find_opt meta.ident_tbl v with
108106 | None -> ()
109107 | Some ident_info -> Hash_ident. add meta.ident_tbl k ident_info
110108 end
@@ -113,59 +111,59 @@ let alias_ident_or_global (meta : Lam_stats.t) (k:Ident.t) (v:Ident.t)
113111(* share -- it is safe to share most properties,
114112 for arity, we might be careful, only [Alias] can share,
115113 since two values have same type, can have different arities
116- TODO: check with reference pass, it might break
114+ TODO: check with reference pass, it might break
117115 since it will create new identifier, we can avoid such issue??
118116
119- actually arity is a dynamic property, for a reference, it can
120- be changed across
117+ actually arity is a dynamic property, for a reference, it can
118+ be changed across
121119 we should treat
122- reference specially. or maybe we should track any
120+ reference specially. or maybe we should track any
123121 mutable reference
124122*)
125123
126124
127125
128126
129127
130- (* How we destruct the immutable block
131- depend on the block name itself,
128+ (* How we destruct the immutable block
129+ depend on the block name itself,
132130 good hints to do aggressive destructing
133131 1. the variable is not exported
134132 like [matched] -- these are blocks constructed temporary
135- 2. how the variable is used
136- if it is guarateed to be
137- - non export
133+ 2. how the variable is used
134+ if it is guarateed to be
135+ - non export
138136 - and non escaped (there is no place it is used as a whole)
139- then we can always destruct it
140- if some fields are used in multiple places, we can create
141- a temporary field
137+ then we can always destruct it
138+ if some fields are used in multiple places, we can create
139+ a temporary field
142140
143- 3. It would be nice that when the block is mutable, its
141+ 3. It would be nice that when the block is mutable, its
144142 mutable fields are explicit, since wen can not inline an mutable block access
145143*)
146144
147- let element_of_lambda (lam : Lam.t ) : Lam_id_kind.element =
148- match lam with
149- | Lvar _
150- | Lconst _
151- | Lprim {primitive = Pfield (_, Fld_module _) ;
145+ let element_of_lambda (lam : Lam.t ) : Lam_id_kind.element =
146+ match lam with
147+ | Lvar _
148+ | Lconst _
149+ | Lprim {primitive = Pfield (_, Fld_module _) ;
152150 args = [ Lglobal_module _ | Lvar _ ];
153151 _} -> SimpleForm lam
154152 (* | Lfunction _ *)
155- | _ -> NA
153+ | _ -> NA
156154
157- let kind_of_lambda_block (xs : Lam.t list ) : Lam_id_kind.t =
158- ImmutableBlock ( Ext_array. of_list_map xs (fun x ->
155+ let kind_of_lambda_block (xs : Lam.t list ) : Lam_id_kind.t =
156+ ImmutableBlock ( Ext_array. of_list_map xs (fun x ->
159157 element_of_lambda x ))
160158
161159let field_flatten_get
162160 lam v i info (tbl : Lam_id_kind.t Hash_ident.t ) : Lam.t =
163- match Hash_ident. find_opt tbl v with
164- | Some (Module g ) ->
165- Lam. prim ~primitive: (Pfield (i, info))
161+ match Hash_ident. find_opt tbl v with
162+ | Some (Module g ) ->
163+ Lam. prim ~primitive: (Pfield (i, info))
166164 ~args: [ Lam. global_module g ] Location. none
167- | Some (ImmutableBlock (arr )) ->
168- begin match arr.(i) with
165+ | Some (ImmutableBlock (arr )) ->
166+ begin match arr.(i) with
169167 | NA -> lam ()
170168 | SimpleForm l -> l
171169 | exception _ -> lam ()
@@ -182,7 +180,7 @@ let field_flatten_get
182180 | _ -> lam ()
183181 )
184182 | Some (Constant (Const_block (_ ,_ ,ls ))) ->
185- begin match Ext_list. nth_opt ls i with
183+ begin match Ext_list. nth_opt ls i with
186184 | None -> lam ()
187185 | Some x when not (Lam_constant. is_allocating x) -> Lam. const x
188186 | Some _ -> lam ()
@@ -191,49 +189,49 @@ let field_flatten_get
191189 | None -> lam ()
192190
193191#if (defined BROWSER || defined RELEASE )
194- let dump ext lam =
192+ let dump ext lam =
195193 ()
196194#else
197195let log_counter = ref 0
198- let dump ext lam =
196+ let dump ext lam =
199197 if ! Js_config. diagnose
200- then
198+ then
201199 (* ATTENTION: easy to introduce a bug during refactoring when forgeting `begin` `end`*)
202- begin
200+ begin
203201 incr log_counter;
204202 Ext_log. dwarn ~__POS__ " \n @[[TIME:]%s: %f@]@." ext (Sys. time () *. 1000. );
205- Lam_print. serialize
203+ Lam_print. serialize
206204 (Ext_filename. new_extension
207205 ! Location. input_name
208206 (Printf. sprintf " .%02d%s.lam" ! log_counter ext)
209207 ) lam;
210208 end
211- #endif
209+ #endif
212210
213211
214212
215213
216214
217- let is_function (lam : Lam.t ) =
218- match lam with
215+ let is_function (lam : Lam.t ) =
216+ match lam with
219217 | Lfunction _ -> true | _ -> false
220218
221- let not_function (lam : Lam.t ) =
222- match lam with
223- | Lfunction _ -> false | _ -> true
224- (*
225- let is_var (lam : Lam.t) id =
226- match lam with
227- | Lvar id0 -> Ident.same id0 id
219+ let not_function (lam : Lam.t ) =
220+ match lam with
221+ | Lfunction _ -> false | _ -> true
222+ (*
223+ let is_var (lam : Lam.t) id =
224+ match lam with
225+ | Lvar id0 -> Ident.same id0 id
228226 | _ -> false *)
229227
230228
231- (* TODO: we need create
232- 1. a smart [let] combinator, reusable beta-reduction
233- 2. [lapply fn args info]
229+ (* TODO: we need create
230+ 1. a smart [let] combinator, reusable beta-reduction
231+ 2. [lapply fn args info]
234232 here [fn] should get the last tail
235- for example
233+ for example
236234 {[
237- lapply (let a = 3 in let b = 4 in fun x y -> x + y) 2 3
238- ]}
235+ lapply (let a = 3 in let b = 4 in fun x y -> x + y) 2 3
236+ ]}
239237*)
0 commit comments