
    J/Phy                        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  e	g d          Z
 G d de          Z G d d	 e j        d	d
                    Z G d de j                  Z G d de          Z G d de          ZdS )    N)Loc)UnsupportedError)	PYVERSION)
SETUP_LOOPFOR_ITER
SETUP_WITHBEFORE_WITHc                        e Zd Zd Zd Zd ZdS )CFBlockc                 L    || _         g | _        i | _        i | _        d| _        d S )NF)offsetbodyoutgoing_jumpsincoming_jumpsterminating)selfr   s     V/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/numba/core/controlflow.py__init__zCFBlock.__init__   s2    	 ! !     c                 h    | j         t          | j                  t          | j                  f}d|z  S )Nz,block(offset:%d, outgoing: %s, incoming: %s))r   sortedr   r   )r   argss     r   __repr__zCFBlock.__repr__   s7    t*++t*++- >DDr   c                 *    t          | j                  S N)iterr   r   s    r   __iter__zCFBlock.__iter__#   s    DIr   N)__name__
__module____qualname__r   r   r    r   r   r   r      sD        	! 	! 	!E E E    r   r   c                   "    e Zd ZdZdZd Zd ZdS )Loopz?
    A control flow loop, as detected by a CFGraph object.
    r"   c                 L    t          |t                    o|j        | j        k    S r   )
isinstancer$   headerr   others     r   __eq__zLoop.__eq__4   s     %&&F5<4;+FFr   c                 *    t          | j                  S r   )hashr'   r   s    r   __hash__zLoop.__hash__7   s    DK   r   N)r   r    r!   __doc__	__slots__r*   r-   r"   r   r   r$   r$   '   sF          IG G G! ! ! ! !r   r$   )entriesexitsr'   r   c                   $    e Zd ZdZd Zd Zd ZdS )_DictOfContainerszA defaultdict with customized equality checks that ignore empty values.

    Non-empty value is checked by: `bool(value_item) == True`.
    c                     t          |t                    r.|                                 }|                                }||k    S t          S r   )r&   r3   _non_empty_itemsNotImplemented)r   r)   minetheirss       r   r*   z_DictOfContainers.__eq__A   sG    e.// 	"((**D++--F6>!r   c                 H    |                      |          }|t          u r|S | S r   )r*   r6   )r   r)   rets      r   __ne__z_DictOfContainers.__ne__I   s*    kk%  .  J7Nr   c                 X    d t          |                                           D             S )Nc                      g | ]\  }}|||fS r"   r"   ).0kvss      r   
<listcomp>z6_DictOfContainers._non_empty_items.<locals>.<listcomp>Q   s%    @@@EArR@B@@@r   )r   itemsr   s    r   r5   z"_DictOfContainers._non_empty_itemsP   s&    @@VDJJLL%9%9@@@@r   N)r   r    r!   r.   r*   r;   r5   r"   r   r   r3   r3   ;   sP         
    A A A A Ar   r3   c                      e Zd ZdZd Zd Zd<dZd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zej        d             Zd Zd Zd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d=d$Z&d<d%Z'd>d'Z(d<d(Z)d) Z*d<d*Z+d+ Z,d, Z-d- Z.d. Z/d/ Z0d0 Z1d=d1Z2d2 Z3d3 Z4d<d4Z5d5 Z6d6 Z7d7 Z8d8 Z9d9 Z:d: Z;d; Z<dS )?CFGraphzB
    Generic (almost) implementation of a Control Flow Graph.
    c                     t                      | _        t          t                     | _        t          t                     | _        i | _        d | _        d S r   )set_nodesr3   _preds_succs
