
    xKgi                        d Z ddlZddlmZmZ ddlZddlmZ ddlm	Z	m
Z
mZmZ ddlZ ej                  d      Z ej                  d      Z ej                  d      Z ej                  e	j&                        Zej+                         Z ed      Z ed      Z ed      Z ed      Zd	 ZdTd
Zd Zi ZdUdZi fdZ  G d de!      Z" G d de"      Z# G d de"      Z$ G d de!      Z%dVdZ&d Z'dWdZ(d Z)d Z*d Z+dXdZ,d Z-d Z.d Z/d  Z0d! Z1d" Z2d# Z3d$ Z4 ejj                  d%d&      Z6edYd'       Z7edZd(       Z8ed)        Z9ed[d*       Z:ed+        Z;dTd,Z<d- Z=dTd.Z>	 	 d\d/Z?dTd0Z@	 d\d1ZAd2 ZBd3 ZCd4 ZDd5 ZEeDZFeCZGd6 ZHed7efd8       ZId9 ZJd: ZKdTd;ZLed]d<       ZMeKZNd= ZOd> ZPd? ZQd@ ZRdA ZSdTdBZTdC ZUdD ZVd^dEZWdF ZXdG ZYdH ZZdI Z[d_dJZ\d_dKZ]dL Z^dM Z_dN Z`dO ZadP ZbdQ ZcdR ZddS Zey)`z+
Generic helpers for LLVM code generation.
    N)contextmanager	ExitStack)ir)utilstypesconfig	debuginfo          c                 F    | j                  d||j                  d            S )N!=r   )icmp_unsignedtypebuildervalues     V/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/numba/core/cgutils.pyas_bool_bitr      s      uejjm<<    c                     |-t        j                  |D cg c]  }|j                   c}      } |t         j                        }t	        |      D ]  \  }}| j                  |||      } |S c c}w )zH
    Create an anonymous struct containing the given LLVM *values*.
    r   LiteralStructTyper   	Undefined	enumerateinsert_value)r   valuesstruct_typev
struct_valis         r   make_anonymous_structr"       sn     **F+CFqAFFF+CDR\\*J&!1))*a;
 "	 ,Ds   A.c                     t        |       }t        |      }t        j                  t        j                  t        j
                  d      |      |      S )z0
    Make a byte array constant from *buf*.
    r   )	bytearraylenr   Constant	ArrayTypeIntType)bufbns      r   make_bytearrayr,   ,   s:     	#AAA;;r||BJJqM15q99r   c                     | |f}t         j                  |      }|Pt        t        d|   }|j                  dz   t        |       z   }|f}t        |       }t        |||      }|t         |<   |S )zK
    Returns a specialized StructProxy subclass for the given fe_type.
    )r   data_)_fe_type)_struct_proxy_cachegetValueStructProxyDataStructProxy__name__strdictr   )fe_typekind	cache_keyresbaseclsnamebases
clsmemberss           r   create_struct_proxyr@   8   s     $I

!
!)
,C
{)' --#%G47+
7E:.),I&Jr   c                     |j                         }|j                  j                  D ]+  }|j                  |t	        ||            }t        | ||       - |j                         D ]  \  }}t        | ||        | S )zJ
    Copy structure from *src* to *dst* with replacement from *repl*.
    )copy
_datamodel_fieldspopgetattrsetattritems)dstsrcreplkr   s        r   copy_structrM   K   sl     99;D^^##HHQQ(Q $ 

1Q Jr   c                   |     e Zd ZdZdZddZd Zd Zd Zd Z	d Z
d	 Zd
 Z fdZd Zd Zd Zd Zd Zd Z xZS )_StructProxyz
    Creates a `Structure` like interface that is constructed with information
    from DataModel instance.  FE type must have a data model that is a
    subclass of StructModel.
    Nc                 f   || _         | j                   j                  | j                     | _        t	        | j                  t
        j                  j                  j                        s$t        dj                  | j                              || _        | j                  | j                        | _        t        | j                        rJ | j                  |      \  }}|j                   j"                  | j                  k7  r3t%        d| j                  j'                         d|j                         |n|j                   |j                   j"                  k7  r/t%        d|j                   j"                  d|j                         | j                  j)                  ||       || _        || _        y )NzNot a structure model: {0}zbad ref type: expected z, got zbad value type: expected )_contextdata_model_managerr0   rC   
isinstancenumbacore	datamodelStructModel	TypeErrorformat_builder_get_be_type_be_type
is_pointer
_make_refsr   pointeeAssertionError
as_pointerstore_value
_outer_ref)selfcontextr   r   ref	outer_refs         r   __init__z_StructProxy.__init__c   sL   --::4==I$//5::+?+?+K+KL,33DOODF F))$//:dmm,,,-	388t}}, $(MM$<$<$>"J K K zzY^^333$(1(>(>

&L M MMMy1#r   c                 R    |"t        | j                  | j                  d      }||fS )z
        Return an (outer ref, value ref) pair.  By default, these are
        the same pointers, but a derived class may override this.
        Tzfill)alloca_oncerZ   r\   )re   rg   s     r   r^   z_StructProxy._make_refs|   s(    
 ;dmmT]]$GCCxr   c                     t         NNotImplementedErrorre   rV   s     r   r[   z_StructProxy._get_be_type       !!r   c                     t         ro   rp   re   indexvals      r   _cast_member_to_valuez"_StructProxy._cast_member_to_value   rs   r   c                     t         ro   rp   ru   s      r   _cast_member_from_valuez$_StructProxy._cast_member_from_value   rs   r   c                 F    t        | j                  | j                  d|      S Nr   )gep_inboundsrZ   rc   re   rv   s     r   _get_ptr_by_indexz_StructProxy._get_ptr_by_index   s    DMM4;;5AAr   c                 Z    | j                   j                  |      }| j                  |      S ro   )rC   get_field_positionr   )re   attrnamerv   s      r   _get_ptr_by_namez_StructProxy._get_ptr_by_name   s'    228<%%e,,r   c                 v    |j                  d      s| | j                  j                  |         S t        |      z;
        Load the LLVM value of the named *field*.
        r/   )
