Skip to content

Commit a8e5ca4

Browse files
author
Hongbo Zhang
committed
small enhancement to cross inlining: TODO: 1. add comments if we can, for example, cross module constants, 2. specialize some functions as early as we can
1 parent b108b85 commit a8e5ca4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+227
-107
lines changed

jscomp/lam_compile.ml

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,38 @@ type default_case =
5151
| Complete
5252
| NonComplete
5353

54+
5455
let rec
55-
compile_let flag (cxt : Lam_compile_defs.cxt) id (arg : Lambda.lambda) : Js_output.t =
56+
get_exp_with_index (cxt : Lam_compile_defs.cxt) lam
57+
((id : Ident.t), (pos : int),env) : Js_output.t =
58+
let f = Js_output.handle_name_tail cxt.st cxt.should_return lam in
59+
Lam_compile_env.find_and_add_if_not_exist (id,pos) env
60+
~not_found:(fun id ->
61+
f (E.str ~pure:false (Printf.sprintf "Err %s %d %d" id.name id.flags pos))
62+
(* E.index m (pos + 1) *) (** shift by one *)
63+
(** This can not happen since this id should be already consulted by type checker *)
64+
)
65+
~found:(fun {id; name; closed_lambda } ->
66+
match id, name, closed_lambda with
67+
| {name = "Sys"; _}, "os_type" , _
68+
(** We drop the ability of cross-compiling
69+
the compiler has to be the same running
70+
*)
71+
-> f (E.str Sys.os_type)
72+
| _, _, Some lam when Lam_util.not_function lam
73+
(* since it's only for alias, there is no arguments,
74+
we should not inline function definition here, even though
75+
it is very small
76+
TODO: add comment here, we should try to add comment for
77+
cross module inlining
78+
*)
79+
->
80+
compile_lambda cxt lam
81+
| _ ->
82+
f (E.ml_var_dot id name)
83+
)
84+
85+
and compile_let flag (cxt : Lam_compile_defs.cxt) id (arg : Lambda.lambda) : Js_output.t =
5686

5787

5888
match flag, arg with
@@ -296,7 +326,7 @@ and
296326
for the function, generative module or functor can be a function,
297327
however it can not be global -- global can only module
298328
*)
299-
[], Lam_compile_global.get_exp (QueryGlobal (i, env,true))
329+
[], Lam_compile_global.get_exp (i, env,true)
300330
| _ ->
301331
begin
302332
match compile_lambda
@@ -326,7 +356,7 @@ and
326356
for the function, generative module or functor can be a function,
327357
however it can not be global -- global can only module
328358
*)
329-
[], Lam_compile_global.get_exp (QueryGlobal (ident, env,true))
359+
[], Lam_compile_global.get_exp (ident, env,true)
330360
| _ ->
331361
begin
332362
match compile_lambda
@@ -438,8 +468,7 @@ and
438468
Js_output.handle_name_tail st should_return lam (Lam_compile_const.translate c)
439469

440470
| Lprim(Pfield n, [ Lprim(Pgetglobal id,[])]) -> (* should be before Pgetglobal *)
441-
Js_output.handle_name_tail st should_return lam
442-
(Lam_compile_global.get_exp (GetGlobal (id,n, env)))
471+
get_exp_with_index cxt lam (id,n, env)
443472

