
    sKg:                     J   d dl Z d dlmZ d dlmZ d dlmZ ddlmZ	 d Z
 G d d	e      Z ej                  d
      j                         Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zedk(  r e j,                          yy)    N)ir)binding)TestCase   )refprune_protoc              #       K    fd}t         j                  j                         D ]&  \  }}|j                  d      sd|  ||      f ( y w)Nc                 X      fd}d j                    d j                   |_        |S )Nc                      |       S N )selffngenerate_tests    `/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/llvmlite/tests/test_refprune.pywrappedz-_iterate_cases.<locals>.wrap.<locals>.wrapped   s     r**    zgenerated test for .)
__module____name____doc__)r   r   r   s   ` r   wrapz_iterate_cases.<locals>.wrap
   s)    	+/a}Mr   casetest_)proto__dict__items
startswith)r   r   kcase_fns   `   r   _iterate_casesr    	   sJ      nn**,
7<<!+tG},, -s
   ;AAc                   J    e Zd ZdZd Z ee      D ]  \  ZZe e       e<    y)TestRefPrunePrototypez-
    Test that the prototype is working.
    c                      |       \  }}}t        j                  ||      j                         }| j                  ||       y r   )r   FanoutAlgorithmrunassertEqual)r   case_gennodesedgesexpectedgots         r   r   z#TestRefPrunePrototype.generate_test   s;    !)uh##E515573'r   N)	r   r   __qualname__r   r   r    namer   localsr   r   r   r"   r"      s,    ( %]3
d 4r   r"      c                   t    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Z ee      D ]  \  ZZe e       e<    y
)TestRefPrunePassz
    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                     t        j                  t        j                         t        g      }t        j                  ||d      S )N
NRT_increfr-   r   FunctionTypeVoidTypeptr_tyFunctionr   mfntys      r   make_increfzTestRefPrunePass.make_incref/   -    r{{}vh7{{1d66r   c                     t        j                  t        j                         t        g      }t        j                  ||d      S )N
NRT_decrefr4   r5   r:   s      r   make_decrefzTestRefPrunePass.make_decref3   r>   r   c                     t        j                  t        j                  d      d      }t        j                  ||d      S )N    r   switcherr4   r   r6   IntTyper9   r:   s      r   make_switcherzTestRefPrunePass.make_switcher7   s-    rzz"~r2{{1d44r   c                     t        j                  t        j                  d      d      }t        j                  ||d      S )Nr   r   brancherr4   rE   r:   s      r   make_brancherzTestRefPrunePass.make_brancher;   s-    rzz!}b1{{1d44r   c                    t        j                         }| j                  |      }| j                  |      }| j	                  |      }| j                  |      }t        j                  t        j                         t        g      }t        j                  ||d      }	|	j                  \  }
d|
_        i }|D ]  }|	j                  |      ||<    t        j                         }|j                         D ]H  \  }}|j                  ||          ||   D ]>  }|dk(  r|j!                  ||
g       |dk(  r|j!                  ||
g       5t#        d       t%        |      }|dk(  r|j'                          |dk(  r|\  }|j)                  ||          |d	k(  r1|\  }}|j!                  |d
      }|j+                  |||   ||          |d	kD  re|j!                  |d
      }|^}}|j-                  |||         }t/        |      D ])  \  }}|j1                  |j3                  |      ||          + @t#        d       |S )Nmainr4   memincrefdecrefunreachabler   r      r   )default)r   Moduler=   rA   rG   rJ   r6   r7   r8   r9   argsr-   append_basic_block	IRBuilderr   position_at_endcallAssertionErrorlenret_voidbranchcbranchswitch	enumerateadd_casetype)r   r(   r)   r;   	incref_fn	decref_fnswitcher_fnbrancher_fnr<   r   ptrbbmapbbbuilderjump_targetsaction	n_targetsdstleftrightselheadtailswis                            r   generate_irzTestRefPrunePass.generate_ir?   s   IIK$$Q'	$$Q'	((+((+r{{}vh7[[Dv.B--b1E"I  ,,. %B##E"I.)X%LLSE2x'LLSE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                     t        j                  t        |            }t        j                         }|j	                          |j                  |       |S r   )llvmparse_assemblystrModulePassManageradd_refprune_passr%   )r   irmodmodpms       r   apply_refprunezTestRefPrunePass.apply_refpruneu   s@    !!#e*-##%

