
    xKg@                     x   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 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*y)$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)
OrderedSet)compute_cfg_from_blocksc                 :    t        | j                        | _        | S )znApply SSA reconstruction algorithm on the given IR.

    Produces minimal SSA using Choi et al algorithm.
    )_run_ssablocks)func_irs    R/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/numba/core/ssa.pyreconstruct_ssar      s    
 gnn-GNN    c                       e Zd Zd Zd Zy)_CacheListVarsc                     i | _         y N)_savedselfs    r   __init__z_CacheListVars.__init__&   s	    r   c                 ~    | j                   j                  |      }||j                         x| j                   |<   }|S r   )r   get	list_vars)r   instgots      r   r   z_CacheListVars.get)   s8    kkood#;&*nn&66DKK
r   N)__name__
__module____qualname__r   r    r   r   r   r   %   s    r   r   c           	      f   | si S t        |       }t        |      }t        | |      }t               }|D ]V  }t        j                  d|       t        | |      \  } }t        j                  dt        |             t        | |||||      } X t        |       }||k7  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   0   s     	
!&
)C!#&G$VS1I$&O ('	

 %VW50'&/B vwW.0  'v.H3""#<==Mr   c                    t        |       }||d<   ||d<   t        t              x|d<   }||d<   t        ||      |d<   t	        | |t        |            }|j                         D ]  \  }	}
||	   }|
|j                  z   |_          |S )z=Rewrite all uses to ``varname`` given the definition map
    r1   r2   phimapr-   phi_locations)_make_statesr   list_compute_phi_locations_run_block_rewrite_FixSSAVarsitemsbody)r   r1   r2   r-   r.   r0   statesr5   	newblockslabelphilistcurblks               r   r+   r+   T   s     &!FF9F8 +D 11F8vF5M4WfEF?"66;3OPI ,,.w5!+ ) r   c           	      l   | j                         j                         D ci c]  \  }}|t        |       }}}d}|rjd}|j                         D ]R  \  }}t        t        j
                  |D cg c]  }||   	 c}t                     }|j                  |      sL||z  }d}T |rj|S c c}}w c c}w )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.
    TF)dominance_frontierr<   setr   operatoror_
difference)r-   kvs	domfronts
keep_goingvinners          r   r&   r&   f   s     *-)?)?)A)G)G)IJ)I2CG)IIJJ

