o
    tBhJ                     @  s"  d Z ddlmZ ddlmZ ddlmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 G dd dZ6dHddZ7dIddZ8dJddZ9edZ:eeee;f e
e: f Z<G dd dee: Z=ee
e: e
e: f Z>G dd de*e>e:  Z?G dd de?e5 Z@dKd d!ZA	"dLdMd'd(ZBG d)d* d*e?e5 ZCdNd,d-ZDG d.d/ d/e?e5 ZEdKd0d1ZFdOd4d5ZGG d6d7 d7e?e5 ZHdPd8d9ZIdZJd:ZK	;dQdRdFdGZLd;S )SzData-flow analyses.    )annotations)abstractmethod)DictGenericIterableIteratorSetTupleTypeVar)
all_values)&AssignAssignMulti
BasicBlockBoxBranchCallCallCCastComparisonOp	ControlOpExtendGetAttrGetElementPtrGoto
InitStaticIntegerIntOp	KeepAliveLoadAddressLoadErrorValue
LoadGlobalLoadLiteralLoadMem
LoadStatic
MethodCallOp	OpVisitorRaiseStandardError
RegisterOpReturnSetAttrSetMemTruncateTupleGetTupleSetUnboxUnreachableValuec                   @  s$   e Zd ZdZdd	d
ZdddZdS )CFGzyControl-flow graph.

    Node 0 is always assumed to be the entry point. There must be a
    non-empty set of exits.
    succ"dict[BasicBlock, list[BasicBlock]]predexitsset[BasicBlock]returnNonec                 C  s   |sJ || _ || _|| _d S N)r3   r5   r6   )selfr3   r5   r6    r<   n/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/mypyc/analysis/dataflow.py__init__:   s   
zCFG.__init__strc                 C  sJ   g }| dt| jdd d  | d| j  | d| j  d|S )Nz	exits: %sc                 S  s   | j S r:   label)er<   r<   r=   <lambda>G   s    zCFG.__str__.<locals>.<lambda>)keyzsucc: %szpred: %s
)appendsortedr6   r3   r5   join)r;   linesr<   r<   r=   __str__E   s
   
zCFG.__str__N)r3   r4   r5   r4   r6   r7   r8   r9   r8   r?   )__name__
__module____qualname____doc__r>   rJ   r<   r<   r<   r=   r2   3   s    
r2   blockslist[BasicBlock]r8   c           
      C  s   i }i }t  }| D ];}tdd |jdd D rJ dt|j }|s+|| |g| D ]}|jr;||j q0|||< g ||< q	|	 D ]\}}|D ]	}	||	 | qOqIt
|||S )zCalculate basic block control-flow graph.

    The result is a dictionary like this:

         basic block index -> (successors blocks, predecesssor blocks)
    c                 s  s    | ]}t |tV  qd S r:   )
isinstancer   ).0opr<   r<   r=   	<genexpr>Y   s    

zget_cfg.<locals>.<genexpr>Nz-Control-flow ops must be at the end of blocks)setanyopslist
terminatortargetsadderror_handlerrF   itemsr2   )
rP   succ_mappred_mapr6   blockr3   error_pointprevnxtrA   r<   r<   r=   get_cfgM   s.   


