
    BVh                         d 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  G d dej                        Z	 G d	 d
ej                        ZddZy)a  Live variable analysis.

See https://en.wikipedia.org/wiki/Live_variable_analysis for a definition of
the following idioms: live variable, live in, live out, which are used
throughout this file.

This analysis attaches the following:
 * symbols that are live at the exit of control flow statements
 * symbols that are live at the entry of control flow statements

Requires activity analysis.
    N)anno)cfg)transformer)annosc                   4     e Zd ZdZ fdZd Zd Zd Z xZS )Analyzerz?CFG visitor that performs liveness analysis at statement level.c                 :    t         t        |   |       || _        y N)superr   __init__include_annotations)selfgraphr   	__class__s      i/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.pyr   zAnalyzer.__init__'   s    	(D"5)2D    c                     t               S r
   )set)r   _s     r   
init_statezAnalyzer.init_state+   s	    5Lr   c                 :    t        |t        j                        ryy)NTF)
isinstancegastLambda)r   fn_ast_nodes     r   lamba_checkzAnalyzer.lamba_check.   s    +t{{+ r   c                    | j                   |   }t        j                  |j                  t        j                  j
                        rIt        j                  |j                  t        j                  j
                        }|j                  }| j                  s||j                  z  }|j                  |j                  z  }t               }|j                  D ]  }|| j                   |   z  } |||z
  z  }t        j                  |j                  t        j                  j                        }	|	D ]^  }
| j                  |
      rt        j                  |