_edge_data_entry_pointr   s    r   r   zCFGraph.__init__Y   s@    ee',,',, r   c                 :    | j                             |           dS )z
        Add *node* to the graph.  This is necessary before adding any
        edges from/to the node.  *node* can be any hashable object.
        N)rG   addr   nodes     r   add_nodezCFGraph.add_node`   s    
 	r   Nc                     || j         vrt          d|d| j                   || j         vrt          d|d| j                   |                     |||           dS )z
        Add an edge from node *src* to node *dest*, with optional
        per-edge *data*.
        If such an edge already exists, it is replaced (duplicate edges
        are not possible).
        zCannot add edge as src node z not in nodes zCannot add edge as dest node N)rG   
ValueError	_add_edge)r   srcdestdatas       r   add_edgezCFGraph.add_edgeg   s     dk!!*!cc4;;0 1 1 1t{""*"ddDKK1 2 2 2sD$'''''r   c              #   P   K   | j         |         D ]}|| j        ||f         fV  dS )z
        Yield (node, data) pairs representing the successors of node *src*.
        (*data* will be None if no data was specified when adding the edge)
        N)rI   rJ   )r   rT   rU   s      r   
successorszCFGraph.successorsv   sG      
 K$ 	3 	3DT	222222	3 	3r   c              #   P   K   | j         |         D ]}|| j        ||f         fV  dS )z
        Yield (node, data) pairs representing the predecessors of node *dest*.
        (*data* will be None if no data was specified when adding the edge)
        N)rH   rJ   )r   rU   rT   s      r   predecessorszCFGraph.predecessors~   sG      
 ;t$ 	2 	2CtsDy111111	2 	2r   c                 *    || j         v sJ || _        dS )z=
        Set the entry point of the graph to *node*.
        N)rG   rK   rN   s     r   set_entry_pointzCFGraph.set_entry_point   s%     t{"""" r   c                 Z    | j         t          d          |                                  dS )z
        Compute essential properties of the control flow graph.  The graph
        must have been fully populated, and its entry point specified. Other
        graph properties are computed on-demand.
        Nzno entry point defined!)rK   RuntimeError_eliminate_dead_blocksr   s    r   processzCFGraph.process   s4     $8999##%%%%%r   c                     | j         S )z
        Return a dictionary of {node -> set(nodes)} mapping each node to
        the nodes dominating it.

        A node D dominates a node N when any path leading to N must go through D
        )_domsr   s    r   
dominatorszCFGraph.dominators        zr   c                     | j         S )z
        Return a dictionary of {node -> set(nodes)} mapping each node to
        the nodes post-dominating it.

        A node P post-dominates a node N when any path starting from N must go
        through P.
        )
_post_domsr   s    r   post_dominatorszCFGraph.post_dominators   s     r   c                     | j         S )z
        Return a dictionary of {node -> node} mapping each node to its
        immediate dominator (idom).

        The idom(B) is the closest strict dominator of V
        )_idomr   s    r   immediate_dominatorszCFGraph.immediate_dominators   re   r   c                     | j         S )a.  
        Return a dictionary of {node -> set(nodes)} mapping each node to
        the nodes in its dominance frontier.

        The dominance frontier _df(N) is the set of all nodes that are
        immediate successors to blocks dominated by N but which aren't
        strictly dominated by N
        )_dfr   s    r   dominance_frontierzCFGraph.dominance_frontier   s     xr   c                     | j         S )z
        return a dictionary of {node -> set(nodes)} mapping each node to
        the set of nodes it immediately dominates

        The domtree(B) is the closest strict set of nodes that B dominates
        )_domtreer   s    r   dominator_treezCFGraph.dominator_tree   s     }r   c                 *    |                                  S r   )_find_exit_pointsr   s    r   _exit_pointszCFGraph._exit_points       %%'''r   c                 *    |                                  S r   )_find_dominatorsr   s    r   rc   zCFGraph._doms       $$&&&r   c                 *    |                                  S r   )_find_back_edgesr   s    r   _back_edgeszCFGraph._back_edges   rx   r   c                 *    |                                  S r   )_find_topo_orderr   s    r   _topo_orderzCFGraph._topo_order   rx   r   c                 *    |                                  S r   )_find_descendentsr   s    r   _descszCFGraph._descs   ru   r   c                 *    |                                  S r   )_find_loopsr   s    r   _loopszCFGraph._loops   s    !!!r   c                 *    |                                  S r   )_find_in_loopsr   s    r   	_in_loopszCFGraph._in_loops   s    ""$$$r   c                 *    |                                  S r   )_find_post_dominatorsr   s    r   rg   zCFGraph._post_doms   s    ))+++r   c                 *    |                                  S r   )_find_immediate_dominatorsr   s    r   rj   zCFGraph._idom   s    ..000r   c                 *    |                                  S r   )_find_dominance_frontierr   s    r   rm   zCFGraph._df   s    ,,...r   c                 *    |                                  S r   )_find_dominator_treer   s    r   rp   zCFGraph._domtree   s    ((***r   c                     | j         |         S )zx
        Return the set of descendents of the given *node*, in topological
        order (ignoring back edges).
        )r   rN   s     r   descendentszCFGraph.descendents   s    
 {4  r   c                 "    | j         J | j         S )z.
        Return the entry point node.
        )rK   r   s    r   entry_pointzCFGraph.entry_point   s      ,,,  r   c                     | j         S )zG
        Return the computed set of exit nodes (may be empty).
        )rt   r   s    r   exit_pointszCFGraph.exit_points  s       r   c                 &    | j         | j                 S )z
        Return the set of nodes constituting the graph's backbone.
        (i.e. the nodes that every path starting from the entry point
         must go through).  By construction, it is non-empty: it contains
         at least the entry point.
        )rg   rK   r   s    r   backbonezCFGraph.backbone  s     t011r   c                     | j         S )z
        Return a dictionary of {node -> loop} mapping each loop header
        to the loop (a Loop instance) starting with it.
        r   r   s    r   loopszCFGraph.loops  s    
 {r   c                 R      fd j                             |d          D             S )zm
        Return the list of Loop objects the *node* belongs to,
        from innermost to outermost.
        c                 *    g | ]}j         |         S r"   r   )r>   xr   s     r   rA   z$CFGraph.in_loops.<locals>.<listcomp>  s    EEE1AEEEr   r"   )r   getrN   s   ` r   in_loopszCFGraph.in_loops  s2    
 FEEE(:(:4(D(DEEEEr   c                     | j         S )zK
        Return the set of dead nodes (eliminated from the graph).
        )_dead_nodesr   s    r   
dead_nodeszCFGraph.dead_nodes  s     r   c                     | j         S )z/
        Return the set of live nodes.
        )rG   r   s    r   nodeszCFGraph.nodes$  s     {r   c                     | j         S )zb
        Return the sequence of nodes in topological order (ignoring back
        edges).
        )r~   r   s    r   
