
    J/Phn                         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
mZmZmZ ddl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 edd          Zd Zd Zd Zi Zd ZdS )z
Utils for IR analysis
    N)reduce)
namedtupledefaultdict   )CFGraph)typeserrorsirconsts)specialuse_defs_resultzusemap,defmapc           	      (   i }i }|                                  D ]\  }}t                      x||<   }t                      x||<   }|j        D ]}t          |          t          v r(t          t          |                   } ||||           At          |t          j                  rt          |j        t          j	                  r1t          d |j        
                                D                       }	nt          |j        t          j                  rt          |j        j        g          }	nft          |j        t          j        t          j        t          j        t          j        f          rd}	n"t#          dt          |j                            |j        j        |	vr|                    |j        j                   |
                                D ]%}
|
j        |vr|                    |
j                   &t)          ||          S )z*
    Find variable use/def per block.
    c              3   $   K   | ]}|j         V  d S Nname).0vars     S/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/numba/core/analysis.py	<genexpr>z#compute_use_defs.<locals>.<genexpr>(   s$      !M!Ms#(!M!M!M!M!M!M     unreachable)usemapdefmap)itemssetbodytypeir_extension_usedefs
isinstancer
   AssignvalueInst	list_varsVarr   ArgConstGlobalFreeVarAssertionErrortargetadd_use_defs_result)blocksvar_use_mapvar_def_mapoffsetir_blockuse_setdef_setstmtfuncrhs_setr   s              r   compute_use_defsr9      s   
 KK"LLNN * *(+-Fg(+-FgM 	* 	*DDzz111+DJJ7T7G,,,$	** 2dj"'22 J!!M!Mdj6J6J6L6L!M!M!MMMGG
BF33 J!4:?"344GG
RVRXry-/Z-9 : : J GG(TZ8H8HIII;#722KK 0111~~'' * *87**KK)))*'	*0 ;{CCCCr   c                     	
 d 

fd} fd} 	fd}i }|                                 D ]}t          |                   ||<   t          t                    	 ||	            |||           |S )z
    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                 X    t          d |                                 D                       S )zFHelper function to determine if a fix-point has been reached.
        c              3   4   K   | ]}t          |          V  d S r   )lenr   vs     r   r   z?compute_live_map.<locals>.fix_point_progress.<locals>.<genexpr>E   s(      22SVV222222r   )tuplevalues)dcts    r   fix_point_progressz,compute_live_map.<locals>.fix_point_progressB   s)     22SZZ\\222222r   c                 n    d} |          }||k    r  | |           |} |          }||k    dS dS )z4Helper function to run fix-point algorithm.
        Nr   )fnrB   	old_point	new_pointrC   s       r   	fix_pointz#compute_live_map.<locals>.fix_pointG   s`     	&&s++	9$$BsGGG!I**3//I 9$$$$$$r   c                     D ]T}|         |         z  }| |xx         |z  cc<                        |          D ]\  }}| |xx         | |         z  cc<   UdS )zGFind all variable definition reachable at the entry of a block
        N)
successors)rB   r2   used_or_definedout_blk_cfgr1   r0   s        r   	def_reachz#compute_live_map.<locals>.def_reachQ   s     " 	, 	,F)&1K4GGOKKK?*KKK!nnV44 , ,
GF+,		, 	,r   c                     | D ]I}| |         }                     |          D ])\  }}||         z  }| |xx         ||         z
  z  cc<   *JdS )z?Find live variables.

        Push var usage backward.
        N)predecessors)	rB   r2   	live_varsinc_blk_data	reachablerN   def_reach_mapr1   s	         r   livenessz"compute_live_map.<locals>.liveness[   s    
  	A 	AFFI"%"2"26":": A A%g(>>	G	K,@ @@	A	A 	Ar   )keysr   r   )rN   r/   r0   r1   rH   rO   rW   live_mapr2   rV   rC   s   ` ``     @@r   compute_live_maprZ   <   s    3 3 3
