Skip to content

Commit a720330

Browse files
authored
Merge pull request #4211 from BuckleScript/int64_optimize
optimize int64 performance
2 parents 016d321 + 1f5ca73 commit a720330

29 files changed

+3240
-1314
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,5 @@ vendor/ocaml
141141
jscomp/.lsp
142142
.vscode/launch.json
143143
tracing*.json
144-
darwin/bsc
144+
darwin/bsc
145+
.nyc_output

jscomp/core/lam_dispatch_primitive.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ let translate loc (prim_name : string)
295295
end
296296
| "caml_bytes_equal" ->
297297
call Js_runtime_modules.caml_primitive
298+
| "caml_int64_succ" ->
299+
E.runtime_call Js_runtime_modules.int64 "succ" args
300+
| "caml_int64_to_string" ->
301+
E.runtime_call Js_runtime_modules.int64 "to_string" args
298302
| "caml_int64_equal_null"
299303
-> Js_long.equal_null args
300304
| "caml_int64_equal_undefined"

jscomp/main/builtin_cmj_datasets.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(* 1c67afbfcabae03627c965ef5a338b0c *)
1+
(* 442de69a70d003e5e42a71e854097867 *)
22
let module_names : string array = Obj.magic (
33
"Gc" (* 220 *),
44
"Js" (* 23 *),
@@ -162,7 +162,7 @@ let module_data : string array = Obj.magic (
162162
(* Array *)"\132\149\166\190\000\000\0020\000\000\000\164\000\000\002\029\000\000\001\252\160\b\000\000l\000\176#map\144\160\160B@@@\176#mem\144\160\160B@@@\176#sub\144\160\160C@@@\176$blit\144\160\160E@@@\176$copy\144\160\160A@@@\176$fill\144\160\160D@@@\176$init\144\160\160B@@@\176$iter\144\160\160B@@@\176$map2\144\160\160C@@@\176$mapi\144\160\160B@@@\176$memq\144\160\160B@@@\176$sort\144\160\160B@@@\176%iter2\144\160\160C@@@\176%iteri\144\160\160B@@@\176&append\144\160\160B@@@\176&concat\144\160\160A@@\144\180A\160\176\001\005\195$prim@@\151\176\149\1761caml_array_concatA \160\144\004\n@\176\1923stdlib-406/array.ml`\001\006\247\001\006\247\192\004\002`\001\006\247\001\0078@\176&exists\144\160\160B@@@\176'for_all\144\160\160B@@@\176'of_list\144\160\160A@@@\176'to_list\144\160\160A@@@\176)fast_sort\144\160\160B@@@\176)fold_left\144\160\160C@@@\176*fold_right\144\160\160C@@@\176*make_float\144\160\160A@@\144\180A\160\176\001\005\201\0049@@\151\176\149\1764caml_make_float_vectA\0048\160\144\004\b@\176\192\0047d\001\007\219\001\007\236\192\0048d\001\007\219\001\007\248@\176+make_matrix\144\160\160C@@@\176+stable_sort\144\004'@\176-create_matrix\144\004\b@A",
163163
(* Bytes *)"\132\149\166\190\000\000\003\243\000\000\001\020\000\000\003\160\000\000\003g\160\b\000\000\168\000\176#cat\144\160\160B@@@\176#map\144\160\160B@@@\176#sub\144\160\160C@@@\176$blit\144\160\160E@@@\176$copy\144\160\160A@@@\176$fill\144\160\160D@@@\176$init\144\160\160B@@@\176$iter\144\160\160B@@@\176$make\144\160\160B@@@\176$mapi\144\160\160B@@@\176$trim\144\160\160A@@@\176%equal\144\160\160B@@\144\180B\160\176\001\005\198$prim@\160\176\001\005\197\004\003@@\151\176\149\1760caml_bytes_equalB \160\144\004\012\160\144\004\011@\176\1923stdlib-406/bytes.ml\001\001A\001%\215\001%\215\192\004\002\001\001A\001%\215\001&\011@\176%index\144\160\160B@@@\176%iteri\144\160\160B@@@\176&concat\144\160\160B@@@\176&extend\144\160\160C@@@\176&rindex\144\160\160B@@@\176'compare\144\160\160B@@\144\180B\160\176\001\005\132!x@\160\176\001\005\133!y@@\151\176\149\1762caml_bytes_compareB \160\144\004\r\160\144\004\012@\176\192\0044\001\001@\001%\164\001%\192\192\0045\001\001@\001%\164\001%\214@\176'escaped\144\160\160A@@@\176(contains\144\160\160B@@@\176)index_opt\144\160\160B@@@\176)lowercase\144\160\160A@@@\176)of_string\144\160\160A@@@\176)to_string\144\160\160A@@@\176)uppercase\144\160\160A@@@\176*capitalize\144\160\160A@@@\176*index_from\144\160\160C@@@\176*rindex_opt\144\160\160B@@@\176*sub_string\144\160\160C@@@\176+blit_string\144\160\160E@@@\176+rindex_from\144\160\160C@@@\176,uncapitalize\144\160\160A@@@\176-contains_from\144\160\160C@@@\176.index_from_opt\144\160\160C@@@\176.rcontains_from\144\160\160C@@@\176/lowercase_ascii\144\160\160A@@@\176/rindex_from_opt\144\160\160C@@@\176/uppercase_ascii\144\160\160A@@@\1760capitalize_ascii\144\160\160A@@@\1760unsafe_of_string\144\160\160A@@\144\180A\160\176\001\005\195\004\182@@\151\176A\160\144\004\005@\176\192\004\173b\001\007\171\001\007\171\192\004\174b\001\007\171\001\007\235@\1760unsafe_to_string\144\160\160A@@\144\180A\160\176\001\005\196\004\198@@\151\176@\160\144\004\005@\176\192\004\189a\001\007j\001\007j\192\004\190a\001\007j\001\007\170@\1762uncapitalize_ascii\144\160\160A@@@A",
164164
(* Int32 *)"\132\149\166\190\000\000\001\234\000\000\000\135\000\000\001\177\000\000\001\160\160\b\000\000 \000\176#abs\144\160\160A@@@\176$pred\144\160\160A@@\144\180A\160\176\001\004\002!n@@\151\176\b\000\000\004\019A\160\144\004\007\160\146\149\018_i\000\000\000\000\001@\176\1923stdlib-406/int32.mlq\001\t\151\001\t\164\192\004\002q\001\t\151\001\t\172@\176$succ\144\160\160A@@\144\180A\160\176\001\004\000!n@@\151\176\b\000\000\004\018A\160\144\004\007\160\146\149\018_i\000\000\000\000\001@\176\192\004\023p\001\t\129\001\t\142\192\004\024p\001\t\129\001\t\150@\176%equal\144\160\160B@@@\176&lognot\144\160\160A@@\144\180A\160\176\001\004\b!n@@\151\176\b\000\000\004\025A\160\144\004\007\160\146\149\018_i\000\255\255\255\255@\176\192\0042u\001\n\n\001\n\025\192\0043u\001\n\n\001\n'@\176'compare\144\160\160B@@\144\180B\160\176\001\004\017!x@\160\176\001\004\018!y@@\151\176\149\1762caml_int32_compareB:caml_int32_compare_unboxed\160\144\004\r\160\144\004\012@\176\192\004L\000C\001\011[\001\011w\192\004M\000C\001\011[\001\011\141@\176)to_string\144\160\160A@@\144\180A\160\176\001\004\011!n@@\151\176\149\1761caml_int32_formatB \160\146\146\"%d\160\144\004\014@\176\192\004ex\001\nk\001\n}\192\004fx\001\nk\001\n\138@\176-of_string_opt\144\160\160A@@@A",
165-
(* Int64 *)"\132\149\166\190\000\000\001\246\000\000\000\135\000\000\001\180\000\000\001\160\160\b\000\000 \000\176#abs\144\160\160A@@@\176$pred\144\160\160A@@\144\180A\160\176\001\004\004!n@@\151\176\b\000\000\004\019B\160\144\004\007\160\146\150\018_j\000\000\000\000\000\000\000\000\001@\176\1923stdlib-406/int64.mlo\001\t\131\001\t\144\192\004\002o\001\t\131\001\t\152@\176$succ\144\160\160A@@\144\180A\160\176\001\004\002!n@@\151\176\b\000\000\004\018B\160\144\004\007\160\146\150\018_j\000\000\000\000\000\000\000\000\001@\176\192\004\023n\001\tm\001\tz\192\004\024n\001\tm\001\t\130@\176%equal\144\160\160B@@@\176&lognot\144\160\160A@@\144\180A\160\176\001\004\n!n@@\151\176\b\000\000\004\025B\160\144\004\007\160\146\150\018_j\000\255\255\255\255\255\255\255\255@\176\192\0042s\001\n\006\001\n\021\192\0043s\001\n\006\001\n#@\176'compare\144\160\160B@@\144\180B\160\176\001\004\021!x@\160\176\001\004\022!y@@\151\176\149\1762caml_int64_compareB:caml_int64_compare_unboxed\160\144\004\r\160\144\004\012@\176\192\004L\000J\001\012b\001\012~\192\004M\000J\001\012b\001\012\148@\176)to_string\144\160\160A@@\144\180A\160\176\001\004\r!n@@\151\176\149\1761caml_int64_formatB \160\146\146\"%d\160\144\004\014@\176\192\004ev\001\ng\001\ny\192\004fv\001\ng\001\n\134@\176-of_string_opt\144\160\160A@@@A",
165+
(* Int64 *)"\132\149\166\190\000\000\001\246\000\000\000\128\000\000\001\169\000\000\001\146\160\b\000\000 \000\176#abs\144\160\160A@@@\176$pred\144\160\160A@@\144\180A\160\176\001\004\003!n@@\151\176\b\000\000\004\019B\160\144\004\007\160\146\150\018_j\000\000\000\000\000\000\000\000\001@\176\1923stdlib-406/int64.mlp\001\t\188\001\t\201\192\004\002p\001\t\188\001\t\209@\176$succ\144\160\160A@@\144\180A\160\176\001\004?$prim@@\151\176\149\176/caml_int64_succA \160\144\004\n@\176\192\004\022o\001\t\137\001\t\137\192\004\023o\001\t\137\001\t\187@\176%equal\144\160\160B@@@\176&lognot\144\160\160A@@\144\180A\160\176\001\004\t!n@@\151\176\b\000\000\004\025B\160\144\004\007\160\146\150\018_j\000\255\255\255\255\255\255\255\255@\176\192\0041t\001\n?\001\nN\192\0042t\001\n?\001\n\\@\176'compare\144\160\160B@@\144\180B\160\176\001\004\019!x@\160\176\001\004\020!y@@\151\176\149\1762caml_int64_compareB:caml_int64_compare_unboxed\160\144\004\r\160\144\004\012@\176\192\004K\000K\001\012\185\001\012\213\192\004L\000K\001\012\185\001\012\235@\176)to_string\144\160\160A@@\144\180A\160\176\001\004>\004J@@\151\176\149\1764caml_int64_to_stringA\004I\160\144\004\b@\176\192\004^w\001\n\160\001\n\160\192\004_w\001\n\160\001\n\221@\176-of_string_opt\144\160\160A@@@A",
166166
(* Js_re *)"\132\149\166\190\000\000\000\003\000\000\000\001\000\000\000\003\000\000\000\003\160\128A",
167167
(* Queue *)"\132\149\166\190\000\000\001\162\000\000\000\134\000\000\001\170\000\000\001\153\160\b\000\0008\000\176#add\144\160\160B@@@\176#pop\144\160\160A@@@\176#top\144\160\160A@@@\176$copy\144\160\160A@@@\176$fold\144\160\160C@@@\176$iter\144\160\160B@@@\176$peek\144\004\020@\176$push\144\004!@\176$take\144\004\031@\176%clear\144\160\160A@@@\176&create\144\160\160A@@\144\180A\160\176\001\003\246%param@@\151\176\177@\146\176&length%first$lastA\160\146\144@\160\146\168@\160#Nil\160AA\160\146\168@\160\004\006\160AA@\176\1923stdlib-406/queue.ml]\001\005:\001\005J\192\004\002a\001\005v\001\005w@\176&length\144\160\160A@@\144\180A\160\176\001\004\022!q@@\151\176\162@\160\004#A\160\144\004\b@\176\192\004\020\000b\001\t\215\001\t\217\192\004\021\000b\001\t\215\001\t\225@\176(is_empty\144\160\160A@@\144\180A\160\176\001\004\020!q@@\151\176\152@\160\151\176\162@\160\004:A\160\144\004\012@\176\192\004+\000_\001\t\184\001\t\186\192\004,\000_\001\t\184\001\t\194@\160\146\144@@\176\004\006\192\0041\000_\001\t\184\001\t\198@\176(transfer\144\160\160B@@@A",
168168
(* Scanf *)"\132\149\166\190\000\000\001\014\000\000\000O\000\000\001\011\000\000\000\252\160\b\000\0000\000\176%scanf\144\160\160A@@@\176&bscanf\144\160\160B@@@\176&fscanf\144\160\160B@@@\176&kscanf\144\160\160C@@@\176&sscanf\144\160\160B@@@\176'kfscanf\144\160\160C@@@\176'ksscanf\144\160\160C@@@\176(Scanning\145\b\000\0004\000@\160\160A@@\160\160A@@\160\160A@@\004\006\004\004\160\160A@@\160\160A@@\160\160A@@\160\160A@@\160\160A@@\160\160A@@@@\176)unescaped\144\160\160A@@@\176-bscanf_format\144\160\160C@@@\176-sscanf_format\144\160\160C@@@\1762format_from_string\144\160\160B@@@@",

jscomp/runtime/caml_format.ml

Lines changed: 91 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,93 @@ let caml_format_int fmt i =
374374
let f = parse_format fmt in
375375
aux f i
376376

377+
(* This can handle unsigned integer (-1L) and print it as "%Lu" which
378+
will overflow signed integer in general
379+
*)
380+
let dec_of_pos_int64 x =
381+
382+
383+
(if x < 0L then
384+
385+
let wbase = 10L in
386+
let cvtbl = "0123456789" in
387+
let y = Caml_int64.discard_sign x in
388+
(* 2 ^ 63 + y `div_mod` 10 *)
389+
390+
let quotient_l = 922337203685477580L (* 2 ^ 63 / 10 *)
391+
(* {lo = -858993460n; hi = 214748364n} *)
392+
(* TODO: int64 constant folding so that we can do idiomatic code
393+
2 ^ 63 / 10 *)in
394+
let modulus_l = 8L in
395+
(* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
396+
we can not do the code above, it can overflow when y is really large
397+
*)
398+
let c, d = Caml_int64.div_mod y wbase in
399+
let e ,f = Caml_int64.div_mod (Caml_int64_extern.add modulus_l d) wbase in
400+
let quotient =
401+
(Caml_int64_extern.add (Caml_int64_extern.add quotient_l c )
402+
e) in
403+
Caml_int64.to_string quotient ^
404+
(Caml_string_extern.get_string_unsafe
405+
cvtbl (Caml_int64_extern.to_int f))
406+
else
407+
Caml_int64.to_string x)
408+
409+
let oct_of_int64 x =
410+
let s = ref "" in
411+
let wbase = 8L in
412+
let cvtbl = "01234567" in
413+
(if x < 0L then
414+
begin
415+
let y = Caml_int64.discard_sign x in
416+
(* 2 ^ 63 + y `div_mod` 8 *)
417+
let quotient_l = 1152921504606846976L
418+
(* {lo = 0n; hi = 268435456n } *) (* 2 ^ 31 / 8 *)
419+
in
420+
421+
(* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
422+
we can not do the code above, it can overflow when y is really large
423+
*)
424+
let c, d = Caml_int64.div_mod y wbase in
425+
426+
let quotient =
427+
ref (Caml_int64_extern.add quotient_l c ) in
428+
let modulus = ref d in
429+
s .contents<-
430+
Caml_string_extern.get_string_unsafe
431+
cvtbl (Caml_int64_extern.to_int modulus.contents) ^ s.contents ;
432+
433+
while quotient.contents <> 0L do
434+
let a, b = Caml_int64.div_mod quotient.contents wbase in
435+
quotient .contents<- a;
436+
modulus .contents<- b;
437+
s .contents<- Caml_string_extern.get_string_unsafe cvtbl (Caml_int64_extern.to_int modulus.contents) ^ s.contents ;
438+
done;
439+
end
440+
else
441+
let a, b = Caml_int64.div_mod x wbase in
442+
let quotient = ref a in
443+
let modulus = ref b in
444+
s .contents<-
445+
Caml_string_extern.get_string_unsafe
446+
cvtbl (Caml_int64_extern.to_int modulus.contents) ^ s.contents ;
447+
448+
while quotient.contents <> 0L do
449+
let a, b = Caml_int64.div_mod (quotient.contents) wbase in
450+
quotient .contents<- a;
451+
modulus .contents<- b;
452+
s .contents<- Caml_string_extern.get_string_unsafe cvtbl (Caml_int64_extern.to_int modulus.contents) ^ s.contents ;
453+
done); s.contents
454+
455+
377456
(* FIXME: improve codegen for such cases
378457
let div_mod (x : int64) (y : int64) : int64 * int64 =
379458
let a, b = Caml_int64.(div_mod (unsafe_of_int64 x) (unsafe_of_int64 y)) in
380459
Caml_int64.unsafe_to_int64 a , Caml_int64.unsafe_to_int64 b
381460
*)
382461
let caml_int64_format fmt x =
383-
let module String = Caml_string_extern in
462+
if fmt = "%d" then Caml_int64.to_string x
463+
else
384464
let f = parse_format fmt in
385465
let x =
386466
if f.signedconv && x < 0L then
@@ -389,114 +469,26 @@ let caml_int64_format fmt x =
389469
Caml_int64_extern.neg x
390470
end
391471
else x in
392-
let s = ref "" in
472+
let s =
393473

394474
begin match f.base with
395475
| Hex ->
396-
s .contents<- Caml_int64.to_hex x ^ s.contents
476+
Caml_int64.to_hex x
397477
| Oct ->
398-
let wbase = 8L in
399-
let cvtbl = "01234567" in
400-
401-
if x < 0L then
402-
begin
403-
let y = Caml_int64.discard_sign x in
404-
(* 2 ^ 63 + y `div_mod` 8 *)
405-
let quotient_l = 1152921504606846976L
406-
(* {lo = 0n; hi = 268435456n } *) (* 2 ^ 31 / 8 *)
407-
in
408-
409-
(* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
410-
we can not do the code above, it can overflow when y is really large
411-
*)
412-
let c, d = Caml_int64.div_mod y wbase in
413-
414-
let quotient =
415-
ref (Caml_int64_extern.add quotient_l c ) in
416-
let modulus = ref d in
417-
s .contents<-
418-
Caml_string_extern.of_char
419-
cvtbl.[ Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
420-
421-
while quotient.contents <> 0L do
422-
let a, b = Caml_int64.div_mod quotient.contents wbase in
423-
quotient .contents<- a;
424-
modulus .contents<- b;
425-
s .contents<- Caml_string_extern.of_char cvtbl.[Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
426-
done;
427-
end
428-
else
429-
let a, b = Caml_int64.div_mod x wbase in
430-
let quotient = ref a in
431-
let modulus = ref b in
432-
s .contents<-
433-
Caml_string_extern.of_char
434-
cvtbl.[ Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
435-
436-
while quotient.contents <> 0L do
437-
let a, b = Caml_int64.div_mod (quotient.contents) wbase in
438-
quotient .contents<- a;
439-
modulus .contents<- b;
440-
s .contents<- Caml_string_extern.of_char cvtbl.[Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
441-
done
442-
478+
oct_of_int64 x
443479
| Dec ->
444-
let wbase = 10L in
445-
let cvtbl = "0123456789" in
446-
447-
if x < 0L then
448-
let y = Caml_int64.discard_sign x in
449-
(* 2 ^ 63 + y `div_mod` 10 *)
450-
451-
let quotient_l = 922337203685477580L (* 2 ^ 63 / 10 *)
452-
(* {lo = -858993460n; hi = 214748364n} *)
453-
(* TODO: int64 constant folding so that we can do idiomatic code
454-
2 ^ 63 / 10 *)in
455-
let modulus_l = 8L in
456-
(* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
457-
we can not do the code above, it can overflow when y is really large
458-
*)
459-
let c, d = Caml_int64.div_mod y wbase in
460-
let e ,f = Caml_int64.div_mod (Caml_int64_extern.add modulus_l d) wbase in
461-
let quotient =
462-
ref (Caml_int64_extern.add (Caml_int64_extern.add quotient_l c )
463-
e) in
464-
let modulus = ref f in
465-
s .contents<-
466-
Caml_string_extern.of_char
467-
cvtbl.[Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
468-
469-
while quotient.contents <> 0L do
470-
let a, b = Caml_int64.div_mod (quotient.contents) wbase in
471-
quotient .contents<- a;
472-
modulus .contents<- b;
473-
s .contents<- Caml_string_extern.of_char cvtbl.[Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
474-
done;
475-
476-
else
477-
let a, b = Caml_int64.div_mod x wbase in
478-
let quotient = ref a in
479-
let modulus = ref b in
480-
s .contents<-
481-
Caml_string_extern.of_char
482-
cvtbl.[ Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
483-
484-
while quotient.contents <> 0L do
485-
let a, b = Caml_int64.div_mod (quotient.contents) wbase in
486-
quotient .contents<- a;
487-
modulus .contents<- b;
488-
s .contents<- Caml_string_extern.of_char cvtbl.[Caml_int64_extern.to_int modulus.contents] ^ s.contents ;
489-
done;
490-
end;
480+
dec_of_pos_int64 x
481+
end in
482+
let fill_s =
491483
if f.prec >= 0 then
492484
begin
493485
f.filter <- " ";
494-
let n = f.prec -Caml_string_extern.length s.contents in
486+
let n = f.prec -Caml_string_extern.length s in
495487
if n > 0 then
496-
s .contents<- repeat n "0" ^ s.contents
497-
end;
488+
repeat n "0" ^ s else s
489+
end else s in
498490

499-
finish_formatting f s.contents
491+
finish_formatting f fill_s
500492

501493
let caml_format_float fmt x =
502494
let module String = Caml_string_extern in

0 commit comments

Comments
 (0)