topo_orderzCFGraph.topo_order*  s    
 r   Fc              #   r   K   t          |          }| j        }|rt          |          }|D ]
}||v r|V  dS )z
        Iterate over the *nodes* in topological order (ignoring back edges).
        The sort isn't guaranteed to be stable.
        N)rF   r~   reversed)r   r   reverseitns        r   	topo_sortzCFGraph.topo_sort1  sZ      
 E

 	"B 	 	AEzz	 	r   c                    ddl }|pt          j        }	 t          d|           |                     |           t          d|           |                     | j        |           t          d|           |                     | j        |           t          d	t          | j                  |           t          d
|           |                     | j	        |           t          d|           |                     | j
        |           t          d|           |                     |                                 |           dS )z3
        Dump extensive debug information.
        r   N   zCFG adjacency lists:filezCFG dominators:streamzCFG post-dominators:zCFG back edges:z
CFG loops:zCFG node-to-loops:zCFG backbone:)pprintsysstdoutprint_dump_adj_listsrc   rg   r   r{   r   r   r   )r   r   r   s      r   dumpzCFGraph.dump>  sM    	!sz	'(t4444  &&&d++++dj...$40000dod333(8!9!9EEEEl&&&&dk$///"....dnT222oD))))dmmood33333r   numba_cfg.dotc                 d   	 ddl }n# t          $ r t          d          w xY w|                    |          }| j        D ]$}|                    t          |                     %| j        D ]B}| j        |         D ]2}|                    t          |          t          |                     3C|S )zRender the controlflow graph with GraphViz DOT via the
        ``graphviz`` python binding.

        Returns
        -------
        g : graphviz.Digraph
            Use `g.view()` to open the graph in the default PDF application.
        r   NzcThe feature requires `graphviz` but it is not available. Please install with `pip install graphviz`)filename)graphvizImportErrorDigraphrG   rO   strrI   edge)r   r   gvgr   r   s         r   
