o
    £¸¢i,=  ã                   @   sú   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 dl	m
  mZ dd„ ZG dd	„ d	ƒZG d
d„ deƒZe d¡ ¡ ZG dd„ deeƒZG dd„ deeƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZedkr{e  ¡  dS dS )é    N)Údefaultdict)Úir)Úbinding)ÚTestCasec                 #   sD    ‡ fdd„}t j ¡ D ]\}}| d¡rd|› ||ƒfV  qd S )Nc                    s(   ‡ ‡fdd„}dˆ j › dˆ j› |_|S )Nc                    s
   ˆ| ˆ ƒS ©N© )Úself)ÚfnÚgenerate_testr   úZ/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/llvmlite/tests/test_refprune.pyÚwrapped   s   
z-_iterate_cases.<locals>.wrap.<locals>.wrappedzgenerated test for Ú.)Ú
__module__Ú__name__Ú__doc__)r	   r   ©r
   )r	   r   Úwrap   s   z_iterate_cases.<locals>.wrapÚcaseÚtest_)ÚprotoÚ__dict__ÚitemsÚ
startswith)r
   r   ÚkÚcase_fnr   r   r   Ú_iterate_cases
   s   €
€þr   c                   @   s   e Zd Zdd„ ZdS )ÚPassManagerMixinc                 C   s0   t  ¡  t j ¡  ¡ }t jddd}t  ||¡S )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Úptor   r   r   Úpb   s   zPassManagerMixin.pbN)r   r   Ú__qualname__r(   r   r   r   r   r      s    r   c                   @   s4   e Zd ZdZdd„ ZeeƒD ]	\ZZeeƒ e< qdS )ÚTestRefPrunePrototypez-
    Test that the prototype is working.
    c                 C   s,   |ƒ \}}}t  ||¡ ¡ }|  ||¡ d S r   )r   ÚFanoutAlgorithmÚrunÚassertEqual)r   Úcase_genÚnodesÚedgesÚexpectedÚgotr   r   r   r
   #   s   z#TestRefPrunePrototype.generate_testN)	r   r   r)   r   r
   r   Únamer   Úlocalsr   r   r   r   r*      s    ÿr*   é   c                   @   sl   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ ZeeƒD ]	\ZZeeƒ e< q*dS )Ú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                 C   ó"   t  t  ¡ tg¡}t j||ddS )NÚ
NRT_incref©r3   ©r   ÚFunctionTypeÚVoidTypeÚptr_tyÚFunction©r   ÚmÚfntyr   r   r   Úmake_incref9   ó   zTestRefPrunePass.make_increfc                 C   r7   )NÚ
NRT_decrefr9   r:   r?   r   r   r   Úmake_decref=   rC   zTestRefPrunePass.make_decrefc                 C   ó"   t  t  d¡d¡}t j||ddS )Né    r   Úswitcherr9   ©r   r;   ÚIntTyper>   r?   r   r   r   Úmake_switcherA   rC   zTestRefPrunePass.make_switcherc                 C   rF   )Né   r   Úbrancherr9   rI   r?   r   r   r   Úmake_brancherE   rC   zTestRefPrunePass.make_brancherc                 C   s¶  t  ¡ }|  |¡}|  |¡}|  |¡}|  |¡}t  t  ¡ tg¡}t j	||dd}	|	j
\}
d|
_i }|D ]	}|	 |¡||< q4t  ¡ }| ¡ D ]’\}}| || ¡ || D ]}|dkrc| ||
g¡ qU|dkro| ||
g¡ qUtdƒ‚t|ƒ}|dkr€| ¡  qF|dkr|\}| || ¡ qF|d	kr©|\}}| |d
¡}| ||| || ¡ qF|d	krÕ| |d
¡}|^}}|j||| d}t|ƒD ]\}}| | |¡|| ¡ qÄqFtdƒ‚|S )NÚmainr9   ÚmemÚincrefÚdecrefÚunreachabler   rL   é   r   )Údefault)r   ÚModulerB   rE   rK   rN   r;   r<   r=   r>   Úargsr3   Úappend_basic_blockÚ	IRBuilderr   Úposition_at_endÚcallÚAssertionErrorÚlenÚret_voidÚbranchÚcbranchÚswitchÚ	enumerateÚadd_caseÚtype)r   r/   r0   r@   Ú	incref_fnÚ	decref_fnÚswitcher_fnÚbrancher_fnrA   r	   ÚptrÚbbmapÚbbÚbuilderÚjump_targetsÚactionÚ	n_targetsÚdstÚleftÚrightÚselÚheadÚtailÚswÚir   r   r   Úgenerate_irI   sP   




