
    ܙd:                        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j        e          Zd
 Z G d d          Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z" G d d          Z# G d de#          Z$ G d d          Z% G d de#          Z& G d  d!e#          Z'd" Z(dS )#a  
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                 8    t          | j                  | _        | S )znApply SSA reconstruction algorithm on the given IR.

    Produces minimal SSA using Choi et al algorithm.
    )_run_ssablocks)func_irs    .lib/python3.11/site-packages/numba/core/ssa.pyreconstruct_ssar      s    
 gn--GNN    c                       e Zd Zd Zd ZdS )_CacheListVarsc                     i | _         d S N)_savedselfs    r   __init__z_CacheListVars.__init__%   s    r   c                 z    | j                             |          }||                                x| j         |<   }|S r   )r   get	list_vars)r   instgots      r   r   z_CacheListVars.get(   s:    kood##;&*nn&6&66DK
r   N)__name__
__module____qualname__r   r    r   r   r   r   $   s2              r   r   c           	         | si S t          |           }t          |          }t          |           }t                      }|D ]l}t                              d|           t          | |          \  } }t                              dt          |                     t          | |||||          } mt          |           }||k    rt          j
        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_posts           r   r   r   /   s      	
!&
)
)C!#&&G$V,,I$&&O  0 0('	
 	
 	

 %VW550'&//BBB vwW.0 0
 'v..H3"#<===Mr   c                 8   t          |           }||d<   ||d<   t          t                    x|d<   }||d<   t          ||          |d<   t	          | |t          |                    }|                                D ]\  }	}
||	         }|
|j        z   |_        |S )z=Rewrite all uses to ``varname`` given the definition map
    r0   r1   phimapr,   phi_locations)_make_statesr   list_compute_phi_locations_run_block_rewrite_FixSSAVarsitemsbody)r   r0   r1   r,   r-   r/   statesr4   	newblockslabelphilistcurblks               r   r*   r*   S   s     &!!FF9F8 +D 1 11F8vF5M4WfEEF?"66;3O3OPPI ,,.. , ,w5!+r   c                 J   d |                                                                  D             d}|rmd}                                D ]T\  }}t          t          j        fd|D             t                                }|                    |          r||z  }d}U|m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                 4    i | ]\  }}|t          |          S r#   )set.0kvss      r   
<dictcomp>z'_iterated_domfronts.<locals>.<dictcomp>k   s$    JJJ2CGGJJJr   TFc                      g | ]
}|         S r#   r#   )rF   v	domfrontss     r   
<listcomp>z'_iterated_domfronts.<locals>.<listcomp>p   s    )C)C)C1)A,)C)C)Cr   )dominance_frontierr;   r   operatoror_rD   
difference)r,   
keep_goingrG   rH   innerrL   s        @r   r%   r%   e   s     KJ)?)?)A)A)G)G)I)IJJJIJ
 "
__&& 	" 	"EAr8<)C)C)C)C)C)C)CSUUKKE## "e!
  " r   c                 p    t                      }|                                D ]\  }}|r|| |         z  }|S r   )rD   r;   )iterated_dfr1   r5   deflabeldefstmtss        r   r8   r8   w   sG     EEM$llnn 3 3( 	3[22Mr   c                     t          |           }||d<   t          t                    x|d<   }t          | |t	                                }||fS )z(Rewrite to put fresh variable names
    r0   r1   )r6   r   r7   r9   _FreshVarHandler)r   r0   r=   r1   r>   s        r   r)   r)      sU     &!!FF9 +D 1 11F8v"663C3E3EFFIfr   c                 <    |                                  ^}}|j        S r   )valuesscope)r   first_s      r   
_get_scoper_      s    IEA;r   c                 D   t          t                    }t          | |t                                 t                              dt          |                     d |                                D             }t                              dt          |                     |S )zm
    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    zdefs %sc                 >    h | ]\  }}t          |          d k    |S )   )lenrE   s      r   	<setcomp>z'_find_defs_violators.<locals>.<setcomp>   s'    <<<uq"B!r   zSSA violators %s)r   r7   _run_block_analysis_GatherDefsHandlerr'   r(   r   r;   )r   defsr.   s      r   r&   r&      s     tD&8&:&:;;;MM)WT]]+++<<