render_dotzCFGraph.render_dotS  s    	!!!!! 	 	 	=  	
 JJJ)) 	 	AFF3q66NNNN 	* 	*AA * *s1vvs4yy))))*s    !c                     | j         |                             |           | j        |                             |           || j        ||f<   d S r   )rH   rM   rI   rJ   )r   from_torV   s       r   rS   zCFGraph._add_edgep  sO     	BE"""Er"""%)r	"""r   c                 &   | j                             |d          D ],}| j        |                             |           | j        ||f= -| j                            |d          D ],}| j         |                             |           | j        ||f= -d S )Nr"   )rI   poprH   removerJ   )r   rO   succpreds       r   _remove_node_edgeszCFGraph._remove_node_edgesw  s    KOOD"-- 	, 	,DK$$T***d
++KOOD"-- 	, 	,DK$$T***d
++	, 	,r   c              #     K   || j         f}t                      }t          |          }|rZ|                                }||vr>|V  |                    |           | j        |         D ]}|                    |           |Xd S d S r   )rK   rF   listr   rM   rI   append)r   r0   seenstackrO   r   s         r   _dfszCFGraph._dfs  s      ?(*GuuW 	'99;;D4


 K- ' 'DLL&&&&  	' 	' 	' 	' 	'r   c                     t                      }|                                 D ]}|                    |           | j        |z
  | _        || _        | j        D ]}|                     |           dS )zx
        Eliminate all blocks not reachable from the entry point, and
        stash them into self._dead_nodes.
        N)rF   r   rM   rG   r   r   )r   liverO   deads       r   r`   zCFGraph._eliminate_dead_blocks  s~    
 uuIIKK 	 	DHHTNNNN;-$ 	* 	*D##D))))	* 	*r   c                     t                      }| j        D ]1}| j                            |          s|                    |           2|S )z2
        Compute the graph's exit points.
        )rF   rG   rI   r   rM   )r   r   r   s      r   rs   zCFGraph._find_exit_points  sM     ee 	# 	#A;??1%% #"""r   c                     | j         | j        g t                      g fd| j        fgr$                                \  }} ||           $S )Nc                     | vrY                     |                                j        | f           |          D ]!}| |fvr                    |f            d S d S r   rM   r   )rO   rU   
back_edgesdfs_rec
post_orderr   r   succss     r   r   z(CFGraph._find_postorder.<locals>.dfs_rec  s    4j/6777!$K 6 6Dd|:55gt_555  6 6r   )rI   r{   rF   rK   r   )	r   cbrV   r   r   r   r   r   r   s	      @@@@@@r   _find_postorderzCFGraph._find_postorder  s    %

uu
	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 4,-. 	yy{{HBBtHHH  	 r   c                 z  	 	fd}| j         }| j        }|                                 }d t          |          D             	||i|                                 |                                 d}|rGd}|D ]@}t          j        |fd||         D                       }|vs|         |k    r||<   d}A|GS )Nc                     | |k    r^|          |         k     r|          } |          |         k     |          |         k    r|         }|          |         k    | |k    ^| S r   r"   )uvidomidxs     r   	intersectz5CFGraph._find_immediate_dominators.<locals>.intersect  sx    q&&!fs1vooQA !fs1voo!fs1vooQA !fs1voo q&&
 Hr   c                     i | ]\  }}||	S r"   r"   )r>   ies      r   
<dictcomp>z6CFGraph._find_immediate_dominators.<locals>.<dictcomp>  s    1111q!111r   TFc              3   $   K   | ]
}|v |V  d S r   r"   )r>   r   r   s     r   	<genexpr>z5CFGraph._find_immediate_dominators.<locals>.<genexpr>  s4       -; -;101T		 ./09			-; -;r   )rK   rH   r   	enumerater   r   	functoolsreduce)
r   r   entrypreds_tableorderchangedr   new_idomr   r   s
           @@r   r   z"CFGraph._find_immediate_dominators  s   	 	 	 	 	 	 !k$$&&11	% 0 0111		 	#G # #$+I-; -; -; -;A -; -; -;< < D==DGx$7$7&DG"G  	# r   c                     | j         }t          t                    }|                                D ];\  }}||vrt                      ||<   ||k    r||                             |           <|S r   )rj   r3   rF   rB   rM   )r   r   domtreer   r   s        r   r   zCFGraph._find_dominator_tree  sn    z#C((JJLL 	" 	"DAq UU
Avv
q!!!r   c                    | j         }| j        }d |D             }|D ]b}t          ||                   dk     r||         D ]=}|||         k    r/||                             |           ||         }|||         k    />c|S )Nc                 ,    i | ]}|t                      S r"   )rF   )r>   r   s     r   r   z4CFGraph._find_dominance_frontier.<locals>.<dictcomp>  s    %%%1a%%%r      )rj   rH   lenrM   )r   r   r   dfr   r   s         r   r   z CFGraph._find_dominance_frontier  s    zk%%%%% 	  	 A;q>""Q&& ^    47llqEIIaLLLQA 47ll 
 	r   c                   
 |r#t          | j                  }| j        }| j        }n#t          | j        g          }| j        }| j        }|st          d          i 
|D ]}t          |g          
|<   g }| j        D ]2}||vr,t          | j                  
|<   |                    |           3|r|                                }||v rt          |g          }||         }	|	r.|t          j
        t           j        