ÿzTestRefPrunePass.generate_irc                 C   s6   t  t|ƒ¡}|  ¡ }| ¡ }| ¡  | ||¡ |S r   )r   Úparse_assemblyÚstrr(   ÚgetModulePassManagerÚadd_refprune_passr,   )r   ÚirmodÚmodr(   Úpmr   r   r   Úapply_refprune   s   zTestRefPrunePass.apply_refprunec                 C   s  t dd„ ƒ}| ¡ D ]\}}| d¡}| d¡}||dœ||< q
| ¡ D ]"\}}	| |¡rF|	d  d8  < || D ]}
||
 d  d8  < q9q$|jD ]	}|jdkrS nqJ|jD ]/}||j }	t|ƒ}| d¡}| d	¡}| j|	d |d
|› d | j|	d |d
|› d qWd S )Nc                   S   s   t tƒS r   )r   Úintr   r   r   r   Ú<lambda>Œ   s    z(TestRefPrunePass.check.<locals>.<lambda>rQ   rR   )rQ   rR   rL   rO   r8   rD   zBB )Úmsg)	r   r   ÚcountÚgetÚ	functionsr3   Úblocksrz   r-   )r   r~   r1   r/   Údr   ÚvsÚn_increfÚn_decrefÚstatsÚdec_bbÚfrk   Útextr   r   r   Úcheck‡   s.   


€

ÿ



úzTestRefPrunePass.checkc                 C   s4   |ƒ \}}}|   ||¡}|  |¡}|  |||¡ d S r   )rx   r€   r   )r   r.   r/   r0   r1   r}   Úoutmodr   r   r   r
   ¦   s   
zTestRefPrunePass.generate_testN)r   r   r)   r   rB   rE   rK   rN   rx   r€   r   r
   r   r3   r   r4   r   r   r   r   r6   0   s    6ÿr6   c                   @   s   e Zd ZdZdZddd„ZdS )ÚBaseTestByIRr   zG
