U
    ?hÊ  ã                   @   st   d Z ddlZddlmZmZ ddlmZ ddlm	Z	 e 
d¡Ze 
d¡Ze 
d d	d
ddg¡¡Zdd„ Zdd„ ZdS )z
NRT specific optimizations
é    N)ÚdefaultdictÚdeque)Úbinding)Úcgutilsz,\s*(?:tail)?\s*call void @NRT_incref\((.*)\)z,\s*(?:tail)?\s*call void @NRT_decref\((.*)\)ú|z[0-9]+:z,[\'"]?[-a-zA-Z$._0-9][-a-zA-Z$._0-9]*[\'"]?:z^definez^;\s*<label>c                    s|   dd„ }‡‡fdd„}dd„ ‰‡‡fdd„‰d	d
„ ‰ ‡ fdd„‰dd„ ‰g }|| ƒD ]\}}|rh||ƒ}||7 }qTd  |¡S )Nc                 s   s€   g }t | ƒ ¡ D ]j}| d¡r2|r&t‚| |¡ q| d¡r^|sDt‚| |¡ d|fV  g }q|rn| |¡ qd|gfV  qd S )NÚdefineÚ}TF)ÚstrÚ
splitlinesÚ
startswithÚAssertionErrorÚappend)ÚmoduleÚcurÚline© r   úK/var/www/html/venv/lib/python3.8/site-packages/numba/core/runtime/nrtopt.pyÚ_extract_functions   s    



z7_remove_redundant_nrt_refct.<locals>._extract_functionsc                    s2   g }ˆ | ƒD ] \}}|r$|r$ˆ|ƒ}||7 }q|S ©Nr   )Ú
func_linesÚoutZis_bbÚbb_lines)Ú_extract_basic_blocksÚ_process_basic_blockr   r   Ú_process_function/   s    
z6_remove_redundant_nrt_refct.<locals>._process_functionc                 s   s¤   | d   d¡st‚| d   d¡s$t‚d| d gfV  g }| dd… D ]@}t |¡}|d k	rvd|fV  g }d|gfV  qD|rD| |¡ qDd|fV  d| d gfV  d S )Nr   r   éÿÿÿÿr   Fé   T)r   r   Ú	_regex_bbÚmatchr   )r   r   ÚlnÚmr   r   r   r   7   s    


z:_remove_redundant_nrt_refct.<locals>._extract_basic_blocksc                    s   ˆ | ƒ} ˆ| ƒ} | S r   r   )r   )Ú(_move_and_group_decref_after_all_increfsÚ_prune_redundant_refct_opsr   r   r   J   s    z9_remove_redundant_nrt_refct.<locals>._process_basic_blockc                 s   sn   t | ƒD ]`\}}t |¡}|d k	r6|| d¡d fV  qt |¡}|d k	r\|d | d¡fV  q|d d fV  qd S )Nr   )Ú	enumerateÚ_regex_increfr   ÚgroupÚ_regex_decref)r   Únumr   r    r   r   r   Ú_examine_refct_opO   s    

z6_remove_redundant_nrt_refct.<locals>._examine_refct_opc                    sð   t tƒ}t tƒ}tƒ ‰ ˆ| ƒD ]d\}}}|r4|r4t‚|r\|dkrLˆ  |¡ q‚||  |¡ q|r|dkrtˆ  |¡ q||  |¡ q| ¡ D ]L\}}|| }tt|ƒt|ƒƒ}	t	|	ƒD ] }
ˆ  | 
¡ ¡ ˆ  | ¡ ¡ q¶qŒ‡ fdd„t| ƒD ƒS )Nzi8* nullc                    s   g | ]\}}|ˆ kr|‘qS r   r   )Ú.0r'   r   ©Z	to_remover   r   Ú
<listcomp>u   s    ÿzS_remove_redundant_nrt_refct.<locals>._prune_redundant_refct_ops.<locals>.<listcomp>)r   r   Úsetr   Úaddr   ÚitemsÚminÚlenÚrangeÚpopÚpopleftr#   )r   Z
incref_mapZ
decref_mapr'   Z
incref_varZ
decref_varÚvarZdecopsZincopsÚctÚ_)r(   r*   r   r"   ]   s(    z?_remove_redundant_nrt_refct.<locals>._prune_redundant_refct_opsc                 S   s´   d}t | ƒD ]\}}t |¡d k	r|d }qd}t | ƒD ]\}}t |¡d k	r8|d }q8t||ƒ}g }g }| d |… D ](}t |¡d k	r”| |¡ qv| |¡ qv|| | |d …  S )Nr   r   )r#   r$   r   r&   Úmaxr   )r   Zlast_incref_posÚposr   Zlast_decref_posZlast_posZdecrefsÚheadr   r   r   r!   x   s     


zM_remove_redundant_nrt_refct.<locals>._move_and_group_decref_after_all_increfsÚ
)Újoin)Zllvmirr   r   Ú	processedZis_funcÚlinesr   )r(   r   r!   r   r"   r   Ú_remove_redundant_nrt_refct   s    
r>   c                 C   sT   z|   d¡ W n tk
r&   |  Y S X | j}tt| ƒƒ}t |¡}t |¡|_|S )a¼  
    Remove redundant reference count operations from the
    `llvmlite.binding.ModuleRef`. This parses the ll_module as a string and
    line by line to remove the unnecessary nrt refct pairs within each block.
    Decref calls are moved after the last incref call in the block to avoid
    temporarily decref'ing to zero (which can happen due to hidden decref from
    alias).

    Note: non-threadsafe due to usage of global LLVMcontext
    Z
NRT_incref)	Zget_functionÚ	NameErrorÚnamer>   r	   ÚllZparse_assemblyr   Znormalize_ir_text)Z	ll_moduler@   ZnewllÚnew_modr   r   r   Úremove_redundant_nrt_refctŸ   s    

rC   )Ú__doc__ÚreÚcollectionsr   r   Zllvmliter   rA   Z
numba.corer   Úcompiler$   r&   r;   r   r>   rC   r   r   r   r   Ú<module>   s"   

øÿ 