Caml1999I037„•¦¾Žjd #Tmc ° 'rewritehÐÀÁ@ÀªÀ³¡’&Lambda&lambda@@õá@û@õá@üÀ³¡&lambda@@õá@ý@õá@þ@°À.lambda/tmc.mliQ [ [ÀQ [ y@@±B@@@„•¦¾H×  #Tmc0L*ÊÒmÔV‚9y¢DïNë  (Warnings0¹‘¡ûÓÉÎþEëf¹{²&Š  )Unit_info0'Á¸›T•ø ¶Î§@aÂR  %Types0€"˜Í|VÈ·`ØX ù  .Type_immediacy00$ôÍ jÌbv\"õkö&  %Subst0—’í=aëqT£/!p+  -Stdlib__Uchar0þ´=‹ÌH^®V9‚˜>ÌÉ  +Stdlib__Sys0öb÷'8ï=OðþIn  .Stdlib__String0 w_‡OA4D"Q~¾õ~  +Stdlib__Set0ø¯Ü”@Z8XäWåaŽa2  +Stdlib__Seq0 ?¯…¨72#š£[O  .Stdlib__Result0pŽ~ !Ô¥Â/”/²‚ö  +Stdlib__Map0*4ɇÂ2ù  .Stdlib__Domain0'Í¿‚Žo\¦0m’š¬.K  .Stdlib__Digest0#z25§ÆªÂ¶I*…  .Stdlib__Buffer0,å¦I÷ú[?¹Ä÷—z  &Stdlib0t0µVoS%{<‰F¡:  %Shape0• À³M„´Î``ll§  )Primitive0õÛdU˜=úÑ\IÆ/ø}  $Path0¸Ðk.tåb ûÃGêmá  )Parsetree0v Ýo[p÷…¯îÓY Y  +Outcometree0B³u©Gê^)=¾ú 9c  $Misc0KÁvor#å2D¾žÚÁ  )Longident0ØwP qÍ;°œ±É¡  (Location0–ÈnBÉŠÄOn?§ö7~Ø  )Load_path0Å,jÚ ¡ö" ¡–nn7Ý  &Lambda0®xÏ_eódT Õ-uq  ,Identifiable0ä]¡/­§*N »Ì ‡  %Ident0>®Ðƒ²Ðz€V)±j¢â  *Format_doc0¯æuy@½…GmWðUà  #Env02ÑO< r7—ß ï  )Debuginfo0_‹·Œí |Po†oÓGq  *Data_types0v\ò«É3Ï,¦S€ví¿hø  *Cmi_format0{)ݬ[…îÆ¥ ¶¸   0CamlinternalLazy0é ÈzYØ#¾â #4²ñ#-  8CamlinternalFormatBasics0“…Ä|.e1R¾$½ŠÕ|o  5Build_path_prefix_map0ÁÑä÷z•d,J4òz  (Asttypes0ÁeT$B¹b‚RMü Ädc@„•¦¾ @@Caml1999T037„•¦¾)Wœv¨C#Tmc’° °ž° *ocaml.text°À&_none_@@ÿA   À‘ ² w Tail-modulo-cons optimization. {b Warning:} this module is unstable and part of {{!Compiler_libs}compiler-libs}. °À.lambda/tmc.mliRÔÔÀVNP@@@@@@3 @@ @@@§²²²²²²²²²²²²²±±±±±±±±±±±±±±±±±±±±±@£#intA;@@“#intA@@@@@;@A@’£$charB;@@“$charA@@@@@A@A@’£&stringQ;@@“&stringA@@@@@G@@@’£%bytesC;@@“%bytesA@@@@@M@@@’£%floatD;@@“%floatA@@@@@S@@@’£$boolE;@@¢ à£%falsec@@]@’ à£$trued@@c@’@@A@@@@@d@A@’£$unitF;@@¢ à£"()e@@n@’@@A@@@@@o@A@’ £#exnG;@@@A@@@@@s@@@’£#effH; À@õá@O@A@A@ @ @@@@|@@@’£,continuationI; À@õá@Q À@õá@P@B“,continuationA@ n Y@ @ @@@@Œ@@@’£%arrayJ; À@õá@R@A“%arrayA@ @ @@@@—@@@’ £$listK; À@õá@S@A¢ à£"[]f@@¤@’ à£"::g  À³ @@õá@T@@±@’ @@A@ Y@ @@@@´@@@’£&optionL; À@õá@V@A¢ à£$Noneh@@Á@’ à£$Somei @@È@’@@A@ Y@ @@@@Ë@@@’£)nativeintM;@@“)nativeintA@@@@@Ñ@@@’£%int32N;@@“%int32A@@@@@×@@@’£%int64O;@@“%int64A@@@@@Ý@@@’£&lazy_tP; À@õá@X@A“&lazy_tA@ Y@ @@@@è@@@’ £5extension_constructorR;@@“5extension_constructorA@@@@@î@@@’£*floatarrayS;@@“*floatarrayA@@@@@ô@@@’£&iarrayT; À@õá@Y@A“&iarrayA@ Y@ @@@@ÿ@@@’ £*atomic_locU; À@õá@Z@A“*atomic_locA@ @ @@@@ @@@’ £.Assert_failure`#Ÿ@ À’  @À³Ö@@õá@J  @À³è@@õá@@  @@õá@[@@A! ° =ocaml.warn_on_literal_pattern%@&@’£0Division_by_zero]#@@@A+ °  . .@’£+End_of_file\#$@@@A3 ° 66@’£'FailureY#,@ '@@A< ° ??@’£0Invalid_argumentX#5@ 0@@AE ° $H#H@’£-Match_failureV#>@ À’  @=  @9  @;@õá@a@@AV ° 5Y4Y@’£)Not_foundZ#O@@@A^ ° =a<a@’£-Out_of_memoryW#W@@@Af ° EiDi@’£.Stack_overflow^#_@@@An ° MqLq@’£.Sys_blocked_io_#g@@@Av ° UyTy@’£)Sys_error[#o@ j@@A ° ^‚]‚@’£:Undefined_recursive_modulea#x@ À’  @w  @s  @u@õá@h@@A ° o“n“@’£:Continuation_already_takenb#‰@@@A˜ ° w›v›@’’&Stdlib@A“ °ž° ¥¤   À‘ ² õ TMC (Tail Modulo Cons) is a code transformation that rewrites transformed functions in destination-passing-style, in such a way that certain calls that were not in tail position in the original program become tail-calls in the transformed program. As a classic example, the following program {| let[@tail_mod_cons] rec map f = function | [] -> [] | x :: xs -> let y = f x in y :: map f xs |} becomes (expressed in almost-source-form; the translation is in fact at the Lambda-level) {| let rec map f = function | [] -> [] | x :: xs -> let y = f x in let dst = y :: Placeholder in map_dps dst 1 f xs; dst and map_dps dst offset f = function | [] -> dst.offset <- [] | x :: xs -> let y = f x in let dst' = y :: Placeholder in dst.offset <- dst'; map_dps dst 1 f fx |} In this example, the expression (y :: map f xs) had a call in non-tail-position, and it gets rewritten into tail-calls. TMC handles all such cases where the continuation of the call (what needs to be done after the return) is a "construction", the creation of a (possibly nested) data block. The code transformation generates two versions of the input function, the "direct" version with the same type and behavior as the original one (here just [map]), and the "destination-passing-style" version (here [map_dps]). Any call to the original function from outside the let..rec declaration gets transformed into a call into the direct version, which will itself call the destination-passing-style versions on recursive calls that may benefit from it (they are in tail-position modulo constructors). Because of this inherent code duplication, the transformation may not always improve performance. In this implementation, TMC is opt-in, we only transform functions that the user has annotated with an attribute to request the transformation. °À¡XRRÀ¢M J L@@@@@@  °šà ’&Lambda &Lambda°À¯O N SÀ°O N Y@@A3®­­®®®®®@§­ @A°À´O N N@@²°@ °ð 'rewriteg °À¾Q [ _À¿Q [ f@б@г¡&lambda °ÀÉQ [ iÀÊQ [ o@@À³ @@õá@ V°@@г¡*&lambda °ÀÖQ [ sÀ×Q [ y@@À³ @@õá@ W*°@@ÀÁ@Àª@õá@ X@õá@ Y/° @@Ð@°ÀãQ [ [ @@±ûB@@°@@5@ °.@@3åääååååå@°80 @A@   H************************************************************************°ÀîA@@ÀïA@L@   H °ÀôBMMÀõBM™@   H OCaml °ÀúCššÀûCšæ@   H °ÀDççÀDç3@   J Frédéric Bour °ÀE44ÀE4‚@   H Gabriel Scherer, projet Partout, INRIA Saclay °À FƒƒÀ FƒÏ@   I Basile Clément, projet Cambium, INRIA Paris °ÀGÐÐÀGÐ@   H °ÀHÀHj@   H Copyright 2020 Institut National de Recherche en Informatique et °ÀIkkÀIk·@   H en Automatique. °À$J¸¸À%J¸@   H °À*KÀ+KQ@   H All rights reserved. This file is distributed under the terms of °À0LRRÀ1LRž@   H the GNU Lesser General Public License version 2.1, with the °À6MŸŸÀ7MŸë@   H special exception on linking described in the file LICENSE. °À [] | x :: xs -> let y = f x in y :: map f xs |} becomes (expressed in almost-source-form; the translation is in fact at the Lambda-level) {| let rec map f = function | [] -> [] | x :: xs -> let y = f x in let dst = y :: Placeholder in map_dps dst 1 f xs; dst and map_dps dst offset f = function | [] -> dst.offset <- [] | x :: xs -> let y = f x in let dst' = y :: Placeholder in dst.offset <- dst'; map_dps dst 1 f fx |} In this example, the expression (y :: map f xs) had a call in non-tail-position, and it gets rewritten into tail-calls. TMC handles all such cases where the continuation of the call (what needs to be done after the return) is a "construction", the creation of a (possibly nested) data block. The code transformation generates two versions of the input function, the "direct" version with the same type and behavior as the original one (here just [map]), and the "destination-passing-style" version (here [map_dps]). Any call to the original function from outside the let..rec declaration gets transformed into a call into the direct version, which will itself call the destination-passing-style versions on recursive calls that may benefit from it (they are in tail-position modulo constructors). Because of this inherent code duplication, the transformation may not always improve performance. In this implementation, TMC is opt-in, we only transform functions that the user has annotated with an attribute to request the transformation. °@ó-./boot/ocamlc)-nostdlib"-I&./boot*-use-prims2runtime/primitives"-g0-strict-sequence*-principal(-absname"-w8+a-4-9-40-41-42-44-45-48+-warn-error"+a*-bin-annot/-strict-formats"-I&lambda"-I%utils"-I'parsing"-I&typing"-I(bytecomp"-I,file_formats"-I&lambda"-I*middle_end"-I2middle_end/closure"-I2middle_end/flambda"-I=middle_end/flambda/base_types"-I'asmcomp"-I&driver"-I(toplevel"-I%tools"-I'runtime"-I1otherlibs/dynlink"-I-otherlibs/str"-I4otherlibs/systhreads"-I.otherlibs/unix"-I8otherlibs/runtime_events"-c‹Œ S/home/teraram/ci/builds/workspace/parallel-build/flambda/true/label/ocaml-manycores    > 1 0 / . - , + * ) ( ' & % $ # " !     @@0ZRg«Lf…åžÐðÿC˜*3¦¥¥¦¦¦¦¦@¤@@  (Asttypes0ÁeT$B¹b‚RMü Ädc  5Build_path_prefix_map0ÁÑä÷z•d,J4òz  8CamlinternalFormatBasics0“…Ä|.e1R¾$½ŠÕ|o  0CamlinternalLazy0é ÈzYØ#¾â #4²ñ#-  *Cmi_format0{)ݬ[…îÆ¥ ¶¸   *Data_types0v\ò«É3Ï,¦S€ví¿hø  )Debuginfo0_‹·Œí |Po†oÓGq  #Env02ÑO< r7—ß ï  *Format_doc0¯æuy@½…GmWðUà  %Ident0>®Ðƒ²Ðz€V)±j¢â  ,Identifiable0ä]¡/­§*N »Ì ‡  60®xÏ_eódT Õ-uq  )Load_path0Å,jÚ ¡ö" ¡–nn7Ý  (Location0–ÈnBÉŠÄOn?§ö7~Ø  )Longident0ØwP qÍ;°œ±É¡  $Misc0KÁvor#å2D¾žÚÁ  +Outcometree0B³u©Gê^)=¾ú 9c  )Parsetree0v Ýo[p÷…¯îÓY Y  $Path0¸Ðk.tåb ûÃGêmá  )Primitive0õÛdU˜=úÑ\IÆ/ø}  %Shape0• À³M„´Î``ll§  &Stdlib0t0µVoS%{<‰F¡:  .Stdlib__Buffer0,å¦I÷ú[?¹Ä÷—z  .Stdlib__Digest0#z25§ÆªÂ¶I*…  .Stdlib__Domain0'Í¿‚Žo\¦0m’š¬.K  .Stdlib__Either0ÿH­D¥ë ˆ’Š?|é>  .Stdlib__Format00¿ƒFËÔñCÃlòWÇ  /Stdlib__Hashtbl0²š±§(L%èŠbØøÕÔ  ,Stdlib__Lazy0ô$¸Àøå©ä1ùmlà  .Stdlib__Lexing0^Êmñ|©•Þð·e–¯´  +Stdlib__Map0*4ɇÂ2ùÌÉ  %Subst0—’í=aëqT£/!p+  0L*ÊÒmÔV‚9y¢DïNë  .Type_immediacy00$ôÍ jÌbv\"õkö&  %Types0€"˜Í|VÈ·`ØX ù  )Unit_info0'Á¸›T•ø ¶Î§@aÂR  (Warnings0¹‘¡ûÓÉÎþEëf¹{²&Š@0L*ÊÒmÔV‚9y¢DïNëAÀAC@@@° Ì@@@@@@@@@@@@@@P@@