U
    9%e:                     @   sH  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 ddlmZ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)pformat)defaultdict)config)irir_utilserrors)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)Zfunc_ir r   M/var/www/html/Darija-Ai-API/env/lib/python3.8/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__%   s    z_CacheListVars.__init__c                 C   s*   | j |}|d kr&|  | j |< }|S r   )r   getZ	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rt	
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	   ZCompilerError)r   cfgdf_plus	violatorscache_list_varsvarnamedefmapZcfg_postr   r   r   r   /   s(     
r   c                 C   sx   t | }||d< ||d< tt |d< }||d< t|||d< t| |t|}| D ]\}	}
||	 }|
|j |_qV|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labelZphilistZcurblkr   r   r   r!   S   s    r!   c                    sn   dd |    D  d}|rjd}  D ]<\}}ttj fdd|D t }||r*||O }d}q*q 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   )r6   vZ	domfrontsr   r   
<listcomp>p   s     z'_iterated_domfronts.<locals>.<listcomp>)Zdominance_frontierr/   r   operatoror_r4   
difference)r"   Z
keep_goingr7   r8   innerr   r;   r   r   e   s    
r   c                 C   s,   t  }| D ]\}}|r|| | O }q|S r   )r4   r/   )Ziterated_dfr'   r)   ZdeflabelZdefstmtsr   r   r   r,   w   s
    r,   c                 C   s6   t | }||d< tt |d< }t| |t }||fS )z(Rewrite to put fresh variable names
    r&   r'   )r*   r   r+   r-   _FreshVarHandler)r   r&   r1   r'   r2   r   r   r   r       s
    r    c                 C   s   |   ^}}|jS r   )valuesscope)r   first_r   r   r   
_get_scope   s    rF   c                 C   sL   t t}t| |t  tdt| dd | D }tdt| |S )zm
    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    zdefs %sc                 S   s    h | ]\}}t |d kr|qS )   )lenr5   r   r   r   	<setcomp>   s      z'_find_defs_violators.<locals>.<setcomp>zSSA violators %s)r   r+   _run_block_analysis_GatherDefsHandlerr   r   r   r/   )r   defsr$   r   r   r   r      s    r   c                 C   s4   |   D ]&\}}td| t|||D ]}q(qd S )Nz"==== SSA block analysis pass on %s)r/   r   r   _run_ssa_block_pass)r   r1   handlerr3   blkrE   r   r   r   rJ      s    rJ   c           	      C   s   i }|   D ]p\}}td| tj|j|jd}g }||d< ||d< t|||D ]}|d k	sbt|	| qR||_
