o
    2g                     @  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 ddlmZ ddlmZ ddlmZ dddZG dd deZdS )a  Bool register elimination optimization.

Example input:

  L1:
    r0 = f()
    b = r0
    goto L3
  L2:
    r1 = g()
    b = r1
    goto L3
  L3:
    if b goto L4 else goto L5

The register b is redundant and we replace the assignments with two copies of
the branch in L3:

  L1:
    r0 = f()
    if r0 goto L4 else goto L5
  L2:
    r1 = g()
    if r1 goto L4 else goto L5

This helps generate simpler IR for tagged integers comparisons, for example.
    )annotations)FuncIR)Assign
BasicBlockBranchGotoRegisterUnreachable)LowLevelIRBuilder)CompilerOptions)IRTransformfnr   optionsr   returnNonec                   sD  i i }i }j D ];}t|jD ]3\}}| D ]}t|tr)|dd |< q|dkrCt|trCt|jtrC|||j< |||j< qq	fdd|D  j D ]0}t|jD ](\}}t|t	r|j
 v r|j|d  }t|tr{|j||j
 u s |j
 qYqRtd |}	t|	 fdd| D }
|
j  |	j _ d S )Nr      c                   s*   h | ]}  |d dkr|jvr|qS )r   r   )getarg_regs).0r)countsr    X/home/garg/my-data/venv/lib/python3.10/site-packages/mypyc/transform/flag_elimination.py	<setcomp>5   s    $z&do_flag_elimination.<locals>.<setcomp>c                   s   i | ]\}}| v r||qS r   r   )r   xy)
candidatesr   r   
<dictcomp>D   s    z'do_flag_elimination.<locals>.<dictcomp>)blocks	enumerateopssources
isinstancer   r   r   valuer   destr   labelremover
   FlagEliminationTransformitemstransform_blocks)r   r   brancheslabelsblockiopsrcnext_opbuilder	transformr   )r   r   r   r   do_flag_elimination&   s>   



	

r3   c                      s<   e Zd Zd fddZdddZdddZdddZ  ZS )r'   r1   r
   
branch_mapdict[Register, Branch]r   r   c                   s$   t  | || _t| | _d S N)super__init__r4   setvaluesr*   )selfr1   r4   	__class__r   r   r8   K   s   z!FlagEliminationTransform.__init__r.   r   c                 C  s^   | j |j}|r(t|j|j|j|j|j|j	d}|j
|_
|j|_| | d S | | d S )N)rare)r4   r   r$   r   r/   truefalser.   liner>   negatedtraceback_entryadd)r;   r.   
old_branch
new_branchr   r   r   visit_assignP   s   z%FlagEliminationTransform.visit_assignr   c                 C  s   | j |j d S r6   )r1   gotor%   r;   r.   r   r   r   
visit_gotoc   s   z#FlagEliminationTransform.visit_gotor   c                 C  s(   || j v r| t  d S | | d S r6   )r*   rD   r	   rI   r   r   r   visit_branchg   s   
z%FlagEliminationTransform.visit_branch)r1   r
   r4   r5   r   r   )r.   r   r   r   )r.   r   r   r   )r.   r   r   r   )__name__
__module____qualname__r8   rG   rJ   rK   __classcell__r   r   r<   r   r'   J   s
    

r'   N)r   r   r   r   r   r   )__doc__
__future__r   mypyc.ir.func_irr   mypyc.ir.opsr   r   r   r   r   r	   mypyc.irbuild.ll_builderr
   mypyc.optionsr   mypyc.transform.ir_transformr   r3   r'   r   r   r   r   <module>   s     
$