s
r   c                 t   i }|j                         D ]/  \  }}|j                  d      }|j                  d      }||d||<   1 |j                         D ]>  \  }}	|j                  |      s|	dxx   dz  cc<   ||   D ]  }
||
   dxx   dz  cc<    @ |j                  D ]  }|j                  dk(  s n j
                  D ]r  }||j                     }	t        |      }|j                  d      }|j                  d      }| j                  |	d   |d| 	       | j                  |	d   |d| 	       t y )
NrN   rO   )rN   rO   r   rL   r3   r@   zBB )msg)r   countget	functionsr-   blocksry   r&   )r   r}   r*   r(   dr   vsn_increfn_decrefstatsdec_bbfrh   texts                 r   checkzTestRefPrunePass.check|   s5   [[]EArxx)Hxx)H&(;AaD # 	HAu||Ah1$&qkFfIh'1,' * " Avv  ((BbggJEr7Dzz,/Hzz,/HU8_hc"JGU8_hc"JG r   c                      |       \  }}}| j                  ||      }| j                  |      }| j                  |||       y r   )ru   r   r   )r   r'   r(   r)   r*   r|   outmods          r   r   zTestRefPrunePass.generate_test   sB    !)uh  .$$U+

68U+r   N)r   r   r,   r   r=   rA   rG   rJ   ru   r   r   r   r    r-   r   r.   r   r   r   r1   r1   &   sQ    77554lH4, %]3
d 4r   r1   c                       e Zd ZdZdZddZy)BaseTestByIRr   zG
declare void @NRT_incref(i8* %ptr)
declare void @NRT_decref(i8* %ptr)
Nc                 h   t        j                  | j                   d|       }t        j                         }||j	                  | j
                         n|j	                  | j
                  |       t        j                         }|j                  |       t        j                         }|||z
  fS )N
subgraph_limit)rw   rx   prologuerz   r{   refprune_bitmaskdump_refprune_statsr%   )r   r|   r   r}   r~   beforeafters          r   r   zBaseTestByIR.check   s    !!T]]O2eW"=>##%!  !6!67  !6!60> ! @))+
s((*EFN""r   r   )r   r   r,   r   r   r   r   r   r   r   r      s    H
#r   r   c                   `    e Zd Zej                  j
                  ZdZd ZdZ	d Z
dZd ZdZd Zy	)
	TestPerBBzv
define void @main(i8* %ptr) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 x    | j                  | j                        \  }}| j                  |j                  d       y NrQ   )r   per_bb_ir_1r&   
basicblockr   r}   r   s      r   test_per_bb_1zTestPerBB.test_per_bb_1   s0    ZZ 0 01
U))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                     | j                  | j                        \  }}| j                  |j                  d       | j	                  dt        |             y )N   zcall void @NRT_incref(i8* %ptr))r   per_bb_ir_2r&   r   assertInry   r   s      r   test_per_bb_2zTestPerBB.test_per_bb_2   sC    ZZ 0 01
U))1-7SBr   z
define void @main(i8* %ptr, i8* %other) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %other)
    ret void
}
c                     | j                  | j                        \  }}| j                  |j                  d       | j	                  dt        |             y )NrQ   !call void @NRT_decref(i8* %other))r   per_bb_ir_3r&   r   r   ry   r   s      r   test_per_bb_3zTestPerBB.test_per_bb_3   C    ZZ 0 01
U))1-93s8Dr   z
; reordered
define void @main(i8* %ptr, i8* %other) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    call void @NRT_decref(i8* %other)
    call void @NRT_incref(i8* %ptr)
    ret void
}
c                     | j                  | j                        \  }}| j                  |j                  d       | j	                  dt        |             y )Nr   r   )r   per_bb_ir_4r&   r   r   ry   r   s      r   test_per_bb_4zTestPerBB.test_per_bb_4   r   r   N)r   r   r,   rw   RefPruneSubpassesPER_BBr   r   r   r   r   r   r   r   r   r   r   r   r   r      sG    --44K.	KCKE
KEr   r   c                   j    e Zd Zej                  j
                  ZdZd ZdZ	d Z
