o
    i@                     @   sL  d Z ddlZddlZ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ZmZmZ ddlmZmZ dd	lmZ eeZd
d ZG d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!d d! Z"d"d# Z#G d$d% d%Z$G d&d' d'e$Z%G d(d) d)Z&G d*d+ d+e$Z'G d,d- d-e$Z(d.d/ Z)dS )0a  
Implement Dominance-Fronter-based SSA by Choi et al described in Inria SSA book

References:

- Static Single Assignment Book by Inria
  http://ssabook.gforge.inria.fr/latest/book.pdf
- Choi et al. Incremental computation of static single assignment form.
    N)reduce)copy)defaultdict)config)irir_utilserrors)
OrderedSet_lazy_pformat)compute_cfg_from_blocksc                 C   s   t | j| _| S )znApply SSA reconstruction algorithm on the given IR.

    Produces minimal SSA using Choi et al algorithm.
    )_run_ssablocks)func_ir r   K/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/numba/core/ssa.pyreconstruct_ssa   s   r   c                   @   s   e Zd Zdd Zdd ZdS )_CacheListVarsc                 C   s
   i | _ d S N)_savedselfr   r   r   __init__%      
z_CacheListVars.__init__c                 C   s*   | j |}|d u r|  | j |< }|S r   )r   get	list_vars)r   instgotr   r   r   r   (   s   z_CacheListVars.getN)__name__
__module____qualname__r   r   r   r   r   r   r   $   s    r   c                 C   s   | si S t | }t|}t| |}t }|D ] }td| t| |\} }tdt| t| |||||} qt | }||krDt	
d| S )z7Run SSA reconstruction on IR blocks of a function.
    zFix SSA violator on var %szReplaced assignments: %szCFG mutated in SSA pass)r   _iterated_domfronts_find_defs_violatorsr   _loggerdebug_fresh_varsr
   _fix_ssa_varsr   CompilerError)r   cfgdf_plus	violatorscache_list_varsvarnamedefmapcfg_postr   r   r   r   /   s&   

r   c                 C   sx   t | }||d< ||d< tt |d< }||d< t|||d< t| |t|}| D ]\}	}
||	 }|
|j |_q+|S )z=Rewrite all uses to ``varname`` given the definition map
    r+   r,   phimapr'   phi_locations)_make_statesr   list_compute_phi_locations_run_block_rewrite_FixSSAVarsitemsbody)r   r+   r,   r'   r(   r*   statesr.   	newblockslabelphilistcurblkr   r   r   r%   S   s   r%   c                    sp   dd |    D  d}|r6d}  D ]\}}ttj fdd|D t }||r3||O }d}q|s S )zCompute the iterated dominance frontiers (DF+ in literatures).

    Returns a dictionary which maps block label to the set of labels of its
    iterated dominance frontiers.
    c                 S   s   i | ]	\}}|t |qS r   )set.0kvsr   r   r   
<dictcomp>k   s    z'_iterated_domfronts.<locals>.<dictcomp>TFc                    s   g | ]} | qS r   r   )r>   v	domfrontsr   r   
<listcomp>p       z'_iterated_domfronts.<locals>.<listcomp>)dominance_frontierr5   r   operatoror_r<   
difference)r'   
keep_goingr?   r@   innerr   rC   r   r    e   s   
r    c                 C   s,   t  }| D ]\}}|r|| | O }q|S r   )r<   r5   )iterated_dfr,   r/   deflabeldefstmtsr   r   r   r2   w   s   r2   c                 C   s6   t | }||d< tt |d< }t| |t }||fS )z(Rewrite to put fresh variable names
    r+   r,   )r0   r   r1   r3   _FreshVarHandler)r   r+   r7   r,   r8   r   r   r   r$      s
   r$   c                 C   s   |   ^}}|jS r   )valuesscope)r   first_r   r   r   
_get_scope   s   rU   c                 C   s   t t}t t}t||d}t| |t  tdt| t	dd |
 D }| }|
 D ]&\}}||vrV|D ]}	||	 }
dd || D }||
sU||  nq:q0tdt| |S )zm
    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    )defsuseszdefs %sc                 S   s    g | ]\}}t |d kr|qS )   )lenr=   r   r   r   rE      s     z(_find_defs_violators.<locals>.<listcomp>c                 S   s   h | ]\}}|qS r   r   )r>   _assignr9   r   r   r   	<setcomp>   rF   z'_find_defs_violators.<locals>.<setcomp>zSSA violators %s)r   r1   r<   dict_run_block_analysis_GatherDefsHandlerr"   r#   r
   r	   r5   
