Skip to content

Commit 6d8439a

Browse files
committed
add optimization of comparisons
1 parent 11a1719 commit 6d8439a

17 files changed

+118
-6
lines changed

jscomp/core/js_exp_make.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ let rec float_equal ?comment (e0 : t) (e1 : t) : t =
787787
float_equal ?comment a e1
788788
| Number (Float { f = f0; _ }), Number (Float { f = f1 }) when f0 = f1 ->
789789
true_
790+
| Number (Bigint { i = i0 }), Number (Bigint { i = i1 }) -> bool (i0 = i1)
790791
| _ -> { expression_desc = Bin (EqEqEq, e0, e1); comment }
791792

792793
let int_equal = float_equal
@@ -1269,6 +1270,16 @@ let bigint_div ?comment (e1: t) (e2: t) = bin ?comment Div e1 e2
12691270

12701271
let bigint_mod ?comment (e1: t) (e2: t) = bin ?comment Mod e1 e2
12711272

1273+
let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) =
1274+
match (cmp, e0.expression_desc, e1.expression_desc) with
1275+
| Ceq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 = i1)
1276+
| Cneq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <> i1)
1277+
| Cge, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 >= i1)
1278+
| Cgt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 > i1)
1279+
| Cle, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <= i1)
1280+
| Clt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 < i1)
1281+
| _ -> bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1
1282+
12721283
(* TODO -- alpha conversion
12731284
remember to add parens..
12741285
*)

jscomp/core/js_exp_make.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ val bigint_div : ?comment: string -> t -> t -> t
286286

287287
val bigint_mod : ?comment: string -> t -> t -> t
288288

289+
val bigint_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t
290+
289291
val js_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t
290292

291293
val not : t -> t

jscomp/core/lam_analysis.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
7676
(* Float operations *)
7777
| Pintoffloat | Pfloatofint | Pnegfloat
7878
(* | Pabsfloat *)
79-
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pjscomp _
79+
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pbigintcomp _ | Pjscomp _
8080
| Pnegbigint | Paddbigint | Psubbigint | Pmulbigint
8181
(* String operations *)
8282
| Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu

jscomp/core/lam_compile_primitive.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)
251251
[Not_found] or [Invalid_argument] ?
252252
*)
253253
match args with [ e1; e2 ] -> E.int_comp cmp e1 e2 | _ -> assert false)
254+
| Pbigintcomp cmp -> (
255+
match args with [ e1; e2 ] -> E.bigint_comp cmp e1 e2 | _ -> assert false)
254256
(* List --> stamp = 0
255257
Assert_false --> stamp = 26
256258
*)

jscomp/core/lam_convert.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t =
260260
| Pmulbigint -> prim ~primitive:Pmulbigint ~args loc
261261
| Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc
262262
| Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc
263+
| Pbigintcomp x -> prim ~primitive:(Pbigintcomp x) ~args loc
263264
| Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc
264265
| Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc
265266
| Poffsetref x -> prim ~primitive:(Poffsetref x) ~args loc