0 0 0 0 0, , , , , , ,A A A A A A A H++-- 4 4{6233$$MIi'''Ih!!!Or   dead_maps_resultzinternal,escaping,combinedc                 b   t          t                    t          t                    t          t                    }|                                D ]\  }}|         ||         z  }t          fd|                     |          D                       }t          d |j                                        D                       }	t          t          j	        |
                                t                                }
|
|	z  }
||
z
  }||<   ||z
  }|                                D ]#\  }}|||         z  }|xx         ||z
  z  cc<   $|s|	||<   t          t          j	        
                                t                                }t          t          j	        
                                t                                }t          t          j	        
                                t                                }t          t          j	        |
                                t                                }||z  |z  }||z
  }|r9|                                 sn$d                    |          }t          |          t          fd|D                       }t          |          S )z
    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   2   K   | ]\  }}||         fV  d S r   r   )r   rL   rT   rY   s      r   r   z$compute_dead_maps.<locals>.<genexpr>   sM       !O !O%3We #*8G+<!= !O !O !O !O !O !Or   c              3   $   K   | ]}|j         V  d S r   r   r>   s     r   r   z$compute_dead_maps.<locals>.<genexpr>   s@       !K !K%& "# !K !K !K !K !K !Kr   z#liveness info missing for vars: {0}c              3   >   K   | ]}||         |         z  fV  d S r   r   )r   kescaping_dead_mapinternal_dead_maps     r   r   z$compute_dead_maps.<locals>.<genexpr>   sM       % % )!,/@/CCD % % % % % %r   )internalescapingcombined)r   r   r   dictrJ   
terminatorr%   r   operatoror_rA   exit_pointsformatRuntimeError_dead_maps_result)rN   r/   rY   r1   exit_dead_mapr2   r3   cur_live_setoutgoing_live_mapterminator_livesetcombined_livesetinternal_setescaping_live_setrL   new_live_setall_varsinternal_dead_varsescaping_dead_varsexit_dead_vars	dead_varsmissing_varsmsgre   ra   rb   s     `                    @@r   compute_dead_mapsr}   v   s    $C((#C(($$M"LLNN 7 7  '+f*==  !O !O !O !O7:~~f7M7M!O !O !O O O ! !K !K*2*=*G*G*I*I!K !K !K K K "(,0A0H0H0J0J"%%%) ) 	.. $&66$0&!(<7%6%<%<%>%> 	K 	K!G\'+g*>>Lg&&&*;l*JJ&&&& ! 	7$6M&! hlHOO$5$5suu==H.?.F.F.H.H #' '.?.F.F.H.H #' 'HL-*>*>*@*@#%%HHN#&88>IIi'L $   	$7>>|LLCs### % % % % %#% % % % %H &7&7&.0 0 0 0r   c                    t          t                    fd}d} |            }||k    r^|D ]I}|         ||         z  }|||         z  }|                     |          D ]\  }	}
|	xx         |z  cc<   J|} |            }||k    ^S )z
    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                  l    t          t          t                                                               S r   )r@   mapr=   rA   )block_entry_varss   r   rC   z2compute_live_variables.<locals>.fix_point_progress   s(    S.557788999r   N)r   r   rJ   )rN   r/   r1   var_dead_maprC   rF   rG   r2   availsuccrT   r   s              @r   compute_live_variablesr      s     #3'': : : : : I""$$I y
 
   	0 	0F$V,{6/BBE\&))E"~~f55 0 0e &&&%/&&&&0 	&&((	 y
 
  r   c                 ^   t                      }| D ]}|                    |           |                                 D ]9\  }}|j        }|                                D ]}|                    ||           :|                    t          |                      |                                 |S r   )	r   add_noder   rg   get_targetsadd_edgeset_entry_pointminprocess)r/   rN   r`   btermr,   s         r   compute_cfg_from_blocksr      s    
))C  Q $ $1|&&(( 	$ 	$FLLF####	$ F$$$KKMMMJr   c              #     K   t                      }|                                                                 D ]_}t          |j                  t          |j                  z  t          |j                  z  }|                    |j                   ||z  }`|                                                                 D ]}|j        |vrt          | |          V  dS )zK
    A generator that yields toplevel loops given a control-flow-graph
    N)	r   loopsrA   r   entriesexitsdiscardheader_fix_loop_exit)rN   blocks_in_looploopinsiderss       r   find_top_level_loopsr      s       UUN		""$$ # #ty>>C$5$55DJG%%%("		""$$ , ,;n,, d+++++, ,r   c                     |                                  t          t          j        fd|j        D             |j                  }|r)|j        |j        |z
  z  }|                    ||          S |S )zg
    Fixes loop.exits for Py3.8+ bytecode CFG changes.
    This is to handle `break` inside loops.
    c                      g | ]
}|         S r   r   )r   r   postdomss     r   
<listcomp>z"_fix_loop_exit.<locals>.<listcomp>  s    )))!)))r   )r   r   )post_dominatorsr   rh   and_r   r   _replace)rN   r   r   r   r   s       @r   r   r   
  s     ""$$H))))dj)))
 E
  y4:--}}5t}444r   	nullifiedz!condition, taken_br, rewrite_stmtc                   +,-./0 ddl m/m0m}m} d+/0fd}-fd.+.fd}+.fd}+.fd} G d d	t
                    ,,fd
}+dk    rDt          d                    dd                     t          |                                            t                      }	t                      }
| j
                                        D ]l\  }}|j        D ]_}t          |t          j                  rCt          |j        t          j                  r$|j        j        dk    r||	|j        <   ||
|j        <   `m ||           }g }|D ]\  -}}g }t          |t          j                  r|j        dk    r|}|j        |j        fD ]} ,            } 0/| |          }t          |t          j                  r ||j                  }|}n/	  || |          }|t/          j        d          }n# |$ r Y nw xY wt          |,          s|                    |           t5          |          dk    r4 |-||g|R  \  }}|r$|                    t7          ||d                     " ,            }	  /| -j                  } || |j        d                   }|t/          j        d          }n# |$ r Y nw xY wt          |,          s6 |-||          \  }}|r$|                    t7          ||d                     d |D             }|D ]\  }}}||v r|j        D ]}t          |t          j                  r|j        |u r||                    |                   }|j        r]|j        }t          j         ||j!                  |_        | j"        |j#        j$                 }|                    |          } |j        || <   tK          | j
                  }!|!&                                }"|	                                D ]U\  }#}||"v rd |!'                    |          D             }$tQ          |$          tQ          |#j)                  k    rt5          |$          dk    r9|#j)                            |$d                   }%|#j*        |%         |
|#         _        g }&g }'tW          |#j*        |#j)                  D ]4\  }(})|)|"v r
|&                    |(           |'                    |)           5|#j*        ,                                 |#j*        -                    |&           |#j)        ,                                 |#j)        -                    |'           W|"D ]
}*| j
        |*= |rt]          j/        |           | _0        +dk    rFt          d                    dd                     t          |                                            dS dS )z
    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
    r   )get_definitionguard
find_constGuardExceptionc                    g }| j                                         D ]}|j        d         }t          |t          j                  r|} 	| |j        j                  }|t          |dd           dk    rn 	| |j	                  }|Zt          |t          j
                  r@|j        t          u r2 	| |j        d                   }||                    |||f           |S )Nopcallr   )r/   rA   r   r!   r
   Branchcondr   getattrr7   r)   r#   boolargsappend)
func_irbranchesblkbranch_or_jumpbranchpredfunction	conditionr   r   s
           r   find_branchesz(dead_branch_prune.<locals>.find_branches0  s    >((** 	F 	FC Xb\N.")44 
F'u^Wfk6FGG#dD(A(AV(K(K$u^WdiHHH ,"8RY77 -$Nd22$)E.'49Q<$P$P	$0$OOVY,DEEEr   c                     | rj         nj        }t          j        |j                  }||j        d<   |j         k    rdndS )Nlocr   r   r   )truebrfalsebrr
   Jumpr   r   )take_truebrr   keepjmpr   s       r   do_prunez#dead_branch_prune.<locals>.do_pruneB  sL     +?v}}gd
+++FM))qqq0r   c                 V   |\  }}t          |t          j                  }t          |t          j                  }|s|rj	 |                    ||          }n# t          $ r Y dS w xY wdk    r+|r| j        n| j        }	t          d|	z  | |||j                    ||          }
d|
fS dS NFNr   
Pruning %sT)r!   r   NoneTyperE   	Exceptionr   r   print)r   r   r   condslhs_condrhs_condlhs_nonerhs_noner   killtakenDEBUGr   s              r   prune_by_typez(dead_branch_prune.<locals>.prune_by_typeI  s     #(h77h77 
	x 
	#'ll8X>> # # #"{{#qyy)4Gv~~&-lT)68Xl$ $ $H[#..E;{s    A 
A%$A%c                     |\  }}	 |                     ||          }n# t          $ r Y dS w xY wdk    r+|r| j        n| j        }t	          d|z  | |||j                     	||           d|fS r   )rE   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   s
           r   prune_by_valuez)dead_branch_prune.<locals>.prune_by_value\  s    "(	#,,x::KK 	 	 	;;	199%0C6>>fmD,%vx9<PPPc"""
 [  s    
--c                 F   	 t          |t          j        t          j        t          j        f          st          d          t          |j                  }n# t
          $ r Y dS w xY wdk    r$|r| j        n| j	        }t          d|z  | |            ||          }d|fS )NzExpected constant Numba IR noder   r   r   T)r!   r
   r(   r*   r)   	TypeErrorr   r#   r   r   r   )r   r   r   r   r   r   r   r   s         r   prune_by_predicatez-dead_branch_prune.<locals>.prune_by_predicatel  s    	 dRXrz29$EFF C ABBBtz**KK 	 	 	;;	199%0C6>>fmD,%vt444c**U{s   AA 
A&%A&c                       e Zd ZdS )"dead_branch_prune.<locals>.UnknownN)__name__
__module____qualname__r   r   r   Unknownr   {  s        r   r   c                 $   |          }t          |t          j                  r|S t          |t          j                  r9|j        }t          |t          j                  r|S |t          j        d          S t          |d                       S )zC
        Resolves an input arg to a constant (if possible)
        Nnoneliteral_type)r!   r   r   Omittedr#   r   )input_arg_idxinput_arg_tyvalr   called_argss      r   resolve_input_arg_constz2dead_branch_prune.<locals>.resolve_input_arg_const~  s     #=1 lEN33 	  lEM22 	.$C#u~.. .
~f---
 |^WWYY???r   r   beforeP   -phibinopNr      TFc                     g | ]	}|j         
S r   )r   r   xs     r   r   z%dead_branch_prune.<locals>.<listcomp>  s    ::::::r   r   c                     g | ]
}|d          S )r   r   r   s     r   r   z%dead_branch_prune.<locals>.<listcomp>"  s    @@@!@@@r   after)1numba.core.ir_utilsr   r   r   r   objectr   centerdumprf   r/   r   r   r!   r
   r"   r#   Exprr   lhsrhsr'   indexr   r   r   r=   r   r   r   rewrite_stmttaken_brr(   r   _definitionsr,   r   r   
dead_nodesrQ   r   incoming_blocksincoming_valueszipclearextendr   ConstantInference_consts)1r   r   r   r   r   r   r   r   r   phi2lblphi2asgnlblr   r6   branch_infonullified_conditionsr   const_condspruneargresolved_constarg_def
prune_statr   	pred_calldeadcondrM   r   r   nullified_info
branch_bitdefnsrepl_idxnew_cfgdead_blocksr   new_incomingidx
ic_val_tmp
ic_blk_tmpic_valic_blkdeadr   r   r   r   r   r   s1    `                                         @@@@@@r   dead_branch_pruner!  #  sp   5 5 5 5 5 5 5 5 5 5 5 5 E     $1 1 1 1 1     &! ! ! ! ! !          &   @ @ @ @ @ @. qyyhoob#&&'''gllnnffGvvHN((** 0 0SH 	0 	0D$	** 0dj"'22 0tz}7M7M*-GDJ'+/HTZ(		0  -((K"- 0B 0B	3i)) .	Bilg.E.E"E!y}5 7 7!(%==grv.. %<%<W]%K%KN)EE)3GS)A)A)1-2^F-C-CN)    ".':: 7&&~666 ;1$$$)E&)S$O;$O$O$O!
E A(//	)U:>1@ 1@ A A A %WYYN*N7FK@@	!+GY^A5F!G!G!)%*^F%;%;N!    ng66 B$6$6vy#$N$N!
E B(//	)U:?1A 1A B B B$ ;:%9:::H# 2 248X 2 2a++ 24%9(..:N:N%ON &2 2%3%<
"$(:15"A"A"A ' 4QX] C#(;;t#4#4*+'hB &gn55G$$&&K MMOO 7 7S+@@g&:&:3&?&?@@@|C$7 8 888<  A%% )//Q@@&)&9#&>##  

&)#*=*-*='? '? 2 2NFF,, "))&111"))&1111#))+++#**:666#))+++#**:666  ! !N4    < 27;;qyygnnR%%&&&gllnn ys$   "G//G76G74>J33J;:J;c                   	
 d}|dk    rgt          d| j        j        z                       dd                     t          d                    dd                     |                                  