<<<IMM$gi&8&8999r   c                     |                                  D ]4\  }}t                              d|           t          |||          D ]}5d S )Nz"==== SSA block analysis pass on %s)r;   r'   r(   _run_ssa_block_pass)r   r=   handlerr?   blkr^   s         r   re   re      s_    llnn  
s:EBBB$VS':: 	 	A	 r   c                 >   i }|                                  D ]\  }}t                              d|           t          j        |j        |j                  }g }||d<   ||d<   t          |||          D ]}|J |                    |           ||_	        |||<   |S )Nz!==== SSA block rewrite pass on %s)r\   locr?   block)
r;   r'   r(   r   Blockr\   rm   ri   appendr<   )	r   r=   rj   r>   r?   rk   newblknewbodystmts	            r   r9   r9      s    Illnn " "
s95AAA	sw777ww'W== 	! 	!D###NN4    !	%r   c                 <    t          t          |                     S )N)r\   )dictr_   )r   s    r   r6   r6      s$         r   c              #   b  K   t                               d|           |j        D ]}t                               d|           t          |t          j                  r|                    | |          }n|                    | |          }||ur|t                               d|           |V  d S )Nz
Running %szon stmt: %szreplaced with: %s)r'   r(   r<   
isinstancer   Assign	on_assignon_other)r=   rk   rj   rs   rets        r   ri   ri      s      MM,(((  mT***dBI&& 	1##FD11CC""6400Cd??sMM-s333				 r   c                       e Zd ZdZd Zd ZdS )_BaseHandlerzGA base handler for all the passes used here for the SSA algorithm.
    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   r=   assigns      r   ry   z_BaseHandler.on_assign         r   c                     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   r=   rs   s      r   rz   z_BaseHandler.on_other   r   r   Nr    r!   r"   __doc__ry   rz   r#   r   r   r}   r}      s<           $    r   r}   c                       e Zd ZdZd ZdS )rf   zEFind all defs

    ``states`` is a Mapping[str, List[ir.Assign]]
    c                 P    ||j         j                                     |           d S r   )targetnamerp   r   s      r   ry   z_GatherDefsHandler.on_assign   s&    v}!"))&11111r   N)r    r!   r"   r   ry   r#   r   r   rf   rf      s-         2 2 2 2 2r   rf   c                   "    e Zd Zd Zej        ZdS )UndefinedVariablec                      t          d          )NzNot intended for instantiation)NotImplementedErrorr   s    r   r   zUndefinedVariable.__init__   s    !"BCCCr   N)r    r!   r"   r   r   	UNDEFINEDr   r#   r   r   r   r      s)        D D D \FFFr   r   c                       e Zd ZdZd Zd ZdS )rY   z9Replaces assignment target with new fresh variables.
    c                    |j         j        |d         k    r|d         }|d         }t          |          dk    ri|j         }t                              d|           |j        |j        vr8d|j        d}t          j        t          j	        ||j
                             n&|                    |j         j        |j
                  }t          j        ||j        |j
        	          }||d
                                      |           |S )Nr0   r\   r1   r   zfirst assign: %sz	variable z is not in scope.rm   r   valuerm   r?   )r   r   rc   r'   r(   	localvarswarningswarnr
   NumbaIRAssumptionWarningrm   redefiner   rx   r   rp   )r   r=   r   r\   r1   	newtargetwmsgs          r   ry   z_FreshVarHandler.on_assign  s   =	!2227OEH%F6{{a"M	0)<<<>88Jy~JJJDM&"A$&,j#2 #2 #2 3 3 3 "NN6=+=6:NNN	Y lJ  F
 6'?#**6222r   c                     |S r   r#   r   s      r   rz   z_FreshVarHandler.on_other  s    r   Nr   r#   r   r   rY   rY     s<           ,    r   rY   c                   D    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
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                     || _         d S r   )_cache_list_vars)r   r/   s     r   r   z_FixSSAVars.__init__)  s     /r   c                    |j         }t          |t          j                  r|                     ||| j                            |j                             }|}|j        t          j        urj|d         |j        j	        k    rT|d         |j        i}t          |          }t          j        ||           t          j        |j        ||j                  S nt          |t          j                  ri|                     |||g          }|O|j        t          j        ur<|d         |j        j	        k    r&t          j        |j        |j        |j                  S |S )Nr0   r   )r   rw   r   Inst_fix_varr   r   r   r   r   r   r	   replace_vars_innerrx   rm   Var)r   r=   r   rhsnewdefreplmaps         r   ry   z_FixSSAVars.on_assign,  sP   lc27## 	]] 5 9 9&, G G F !fm2<&G&G)$(:::%i0&-@Gs))C/W===9%}!"J   
 RV$$ 		]]66C599F!fm2<&G&G)$(:::9%}$m"J    r   c                     |                      ||| j                            |                    }|\|j        t          j        urI|d         |j        j        k    r3|d         |j        i}t          |          }t          j	        ||           |S )Nr0   )