dominatorsintersectionadd)r   r'   rV   rW   r7   r)   domsr?   
use_blocksr9   dom
def_labelsr   r   r   r!      s&   

r!   c                 C   s<   |   D ]\}}td| ||d< t|||D ]}qqd S )Nz"==== SSA block analysis pass on %sr9   )r5   r"   r#   _run_ssa_block_pass)r   r7   handlerr9   blkrT   r   r   r   r]      s   r]   c           	      C   s   i }|   D ]8\}}td| tj|j|jd}g }||d< ||d< t|||D ]}|d us1J || q)||_	|||< q|S )Nz!==== SSA block rewrite pass on %s)rR   locr9   block)
r5   r"   r#   r   BlockrR   ri   rf   appendr6   )	r   r7   rg   r8   r9   rh   newblknewbodystmtr   r   r   r3      s   
r3   c                 C   s   t t| dS )N)rR   )r\   rU   )r   r   r   r   r0      s   r0   c                 c   sr    t d| |jD ],}t d| t|tjr|| |}n|| |}||ur3|d ur3t d| |V  q
d S )Nz
Running %szon stmt: %szreplaced with: %s)r"   r#   r6   
isinstancer   Assign	on_assignon_other)r7   rh   rg   ro   retr   r   r   rf      s   
rf   c                   @       e Zd ZdZdd Zdd ZdS )_BaseHandlerzGA base handler for all the passes used here for the SSA algorithm.
    c                 C      dS )a  
        Called when the pass sees an ``ir.Assign``.

        Subclasses should override this for custom behavior

        Parameters
        -----------
        states : dict
        assign : numba.ir.Assign

        Returns
        -------
        stmt : numba.ir.Assign or None
            For rewrite passes, the return value is used as the replacement
            for the given statement.
        Nr   )r   r7   assignr   r   r   rr          z_BaseHandler.on_assignc                 C   rw   )a  
        Called when the pass sees an ``ir.Stmt`` that's not an assignment.

        Subclasses should override this for custom behavior

        Parameters
        -----------
        states : dict
        assign : numba.ir.Stmt

        Returns
        -------
        stmt : numba.ir.Stmt or None
            For rewrite passes, the return value is used as the replacement
            for the given statement.
        Nr   r   r7   ro   r   r   r   rs      ry   z_BaseHandler.on_otherNr   r   r   __doc__rr   rs   r   r   r   r   rv      s    rv   c                   @   ru   )r^   aZ  Find all defs and uses of variable in each block

    ``states["label"]`` is a int; label of the current block
    ``states["defs"]`` is a Mapping[str, List[Tuple[ir.Assign, int]]]:
        - a mapping of the name of the assignee variable to the assignment
          IR node and the block label.
    ``states["uses"]`` is a Mapping[Set[int]]
    c                 C   sX   |d |j j ||d f | D ]}|j}||j jkr)|d | |d  qd S )NrV   r9   rW   )targetnamerl   r   ra   )r   r7   rx   varr?   r   r   r   rr     s   z_GatherDefsHandler.on_assignc                 C   s.   |  D ]}|j}|d | |d  qd S )NrW   r9   )r   r~   ra   )r   r7   ro   r   r?   r   r   r   rs     s   z_GatherDefsHandler.on_otherNr{   r   r   r   r   r^     s    	r^   c                   @   s   e Zd Zdd ZejZdS )UndefinedVariablec                 C   s   t d)NzNot intended for instantiation)NotImplementedErrorr   r   r   r   r     s   zUndefinedVariable.__init__N)r   r   r   r   r   	UNDEFINEDr}   r   r   r   r   r     s    
r   c                   @   ru   )rP   z9Replaces assignment target with new fresh variables.
    c                 C   s   |j j|d krU|d }|d }t|dkr8|j }td| |j|jvr7d|jd}ttj	||j
d n
|j|j j|j
d}tj||j|j
d	}||d
  | |S )Nr+   rR   r,   r   zfirst assign: %sz	variable z is not in scope.ri   r}   valueri   r9   )r}   r~   rY   r"   r#   	localvarswarningswarnr   NumbaIRAssumptionWarningri   redefiner   rq   r   rl   )r   r7   rx   rR   r,   	newtargetwmsgr   r   r   rr   &  s(   