fd	fd	}	fd
}ddlmm | j        	                                D ]a}|j
        D ]W	t          	t          j                  r;	j        
t          
t          j                  r |
| |            |
| |           Xb|dk    rHt          d                    dd                     |                                  t          d           dS dS )aP  
    This rewrites values known to be constant by their semantics as ir.Const
    nodes, this is to give branch pruning the best chance possible of killing
    branches. An example might be rewriting len(tuple) as the literal length.

    func_ir is the IR
    called_args are the actual arguments with which the function is called
    r   r   zrewrite_semantic_constants: r   r   r   *c                     t          j        ||j                  |_        | j        |j        j                 }|                              }|j        ||<   dS )zr
        Rewrites the stmt as a ir.Const new_val and fixes up the entries in
        func_ir._definitions
        N)r
   r(   r   r#   r   r,   r   r   )r   r6   new_valr  r  r   s        r   rewrite_statementz5rewrite_semantic_constants.<locals>.rewrite_statementY  sL    
 Xgtx00
$T[%56;;s##*hr   c                 "   t          | dd           dk    rr| j        dk    ri || j                  }t          |t          j                  r?||j                 }t          |t          j                  r ||j	                   d S d S d S d S d S )Nr   r   ndim)
r   attrr#   r!   r
   r'   r   r   Arrayr(  )	r   r   r   r  argtyr   r   r&  r6   s	        r   rewrite_array_ndimz6rewrite_semantic_constants.<locals>.rewrite_array_ndimc  s    3d##y00x6!!%CCgrv.. E'6E!%55 E))'4DDDDD 10!!E EE Er   c                 f   t          | dd           dk    r || j                  }|t          |t          j                  rt          |dd           t
          u r| j        \  } ||          }t          |t          j                  r=||j                 }t          |t          j
                  r 	|