fd|	D                       z  }|
|         k    rHt          |          t          
|                   k     sJ |
|<   |                    ||                    |
S )Nz5no entry points: dominator algorithm cannot be seededc                      g | ]
}|         S r"   r"   )r>   pdomss     r   rA   z5CFGraph._find_dominators_internal.<locals>.<listcomp>$  s    -E-E-E!d1g-E-E-Er   )rF   rt   rI   rH   rK   r_   rG   r   r   r   r   intersectionr   extend)r   postr0   r   succs_tabler   todor   new_domspredsr   s             @r   _find_dominators_internalz!CFGraph._find_dominators_internal   s   
  	&$+,,G+K+KK4,-..G+K+K 	3  2 3 3 3  	 	A1#hhDGG 	 	Adk**QA 	,

AG||A3xxHNE GI,S-=-E-E-E-Eu-E-E-EG G G47""8}}s47||3333"QKN+++  	, r   c                 .    |                      d          S )NFr  )r  r   s    r   rw   zCFGraph._find_dominators+  s    --5-999r   c                    t                      }| j                            |           | j                                        D ])}|j        s |j        D ]}|                     ||           *|                     d          }||= |                                D ]}|	                    |           | 
                    |           | j                            |           |S )NTr	  )objectrt   rM   r   valuesr1   r   rS   r  discardr   r   )r   
dummy_exitloopbpdomsr   s         r   r   zCFGraph._find_post_dominators.  s     XX
j)))K&&(( 	2 	2D: 2 2 2ANN1j1111..D.99*LLNN 	% 	%DLL$$$$
+++  ,,,r   c                 `   
 |Jt          |t                    st          dt          |                     |                    dd           t                      }g 
i                                  }t                      } 
fd} ||           d}
r|dz  }
d         }|         }|r@|                                }	|	
v r|                    ||	f           n9|	|vr ||	           n)
                                 |                    |           
||dxx         |z  cc<   |S )zu
        Find back edges.  An edge (src, dest) is a back edge if and
        only if *dest* dominates *src*.
        Nz*stats* must be a dict; got iteration_countr   c                 f                         |            d j        |          D             | <   d S )Nc                     g | ]}|S r"   r"   )r>   rU   s     r   rA   z@CFGraph._find_back_edges.<locals>.push_state.<locals>.<listcomp>\  s     D D D$ D D Dr   )r   rI   )rO   r   r   succs_states    r   
push_statez,CFGraph._find_back_edges.<locals>.push_stateZ  s:    LL D D$+d2C D D DKr   r   )	r&   dict	TypeErrortype
setdefaultrF   r   r   rM   )r   statsr   r   checkedr  iter_cttos	tos_succscur_noder   r  s   `         @@r   rz   zCFGraph._find_back_edgesC  s    eT** N LtE{{ L LMMM.222
 UU
&&((%%	E 	E 	E 	E 	E 	E 	E 	
;  	!qLG)C#C(I !$==??u$$NNC?3333W,,Jx((( 		C   %  	!( #$$$/$$$r   c                     | j         | j        g t                      fd | j                                                    S )Nc                     | vrH                     |            |          D ]}| |fvr |                               |            d S d S r   r   )rO   rU   _dfs_recr   r   r   r   s     r   r%  z*CFGraph._find_topo_order.<locals>._dfs_rec  so    4!$K ' 'Dd|:55 !!$'''''  r   )rI   r{   rF   rK   r   )r   r%  r   r   r   r   s    @@@@@r   r}   zCFGraph._find_topo_orderz  s~    %

uu	( 	( 	( 	( 	( 	( 	( 	( 	( 	"###r   c                     i }t          | j                  D ]`}t                      x||<   }| j        |         D ]=}||f| j        vr0|                    |           |                    ||                    >a|S r   )r   r~   rF   rI   r{   rM   update)r   descsrO   
node_descsr   s        r   r   zCFGraph._find_descendents  s    T-.. 	3 	3D'*uu,E$K*D) 3 3$<t'777NN4(((%%eDk2223 r   c                 p   i }| j         D ]\  }}|}t          |g          }|g}|rO|                                }||vr5|                    |           |                    | j        |                    |O||v r||                             |           |||<   i }|                                D ]\  }}t                      }	t                      }
|D ]H}|	                    | j        |         |z
             |
                    | j        |         |z
             It          |||	|
          }|||<   |S )zC
        Find the loops defined by the graph's back edges.
        )r'   r   r0   r1   )