jscomp/core/lam_dispatch_primitive.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression
123123
| "caml_float_equal_null" | "caml_float_equal_nullable"
124124
| "caml_float_equal_undefined" -> (
125125
match args with [ e0; e1 ] -> E.float_comp Ceq e0 e1 | _ -> assert false)
126+
| "caml_bigint_equal_null" | "caml_bigint_equal_nullable"
127+
| "caml_bigint_equal_undefined" -> (
128+
match args with [ e0; e1 ] -> E.bigint_comp Ceq e0 e1 | _ -> assert false)
126129
| "caml_string_equal_null" | "caml_string_equal_nullable"
127130
| "caml_string_equal_undefined" -> (
128131
match args with
@@ -137,8 +140,9 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression
137140
| "caml_int_compare" ->
138141
E.runtime_call Js_runtime_modules.caml_primitive "int_compare" args
139142
| "caml_float_compare" -> call Js_runtime_modules.caml_primitive
143+
| "caml_bigint_compare" -> call Js_runtime_modules.caml_primitive
140144
| "caml_string_compare" -> call Js_runtime_modules.caml_primitive
141-
| "caml_bool_min" | "caml_int_min" | "caml_float_min" | "caml_string_min" -> (
145+
| "caml_bool_min" | "caml_int_min" | "caml_float_min" | "caml_bigint_min" | "caml_string_min" -> (
142146
match args with
143147
| [ a; b ] ->
144148
if
@@ -147,7 +151,7 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression
147151
then E.econd (E.js_comp Clt a b) a b
148152
else call Js_runtime_modules.caml_primitive
149153
| _ -> assert false)
150-
| "caml_bool_max" | "caml_int_max" | "caml_float_max" | "caml_string_max" -> (
154+
| "caml_bool_max" | "caml_int_max" | "caml_float_max" | "caml_bigint_max" | "caml_string_max" -> (
151155
match args with
152156
| [ a; b ] ->
153157
if

jscomp/core/lam_primitive.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ type t =
9090
| Pfloatcomp of Lam_compat.comparison
9191
| Pjscomp of Lam_compat.comparison
9292
| Pint64comp of Lam_compat.comparison
93+
| Pbigintcomp of Lam_compat.comparison
9394
| Pjs_apply (*[f;arg0;arg1; arg2; ... argN]*)
9495
| Pjs_runtime_apply (* [f; [...]] *)
9596
(* String operations *)
@@ -281,6 +282,11 @@ let eq_primitive_approx (lhs : t) (rhs : t) =
281282
| Pfloatcomp comparison1 ->
282283
Lam_compat.eq_comparison comparison comparison1
283284
| _ -> false)
285+
| Pbigintcomp comparison -> (
286+
match rhs with
287+
| Pbigintcomp comparison1 ->
288+
Lam_compat.eq_comparison comparison comparison1
289+
| _ -> false)
284290
| Pjscomp comparison -> (
285291
match rhs with
286292
| Pjscomp comparison1 -> Lam_compat.eq_comparison comparison comparison1

jscomp/core/lam_primitive.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ type t =
8080
| Pfloatcomp of Lam_compat.comparison
8181
| Pjscomp of Lam_compat.comparison
8282
| Pint64comp of Lam_compat.comparison
83+
| Pbigintcomp of Lam_compat.comparison
8384
| Pjs_apply (*[f;arg0;arg1; arg2; ... argN]*)
8485
| Pjs_runtime_apply (* [f; [...]] *)
8586
| Pstringlength

jscomp/core/lam_print.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ let primitive ppf (prim : Lam_primitive.t) =
140140
| Pmulbigint -> fprintf ppf "*n"
141141
| Pdivbigint -> fprintf ppf "/n"
142142
| Pmodbigint -> fprintf ppf "modn"
143+
| Pbigintcomp Ceq -> fprintf ppf "==,"
144+
| Pbigintcomp Cneq -> fprintf ppf "!=,"
145+
| Pbigintcomp Clt -> fprintf ppf "<,"
146+
| Pbigintcomp Cle -> fprintf ppf "<=,"
147+
| Pbigintcomp Cgt -> fprintf ppf ">,"
148+
| Pbigintcomp Cge -> fprintf ppf ">=,"
143149
| Pjscomp Ceq -> fprintf ppf "#=="
144150
| Pjscomp Cneq -> fprintf ppf "#!="
145151
| Pjscomp Clt -> fprintf ppf "#<"

jscomp/ml/lambda.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ type primitive =
230230
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat
231231
| Pfloatcomp of comparison
232232
(* Bigint operations *)
233-
| Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
233+
| Pnegbigint | Paddbigint | Psubbigint
234+
| Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
235+
| Pbigintcomp of comparison
234236
(* String operations *)
235237
| Pstringlength | Pstringrefu | Pstringrefs
236238
| Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets

jscomp/ml/lambda.mli

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ type primitive =
196196
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat
197197
| Pfloatcomp of comparison
198198
(* Bigint operations *)
199-
| Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
199+
| Pnegbigint | Paddbigint | Psubbigint
200+
| Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe
201+
| Pbigintcomp of comparison
200202
(* String operations *)
201203
| Pstringlength | Pstringrefu | Pstringrefs
202204
| Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets

jscomp/ml/printlambda.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ let primitive ppf = function
185185
| Pdivbigint Unsafe -> fprintf ppf "/nu"
186186
| Pmodbigint Safe -> fprintf ppf "mod"
187187
| Pmodbigint Unsafe -> fprintf ppf "mod_unsafe"
188+
| Pbigintcomp(Ceq) -> fprintf ppf "==,"
189+
| Pbigintcomp(Cneq) -> fprintf ppf "!=,"
190+
| Pbigintcomp(Clt) -> fprintf ppf "<,"
191+
| Pbigintcomp(Cle) -> fprintf ppf "<=,"
192+
| Pbigintcomp(Cgt) -> fprintf ppf ">,"
193+
| Pbigintcomp(Cge) -> fprintf ppf ">=,"
188194
| Pstringlength -> fprintf ppf "string.length"
189195
| Pstringrefu -> fprintf ppf "string.unsafe_get"
190196
| Pstringrefs -> fprintf ppf "string.get"
@@ -292,6 +298,7 @@ let name_of_primitive = function
292298
| Pmulbigint -> "Pmulbigint"
293299
| Pdivbigint _ -> "Pdivbigint"
294300
| Pmodbigint _ -> "Pmodbigint"
301+
| Pbigintcomp _ -> "Pbigintcomp"
295302
| Pstringlength -> "Pstringlength"
296303
| Pstringrefu -> "Pstringrefu"
297304
| Pstringrefs -> "Pstringrefs"

jscomp/ml/translcore.ml

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type specialized = {
5757
stringcomp : Lambda.primitive;
5858
bytescomp : Lambda.primitive;
5959
int64comp : Lambda.primitive;
60+
bigintcomp : Lambda.primitive;
6061
simplify_constant_constructor : bool;
6162
}
6263

@@ -82,6 +83,7 @@ let comparisons_table =
8283
Pccall
8384
(Primitive.simple ~name:"caml_bytes_equal" ~arity:2 ~alloc:false);
8485
int64comp = Pbintcomp (Pint64, Ceq);
86+
bigintcomp = Pbigintcomp Ceq;
8587
simplify_constant_constructor = true;
8688
} );
8789
( "%notequal",
@@ -102,6 +104,7 @@ let comparisons_table =
102104
(Primitive.simple ~name:"caml_bytes_notequal" ~arity:2
103105
~alloc:false);
104106
int64comp = Pbintcomp (Pint64, Cneq);
107+
bigintcomp = Pbigintcomp Cneq;
105108
simplify_constant_constructor = true;
106109
} );
107110
( "%lessthan",
@@ -122,6 +125,7 @@ let comparisons_table =
122125
(Primitive.simple ~name:"caml_bytes_lessthan" ~arity:2
123126
~alloc:false);
124127
int64comp = Pbintcomp (Pint64, Clt);
128+
bigintcomp = Pbigintcomp Clt;
125129
simplify_constant_constructor = false;
126130
} );
127131
( "%greaterthan",
@@ -144,6 +148,7 @@ let comparisons_table =
144148
(Primitive.simple ~name:"caml_bytes_greaterthan" ~arity:2
145149
~alloc:false);
146150
int64comp = Pbintcomp (Pint64, Cgt);
151+
bigintcomp = Pbigintcomp Cgt;
147152
simplify_constant_constructor = false;
148153
} );
149154
( "%lessequal",
@@ -166,6 +171,7 @@ let comparisons_table =
166171
(Primitive.simple ~name:"caml_bytes_lessequal" ~arity:2
167172
~alloc:false);
168173
int64comp = Pbintcomp (Pint64, Cle);
174+
bigintcomp = Pbigintcomp Cle;
169175
simplify_constant_constructor = false;
170176
} );
171177
( "%greaterequal",
@@ -188,6 +194,7 @@ let comparisons_table =
188194
(Primitive.simple ~name:"caml_bytes_greaterequal" ~arity:2
189195
~alloc:false);
190196
int64comp = Pbintcomp (Pint64, Cge);
197+
bigintcomp = Pbigintcomp Cge;
191198
simplify_constant_constructor = false;
192199
} );
193200
( "%compare",
@@ -214,6 +221,9 @@ let comparisons_table =
214221
int64comp =
215222
Pccall
216223
(Primitive.simple ~name:"caml_int64_compare" ~arity:2 ~alloc:false);
224+
bigintcomp =
225+
Pccall
226+
(Primitive.simple ~name:"caml_bigint_compare" ~arity:2 ~alloc:false);
217227
simplify_constant_constructor = false;
218228
} );
219229
( "%bs_max",
@@ -226,6 +236,7 @@ let comparisons_table =
226236
floatcomp = arity2 "caml_float_max";
227237
stringcomp = arity2 "caml_string_max";
228238
int64comp = arity2 "caml_int64_max";
239+
bigintcomp = arity2 "caml_bigint_max";
229240
simplify_constant_constructor = false;
230241
} );
231242
( "%bs_min",
@@ -237,6 +248,7 @@ let comparisons_table =
237248
floatcomp = arity2 "caml_float_min";
238249
stringcomp = arity2 "caml_string_min";
239250
int64comp = arity2 "caml_int64_min";
251+
bigintcomp = arity2 "caml_bigint_min";
240252
simplify_constant_constructor = false;
241253
} );
242254
( "%bs_equal_null",
@@ -249,6 +261,7 @@ let comparisons_table =
249261
floatcomp = arity2 "caml_float_equal_null";
250262
stringcomp = arity2 "caml_string_equal_null";
251263
int64comp = arity2 "caml_int64_equal_null";
264+
bigintcomp = arity2 "caml_bigint_equal_null";
252265
simplify_constant_constructor = true;
253266
} );
254267
( "%bs_equal_undefined",
@@ -261,6 +274,7 @@ let comparisons_table =
261274
floatcomp = arity2 "caml_float_equal_undefined";
262275
stringcomp = arity2 "caml_string_equal_undefined";
263276
int64comp = arity2 "caml_int64_equal_undefined";
277+
bigintcomp = arity2 "caml_bigint_equal_undefined";
264278
simplify_constant_constructor = true;
265279
} );
266280
( "%bs_equal_nullable",
@@ -273,6 +287,7 @@ let comparisons_table =
273287
floatcomp = arity2 "caml_float_equal_nullable";
274288
stringcomp = arity2 "caml_string_equal_nullable";
275289
int64comp = arity2 "caml_int64_equal_nullable";
290+
bigintcomp = arity2 "caml_bigint_equal_nullable";
276291
simplify_constant_constructor = true;
277292
} );
278293
]
@@ -356,6 +371,12 @@ let primitives_table =
356371
("%mulbigint", Pmulbigint);
357372
("%divbigint", Pdivbigint Safe);
358373
("%modbigint", Pmodbigint Safe);
374+
("%eqbigint", Pbigintcomp Ceq);
375+
("%noteqbigint", Pbigintcomp Cneq);
376+
("%ltbigint", Pbigintcomp Clt);
377+
("%lebigint", Pbigintcomp Cle);
378+
("%gtbigint", Pbigintcomp Cgt);
379+
("%gebigint", Pbigintcomp Cge);
359380
("%string_length", Pstringlength);
360381
("%string_safe_get", Pstringrefs);
361382
("%string_unsafe_get", Pstringrefu);
@@ -402,7 +423,7 @@ let primitives_table =
402423
let find_primitive prim_name = Hashtbl.find primitives_table prim_name
403424