rf   rA   r   c                 C  s.   t | jdkrt| jd tr| jd j} | S )N   rV   )lenrY   rR   r   rA   r@   r<   r<   r=   get_real_targety   s   ri   r9   c                 C  s   d}|rL| D ]}t |j D ]\}}|j|t| qqd}t| }| dd }|   t |D ]\}}|dks?|j| rE| | q2d}q2|sdS dS )zCleanup the control flow graph.

    This eliminates obviously dead basic blocks and eliminates blocks that contain
    nothing but a single jump.

    There is a lot more that could be done.
    TFNr   )		enumerater[   r\   
set_targetri   rf   clearr5   rF   )rP   changedrb   itgtcfgorig_blocksr<   r<   r=   cleanup_cfg   s   rr   Tc                   @  s    e Zd ZdddZdd	d
ZdS )AnalysisResultbeforeAnalysisDict[T]afterr8   r9   c                 C  s   || _ || _d S r:   ru   rw   )r;   ru   rw   r<   r<   r=   r>      s   
zAnalysisResult.__init__r?   c                 C  s   d| j  d| j dS )Nzbefore: z
after: rE   rx   )r;   r<   r<   r=   rJ      s   zAnalysisResult.__str__N)ru   rv   rw   rv   r8   r9   rK   )rL   rM   rN   r>   rJ   r<   r<   r<   r=   rt      s    
rt   c                   @  s>  e Zd Zd\ddZed]dd	Zed^ddZed_ddZed`ddZdaddZ	dbddZ
dcddZddddZded d!Zdfd#d$Zdgd&d'Zdhd)d*Zdid,d-Zdjd/d0Zdkd2d3Zdld5d6Zdmd8d9Zdnd;d<Zdod>d?ZdpdAdBZdqdDdEZdrdGdHZdsdJdKZdtdMdNZdudPdQZdvdSdTZdwdVdWZdxdYdZZ d[S )yBaseAnalysisVisitorrT   r   r8   GenAndKill[T]c                 C     t  t  fS r:   rW   r;   rT   r<   r<   r=   
visit_goto      zBaseAnalysisVisitor.visit_gotor(   c                 C     t r:   NotImplementedErrorr}   r<   r<   r=   visit_register_op      z%BaseAnalysisVisitor.visit_register_opr   c                 C  r   r:   r   r}   r<   r<   r=   visit_assign   r   z BaseAnalysisVisitor.visit_assignr   c                 C  r   r:   r   r}   r<   r<   r=   visit_assign_multi   r   z&BaseAnalysisVisitor.visit_assign_multir+   c                 C  r   r:   r   r}   r<   r<   r=   visit_set_mem   r   z!BaseAnalysisVisitor.visit_set_memr   c                 C  
   |  |S r:   r   r}   r<   r<   r=   
visit_call      
zBaseAnalysisVisitor.visit_callr$   c                 C  r   r:   r   r}   r<   r<   r=   visit_method_call   r   z%BaseAnalysisVisitor.visit_method_callr   c                 C  r   r:   r   r}   r<   r<   r=   visit_load_error_value   r   z*BaseAnalysisVisitor.visit_load_error_valuer!   c                 C  r   r:   r   r}   r<   r<   r=   visit_load_literal   r   z&BaseAnalysisVisitor.visit_load_literalr   c                 C  r   r:   r   r}   r<   r<   r=   visit_get_attr   r   z"BaseAnalysisVisitor.visit_get_attrr*   c                 C  r   r:   r   r}   r<   r<   r=   visit_set_attr   r   z"BaseAnalysisVisitor.visit_set_attrr#   c                 C  r   r:   r   r}   r<   r<   r=   visit_load_static   r   z%BaseAnalysisVisitor.visit_load_staticr   c                 C  r   r:   r   r}   r<   r<   r=   visit_init_static   r   z%BaseAnalysisVisitor.visit_init_staticr-   c                 C  r   r:   r   r}   r<   r<   r=   visit_tuple_get   r   z#BaseAnalysisVisitor.visit_tuple_getr.   c                 C  r   r:   r   r}   r<   r<   r=   visit_tuple_set   r   z#BaseAnalysisVisitor.visit_tuple_setr   c                 C  r   r:   r   r}   r<   r<   r=   	visit_box   r   zBaseAnalysisVisitor.visit_boxr/   c                 C  r   r:   r   r}   r<   r<   r=   visit_unbox   r   zBaseAnalysisVisitor.visit_unboxr   c                 C  r   r:   r   r}   r<   r<   r=   
visit_cast   r   zBaseAnalysisVisitor.visit_castr'   c                 C  r   r:   r   r}   r<   r<   r=   visit_raise_standard_error   r   z.BaseAnalysisVisitor.visit_raise_standard_errorr   c                 C  r   r:   r   r}   r<   r<   r=   visit_call_c   r   z BaseAnalysisVisitor.visit_call_cr,   c                 C  r   r:   r   r}   r<   r<   r=   visit_truncate   r   z"BaseAnalysisVisitor.visit_truncater   c                 C  r   r:   r   r}   r<   r<   r=   visit_extend   r   z BaseAnalysisVisitor.visit_extendr    c                 C  r   r:   r   r}   r<   r<   r=   visit_load_global   r   z%BaseAnalysisVisitor.visit_load_globalr   c                 C  r   r:   r   r}   r<   r<   r=   visit_int_op   r   z BaseAnalysisVisitor.visit_int_opr   c                 C  r   r:   r   r}   r<   r<   r=   visit_comparison_op   r   z'BaseAnalysisVisitor.visit_comparison_opr"   c                 C  r   r:   r   r}   r<   r<   r=   visit_load_mem   r   z"BaseAnalysisVisitor.visit_load_memr   c                 C  r   r:   r   r}   r<   r<   r=   visit_get_element_ptr   r   z)BaseAnalysisVisitor.visit_get_element_ptrr   c                 C  r   r:   r   r}   r<   r<   r=   visit_load_address  r   z&BaseAnalysisVisitor.visit_load_addressr   c                 C  r   r:   r   r}   r<   r<   r=   visit_keep_alive  r   z$BaseAnalysisVisitor.visit_keep_aliveN)rT   r   r8   rz   )rT   r(   r8   rz   )rT   r   r8   rz   )rT   r   r8   rz   )rT   r+   r8   rz   )rT   r   r8   rz   )rT   r$   r8   rz   )rT   r   r8   rz   )rT   r!   r8   rz   )rT   r   r8   rz   )rT   r*   r8   rz   )rT   r#   r8   rz   )rT   r   r8   rz   )rT   r-   r8   rz   )rT   r.   r8   rz   )rT   r   r8   rz   )rT   r/   r8   rz   )rT   r   r8   rz   )rT   r'   r8   rz   )rT   r   r8   rz   )rT   r,   r8   rz   )rT   r   r8   rz   )rT   r    r8   rz   )rT   r   r8   rz   )rT   r   r8   rz   )rT   r"   r8   rz   )rT   r   r8   rz   )rT   r   r8   rz   )rT   r   r8   rz   )!rL   rM   rN   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   r<   r<   r=   ry      sD    























ry   c                   @  sb   e Zd ZdZd!d"ddZd#ddZd$ddZd%ddZd&ddZd'ddZ	d(ddZ
d)ddZd S )*DefinedVisitora  Visitor for finding defined registers.

    Note that this only deals with registers and not temporaries, on
    the assumption that we never access temporaries when they might be
    undefined.

    If strict_errors is True, then we regard any use of LoadErrorValue
    as making a register undefined. Otherwise we only do if
    `undefines` is set on the error value.

    This lets us only consider the things we care about during
    uninitialized variable checking while capturing all possibly
    undefined things for refcounting.
    Fstrict_errorsboolr8   r9   c                 C  
   || _ d S r:   r   )r;   r   r<   r<   r=   r>     r   zDefinedVisitor.__init__rT   r   GenAndKill[Value]c                 C  r{   r:   r|   r}   r<   r<   r=   visit_branch  r   zDefinedVisitor.visit_branchr)   c                 C  r{   r:   r|   r}   r<   r<   r=   visit_return  r   zDefinedVisitor.visit_returnr0   c                 C  r{   r:   r|   r}   r<   r<   r=   visit_unreachable!  r   z DefinedVisitor.visit_unreachabler(   c                 C  r{   r:   r|   r}   r<   r<   r=   r   $  r   z DefinedVisitor.visit_register_opr   c                 C  s6   t |jtr|jjs| jrt |jhfS |jht fS r:   )rR   srcr   	undefinesr   rW   destr}   r<   r<   r=   r   '  s   zDefinedVisitor.visit_assignr   c                 C  r{   r:   r|   r}   r<   r<   r=   r   .  s   z!DefinedVisitor.visit_assign_multir+   c                 C  r{   r:   r|   r}   r<   r<   r=   r   2  r   zDefinedVisitor.visit_set_memNF)r   r   r8   r9   rT   r   r8   r   rT   r)   r8   r   rT   r0   r8   r   rT   r(   r8   r   rT   r   r8   r   rT   r   r8   r   rT   r+   r8   r   )rL   rM   rN   rO   r>   r   r   r   r   r   r   r   r<   r<   r<   r=   r     s    





r   rp   initial_defined
set[Value]AnalysisResult[Value]c                 C  s   t | |t |dtdS )zCalculate potentially defined registers at each CFG location.

    A register is defined if it has a value along some path from the initial location.
    FrP   rp   gen_and_killinitialbackwardkind)run_analysisr   MAYBE_ANALYSIS)rP   rp   r   r<   r<   r=   analyze_maybe_defined_regs6  s   r   FregsIterable[Value]r   r   c              	   C  s    t | |t|d|dtt|dS )aI  Calculate always defined registers at each CFG location.

    This analysis can work before exception insertion, since it is a
    sound assumption that registers defined in a block might not be
    initialized in its error handler.

    A register is defined if it has a value along all paths from the
    initial location.
    r   FrP   rp   r   r   r   r   universe)r   r   MUST_ANALYSISrW   )rP   rp   r   r   r   r<   r<   r=   analyze_must_defined_regsG  s   r   c                   @  s\   e Zd ZdddZd d
dZd!ddZd"ddZd#ddZd$ddZd%ddZ	d&ddZ
dS )'BorrowedArgumentsVisitorargsr   r8   r9   c                 C  r   r:   )r   )r;   r   r<   r<   r=   r>   c  r   z!BorrowedArgumentsVisitor.__init__rT   r   r   c                 C  r{   r:   r|   r}   r<   r<   r=   r   f  r   z%BorrowedArgumentsVisitor.visit_branchr)   c                 C  r{   r:   r|   r}   r<   r<   r=   r   i  r   z%BorrowedArgumentsVisitor.visit_returnr0   c                 C  r{   r:   r|   r}   r<   r<   r=   r   l  r   z*BorrowedArgumentsVisitor.visit_unreachabler(   c                 C  r{   r:   r|   r}   r<   r<   r=   r   o  r   z*BorrowedArgumentsVisitor.visit_register_opr   c                 C  s&   |j | jv rt |j hfS t t fS r:   )r   r   rW   r}   r<   r<   r=   r   r  s   z%BorrowedArgumentsVisitor.visit_assignr   c                 C  r{   r:   r|   r}   r<   r<   r=   r   w  r   z+BorrowedArgumentsVisitor.visit_assign_multir+   c                 C  r{   r:   r|   r}   r<   r<   r=   r   z  r   z&BorrowedArgumentsVisitor.visit_set_memN)r   r   r8   r9   r   r   r   r   r   r   r   )rL   rM   rN   r>   r   r   r   r   r   r   r   r<   r<   r<   r=   r   b  s    






r   borrowedc              	   C  s   t | |t||dt|dS )zCalculate arguments that can use references borrowed from the caller.

    When assigning to an argument, it no longer is borrowed.
    Fr   )r   r   r   )rP   rp   r   r<   r<   r=   analyze_borrowed_arguments~  s   r   c                   @  R   e Zd ZdddZddd	ZdddZdddZdddZdddZd ddZ	dS )!UndefinedVisitorrT   r   r8   r   c                 C  r{   r:   r|   r}   r<   r<   r=   r     r   zUndefinedVisitor.visit_branchr)   c                 C  r{   r:   r|   r}   r<   r<   r=   r     r   zUndefinedVisitor.visit_returnr0   c                 C  r{   r:   r|   r}   r<   r<   r=   r     r   z"UndefinedVisitor.visit_unreachabler(   c                 C  s   t  |js	|hfS t  fS r:   )rW   is_voidr}   r<   r<   r=   r     s   z"UndefinedVisitor.visit_register_opr   c                 C     t  |jhfS r:   rW   r   r}   r<   r<   r=   r        zUndefinedVisitor.visit_assignr   c                 C  r   r:   r   r}   r<   r<   r=   r     r   z#UndefinedVisitor.visit_assign_multir+   c                 C  r{   r:   r|   r}   r<   r<   r=   r     r   zUndefinedVisitor.visit_set_memNr   r   r   r   r   r   r   
rL   rM   rN   r   r   r   r   r   r   r   r<   r<   r<   r=   r     s    





r   c                 C  s(   t tg | | }t| |t |dtdS )zCalculate potentially undefined registers at each CFG location.

    A register is undefined if there is some path from initial block
    where it has an undefined value.

    Function arguments are assumed to be always defined.
    Fr   )rW   r   r   r   r   )rP   rp   r   initial_undefinedr<   r<   r=   analyze_undefined_regs  s   
r   rT   r%   c                 C  s,   t  }|  D ]}t|ts|| q|S r:   )rW   sourcesrR   r   r]   )rT   resultsourcer<   r<   r=   non_trivial_sources  s   

r   c                   @  r   )!LivenessVisitorrT   r   r8   r   c                 C     t |t fS r:   r   rW   r}   r<   r<   r=   r     r   zLivenessVisitor.visit_branchr)   c                 C  s&   t |jts|jht fS t t fS r:   )rR   valuer   rW   r}   r<   r<   r=   r     s   zLivenessVisitor.visit_returnr0   c                 C  r{   r:   r|   r}   r<   r<   r=   r     r   z!LivenessVisitor.visit_unreachabler(   c                 C  s"   t |}|js||hfS |t fS r:   )r   r   rW   )r;   rT   genr<   r<   r=   r     s   

z!LivenessVisitor.visit_register_opr   c                 C     t ||jhfS r:   r   r   r}   r<   r<   r=   r        zLivenessVisitor.visit_assignr   c                 C  r   r:   r   r}   r<   r<   r=   r     r   z"LivenessVisitor.visit_assign_multir+   c                 C  r   r:   r   r}   r<   r<   r=   r     r   zLivenessVisitor.visit_set_memNr   r   r   r   r   r   r   r   r<   r<   r<   r=   r     s    





r   c                 C  s   t | |t t dtdS )zCalculate live registers at each CFG location.

    A register is live at a location if it can be read along some CFG path starting
    from the location.
    Tr   )r   r   rW   r   )rP   rp   r<   r<   r=   analyze_live_regs  s   r   rg   Nr   OpVisitor[GenAndKill[T]]r   set[T]r   intr   r   set[T] | NoneAnalysisResult[T]c                  C  s~  i }i }| D ]3}	t  }
t  }|	j}|rtt|}|D ]}||\}}|
| |B }
|| |B }q|
||	< |||	< qt| }|sG|ddd }t |}i }i }| D ]%}	|tkrbt  ||	< t  ||	< qQ|dusjJ dt |||	< t |||	< qQ|r|j}|j}n|j}|j}|r| }|	| || rd}|| D ]}|du rt || }q|tkr||| O }q||| M }q|dusJ nt |}|||< |||  || B }||| kr|| D ]}||vr|
| || q|||< |si }i }| D ]7}	|	}|| }t|	j}|rtt|}|D ]\}}||||f< ||\}}|| |B }||||f< qq|r:||}}t||S )aP  Run a general set-based data flow analysis.

    Args:
        blocks: All basic blocks
        cfg: Control-flow graph for the code
        gen_and_kill: Implementation of gen and kill functions for each op
        initial: Value of analysis for the entry points (for a forward analysis) or the
            exit points (for a backward analysis)
        kind: MUST_ANALYSIS or MAYBE_ANALYSIS
        backward: If False, the analysis is a forward analysis; it's backward otherwise
        universe: For a must analysis, the set of all possible values. This is the starting
            value for the work list algorithm, which will narrow this down until reaching a
            fixed point. For a maybe analysis the iteration always starts from an empty set
            and this argument is ignored.

    Return analysis results: (before, after)
    NrV   z,Universe must be defined for a must analysis)rW   rY   rZ   reversedacceptr   r3   r5   popremoverF   r]   rj   rt   ) rP   rp   r   r   r   r   r   	block_gen
block_killrb   r   killrY   rT   opgenopkillworklistworksetru   rw   ra   r`   rA   
new_beforer5   	new_afterr3   	op_beforeop_aftercurops_enumidxr<   r<   r=   r     s   







r   )rP   rQ   r8   r2   )rA   r   r8   r   )rP   rQ   r8   r9   )rP   rQ   rp   r2   r   r   r8   r   r   )rP   rQ   rp   r2   r   r   r   r   r   r   r8   r   )rP   rQ   rp   r2   r   r   r8   r   )rT   r%   r8   r   )rP   rQ   rp   r2   r8   r   r:   )rP   rQ   rp   r2   r   r   r   r   r   r   r   r   r   r   r8   r   )MrO   
__future__r   abcr   typingr   r   r   r   r   r	   r
   mypyc.ir.func_irr   mypyc.ir.opsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   rf   ri   rr   rs   r   AnalysisDictrt   
GenAndKillry   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   r<   r<   r=   <module>   s<    $*

,
	]
.