|j                   d S d S t          |t          j                  rH|j        dk    r?|j        }t          |t          j
                  r  	|
|j                   d S d S d S d S d S d S d S d S )Nr   r   r#   typed_getitem)r   r7   r!   r
   r)   r=   r   r'   r   r   	BaseTuplecountr   r   dtype)r   r   r   r7   r  r  r+  r   r   r&  r6   s          r   rewrite_tuple_lenz5rewrite_semantic_constants.<locals>.rewrite_tuple_lenm  sk   3d##v--5#(;;D Zbi%@%@ D'400C77%==grv.. F'6E!%99 F))'4EEEEEF F "'22 FjO33#ME!%99 F))'4EEEEE .-    77F F33F Fr   )r   r   r   zP--------------------------------------------------------------------------------N)r   func_id	func_namer   r   r   r   r   r/   rA   r   r!   r
   r"   r#   r   )r   r   r   r,  r2  r   r   r   r&  r6   r   s         @@@@@r   rewrite_semantic_constantsr5  H  s    Eqyy-()*0&S//	; 	; 	;hoob#&&'''% % % % %E E E E E E E EF F F F F F F F& :9999999~$$&& A AH 	A 	AD$	** Ajc27++ A&&sG[AAA%%c7K@@@	A qyygnnR%%&&&h yr   c                    ddl m} t                      }i }| j                                        D ]}|                    d          D ]}|                    |j        | |j                  }t          |t          j        t          j        f          r|j        }n|                    |j        | |          }|t          j        u ro|j        \  }	|                     |	          }
