ó
\K]c           @   sÕ   d  Z  d d l Z d d l m Z d d l m Z m Z d d l m Z d d l	 m
 Z
 d d l m Z m Z e d d	 ƒ Z i  Z d
 „  Z d „  Z e d d ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z d S(   s   
Utils for IR analysis
iÿÿÿÿN(   t   reduce(   t
   namedtuplet   defaultdict(   t   ir(   t   CFGraph(   t   typest   constst   use_defs_results   usemap,defmapc         C   sÏ  i  } i  } x­|  j  ƒ  D]Ÿ\ } } t ƒ  | | <} t ƒ  | | <} xn| j D]c} t | ƒ t k r t t | ƒ } | | | | ƒ qQ n  t | t j ƒ r{t | j t j	 ƒ rØ t d „  | j j
 ƒ  Dƒ ƒ }	 nx t | j t j ƒ rt | j j g ƒ }	 nK t | j t j t j t j t j f ƒ r8d }	 n t d t | j ƒ ƒ ‚ | j j |	 k r{| j | j j ƒ q{n  x6 | j
 ƒ  D]( }
 |
 j | k rˆ| j |
 j ƒ qˆqˆWqQ Wq Wt d | d | ƒ S(   s*   
    Find variable use/def per block.
    c         s   s   |  ] } | j  Vq d  S(   N(   t   name(   t   .0t   var(    (    s-   lib/python2.7/site-packages/numba/analysis.pys	   <genexpr>(   s    t   unreachablet   usemapt   defmap(    (   t   itemst   sett   bodyt   typet   ir_extension_usedefst
   isinstanceR   t   Assignt   valuet   Instt	   list_varst   VarR   t   Argt   Constt   Globalt   FreeVart   AssertionErrort   targett   addt   _use_defs_result(   t   blockst   var_use_mapt   var_def_mapt   offsett   ir_blockt   use_sett   def_sett   stmtt   funct   rhs_setR
   (    (    s-   lib/python2.7/site-packages/numba/analysis.pyt   compute_use_defs   s2    "	c   	         s   d „  ‰ ‡ f d †  } ‡  ‡ ‡ f d †  } ‡  ‡ ‡ f d †  } i  } x( | j  ƒ  D] } t ˆ | ƒ | | <qU Wt t ƒ ‰ | | ˆ ƒ | | | ƒ | S(   s¾   
    Find variables that must be alive at the ENTRY of each block.
    We use a simple fix-point algorithm that iterates until the set of
    live variables is unchanged for each block.
    c         S   s   t  d „  |  j ƒ  Dƒ ƒ S(   sF   Helper function to determine if a fix-point has been reached.
        c         s   s   |  ] } t  | ƒ Vq d  S(   N(   t   len(   R	   t   v(    (    s-   lib/python2.7/site-packages/numba/analysis.pys	   <genexpr>E   s    (   t   tuplet   values(   t   dct(    (    s-   lib/python2.7/site-packages/numba/analysis.pyt   fix_point_progressB   s    c            sE   d } ˆ  | ƒ } x, | | k r@ |  | ƒ | } ˆ  | ƒ } q Wd S(   s4   Helper function to run fix-point algorithm.
        N(   t   None(   t   fnR0   t	   old_pointt	   new_point(   R1   (    s-   lib/python2.7/site-packages/numba/analysis.pyt	   fix_pointG   s    
c            sk   xd ˆ D]\ } ˆ | ˆ | B} |  | c | O<x1 ˆ  j  | ƒ D]  \ } } |  | c |  | O<q? Wq Wd S(   sG   Find all variable definition reachable at the entry of a block
        N(   t
   successors(   R0   R$   t   used_or_definedt   out_blkt   _(   t   cfgR#   R"   (    s-   lib/python2.7/site-packages/numba/analysis.pyt	   def_reachQ   s
    c            se   x^ |  D]V } |  | } xC ˆ  j  | ƒ D]2 \ } } | ˆ | @} |  | c | ˆ | O<q' Wq Wd S(   s?   Find live variables.

        Push var usage backward.
        N(   t   predecessors(   R0   R$   t	   live_varst   inc_blkt   _datat	   reachable(   R;   t   def_reach_mapR#   (    s-   lib/python2.7/site-packages/numba/analysis.pyt   liveness[   s
    
(   t   keysR   R   (	   R;   R!   R"   R#   R6   R<   RC   t   live_mapR$   (    (   R;   RB   R1   R#   R"   s-   lib/python2.7/site-packages/numba/analysis.pyt   compute_live_map<   s    	

t   dead_maps_results   internal,escaping,combinedc            s*  t  t ƒ ‰  t  t ƒ ‰ t  t ƒ } x| j ƒ  D]ú \ } } ˆ | | | B} t ‡ f d †  |  j | ƒ Dƒ ƒ } t d „  | j j ƒ  Dƒ ƒ }	 t t j	 | j
 ƒ  t ƒ  ƒ }
 |
 |	 O}
 | |
 } | ˆ | <| | } x< | j ƒ  D]. \ } } | | | B} ˆ  | c | | O<qæ W| s1 |	 | | <q1 q1 Wt t j	 ˆ j
 ƒ  t ƒ  ƒ } t t j	 ˆ j
 ƒ  t ƒ  ƒ } t t j	 ˆ  j
 ƒ  t ƒ  ƒ } t t j	 | j
 ƒ  t ƒ  ƒ } | | B| B} | | } | rò|  j ƒ  sÔqòd j | ƒ } t | ƒ ‚ n  t ‡  ‡ f d †  | Dƒ ƒ } t d ˆ d ˆ  d | ƒ S(   s©   
    Compute the end-of-live information for variables.
    `live_map` contains a mapping of block offset to all the living
    variables at the ENTRY of the block.
    c         3   s%   |  ] \ } } | ˆ  | f Vq d  S(   N(    (   R	   R9   R@   (   RE   (    s-   lib/python2.7/site-packages/numba/analysis.pys	   <genexpr>Š   s   c         s   s   |  ] } | j  Vq d  S(   N(   R   (   R	   R-   (    (    s-   lib/python2.7/site-packages/numba/analysis.pys	   <genexpr>   s   s#   liveness info missing for vars: {0}c         3   s'   |  ] } | ˆ | ˆ  | Bf Vq d  S(   N(    (   R	   t   k(   t   escaping_dead_mapt   internal_dead_map(    s-   lib/python2.7/site-packages/numba/analysis.pys	   <genexpr>¶   s   t   internalt   escapingt   combined(   R   R   R   t   dictR7   t
   terminatorR   R    t   operatort   or_R/   t   exit_pointst   formatt   RuntimeErrort   _dead_maps_result(   R;   R!   RE   R#   t   exit_dead_mapR$   R%   t   cur_live_sett   outgoing_live_mapt   terminator_livesett   combined_livesett   internal_sett   escaping_live_setR9   t   new_live_sett   all_varst   internal_dead_varst   escaping_dead_varst   exit_dead_varst	   dead_varst   missing_varst   msgRM   (    (   RI   RJ   RE   s-   lib/python2.7/site-packages/numba/analysis.pyt   compute_dead_mapsv   sL    		




c            s±   t  t ƒ ‰  ‡  f d †  } d } | ƒ  } x€ | | k r¬ x^ | D]V } ˆ  | | | B} | | | 8} x- |  j | ƒ D] \ }	 }
 ˆ  |	 c | O<qv Wq@ W| } | ƒ  } q- Wˆ  S(   sÙ   
    Compute the live variables at the beginning of each block
    and at each yield point.
    The ``var_def_map`` and ``var_dead_map`` indicates the variable defined
    and deleted at each block, respectively.
    c              s   t  t t ˆ  j ƒ  ƒ ƒ S(   N(   R.   t   mapR,   R/   (    (   t   block_entry_vars(    s-   lib/python2.7/site-packages/numba/analysis.pyR1   È   s    N(   R   R   R2   R7   (   R;   R!   R#   t   var_dead_mapR1   R4   R5   R$   t   availt   succR@   (    (   Rg   s-   lib/python2.7/site-packages/numba/analysis.pyt   compute_live_variables¾   s    		c         C   s•   t  ƒ  } x |  D] } | j | ƒ q WxJ |  j ƒ  D]< \ } } | j } x$ | j ƒ  D] } | j | | ƒ qV Wq4 W| j t |  ƒ ƒ | j ƒ  | S(   N(	   R   t   add_nodeR   RO   t   get_targetst   add_edget   set_entry_pointt   mint   process(   R!   R;   RH   t   bt   termR   (    (    s-   lib/python2.7/site-packages/numba/analysis.pyt   compute_cfg_from_blocksë   s    		
c         c   s¡   t  ƒ  } x] |  j ƒ  j ƒ  D]I } t  | j ƒ t  | j ƒ Bt  | j ƒ B} | j | j ƒ | | O} q Wx1 |  j ƒ  j ƒ  D] } | j | k r| | Vq| q| Wd S(   sK   
    A generator that yields toplevel loops given a control-flow-graph
    N(   R   t   loopsR/   R   t   entriest   exitst   discardt   header(   R;   t   blocks_in_loopt   loopt   insiders(    (    s-   lib/python2.7/site-packages/numba/analysis.pyt   find_top_level_loopsú   s    	)c            s‡  d d l  m ‰ m ‰ m } m } d ‰  ‡ ‡ f d †  } ‡ f d †  ‰ ‡  ‡ f d †  } ‡  ‡ f d †  } d t f d	 „  ƒ  Y‰ ‡ ‡ f d
 †  } ˆ  d k rÀ d j d d ƒ GH|  j ƒ  GHn  | |  ƒ } g  }	 xY| D]Q\ ‰ }
 } g  } t |
 t	 j
 ƒ rÙ |
 j d k rÙ | } xÃ |
 j |
 j g D]¯ } ˆ ƒ  } ˆ ˆ |  | ƒ } t | t	 j ƒ rs| | j ƒ } | } nE y1 | |  | ƒ } | d k r£t j d ƒ } n  Wn | k
 r·n Xt | ˆ ƒ s(| j | ƒ q(q(Wt | ƒ d k r*| ˆ |
 | | Œ \ } } | r'|	 j |
 | f ƒ q'q*qÙ qÙ Wg  |	 D] } | d ^ q5} x¿ | D]· \ } } } | | k rRx™ | j D]‹ } t | t	 j ƒ rw| j | k rw|	 | j | ƒ d } t	 j | d | j ƒ| _ |  j | j j } | j | ƒ } | j | | <qwqwWqRqRWt |  j ƒ } x | j ƒ  D] } |  j | =q)W|	 rXt  j! |  ƒ |  _" n  ˆ  d k rƒd j d d ƒ GH|  j ƒ  GHn  d S(   sÓ   
    Removes dead branches based on constant inference from function args.
    This directly mutates the IR.

    func_ir is the IR
    called_args are the actual arguments with which the function is called
    i   (   t   get_definitiont   guardt
   find_constt   GuardExceptioni    c            s‰   g  } x| |  j  j ƒ  D]k } | j d } t | t j ƒ r | } ˆ ˆ  |  | j j ƒ } | d  k	 r | j	 | | | f ƒ q q q W| S(   Niÿÿÿÿ(
   R!   R/   R   R   R   t   Brancht   condR   R2   t   append(   t   func_irt   branchest   blkt   branch_or_jumpt   brancht	   condition(   R~   R   (    s-   lib/python2.7/site-packages/numba/analysis.pyt   find_branches  s     c            sT   |  r ˆ  j  n ˆ  j } t j | d ˆ  j ƒ} | | j d <| ˆ  j  k rP d Sd S(   Nt   lociÿÿÿÿi   i    (   t   truebrt   falsebrR   t   JumpRŒ   R   (   t   take_truebrR‡   t   keept   jmp(   R‰   (    s-   lib/python2.7/site-packages/numba/analysis.pyt   do_prune#  s    c            sÒ   | \ } } t  | t j ƒ } t  | t j ƒ } | s< | rÈ y | j | | ƒ } Wn t k
 rl t d  f SXˆ  d k r¯ | rˆ |  j n |  j }	 d |	 |  | | | j f GHn  ˆ | | ƒ }
 t	 |
 f St d  f S(   Ni    s
   Pruning %s(
   R   R   t   NoneTypeR3   t	   Exceptiont   FalseR2   RŽ   R   t   True(   R‰   RŠ   R‡   t   condst   lhs_condt   rhs_condt   lhs_nonet   rhs_noneR   t   killt   taken(   t   DEBUGR“   (    s-   lib/python2.7/site-packages/numba/analysis.pyt   prune_by_type*  s    
c   	         s˜   | \ } } y | j  | | ƒ } Wn t k
 r< t d  f SXˆ  d k r | rX |  j n |  j } d | |  | | | j  f GHn  ˆ | | ƒ } t | f S(   Ni    s
   Pruning %s(   R3   R•   R–   R2   RŽ   R   R—   (	   R‰   RŠ   R‡   R˜   R™   Rš   R   R   Rž   (   RŸ   R“   (    s-   lib/python2.7/site-packages/numba/analysis.pyt   prune_by_value=  s    t   Unknownc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s-   lib/python2.7/site-packages/numba/analysis.pyR¢   I  s   c            s€   ˆ |  } t  | t j ƒ r  | St  | t j ƒ rm | j } t  | t j ƒ rQ | S| d k rm t j d ƒ Sn  t | d ˆ  ƒ  ƒ S(   sC   
        Resolves an input arg to a constant (if possible)
        t   nonet   literal_typeN(   R   R   R”   t   OmittedR   R2   t   getattr(   t   input_arg_idxt   input_arg_tyt   val(   R¢   t   called_args(    s-   lib/python2.7/site-packages/numba/analysis.pyt   resolve_input_arg_constL  s    
	t   beforeiP   t   -t   binopR¥   i   RŒ   t   afterN(#   t   ir_utilsR~   R   R€   R   t   objectt   centert   dumpR   R   t   Exprt   opt   lhst   rhsR   t   indexR2   R   R”   R„   R,   R   R   R   R   RŒ   t   _definitionsR   R   Rt   R!   t
   dead_nodesR   t   ConstantInferencet   _consts(   R…   R¬   R€   R   R‹   R    R¡   R­   t   branch_infot   nullified_conditionsRŠ   R‡   t   const_condst   prunet   argt   resolved_constt   arg_deft
   prune_statRž   t   xt   deadcondR:   Rƒ   t
   branch_bitt   defnst   repl_idxR;   t   dead(    (   RŸ   R¢   R‰   R¬   R“   R~   R   s-   lib/python2.7/site-packages/numba/analysis.pyt   dead_branch_prune  sj    "!		 !(   t   __doc__RP   t	   functoolsR    t   collectionsR   R   t   numbaR   t   numba.controlflowR   R   R   R    R   R+   RF   RU   Re   Rk   Rt   R}   RÍ   (    (    (    s-   lib/python2.7/site-packages/numba/analysis.pyt   <module>   s    	%	7	H	-		