__&EAr8<<)C1)A,)CSUKE#e!
	 '   K
 *Ds   B+/B1c                 `    t               }|j                         D ]  \  }}|s	|| |   z  } |S r   )rE   r<   )iterated_dfr2   r6   deflabeldefstmtss        r   r9   r9   x   s:     EM$lln([22M - r   c                 |    t        |       }||d<   t        t              x|d<   }t        | |t	                     }||fS )z(Rewrite to put fresh variable names
    r1   r2   )r7   r   r8   r:   _FreshVarHandler)r   r1   r>   r2   r?   s        r   r*   r*      sI     &!FF9 +D 11F8v"663C3EFIfr   c                 >    | j                         ^}}|j                  S r   )valuesscope)r   first_s      r   
_get_scoperZ      s    IEA;;r   c           	      x   t        t              }t        t              }t        ||      }t	        | |t                      t        j                  dt        |             t        |j                         D cg c]  \  }}t        |      dkD  s| c}}      }|j                         }|j                         D ]Q  \  }}	||vs|	D ]B  }
||
   }||   D 
ch c]  \  }}
|
	 }}}
|j                  |      r1|j                  |        Q S t        j                  dt        |             |S c c}}w c c}
}w )zm
    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    )defsuseszdefs %s   zSSA violators %s)r   r8   rE   dict_run_block_analysis_GatherDefsHandlerr(   r)   r   r   r<   len
dominatorsintersectionadd)r   r-   r\   r]   r>   rI   rJ   r/   doms
use_blocksr@   dom_assign
def_labelss                 r   r'   r'      s    tDsDt$'F(:(<=MM)WT]+ 4::<G<%!R3r7Q;A<GHI>>D:I#5k:>q'C'e'
C!..s3MM!$ $ & MM$gi&89 H Ds   8D0
D0
D6
c                     | j                         D ]2  \  }}t        j                  d|       ||d<   t        |||      D ]  } 4 y )Nz"==== SSA block analysis pass on %sr@   )r<   r(   r)   _run_ssa_block_pass)r   r>   handlerr@   blkrY   s         r   r`   r`      sD    lln
s:EBw$VS':A ; %r   c                 :   i }| j                         D ]  \  }}t        j                  d|       t        j                  |j
                  |j                        }g }||d<   ||d<   t        |||      D ]  }|J |j                  |        ||_	        |||<    |S )Nz!==== SSA block rewrite pass on %s)rW   locr@   block)
r<   r(   r)   r   BlockrW   rp   rl   appendr=   )	r   r>   rm   r?   r@   rn   newblknewbodystmts	            r   r:   r:      s    Illn
s95A		sww7ww'W=D###NN4  > !	% % r   c                 ,    t        t        |             S )N)rW   )r_   rZ   )r   s    r   r7   r7      s      r   c              #   D  K   t         j                  d|       |j                  D ]w  }t         j                  d|       t        |t        j
                        r|j                  | |      }n|j                  | |      }||ur|t         j                  d|       | y y w)Nz
Running %szon stmt: %szreplaced with: %s)r(   r)   r=   
isinstancer   Assign	on_assignon_other)r>   rn   rm   rv   rets        r   rl   rl      s     MM,(mT*dBII&##FD1C""640Cd?sMM-s3	 s   BB c                       e Zd ZdZd Zd Zy)_BaseHandlerzGA base handler for all the passes used here for the SSA algorithm.
    c                      y)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   r{   z_BaseHandler.on_assign       r   c                      y)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>   rv   s      r   r|   z_BaseHandler.on_other   r   r   Nr!   r"   r#   __doc__r{   r|   r$   r   r   r   r      s    $r   r   c                       e Zd ZdZd Zd Zy)ra   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                    |d   |j                   j                     j                  ||d   f       |j                         D ]B  }|j                  }||j                   j                  k7  s)|d   |   j	                  |d          D y )Nr\   r@   r]   )targetnamers   r   re   )r   r>   r   varrI   s        r   r{   z_GatherDefsHandler.on_assign  su    vv}}))*1166'?2KL##%CAFMM&&&vq!%%fWo6 &r   c                 z    |j                         D ](  }|j                  }|d   |   j                  |d          * y )Nr]   r@   )r   r   re   )r   r>   rv   r   rI   s        r   r|   z_GatherDefsHandler.on_other  s7    >>#CA6N1!!&/2 $r   Nr   r$   r   r   ra   ra     s    73r   ra   c                   *    e Zd Zd Zej
                  Zy)UndefinedVariablec                     t        d      )NzNot intended for instantiation)NotImplementedErrorr   s    r   r   zUndefinedVariable.__init__  s    !"BCCr   N)r!   r"   r#   r   r   	UNDEFINEDr   r$   r   r   r   r     s    D \\Fr   r   c                       e Zd ZdZd Zd Zy)rT   z9Replaces assignment target with new fresh variables.
    c                 V   |j                   j                  |d   k(  r|d   }|d   }t        |      dk(  r|j                   }t        j	                  d|       |j                  |j
                  vrvd|j                  d}t        j                  t        j                  ||j                               n1|j                  |j                   j                  |j                        }t        j                  ||j                  |j                  	      }||d
      j                  |       |S )Nr1   rW   r2   r   zfirst assign: %sz	variable z is not in scope.rp   r   valuerp   r@   )r   r   rb   r(   r)   	localvarswarningswarnr
   NumbaIRAssumptionWarningrp   redefiner   rz   r   rs   )r   r>   r   rW   r2   	newtargetwmsgs          r   r{   z_FreshVarHandler.on_assign'  s    ==	!227OEH%F6{a"MM	0)<>>8&y~~&88IJDMM&"A"A$&,jj#2 3 "NN6==+=+=6::NN	YY llJJF
 6'?#**62r   c                     |S r   r$   r   s      r   r|   z_FreshVarHandler.on_other=  s    r   Nr   r$   r   r   rT   rT   $  s    ,r   rT   c                   B    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
dd	Zy
)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                     || _         y r   )_cache_list_vars)r   r0   s     r   r   z_FixSSAVars.__init__J  s
     /r   c                 .   |j                   }t        |t        j                        r| j	                  ||| j
                  j                  |j                               }||j                  t        j                  urz|d   |j                  j                  k7  r^|d   |j                  i}t        |      }t        j                  ||       t        j                  |j                  ||j                        S |S t        |t        j                        r| j	                  |||g      }|n|j                  t        j                  urR|d   |j                  j                  k7  r6t        j                  |j                  |j                  |j                        S |S )Nr1   r   )r   ry   r   Inst_fix_varr   r   r   r   r   r   r	   replace_vars_innerrz   rp   Var)r   r>   r   rhsnewdefreplmaps         r   r{   z_FixSSAVars.on_assignM  sC   llc277#]] 5 5 9 9&,, GF !fmm2<<&G)$(:(::%i0&--@Gs)C//W=99%}}!"JJ    RVV$]]66C59F!fmm2<<&G)$(:(::99%}}$mm"JJ  r   c                 6   | j                  ||| j                  j                  |            }|j|j                  t        j
                  urN|d   |j                  j                  k7  r2|d   |j                  i}t        |      }t        j                  ||       |S )Nr1   )
r   r   r   r   r   r   r   r   r	   replace_vars_stmt)r   r>   rv   r   r   s        r   r|   z_FixSSAVars.on_otherl  s    D$//33D9
 &--r||"Ci FMM$6$66!),fmm<Dz**49r   c                 v    |D cg c]  }|j                    }}|d   }||v r| j                  ||      S yc c}w )z0Fix all variable uses in ``used_vars``.
        r1   N)r   	_find_def)r   r>   rv   	used_varsrI   varnamesphivars          r   r   z_FixSSAVars._fix_varw  sI     %..IqAFFI.	"X>>&$//  /s   6c                 F   t         j                  d|d   |       d}|d   }|d   |   }|d   |   }|d   }| j                  ||      }t        |      D ]*  }	| j                  |	||      }
|
|k  r|	} n|	|v s%|d	   } n || j	                  |||j
                  
      }|S )z?Find definition of ``stmt`` for the statement ``stmt``
        zfind_def var=%r stmt=%sr1   Nr@   r2   r5   rq   )stopr   )r(   r)   _stmt_indexreversed_find_def_from_toprp   )r   r>   rv   selected_defr@   
local_defs
local_phisrq   cur_posdefstmtdef_poss              r   r   z_FixSSAVars._find_def  s     	/	1BDIwH%e,
H%e,
w""4/
+G&&wG&DG &J&)"~ , 22488 3 L r   c                    t         j                  d|       |d   }|d   }|d   }|d   }||v r9|d   }|d   j                  }|j                  |d   |	      }	t	        j
                  |	t        j                  j                  |	      |
      }
t         j                  d|
|       ||   j                  d|
       ||   j                  |
       |j                  |      D ]  \  }}| j                  |||	      }t         j                  d|       |
j                  j                  j                  |j                         |
j                  j                  j                  |        |
S |j!                         |   }||k(  rt#        |d   |       t$        S t         j                  d||       | j                  |||	      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-   r2   r5   r6   rW   rq   r1   r   r   zinsert phi node %s at %sr   zincoming_def %szidom %s from label %s)r(   r)   rp   r   r   rz   Exprphiinsertrs   predecessors_find_def_from_bottomr   incoming_valuesr   incoming_blocksimmediate_dominators"_warn_about_uninitialized_variabler   )r   r>   r@   rp   r-   r2   r5   r6   rW   freshvarphinodepredrY   incoming_defidoms                  r   r   z_FixSSAVars._find_def_from_top  s    	2E:Um!!/M!7OE/%%C~~fY&7S~AHiiggkkck*G
 MM4guE5M  G,5M  )++E2a#99Dc  :   />--44\5H5HI--44T: 3 N++-e4Du} 36)3DcJ((MM14?--fd-DDr   c                 |    t         j                  d|       |d   }||   }|r|d   }|S | j                  |||      S )z<Find definition from within the block at ``label``.
        zfind_def_from_bottom label %rr2   r   r   )r(   r)   r   )r   r>   r@   rp   r2   r\   lastdefs          r   r   z!_FixSSAVars._find_def_from_bottom  sO     	5u=!e}2hGN**65c*BBr   c                     t        t        |j                              d| D ]  }|j                  |   |u s|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)rangerb   r=   )r   r   rq   r   is        r   r   z_FixSSAVars._stmt_index  sG     s5::'.Azz!}' / 5::r   N)r   )r!   r"   r#   r   r   r{   r|   r   r   r   r   r   r$   r   r   r;   r;   A  s2    0>	08,E\
Cr   r;   c                     t         j                  r.t        j                  t	        j
                  d|  |             y y )Nz Detected uninitialized variable r   )r   ALWAYS_WARN_UNINIT_VARr   r   r
   NumbaWarning)r1   rp   s     r   r   r     s7    $$27)<	
 %r   )+r   loggingrF   r   	functoolsr   r   pprintr   collectionsr   numbar   
numba.corer   r	   r
   numba.core.utilsr   numba.core.analysisr   	getLoggerr!   r(   r   r   r   r+   r&   r9   r*   rZ   r'   r`   r:   r7   rl   r   ra   r   rT   r;   r   r$   r   r   <module>r      s          #  + + ' 7 '

H
% !H$$
<"
% %P3 32 | :`, `F
r   