
    |h,=                     v   S SK r S SKJr  S SKJr  S SKJr  S SKJr  S SK	J
s  Jr  S r " S S5      r " S	 S
\5      r\R                   " S5      R#                  5       r " S S\\5      r " S S\\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r\S:X  a  \ R4                  " 5         gg)    N)defaultdict)ir)binding)TestCasec              #      ^ #    U 4S jn[         R                  R                  5        H,  u  p#UR                  S5      (       d  M  SU 3U" U5      4v   M.     g 7f)Nc                 Z   >^  U U4S jnST R                    ST R                   3Ul        U$ )Nc                    > T" U T5      $ N )selffngenerate_tests    V/home/james-whalen/.local/lib/python3.13/site-packages/llvmlite/tests/test_refprune.pywrapped-_iterate_cases.<locals>.wrap.<locals>.wrapped   s     r**    zgenerated test for .)
__module____name____doc__)r   r   r   s   ` r   wrap_iterate_cases.<locals>.wrap   s)    	+/a}Mr   casetest_)proto__dict__items
startswith)r   r   kcase_fns   `   r   _iterate_casesr!   
   sJ      nn**,
<<!+tG},, -s   >AAc                       \ rS rSrS rSrg)PassManagerMixin   c                     [         R                  " 5         [         R                  R                  5       R	                  5       n[         R
                  " SSS9n[         R                  " X5      $ )Nr   )speed_level
size_level)llvminitialize_native_targetTargetfrom_default_triplecreate_target_machinecreate_pipeline_tuning_optionscreate_pass_builder)r   tmptos      r   pbPassManagerMixin.pb   sL    %%'[[,,.DDF11aAN''00r   r   N)r   r   __qualname____firstlineno__r1   __static_attributes__r   r   r   r#   r#      s    1r   r#   c                   V    \ rS rSrSrS r\" \5       H  u  rr\\	" 5       \'   M     Sr
g)TestRefPrunePrototype   z%
Test that the prototype is working.
c                     U" 5       u  p#n[         R                  " X#5      R                  5       nU R                  XE5        g r
   )r   FanoutAlgorithmrunassertEqual)r   case_gennodesedgesexpectedgots         r   r   #TestRefPrunePrototype.generate_test#   s5    !)h##E1557'r   r   N)r   r   r3   r4   r   r   r!   namer   localsr5   r   r   r   r7   r7      s,    ( %]3
d 4r   r7      c                       \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 r\" \5       H  u  rr\\" 5       \'   M     Srg)TestRefPrunePass0   z
Test that the C++ implementation matches the expected behavior as for
the prototype.