r   r   r   r   r   r   r   r   r	   replace_vars_stmt)r   r=   rs   r   r   s        r   rz   z_FixSSAVars.on_otherK  s    D$/33D99
 
 &-r|"C"Ci FM$666!),fm<Dzz*4999r   c                 b    d |D             }|d         }||v r|                      ||          S dS )z0Fix all variable uses in ``used_vars``.
        c                     g | ]	}|j         
S r#   )r   )rF   rG   s     r   rM   z(_FixSSAVars._fix_var.<locals>.<listcomp>Y  s    ...qAF...r   r0   N)	_find_def)r   r=   rs   	used_varsvarnamesphivars         r   r   z_FixSSAVars._fix_varV  sH     /.I...	"X>>&$/// r   c                    t                               d|d         |           d}|d         }|d         |         }|d         |         }|d         }|                     ||          }t          |          D ]2}	|                     |	||          }
|
|k     r|	} n|	|v r
|d	         } n3||                     |||j        
          }|S )z?Find definition of ``stmt`` for the statement ``stmt``
        zfind_def var=%r stmt=%sr0   Nr?   r1   r4   rn   )stopr   )r'   r(   _stmt_indexreversed_find_def_from_toprm   )r   r=   rs   selected_defr?   
local_defs
local_phisrn   cur_posdefstmtdef_poss              r   r   z_FixSSAVars._find_def^  s    	/	1BDIIIwH%e,
H%e,
w""4//
++ 		 		G&&wG&DDG  &J&&)"~ ' 2248 3  L r   c                    t                               d|           |d         }|d         }|d         }|d         }||v rM|d         }|d         j        }|                    |d         |	          }	t	          j        |	t          j                            |	          |
          }
t                               d|
|           ||                             d|
           ||         	                    |
           |
                    |          D ]{\  }}|                     |||	          }t                               d|           |
j        j        	                    |j                   |
j        j        	                    |           ||
S |                                |         }||k    rt#          |d         |           t$          S t                               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,   r1   r4   r5   r\   rn   r0   r   r   zinsert phi node %s at %sr   zincoming_def %szidom %s from label %s)r'   r(   rm   r   r   rx   Exprphiinsertrp   predecessors_find_def_from_bottomr   incoming_valuesr   incoming_blocksimmediate_dominators"_warn_about_uninitialized_variabler   )r   r=   r?   rm   r,   r1   r4   r5   r\   freshvarphinodepredr^   incoming_defidoms                  r   r   z_FixSSAVars._find_def_from_topz  s    	2E:::Um!!/M!!7OE/%C~~fY&7S~AAHigkkck**  G
 MM4guEEE5M  G,,,5M  )))++E22 ; ;a#99Dc  :     />>>-44\5HIII-44T::::N++--e4Du}} 36)3DcJJJ((MM14???--fd-DDDr   c                     t                               d|           |d         }||         }|r
|d         }|S |                     |||          S )z<Find definition from within the block at ``label``.
        zfind_def_from_bottom label %rr1   r   r   )r'   r(   r   )r   r=   r?   rm   r1   rg   lastdefs          r   r   z!_FixSSAVars._find_def_from_bottom  s^     	5u===!e} 	C2hGN**65c*BBBr   r   c                     t          t          |j                            d|         D ]}|j        |         |u r|c S t          |j                  S )zFind the positional index of the statement at ``block``.

        Assumptions:
        - no two statements can point to the same object.
        N)rangerc   r<   )r   r   rn   r   is        r   r   z_FixSSAVars._stmt_index  sY     s5:''. 	 	Az!}'' (5:r   N)r   )r    r!   r"   r   r   ry   rz   r   r   r   r   r   r#   r   r   r:   r:      s         0 0 0  >	 	 	0 0 0  8,E ,E ,E\
C 
C 
C     r   r:   c                 x    t           j        r-t          j        t	          j        d|  |                     d S d S )Nz Detected uninitialized variable r   )r   ALWAYS_WARN_UNINIT_VARr   r   r
   NumbaWarning)r0   rm   s     r   r   r     sX    $ 
<7<<  	
 	
 	
 	
 	

 
r   ))r   loggingrO   r   	functoolsr   r   pprintr   collectionsr   numbar   
numba.corer   r	   r
   numba.core.analysisr   	getLoggerr    r'   r   r   r   r*   r%   r8   r)   r_   r&   re   r9   r6   ri   r}   rf   r   rY   r:   r   r#   r   r   <module>r      s                         # # # # # #       + + + + + + + + + + 7 7 7 7 7 7 '
H
%
%         ! ! !H  $  $      
      "  
 
 
% % % % % % % %P2 2 2 2 2 2 2 2           |   :` ` ` ` `, ` ` `F
 
 
 
 
r   