
    shn                         S r SSKrSSKJr  SSKJrJr  SSKJr  SSK	J
r
JrJrJr  SSKJr  \" S	S
5      r0 rS rS r\" SS5      rS rS rS rS rS r\" SS5      rS rS rS r0 rS rg)z
Utils for IR analysis
    N)reduce)
namedtupledefaultdict   )CFGraph)typeserrorsirconsts)specialuse_defs_resultzusemap,defmapc           	         0 n0 nU R                  5        GH!  u  p4[        5       =X'   n[        5       =X#'   nUR                   GH  n[        U5      [        ;   a  [        [        U5         nU" XuU5        M4  [        U[        R                  5      (       GaV  [        UR                  [        R                  5      (       a+  [        S UR                  R                  5        5       5      n	O[        UR                  [        R                  5      (       a!  [        UR                  R                  /5      n	Oy[        UR                  [        R                  [        R                  [        R                  [        R                   45      (       a  Sn	O[#        S[        UR                  5      5      eUR$                  R                  U	;  a%  UR'                  UR$                  R                  5        UR                  5        H0  n
U
R                  U;  d  M  UR'                  U
R                  5        M2     GM     GM$     [)        XS9$ )z"
Find variable use/def per block.
c              3   8   #    U  H  oR                   v   M     g 7fNname).0vars     g/Users/tiagomarins/Projetos/claudeai/copy_bank/venv/lib/python3.13/site-packages/numba/core/analysis.py	<genexpr>#compute_use_defs.<locals>.<genexpr>(   s     !M6Ls((6L    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_defsr:      s   
 KK"LLN(+-g(+-gMMDDz11+DJ7TG,$		**djj"''22!!Mdjj6J6J6L!MMG

BFF33!4::??"34G

RVVRXXryy-/ZZ-9 : : G(TZZ8HII;;##72KK 0 01~~'887*KK) (' " +6 ;CC    c                    ^ ^^^	^
 S m
U
4S jnU UU4S jnU U	U4S jn0 nUR                  5        H  n[        TU   5      Xx'   M     [        [        5      m	U" UT	5        U" Xg5        U$ )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                 B    [        S U R                  5        5       5      $ )zFHelper function to determine if a fix-point has been reached.
        c              3   8   #    U  H  n[        U5      v   M     g 7fr   )lenr   vs     r   r   ?compute_live_map.<locals>.fix_point_progress.<locals>.<genexpr>E   s     2\SVV\r   )tuplevalues)dcts    r   fix_point_progress,compute_live_map.<locals>.fix_point_progressB   s     2SZZ\222r;   c                 X   > SnT" U5      nX#:w  a  U " U5        UnT" U5      nX#:w  a  M  gg)z4Helper function to run fix-point algorithm.
        Nr   )fnrE   	old_point	new_pointrF   s       r   	fix_point#compute_live_map.<locals>.fix_pointG   s8     	&s+	$sG!I*3/I $r;   c                    > T HB  nTU   TU   -  nX==   U-  ss'   TR                  U5       H  u  p4X==   X   -  ss'   M     MD     g)zGFind all variable definition reachable at the entry of a block
        N)
successors)rE   r3   used_or_definedout_blk_cfgr2   r1   s        r   	def_reach#compute_live_map.<locals>.def_reachQ   sR     "F)&1K4GGOK?*K!nnV4
+ 5	 "r;   c                    > U  H;  nX   nTR                  U5       H  u  p4UTU   -  nX==   UTU   -
  -  ss'   M!     M=     g)z/Find live variables.

Push var usage backward.
N)predecessors)	rE   r3   	live_varsinc_blk_data	reachablerS   def_reach_mapr2   s	         r   liveness"compute_live_map.<locals>.liveness[   sR    
 FI"%"2"26":%g(>>		K,@ @@	 #; r;   )keysr   r   )rS   r0   r1   r2   rL   rT   r]   live_mapr3   r\   rF   s   ` ``     @@r   compute_live_mapra   <   sd    3
0,A H++-{623    $Mi'h!Or;   dead_maps_resultzinternal,escaping,combinedc                   ^^^ [        [        5      m[        [        5      m[        [        5      nUR                  5        H  u  pVTU   X5   -  n[        U4S jU R	                  U5       5       5      n[        S UR
                  R                  5        5       5      n	[        [        R                  UR                  5       [        5       5      n
X-  n
Xz-
  nUTU'   X{-
  nUR                  5        H  u  pXU   -  nTU==   X-
  -  ss'   M     U(       a  M  XU'   M     [        [        R                  TR                  5       [        5       5      n[        [        R                  TR                  5       [        5       5      n[        [        R                  TR                  5       [        5       5      n[        [        R                  UR                  5       [        5       5      nUU-  U-  nUU-
  nU(       a2  U R                  5       (       d  OSR                  U5      n[        U5      e[        UU4S jU 5       5      n[        TTUS9$ )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   6   >#    U  H  u  pUTU   4v   M     g 7fr   r   )r   rQ   rZ   r`   s      r   r   $compute_dead_maps.<locals>.<genexpr>   s%      !O7M^W #*8G+<!=7Ms   c              3   :   #    U  H  nUR                   v   M     g 7fr   r   r@   s     r   r   re      s      !K*IQ "#*Is   z#liveness info missing for vars: {0}c              3   >   >#    U  H  nUTU   TU   -  4v   M     g 7fr   r   )r   kescaping_dead_mapinternal_dead_maps     r   r   re      s.      %# )!,/@/CCD#s   )internalescapingcombined)r   r   r   dictrO   
terminatorr&   r   operatoror_rD   exit_pointsformatRuntimeError_dead_maps_result)rS   r0   r`   r2   exit_dead_mapr3   r4   cur_live_setoutgoing_live_mapterminator_livesetcombined_livesetinternal_setescaping_live_setrQ   new_live_setall_varsinternal_dead_varsescaping_dead_varsexit_dead_vars	dead_varsmissing_varsmsgrm   ri   rj   s     `                    @@r   compute_dead_mapsr   v   s&    $C(#C($M"LLN  '+*==  !O7:~~f7M!O O ! !K*2*=*=*G*G*I!K K "(,,0A0H0H0J"%%) 	. $6$0&!(7%6%<%<%>!G'g*>>Lg&*;*JJ& &? ! $6&!; +@ hllHOO$5su=H.?.F.F.H #'.?.F.F.H #'HLL-*>*>*@#%HN#&88>IIi'L  7>>|LCs## %#% %H &7&7&.0 0r;   c                    ^ [        [        5      mU4S jnSnU" 5       nXV:w  aQ  U H;  nTU   X'   -  nXU   -  nU R                  U5       H  u  pTU	==   U-  ss'   M     M=     UnU" 5       nXV:w  a  MQ  T$ )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                  R   > [        [        [        T R                  5       5      5      $ r   )rC   mapr?   rD   )block_entry_varss   r   rF   2compute_live_variables.<locals>.fix_point_progress   s    S.557899r;   N)r   r   rO   )rS   r0   r2   var_dead_maprF   rJ   rK   r3   availsuccrZ   r   s              @r   compute_live_variablesr      s     #3': I"$I 
  F$V,{/BBE&))E"~~f5 &%/&  6  	&(	 
  r;   c                 <   [        5       nU  H  nUR                  U5        M     U R                  5        H9  u  p#UR                  nUR	                  5        H  nUR                  X%5        M     M;     UR                  [        U 5      5        UR                  5         U$ r   )	r   add_noder   ro   get_targetsadd_edgeset_entry_pointminprocess)r0   rS   rh   btermr-   s         r   compute_cfg_from_blocksr      s|    
)CQ  ||&&(FLL# ) 
 F$KKMJr;   c              #     #    [        5       nU R                  5       R                  5        Hc  n[        UR                  5      [        UR                  5      -  [        UR
                  5      -  nUR                  UR                  5        X-  nMe     U R                  5       R                  5        H"  nUR                  U;  d  M  [        X5      v   M$     g7f)zC
A generator that yields toplevel loops given a control-flow-graph
N)	r   loopsrD   r   entriesexitsdiscardheader_fix_loop_exit)rS   blocks_in_looploopinsiderss       r   find_top_level_loopsr      s      UN		""$tyy>C$55DJJG%" %
 		""$;;n, ++ %s   B?CCc                    U R                  5       n[        [        R                  UR                   Vs/ s H  o2U   PM	     snUR                  5      nU(       a+  UR
                  UR                  U-
  -  nUR                  XES9$ U$ s  snf )z[
Fixes loop.exits for Py3.8+ bytecode CFG changes.
This is to handle `break` inside loops.
)r   r   )post_dominatorsr   rp   and_r   r   _replace)rS   r   postdomsr   r   r   s         r   r   r   
  sy     ""$H"jj)j!j)

E
 yy4::--}}5}44 	*s   B
	nullifiedz!condition, taken_br, rewrite_stmtc                   ^^+^,^-^.^/^0 SSK Jm/Jm0JnJn  Sm+U/U04S jnU-4S jm.U+U.4S jnU+U.4S jnU+U.4S jn " S S	[
        5      m,U,U4S
 jnT+S:  a4  [        SR                  SS5      5        [        U R                  5       5        [        5       n	[        5       n
U R                  R                  5        H  u  pUR                   H  n[        U[        R                  5      (       d  M$  [        UR                   [        R"                  5      (       d  MO  UR                   R$                  S:X  d  Mk  XUR                   '   XUR                   '   M     M     U" U 5      n/ nU GH  u  m-nn/ n[        U[        R"                  5      (       Ga  UR$                  S:X  a  UnUR&                  UR(                  4 H  nT," 5       nT0" T/U U5      n[        U[        R*                  5      (       a  U" UR,                  5      nUnO# U" U U5      nUc  [.        R0                  " S5      n[        UT,5      (       a  M~  UR3                  U5        M     [5        U5      S:X  a7  U" T-UU/UQ76 u  nnU(       a  UR3                  [7        UUS5      5        GM*  GM-  GM0  T," 5       n T/" U T-R8                  5      nU" U UR:                  S   5      nUc  [.        R0                  " S5      n[        UT,5      (       a  GM  U" T-UU5      u  nnU(       d  GM  UR3                  [7        UUS5      5        GM     U Vs/ s H  nUR<                  PM     nnU H  u  nnnUU;   d  M  UR                   H  n[        U[        R                  5      (       d  M$  UR                   UL d  M5  UUR-                  U5         nUR>                  (       d  M\  UR@                  n[        RB                  " UURD                  S9Ul        U RF                  URH                  RJ                     nUR-                  U5      n UR                   UU '   M     M     [M        U R                  5      n!U!RO                  5       n"U	R                  5        GH_  u  n#nUU";   a  M  U!RQ                  U5       Vs/ s H  nUS   PM
     n$n[S        U$5      [S        U#RT                  5      :w  d  MW  [5        U$5      S:X  a7  U#RT                  R-                  U$S   5      n%U#RV                  U%   U
U#   l        M  / n&/ n'[Y        U#RV                  U#RT                  5       H0  u  n(n)U)U";   a  M  U&R3                  U(5        U'R3                  U)5        M2     U#RV                  R[                  5         U#RV                  R]                  U&5        U#RT                  R[                  5         U#RT                  R]                  U'5        GMb     U" H  n*U R                  U*	 M     U(       a  [^        R`                  " U 5      U l1        T+S:  a5  [        SR                  SS5      5        [        U R                  5       5        gg! U a     GN-f = f! U a     GNf = fs  snf s  snf )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                   > / nU R                   R                  5        H  nUR                  S   n[        U[        R
                  5      (       d  M3  UnT	" TXR                  R                  5      nUc  MW  [        USS 5      S:X  d  Mj  T	" TXR                  5      nUc  M  [        U[        R                  5      (       d  M  UR                  [        L d  M  T	" TXR                  S   5      nUc  M  UR                  XGU45        M     U$ )Nopcallr   )r0   rD   r   r"   r
   Branchcondr   getattrr8   r*   r$   boolargsappend)
func_irbranchesblkbranch_or_jumpbranchpredfunction	conditionr   r   s
           r   find_branches(dead_branch_prune.<locals>.find_branches0  s    >>((*C XXb\N."))44'^Wkk6F6FG#dD(AV(K$^WiiHH ,"8RYY77$NNd2$).'99Q<$P	$0$OOV,DE + r;   c                    > U (       a  TR                   OTR                  n[        R                  " UTR                  S9nX1R
                  S'   UTR                   :X  a  S$ S$ )Nlocr   r   r   )truebrfalsebrr
   Jumpr   r   )take_truebrr   keepjmpr   s       r   do_prune#dead_branch_prune.<locals>.do_pruneB  sI     +v}}ggd

+FMM)q0q0r;   c                 n  > Uu  pE[        U[        R                  5      n[        U[        R                  5      nU(       d  U(       a^   UR                  XE5      nTS:  a:  U(       a  U R
                  OU R                  n	[        SU	-  XUUR                  5        T" X5      n
SU
4$ g! [         a     gf = fNFNr   
Pruning %sT)r"   r   NoneTyperI   	Exceptionr   r   print)r   r   r   condslhs_condrhs_condlhs_nonerhs_noner   killtakenDEBUGr   s              r   prune_by_type(dead_branch_prune.<locals>.prune_by_typeI  s     #h7h7x#'ll8> qy)4v~~&--lT)6Xll$[.E;  #"#s   	B' '
B43B4c                    > Uu  pE UR                  XE5      nTS:  a9  U(       a  U R                  OU R                  n[	        SU-  XXQR                   5        T	" Xb5        SU4$ ! [         a     gf = fr   )rI   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   s
           r   prune_by_value)dead_branch_prune.<locals>.prune_by_value\  sv    "	#,,x:K 19%06>>fmmD,%v<<P"
 [    		s   A# #
A0/A0c                 b  >  [        U[        R                  [        R                  [        R                  45      (       d  [        S5      e[        UR                  5      nTS:  a.  U(       a  U R                  OU R                  n[        SU-  X5        T" X25      nSU4$ ! [
         a     gf = f)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_predicate-dead_branch_prune.<locals>.prune_by_predicatel  s    	 dRXXrzz299$EFF ABBtzz*K 19%06>>fmmD,%v4*U{  		s   AB! !
B.-B.c                       \ rS rSrSrg)"dead_branch_prune.<locals>.Unknowni{  r   N)__name__
__module____qualname____firstlineno____static_attributes__r   r;   r   Unknownr   {  s    r;   r   c                 >  > TU    n[        U[        R                  5      (       a  U$ [        U[        R                  5      (       aF  UR                  n[        U[        R                  5      (       a  U$ Uc  [        R                  " S5      $ [        UST" 5       5      $ )z3
Resolves an input arg to a constant (if possible)
noneliteral_type)r"   r   r   Omittedr$   r   )input_arg_idxinput_arg_tyvalr   called_argss      r   resolve_input_arg_const2dead_branch_prune.<locals>.resolve_input_arg_const~  s     #=1 lENN33 lEMM22$$C#u~~..
~~f--
 |^WY??r;   r   beforeP   -phibinopNr      TFr   after)2numba.core.ir_utilsr   r   r   r   objectr   centerdumprn   r0   r   r   r"   r
   r#   r$   Exprr   lhsrhsr(   indexr   r   r   r?   r   r   r   r   rewrite_stmttaken_brr)   r   _definitionsr-   r   r   
dead_nodesrW   r   incoming_blocksincoming_valueszipclearextendr   ConstantInference_consts)1r   r   r   r   r   r   r   r   r   phi2lblphi2asgnlblr   r7   branch_infonullified_conditionsr   const_condspruneargresolved_constarg_def
prune_statr   	pred_callxdeadcondrR   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-  #  si   5 5 E$1&! & @. qyhoob#&'gllnfGvHNN((*HHD$		**djj"''22tzz}}7M*-DJJ'+/TZZ(	  +  (K"-	3i))illg.E"E!y}}5!(=grvv..%<W]]%KN)E)3GS)A)1-2^^F-CN ".'::&&~6% 6* ;1$$)&)S$O;$O!
E(//	)U:>1@ A  % %YN*7FKK@	!+GY^^A5F!G!)%*^^F%;N ng66$6vy#$N!
EJ(//	)U:?1A B_ #.B &::%9%9H:#48XXa++4%9(..:N%ON &222%3%<%<
"$((:155"A ' 4 4QXX]] C#(;;t#4*+''h  $^ &gnn5G$$&K MMOS+&-&:&:3&?@&?!&?@|C$7$7 88< A% ))//Q@&)&9&9#&>#  

&)#*=*=*-*=*='?NFF, "))&1"))&1'? ##))+##**:6##))+##**:65 $: NN4    227;qygnnR%&glln O * , " 2 ;n As1   ?"YAY,YY$YYYYc                   ^^^^	^
 SnUS:  a]  [        SU R                  R                  -   R                  SS5      5        [        SR                  SS5      5        U R	                  5         U
4S jmUUUU	4S	 jnUUUU	4S
 jnSSKJmJm  U R                  R                  5        Hv  nUR                   Hc  m	[        T	[        R                  5      (       d  M$  T	R                  m
[        T
[        R                  5      (       d  MQ  U" T
X5        U" T
X5        Me     Mx     US:  a7  [        SR                  SS5      5        U R	                  5         [        S5        gg)a8  
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                    > [         R                  " X!R                  5      Ul        U R                  UR
                  R                     nUR                  T5      nUR                  X4'   g)zZ
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   r7   new_valr"  r#  r   s        r   rewrite_statement5rewrite_semantic_constants.<locals>.rewrite_statementY  sL    
 XXgxx0
$$T[[%5%56;;s#**r;   c                 6  > [        U SS 5      S:X  a  U R                  S:X  av  T" TXR                  5      n[        U[        R
                  5      (       aC  X#R                     n[        U[        R                  5      (       a  T" UTUR                  5        g g g g g )Nr   r   ndim)
r   attrr$   r"   r
   r(   r  r   Arrayr5  )	r   r   r   r  argtyr   r   r2  r7   s	        r   rewrite_array_ndim6rewrite_semantic_constants.<locals>.rewrite_array_ndimc  s    3d#y0xx6!Cgrvv..'6E!%55)'4D 6 / " 1r;   c                   > [        U SS 5      S:X  Ga9  T" TXR                  5      nUGb!  [        U[        R                  5      (       Ga   [        USS 5      [
        L a  U R                  u  nT" TX5      n[        U[        R                  5      (       aC  X%R                     n[        U[        R                  5      (       a  T	" UT
UR                  5        g g [        U[        R                  5      (       aR  UR                  S:X  aA  UR                  n[        U[        R                  5      (       a  T	" UT
UR                  5        g g g g g g g g )Nr   r   r$   typed_getitem)r   r8   r"   r
   r*   r?   r   r(   r  r   	BaseTuplecountr  r   dtype)r   r   r   r8   r  r  r8  r   r   r2  r7   s          r   rewrite_tuple_len5rewrite_semantic_constants.<locals>.rewrite_tuple_lenm  s   3d#v-((;D Zbii%@%@D'40C7=grvv..'6E!%99)'4E : "''22jjO3#MME!%99)'4E : 4 3 8 &A  .r;   )r   r   r   zP--------------------------------------------------------------------------------N)r   func_id	func_namer  r  r   r   r   r0   rD   r   r"   r
   r#   r$   r  )r   r   r   r9  r@  r   r   r   r2  r7   r   s         @@@@@r   rewrite_semantic_constantsrD  H  s    Eqy-(()*0&S/	;hoob#&'%E EF F& :~~$$&HHD$		**jjc277++&sGA%c7@  ' qygnnR%&h r;   c                    SSK Jn  [        5       n0 nU R                  R	                  5        GH'  nUR                  SS9 GH  nUR                  UR                  XR                  5      n[        U[        R                  [        R                  45      (       a  UR                  nOUR                  UR                  X5      nU[        R                   L d  M  UR"                  u  n	U R                  U	5      n
[        U
[        R$                  5      (       d  M  U
R&                  nUR)                  U5        UR+                  XR,                  5        GM     GM*     U H  nX   n[        U[.        R0                  5      =(       a    UR2                  SL nU(       a  XL   n[4        R6                  " X?S9e[        U[.        R8                  [.        R0                  45      (       a  M  XL   n[4        R6                  " X?S9e   g)a  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.corerF  r   r0   rD   
find_exprsr   r   r8   r"   r
   r*   r+   r$   resolve_func_from_moduler   	literallyr   r(   r  r.   
setdefaultr   r   InitialValueinitial_valuer	   ForceLiteralArgLiteral)r   argtypesrF  marked_args	first_locr   assignr   fnobjr  defargargindexpos	query_argdo_raiser   s                   r   find_literally_callsrZ    s    $%KI~~$$&nnn/F..!8!8';;OC#		2::677		 x'H'H'.5))) //4fbff--%||HOOH-((::> 0 '" M	y%*<*<= 4++t3 	.C((>>)emmU5G5G%HII.C((>> r;   c                     [        5       nU R                  5        HE  nUR                   H2  n[        U5      [        ;   d  M  [        [        U5         nU" X15        M4     MG     U$ )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   rD   r   r    ir_extension_use_alloca)r0   use_alloca_varsr4   r7   r8   s        r   must_use_allocar^    sW     eOMMOMMDDz44.tDz:T+	 " $ r;   ) __doc__rp   	functoolsr   collectionsr   r   controlflowr   rG  r   r	   r
   r   
numba.miscr   r/   r!   r:   ra   ru   r   r   r   r   r   r   r-  rD  rZ  r\  r^  r   r;   r   <module>rd     s      /   0 0  /A   "DJ4n 13OP E0P&Z, * {$GH	bJ	DN-?`  r;   