dZd ZdZd Zd	Zd
 Zy)TestDiamondz
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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   per_diamond_1r&   diamondr   s      r   test_per_diamond_1zTestDiamond.test_per_diamond_1  .    ZZ 2 23
U*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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   per_diamond_2r&   r   r   s      r   test_per_diamond_2z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                 x    | j                  | j                        \  }}| j                  |j                  d       y Nr   )r   per_diamond_3r&   r   r   s      r   test_per_diamond_3z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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   per_diamond_4r&   r   r   s      r   test_per_diamond_4zTestDiamond.test_per_diamond_4C  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                 x    | j                  | j                        \  }}| j                  |j                  d       y )Nr   )r   per_diamond_5r&   r   r   s      r   test_per_diamond_5zTestDiamond.test_per_diamond_5X  r   r   N)r   r   r,   rw   r   DIAMONDr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      sP    --55	M+M+M +M +M"+r   r   c                   `    e Zd ZdZej
                  j                  ZdZd Z	dZ
d ZdZd Zd Zy	)

TestFanoutz6More 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                 x    | j                  | j                        \  }}| j                  |j                  d       y )N   )r   fanout_1r&   fanoutr   s      r   test_fanout_1zTestFanout.test_fanout_1q  ,    ZZ.
U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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_2r&   r   r   s      r   test_fanout_2z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                 x    | j                  | j                        \  }}| j                  |j                  d       y )N   r   fanout_3r&   r   r   s      r   test_fanout_3zTestFanout.test_fanout_3  r   r   c                 |    | j                  | j                  d      \  }}| j                  |j                  d       y )Nr   r   r   r   r   s      r   test_fanout_3_limitedz TestFanout.test_fanout_3_limited  s2     ZZaZ@
Uq)r   N)r   r   r,   r   rw   r   FANOUTr   r   r   r   r   r   r   r   r   r   r   r   r   ]  sD     --44H*H*H$**r   r   c                   t    e Zd Zej                  j
                  ZdZd ZdZ	d Z
dZd ZdZd Zd	Zd
 ZdZd Zy)TestFanoutRaisea'  
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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_raise_1r&   fanout_raiser   s      r   test_fanout_raise_1z#TestFanoutRaise.test_fanout_raise_1  0    ZZ 3 34
U++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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_raise_2r&   r   r   s      r   test_fanout_raise_2z#TestFanoutRaise.test_fanout_raise_2  s2     ZZ 3 34
U++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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_raise_3r&   r   r   s      r   test_fanout_raise_3z#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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_raise_4r&   r   r   s      r   test_fanout_raise_4z#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                 x    | j                  | j                        \  }}| j                  |j                  d       y r   )r   fanout_raise_5r&   r   r   s      r   test_fanout_raise_5z#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                 x    | j                  | j                        \  }}| j                  |j                  d       y )N   )r   fanout_raise_6r&   r   r   s      r   test_fanout_raise_6z#TestFanoutRaise.test_fanout_raise_6'  r   r   N)r   r   r,   rw   r   FANOUT_RAISEr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s\    --::N0N 0N 0N0N$0
N40r   r   __main__)unittestllvmliter   r   rw   llvmlite.testsr    r   r   r    r"   rF   
as_pointerr8   r1   r   r   r   r   r   r   rL   r   r   r   <module>r      s      $ # %	-H  
A	!	!	#xx xv#8 #,@E @EF`+, `+FD* D*NE0l E0P zHMMO r   