startswithrC   r   AttributeErrorre   fields     r   __getattr__z_StructProxy.__getattr__   s7     $::5ABB ''r   c                     |j                  d      rt        t        |   ||      S || | j                  j                  |      <   yz@
        Store the LLVM *value* into the named *field*.
        r/   N)r   superrO   __setattr__rC   r   re   r   r   	__class__s      r   r   z_StructProxy.__setattr__   s@     C t8FF:?T__//67r   c                 z    | j                   j                  | j                  |            }| j                  ||      S z>
        Load the LLVM value of the field at *index*.
        )rZ   loadr   rx   )re   rv   
member_vals      r   __getitem__z_StructProxy.__getitem__   s6     ]]''(>(>u(EF
))%<<r   c                 f   | j                  |      }| j                  ||      }|j                  |j                  j                  k7  rt	        |j                        rt	        |j                  j                        r}|j                  j                  |j                  j                  j                  k(  rF| j
                  j                  | j                  ||j                  j                  j                        }nt        dj                  ||| |            | j                  j                  ||       y)C
        Store the LLVM *value* into the field at *index*.
        zjInvalid store of {value.type} to {ptr.type.pointee} in {self._datamodel} (trying to write member #{index}))r   ptrre   rv   N)r   rz   r   r_   r]   rQ   addrspacecastrZ   	addrspacerX   rY   rb   )re   rv   r   r   s       r   __setitem__z_StructProxy.__setitem__   s     $$U+,,UE:::)))5::&:chh6F6F+G

**chh.>.>.F.FF 33DMM4947HH4D4D4N4NP   !D "(e4.3 "( "5	6 6 	E3'r   c                 .    | j                   j                  S z.
        Return the number of fields.
        )rC   field_countre   s    r   __len__z_StructProxy.__len__   s     ***r   c                     | j                   S zF
        Return the LLVM pointer to the underlying structure.
        )rd   r   s    r   _getpointerz_StructProxy._getpointer   s     r   c                 L    | j                   j                  | j                        S zM
        Load and return the value of the underlying LLVM structure.
        )rZ   r   rd   r   s    r   	_getvaluez_StructProxy._getvalue   s     }}!!$//22r   c                     t        |j                        rJ |j                  | j                  k(  sJ |j                  | j                  f       | j                  j	                  || j
                         y)z4
        Store the value in this structure.
        N)r]   r   r\   rZ   rb   rc   re   r   s     r   	_setvaluez_StructProxy._setvalue   sV     ejj)))zzT]]*GUZZ,GG*E4;;/r   NN)r5   
