Caml1999I037jd#Tmc'rewritei@&Lambda&lambda@@@@@&lambda@@@@@@.lambda/tmc.mliQ [ [Q [ y@@B@@@H#Tmc0QR)ؓ(Warnings0ۮUrԽLMǠ)Unit_info0UB(+x)}x֠%Types0(m4S%Qd.Type_immediacy0v :g+%Subst0.p#T𒠠-Stdlib__Uchar0No>q՗c7X/>+Stdlib__Sys0 K*q\VtV+˨.Stdlib__String0!X.}Vw+D#H=4+Stdlib__Set0jʺz?i+Stdlib__Seq04+{*.Stdlib__Result0MuW86hǠ+Stdlib__Map0V_xw.Stdlib__Lexing0$Gz|HQՠ,Stdlib__Lazy0`9'3cQrڄX/Stdlib__Hashtbl0hItBTٓ}let.Stdlib__Format0䦗. zw.Stdlib__Either0Kco-.D٠.Stdlib__Domain0_+I\bsz)>.Stdlib__Digest0b{{5s5.Stdlib__Buffer0IT0+袧7&Stdlib0GI,&+< %Shape0%>+/2}RS3V)Primitive0HCګ'Ơ$Path0B5YAn0w)Parsetree0o\V]Wggr+Outcometree0 ֩[=$Misc0Ÿ˖ɦnƹV !)Longident0o\-Is?)̚ (Location04 RS1Df(0)Load_path0V^3J@Y qSC9&Lambda0VD2Sk{;Nl,Identifiable0Hɸ b]1%Ident00g&Bx+*Format_doc0;TD&K^_Z#Env0'(Sl-L>56j)Debuginfo0#Ļy`DAV*Data_types0{dE)`cR*Cmi_format0^퀭ˏEF$0CamlinternalLazy0r{{ yO8CamlinternalFormatBasics0& g.r5Build_path_prefix_map0K*DV.Q(Asttypes0ʼnmX֛@-@@@Caml1999T037)XwC#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.mliRVNP@@@@@@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@nY@@@@@@@@@%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\#$@@@A366@'FailureY#,@'@@A<??@0Invalid_argumentX#5@0@@AE$H#H@-Match_failureV#>@@=@9@;@@a@@AV5Y4Y@)Not_foundZ#O@@@A^=a<a@-Out_of_memoryW#W@@@AfEiDi@.Stack_overflow^#_@@@AnMqLq@.Sys_blocked_io_#g@@@AvUyTy@)Sys_error[#o@j@@A^]@:Undefined_recursive_modulea#x@@w@s@u@@h@@Aon@:Continuation_already_takenb#@@@Awv@&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. XRRM J L@@@@@@ࠐ&Lambda&LambdaO N SO N Y@@A3@ @AO N N@@@'rewritehQ [ _Q [ f@б@г&lambdaQ [ iQ [ o@@ @@@ h@@г*&lambdaQ [ sQ [ y@@ @@@ i*@@@@@ j@@ k/ @@@Q [ [ @@B@@@@5@.@@3@80 @A@ H************************************************************************A@@A@L@ H BMMBM@ H OCaml CC@ H DD3@ J Frédéric Bour E44E4@ H Gabriel Scherer, projet Partout, INRIA Saclay  F F@ I Basile Clément, projet Cambium, INRIA Paris GG@ H HHj@ H Copyright 2020 Institut National de Recherche en Informatique et IkkIk@ H en Automatique. $J%J@ H *K+KQ@ H All rights reserved. This file is distributed under the terms of 0LRR1LR@ H the GNU Lesser General Public License version 2.1, with the 6M7M@ 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 T/home/teraram/ci/builds/workspace/parallel-build/flambda/false/label/ocaml-manycores >10/.-,+*)('&%$#"! @@0x~Gy "s3@@@(Asttypes0ʼnmX֛@-5Build_path_prefix_map0K*DV.Q8CamlinternalFormatBasics0& g.r0CamlinternalLazy0r{{ yO*Cmi_format0^퀭ˏEF$*Data_types0{dE)`cR)Debuginfo0#Ļy`DAV#Env0'(Sl-L>56j*Format_doc0;TD&K^_Z%Ident00g&Bx+,Identifiable0Hɸ b]160VD2Sk{;Nl)Load_path0V^3J@Y qSC9(Location04 RS1Df(0)Longident0o\-Is?)̚ $Misc0Ÿ˖ɦnƹV !+Outcometree0 ֩[=)Parsetree0o\V]Wggr$Path0B5YAn0w)Primitive0HCګ'Ơ%Shape0%>+/2}RS3V&Stdlib0GI,&+< .Stdlib__Buffer0IT0+袧7.Stdlib__Digest0b{{5s5.Stdlib__Domain0_+I\bsz)>.Stdlib__Either0Kco-.D٠.Stdlib__Format0䦗. zw/Stdlib__Hashtbl0hItBTٓ}let,Stdlib__Lazy0`9'3cQrڄX.Stdlib__Lexing0$Gz|HQՠ+Stdlib__Map0V_xw.Stdlib__Result0MuW86hǠ+Stdlib__Seq04+{*+Stdlib__Set0jʺz?i.Stdlib__String0!X.}Vw+D#H=4+Stdlib__Sys0 K*q\VtV+˨-Stdlib__Uchar0No>q՗c7X/>%Subst0.p#T𒠠0QR)ؓ.Type_immediacy0v :g+%Types0(m4S%Qd)Unit_info0UB(+x)}x֠(Warnings0ۮUrԽLM@0QR)ؓAAC@@@@@@@@@@@@@@@@@P@@