r{   rF   r   rM   r  rH   r'  rB   rI   r$   )r   bodiesrT   rU   r'   r   queuer   r   r0   r1   r  s               r   r   zCFGraph._find_loops  sb    ) 	& 	&ICF x==DEE 1IIKKD==HHQKKKLLQ000	  1 v%%d++++!%v "LLNN 	! 	!LFDeeGEEE 4 4t{1~4555T[^d23333vD'OOOD E&MMr   c                     | j         }t          d | j        D                       }t          |                                d           D ],}|j        D ]"}||                             |j                   #-|S )Nc              3      K   | ]}|g fV  	d S r   r"   )r>   r   s     r   r   z)CFGraph._find_in_loops.<locals>.<genexpr>  s&      55AB555555r   c                 *    t          | j                  S r   )r   r   )r  s    r   <lambda>z(CFGraph._find_in_loops.<locals>.<lambda>  s    C	NN r   )key)r   r  rG   r   r  r   r   r'   )r   r   r   r  r   s        r   r   zCFGraph._find_in_loops  s    5555555 5<<>>/J/JKKK 	0 	0DY 0 0""4;////0r   c                     t          d | j                                        D                       }dd l}|                    ||           d S )Nc              3   X   K   | ]%\  }}|t          t          |                    fV  &d S r   )r   r   )r>   rT   destss      r   r   z*CFGraph._dump_adj_lists.<locals>.<genexpr>  sU       @ @'S% vd5kk223 @ @ @ @ @ @r   r   r   )r  rI   rB   r   )r   r   	adj_listsr   s       r   r   zCFGraph._dump_adj_lists  sg     @ @+/;+<+<+>+>@ @ @ @ @	i-----r   c                     t          |t                    st          S dD ]-}t          | |d           }t          ||d           }||k    r dS .dS )N)rG   rJ   rK   rH   rI   FT)r&   rD   r6   getattr)r   r)   r   thisthats        r   r*   zCFGraph.__eq__  se    %)) 	"!!M 	 	A4D))D5!T**Dt||uu tr   c                 .    |                      |           S r   )r*   r(   s     r   r;   zCFGraph.__ne__  s    ;;u%%%%r   r   )F)r   )=r   r    r!   r.   r   rP   rW   rY   r[   r]   ra   rd   rh   rk   rn   rq   r   cached_propertyrt   rc   r{   r~   r   r   r   rg   rj   rm   rp   r   r   r   r   r   r   r   r   r   r   r   r   rS   r   r   r`   rs   r   r   r   r   r  rw   r   rz   r}   r   r   r   r   r*   r;   r"   r   r   rD   rD   T   s6        ! ! !  ( ( ( (3 3 32 2 2! ! !& & &      	 	 	   ( ( ( ' ' ' ' ' ' ' ' ' ( ( ( " " " % % % , , , 1 1 1 / / / + + +! ! !! ! !! ! !2 2 2  F F F               4 4 4 4*   :* * * *, , ,' ' ' '* * *    0& & &P    ) ) ) )V: : :  *5 5 5 5n  $  " " "H	 	 	. . .	 	 	& & & & &r   rD   c                       e Zd ZdZd Zd Zd Zd ZddZd Z	dd
Z
d Zd Zd Zd Zd Zd Zd Zd Zd ZeZeZeZeZeZeZeZeZd ZeZeZd Zd Z e Z!d Z"e#dv rd Z$ne#dv rn e%e#          d Z&d Z'dS )ControlFlowAnalysisz
    Attributes
    ----------
    - bytecode

    - blocks

    - blockseq

    - doms: dict of set
        Dominators

    - backbone: set of block offsets
        The set of block that is common to all possible code path.

    c                     || _         i | _        i | _        g | _        d | _        d | _        d| _        d | _        g | _        g | _	        g | _
        d S NT)bytecodeblocks
liveblocksblockseqr   r   _force_new_block	_curblock_blockstackr   _withs)r   r@  s     r   r   zControlFlowAnalysis.__init__  sU     	 $r   c              #   <   K   | j         D ]}| j        |         V  dS )z=
        Return all blocks in sequence of occurrence
        N)rC  rA  r   r   s     r   