__module____qualname____doc__r0   ri   r^   r[   rx   rz   r   r   r   r   r   r   r   r   r   r   __classcell__r   s   @r   rO   rO   Z   s\     H$2"""B-(@=(.+30r   rO   c                   "    e Zd ZdZd Zd Zd Zy)r3   zl
    Create a StructProxy suitable for accessing regular values
    (e.g. LLVM values or alloca slots).
    c                 "    |j                         S ro   )get_value_typerr   s     r   r[   zValueStructProxy._get_be_type   s    ''))r   c                     |S ro    ru   s      r   rx   z&ValueStructProxy._cast_member_to_value       
r   c                     |S ro   r   ru   s      r   rz   z(ValueStructProxy._cast_member_from_value   r   r   Nr5   r   r   r   r[   rx   rz   r   r   r   r3   r3      s    *r   r3   c                   "    e Zd ZdZd Zd Zd Zy)r4   zO
    Create a StructProxy suitable for accessing data persisted in memory.
    c                 "    |j                         S ro   )get_data_typerr   s     r   r[   zDataStructProxy._get_be_type   s    &&((r   c                 p    | j                   j                  |      }|j                  | j                  |      S ro   )rC   	get_model	from_datarZ   re   rv   rw   models       r   rx   z%DataStructProxy._cast_member_to_value   s+    ))%0t}}c22r   c                 p    | j                   j                  |      }|j                  | j                  |      S ro   )rC   r   as_datarZ   r   s       r   rz   z'DataStructProxy._cast_member_from_value   s+    ))%0}}T]]C00r   Nr   r   r   r   r4   r4      s    )31r   r4   c                   `     e Zd ZdZddZd Zd Zd Z fdZd Z	d Z
d	 Zd
 Zd Zd Z xZS )	Structurezs
    A high-level object wrapping a alloca'ed LLVM structure, including
    named fields and attribute access.
    c                    |j                  |       | _        || _        || _        |t	        || j                  d      | _        |t        |j                        rJ |j                  | j                  k(  sJ |j                  | j                  f       |j                  || j
                         n|J t        |j                        sJ | j                  |j                  j                  k7  r\|r+|j                  || j                  j                               }n/t        d|j                  j                  d| j                        || _        i | _        g | _        g | _        t!        d      }t#        | j$                        D ]X  \  }\  }}	|| j                  |<   | j                  j'                  |t!        |      f       | j                  j'                  |	       Z y )NTrk   zmismatching pointer type: got z, expected r   )get_struct_type_typerQ   rZ   rm   rc   r]   r   rb   r_   bitcastra   rX   _namemap_fdmap_typemapint32_tr   rD   append)
re   rf   r   r   rg   cast_refr<   r!   rL   tps
             r   ri   zStructure.__init__  s   ,,T2
;%gtzzFDK %ejj111zzTZZ/I%**djj1II/eT[[1= =chh'''zzSXX---!//#tzz/D/D/FGC#88++TZZ9: : DKqz#DLL1JAw2 DMM!KKgaj12MM  $ 2r   c                 p    | j                   j                  | j                  | j                  |   d      }|S )NT)inbounds)rZ   geprc   r   )re   rv   r   s      r   r   zStructure._get_ptr_by_index$  s/    mmT[[-?$O
r   c                 >    | j                  | j                  |         S ro   )r   r   )re   r   s     r   r   zStructure._get_ptr_by_name(  s    %%dmmH&=>>r   c                 ^    |j                  d      s| | j                  |      S t        |      r   )r   r   r   r   s     r   r   zStructure.__getattr__+  s1     $e,-- ''r   c                 t    |j                  d      rt        t        |   ||      S || | j                  |   <   yr   )r   r   r   r   r   r   s      r   r   zStructure.__setattr__4  s:     C D5eUCC%*T]]5!"r   c                 V    | j                   j                  | j                  |            S r   )rZ   r   r   r~   s     r   r   zStructure.__getitem__<  s$    
 }}!!$"8"8"?@@r   c                 *   | j                  |      }|j                  j                  |j                  k7  rCd}t        ||t	        |j                  j                        t	        |j                        fz        | j
                  j                  ||       y)r   z:Type mismatch: __setitem__(%d, ...) expected %r but got %rN)r   r   r_   r`   r6   rZ   rb   )re   rv   r   r   fmts        r   r   zStructure.__setitem__C  s}     $$U+88uzz)NC (+CHH,<,<(=(+EJJ(9 "9 : : 	E3'r   c                 ,    t        | j                        S r   )r%   r   r   s    r   r   zStructure.__len__O  s     4==!!r   c                     | j                   S r   )rc   r   s    r   r   zStructure._getpointerU  s     {{r   c                 L    | j                   j                  | j                        S r   )rZ   r   rc   r   s    r   r   zStructure._getvalue[  s     }}!!$++..r   c                     t        |j                        rJ |j                  | j                  k(  sJ |j                  | j                  f       | j                  j	                  || j
                         y)z!Store the value in this structureN)r]   r   r   rZ   rb   rc   r   s     r   r   zStructure._setvaluea  sT    ejj)))zzTZZ'A%**djj)AA'E4;;/r   )NNF)r5   r   r   r   ri   r   r   r   r   r   r   r   r   r   r   r   r   s   @r   r   r      s@    %>?(+A
("/0r   r   c                    t        |t              rt        j                  t        |      }t        j                  |       5  | j                         5  | j                  |||      }| j                   |d      |       ddd       |r+| j                  j                  j                  d      |       cddd       S # 1 sw Y   AxY w# 1 sw Y   yxY w)a  Allocate stack memory at the entry block of the current function
    pointed by ``builder`` with llvm type ``ty``.  The optional ``size`` arg
    set the number of element to allocate.  The default is 1.  The optional
    ``name`` arg set the symbol name inside the llvm IR for debugging.
    If ``zfill`` is set, fill the memory with zeros at the current
    use-site location.  Note that the memory is always zero-filled after the
    ``alloca`` at init-site (the entry block).
    )sizenameN)rS   intr   r&   intp_tr	   suspend_emissiongoto_entry_blockallocarb   r   r_   )r   tyr   r   rl   r   s         r   rm   rm   j  s     ${{64( 
	#	#G	,%%'..$T.:CMM"T(C( (
 MM#((**40#6 
-	,'' 
-	,s$    C
-B>>6C
>C	C

Cc                 t     |d      }|j                  t        d      g      }| j                  |t              S )zCompute sizeof using GEP
    Nr
   )r   r   ptrtointr   )r   ptr_typenulloffsets       r   sizeofr     s4     D>DXXwqzl#FFF++r   c                 Z    t        | |j                  |      }| j                  ||       |S )z
    Like alloca_once(), but passing a *value* instead of a type.  The
    type is inferred and the allocated slot is also initialized with the
    given value.
    rk   )rm   r   rb   )r   r   r   rl   storages        r   alloca_once_valuer     s)     '5::U;GMM%!Nr   c                     t        | ||      }|j                  j                  d       |j                  j                  d       |S )z_
    Insert a pure function (in the functional programming sense) in the
    given module.
    readonlynounwind)get_or_insert_function
attributesaddmodulefntyr   fns       r   insert_pure_functionr     s;    
 
 d	3BMMj!MMj!Ir   c                 p    | j                   j                  |d      }|t        j                  | ||      }|S )zm
    Get the function named *name* with type *fnty* from *module*, or insert it
    if it doesn't exist.
    N)globalsr2   r   Functionr   s       r   r   r     s6    
 
		D$	'B	z[[t,Ir   c                 f    	 | j                  |      S # t        $ r | j                  |      cY S w xY wro   )get_named_metadataKeyErroradd_named_metadata)r   r   s     r   get_or_insert_named_metadatar     s8    /((.. /((../s    00c                 T    | j                  |      }t        j                  | |||      S ro   )get_unique_namer   GlobalVariable)r   r   r   r   unique_names        r   add_global_variabler    s)    ((.KVRi@@r   c                 X    | j                   }|j                  | j                  |       y y ro   )basic_block
terminatorbranch)r   bbendbbs      r   	terminater    s(    			B	}}u r   c                      | d       S ro   r   )ltypes    r   get_null_valuer    s    ;r   c                 R    t        |j                        }| j                  d||      S )N==r  r   r   r   rw   r   s      r   is_nullr    %    #((#D  tS11r   c                 R    t        |j                        }| j                  d||      S )Nr   r  r  s      r   is_not_nullr    r  r   c                 (    | j                  |d      S )NFlikelyif_thenr   preds     r   if_unlikelyr    s    ??4?..r   c                 (    | j                  |d      S )NTr  r  r  s     r   	if_likelyr!    s    ??4?--r   c                 B    | j                  | j                  |            S ro   )r  not_r  s     r   ifnotr$    s    ??7<<-..r   c                 N    |j                  d      }| j                  ||dg      S )z#
    Increment an index *val*.
    r
   nsw)flags)r   r   )r   rw   ones      r   increment_indexr)    s*     ((1+C ;;sCw;//r   Loop)rv   do_breakc              #      K   ||j                   }| |d      }|} j                  d      } j                  d      } j                  d       fd} j                  } j                  |        j	                  |      5   j                  |d      }	 j                  d	|	|      }
 j                  |
|       ddd        j	                  |      5  t        	|        j                  }t         |	      }t         |       ddd       	j                  ||       |	j                  |        j                         y# 1 sw Y   xY w# 1 sw Y   KxY ww)
a  
    Generate LLVM IR for a for-loop in [start, count).
    *start* is equal to 0 by default.

    Yields a Loop namedtuple with the following members:
    - `index` is the loop index's value
    - `do_break` is a no-argument callable to break out of the loop
    Nr   for.condfor.bodyfor.endc                  (    j                          y ro   )r	  )r
  r   s   r   r+  zfor_range.<locals>.do_break  s    ur   
loop.indexr   <)r   append_basic_blockr  r	  
goto_blockphiicmp_signedcbranchr*  r)  r  add_incomingposition_at_end)r   countstartintpstopbbcondbbbodyr+  bbstartrv   r  incrr
  s   `           @r   	for_rangerC    sE     |zz}QD''
3F''
3F&&y1E !!GNN6			F	#D|4""3t4fe, 
$
 
		F	#5(##$$w.'6" 
$ 
ug&	tV$E" 
$	#
 
$	#s6   BE":E
 E"3E>E"
EE"EE"c              #   v  K   ||j                   }| j                  d      }| j                  d      }| j                  d      }| j                  }	| j                  |       | j	                  |      5  | j                  |d      }
| j                  |d      }|r| j                  d|
|      }n| j                  d	|
|      }| j                  |||       ddd       | j	                  |      5  
f | j                  }| j                  |
|      }t        | |      }t        | |       ddd       
j                  ||	       |
j                  |       j                  t        j                  |d
      |	       |j                  |       | j                  |       y# 1 sw Y   xY w# 1 sw Y   xY ww)a[  
    Generate LLVM IR for a for-loop based on a slice.  Yields a
    (index, count) tuple where `index` is the slice index's value
    inside the loop, and `count` the iteration count.

    Parameters
    -------------
    builder : object
        IRBuilder object
    start : int
        The beginning value of the slice
    stop : int
        The end value of the slice
    step : int
        The step value of the slice
    intp :
        The data type
    inc : boolean, optional
        Signals whether the step is positive (True) or negative (False).

    Returns
    -----------
        None
    Nr-  r.  r/  r1  r2  z
loop.countr3  >r   )r   r4  r  r	  r5  r6  r7  r8  r   r)  r  r9  r   r&   r:  )r   r<  r>  stepr=  incr?  r@  r
  rA  rv   r;  r  rB  
next_counts                  r   for_range_slicerI    s    4 |zz''
3F''
3F&&y1E!!GNN6			F	#D|4D|4&&sE48D&&sE48Dfe, 
$ 
		F	#Ul$${{5$'$We4
'6" 
$ 
ug&	tV$	r{{4+W5	z6*E") 
$	# 
$	#s8   A0F92A#F!F9.=F-+A6F9!F*&F9-F62F9c              #   L  K   |j                   }| j                  d|t        j                  |d            }t	        | ||||d      }t	        | ||||d      }t
        d        }| j                  |d      5 \  }	}
 ||	|       ||
|      f ddd       y# 1 sw Y   yxY ww)	a  
    A helper wrapper for for_range_slice().  This is a context manager which
    yields two for_range_slice()-alike context managers, the first for
    the positive step case, the second for the negative step case.

    Use:
        with for_range_slice_generic(...) as (pos_range, neg_range):
            with pos_range as (idx, count):
                ...
            with neg_range as (idx, count):
                ...
    >=r   T)rG  Fc              3   p   K   | 5  |5 }| d d d        d d d        y # 1 sw Y   xY w# 1 sw Y   y xY wwro   r   )condinner_cmr   s      r   cm_condz(for_range_slice_generic.<locals>.cm_cond`  s,     U  T Ts$   6**	6'	*36r  N)r   r7  r   r&   rI  r   if_else)r   r<  r>  rF  r=  is_pos_steppos_for_rangeneg_for_rangerO  then	otherwises              r   for_range_slice_genericrV  L  s      ::D%%dD"++dA2FGK#GUD$$OM#GUD$%PM 
 
T	26GtYdM*GI},MMM 
3	2	2s   A5B$7B	B$B!B$c              #      K   |dv sJ |sd y|dk(  rd }nd }t        |  ||      |      5 }t        |      t        |      k(  sJ  ||       ddd       y# 1 sw Y   yxY ww)a  
    Generate a loop nest walking a N-dimensional array.
    Yields a tuple of N indices for use in the inner loop body,
    iterating over the *shape* space.

    If *order* is 'C' (the default), indices are incremented inside-out
    (i.e. (0,0), (0,1), (0,2), (1,0) etc.).
    If *order* is 'F', they are incremented outside-in
    (i.e. (0,0), (1,0), (2,0), (0,1) etc.).
    This has performance implications when walking an array as it impacts
    the spatial locality of memory accesses.
    CFr   Fc                     | d d d   S )Nr   xs    r   <lambda>zloop_nest.<locals>.<lambda>~  s    a"gr   c                     | S ro   r   r\  s    r   r^  zloop_nest.<locals>.<lambda>  s    ar   N)
_loop_nestr%   )r   shaper=  order_swapindicess         r   	loop_nestre  j  sj      D==C<%EEut4w<3u:---.  544s   -A($A	A(A%!A(c              #     K   t        | |d   |      5 }t        |      dkD  r,t        | |dd  |      5 }|j                  f|z    d d d        n|j                  f d d d        y # 1 sw Y   xY w# 1 sw Y   y xY ww)Nr   r=  r
   )rC  r%   r`  rv   )r   ra  r=  looprd  s        r   r`  r`    su     	7E!H4	0Du:>GU12Y5zzmg-- 65 ::- 
1	055 
1	0s3   A?A3A'A3	A?'A0	,A33A<8A?c                     t        |      }||d   j                  } t        j                  ||      t        j                        }t        |      D ]  \  }}| j                  |||      } |S )z
    Pack a sequence of values in a LLVM array.  *ty* should be given
    if the array may be empty, in which case the type can't be inferred
    from the values.
    r   )r%   r   r   r'   r   r   r   )r   r   r   r+   aryr!   r   s          r   
pack_arrayrk    sf     	FA	zAY^^
",,r1
bll
+C&!1""31- "Jr   c                     t        j                  |D cg c]  }|j                   c}      } |t         j                        }t	        |      D ]  \  }}| j                  |||      } |S c c}w )z7
    Pack a sequence of values into a LLVM struct.
    r   )r   r   r   structtystr!   s         r   pack_structro    sf     ##V$<VQVVV$<=H	",,	B&!1!!"a+ "I	 %=s   A,c                     |t        |j                  j                        }t        |      D cg c]  }| j	                  ||       }}|S c c}w )zH
    Unpack an array or structure of values, return a Python tuple.
    )r%   r   elementsrangeextract_value)r   tupr;  r!   valss        r   unpack_tuplerv    sX     }CHH%%&5\#! !!#q)! 	 #K#s   Ac                     t        ||j                  |j                        }t        ||j                  |j                        }t	        | ||j
                  |||j                  |||	      S )N)r;  )r.   ra  strideslayoutinds
wraparoundboundscheck)rv  ra  ndimrx  get_item_pointer2r.   ry  )	rf   r   arytyrj  rz  r{  r|  shapesrx  s	            r   get_item_pointerr    s[    
 '399EJJ?F7CKKuzzBGWgCHHF%,U\\(2M Mr   c                    fd}d}j                  d      }t        |      5  t        j                  r |        | j                  j                  t        |f       d d d        j                  dj                  d            }t        |      5  t        j                  r |        | j                  j                  t        |f       d d d        y # 1 sw Y   zxY w# 1 sw Y   y xY w)Nc                       >t         t              rt        dj                                y t        d        y t        d       y )NzFdebug: IndexError: index %d is out of bounds for axis {} with size %d
zFdebug: IndexError: index %d is out of bounds for axis %d with size %d
z9debug: IndexError: index %d is out of bounds for size %d
)rS   r   printfrY   )axisr   dimleninds   r   _dbgzdo_boundscheck.<locals>._dbg  s_     $$w !44:F4L#vO w !458$ 7O r   zindex is out of boundsrK  r3  r   )r7  r  r   FULL_TRACEBACKS	call_convreturn_user_exc
IndexErrorr   )	rf   r   r  r  r  r  msgout_of_bounds_upperout_of_bounds_lowers	    ````    r   do_boundscheckr    s       #C!--dC@	W1	2!!F))':vF 
3 "--c3D	W1	2!!F))':vF 
3	2 
3	2
 
3	2s   :C!:C-!C*-C6c	                    |rog }	t        ||      D ]]  \  }
}|j                  d|
|
j                  d            }|j                  ||
      }|j	                  |||
      }|	j                  |       _ n|}	|r/t        t        |	|            D ]  \  }\  }
}t        | ||
||        |	s|j                  |t        d      g      S |	d   j                  }|dv rg }|dk(  rRt        t        |            D ]:  } |d      }||dz   d  D ]  }|j                  ||      } |j                  |       < n_|dk(  rOt        t        |            D ]7  } |d      }|d | D ]  }|j                  ||      } |j                  |       9 nt        d       |d      }t        |	|      D ])  \  }}|j                  ||      }|j                  ||      }+ |j                  ||g      }|S t        ||	      D cg c]  \  }}|j                  ||       }}}t        j                  |j                  |      }t!        |||      S c c}}w )Nr3  r   rX  Cr
   rY  unreachable)zipr7  r   r   selectr   r   r  r   r   rr  r%   mul	Exception	functoolsreducepointer_add)rf   r   r.   ra  rx  ry  rz  r{  r|  rd  r  r  negativewrappedselectedr  r=  stepsr!   lastjlocstmpr   dimoffsr   s                              r   r~  r~    s=   
 tU+KC**3SXXa[AHkk&#.G~~h=HNN8$	 , #,S%-@#AD-37GS&$? $B {{4'!*..1:??D~S=3u:&Awq1uvA";;tQ/D 'T"	 '
 s]3u:&AwrA";;tQ/D #T"	 ' M** 1g'DAq++a#C++c3'C ( kk$&
 25Wg1FG1FA7;;q!$1FG!!'++w77D&11 Hs   3H?c                 D   |j                  d      }t        |j                   t        j                  t        j                  f      r |||      }|S t        |j                   t        j
                        r| j                  |||      }|S t        d|j                         )Nr   zunexpected value type )r   rS   r   	FloatType
DoubleTyper(   r7  rX   )r   r   fpredicondnullvalisnulls         r   _scalar_pred_against_zeror    s    jjmG%**r||R]];<ug&
 M	 
EJJ

	+$$UE7; M ejjBCCr   c                 Z    t        | |t        j                  | j                  d      d      S )zK
    Return a predicate representing whether *value* is equal to zero.
    r  r  r  partialfcmp_orderedr   s     r   is_scalar_zeror  %  s/     %	))'*>*>EtM Mr   c                 Z    t        | |t        j                  | j                  d      d      S )z
    Return a predicate representing whether a *value* is not equal to zero.
    (not exactly "not is_scalar_zero" because of nans)
    r   r  r  r  fcmp_unorderedr   s     r   is_not_scalar_zeror  -  /    
 %	))'*@*@$GO Or   c                 Z    t        | |t        j                  | j                  d      d      S )z]
    Return a predicate representing whether *value* is equal to either zero
    or NaN.
    r  r  r   s     r   is_scalar_zero_or_nanr  6  r  r   c                 Z    t        | |t        j                  | j                  d      d      S )z:
    Is *value* negative?  Assumes *value* is signed.
    r3  r  r   s     r   is_scalar_negr  C  s/     %	))'*>*>DcK Kr   stackc              #      K   |j                  | j                  |d            \  }}|5  d ddd       |j                  |       y# 1 sw Y   xY ww)a  
    The Python code::

        with contextlib.ExitStack() as stack:
            with early_exit_if(builder, stack, cond):
                cleanup()
            body()

    emits the code::

        if (cond) {
            <cleanup>
        }
        else {
            <body>
        }

    This can be useful for generating code with lots of early exits, without
    having to increase the indentation each time.
    Fr  N)enter_contextrP  )r   r  rM  rT  rU  s        r   early_exit_ifr  K  sI     , ))'//$u/*MNOD)	 
		" 
s   (AA	A	AAc                 0    t        | |t        | |            S )z
    A convenience wrapper for :func:`early_exit_if`, for the common case where
    the CPython API indicates an error by returning ``NULL``.
    )r  r  )r   r  objs      r   early_exit_if_nullr  g  s    
 %#)>??r   c                     |j                  t        ||      d      5  |d   }|dd xs d}| j                  j                  |||       ddd       y# 1 sw Y   yxY w)zu
    Guard against *value* being null or zero.
    *exc_tuple* should be a (exception type, arguments...) tuple.
    Fr  r   r
   N)r  r  r  r  )rf   r   r   	exc_tupleexcexc_argss         r   
guard_nullr  o  sY    
 
7	FlQR=(D))'3A 
G	F	Fs   ,AAc                 "   t        |j                  t        j                        sJ |j                         |r|fnd}|j	                  t        ||      d      5  | j                  j                  |t        |       ddd       y# 1 sw Y   yxY w)zG
    Guard against *pointer* being NULL (and raise a MemoryError).
    r   Fr  N)	rS   r   r   PointerTyper  r  r  r  MemoryError)rf   r   pointerr  r  s        r   guard_memory_errorr  z  sl     gllBNN3AW\\A3v"H	'25	A))';I 
B	A	As   "BBc              #   x   K   | j                  t        | |      |      5  d ddd       y# 1 sw Y   yxY ww)z>
    Execute the given block if the scalar value is zero.
    r  N)r  r  )r   r   r  s      r   if_zeror    s.     
 
7	G 
H	G	Gs   :.	:7:c                 6    t        | t        j                        S )z7
    Whether the LLVM type *typ* is a struct type.
    )rS   r   r  )ltyps    r   r]   r]     s     dBNN++r   c                     t        | |d|      }t        |j                  j                        rJ | j	                  ||j                               S r|   )r}   r]   r   r_   r   ra   )r   recordr   typpvals        r   get_record_memberr    sB    F3D$))++,,,??4!122r   c                 F    | j                  d||j                  d            S )Nr3  r   )r7  r   )r   rw   s     r   
is_neg_intr    s    sC!55r   c                 &    t        | |g|ddi|S )z8
    Same as *gep*, but add the `inbounds` keyword.
    r   T)r   )r   r   rz  kwss       r   r}   r}     s      w9d9T9S99r   c                     |j                  dd      }|j                  dd      }|rJ g }|D ]1  }t        |t              rt        |      }n|}|j	                  |       3 | j                  ||||      S )z
    Emit a getelementptr instruction for the given pointer and indices.
    The indices can be LLVM values or Python int constants.
    r    r   F)r   r   )rE   rS   r   r   r   r   )	r   r   rz  r  r   r   idxr!   r  s	            r   r   r     sv    
 7762Dwwz5)HN7
Ca!*CC

3  ;;sCdX;>>r   c                     | j                  |t              }t        |t              rt        |      }| j	                  ||      }| j                  ||xs |j                        S )z
    Add an integral *offset* to pointer *ptr*, and return a pointer
    of *return_type* (or, if omitted, the same type as *ptr*).

    Note the computation is done in bytes, and ignores the width of
    the pointed item type.
    )r   r   rS   r   r   inttoptrr   )r   r   r   return_typeintptrs        r   r  r    sU     c6*F&#[[(FFK$;388<<r   c           	          | j                   j                  dt        |j                  f      }| j	                  |t              }t        |t              rt        |      }| j                  ||||t        d      g       y)z=
    Fill *size* bytes starting from *ptr* with *value*.
    zllvm.memsetr   N)
r   declare_intrinsic	voidptr_tr   r   rS   r   int8_tcallbool_t)r   r   r   r   r   s        r   memsetr    sa     
	)	)-)TYY9O	PB
//#y
)C%uLLc5$q	23r   c                     | j                  |      }t        | |t        | |j                        d       | j	                  ||       y)z7
    Fill padding bytes of the pointee with zeros.
    r   N)r   r  r   r   rb   )r   r   rw   s      r   memset_paddingr    s9    
 ,,s
C
7C2A6MM#sr   c                     t        | t        j                        r| }n| j                  }t	        ||j
                  |      }||_        d|_        ||_        |S )zO
    Get or create a (LLVM module-)global constant with *name* or *value*.
    T)	rS   r   Moduler   r  r   linkageglobal_constantinitializer)builder_or_moduler   r   r  r   r.   s         r   r  r    sQ     #RYY/""))vuzz48DDLDDKr   c                    |dkD  sJ |j                  |      }|j                  d      }t        | |j                         }| j                  t        | |            5 \  }}|5  | j	                  ||      }| j                  ||       ddd       |5  | j                  ||      }| j	                  ||      }| j                  | j                  ||      |       ddd       ddd       | j                  |      }| j                  || j                  ||            }	||	fS # 1 sw Y   xY w# 1 sw Y   TxY w# 1 sw Y   XxY w)a  
    Compute the (quotient, remainder) of *val* divided by the constant
    positive *divisor*.  The semantics reflects those of Python integer
    floor division, rather than C's / LLVM's signed division and modulo.
    The difference lies with a negative *val*.
    r   r
   N)
r   rm   rP  r  sdivrb   r   subr   r  )
r   rw   divisorr(  quotif_negif_posquot_valval_plus_onerem_vals
             r   divmod_by_constantr    s    Q;;hhwG
((1+Cw)D	GS1	26Fvv||C1HMM(D)  ";;sC0L||L':HMM'++h4d;	  
3 ||D!Hkk#w{{8W=>GW V V 
3	2s=   D6!%D
D6AD*D6D'	#D6*D3	/D66D?c                 p    | j                  d      }| j                  |||       | j                  |       |S )z
    Branch conditionally or continue.

    Note: a new block is created and builder is moved to the end of the new
          block.
    z	.continue)r4  r8  r:  )r   rM  bbtruebbconts       r   cbranch_or_continuer    s7     ''4FOOD&&)F#Mr   c                 J   |j                   |j                   k(  sJ t        | ||j                         5 }| j                  ||j                  g      }| j                  ||j                  g      }| j	                  | j                  |      |       ddd       y# 1 sw Y   yxY w)z
    Emit a memcpy to the builder.

    Copies each element of dst to src. Unlike the C equivalent, each element
    can be any LLVM type.

    Assumes
    -------
    * dst.type == src.type
    * count is positive
    rg  N)r   rC  r   rv   rb   r   )r   rI   rJ   r;  rh  out_ptrin_ptrs          r   memcpyr    s{     88sxx	7E

	3t++cDJJ<0S4::,/gll6*G4 
4	3	3s   ABB"c           	      ^   |j                   }t        |t              rt        j                  ||      }| j
                  j                  |t        t        |g      }t        }	| j                  || j                  |t              | j                  |t              | j                  ||      |	g       y ro   )r   rS   r   r   r&   r   r  r  	false_bitr  r   r  )
r   	func_namerI   rJ   r;  itemsizealignsize_tr  is_volatiles
             r   _raw_memcpyr	  1  s    ZZF(C ;;vx0^^--i/8)V.LNFKLL'//#y9!//#y9!++eX6%' (r   c           	      $    t        | d|||||      S )za
    Emit a raw memcpy() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memcpyr	  r   rI   rJ   r;  r  r  s         r   
raw_memcpyr  ?  s    
 wsC%PPr   c           	      $    t        | d|||||      S )zb
    Emit a raw memmove() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memmover  r  s         r   raw_memmover  G  s     
 wS%( (r   c                    | j                  ||      }| j                  |d      }| j                  |d      }| j                  ||      }| j                  |d      }| j                  || j                  |d            }	||	fS )zq
    Compute (a * b + c) and return a (result, overflow bit) pair.
    The operands must be signed integers.
    r   r
   )smul_with_overflowrs  sadd_with_overflowor_)
r   ar*   cpprodprod_ovfr  r;   ovfs
             r   muladd_with_overflowr  P  s    
 	""1a(A  A&D$$Q*H""4+A


1
%C
++h 5 5a ;
<C8Or   c                    t        |t              sJ | j                  }t        }t	        |dz   j                  d            }t        |d|      }t        j                  t        |gd      }	 |j                  d      }| j                  ||      }	| j                  ||	gt        |      z         S # t        $ r t        j                  ||d      }Y Tw xY w)a  
    Calls printf().
    Argument `format` is expected to be a Python string.
    Values to be printed are listed in `args`.

    Note: There is no checking to ensure there is correct number of values
    in `args` and there type matches the declaration in the format string.
     asciiprintf_formatTvar_argr  r2  )rS   r6   r   r  r,   encoder  r   FunctionTyper   
get_globalr   r   r   r  list)
r   rY   argsmodcstring	fmt_bytes
global_fmtr   r   ptr_fmts
             r   r  r  ^  s     fc"""
..CG66w?@I oyAJ??7WIt<D3^^H% ooj'2G<<WIT
233	  3[[d23s   -B/ /!CCc                    t        |t              sJ | j                  }t        }t	        |dz   j                  d            }t        |d|      }t        j                  t        |t        |gd      }	d}
t        j                  rd|
z   }
	 |j                  |
      }| j!                  ||      }| j#                  ||||gt%        |      z         S # t        $ r t        j                  ||	|
      }Y Vw xY w)	z8Calls libc snprintf(buffer, bufsz, format, ...args)
    r  r  snprintf_formatTr  snprintfr/   r2  )rS   r6   r   r  r,   r!  r  r   r"  r   r   r   IS_WIN32r#  r   r   r   r  r$  )r   bufferbufszrY   r%  r&  r'  r(  r)  r   symbolr   r*  s                r   r-  r-  x  s     fc"""