This generates a LLVM module for each test case, runs the pruner and checks
that the expected results are achieved.
c                     [         R                  " [         R                  " 5       [        /5      n[         R                  " XSS9$ )N
NRT_increfrC   r   FunctionTypeVoidTypeptr_tyFunctionr   mfntys      r   make_increfTestRefPrunePass.make_incref9   +    r{{}vh7{{166r   c                     [         R                  " [         R                  " 5       [        /5      n[         R                  " XSS9$ )N
NRT_decrefrK   rL   rQ   s      r   make_decrefTestRefPrunePass.make_decref=   rV   r   c                     [         R                  " [         R                  " S5      S5      n[         R                  " XSS9$ )N    r   switcherrK   r   rM   IntTyperP   rQ   s      r   make_switcherTestRefPrunePass.make_switcherA   s+    rzz"~r2{{144r   c                     [         R                  " [         R                  " S5      S5      n[         R                  " XSS9$ )N   r   brancherrK   r^   rQ   s      r   make_brancherTestRefPrunePass.make_brancherE   s+    rzz!}b1{{144r   c                    [         R                  " 5       nU R                  U5      nU R                  U5      nU R	                  U5      nU R                  U5      n[         R                  " [         R                  " 5       [        /5      n[         R                  " X8SS9n	U	R                  u  n
SU
l        0 nU H  nU	R                  U5      X'   M     [         R                  " 5       nUR                  5        GHO  u  pUR                  X   5        X    H@  nUS:X  a  UR!                  XJ/5        M  US:X  a  UR!                  XZ/5        M7  [#        S5      e   [%        U5      nUS:X  a  UR'                  5         M  US:X  a  Uu  nUR)                  UU   5        M  US	:X  a2  Uu  nnUR!                  US
5      nUR+                  UUU   UU   5        M  US	:  ae  UR!                  US
5      nUtnnUR-                  UUU   S9n[/        U5       H*  u  nnUR1                  UR3                  U5      UU   5        M,     GMG  [#        S5      e   U$ )NmainrK   memincrefdecrefunreachabler   rc      r   )default)r   ModulerT   rY   r`   re   rM   rN   rO   rP   argsrC   append_basic_block	IRBuilderr   position_at_endcallAssertionErrorlenret_voidbranchcbranchswitch	enumerateadd_casetype)r   r>   r?   rR   	incref_fn	decref_fnswitcher_fnbrancher_fnrS   r   ptrbbmapbbbuilderjump_targetsaction	n_targetsdstleftrightselheadtailswis                            r   generate_irTestRefPrunePass.generate_irI   s   IIK$$Q'	$$Q'	((+((+r{{}vh7[[v.B--b1EI  ,,. %B##EI.)X%LLE2x'LLE2(77 $ L)IA~  "a$uSz*a ,ull;3U4[%,?Qll;3 ,^^Ct^='oFAsKKU3Z8 . %]33? !.B r   c                     [         R                  " [        U5      5      nU R                  5       nUR	                  5       nUR                  5         UR                  X#5        U$ r
   )r(   parse_assemblystrr1   getModulePassManageradd_refprune_passr;   )r   irmodmodr1   pms        r   apply_refpruneTestRefPrunePass.apply_refprune   sK    !!#e*-WWY$$&

s
r   c                    [        S 5      nUR                  5        H-  u  pVUR                  S5      nUR                  S5      nXxS.XE'   M/     UR                  5        HD  u  pYUR                  U5      (       d  M  U	S==   S-  ss'   X%    H  n
XJ   S==   S-  ss'   M     MF     UR                   H  nUR
                  S:X  d  M    O   WR                   Hl  nXLR
                     n	[        U5      nUR                  S5      nUR                  S5      nU R                  U	S   US	U 3S
9  U R                  U	S   US	U 3S
9  Mn     g )Nc                       [        [        5      $ r
   )r   intr   r   r   <lambda>(TestRefPrunePass.check.<locals>.<lambda>   s	    C 0r   rj   rk   )rj   rk   rc   rh   rJ   rX   zBB )msg)	r   r   countget	functionsrC   blocksr   r<   )r   r   r@   r>   dr   vsn_increfn_decrefstatsdec_bbfr   texts                 r   checkTestRefPrunePass.check   s1   
 01[[]EAxx)Hxx)H&;AD # 	HA||Ah1$&kFIh'1,' * " Avv 
 ((BggJEr7Dzz,/Hzz,/HU8_hc"JGU8_hc"JG r   c                     U" 5       u  p#nU R                  X#5      nU R                  U5      nU R                  XdU5        g r
   )r   r   r   )r   r=   r>   r?   r@   r   outmods          r   r   TestRefPrunePass.generate_test   s<    !)h  .$$U+

6U+r   r   N)r   r   r3   r4   r   rT   rY   r`   re   r   r   r   r   r!   rC   r   rD   r5   r   r   r   rG   rG   0   sQ    77554lH>, %]3
d 4r   rG   c                   &    \ rS rSrSrSrSS jrSrg)BaseTestByIR   r   zG
declare void @NRT_incref(i8* %ptr)
declare void @NRT_decref(i8* %ptr)
Nc                    [         R                  " U R                   SU 35      nU R                  5       nUR	                  5       nUc  UR                  U R                  5        OUR                  U R                  US9  [         R                  " 5       nUR                  X45        [         R                  " 5       nX7U-
  4$ )N
subgraph_limit)	r(   r   prologuer1   r   r   refprune_bitmaskdump_refprune_statsr;   )r   r   r   r   r1   r   beforeafters           r   r   BaseTestByIR.check   s    !!T]]O2eW"=>WWY$$&!  !6!67  !6!60> ! @))+
s((*FN""r   r   r
   )r   r   r3   r4   r   r   r   r5   r   r   r   r   r      s    H
#r   r   c                   h    \ rS rSr\R
                  R                  rSrS r	Sr
S rSrS rSrS	 rS
rg)	TestPerBB   zv
define void @main(i8* %ptr) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g Nrm   )r   per_bb_ir_1r<   
basicblockr   r   r   s      r   test_per_bb_1TestPerBB.test_per_bb_1   s.    ZZ 0 01
))1-r   z
define void @main(i8* %ptr) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                     U R                  U R                  5      u  pU R                  UR                  S5        U R	                  S[        U5      5        g )N   zcall void @NRT_incref(ptr %ptr))r   per_bb_ir_2r<   r   assertInr   r   s      r   test_per_bb_2TestPerBB.test_per_bb_2   sA    ZZ 0 01
))1-7SBr   z
define void @main(ptr %ptr, ptr %other) {
    call void @NRT_incref(ptr %ptr)
    call void @NRT_incref(ptr %ptr)
    call void @NRT_decref(ptr %ptr)
    call void @NRT_decref(ptr %other)
    ret void
}
c                     U R                  U R                  5      u  pU R                  UR                  S5        U R	                  S[        U5      5        g )Nrm   !call void @NRT_decref(ptr %other))r   per_bb_ir_3r<   r   r   r   r   s      r   test_per_bb_3TestPerBB.test_per_bb_3   A    ZZ 0 01
))1-93s8Dr   z
; reordered
define void @main(ptr %ptr, ptr %other) {
    call void @NRT_incref(ptr %ptr)
    call void @NRT_decref(ptr %ptr)
    call void @NRT_decref(ptr %ptr)
    call void @NRT_decref(ptr %other)
    call void @NRT_incref(ptr %ptr)
    ret void
}
c                     U R                  U R                  5      u  pU R                  UR                  S5        U R	                  S[        U5      5        g )Nr   r   )r   per_bb_ir_4r<   r   r   r   r   s      r   test_per_bb_4TestPerBB.test_per_bb_4  r   r   r   N)r   r   r3   r4   r(   RefPruneSubpassesPER_BBr   r   r   r   r   r   r   r   r   r5   r   r   r   r   r      sG    --44K.	KCKE
KEr   r   c                   r    \ rS rSr\R
                  R                  rSrS r	Sr
S rSrS rSrS	 rS
rS rSrg)TestDiamondi  z
define void @main(i8* %ptr) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br label %bb_B
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   per_diamond_1r<   diamondr   s      r   test_per_diamond_1TestDiamond.test_per_diamond_1  ,    ZZ 2 23
*r   z
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    br label %bb_D
bb_C:
    br label %bb_D
bb_D:
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   per_diamond_2r<   r   r   s      r   test_per_diamond_2TestDiamond.test_per_diamond_2,  r   r   a3  
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    br label %bb_D
bb_C:
    call void @NRT_decref(i8* %ptr)  ; reject because of decref in diamond
    br label %bb_D
bb_D:
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g Nr   )r   per_diamond_3r<   r   r   s      r   test_per_diamond_3TestDiamond.test_per_diamond_3@  r   r   a5  
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_incref(i8* %ptr)     ; extra incref will not affect prune
    br label %bb_D
bb_C:
    br label %bb_D
bb_D:
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   per_diamond_4r<   r   r   s      r   test_per_diamond_4TestDiamond.test_per_diamond_4T  r   r   a0  
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    br label %bb_D
bb_C:
    br label %bb_D
bb_D:
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g )Nr   )r   per_diamond_5r<   r   r   s      r   test_per_diamond_5TestDiamond.test_per_diamond_5i  r   r   r   N)r   r   r3   r4   r(   r   DIAMONDr   r   r   r   r   r   r   r   r   r   r   r5   r   r   r   r   r     sP    --55	M+M+M +M +M"+r   r   c                   h    \ rS rSrSr\R                  R                  rSr	S r
SrS rSrS rS	 rS
rg)
TestFanoutin  z6More complex cases are tested in TestRefPrunePass
    z
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret void
bb_C:
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g )N   )r   fanout_1r<   fanoutr   s      r   test_fanout_1TestFanout.test_fanout_1  *    ZZ.
q)r   a6  
define void @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret void
bb_C:
    call void @NRT_decref(i8* %ptr)
    br label %bb_B                      ; illegal jump to other decref
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_2r<   r   r   s      r   test_fanout_2TestFanout.test_fanout_2  r   r   a}  
define void @main(i8* %ptr, i1 %cond) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
bb_C:
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g )N   r   fanout_3r<   r   r   s      r   test_fanout_3TestFanout.test_fanout_3  r   r   c                 t    U R                  U R                  SS9u  pU R                  UR                  S5        g )Nrc   r   r   r  r   s      r   test_fanout_3_limited TestFanout.test_fanout_3_limited  s0     ZZaZ@
q)r   r   N)r   r   r3   r4   r   r(   r   FANOUTr   r   r   r  r  r  r  r  r5   r   r   r   r   r   n  sD     --44H*H*H$**r   r   c                   |    \ rS rSr\R
                  R                  rSrS r	Sr
S rSrS rSrS	 rS
rS rSrS rSrg)TestFanoutRaisei  a'  
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret i32 0
bb_C:
    store i8* null, i8** %excinfo, !numba_exception_output !0
    ret i32 1
}
!0 = !{i1 true}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_raise_1r<   fanout_raiser   s      r   test_fanout_raise_1#TestFanoutRaise.test_fanout_raise_1  .    ZZ 3 34
++Q/r   a:  
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret i32 0
bb_C:
    store i8* null, i8** %excinfo, !numba_exception_typo !0      ; bad metadata
    ret i32 1
}

!0 = !{i1 true}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_raise_2r<   r  r   s      r   test_fanout_raise_2#TestFanoutRaise.test_fanout_raise_2  s0     ZZ 3 34
++Q/r   a:  
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    ret i32 0
bb_C:
    store i8* null, i8** %excinfo, !numba_exception_output !0
    ret i32 1
}

!0 = !{i32 1}       ; ok; use i32
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_raise_3r<   r  r   s      r   test_fanout_raise_3#TestFanoutRaise.test_fanout_raise_3  r  r   a!  
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    ret i32 1    ; BAD; all tails are raising without decref
bb_C:
    ret i32 1    ; BAD; all tails are raising without decref
}

!0 = !{i1 1}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_raise_4r<   r  r   s      r   test_fanout_raise_4#TestFanoutRaise.test_fanout_raise_4  r  r   a  
define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    br label %common.ret
bb_C:
    store i8* null, i8** %excinfo, !numba_exception_output !0
    br label %common.ret
common.ret:
    %common.ret.op = phi i32 [ 0, %bb_B ], [ 1, %bb_C ]
    ret i32 %common.ret.op
}
!0 = !{i1 1}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g r   )r   fanout_raise_5r<   r  r   s      r   test_fanout_raise_5#TestFanoutRaise.test_fanout_raise_5  r  r   af  
define i32 @main(i8* %ptr, i1 %cond1, i1 %cond2, i1 %cond3, i8** %excinfo) {
bb_A:
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    br i1 %cond1, label %bb_B, label %bb_C
bb_B:
    call void @NRT_decref(i8* %ptr)
    br i1 %cond2, label %bb_D, label %bb_E
bb_C:
    store i8* null, i8** %excinfo, !numba_exception_output !0
    ret i32 1
bb_D:
    call void @NRT_decref(i8* %ptr)
    ret i32 0
bb_E:
    call void @NRT_incref(i8* %ptr)
    br i1 %cond3, label %bb_F, label %bb_C
bb_F:
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret i32 0
}
!0 = !{i1 1}
c                 v    U R                  U R                  5      u  pU R                  UR                  S5        g )N   )r   fanout_raise_6r<   r  r   s      r   test_fanout_raise_6#TestFanoutRaise.test_fanout_raise_68  r  r   r   N)r   r   r3   r4   r(   r   FANOUT_RAISEr   r  r  r  r  r  r  r  r   r#  r$  r(  r)  r5   r   r   r   r  r    s\    --::N0N 0N 0N0N$0
N40r   r  __main__)unittestcollectionsr   llvmliter   r   r(   llvmlite.testsr   llvmlite.tests.refprune_prototestsrefprune_protor   r!   r#   r7   r_   
as_pointerrO   rG   r   r   r   r   r  r   rh   r   r   r   <module>r5     s     #  $ # - -	-1 1H  
A	!	!	#~x!1 ~B#8- #.@E @EF`+, `+FD* D*NE0l E0P zMMO r   