declare void @NRT_incref(i8* %ptr)
declare void @NRT_decref(i8* %ptr)
Nc                 C   st   t  | j› d|› ¡}|  ¡ }| ¡ }|d u r| | j¡ n|j| j|d t  ¡ }| ||¡ t  ¡ }||| fS )NÚ
©Úsubgraph_limit)	r   ry   Úprologuer(   r{   r|   Úrefprune_bitmaskÚdump_refprune_statsr,   )r   r}   r•   r~   r(   r   ÚbeforeÚafterr   r   r   r   ¹   s   ÿzBaseTestByIR.checkr   )r   r   r)   r—   r–   r   r   r   r   r   r’   ±   s    r’   c                   @   sD   e Zd ZejjZdZdd„ ZdZ	dd„ Z
dZdd	„ Zd
Zdd„ ZdS )Ú	TestPerBBzv
define void @main(i8* %ptr) {
    call void @NRT_incref(i8* %ptr)
    call void @NRT_decref(i8* %ptr)
    ret void
}
c                 C   ó"   |   | j¡\}}|  |jd¡ d S ©NrT   )r   Úper_bb_ir_1r-   Ú
basicblock©r   r~   rŒ   r   r   r   Útest_per_bb_1Ó   ó   zTestPerBB.test_per_bb_1zâ
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                 C   ó2   |   | j¡\}}|  |jd¡ |  dt|ƒ¡ d S )Né   zcall void @NRT_incref(ptr %ptr))r   Úper_bb_ir_2r-   rŸ   ÚassertInrz   r    r   r   r   Útest_per_bb_2â   ó   zTestPerBB.test_per_bb_2zÌ
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                 C   r£   )NrT   ú!call void @NRT_decref(ptr %other))r   Úper_bb_ir_3r-   rŸ   r¦   rz   r    r   r   r   Útest_per_bb_3ò   r¨   zTestPerBB.test_per_bb_3zü
; 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                 C   r£   )Nr¤   r©   )r   Úper_bb_ir_4r-   rŸ   r¦   rz   r    r   r   r   Útest_per_bb_4  r¨   zTestPerBB.test_per_bb_4N)r   r   r)   r   ÚRefPruneSubpassesÚPER_BBr—   rž   r¡   r¥   r§   rª   r«   r¬   r­   r   r   r   r   r›   È   s    
r›   c                   @   sP   e Zd ZejjZdZdd„ ZdZ	dd„ Z
dZdd	„ Zd
Zdd„ ZdZdd„ ZdS )Ú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                 C   rœ   r   )r   Úper_diamond_1r-   Údiamondr    r   r   r   Útest_per_diamond_1  r¢   zTestDiamond.test_per_diamond_1zè
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                 C   rœ   r   )r   Úper_diamond_2r-   r²   r    r   r   r   Útest_per_diamond_2,  r¢   zTestDiamond.test_per_diamond_2a3  
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                 C   rœ   ©Nr   )r   Úper_diamond_3r-   r²   r    r   r   r   Útest_per_diamond_3@  r¢   zTestDiamond.test_per_diamond_3a5  
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                 C   rœ   r   )r   Úper_diamond_4r-   r²   r    r   r   r   Útest_per_diamond_4T  r¢   zTestDiamond.test_per_diamond_4a0  
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                 C   rœ   )Nr¤   )r   Úper_diamond_5r-   r²   r    r   r   r   Útest_per_diamond_5i  r¢   zTestDiamond.test_per_diamond_5N)r   r   r)   r   r®   ÚDIAMONDr—   r±   r³   r´   rµ   r·   r¸   r¹   rº   r»   r¼   r   r   r   r   r°     s    r°   c                   @   sD   e Zd ZdZejjZdZdd„ Z	dZ
dd„ ZdZd	d
„ Zdd„ ZdS )Ú
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                 C   rœ   )Né   )r   Úfanout_1r-   Úfanoutr    r   r   r   Útest_fanout_1‚  r¢   zTestFanout.test_fanout_1a6  
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                 C   rœ   r¶   )r   Úfanout_2r-   rÁ   r    r   r   r   Útest_fanout_2”  r¢   zTestFanout.test_fanout_2a}  
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                 C   rœ   )Né   ©r   Úfanout_3r-   rÁ   r    r   r   r   Útest_fanout_3ª  r¢   zTestFanout.test_fanout_3c                 C   s&   | j | jdd\}}|  |jd¡ d S )NrL   r”   r   rÆ   r    r   r   r   Útest_fanout_3_limited®  s   z TestFanout.test_fanout_3_limitedN)r   r   r)   r   r   r®   ÚFANOUTr—   rÀ   rÂ   rÃ   rÄ   rÇ   rÈ   rÉ   r   r   r   r   r¾   n  s    r¾   c                   @   s\   e Zd ZejjZdZdd„ ZdZ	dd„ Z
dZdd	„ Zd
Zdd„ ZdZdd„ ZdZdd„ ZdS )Ú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                 C   rœ   r   )r   Úfanout_raise_1r-   Úfanout_raiser    r   r   r   Útest_fanout_raise_1Ç  r¢   z#TestFanoutRaise.test_fanout_raise_1a:  
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                 C   rœ   r¶   )r   Úfanout_raise_2r-   rÍ   r    r   r   r   Útest_fanout_raise_2Û  s   z#TestFanoutRaise.test_fanout_raise_2a:  
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                 C   rœ   r   )r   Úfanout_raise_3r-   rÍ   r    r   r   r   Útest_fanout_raise_3ñ  r¢   z#TestFanoutRaise.test_fanout_raise_3a!  
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                 C   rœ   r¶   )r   Úfanout_raise_4r-   rÍ   r    r   r   r   Útest_fanout_raise_4  r¢   z#TestFanoutRaise.test_fanout_raise_4a™  
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                 C   rœ   r   )r   Úfanout_raise_5r-   rÍ   r    r   r   r   Útest_fanout_raise_5  r¢   z#TestFanoutRaise.test_fanout_raise_5af  
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                 C   rœ   )Né   )r   Úfanout_raise_6r-   rÍ   r    r   r   r   Útest_fanout_raise_68  r¢   z#TestFanoutRaise.test_fanout_raise_6N)r   r   r)   r   r®   ÚFANOUT_RAISEr—   rÌ   rÎ   rÏ   rÐ   rÑ   rÒ   rÓ   rÔ   rÕ   rÖ   rØ   rÙ   r   r   r   r   rË   µ  s    rË   Ú__main__)ÚunittestÚcollectionsr   Úllvmliter   r   r   Úllvmlite.testsr   Úllvmlite.tests.refprune_protoÚtestsÚrefprune_protor   r   r   r*   rJ   Ú
as_pointerr=   r6   r’   r›   r°   r¾   rË   r   rO   r   r   r   r   Ú<module>   s*    	 CcG 	ÿ