t         j"                  j$                        }||j                  |j&                  z
  z  }` nS| j)                  |      sJ |j                  |f       t               }|j                  D ]  }|| j                   |   z  } |}|| j                   |<   || j*                  |<   ||k7  S r
   )in_r   hasannoast_nodeStaticSCOPEgetannoreadr   annotationsmodifieddeletedr   nextDEFINED_FNS_INr   r   NodeAnnoARGS_AND_BODY_SCOPEbound
can_ignoreout)r   nodeprev_live_in
node_scopegenkilllive_outnlive_inreaching_functionsr   fn_scopes               r   
visit_nodezAnalyzer.visit_node5   s   88D>L||DMM4;;#4#45<<t{{/@/@AjOOc%%z%%%   :#5#55dhyy  !DHHQK x$'g<<
--335+ 4+K(
<<U^^-O-OP 	HMMHNN234 __T"9T]]D$99"hyy  !DHHQK gDHHTNDHHTN 7""r   )	__name__
__module____qualname____doc__r   r   r   r9   __classcell__r   s   @r   r   r   $   s    G3)#r   r   c                   t     e Zd ZdZ fdZ fdZd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Z xZS )TreeAnnotatoraV  Runs liveness analysis on each of the functions defined in the AST.

  If a function defined other local functions, those will have separate CFGs.
  However, dataflow analysis needs to tie up these CFGs to properly emulate the
  effect of closures. In the case of liveness, the parent function's live
  variables must account for the variables that are live at the entry of each
  subfunction. For example:

    def foo():
      # baz is live from here on
      def bar():
        print(baz)

  This analyzer runs liveness analysis on each individual function, accounting
  for the effect above.
  c                 d    t         t        |   |       || _        d| _        || _        d | _        y )NF)r   rA   r   r   allow_skipsgraphscurrent_analyzer)r   source_inforD   r   r   s       r   r   zTreeAnnotator.__init__s   s1    	-'42DDDK Dr   c                    t         t        |   |      }| j                  t	        |t
        j                        r|| j                  j                  j                  v rr| j                  j                  j                  |   }t        j                  |t        j                  j                  t        | j                  j                  |                |S r
   )r   rA   visitrE   r   r   stmtr   indexr   setannor!   LIVE_VARS_IN	frozensetr   )r   r/   cfg_noder   s      r   rH   zTreeAnnotator.visitz   s    +D1D)4#%%++111&&,,2248h
ll411T2266x@ACKr   c                     | j                   }t        | j                  |   | j                        }|j	                          || _         | j                  |      }|| _         |S r
   )rE   r   rD   r   visit_reversegeneric_visit)r   r/   	is_lambdaparent_analyzeranalyzers        r   _analyze_functionzTreeAnnotator._analyze_function   sY    ++OD)4+C+CDH$Dd#D+DKr   c                 (    | j                  |d      S )NTrR   rU   r   r/   s     r   visit_LambdazTreeAnnotator.visit_Lambda   s    !!$$!77r   c                 (    | j                  |d      S )NFrW   rX   rY   s     r   visit_FunctionDefzTreeAnnotator.visit_FunctionDef   s    !!$%!88r   c                 .   | j                   j                  j                  |   }t               }|D ]*  }|j	                  | j                   j
                  |          , t        j                  |t        j                  j                  t        |             |S r
   )rE   r   	stmt_nextr   updater   r   rK   r!   LIVE_VARS_OUTrM   )r   r/   
successorsstmt_live_outss        r   _block_statement_live_outz'TreeAnnotator._block_statement_live_out   sw    &&,,66t<JEM 940044Q789LLt{{00)M2JKKr   c                    || j                   j                  j                  v rF| j                   j                  j                  |   }t        | j                   j                  |         }nrt        j                  |t
        j                  j                        sJ dj                  |             t        j                  |t
        j                  j                        }t        j                  |t
        j                  j                  |       |S )Nz9If not matching a CFG node, must be a block statement: {})rE   r   rJ   rM   r   r   r   r!   rL   formatr#   rK   )r   r/   
entry_noderN   stmt_live_ins        r   _block_statement_live_inz&TreeAnnotator._block_statement_live_in   s    T**00666&&,,22:>ht4488BCl\\*dkk&>&>? $z"$? \\*dkk.F.FGlLLt{{//>Kr   c                 ~    | j                  |      }| j                  |      }| j                  ||j                        S r
   rQ   rd   ri   testrY   s     r   visit_IfzTreeAnnotator.visit_If   9    d#D))$/D((tyy99r   c                 ~    | j                  |      }| j                  |      }| j                  ||j                        S r
   )rQ   rd   ri   iterrY   s     r   	visit_ForzTreeAnnotator.visit_For   rn   r   c                 ~    | j                  |      }| j                  |      }| j                  ||j                        S r
   rk   rY   s     r   visit_WhilezTreeAnnotator.visit_While   rn   r   c                     | j                  |      }| j                  |      }| j                  ||j                  d         S Nr   rQ   rd   ri   bodyrY   s     r   	visit_TryzTreeAnnotator.visit_Try   =    d#D))$/D((tyy|<<r   c                     | j                  |      }| j                  |      }| j                  ||j                  d         S ru   rv   rY   s     r   visit_ExceptHandlerz!TreeAnnotator.visit_ExceptHandler   ry   r   c                 b    | j                  |      }| j                  ||j                  d         S ru   )rQ   ri   itemsrY   s     r   
visit_WithzTreeAnnotator.visit_With   s-    d#D((tzz!}==r   c                    | j                  |      }| j                  j                  j                  |   }t	        j
                  |t        j                  j                  t        | j                  j                  |                |S r
   )
rQ   rE   r   rJ   r   rK   r!   r`   rM   r.   )r   r/   rN   s      r   
visit_ExprzTreeAnnotator.visit_Expr   sg    d#D$$**006HLLt{{0040044X>?AKr   )r:   r;   r<   r=   r   rH   rU   rZ   r\   rd   ri   rm   rq   rs   rx   r{   r~   r   r>   r?   s   @r   rA   rA   a   sN    "!	89
:
:
:
=
=
>r   rA   c                 >    t        |||      j                  |       } | S )a-  Resolves the live symbols at the exit of control flow statements.

  Args:
    node: ast.AST
    source_info: transformer.SourceInfo
    graphs: Dict[ast.FunctionDef, cfg.Graph]
    include_annotations: Bool, whether type annotations should be included in
      the analysis.
  Returns:
    ast.AST
  )rA   rH   )r/   rF   rD   r   s       r   resolver      s#     
{F,?	@	F	Ft	L$	+r   )T)r=   r    tensorflow.python.autograph.pyctr   r   r   0tensorflow.python.autograph.pyct.static_analysisr   GraphVisitorr   BaserA   r    r   r   <module>r      sH     1 0 8 B:#s :#zjK$$ j\r   