Caml1999I037O*N86&3Simple_value_approx)boxed_intU;!a@@A%Int32@%int32N@@@@@@ *middle_end/flambda/simple_value_approx.mliXX@@"A@%Int64@%int64O@@@@@@YY@@6B@)Nativeint@*)nativeintM@@@@@@)Z*Z@@JC@@@A@@@@@@/Wxx@@A@O@@A@,value_stringV;@@(contents@@&optionL&stringQ@@@@@@I]J]@@jE@$size@@#intA@@@W^?AX^?L@@xF@@@A@@@@@[\\_MN@@@@|D@A@0unresolved_valueW;@@2Set_of_closures_id2Set_of_closures_id!t@@@@@sbhjtbh@@H@&Symbol(&Symbol!t@@@@@cc@@I@@@A@@@@@aPP@@@@G@A@2unknown_because_ofX;@@0Unresolved_value;:@@@@@ff@@K@%Other<@@gg@@L@@@A@@@@@e@@@@J@A@!tY;@@%descrF@@%descrZ@@@"vv@@V@#var_@@(Variable!t@@@ @@@!ww@@W@&symbol`@@@d!t@@@@@@@@@@@@@@@xx@@X@@@@@@@@@unny@@@@M@A@D;@@+Value_blocka#Tag!t@@@4%arrayJi@@@2@@@3@@||@@:Y@)Value_intp@@@1@@'}(}&@@HZ@*Value_charq$charB@@@0@@7~')8~'=@@X[@+Value_floatr%floatD@@@.@@@/@@L>@M>]@@m\@/Value_boxed_intsa!a@+@@@,@@@@-c^`d^@@]@5Value_set_of_closurest5value_set_of_closures_@@@*@@st@@^@-Value_closureu-value_closure[@@@)@@@@_@,Value_stringv\@@@(@@@@`@1Value_float_arrayw1value_float_arraya@@@'@@0@@a@-Value_unknownx @@@&@@131X@@b@,Value_bottomy@@Y[Yi@@c@,Value_externz)Export_id!t@@@%@@jlj@@d@,Value_symbolW!t@@@$@@@@e@0Value_unresolvedL@@@#@@@@f@@@@@@@@@{@@@@ N@B@p;@@/set_of_closures@@@@@6/@@g@*closure_id@@*Closure_id!t@@@5 02 0L@@*h@@@A@@@@@ MN@@@@.O@B@5function_declarations\;@@/is_classic_mode@@$boolE@@@;!vx"v@@Bi@2set_of_closures_id@@!t@@@:/0@@Pj@6set_of_closures_origin@@6Set_of_closures_origin!t@@@9?@@@`k@$funs@@#Map!t4function_declaration^@@@7@@@8VW@@wl@@@@@@@@@ZPP[ @@@@{P@B@-function_body];@@.free_variables@@#Set!t@@@Dp@Bq@b@@m@,free_symbolsI@@#Set!t@@@Ccec@@n@$stubJ@@m@@@B@@o@#dbgY@@)Debuginfo!t@@@A@@p@&inline@@&Lambda0inline_attribute@@@@@@s@*specialise@@4specialise_attribute@@@?@@t@,is_a_functor@@@@@> @@u@$body@@'Flambda!t@@@=   @@v@$poll@@:.poll_attribute@@@<!#!?@@w@@@@@@@@@""@A@@@@ Q@B@;@@.closure_origin@@.Closure_origin!t@@@Ihjh@@x@¶ms@@$listK)Parameter!t@@@G@@@H@@4y@-function_body@@ߠ@@@E@@@F$%@@Ez@@@@@@@@@(CC)@@@@IR@B@;@@.function_decls@@$@@@\89@@Y{@*bound_varsM@@2Var_within_closure#Map!t6@@@Z@@@[NO@@o|@)free_varsN@@#Map!t.specialised_to@@@X@@@Yef4@@}@0invariant_paramsX@@&Stdlib$Lazy!t#Map!t#Set!t@@@U@@@V@@@W575o@@~@)recursiveY@@$$Lazy!t#Set!t@@@S@@@Tprp@@@$sizeZ@@<$Lazy!t#Map!t|k@@@O@@@P@@@Q@@@R@@@@0specialised_args[@@#Map!t.specialised_to@@@M@@@N"$"]@@A@*fresheningx@@*Freshening+Project_var!t@@@L@@ B@6direct_call_surrogates@@#Map!t!t@@@J@@@K@@$C@@@@@@@@@@@@@(S@B@:value_float_array_contents`;@@(Contents @@@]@@@^@@') '>@@@D@2Unknown_or_mutable@@(?A)?U@@IE@@@A@@@@@,@@@@LT@B@;@@(contents@@-@@@`;qs<q@@\F@$size@@@@@_GH@@hG@@@A@@@@@KWWL@@@@lU@B@%descrb@B@@@a@@@b@@c@\]@@}H@@&descrsc@cW@@@d@@@ek@@@f@@@g@@h@wx@@I@@%printd@&Format)formatter@@@i@w@@@j$unitF@@@k@@l@@m@XXX@@J@@+print_descre@2&Format)formatter@@@n@@@@o@@@p@@q@@r@@@K@@;print_value_set_of_closuresf@M&Format)formatter@@@s@V@@@t8@@@u@@v@@w@  @@L@@;print_function_declarationsg@h&Format)formatter@@@x@@@@yS@@@z@@{@@|@   a j@@M@@(c(c?((@@_`@@.make_const_int{@@@@@!t@@@蠠@E@@@@@@@@\)M)M])M)v@@}a@@/make_const_char|@6@@@@!t@@@@c@@@@@@@@z)w)w{)w)@@b@@/make_const_bool}@j@@@@!t@@@@@@@@@@@@))))@@c@@0make_const_float~@^@@@@!t@@@@@@@@@@@@))))@@d@@4make_const_boxed_int@̠!i@@@@@@!t@@@@@@@@@@@@@@)))*;@@e@@4make_const_int_named@@@@@%named@@@@@@@@@@@@*=*=*=*p@@f@@5make_const_char_named@@@@@=%named@@@@@@@@@ @@ @*q*q*q*@@7g@@5make_const_bool_named@@@@ @[%named@@@ @@@@ @@@@@4 **5 **@@Uh@@6make_const_float_named@@@@@y%named@@@@;@@@@@@@@R!**S!*+@@si@@:make_const_boxed_int_named@h!i@@@@@@%named@@@@_@@@@@@@@@@v"++w"++]@@j@@5augment_with_variable@m@@@@!t@@@x@@@@@@@ @',4,4',4,d@@k@@3augment_with_symbol@@@@!@"!t@@@"@@@#@@$@@%@*,,*,,@@l@@9augment_with_symbol_field@@@@&@;!t@@@'@o@@@(@@@)@@*@@+@@,@------S@@m@@3replace_description@@@@-@!@@@.@@@/@@0@@1@0--0--@@n@@1augment_with_kind@@@@2@I*value_kind@@@3@@@4@@5@@6@3--3-.*@@ o@@8augment_kind_with_approx@@@@7@b*value_kind@@@8h*value_kind@@@9@@:@@;@ 6.k.k 6.k.@@ 3p@@/equal_boxed_int@ (!a@=@@@<@@ 4!b@?@@@>@@@@@@@A@@B@@C@@D@ 78.. 88..@@ Xq@@$meet4really_import_approx@2@@@E5@@@F@@G@:@@@H@?@@@IB@@@J@@K@@L@@M@ Y<// Z<//@@ zr@@%known@P@@@NL@@@O@@P@ k?00 l?00@@ s@@&useful@b@@@Q^@@@R@@S@ }B0h0h ~B0h0~@@ t@@.all_not_useful@x@@@T@@@Uu@@@V@@W@ E00 E00@@ u@@0warn_on_mutation@@@@X@@@Y@@Z@ J11 J11@@ v@@6simplification_summary;@@,Nothing_done@@ M11 M11@@ x@-Replaced_term@@ N11 N12@@ y@@@A@@@@@ L11@@A@ w@A@5simplification_result;@@@A@!t@@@]@/@@@\@@@@[@@^@@@@ P22 P22S@@@@ z@A@;simplification_result_named;@@@A@"%named@@@a@ @@@`@@@@_@@b@@@@ Q2T2T Q2T2@@@@ !{@A@(simplify@@@@c@B!t@@@dR@@@e@@f@@g@ V3p3p V3p3@@ ;|@@2simplify_using_env@ @@@h1is_present_in_env@ f!t@@@i@@@j@@k@l!t@@@l*@@@m@@n@@o@@p@ C\44 D`551@@ d}@@.simplify_named@ :@@@q@%named@@@ru@@@s@@t@@u@ ]b5353 ^b535y@@ ~~@@8simplify_named_using_env@ T@@@v1is_present_in_env@ !t@@@w\@@@x@@y@%named@@@z*@@@{@@|@@}@@~@ d5{5{ h55@@ @@=simplify_var_to_var_using_env@ }@@@1is_present_in_env@ !t@@@@@@@@ h !t@@@@@@@@@@@ m66 p77'@@ @@,simplify_var@ @@@ @%named@@@@ @@@@@@@@@@@ r7)7) r7)7[@@ @@0get_field_result;@@"Ok @@@@@ u7u7w u7u7@@ @+Unreachable@@ v77 v77@@ @@@A@@@@@ t7]7]@@@@ @A@)get_field@ @@@+field_index @@@2@@@@@@@@ ~99 ~99;@@ +@@8checked_approx_for_block;@@%Wrong@@ 9]9_ 9]9f@@ :@"Ok !t@@@  @@@@@@@@ 29g9i 39g9@@ S@@@A@@@@@ 69=9=@@@@ V@A@6check_approx_for_block@ ,@@@6@@@@@@ G99 H9:@@ h@@4approx_for_bound_var@ @@@@!t@@@ I@@@@@@@@ `:: a:;@@ @@@@ @"Ok  1!t@@@@@@ @@@@@ >> >>@@ %@@@A@@@@@ =u=u@@@@ (@A@ check_approx_for_set_of_closures@ @@@Y@@@@@@ ?? ??@@ :@@:checked_approx_for_closure;@@%Wrong@@ (?? )?@@@ I@"Ok @@@  r!t@@@@@@  !t@@@@@@ @@@@@ Q@@ R@0@c@@ r@@@A@@@@@ U??@@@@ u@A@8check_approx_for_closure@ K@@@F@@@@@@ fAA gAA@@ @@ .checked_approx_for_closure_allowing_unresolved;@@%Wrong@@ uBB vBB@@ @*Unresolved @@@@@ BB  BB@@@ @'Unknown@@ BABC BABL@@ @ #Unknown_because_of_unresolved_value @@@@@ BMBO BMB@@ @"Ok %@@@ j !t@@@@@@ v 9!t@@@@@@ Q@@@@@ BB BB@@ @@@A@@@@@ AA@@@@ @A@ ,check_approx_for_closure_allowing_unresolved@ @@@i@@@@@@ CxCx CC@@ @@6check_approx_for_float@ @@@  @@@@@@@@@ D)D) D)DW@@ @@7float_array_as_constant@ ]@@@   @@@@@@@@@@@@ DD DD@@ *@@7check_approx_for_string@ @@@ ۠ @@@@@@@@@ E.E. !E.E^@@ A@@7switch_branch_selection;@@/Cannot_be_taken@@ /EE 0EE@@ P@,Can_be_taken@@ 8EE 9EE@@ Y@-Must_be_taken@@ AEE BEE@@ b@@@A@@@@@ EE`E`@@A@ e@A@ %potentially_taken_const_switch_branch@ ;@@@@ @@@5@@@@@@@@ \EE ]EFH@@ }@@ %potentially_taken_block_switch_branch@ S@@@@ @@@@@@@@@@@ sFIFI tFIF@@ @@.function_arity@ /@@@ 0@@@@@@ FF FF@@ @@s-Stdlib__Uchar056uf4[_+Stdlib__Sys0 -ռ鱦s5/.Stdlib__String0Vê>)Longident0s `7mɕc(Location0a7cK_H%9)Load_path0I@18 ~,Linkage_name0EwKсڊs&Lambda0z1x]&ZT7Internal_variable_names0HdeՄL ԩ,Identifiable0 {d\FX'`%Ident0">WA+9*X*Freshening0/^*b1R*Format_doc0]mWϓ:Mݠ'Flambda0Idvu ")Export_id0-bw+LO#Env0zV L{YWI)Debuginfo0PtJ=^w/*Data_types0I'Ue`wq]Ѡ0Compilation_unit0 {p-Vg_*Cmi_format0c˯7͗ԩmݠ.Closure_origin0vˆtT{(}z*Closure_id05:z[ކ/Closure_element0YWZ̡Q.hV&2Clambda_primitives01U10CamlinternalLazy0&͂7 Pˆ8CamlinternalFormatBasics0%FU(Q/Tu5Build_path_prefix_map0z HkGs(Asttypes0>n{T8cئ/Allocated_const0ЖݔTW@@@Caml1999T037Yl0xƖC3Simple_value_approx-ocaml.warning *middle_end/flambda/simple_value_approx.mliQQ@2+a-4-9-30-40-41-42 QQ@@QQ@@@@@@QQ@3@@@@@@#intA;@@@A@@@@@&_none_@@A@A@$charB;@@A@@@@@@A@&stringQ;@@ A@@@@@ @@@%bytesC;@@A@@@@@@@@%floatD;@@A@@@@@@@@$boolE;@@%falsec@@@$trued@@#@@@A@@@@@$@A@$unitF;@@"()e@@.@@@A@@@@@/@A@ #exnG;@@@A@@@@@3@@@#effH;@@O@A@A@@@@@@<@@@,continuationI;@@Q@@P@B@A@nY@@@@@@K@@@%arrayJ;@@R@A@A@@@@@@U@@@ $listK;@@S@A"[]f@@b@"::g@@@T@@o@ @@A@Y@@@@@r@@@&optionL;@@V@A$Noneh@@@$Somei@@@@@A@Y@@@@@@@@)nativeintM;@@A@@@@@@@@%int32N;@@A@@@@@@@@%int64O;@@A@@@@@@@@&lazy_tP;@@X@AJA@Y@@@@@@@@5extension_constructorR;@@A@@@@@@@@*floatarrayS;@@A@@@@@@@@&iarrayT;@@Y@A[A@Y@@@@@@@@*atomic_locU;@@Z@AdA@@@@@@@@@.Assert_failure`#@@@@@J@@@@@@@@[@@AϠ=ocaml.warn_on_literal_patternӐ@@0Division_by_zero]#@@@A٠  @+End_of_file\#$@@@Aᠰ@'FailureY#,@'@@A꠰@0Invalid_argumentX#5@0@@A󠰠$#@-Match_failureV#>@@=@9@;@@a@@A54@)Not_foundZ#O@@@A =<@-Out_of_memoryW#W@@@AED@.Stack_overflow^#_@@@AML@.Sys_blocked_io_#g@@@A$U'T'@)Sys_error[#o@j@@A-^0]0@:Undefined_recursive_modulea#x@@w@s@u@@h@@A>oAnA@:Continuation_already_takenb#@@@AFwIvI@&Stdlib@Azy@*ocaml.textT Simple approximations to the runtime results of computations. This pass is designed for speed rather than accuracy; the performance is important since it is used heavily during inlining. SU9v@@@@@@A+)boxed_intAWxWx@А!a@3@;@@@A@A@G@B@@@WxxZ@@@@@@@AWx}Wx@@BA@;@A%Int32@+@@@@@@XX@@A@%Int64@>@@@@@@YY@@B@)Nativeint@Q0@@@@@@Z@@@ C@@@A@@@@@@E@A@B@#;;XX@/@@г=)boxed_intX9@гA%int32XX@@Ig@@@NhD@@F@#BB Y!Y@6@@гD)boxed_int*Y@@гH%int642Y3Y@@P@@@UK@@M@#II:Z;Z@>@@гK)boxed_intDZ@гO)nativeintLZMZ@@W@@@\@@T@@A@@@:@A+,value_stringBZ\[\@@;@@(contents@@!@@@@@@ٰl]m]@@yE@$size@@:@@@ܰx^?Ay^?L@@F@@@A@@@@@|\}_MN@@@@D@@#""] @@@Ш@г%&option]]@г*&string] ]@@23@E;@@@A@@@@@"@@@@A@@@< @@?@@ @6@#22-^?E@,@@Ш@г5#int^?H^?K@@=@@@@@@<@@A@8@@3@@A98@A+0unresolved_valueCaPUaPe@@;@@2Set_of_closures_id2Set_of_closures_id!t@@@3@@bhjbh@@H@&Symbol(&Symbol!t@@@@@cc@@I@@@A@@@@@aPP@@@@G@@#((bhlbh~@@г*2Set_of_closures_idbhbh@/bh-@.@@83@iI;@@@A@@@@@@@@@A 4@@@@6@#22 c c@'@г4&Symbolcc@9c7@8@@B9@@@@;@@A@7@@3@@A8;@A+2unknown_because_of:D(e)e@@;@@0Unresolved_value;{@@@@@7f8f@@DK@%Other<@@@gAg@@ML@@@A@@@@@De@@@@PJ@@#KfLf@@г0unresolved_valueUf@@$3@??@@@@@@W5;@@@A@@@@@@@@@A$@@@@&@#""`g @@@@#@@A@@@3LKKLLLLL@ @A #@A+!t=Emunsnunt@@;@@%descrF@@%descr>E@@@|v}v@@V@#var_@@Ӡ(Variable!t@@@g@@@iww@@W@&symbol`@@@!t@@@l@s@@@m@@@o@@p@@@rxx@@X@@@@@@@@@unny@)ocaml.doc} k A value of type [t] corresponds to an "approximation" of the result of a computation in the program being compiled. That is to say, it represents what knowledge we have about such a result at compile time. The simplification pass exploits this information to partially evaluate computations. At a high level, an approximation for a value [v] has three parts: - the "description" (for example, "the constant integer 42"); - an optional variable; - an optional symbol or symbol field. If the variable (resp. symbol) is present then that variable (resp. symbol) may be used to obtain the value [v]. The exact semantics of the variable and symbol fields follows. Approximations are deduced at particular points in an expression tree, but may subsequently be propagated to other locations. At the point at which an approximation is built for some value [v], we can construct a set of variables (call the set [S]) that are known to alias the same value [v]. Each member of [S] will have the same or a more precise [descr] field in its approximation relative to the approximation for [v]. (An increase in precision may currently be introduced for pattern matches.) If [S] is non-empty then it is guaranteed that there is a unique member of [S] that was declared in a scope further out ("earlier") than all other members of [S]. If such a member exists then it is recorded in the [var] field. Otherwise [var] is [None]. Analogous to the construction of the set [S], we can construct a set [T] consisting of all symbols that are known to alias the value whose approximation is being constructed. If [T] is non-empty then the [symbol] field is set to some member of [T]; it does not matter which one. (There is no notion of scope for symbols.) Note about mutable blocks: Mutable blocks are always represented by [Value_unknown] or [Value_bottom]. Any other approximation could leave the door open to a miscompilation. Such bad scenarios are most likely a user using [Obj.magic] or [Obj.set_field] in an inappropriate situation. Such a situation might be: [let x = (1, 1) in Obj.set_field (Obj.repr x) 0 (Obj.repr 2); assert(fst x = 2)] The user would probably expect the assertion to be true, but the compiler could in fact propagate the value of [x] across the [Obj.set_field]. Insisting that mutable blocks have [Value_unknown] or [Value_bottom] approximations certainly won't always prevent this kind of error, but should help catch many of them. It is possible that there may be some false positives, with correct but unreachable code causing this check to fail. However the likelihood of this seems sufficiently low, especially compared to the advantages gained by performing the check, that we include it. An example of a pattern that might trigger a false positive is: [type a = { a : int } type b = { mutable b : int } type _ t = | A : a t | B : b t let f (type x) (v:x t) (r:x) = match v with | A -> r.a | B -> r.b <- 2; 3 let v = let r = ref A in r := A; (* Some pattern that the compiler can't understand *) f !r { a = 1 }] When inlining [f], the B branch is unreachable, yet the compiler cannot prove it and must therefore keep it. itkm@@@@@@@@@M@@#ZZSv@R@@Ш@г]%descrvv@@e3@|;@@@@@@@@@1.@@o;@@@@@@@@@{@@@@N@-value_closure?E;@@@A@@@@@MN@@@@O@5function_declarations@E;@@@@@@@@@PP @@@@P@-function_bodyAE;@@@@@@@@@""@A@@@@Q@4function_declarationBE;@@@@@@@@@ CC @@@@R@5value_set_of_closuresCE;@@@@@@@@@@@@@S@:value_float_array_contentsDE;@@@A@@@@@?U@@@@'T@1value_float_arrayEE;@@@A@@@@@"WW#@@@@/U@@ANM@@@@N@@#,w@@@Ш@г&option5w6w@г(Variable@wAw@DwEw@@@m@@@n @@@@jq@@#Ox@@@Ш@г&optionXxYx@В@г&Symbolgxhx@ưkxlx@@@@@@гɠ&optionwxxx@гΠ#intxx@@@@@ @@@ @@@x.@@@@s@@@@@ӠL@@@@@@+{{@@;@@+Value_blocka#Tag!t@@@"I@@@@@@@@||@@Y@)Value_intp@@@@@}}&@@Z@*Value_charq@@@@@~')~'=@@[@+Value_floatr*@@@@@@@@>@>]@@\@/Value_boxed_intsK!a@F@@@@F@@@@@ð^`^@@]@5Value_set_of_closurest@@@@@@@^@-Value_closureu.@@@@@@@*_@,Value_stringv@@@@@+,@@8`@1Value_float_arrayw@@@@@9:0@@Fa@-Value_unknownx!@@@@@G13H1X@@Tb@,Value_bottomy@@PY[QYi@@]c@,Value_externz)Export_id!t@@@@@bjlcj@@od@,Value_symbol!t@@@@@rs@@e@0Value_unresolved@@@@@@@f@@@@@@@@@@@@@#||@@г頡#Tag||@||@@@@@г%array| @г!t| | @@Ұ@@@Ӱ@@@@@#}}@@г#int}#@@@@@@@#~'+~'5@@г$char~'9@@@@@@@#>B>M@@г&option>W@г%float>Q>V@@ @@@  @@@@@#^b^q@@г)boxed_int^w^@А !^t^v@@@$@@А!a )^^@@@г %descr ^ @@4 @@@#  @@г 5value_set_of_closures@@D@@@@@#  #$@@г-value_closure-@@T@@@@@#34@@г,value_string=@@d@@@@@#C D@ @г1value_float_arrayM@@t@@@@@#S15T1B@ @г2unknown_because_of]1F@@@@@@@#cY]@@@@@#ijnjjz@@г)Export_iduj~vj@yj@@@"@@@@@#@@г&Symbol@ @@@' @@@@"@#@@г 0unresolved_value@@'Ȱ@@@@$@@@@@+@@;@@/set_of_closures@@I@@@/@@g@*closure_id@@*Closure_id!t@@@~020L@@h@@@A@@@@@@@@@#*@@@Ш@г !t-.@@(@@+@@@'@###0<@@@Ш@г&*Closure_id0?0I@+0J0K@@@5@@8@@@0@@A@@+PTPi@@;@@/is_classic_mode@@@@@vxv@@i@2set_of_closures_id@@C!t@@@@@j@6set_of_closures_origin@@6Set_of_closures_origin!t@@@ϰ"#@@/k@$funs@@#Map!t/@@@ @@@ ݰ78@@Dl@@@@@@@@@A@@@>@#@@;?v@:@@Ш@гC$boolHvIv@@Kp@@N@@s@J@#FF?Q@>@@Ш@гI2Set_of_closures_id\]@P`a@@@X@@[@@@U@#QQHj@G@@Ш@гT6Set_of_closures_originuv@Yyz@@@c@@f@@@^@#ZZL@K@@Ш@г](Variable@e@@i@ @гl4function_declaration@@t˰@@@}̰ @@@@ @s@@@@@+"&"3@@;@@.free_variables@@/#Set!t@@@ @B@b@@m@,free_symbolsI@@#Set!t@@@cec@@n@$stubJ@@@@@@@o@#dbgY@@)Debuginfo!t@@@@@p@&inline@@&Lambda0inline_attribute@@@@@s@*specialise@@4specialise_attribute@@@ @@t@,is_a_functor@@@@@ @@!u@$body@@'Flambda!t@@@$ %  @@1v@$poll@@:.poll_attribute@@@2!#3!?@@?w@@@@@@@@@4@@@1@#|:@P@{@@Ш@г(VariableG@SH@[@K@\L@_@@P@`Q@a@ @@y @@@@ |@@#Zcq@@@Ш@г&Symbolgcthcz@kc{lc~@@pcqc@ @@ @@@@@@#z@@@Ш@г$bool@@@@@@@@#@@@Ш@г)Debuginfo@@@@İ@@@@@@#@@@Ш@г&Lambda@@@@ݰ@@@@@@#@@@Ш@г&Lambda@ǰ@@@@@@@@@#ȠȰ@@@Ш@гˠ$bool @@@@@@ @@#Πΰ @@@Ш@гѠ'Flambda  @ְ  @@@!@@@@$@@#נװ !'@@@Ш@гڠ&Lambda !) !/@ !0 !>@@@:@@@@=@@@@@@+ CG C[@@;@@.closure_origin@@.Closure_origin!t@@@f ,hj -h@@ 9x@¶ms@@)Parameter!t@@@@@@ A B@@ Ny@-function_body@@R@@@@@@ư R S@@ _z@@@@@@@@@L@@@I@#77. Zhx@-@@Ш@г:.Closure_origin eh{ fh@? ih jh@@@I@@L@@g@D@#@@2 s@1@@Ш@гC$list | }@гH)Parameter  @M  @@@W@@@\ @@_@@@R@#NND @C@@Ш@гQ&option  @гV-function_body  @@^а@@@cѰ @@f@@@]@@@@@+  @@;@@.function_decls@@@@@ɰ  @@ {@*bound_varsM@@2Var_within_closure#Map!tj@@@"<@@@">  @@ |@)free_varsN@@W#Map!t.specialised_to@@@"A@@@"C  4@@ }@0invariant_paramsX@@n$Lazy!tu#Map!t}#Set!t@@@"@@@"@@@" 57 5o@@ ~@)recursiveY@@$Lazy!t#Set!t@@@"@@@" &pr 'p@@ 3@$sizeZ@@$Lazy!t#Map!t  @@@"@@@"@@@"@@@" H I@ Z For functions that are very likely to be inlined, the size of the function's body.  V W!@@@@@@@ c@@0specialised_args[@@#Map!tJ.specialised_to@@@"@@@" m"$ n"]@@ zA@*fresheningx@@*Freshening+Project_var!t@@@#ذ  @@ B@6direct_call_surrogates@@#Map!t!t@@@&@@@&  @@ C@@@@@@@@@@@@@# @@@Ш@г砐5function_declarations  @@ϰ@@@@@@# @@@Ш@г2Var_within_closure  @  @@  @ @г!t  @@@@@  @@@@"?@@#  @@@Ш@г(Variable % -@ . 1@@  2 3@ @г'Flambda  @  $@@@)@@@'* @@*@@"D-@@# 5G@@@Ш@г 5h 5l@ 5m 5n@@г"(Variable '5Y (5a@* +5b ,5e@@. 05f 15g@ @г1(Variable >5J ?5R@9 B5S C5V@@= G5W H5X@ @@Gp @@@Pq@@@Xr3@@[@@"u@B@#>>- Sp{@,@@Ш@гAC ]p ^p@F ap bp@@гI(Variable op~ pp@Q sp tp@@U xp yp@ @@_ @@@g@@j@@"@Z@#VV; @,@@Ш@гY[  @^  @@гa(Variable  @i  @@m  @ @гp&option  @гu#int  @@}@@@ @@@@@@/@@@@"@|  zy@yy@@@y@y@#uue "4@d@@Ш@гx(Variable "N "V@ "W "Z@@ "[ "\@ @г'Flambda "7 ">@ "? "M@@@!@@@" @@@@"%@@# @@@Ш@г*Freshening  @  @@  @ @@B @@@@#E@@# #@@@Ш@г*Closure_id 0 1@ 4 5@@ 9 :@ @г*Closure_id E F@ I J@@@r@@@s @@@@&v@@@@@?@+== T  U$@@;@@(Contents ՠ@@@&@@@&@@ h') i'>@@ uD@2Unknown_or_mutable@@ q?AW@@ }E@@@A@@@@@Z@@@W@# x'+ y'3@@г%array '9@г"!t '7 '8@@*@@@/%@@@@'@### ?Cx@!@@@$@@A@{@+yy W[ Wl@@;@@(contents@@@@@& qs q@@ F@$size@@ s@@@&  @@ G@@@A@@@@@@@@@# q{@@@Ш@г:value_float_array_contents q~ q@@$@@'@@&@#@# @@@Ш@г"#int  @@*@@-@@&@)@@A@@@3        @@A $@%descr  @б@г !t  @@ @@@<3        @ cI N  T c  @A@@г %descr  @@ @@@<@@@@@< @@@  @ X 4 Extraction of the description of approximation(s).   @@@@@@@ *H@@@ h 䐠@@@@@@9&descrs 4 5@б@г $list ?  @@г ܠ!t I  J @@ @@@<3 8 7 7 8 8 8 8 8@\qB@A@@@ @@@< @@г à$list ] ^@г 렐%descr g h@@ @@@<@@@@@@<# @@@#@@<&,@@@ w@@ I@@@@,%print[ X\ Xa@б@г &Format)formatter Xd Xj@  Xk Xt@@@@@@D3        @Nm(@A @@б@г :!t Xx Xy@@ @@@D@@г K$unit X} X@@ @@@D@@@@@D!@@@'@@D$/ @@@ XX@ 3 Pretty-printing of approximations to a formatter.   W@@@@@@@ J@@@  @@@@@@C+print_descr\  @б@г d&Format)formatter  @   @@@@@@D3        @eA@A @@б@г %descr  @@ @@@D@@г $unit@@ @@@D@@@@@D!@@@'@@D$/ @@@&@@2K@@@@*;print_value_set_of_closures]12@б@г &Format)formatter@A@ DE@@@@@@D343344444@Lj(@A @@б@г E5value_set_of_closuresVW @@ @@@D @@г $unitc  d  @@ @@@D!@@@@@D"!@@@'@@D#$/ @@@q@@}L@@@@*;print_function_declarations^|  }  0@б@г &Format)formatter 1 5 1 ;@  1 < 1 E@@@@@@D$3~~@Lj(@A @@б@г 5function_declarations F K F `@@ @@@D%@@гE$unit a f a j@@ @@@D&@@@@@D'!@@@'@@D($/ @@@  @@M@@@@*@@@2@@@D@'@@б0specialised_argsг #Map!t(Variablen""Ho""P@ r""Qs""T@@w""Ux""V@ @г`.specialised_to'Flambda""1""8@ ""9""G@@@@@@DA3 @@@2@@@DC8@@б*fresheningг&+Project_var!t*Freshening"W"g"W"q@ "W"r"W"}@@"W"~"W"@ @@@@@DD[@@б6direct_call_surrogatesг #Map!t*Closure_id""""@ """"@@""""@ @г !t*Closure_id""""@ """"@@@@@@DE @@@2@@@DG@@г ꠐ5value_set_of_closures""""@@ @@@DH@@H@@DI"" @@oR@@DJ"W"\ @@z@@DK "" @@@@DL!!@@D@@DM!!@@O@@DN!!@@@@DO![!`!@@@@DP° !1!6%@@@#!!(@@/O@@*@@ *update_freshening_of_value_set_of_closuresa.""/"#@б@г (5value_set_of_closures9## :##@@ @@@DQ3(''(((((@@A@@б*fresheningг+Project_var!t*FresheningT# #0U# #:@ X# #;Y# #F@@]# #G^# #H@ @@@@@DR%@@г Z5value_set_of_closuresk#I#Nl#I#c@@ @@@DS2@@0@@DT5t# #% @@@<@@DU9? @@@z""@@P@@@@?-value_unknownb####@б@гh2unknown_because_of####@@ @@@DV3~~@Xm@A@@г2!t####@@ @@@DW@@@@@DX@@@## @ 򐠠 ' Basic construction of approximations. #e#e#e#@@@@@@@Q@@@~@@@@@@1)value_intc####@б@г#int####@@ @@@DY3@J_8@A@@г{!t####@@ @@@DZ@@@@@D[@@@## @@R@@ @@*value_chard####@б@г$char ## ##@@ @@@D\3@1F@A@@г!t####@@ @@@D]@@@@@D^@@@### @@/S@@ @@+value_floate.##/#$@б@г堐%float9#$:#$ @@ @@@D_3(''(((((@1F@A@@г۠!tH#$ I#$@@ @@@D`@@@@@Da@@@S## @@_T@@ @@/value_any_floatf^$$_$$"@г!tg$$%h$$&@@ @@@Db3VUUVVVVV@/D@A@@@q$$ @@}U@@ @@9value_mutable_float_arrayg|$'$+}$'$D@б$sizeгI#int$'$L$'$O@@ @@@Dc3xwwxxxxx@#6!@A@@г+!t$'$S$'$T@@ @@@Dd@@ @@De$'$G @@@$'$' @@V@@@@;value_immutable_float_arrayh$U$Y$U$t@б@г*%array$U$y$U$~@гW!t$U$w$U$x@@ @@@Df3@<S)@A@@@ @@@Dh @@гk!t$U$$U$@@ @@@Di@@@@@Dj@@@$U$U @@W@@ @@,value_stringi$$$$@б@г#int$$$$@@ @@@Dk3@6U@A@@б@гS&option $$ $$@гȠ&string$$$$@@ @@@Dl@@@@@@Dn  @@г!t&$$'$$@@ @@@Do-@@@@@Dp0@@@6@@Dq39 @@@4$$@@@X@@@@9/value_boxed_intj?$$@$$@б@г)boxed_intJ$$K$$@А!i@DyF@Dr3?>>?????@Xm%@AX$$Y$$@@@ @@@Dt @@б@А!ie$$f$$@@г!tn$$o$$@@ @@@Du@@@&@@Dv!@@@@@Dw$" @@@|$$@@Y@@@@*+value_blockk$$$$@б@г!t#Tag$$$$@ $$$$@@@@@@Dz3@Lg(@A @@б@г%array$$$%@гI!t$$$$@@ @@@D{@@@@@@D}  @@г[!t$%$%@@ @@@D~-@@@@@D0@@@6@@D3> @@@$$@@Z@@@@9,value_externl%% %%@б@г!t)Export_id%%%%#@ %%$%%%@@@@@@D3@[y(@A @@г!t%%)%%*@@ @@@D@@@@@D@@@%% @@[@@ @@,value_symbolm%+%/%+%;@б@гD!t&Symbol)%+%>*%+%D@ -%+%E.%+%F@@@@@@D3@:X(@A @@гР!t=%+%J>%+%K@@ @@@D@@@@@D@@@H%+%+ @@T\@@ @@,value_bottomnS%L%PT%L%\@г!t\%L%_]%L%`@@ @@@D3KJJKKKKK@/M@A@@@f%L%L @@r]@@ @@0value_unresolvedoq%a%er%a%u@б@г0unresolved_value|%a%x}%a%@@ @@@D3kjjkkkkk@!4@A@@г!t%a%%a%@@ @@@D@@@@@D@@@%a%a @@^@@ @@-value_closurep'#'''#'4@б+closure_varг !t(Variable'5'G'5'O@ '5'P'5'Q@@@@@@D3@<Q*@A @@б3set_of_closures_varг"++\?"++]@@ @@@D:@@@@@ @@DA! @@@I @@DD5@@@B@@DGE@@@S"++@@_j@@@@M5augment_with_variable|^',4,8_',4,M@б@г!ti',4,Pj',4,Q@@ @@@D3XWWXXXXX@f@A@@б@г!t(Variable~',4,U',4,]@ ',4,^',4,_@@@@@@D @@г#!t',4,c',4,d@@ @@@D'@@@@@D*@@@0@@D-3 @@@',4,4@搠 Augment an approximation with a given variable (see comment above). If the approximation was already augmented with a variable, the one passed to this function replaces it within the approximation. $+_+_&+,3@@@@@@@k@@@r@@@@@@L3augment_with_symbol}*,,*,,@б@г`!t*,,*,,@@ @@@D3@ez8@A@@б@г!t&Symbol*,,*,,@ *,,*,,@@@@@@D @@г!t*,,*,,@@ @@@D'@@@@@D*@@@0@@D-3 @@@*,,@J ; Like [augment_with_variable], but for symbol information. ),f,f),f,@@@@@@@l@@@Z֐@@@@@@L9augment_with_symbol_field~&---'---7@б@гĠ!t1---:2---;@@ @@@D3      @ez8@A@@б@гa!t&SymbolF---?G---E@ J---FK---G@@@@@@D @@б@г#intZ---K[---N@@ @@@D)@@г!tg---Rh---S@@ @@@D6@@@@@D9@@@%@@D<- @@@B@@D?E@@@x---@ ? Like [augment_with_symbol], but for symbol field information. ,,,,,-@@@@@@@m@@!@L@@@@@@^3replace_description0--0--@б@г:!t0--0--@@ @@@D3@w8@A@@б@г<%descr0--0--@@ @@@D@@гX!t0--0--@@ @@@D@@@@@D!@@@'@@D$* @@@0--@ 2 Replace the description within an approximation. /-U-U/-U-@@@@@@@n@@@+@@@@@@C1augment_with_kind3--3-. @б@г!t3-.3-.@@ @@@D3@\q8@A@@б@г*value_kind&Lambda3-.3-.@ 3-.3-.%@@@@@@D @@г!t)3-.)*3-.*@@ @@@D'@@@@@D*@@@0@@D-3 @@@73--@ 9 Improve the description by taking the kind into account D2--E2--@@@@@@@Qo@@@ @@@@@@L8augment_kind_with_approx[6.k.o\6.k.@б@г!tf6.k.g6.k.@@ @@@D3UTTUUUUU@ez8@A@@б@г*value_kind&Lambda{6.k.|6.k.@ 6.k.6.k.@@@@@@D @@г*value_kind&Lambda6.k.6.k.@ 6.k.6.k.@@@@@@D0 @@@@@D3$ @@@9@@D6< @@@6.k.k@쐠 9 Improve the kind by taking the description into account 5.,.,5.,.j@@@@@@@p@@@x@@@@@@U/equal_boxed_int8..8..@б@г*)boxed_int8..8..@А!a@EF@D3@t>@A8..8..@@@ @@@D @@б@А!a8..8..@@б@гP)boxed_int8..8..@А!b@E F@D&8..8..@@@ @@@E-@@б@А!b38..8..@@гà$bool8..8..@@ @@@EB@@@$@@EE@@@@@EH" @@@P@@EK<@@@I@@ENL@@@/8..@@;q@@@@T$meet:<//;<//@б4really_import_approxб@гܠ!tI<//J<//@@ @@@E 387788888@q#@A@@г렐!tX<//Y<//@@ @@@E @@@@@E @@б@г!tj<//k<//@@ @@@E !@@б@г !ty<//z<//@@ @@@E0@@г!t<//<//@@ @@@E=@@@@@E@@@@%@@EC( @@V6@@EF<//@@@<//@@r@@@@M%known?00 ?00@б@гA!t?00?00@@ @@@E3@f@A@@гe$bool?00?00@@ @@@E@@@@@E@@@?00 @ < An approximation is "known" iff it is not [Value_unknown]. >//>/0@@@@@@@s@@@ @@@@@@1&usefulB0h0lB0h0r@б@г!tB0h0uB0h0v@@ @@@E3@J_8@A@@г$boolB0h0zB0h0~@@ @@@E@@@@@E@@@B0h0h @Y D An approximation is "useful" iff it is neither unknown nor bottom. A00A00g@@@@@@@+t@@@i吠@@@@@@1.all_not_useful5E006E00@б@г$list@E00AE00@гݠ!tJE00KE00@@ @@@E398899999@TiB@A@@@ @@@E @@г$bool^E00_E00@@ @@@E@@@@@E@@@iE00 @ I Whether all approximations in the given list do *not* satisfy [useful]. vD00wD00@@@@@@@u@@@=@@@@@@60warn_on_mutationJ11J11@б@г+!tJ11J11@@ @@@E3@On8@A@@гO$boolJ11J11@@ @@@E@@@@@E @@@J11 @ Whether to warn on attempts to mutate a value. It must have been resolved (it cannot be [Value_extern] or [Value_symbol]). (See comment above for further explanation.) G00I1f1@@@@@@@v@@@ @@@@@@1A+6simplification_summaryFL11L11@@;@@,Nothing_done@@M11M11@@x@-Replaced_term@@N11N12@@y@@@A@@@@@L11@@A@w@@#M11@@@@@#N12@@@@@@A@@@3@avO@A@A+5simplification_resultG P22 P22*@@;@@@A@!t@@@E(@J@@@E)@@@@E*@@E+@@@@%P22&P22S@@@@2z@@@AВ@г'Flambda5P22-6P224@"9P225:P226@@@*3&%%&&&&&@Alf:;@@@AB@@@E6@E'@@@@$@@@!@A@@@г16simplification_summaryQP229RP22O@@9@@@г6!t\P22R7@@=!8@@@P"*9@@;@@3IHHIIIII@"@A<;@A+;simplification_result_namedHjQ2T2YkQ2T2t@@;@@aA@W%named@@@E;@@@@E<@@@@E=@@E>@@@@Q2T2TQ2T2@@@@{@@@AВ@г'FlambdaQ2T2wQ2T2~@"Q2T2Q2T2@@@*3@a9;@@@AA@@@EI@E:@@@@$@@@!@A@@@г16simplification_summaryQ2T2Q2T2@@9@@@г6!tQ2T27@@=!8@@@P"*9@@;@@3@"@A<;@(simplifyV3p3tV3p3|@б@гg!tV3p3V3p3@@ @@@EM3@=uo@A@@б@г!t'FlambdaV3p3V3p3@ V3p3V3p3@@@@@@EN @@г5simplification_resultV3p3V3p3@@ @@@EO'@@@@@EP*@@@0@@EQ-3 @@@ V3p3p@Q Given an expression and its approximation, attempt to simplify the expression to a constant (with associated approximation), taking into account whether the expression has any side effects. S22U343o@@@@@@@#|@@@aݐ@@@@@@L2simplify_using_env-\44.\44@б@гˠ!t8]449]44@@ @@@ER3'&&'''''@ez8@A@@б1is_present_in_envб@г!t(VariableQ^44R^44@ U^44V^44@@@@@@ES @@г $boolc^45d^45@@ @@@ET+@@@@@EU.@@б@гS!t'Flambday_55 z_55@ }_55~_55@@@@@@EVF @@г5simplification_result`55`551@@ @@@EWS@@@@@EXV@@T-@@EYY^44 @@@`@@EZ]c@@@\44@吠  As for [simplify], but also enables us to simplify based on equalities between variables. The caller must provide a function that tells us whether, if we simplify to a given variable, the value of that variable will be accessible in the current environment. X33[44@@@@@@@}@@"@q@@@@@@|.simplify_namedb5357b535E@б@г_!tb535Hb535I@@ @@@E[3@8@A@@б@г%named'Flambdab535Mb535T@ b535Ub535Z@@@@@@E\ @@г;simplification_result_namedb535^b535y@@ @@@E]'@@@@@E^*@@@0@@E_-3 @@@ b5353@@ ~@@@@38simplify_named_using_env d5{5 d5{5@б@г!t e55 e55@@ @@@E`3        @La@A@@б1is_present_in_envб@г!t(Variable 0f55 1f55@  4f55 5f55@@@@@@Ea @@гꠐ$bool Bf55 Cf55@@ @@@Eb+@@@@@Ec.@@б@г2%named'Flambda Xg55 Yg55@  \g55 ]g55@@@@@@EdF @@г;simplification_result_named jh55 kh55@@ @@@EeS@@@@@EfV@@T-@@EgY vf55 @@@`@@Eh]c@@@ |d5{5{@@ @@@@c=simplify_var_to_var_using_env m66 m66@б@г%!t n66 n66@@ @@@Ei3        @|@A@@б1is_present_in_envб@г!t(Variable o66 o67@  o67 o67@@@@@@Ej @@г e$bool o67  o67@@ @@@Ek+@@@@@El.@@г &option p77! p77'@гI!t(Variable p77 p77@  p77 p77 @@@@@@EmN @@@ @@@EoS@@Q*@@EpV o66!@@@]@@EqZ`$@@@ m66'@< If the given approximation identifies another variable and [is_present_in_env] deems it to be in scope, return that variable (wrapped in a [Some]), otherwise return [None]. !j66!l66@@@@@@@!@@7@L Ȑ@@@@@@y,simplify_var!r7)7-!r7)79@б@г!t!#r7)7<!$r7)7=@@ @@@Er3!!!!!!!!@8@A@@г {&option!2r7)7U!3r7)7[@В@г%named'Flambda!Dr7)7B!Er7)7I@ !Hr7)7J!Ir7)7O@@@@@@Es& @@@г렐!t!Xr7)7R!Yr7)7S@@ @@@Et5@@@@@ @@Eu<! @@@: @@@EwA!jr7)7A8@@@H@@ExEK;@@@!pr7)7)>@@!|@@@@@KA+0get_field_resultI!|t7]7b!}t7]7r@@;@@"Ok @@@Ey@@!u7u7w!u7u7@@!@+Unreachable@@!v77!v77@@!@@@A@@@@@!t7]7]@@@@!@@#!u7u7y!u7u7{@@г!t!u7u7@@$3!!!!!!!!@?5;@@@A@@@@@@@@@A$@@@@&@#""!v77 @@@@#@@A@@@3!!!!!!!!@ @A #@)get_field!~99!~99@б@г^!t!~99!~99@@ @@@E3!!!!!!!!@&ZT@A@@б+field_indexг!#int!~99$!~99'@@ @@@E@@гo0get_field_result!~99+!~99;@@ @@@E @@@@E#!~99 @@@*@@E'- @@@!~99@B k Given the approximation [t] of a value, expected to correspond to a block (in the [Pmakeblock] sense of the word), and a field index then return an appropriate approximation for that field of the block (or [Unreachable] if the code with the approximation [t] is unreachable). N.B. Not all cases of unreachable code are returned as [Unreachable]. "x77"}99@@@@@@@"@@@R!ΐ@@@@@@FA+8checked_approx_for_blockJ"9=9B" 9=9Z@@;@@%Wrong@@")9]9_"*9]9f@@"6@"Ok!t@@@E!@@@E@@@E@@"C9g9i"D9g9@@"P@@@A@@@@@"G9=9=@@@@"S@@#''"N9]9a%@$@@@(@#$$"T9g9k"U9g9m@@г&#Tag"`9g9q"a9g9t@-"d9g9u"e9g9v@@@53"Q"P"P"Q"Q"Q"Q"Q@rO;@@@A@@@@@&@@@$@A @@г5%array"t9g9{1@г9!t"|9g9y"}9g9z@@A@@@F<@@@@>@@A@:@@3"j"i"i"j"j"j"j"j@@A;>@6check_approx_for_block"99"99@б@г(!t"99"99@@ @@@E3""""""""@3{@A@@г8checked_approx_for_block"99"9:@@ @@@E@@@@@E@@@"99 @ T Try to prove that a value with the given approximation may be used as a block. "99"99@@@@@@@"@@@"@@@@@@14approx_for_bound_var"::"::@б@г͠5value_set_of_closures"::"::@@ @@@E3""""""""@J_8@A@@б@г!!t2Var_within_closure"::":;@ ":;":;@@@@@@E @@г!t#:;#:;@@ @@@E'@@@@@E*@@@0@@E-3 @@@#::@[ Find the approximation for a bound variable in a set-of-closures approximation. A fatal error is produced if the variable is not bound in the given approximation. # ::#!::@@@@@@@#-@@@k"琠@@@@@@L@@A@:@@3########@@A;>@ 'strict_check_approx_for_set_of_closures$==$===@б@г !t$=>=C$=>=D@@ @@@E3$ $ $ $ $ $ $ $ @*{@A@@г )strict_checked_approx_for_set_of_closures$*=E=J$+=E=s@@ @@@E@@@@@E@@@$5== @@$A@@ @@A+ "checked_approx_for_set_of_closuresL$A=u=z$B=u=@@;@@%Wrong@@$K==$L==@@$X@*Unresolved!@@@E@@$Y==$Z==@@$f@'Unknown@@$b==$c==@@$o@ #Unknown_because_of_unresolved_value!@@@E@@$p==$q=>@@$}@"Ok#ɠ !t@@@E@@@E {@@@E@@$>>$>>@@$@@@A@@@@@$=u=u@@@@$@@#LL$==J@I@@@M@#II$==$==@B@гK0unresolved_value$==L@@R3$$$$$$$$@vl;@@@A@@@@@@@@@AR@@@@T@#PP$==N@M@@@Q@#MM$==$==@F@гO0unresolved_value$=>P@@VQ@@@@S@#OO$>>$>>@<@гQ&option$>>$>>@гV(Variable$>>$>>@]$>>$>>@@@e<@@@j= @@г`5value_set_of_closures$>>a@@gFb@@@@d@@A@`@@3$$$$$$$$@F@Aad@ check_approx_for_set_of_closures$??$??@б@г!!t%??%??@@ @@@E3$$$$$$$$@a@A@@гР "checked_approx_for_set_of_closures%??%??@@ @@@E@@@@@E@@@%?? @!d Try to prove that a value with the given approximation may be used as a set of closures. Values coming from external compilation units with unresolved approximations are permitted. %)>>%*?X?@@@@@@@%6@@@!t$𐠠@@@@@@1A+:checked_approx_for_closureM%A??%B??@@;@@%Wrong@@%K??%L?@@@%X@"Ok!j@@@EϠ$!!t@@@E@@@EҠ$"!t@@@E@@@Eՠ!g@@@E@@%v@@%w@0@c@@%@@@A@@@@@%z??@@@@%@@#88%??6@5@@@9@#55%@@%@@ @@г7-value_closure%@@%@@@@?3%}%|%|%}%}%}%}%}@|Y;@@@A@@@@@@@@@A@@гA&option%@@)%@@/@гF(Variable%@@%@@&@M%@@'%@@(@@@U@@@Z  @@гP&option%@0@E%@0@K@гU&Symbol%@0@<%@0@B@\%@0@C%@0@D@@@d:@@@i; @@г_5value_set_of_closures%@0@N`@@fDa@@@@c@@A@_@@3%%%%%%%%@D@A`c@8check_approx_for_closure%AA%AA@б@г"!t%AA%AA@@ @@@E3%%%%%%%%@_@A@@г:checked_approx_for_closure%AA%AA@@ @@@E@@@@@E@@@&AA @"O Try to prove that a value with the given approximation may be used as a closure. Values coming from external compilation units with unresolved approximations are not permitted. &@e@e&@A%@@@@@@@&!@@@"_%ې@@@@@@1A+ .checked_approx_for_closure_allowing_unresolvedN&,AA&-AB@@;@@%Wrong@@&6BB&7BB@@&C@*Unresolved#@@@E@@&DBB &EBB@@@&Q@'Unknown@@&MBABC&NBABL@@&Z@ #Unknown_because_of_unresolved_value#@@@E@@&[BMBO&\BMB@@&h@"Ok"z@@@E%"!t@@@E@@@E%Š#!t@@@E@@@E"w@@@E@@&BB&BB@@&@@@A@@@@@&AA@@@@&@@#]]&BB[@Z@@@^@#ZZ&BB"&BB,@S@г\0unresolved_value&BB0]@@c3&&&&&&&&@};@@@A@@@@@@@@@Ac@@@@e@#aa&BABE_@^@@@b@#^^&BMBQ&BMBt@W@г`0unresolved_value&BMBxa@@gb@@@@d@#``&BB&BB@<@гb-value_closure&BB&BB@@j,@@гg&option&BB&BB@гl(Variable&BB&BB@s&BB&BB@@@{F@@@G @@гv&option&BB&BB@г{&Symbol&BB&BB@'BB'BB@@@a@@@b @@г5value_set_of_closures' BB@@k@@@@@@A@@@3&&&&&&&&@k@A@ ,check_approx_for_closure_allowing_unresolved'CxC|'CxC@б@г#!t'#CC'$CC@@ @@@F3''''''''@@A@@г .checked_approx_for_closure_allowing_unresolved'2CC'3CC@@ @@@F@@@@@F@@@'=CxCx @# As for [check_approx_for_closure], but values coming from external compilation units with unresolved approximations are permitted. 'JBB'KC1Cw@@@@@@@'W@@@#'@@@@@@16check_approx_for_float'aD)D-'bD)DC@б@г#!t'lD)DF'mD)DG@@ @@@F3'['Z'Z'['['['['[@J_8@A@@г&Ġ&option'{D)DQ'|D)DW@г'1%float'D)DK'D)DP@@ @@@F@@@@@@F @@@$@@F!'@@@'D)D)@#ݐ > Returns the value if it can be proved to be a constant float 'CC'CD(@@@@@@@'@@*@#'i@@@@@@@7float_array_as_constant'DD'DD@б@г#1value_float_array'DD'DD@@ @@@F3''''''''@Yn8@A@@г'&option'DD'DD@г'C$list'DD'DD@г'%float'DD'DD@@ @@@F#@@@@@@F( @@@&@@@F-#@@@3@@F06&@@@'DD)@$D D Returns the value if it can be proved to be a constant float array ( DYDY( DYD@@@@@@@(@@9@$T'А@@@@@@O7check_approx_for_string( E.E2(!E.EI@б@г$!t(+E.EL(,E.EM@@ @@@F3((((((((@h}8@A@@г'&option(:E.EX(;E.E^@г'&string(DE.EQ(EE.EW@@ @@@F@@@@@@F  @@@$@@F!!'@@@(TE.E.@$ ? Returns the value if it can be proved to be a constant string (aDD(bDE-@@@@@@@(n@@*@$((@@@@@@@A+7switch_branch_selectionO(yE`Ee(zE`E|@@;@@/Cannot_be_taken@@(EE(EE@@(@,Can_be_taken@@(EE(EE@@(@-Must_be_taken@@(EE(EE@@(@@@A@@@@@(E`E`@@A@(@@#(EE@@@@ @#(EE@@@@@#(EE@@@@@@A@@@3((((((((@^@A@ %potentially_taken_const_switch_branch(EE(EF"@б@г%W!t(EF%(EF&@@ @@@F(3((((((((@VP@A@@б@г(#int(EF*(EF-@@ @@@F)@@гi7switch_branch_selection(EF1(EFH@@ @@@F*@@@@@F+!@@@'@@F,$* @@@(EE@%8 < Check that the branch is compatible with the approximation (EE(EE@@@@@@@) @@@%H(Đ@@@@@@C %potentially_taken_block_switch_branch)FIFM)FIFr@б@г%!t)FIFu) FIFv@@ @@@F-3)) ) )))))@\q8@A@@б@г(#int)0FIFz)1FIF}@@ @@@F.@@гĠ7switch_branch_selection)=FIF)>FIF@@ @@@F/@@@@@F0!@@@'@@F1$* @@@)KFIFI@@)W@@@@*.function_arity)VFF)WFF@б@г%X4function_declaration)aFF)bFF@@ @@@F23)P)O)O)P)P)P)P)P@CX@A@@г)0#int)pFF)qFF@@ @@@F3@@@@@F4@@@){FF @@)@@ @@GH'@ *AGH(*BGH)@@@@@@F>2 @@@@@F?5$ @@б@б@г#6!t6Set_of_closures_origin*ZH+H1*[H+HG@ *^H+HH*_H+HI@@@@@@F@O @@г#L!t6Set_of_closures_origin*pH+HM*qH+Hc@ *tH+Hd*uH+He@@@@@@FAe @@@@@FBh$ @@г&5function_declarations*HgHl*HgH@@ @@@FCu@@@@@FDx*H+H0 @@@I@@FE|*GG @@@@@FF@@@*GG@@*@@@@ update_function_declaration_body*HH*HH@б@г&4function_declaration*HH*HH@@ @@@FG3********@@A@@б@б@г"!t'Flambda*HH*HH@ *HH*HH@@@@@@FH @@г"!t'Flambda*HH*HH@ *HH*HH@@@@@@FI2 @@@@@FJ5$ @@г&砐4function_declaration*HH*HH@@ @@@FKB@@@@@FLE*HH @@@L@@FMIO @@@*HH@@+ @@@@O0make_closure_map+ IzI~+ IzI@б@г(G#Map!t2Set_of_closures_id+II+II@ +!II+"II@@+&II+'II@ @г'85function_declarations+1II+2II@@ @@@IW3+ +++ + + + + @;@A@@@+ @@@IY @@г$#Map!t*Closure_id+MII+NII@ +QII+RII@@+VII+WII@ @г'h5function_declarations+aII+bII@@ @@@IZ0@@@)@@@I\5 @@@5@@I]8>@@@+qIzIz@' v Creates a map from closure IDs to function declarations by iterating over all sets of closures in the given map. +~HH+ILIy@@@@@@@+@@+@'+E@@@@@@W5clear_function_bodies+II+IJ @б@г'5function_declarations+IJ +IJ!@@ @@@I^3++++++++@p8@A@@г'5function_declarations+IJ%+IJ:@@ @@@I_@@@@@I`@@@+II @@+@@ @@@*)A@)k)eA@) )A@((A@(^(XA@(Q'/B@'%"B@'$B@'$ B@'"B@'"B@'B@'=B@@f@_@@r@k)@"@@q@jC@#@@@@}S@L@@@z)@"@@@q@j@X@8@@}3@,@y@r(@!@@5@.@@c!@@T@4@@g@@i@I"@@@d^A@4.A@  A@ x 6@  @  B@ ; @  S@ 3 @  A@  S@ 2 ,A@  @  @@ @A@K$@A@hA@ A@Z@93A@O(@@m@M@A@@_&@@@t@z@s @@@3,e,d,d,e,e,e,e,e@@A@ H************************************************************************,A@@,A@L@ H ,BMM,BM@ H OCaml ,C,C@ H ,D,D3@ H Pierre Chambart, OCamlPro ,E44,E4@ H Mark Shinwell and Leo White, Jane Street Europe ,F,F@ H ,G,G@ H Copyright 2013--2016 OCamlPro SAS ,H,Hg@ H Copyright 2014--2016 Jane Street Group LLC ,Ihh,Ih@ H ,J,J@ H All rights reserved. This file is distributed under the terms of ,K,KN@ H the GNU Lesser General Public License version 2.1, with the ,LOO,LO@ H special exception on linking described in the file LICENSE. ,M,M@ H ,N,N5@ H************************************************************************,O66,O6@ * Simple approximations to the runtime results of computations. This pass is designed for speed rather than accuracy; the performance is important since it is used heavily during inlining. +=> [None] if unknown or mutable ,],]>@ l* A value of type [t] corresponds to an "approximation" of the result of a computation in the program being compiled. That is to say, it represents what knowledge we have about such a result at compile time. The simplification pass exploits this information to partially evaluate computations. At a high level, an approximation for a value [v] has three parts: - the "description" (for example, "the constant integer 42"); - an optional variable; - an optional symbol or symbol field. If the variable (resp. symbol) is present then that variable (resp. symbol) may be used to obtain the value [v]. The exact semantics of the variable and symbol fields follows. Approximations are deduced at particular points in an expression tree, but may subsequently be propagated to other locations. At the point at which an approximation is built for some value [v], we can construct a set of variables (call the set [S]) that are known to alias the same value [v]. Each member of [S] will have the same or a more precise [descr] field in its approximation relative to the approximation for [v]. (An increase in precision may currently be introduced for pattern matches.) If [S] is non-empty then it is guaranteed that there is a unique member of [S] that was declared in a scope further out ("earlier") than all other members of [S]. If such a member exists then it is recorded in the [var] field. Otherwise [var] is [None]. Analogous to the construction of the set [S], we can construct a set [T] consisting of all symbols that are known to alias the value whose approximation is being constructed. If [T] is non-empty then the [symbol] field is set to some member of [T]; it does not matter which one. (There is no notion of scope for symbols.) Note about mutable blocks: Mutable blocks are always represented by [Value_unknown] or [Value_bottom]. Any other approximation could leave the door open to a miscompilation. Such bad scenarios are most likely a user using [Obj.magic] or [Obj.set_field] in an inappropriate situation. Such a situation might be: [let x = (1, 1) in Obj.set_field (Obj.repr x) 0 (Obj.repr 2); assert(fst x = 2)] The user would probably expect the assertion to be true, but the compiler could in fact propagate the value of [x] across the [Obj.set_field]. Insisting that mutable blocks have [Value_unknown] or [Value_bottom] approximations certainly won't always prevent this kind of error, but should help catch many of them. It is possible that there may be some false positives, with correct but unreachable code causing this check to fail. However the likelihood of this seems sufficiently low, especially compared to the advantages gained by performing the check, that we include it. An example of a pattern that might trigger a false positive is: [type a = { a : int } type b = { mutable b : int } type _ t = | A : a t | B : b t let f (type x) (v:x t) (r:x) = match v with | A -> r.a | B -> r.b <- 2; 3 let v = let r = ref A in r := A; (* Some pattern that the compiler can't understand *) f !r { a = 1 }] When inlining [f], the B branch is unreachable, yet the compiler cannot prove it and must therefore keep it. ) ) No description was found for this value ,,@ } CR-soon mshinwell: add support for the approximations of the results, so we can do all of the tricky higher-order cases. ,,%W@ ( when [is_classic_mode] is [false], functions in [function_declarations] are guaranteed to have function bodies (ie: [function_declaration.function_body] will be of the [Some] variant). When it [is_classic_mode] is [true], however, no guarantees about the function_bodies are given. ,XX,@ [* For functions that are very likely to be inlined, the size of the function's body. " ; Any freshening that has been applied to [function_decls]. ,^`,^@ 5* Extraction of the description of approximation(s). 堠 4* Pretty-printing of approximations to a formatter. 6 (* Basic construction of approximations. Q * Construct a closure approximation given the approximation of the corresponding set of closures and the closure ID of the closure to be projected from such set. [closure_var] and/or [set_of_closures_var] may be specified to augment the approximation with variables that may be used to access the closure value itself, so long as they are in scope at the proposed point of use.  * Construct a set of closures approximation. [set_of_closures_var] is as for the parameter of the same name in [value_closure], above. N * Take the given constant and produce an appropriate approximation for it together with an Flambda expression representing it. 堠 * Augment an approximation with a given variable (see comment above). If the approximation was already augmented with a variable, the one passed to this function replaces it within the approximation. i <* Like [augment_with_variable], but for symbol information.  @* Like [augment_with_symbol], but for symbol field information.  3* Replace the description within an approximation. = :* Improve the description by taking the kind into account ܠ :* Improve the kind by taking the description into account r CR-soon mshinwell for pchambart: Add comment describing semantics. (Maybe we should move the comment from the .ml file into here.) -&:..-';/M/@ =* An approximation is "known" iff it is not [Value_unknown]. W E* An approximation is "useful" iff it is neither unknown nor bottom.  J* Whether all approximations in the given list do *not* satisfy [useful].  * Whether to warn on attempts to mutate a value. It must have been resolved (it cannot be [Value_extern] or [Value_symbol]). (See comment above for further explanation.) v * Given an expression and its approximation, attempt to simplify the expression to a constant (with associated approximation), taking into account whether the expression has any side effects. " * As for [simplify], but also enables us to simplify based on equalities between variables. The caller must provide a function that tells us whether, if we simplify to a given variable, the value of that variable will be accessible in the current environment.  * If the given approximation identifies another variable and [is_present_in_env] deems it to be in scope, return that variable (wrapped in a [Some]), otherwise return [None].  = l* Given the approximation [t] of a value, expected to correspond to a block (in the [Pmakeblock] sense of the word), and a field index then return an appropriate approximation for that field of the block (or [Unreachable] if the code with the approximation [t] is unreachable). N.B. Not all cases of unreachable code are returned as [Unreachable].  : U* Try to prove that a value with the given approximation may be used as a block.  * Find the approximation for a bound variable in a set-of-closures approximation. A fatal error is produced if the variable is not bound in the given approximation.  ' "* Given a set-of-closures approximation and a closure ID, apply any freshening specified by the approximation to the closure ID, and return the resulting ID. Causes a fatal error if the resulting closure ID does not correspond to any function declaration in the approximation.  s In the [Ok] case, there may not be a variable associated with the set of closures; it might be out of scope. -M>>-N>b>@ * Try to prove that a value with the given approximation may be used as a set of closures. Values coming from external compilation units with unresolved approximations are permitted. * * Try to prove that a value with the given approximation may be used as a closure. Values coming from external compilation units with unresolved approximations are not permitted. B s CR-someday mshinwell: naming is inconsistent: this is as "strict" as "strict_check_approx_for_set_of_closures" -YA&A&-ZAkA@ * As for [check_approx_for_closure], but values coming from external compilation units with unresolved approximations are permitted.  ?* Returns the value if it can be proved to be a constant float  E* Returns the value if it can be proved to be a constant float array \ @* Returns the value if it can be proved to be a constant string  =* Check that the branch is compatible with the approximation n [* Create a set of function declarations based on another set of function declarations.  w* Creates a map from closure IDs to function declarations by iterating over all sets of closures in the given map. @-./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"-I2middle_end/flambda"-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-- =/builds/workspace/precheck/flambda/false/label/ocaml-linux-32 >10/.-,+*)('&%$#"! @@0BbP1DJy}3--------@-@@/Allocated_const0ЖݔTWŠ(Asttypes0>n{T8cئ5Build_path_prefix_map0z HkGs8CamlinternalFormatBasics0%FU(Q/Tu0CamlinternalLazy0&͂7 Pˆ2Clambda_primitives01U1/Closure_element0YWZ̡Q.hV&'05:z[ކ.Closure_origin0vˆtT{(}z*Cmi_format0c˯7͗ԩmݠ0Compilation_unit0 {p-Vg_*Data_types0I'Ue`wq]Ѡ)Debuginfo0PtJ=^w/#Env0zV L{YWI'0-bw+LO%#0Idvu "*Format_doc0]mWϓ:Mݠ"0/^*b1R%Ident0">WA+9*X,Identifiable0 {d\FX'`7Internal_variable_names0HdeՄL ԩ&Lambda0z1x]&ZT,Linkage_name0EwKсڊs)Load_path0I@18 ~(Location0a7cK_H%9)Longident0s `7mɕc$Misc0ob]6>Vê>0Mutable_variable0~emPs+Ӑ0ҡ4d,)Z0\݅}x.Type_immediacy0A^abOhՠ%Types0^Y~# )Unit_info0ڀh%(2Var_within_closure00SSJh6 (Variable0' Gr㠠(Warnings0mJɒkgr@  @@M)(@@,,@@{ʰ+B"@]!C!*i)@ ! ː%b$k@@%#*$)@&&%@ f  6 e%$@R@+(@@*)@@@''6,,@@@((U@@`'n&*2)1@ݐ a@ @*)@''l@M @@#<#2@(@#@wİ+’+@# "@@  @ o@@  n y @@@!@**@  #@@ w 3+&@@G@@'&@#\#@%a$''\@+""Z@%%@ *)@-p-^@ݐ_%a#@ְ)")@/(ȕ(@ b , ΐ #@!5!|@AI@@%b#@w`@@=w@)c@  kа--N@".K.g@  Ѱ/~@ ʓ }''?@@'@  d@@@~@@א&@@t    +*@5S,],@@&&@Ðݰ(@'@*)@  ,)~)l@,#-e-N@@+*,,@  "Ȑ#@  @  )2(@?#@X@&&$@АL  @,֕,@&~%(N'@..Z@Ґ!#A#@J@5'#&@@@P,X&@@P@@