..CG66w?@I &7CJ??'67+TD Fv1^^F# ooj'2G<<VUG4tDzABB	  1[[d01s   
C !C21C2c                     t        |t              sJ t        j                  t        j                  d      |      }t        | |d      }| j                  |t              }t        | |t        |      |g|  |S )z{Similar to `snprintf()` but the buffer is stack allocated to size
    *bufsz*.

    Returns the buffer pointer as i8*.
    r   Trk   )
rS   r   r   r'   r(   rm   r   r  r-  r   )r   r0  rY   r%  spacetyspacer/  s          r   snprintf_stackbufferr5    sf     eS!!!ll2::a=%0G5E__UI.FWffUmV;d;Mr   c                 B    | j                  d      j                  d      S )zk
    Normalize the given string to latin1 compatible encoding that is
    suitable for use in LLVM IR.
    utf8latin1)r!  decode)texts    r   normalize_ir_textr;    s     ;;v%%h//r   c                 p   d}| j                  |t              }t        | d||       t        j                  d      }| j                  ||j                               }t        | |      5 }| j                  |j                  t        |            }| j                  d|t        d            }| j                  |      5  t        | d       ddd       | j                  ||j                  g      }| j                  |      }	t        | d|	       ddd       t        | d       y# 1 sw Y   YxY w# 1 sw Y   "xY w)	zIDebug print the memory region in *ptr* to *ptr + nbytes*
    as hex.
       zhexdump p=%p n=%zur   r  r   
