NL i1'dZddlmZddlmZddlmZmZmZm Z m Z m Z ddl m Z mZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZeeee fdfZ!eedfZ"e#eee!e"fefZ$ddZ%dd Z& dd Z'dd Z( dd Z) dd Z* ddZ+ ddZ, ddZ-ddZ.y)aYTransformation for inserting refrecence count inc/dec opcodes. This transformation happens towards the end of compilation. Before this transformation, reference count management is not explicitly handled at all. By postponing this pass, the previous passes are simpler as they don't have to update reference count opcodes. The approach is to decrement reference counts soon after a value is no longer live, to quickly free memory (and call __del__ methods), though there are no strict guarantees -- other than that local variables are freed before return from a function. Function arguments are a little special. They are initially considered 'borrowed' from the caller and their reference counts don't need to be decremented before returning. An assignment to a borrowed value turns it into a regular, owned reference that needs to freed before return. ) annotations)Iterable) AnalysisDictanalyze_borrowed_argumentsanalyze_live_regsanalyze_must_defined_regs cleanup_cfgget_cfg)FuncIR all_values)Assign BasicBlockBranch ControlOpDecRefGotoIncRefInteger KeepAlive LoadAddressOpRegister RegisterOpUndefValue.c &t|j}t|j|j}|Dchc]}|js|}}t |j}t |j|}t|j||}t|j|||d}t|} i} |jjD]} t| jdttfrDt| | |j|j |j |j"|j"| t%| |j |j"|j |j"t'|jycc}w)zgInsert reference count inc/dec opcodes to a function. This is the entry point to this module. T) strict_errorsN)r blocksr arg_regs is_borrowedsetrrrmake_value_orderingcopy isinstanceopsrrinsert_branch_inc_and_decrefsbeforeaftertransform_blockr ) ircfgvaluesvalueborrowedargsliveborrowdefinedorderingcacheblocks ^/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/mypyc/transform/refcount.pyinsert_ref_count_opcodesr8;s3 ")) C  RYY /F#)?%U->->?H?2;;'D RYY ,D ' 3 AF' 3fTXYG"2&HE! V eiimfd^ 4 )       t{{DJJ w}}U V +@s F Fc.t|txr||vSN)r%r)post_must_definedsrcs r7is_maybe_undefinedr=[s c8 $ E4E)EEc |jjrAt|ttfs*|j t |t|||yyy)Nis_xdec)type is_refcountedr%rrappendrr=)r&destr3keys r7maybe_append_dec_refrG_sG yyz$%8H'I 6$(:73<(NOP(Jr>cf|jjr|jt|yyr:)rBrCrDr)r&rEs r7maybe_append_inc_refrIfs$ yy 6$< r>c|j}g}t|D]X\}}||f} ||| vsJt|tr |jn|} |j } t| D]\\} } | || vs| || vs| | d| vst || | || vs0| || vs8t|tsJ|t|| || ^t|ts|j|t|tr|jD]%} | || vs | || vs| | vst|| || '| jr$| || vs-t|tr| jrKt|| || [||_yr:)r& enumerater%r rEstolenrIrGrrDrunique_sourcesis_voidrr!)r6pre_live post_live pre_borrowr;old_opsr&ioprFrErLjr<s r7r*r*ksiiGC7#&D2aj#&&&$R0rwwb ' LFAsin$z#(>#PRQRBS$S#.z#.48C=3H%b&15251(d4EsK L"i( JJrN b) $ $$& GC)C.(S 3-GCW]L]$S#/@#F G IcN*J/D4D4D d,=s CM&DNEIr>c |t|jdz f}||} ||} ||} |j} t| j D]\} }t | t r0| jt jk(r| dk(r| jf}nd}t||| | | ||}t|||| |}| j| t|||||y)aNInsert inc_refs and/or dec_refs after a branch/goto. Add dec_refs for registers that become dead after a branch. Add inc_refs for registers that become unborrowed after a branch or goto. Branches are special as the true and false targets may have a different live and borrowed register sets. Add new blocks before the true/false target blocks that tweak reference counts. Example where we need to add an inc_ref: def f(a: int) -> None if a: a = 1 return a # a is borrowed if condition is false and unborrowed if true rN)lenr& terminatorrKtargetsr%rrTIS_ERRORr.after_branch_decrefsafter_branch_increfs set_target add_block)r6r5rrOrQ post_borrowr;r4prev_keysource_live_regssource_borrowedsource_definedtermrStargetomitteddecsincss r7r'r's4s599~)*H)!(+O&x0N   Dt||~.I 6 dF #6??(BqAvzzmGG# Hno?OQY[b $FHj/S[\ 9T4GHIr>cr||df}||z |z }|r#tfdt|fdDSy)Nrc3nK|],}|jjr|vr|t|f.ywr:)rBrCr=).0regrhres r7 z'after_branch_decrefs..s: xx%%#W*<$^S9 : s25c|Sr:rXrr4s r7z&after_branch_decrefs..s HQKr>rFrXtuplesorted) labelrOrerdrcr4rhtarget_pre_livedecrefs ` `` r7r]r]sLuax(O  // AF  f*?@   r>cv||df}||df}||z |z}|r tdt|fdDSy)Nrc3NK|]}|jjs|ywr:)rBrCrmrns r7roz'after_branch_increfs..s! H^H^C s%%c|Sr:rXrqs r7rsz&after_branch_increfs..s  r>rtrXru)rxrOrQrdr4rytarget_borrowedincrefs ` r7r^r^sZuax(O *O/? BF  !&.CD    r>cF|s|s|S|||f|vr||||fSt}|j||jjd|D|jjd|D|jjt ||||||f<|S)Nc3<K|]\}}t||yw)r@N)r)rmrnxdecs r7rozadd_block..sE93VC..Esc32K|]}t|ywr:)rr}s r7rozadd_block..s1SVC[1s)rrDr&extendr)rirjr5rrxr6s r7r`r`s   tTe#UD$&'' LE MM% IIEEE II1D11 IIT%[!$E%t  Lr>ci}d}|jD] }|||<|dz }|jD]}|jD]}t|trN)r+r returnNone)r; set[Value]r<rrbool) r&list[Op]rErr3AnalysisDict[Value]rFztuple[BasicBlock, int]rr)r&rrErrr) r6rrOrrPrrQrr;rrr)r6rr5 BlockCacherlist[BasicBlock]rOrrQrrarr;rr4dict[Value, int]rr)rxrrOrrerrdrrcrr4rrhzIterable[Value]rztuple[tuple[Value, bool], ...]) rxrrOrrQrrdrr4rrztuple[Value, ...]) riDecsrjIncsr5rrrrxrrr)r+r rr)/__doc__ __future__rcollections.abcrmypyc.analysis.dataflowrrrrr r mypyc.ir.func_irr r mypyc.ir.opsr rrrrrrrrrrrrrrrvrrrdictrr8r=rGrIr*r'r]r^r`r#rXr>r7rs/$#$0$ U5$;  $% UCZ % D$./; < @FQ QQ)<QCYQ Q! 0 0!0#0$ 0 + 0  0f/I /I /I /I" /I $ /I % /I+/I/I /Id !  !   $( !$     " #-7GPZ&r>