404425
let specialize_comparison
405-
({ gencomp; intcomp; floatcomp; stringcomp; bytescomp; int64comp; boolcomp } :
426+
({ gencomp; intcomp; floatcomp; stringcomp; bytescomp; int64comp; bigintcomp; boolcomp } :
406427
specialized) env ty =
407428
match () with
408429
| ()
@@ -414,6 +435,7 @@ let specialize_comparison
414435
| () when is_base_type env ty Predef.path_string -> stringcomp
415436
| () when is_base_type env ty Predef.path_bytes -> bytescomp
416437
| () when is_base_type env ty Predef.path_int64 -> int64comp
438+
| () when is_base_type env ty Predef.path_bigint -> bigintcomp
417439
| () when is_base_type env ty Predef.path_bool -> boolcomp
418440
| () -> gencomp
419441

jscomp/runtime/caml.res

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ let float_compare = (x: float, y: float) =>
5252
0
5353
}
5454

55+
let bigint_compare = (x: bigint, y: bigint) =>
56+
if x == y {
57+
0
58+
} else if x < y {
59+
-1
60+
} else if x > y {
61+
1
62+
} else if x == x {
63+
1
64+
} else if y == y {
65+
-1
66+
} else {
67+
0
68+
}
69+
5570
/* Lexical order */
5671
let string_compare = (s1: string, s2: string): int =>
5772
if s1 == s2 {

jscomp/runtime/caml.resi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type selector<'a> = ('a, 'a) => 'a
2727
let int_compare: (int, int) => int
2828
let bool_compare: (bool, bool) => int
2929
let float_compare: (float, float) => int
30+
let bigint_compare: (bigint, bigint) => int
3031
let string_compare: (string, string) => int
3132

3233
let bool_min: selector<bool>

lib/es6/caml.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ function float_compare(x, y) {
3939
}
4040
}
4141