Nz %02x)zextr   r  r   r(   r   ra   rC  uremrv   r   r  r   r   )
r   r   nbytesbytes_per_linebyte_tr  div_bydo_new_liner   rw   s
             r   hexdumprF    s     N\\&&)F
7(ZZ]F
//#v002
3C	7F	#scii)?@++D&&)D__[)7D! * S399+.ll6"w% 
$ 7D *) 
$	#s&   (AD,;D AD, D)	%D,,D5c                 z    | du xs6 t        | t        j                        xs t        | t        j                        S )z returns if 'ty' is none N)rS   r   NoneTypeOmitted)r   s    r   is_nonelikerJ    s6     	d
 	&2u~~&	&2u}}%r   c                 h    t        j                  t        j                  | t        |            |      S )z
    Create an LLVM-constant of a fixed-length array from Python values.

    The type provided is the type of the elements.
    )r   r&   r'   r%   )r   rw   s     r   create_constant_arrayrL    s$     ;;r||BC1377r   ro   )r   )Nr  F)r  F)r   r   )NT)r  )FF)F)internal)r
   )fr   collections
contextlibr   r   r  llvmliter   
numba.corer   r   r   r	   numba.core.datamodelrT   r(   r  r  r   MACHINE_BITSr   ra   r  true_bitr  	true_byte
false_byter   r"   r,   r1   r@   rM   objectrO   r3   r4   r   rm   r   r   r   r   r   r  r  r  r  r  r  r!  r$  r)  
namedtupler*  rC  rI  rV  re  r`  rk  ro  rv  r  r  r~  r  r  r  r  is_trueis_falser  r  r  r  r  r  
guard_zeror]   r  r  r}   r   r  r  r  r  r  r  r  r	  r  r  r  r  r-  r5  r;  rF  rJ  rL  r   r   r   <module>r\     s  
  0   6 6  
A	A
"**R.	E&&	'	!91I	1I	AY
=	:  &  " B06 B0J| 1l 1 g0 g0X2,/A
2
2
/./0 {f&;< (# (#V 6# 6#r N N: ! !6    	 EJ!&	MG> 5:72tMOO K #) # #6@BJ   
,36:?&=4	>
5*(Q(44C40.8r   