|||< q|S )Nz!==== SSA block rewrite pass on %s)rC   locr3   block)r/   r   r   r   ZBlockrC   rP   rM   AssertionErrorappendr0   )	r   r1   rN   r2   r3   rO   ZnewblkZnewbodystmtr   r   r   r-      s    
r-   c                 C   s   t t| dS )N)rC   )dictrF   )r   r   r   r   r*      s    r*   c                 c   sp   t d| |jD ]X}t d| t|tjr<|| |}n|| |}||k	rd|d k	rdt d| |V  qd S )Nz
Running %szon stmt: %szreplaced with: %s)r   r   r0   
isinstancer   Assign	on_assignon_other)r1   rO   rN   rT   retr   r   r   rM      s    
rM   c                   @   s    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   s   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   r1   assignr   r   r   rX      s    z_BaseHandler.on_assignc                 C   s   dS )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   r1   rT   r   r   r   rY      s    z_BaseHandler.on_otherNr   r   r   __doc__rX   rY   r   r   r   r   r[      s   r[   c                   @   s   e Zd ZdZdd ZdS )rK   zEFind all defs

    ``states`` is a Mapping[str, List[ir.Assign]]
    c                 C   s   ||j j | d S r   )targetnamerS   r\   r   r   r   rX      s    z_GatherDefsHandler.on_assignN)r   r   r   r`   rX   r   r   r   r   rK      s   rK   c                   @   s   e Zd Zdd ZejZdS )UndefinedVariablec                 C   s   t dd S )NzNot intended for instantiation)NotImplementedErrorr   r   r   r   r      s    zUndefinedVariable.__init__N)r   r   r   r   r   	UNDEFINEDra   r   r   r   r   rc      s   rc   c                   @   s    e Zd ZdZdd Zdd ZdS )rA   z9Replaces assignment target with new fresh variables.
    c                 C   s   |j j|d kr|d }|d }t|dkrp|j }td| |j|jkrd|jd}ttj	||j
d n|j|j j|j
d}tj||j|j
d	}||d
  | |S )Nr&   rC   r'   r   zfirst assign: %sz	variable z is not in scope.rP   ra   valuerP   r3   )ra   rb   rH   r   r   Z	localvarswarningswarnr	   ZNumbaIRAssumptionWarningrP   redefiner   rW   rh   rS   )r   r1   r]   rC   r'   Z	newtargetZwmsgr   r   r   rX     s&    

z_FreshVarHandler.on_assignc                 C   s   |S r   r   r^   r   r   r   rY     s    z_FreshVarHandler.on_otherNr_   r   r   r   r   rA     s   rA   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 )r.   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   )  s    z_FixSSAVars.__init__c                 C   s   |j }t|tjr| ||| j|j }|d k	r|jtjk	r|d |jj	kr|d |ji}t
|}t|| tj|j||jdS nVt|tjr| |||g}|d k	r|jtjk	r|d |jj	krtj|j|j|jdS |S )Nr&   rg   )rh   rV   r   ZInst_fix_varrl   r   ra   re   rb   r   r   Zreplace_vars_innerrW   rP   ZVar)r   r1   r]   rhsnewdefreplmapr   r   r   rX   ,  s6      z_FixSSAVars.on_assignc                 C   s`   |  ||| j|}|d k	r\|jtjk	r\|d |jjkr\|d |ji}t|}t	|| |S )Nr&   )
rm   rl   r   ra   r   re   rb   r   r   Zreplace_vars_stmt)r   r1   rT   ro   rp   r   r   r   rY   K  s      
z_FixSSAVars.on_otherc                 C   s.   dd |D }|d }||kr*|  ||S dS )z0Fix all variable uses in ``used_vars``.
        c                 S   s   g | ]
}|j qS r   )rb   )r6   r7   r   r   r   r<   Y  s     z(_FixSSAVars._fix_var.<locals>.<listcomp>r&   N)	_find_def)r   r1   rT   Z	used_varsvarnamesZphivarr   r   r   rm   V  s    z_FixSSAVars._fix_varc                 C   s   t d|d | d}|d }|d | }|d | }|d }| ||}t|D ]:}	| j|	||d}
|
|k rx|	} qqR|	|krR|d	 } qqR|dkr| j|||jd
}|S )z?Find definition of ``stmt`` for the statement ``stmt``
        zfind_def var=%r stmt=%sr&   Nr3   r'   r(   rQ   )stoprf   )r   r   _stmt_indexreversed_find_def_from_toprP   )r   r1   rT   Zselected_defr3   Z
local_defsZ
local_phisrQ   Zcur_posdefstmtZdef_posr   r   r   rq   ^  s,      z_FixSSAVars._find_defc                 C   s:  t d| |d }|d }|d }|d }||kr|d }|d j}|j|d |d	}	tj|	tjj|d	|d
}
t d|
| || d|
 || 	|
 |
|D ]B\}}| j|||d	}t d| |
jj	|j |
jj	| q|
S | | }||krt|d | tS t d|| | j|||d	S 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)   rC   rQ   r&   rf   rg   zinsert phi node %s at %sr   zincoming_def %szidom %s from label %sN)r   r   rP   rk   r   rW   ExprphiinsertrS   Zpredecessors_find_def_from_bottomrh   Zincoming_valuesra   Zincoming_blocksZimmediate_dominators"_warn_about_uninitialized_variablerc   )r   r1   r3   rP   r"   r'   r(   r)   rC   ZfreshvarZphinodepredrE   Zincoming_defZidomr   r   r   rw   z  sB    
  
z_FixSSAVars._find_def_from_topc                 C   s@   t d| |d }|| }|r,|d }|S | j|||dS dS )z<Find definition from within the block at ``label``.
        zfind_def_from_bottom label %rr'   rt   rf   N)r   r   rw   )r   r1   r3   rP   r'   rL   Zlastdefr   r   r   r|     s    z!_FixSSAVars._find_def_from_bottomrt   c                 C   s<   t t|jd| D ]}|j| |k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)rangerH   r0   )r   rx   rQ   rs   ir   r   r   ru     s    	
z_FixSSAVars._stmt_indexN)rt   )r   r   r   r`   r   rX   rY   rm   rq   rw   r|   ru   r   r   r   r   r.      s   .r.   c                 C   s$   t jr ttjd|  |d d S )Nz Detected uninitialized variable rf   )r   ZALWAYS_WARN_UNINIT_VARri   rj   r	   ZNumbaWarning)r&   rP   r   r   r   r}     s    r}   ))r`   loggingr=   ri   	functoolsr   r   pprintr   collectionsr   Znumbar   Z
numba.corer   r   r	   Znumba.core.analysisr
   	getLoggerr   r   r   r   r   r!   r   r,   r    rF   r   rJ   r-   r*   rM   r[   rK   rc   rA   r.   r}   r   r   r   r   <module>   s>   	

$
(	 $