42+
function bigint_compare(x, y) {
43+
if (x === y) {
44+
return 0;
45+
} else if (x < y) {
46+
return -1;
47+
} else if (x > y || x === x) {
48+
return 1;
49+
} else if (y === y) {
50+
return -1;
51+
} else {
52+
return 0;
53+
}
54+
}
55+
4256
function string_compare(s1, s2) {
4357
if (s1 === s2) {
4458
return 0;
@@ -175,6 +189,7 @@ export {
175189
int_compare ,
176190
bool_compare ,
177191
float_compare ,
192+
bigint_compare ,
178193
string_compare ,
179194
bool_min ,
180195
int_min ,

lib/js/caml.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ function float_compare(x, y) {
3939
}
4040
}
4141

42+
function bigint_compare(x, y) {
43+
if (x === y) {
44+
return 0;
45+
} else if (x < y) {
46+
return -1;
47+
} else if (x > y || x === x) {
48+
return 1;
49+
} else if (y === y) {
50+
return -1;
51+
} else {
52+
return 0;
53+
}
54+
}
55+
4256
function string_compare(s1, s2) {
4357
if (s1 === s2) {
4458
return 0;
@@ -174,6 +188,7 @@ function i64_max(x, y) {
174188
exports.int_compare = int_compare;
175189
exports.bool_compare = bool_compare;
176190
exports.float_compare = float_compare;
191+
exports.bigint_compare = bigint_compare;
177192
exports.string_compare = string_compare;
178193
exports.bool_min = bool_min;
179194
exports.int_min = int_min;

0 commit comments

Comments
 (0)