444473
| Lprim(Praise _raise_kind, [ e ]) ->
445474
begin
@@ -1075,7 +1104,7 @@ and
10751104
|> List.map (fun (x : Lambda.lambda) ->
10761105
match x with
10771106
| Lprim (Pgetglobal i, []) ->
1078-
[], Lam_compile_global.get_exp (QueryGlobal (i, env, true))
1107+
[], Lam_compile_global.get_exp (i, env, true)
10791108
| _ ->
10801109
begin
10811110
match compile_lambda {cxt with st = NeedValue; should_return = False}

jscomp/lam_compile_env.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ type module_info = {
4646
type primitive_description = Types.type_expr option Primitive.description
4747

4848
type key =
49-
| GetGlobal of Ident.t * int * Env.t
50-
| QueryGlobal of Ident.t * Env.t * bool (** we need register which global variable is an dependency *)
51-
| CamlRuntimePrimitive of primitive_description * J.expression list
49+
50+
Ident.t * Env.t * bool (** we need register which global variable is an dependency *)
51+
5252

5353
type ident_info = {
5454
id : Ident.t;

jscomp/lam_compile_env.mli

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@
2525
type primitive_description = Types.type_expr option Primitive.description
2626

2727
type key =
28-
| GetGlobal of Ident.t * int * Env.t
29-
| QueryGlobal of Ident.t * Env.t * bool
28+
Ident.t * Env.t * bool
3029
(** the boolean is expand or not
3130
when it's passed as module, it should be expanded,
3231
otherwise for alias, [include Array], it's okay to return an identifier
3332
TODO: be more clear about its concept
3433
*)
3534
(** we need register which global variable is an dependency *)
36-
| CamlRuntimePrimitive of primitive_description * J.expression list
35+
3736

3837
type ident_info = {
3938
id : Ident.t;

jscomp/lam_compile_external_call.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ let translate
288288
in
289289
E.obj kvs
290290
| None -> assert false
291-
(* Lam_compile_global.get_exp (CamlRuntimePrimitive (prim, args)) *)
291+
292292
end
293293
| Js_call{ external_module_name = module_name;
294294
txt = { name = fn; splice = js_splice ;
@@ -375,8 +375,8 @@ let translate
375375
| _ -> assert false
376376
end
377377

378-
| Normal ->
379-
Lam_compile_global.get_exp (CamlRuntimePrimitive (prim, args))
378+
| Normal -> Lam_dispatch_primitive.query prim args
379+
380380

381381
end
382382

jscomp/lam_compile_global.ml

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,11 @@ let query_lambda id env =
4141
Lambda.Lprim(Pfield i, [Lprim(Pgetglobal id,[])])))
4242
sigs))
4343

44+
4445
(* Given an module name and position, find its corresponding name *)
4546
let get_exp (key : Lam_compile_env.key) : J.expression =
4647
match key with
47-
| GetGlobal ((id : Ident.t), (pos : int),env) ->
48-
Lam_compile_env.find_and_add_if_not_exist (id,pos) env
49-
~not_found:(fun id ->
50-
E.str ~pure:false (Printf.sprintf "Err %s %d %d" id.name id.flags pos)
51-
(* E.index m (pos + 1) *) (** shift by one *)
52-
(** This can not happen since this id should be already consulted by type checker *)
53-
)
54-
~found:(fun {id; name;_} ->
55-
match id, name with
56-
| {name = "Sys"; _}, "os_type"
57-
(** We drop the ability of cross-compiling
58-
the compiler has to be the same running
59-
*)
60-
-> E.str Sys.os_type
61-
| _ ->
62-
E.ml_var_dot id name
63-
)
64-
65-
| QueryGlobal (id, env, expand) ->
48+
(id, env, expand) ->
6649
if Ident.is_predef_exn id
6750
then
6851
begin
@@ -83,9 +66,7 @@ let get_exp (key : Lam_compile_env.key) : J.expression =
8366
else
8467
E.ml_var id)
8568

86-
| CamlRuntimePrimitive (prim, args) ->
87-
Lam_dispatch_primitive.query prim args
88-
69+
8970

9071
(* TODO: how nested module call would behave,
9172
In the future, we should keep in track of if

jscomp/lam_compile_group.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ let lambda_as_module
354354
(lam : Lambda.lambda) =
355355
begin
356356
Lam_current_unit.set_file filename ;
357-
Lam_current_unit.iset_debug_file "ari_regress_test.ml";
357+
Lam_current_unit.iset_debug_file "pervasives.ml";
358358
Ext_pervasives.with_file_as_chan
359359
(Ext_filename.chop_extension ~loc:__LOC__ filename ^ ".js")
360360
(fun chan -> Js_dump.dump_program (compile ~filename false env sigs lam) chan)

jscomp/lam_compile_primitive.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ let translate
298298
1. include Array --> let include = Array
299299
2. get exception
300300
*)
301-
Lam_compile_global.get_exp (QueryGlobal (i,env,false))
301+
Lam_compile_global.get_exp (i,env,false)
302302

303303
(** only when Lapply -> expand = true*)
304304
| Praise _raise_kind -> assert false (* handled before here *)

jscomp/lam_inline_util.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
let maybe_functor (name : string) =
2525
name.[0] >= 'A' && name.[0] <= 'Z'
2626

27+
28+
let should_be_functor (name : string) lam =
29+
maybe_functor name && (function | Lambda.Lfunction _ -> true | _ -> false) lam
30+
2731
(* TODO: add a context, like
2832
[args]
2933
[Lfunction(params,body)]

jscomp/lam_inline_util.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@
2323
(** Utilities for lambda inlining *)
2424

2525
val maybe_functor : string -> bool
26+
27+
val should_be_functor : string -> Lambda.lambda -> bool

jscomp/lam_stats_util.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,21 @@ let export_to_cmj
250250
(fun acc (x : Ident.t) (lambda : Lambda.lambda) ->
251251
let arity = get_arity meta (Lvar x) in
252252
let closed_lambda =
253-
if Lam_inline_util.maybe_functor x.name
253+
if Lam_inline_util.should_be_functor x.name lambda (* can also be submodule *)
254254
then
255255
if Lam_analysis.is_closed lambda (* TODO: seriealize more*)
256256
then Some lambda
257257
else None
258+
else
259+
if Lam_analysis.size lambda < Lam_analysis.small_inline_size
260+
&&
261+
Lam_analysis.is_closed lambda
262+
(* global need re-assocate when do the beta reduction *)
263+
then
264+
begin
265+
Ext_log.dwarn __LOC__ "%s recorded for inlining @." x.name ;
266+
Some lambda
267+
end
258268
else None in
259269
String_map.add x.name Js_cmj_format.{arity ; closed_lambda } acc
260270
)

jscomp/lam_util.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,7 @@ let mk_apply_info ?(loc = Location.none) apply_status : Lambda.apply_info =
316316
let lam_true : Lambda.lambda = Lconst (Const_pointer ( 1, NullConstructor "true"))
317317

318318
let lam_false : Lambda.lambda = Lconst (Const_pointer( 0, NullConstructor "false"))
319+
320+
let not_function (lam : Lambda.lambda) =
321+
match lam with
322+
| Lfunction _ -> false | _ -> true

jscomp/lam_util.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,4 @@ val mk_apply_info : ?loc:Location.t -> Lambda.apply_status -> Lambda.apply_info
6161

6262
val lam_true : Lambda.lambda
6363
val lam_false : Lambda.lambda
64+
val not_function : Lambda.lambda -> bool

jscomp/stdlib/camlinternalFormat.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function rev_char_set(char_set) {
3434
for(var i = 0; i<= 31; ++i){
3535
char_set$prime[i] = Pervasives.char_of_int(char_set.charCodeAt(i) ^ 255);
3636
}
37-
return Bytes.unsafe_to_string(char_set$prime);
37+
return Caml_string.bytes_to_string(char_set$prime);
3838
}
3939

4040
function is_in_char_set(char_set, c) {
@@ -3309,7 +3309,7 @@ function fix_padding(padty, width, str) {
33093309
break;
33103310

33113311
}
3312-
return Bytes.unsafe_to_string(res);
3312+
return Caml_string.bytes_to_string(res);
33133313
}
33143314
}
33153315

@@ -3350,7 +3350,7 @@ function fix_int_precision(prec, str) {
33503350
var res = Bytes.make(prec$1 + 2, /* "0" */48);
33513351
res[1] = str.charCodeAt(1);
33523352
$$String.blit(str, 2, res, prec$1 - len + 4, len - 2);
3353-
return Bytes.unsafe_to_string(res);
3353+
return Caml_string.bytes_to_string(res);
33543354
}
33553355
else {
33563356
exit = 2;
@@ -3383,7 +3383,7 @@ function fix_int_precision(prec, str) {
33833383
var res$1 = Bytes.make(prec$1 + 1, /* "0" */48);
33843384
res$1[0] = c;
33853385
$$String.blit(str, 1, res$1, prec$1 - len + 2, len - 1);
3386-
return Bytes.unsafe_to_string(res$1);
3386+
return Caml_string.bytes_to_string(res$1);
33873387
}
33883388
else {
33893389
return str;
@@ -3393,7 +3393,7 @@ function fix_int_precision(prec, str) {
33933393
if (prec$1 > len) {
33943394
var res$2 = Bytes.make(prec$1, /* "0" */48);
33953395
$$String.blit(str, 0, res$2, prec$1 - len, len);
3396-
return Bytes.unsafe_to_string(res$2);
3396+
return Caml_string.bytes_to_string(res$2);
33973397
}
33983398
else {
33993399
return str;

jscomp/stdlib/camlinternalLazy.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
'use strict';
33

44
var Caml_obj_runtime = require("../runtime/caml_obj_runtime");
5-
var Obj = require("./obj");
65
var Caml_exceptions = require("../runtime/caml_exceptions");
76

87
var Undefined = [
@@ -21,7 +20,7 @@ function force_lazy_block(blk) {
2120
try {
2221
var result = closure(/* () */0);
2322
blk[0] = result;
24-
Caml_obj_runtime.caml_obj_set_tag(blk, Obj.forward_tag);
23+
Caml_obj_runtime.caml_obj_set_tag(blk, 250);
2524
return result;
2625
}
2726
catch (e){
@@ -37,16 +36,16 @@ function force_val_lazy_block(blk) {
3736
blk[0] = raise_undefined;
3837
var result = closure(/* () */0);
3938
blk[0] = result;
40-
Caml_obj_runtime.caml_obj_set_tag(blk, Obj.forward_tag);
39+
Caml_obj_runtime.caml_obj_set_tag(blk, 250);
4140
return result;
4241
}
4342

4443
function force(lzv) {
4544
var t = Caml_obj_runtime.caml_obj_tag(lzv);
46-
if (t === Obj.forward_tag) {
45+
if (t === 250) {
4746
return lzv[0];
4847
}
49-
else if (t !== Obj.lazy_tag) {
48+
else if (t !== 246) {
5049
return lzv;
5150
}
5251
else {
@@ -56,10 +55,10 @@ function force(lzv) {
5655

5756
function force_val(lzv) {
5857
var t = Caml_obj_runtime.caml_obj_tag(lzv);
59-
if (t === Obj.forward_tag) {
58+
if (t === 250) {
6059
return lzv[0];
6160
}
62-
else if (t !== Obj.lazy_tag) {
61+
else if (t !== 246) {
6362
return lzv;
6463
}
6564
else {

jscomp/stdlib/camlinternalMod.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
'use strict';
33

44
var Caml_obj_runtime = require("../runtime/caml_obj_runtime");
5-
var Obj = require("./obj");
65
var Caml_exceptions = require("../runtime/caml_exceptions");
76
var CamlinternalOO = require("./camlinternalOO");
87
var $$Array = require("./array");
@@ -67,7 +66,7 @@ function update_mod(shape, o, n) {
6766
if (typeof shape === "number") {
6867
switch (shape) {
6968
case 0 :
70-
if (Caml_obj_runtime.caml_obj_tag(n) === Obj.closure_tag && n.length <= o.length) {
69+
if (Caml_obj_runtime.caml_obj_tag(n) === 247 && n.length <= o.length) {
7170
overwrite(o, n);
7271
return Caml_obj_runtime.caml_obj_truncate(o, n.length);
7372
}
@@ -77,17 +76,17 @@ function update_mod(shape, o, n) {
7776
});
7877
}
7978
case 1 :
80-
if (Caml_obj_runtime.caml_obj_tag(n) === Obj.lazy_tag) {
79+
if (Caml_obj_runtime.caml_obj_tag(n) === 246) {
8180
o[0] = n[0];
8281
return /* () */0;
8382
}
84-
else if (Caml_obj_runtime.caml_obj_tag(n) === Obj.forward_tag) {
85-
Caml_obj_runtime.caml_obj_set_tag(o, Obj.forward_tag);
83+
else if (Caml_obj_runtime.caml_obj_tag(n) === 250) {
84+
Caml_obj_runtime.caml_obj_set_tag(o, 250);
8685
o[0] = n[0];
8786
return /* () */0;
8887
}
8988
else {
90-
Caml_obj_runtime.caml_obj_set_tag(o, Obj.forward_tag);
89+
Caml_obj_runtime.caml_obj_set_tag(o, 250);
9190
o[0] = n;
9291
return /* () */0;
9392
}

jscomp/stdlib/camlinternalOO.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ function inherits(cla, vals, virt_meths, concr_meths, param, top) {
815815
narrow(cla, vals, virt_meths, concr_meths);
816816
var init = top ? $$super(cla, param[4]) : $$super(cla);
817817
widen(cla);
818-
return $$Array.concat([
818+
return Caml_array.caml_array_concat([
819819
/* :: */0,
820820
/* array */[init],
821821
[

0 commit comments

Comments
 (0)