o
    V۷itT                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlm  m	Z
 d dl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)ir)binding)TestCase)opaque_pointers_enabledc                 #   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   R/home/ubuntu/vllm_env/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                   @   s   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dd Zdd ZeeD ]	\ZZee e< q2eeD ]\ZZee ed < 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_incref=      zTestRefPrunePass.make_increfc                 C   r7   )N
NRT_decrefr9   r:   r?   r   r   r   make_decrefA   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_switcherE   rC   zTestRefPrunePass.make_switcherc                 C   rF   )N   r   brancherr9   rI   r?   r   r   r   make_brancherI   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 ]\}}|||||  qqFt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_irM   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 t|}t  }|  || |S r   )r   ry   rz   ModulePassManagerr|   r,   )r   r}   r~   r   r   r   r   apply_refprune_legacy   s
   
z&TestRefPrunePass.apply_refprune_legacyc                 C   s
  i }|  D ]\}}|d}|d}||d||< q|  D ]"\}}	||rB|	d  d8  < || D ]}
||
 d  d8  < q5q |jD ]	}|jdkrO nqF|jD ]/}||j }	t|}|d}|d}| j|	d |d| d	 | j|	d |d| d	 qSd S )
NrQ   rR   )rQ   rR   rL   rO   r8   rD   zBB )msg)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   4   | \}}}|  ||}| |}| ||| d S r   )rx   r   r   r   r.   r/   r0   r1   r}   outmodr   r   r   r
         
zTestRefPrunePass.generate_testc                 C   r   r   )rx   r   r   r   r   r   r   generate_test_legacy   r   z%TestRefPrunePass.generate_test_legacy_legacyN)r   r   r)   r   rB   rE   rK   rN   rx   r   r   r   r
   r   r   r3   r   r4   r   r   r   r   r6   4   s"    6r6   c                   @   s(   e Zd ZdZdZdd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.checkc                 C   sj   t | j d| }t  }|d u r|| j n|j| j|d t  }|| t  }||| fS r   )r   ry   r   r   r|   r   r   r,   )r   r}   r   r~   r   r   r   r   r   r   check_legacy   s   
zBaseTestByIR.check_legacyr   )r   r   r)   r   r   r   r   r   r   r   r   r      s
    
r   c                   @   st   e Zd ZejjZdZdd Zdd Z	dZ
dd Zd	d
 Zer dndZdd Zdd Zer.dndZd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_1c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_bb_1_legacy   r   zTestPerBB.test_per_bb_1_legacyz
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   J   |  | j\}}| |jd tr| dt| d S | dt| d S N   zcall void @NRT_incref(ptr %ptr)zcall void @NRT_incref(i8* %ptr))r   per_bb_ir_2r-   r   r   assertInrz   r   r   r   r   test_per_bb_2  
   zTestPerBB.test_per_bb_2c                 C   r   r   )r   r   r-   r   r   r   rz   r   r   r   r   test_per_bb_2_legacy  r   zTestPerBB.test_per_bb_2_legacyz
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
}
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                 C   r   NrT   !call void @NRT_decref(ptr %other)!call void @NRT_decref(i8* %other))r   per_bb_ir_3r-   r   r   r   rz   r   r   r   r   test_per_bb_3(  r   zTestPerBB.test_per_bb_3c                 C   r   r   )r   r   r-   r   r   r   rz   r   r   r   r   test_per_bb_3_legacy2  r   zTestPerBB.test_per_bb_3_legacyz
; 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
}
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                 C   r   Nr   r   r   )r   per_bb_ir_4r-   r   r   r   rz   r   r   r   r   test_per_bb_4R  r   zTestPerBB.test_per_bb_4c                 C   r   r   )r   r   r-   r   r   r   rz   r   r   r   r   test_per_bb_4_legacy\  r   zTestPerBB.test_per_bb_4_legacyN)r   r   r)   r   RefPruneSubpassesPER_BBr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s(    



r   c                   @   sx   e Zd ZejjZdZdd Zdd Z	dZ
dd Zd	d
 ZdZdd Zdd ZdZdd Zdd ZdZd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_1u  r   zTestDiamond.test_per_diamond_1c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_diamond_1_legacyy  r   z%TestDiamond.test_per_diamond_1_legacyz
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_2c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_diamond_2_legacy  r   z%TestDiamond.test_per_diamond_2_legacya3  
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_3c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_diamond_3_legacy  r   z%TestDiamond.test_per_diamond_3_legacya5  
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_4  r   zTestDiamond.test_per_diamond_4c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_diamond_4_legacy  r   z%TestDiamond.test_per_diamond_4_legacya0  
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_5  r   zTestDiamond.test_per_diamond_5c                 C   r   r   )r   r   r-   r   r   r   r   r   test_per_diamond_5_legacy  r   z%TestDiamond.test_per_diamond_5_legacyN)r   r   r)   r   r   DIAMONDr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   g  s"    r   c                   @   sd   e Zd ZdZejjZdZdd Z	dd Z
dZdd	 Zd
d ZdZdd Zd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_1c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_1_legacy  r   zTestFanout.test_fanout_1_legacya6  
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_2c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_2_legacy  r   zTestFanout.test_fanout_2_legacya}  
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   &   | j | jdd\}}| |jd d S NrL   r   r   r   r   r   r   r   test_fanout_3_limited&     z TestFanout.test_fanout_3_limitedc                 C   r   r   r   r   r-   r   r   r   r   r   test_fanout_3_legacy,  r   zTestFanout.test_fanout_3_legacyc                 C   r   r   r   r   r   r   r   test_fanout_3_limited_legacy0  r   z'TestFanout.test_fanout_3_limited_legacyN)r   r   r)   r   r   r   FANOUTr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    r   c                   @   s   e Zd ZejjZdZdd Zdd Z	dZ
dd Zd	d
 ZdZdd Zdd ZdZdd Zdd ZdZdd Zdd ZdZd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_1I  r   z#TestFanoutRaise.test_fanout_raise_1c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_1_legacyM  r   z*TestFanoutRaise.test_fanout_raise_1_legacya:  
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_2a     z#TestFanoutRaise.test_fanout_raise_2c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_2_legacyg  r   z*TestFanoutRaise.test_fanout_raise_2_legacya:  
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_3c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_3_legacy  r   z*TestFanoutRaise.test_fanout_raise_3_legacya!  
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_4c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_4_legacy  r   z*TestFanoutRaise.test_fanout_raise_4_legacya  
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_5c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_5_legacy  r   z*TestFanoutRaise.test_fanout_raise_5_legacyaf  
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_6  r   z#TestFanoutRaise.test_fanout_raise_6c                 C   r   r   )r   r   r-   r   r   r   r   r   test_fanout_raise_6_legacy  r   z*TestFanoutRaise.test_fanout_raise_6_legacyN)r   r   r)   r   r   FANOUT_RAISEr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   7  s(    r   __main__)unittestllvmliter   r   r   llvmlite.testsr   llvmlite.tests.refprune_prototestsrefprune_protor   r   r   r   r*   rJ   
as_pointerr=   r6   r   r   r   r   r   r   rO   r   r   r   r   <module>   s,    	 $ wY #