z_FreshVarHandler.on_assignc                 C   s   |S r   r   rz   r   r   r   rs   <  s   z_FreshVarHandler.on_otherNr{   r   r   r   r   rP   #  s    rP   c                   @   sR   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dZdS )r4   aF  Replace variable uses in IR nodes to the correct reaching variable
    and introduce Phi nodes if necessary. This class contains the core of
    the SSA reconstruction algorithm.

    See Ch 5 of the Inria SSA book for reference. The method names used here
    are similar to the names used in the pseudocode in the book.
    c                 C   s
   || _ d S r   )_cache_list_vars)r   r*   r   r   r   r   I  r   z_FixSSAVars.__init__c                 C   s   |j }t|tjrD| ||| j|j }|d urB|jtjurB|d |jj	krB|d |ji}t
|}t|| tj|j||jdS |S t|tjro| |||g}|d uro|jtjuro|d |jj	krotj|j|j|jdS |S )Nr+   r   )r   rp   r   Inst_fix_varr   r   r}   r   r~   r   r   replace_vars_innerrq   ri   Var)r   r7   rx   rhsnewdefreplmapr   r   r   rr   L  s4   z_FixSSAVars.on_assignc                 C   s`   |  ||| j|}|d ur.|jtjur.|d |jjkr.|d |ji}t|}t	|| |S )Nr+   )
r   r   r   r}   r   r   r~   r   r   replace_vars_stmt)r   r7   ro   r   r   r   r   r   rs   k  s   z_FixSSAVars.on_otherc                 C   s.   dd |D }|d }||v r|  ||S dS )z0Fix all variable uses in ``used_vars``.
        c                 S   s   g | ]}|j qS r   )r~   )r>   r?   r   r   r   rE   y  s    z(_FixSSAVars._fix_var.<locals>.<listcomp>r+   N)	_find_def)r   r7   ro   	used_varsvarnamesphivarr   r   r   r   v  s
   z_FixSSAVars._fix_varc                 C   s   t d|d | d}|d }|d | }|d | }|d }| ||}t|D ]}	| j|	||d}
|
|k r;|	} n|	|v rE|d	 } nq)|du rS| j|||jd
}|S )z?Find definition of ``stmt`` for the statement ``stmt``
        zfind_def var=%r stmt=%sr+   Nr9   r,   r.   rj   )stopr   )r"   r#   _stmt_indexreversed_find_def_from_topri   )r   r7   ro   selected_defr9   
local_defs
local_phisrj   cur_posdefstmtdef_posr   r   r   r   ~  s*   z_FixSSAVars._find_defc                 C   s4  t d| |d }|d }|d }|d }||v rx|d }|d j}|j|d |d	}	tj|	tjj|d	|d
}
t d|
| || d|
 || 	|
 |
|D ]!\}}| j|||d	}t d| |
jj	|j |
jj	| qT|
S | | }||krt|d | tS t d|| | j|||d	S )zFind definition reaching block of ``label``.

        This method would look at all dominance frontiers.
        Insert phi node if necessary.
        zfind_def_from_top label %rr'   r,   r.   r/   rR   rj   r+   r   r   zinsert phi node %s at %sr   zincoming_def %szidom %s from label %s)r"   r#   ri   r   r   rq   Exprphiinsertrl   predecessors_find_def_from_bottomr   incoming_valuesr}   incoming_blocksimmediate_dominators"_warn_about_uninitialized_variabler   )r   r7   r9   ri   r'   r,   r.   r/   rR   freshvarphinodepredrT   incoming_defidomr   r   r   r     s>   
z_FixSSAVars._find_def_from_topc                 C   s<   t d| |d }|| }|r|d }|S | j|||dS )z<Find definition from within the block at ``label``.
        zfind_def_from_bottom label %rr,   r   r   )r"   r#   r   )r   r7   r9   ri   r,   rV   lastdefr   r   r   r     s   z!_FixSSAVars._find_def_from_bottomr   c                 C   s<   t t|jd| D ]}|j| |u r|  S qt|jS )zFind the positional index of the statement at ``block``.

        Assumptions:
        - no two statements can point to the same object.
        N)rangerY   r6   )r   r   rj   r   ir   r   r   r     s
   	
z_FixSSAVars._stmt_indexN)r   )r   r   r   r|   r   rr   rs   r   r   r   r   r   r   r   r   r   r4   @  s    .r4   c                 C   s(   t jrttjd|  |d d S d S )Nz Detected uninitialized variable r   )r   ALWAYS_WARN_UNINIT_VARr   r   r   NumbaWarning)r+   ri   r   r   r   r     s   r   )*r|   loggingrH   r   	functoolsr   r   collectionsr   numbar   
numba.corer   r   r   numba.core.utilsr	   r
   numba.core.analysisr   	getLoggerr   r"   r   r   r   r%   r    r2   r$   rU   r!   r]   r3   r0   rf   rv   r^   r   rP   r4   r   r   r   r   r   <module>   s@    	

$
( $