iterblockszControlFlowAnalysis.iterblocks  s8        	! 	!A+a.    	! 	!r   c              #   N   K   | j         D ]}|| j        v r| j        |         V  dS )zB
        Return all live blocks in sequence of occurrence
        N)rC  rB  rA  rI  s     r   iterliveblocksz"ControlFlowAnalysis.iterliveblocks   sC        	% 	%ADO##k!n$$$	% 	%r   c              #   |   K   |j                                         D ]\  }}|| j        v r| j        |         |fV   dS )zQ
        Yield (incoming block, number of stack pops) pairs for *block*.
        N)r   rB   rB  rA  )r   blockr   popss       r   incoming_blocksz#ControlFlowAnalysis.incoming_blocks  sY       +1133 	+ 	+GAtDO##k!nd****	+ 	+r   Nc                 <    | j                             d            d S )Nr   )graphr   )r   r   s     r   r   zControlFlowAnalysis.dump  s    
T"""""r   c                                                       D ]}}d|j        z  }t           |d           }| ||           +|j        rKt	           j        j        j        |j                  }|j        dv rd}n
d|j        z  }t          ||          ~t           j         j        dd                    D ]*\  }} j        |         }|j        s|j        s
d|j        |<   +t                      }	 j        D ]}
|	                    |
            j                                        D ]=}
|
j                                        D ]!\  }}|	                    |
j        ||           ">|	                    t-           j                             |	                                 |	 _         j                                        D ];}
|
j                                        D ]\  }}| j        |         j        |
j        <    <t5           fd j                                        D                        _        t;           j                  D ]}| j        v r nt=          d	           j                                        }tA                      } j        !                                D ]1}
 j        "                    |
          r|#                    |
           2||z
   _        d S )
Nzop_%s>   SETUP_FINALLYz2'try' block not supported until python3.7 or laterz$Use of unsupported opcode (%s) found)locr   r   c              3   6   K   | ]}|j         |         fV  d S r   )rA  )r>   r   r   s     r   r   z*ControlFlowAnalysis.run.<locals>.<genexpr>;  sB       < <#$ !"4;q>2 < < < < < <r   zNo live block that exits!?)$
_iter_instopnamer7  is_jumpr   r@  func_idr   linenor   ziprC  rA  r   r   rD   rP   r  rB   rW   r   r]   minra   rR  r   r  r   rB  r   AssertionErrorr   rF   keysr   rM   )r   instfnamefnlmsgcurnxtblkrR  r  outrO  lastblkr   inloopblockss   `               r   runzControlFlowAnalysis.run  s+   OO%% 	 	Ddk)Eud++B~4 
-6DD;"333NCC@4;NC&s2222  DM4=+<== 	, 	,HC+c"C% ,co ,*+"3'		 	 	ANN1##%% 	4 	4A-3355 4 4	Tqxd33334c$+..///
 ##%% 	A 	AA-3355 A A	T<@C /99A  < < < <(,
(8(8(:(:< < < < <  .. 	? 	?G$/)) * !!=>>> :&&(( uu!!## 	$ 	$Az""1%% $  ### </r   r   c                 $    || j         j        |<   dS )z
        Register a jump (conditional or not) to *target* offset.
        *pops* is the number of stack pops implied by the jump (default 0).
        N)rE  r   )r   targetrO  s      r   jumpzControlFlowAnalysis.jumpQ  s    
 15%f---r   c              #      K   | j         D ]i}|                     |          r*|                     |           |                     |           | j        j                            |j                   |V  jd S r   )r@  _use_new_block_guard_with_as_start_new_blockrE  r   r   r   r   r`  s     r   rW  zControlFlowAnalysis._iter_instX  s      M 	 	D""4(( ,##D)))%%d+++N&&t{333JJJJ	 	r   c                 p    |j         | j        j        v rd}n|j        t          v rd}n| j        }d| _        |S )NTF)r   r@  labelsrX  NEW_BLOCKERSrD  )r   r`  ress      r   rp  z"ControlFlowAnalysis._use_new_block`  sD    ;$-...CC[L((CC'C %
r   c                     t          |j                  | _        | j        | j        |j        <   | j                            |j                   d S r   )r   r   rE  rA  rC  r   rs  s     r   rr  z$ControlFlowAnalysis._start_new_blockk  sA     --#'>DK T[)))))r   c                 |    |j         dk    r.| j        |j                 j         }|dk    rd}t          |          dS dS )zChecks if the next instruction after a SETUP_WITH is something other
        than a POP_TOP, if it is something else it'll be some sort of store
        which is not supported (this corresponds to `with CTXMGR as VAR(S)`).r   POP_TOPzGThe 'with (context manager) as (variable):' construct is not supported.N)rX  r@  nextr   )r   current_instnext_oprd  s       r   rq  z"ControlFlowAnalysis._guard_with_asp  sT     ,..mL$56=G)##$ 's+++ /.##r   c                     |                                 }| j                            |           | j                            |j        |f           |                     |j                   d| _        d S r?  )get_jump_targetrF  r   r   r   rn  r{  rD  r   r`  ends      r   op_SETUP_LOOPz!ControlFlowAnalysis.op_SETUP_LOOP|  k    ""$$$$$DK-... 			$) $r   c                     |                                 }| j                            |           | j                            |j        |f           |                     |j                   d| _        d S r?  )r  rF  r   rG  r   rn  r{  rD  r  s      r   op_SETUP_WITHz!ControlFlowAnalysis.op_SETUP_WITH  r  r   c                 8    | j                                          d S r   )rF  r   rs  s     r   op_POP_BLOCKz ControlFlowAnalysis.op_POP_BLOCK  s    r   c                     |                      |                                           |                      |j                   d| _        d S r?  rn  r  r{  rD  rs  s     r   op_FOR_ITERzControlFlowAnalysis.op_FOR_ITER  B    		$&&(()))		$) $r   c                     |                      |                                           |                      |j                   d| _        d S r?  r  rs  s     r   _op_ABSOLUTE_JUMP_IFz(ControlFlowAnalysis._op_ABSOLUTE_JUMP_IF  r  r   c                     |                      |                                           |                      |j        d           d| _        d S )Nr   )rO  Tr  rs  s     r   _op_ABSOLUTE_JUMP_OR_POPz,ControlFlowAnalysis._op_ABSOLUTE_JUMP_OR_POP  sF    		$&&(()))		$)!	$$$ $r   c                 b    |                      |                                           d| _        d S r?  rn  r  rD  rs  s     r   op_JUMP_ABSOLUTEz$ControlFlowAnalysis.op_JUMP_ABSOLUTE  .    		$&&(())) $r   c                 b    |                      |                                           d| _        d S r?  r  rs  s     r   op_JUMP_FORWARDz#ControlFlowAnalysis.op_JUMP_FORWARD  r  r   c                 ,    d| j         _        d| _        d S r?  rE  r   rD  rs  s     r   op_RETURN_VALUEz#ControlFlowAnalysis.op_RETURN_VALUE      %)" $r   ))      )r     c                 ,    d| j         _        d| _        d S r?  r  rs  s     r   op_RETURN_CONSTz#ControlFlowAnalysis.op_RETURN_CONST  s    )-DN&$(D!!!r   ))r  
   )r     c                 ,    d| j         _        d| _        d S r?  r  rs  s     r   op_RAISE_VARARGSz$ControlFlowAnalysis.op_RAISE_VARARGS  r  r   c                 T    |                      | j        d                    d| _        d S )Nr  T)rn  rF  rD  rs  s     r   op_BREAK_LOOPz!ControlFlowAnalysis.op_BREAK_LOOP  s*    		$"2&''' $r   r   )r   )(r   r    r!   r.   r   rJ  rL  rP  r   rk  rn  rW  rp  rr  rq  r  r  r  r  r  op_POP_JUMP_IF_FALSEop_POP_JUMP_IF_TRUEop_JUMP_IF_FALSEop_JUMP_IF_TRUEop_POP_JUMP_FORWARD_IF_FALSEop_POP_JUMP_BACKWARD_IF_FALSEop_POP_JUMP_FORWARD_IF_TRUEop_POP_JUMP_BACKWARD_IF_TRUEr  op_JUMP_IF_FALSE_OR_POPop_JUMP_IF_TRUE_OR_POPr  r  op_JUMP_BACKWARDr  r   r  NotImplementedErrorr  r  r"   r   r   r=  r=    s           ! ! !% % %+ + +# # # #<0 <0 <0|5 5 5 5  	 	 	* * *

, 
, 
,% % %% % %  % % %
% % %
 0.+*O#7 $8!"6#7 % % %
 75% % %% % % '% % % &&&	) 	) 	) 	) 
(	(	(!!),,,% % %% % % % %r   r=  )collectionsr   r   numba.core.irr   numba.core.errorsr   numba.core.utilsr   	frozensetrv  r  r   
namedtupler$   defaultdictr3   rD   r=  r"   r   r   <module>r     s           



       . . . . . . & & & & & & y     
    f   .! ! ! ! !!;!&"HJ J ! ! !(A A A A A/ A A A2C
& C
& C
& C
& C
&f C
& C
& C
&Lr% r% r% r% r%& r% r% r% r% r%r   