t          |
t          j                  r7|
j        }|                    |           |                    ||j                   |D ]}||         }t          |t.          j                  o|j        du }|r||         }t5          j        ||          t          |t.          j        t.          j        f          s||         }t5          j        ||          dS )a3  An analysis to find `numba.literally` call inside the given IR.
    When an unsatisfied literal typing request is found, a `ForceLiteralArg`
    exception is raised.

    Parameters
    ----------

    func_ir : numba.ir.FunctionIR

    argtypes : Sequence[numba.types.Type]
        The argument types.
    r   )ir_utilsr   )r   Nr   )
numba.corer7  r   r/   rA   
find_exprsr   r   r7   r!   r
   r)   r*   r#   resolve_func_from_moduler   	literallyr   r'   r   r-   
setdefaultr   r   InitialValueinitial_valuer	   ForceLiteralArgLiteral)r   argtypesr7  marked_args	first_locr   assignr   fnobjr  defargargindexpos	query_argdo_raiser   s                   r   find_literally_callsrK    s    $#####%%KI~$$&& ? ?nnn// 	? 	?F..!8'6;OOC#	2:677 5	 x'H'.5 5))) //44fbf-- ?%|HOOH---((6:>>>	?   
? 
?SM	y%*<== 4+t3 	 	?C.C(#>>>>)emU5G%HII 	?C.C(#>>>>	?
? 
?r   c                     t                      }|                                 D ]I}|j        D ]?}t          |          t          v r't          t          |                   } |||           ?@J|S )a  
    Analyzes a dictionary of blocks to find variables that must be
    stack allocated with alloca.  For each statement in the blocks,
    determine if that statement requires certain variables to be
    stack allocated.  This function uses the extension point
    ir_extension_use_alloca to allow other IR node types like parfors
    to register to be processed by this analysis function.  At the
    moment, parfors are the only IR node types that may require
    something to be stack allocated.
    )r   rA   r   r   ir_extension_use_alloca)r/   use_alloca_varsr3   r6   r7   s        r   must_use_allocarO    s~     eeOMMOO  M 	 	DDzz444.tDzz:T?+++ 5	 r   ) __doc__rh   	functoolsr   collectionsr   r   controlflowr   r8  r   r	   r
   r   
numba.miscr   r.   r    r9   rZ   rm   r}   r   r   r   r   r   r!  r5  rK  rM  rO  r   r   r   <module>rU     s           / / / / / / / /             0 0 0 0 0 0 0 0 0 0 0 0       :/AA   "D "D "DJ4 4 4n J13OPP E0 E0 E0P& & &Z  , , ,   * J{$GHH	b b bJ	D D DN-? -? -?`      r   