U
    ú¾|ei˜  ã                   @   sN  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 d¡Ze d¡Ze d¡Ze e	j¡Ze ¡ ZedƒZedƒZedƒZedƒZd	d
„ Zdšdd„Zdd„ Zi Zd›dd„Zi fdd„Z G dd„ de!ƒZ"G dd„ de"ƒZ#G dd„ de"ƒZ$G dd„ de!ƒZ%dœdd„Z&d d!„ Z'd�d"d#„Z(d$d%„ Z)d&d'„ Z*d(d)„ Z+džd*d+„Z,d,d-„ Z-d.d/„ Z.d0d1„ Z/d2d3„ Z0d4d5„ Z1d6d7„ Z2d8d9„ Z3d:d;„ Z4e 5d<d=¡Z6edŸd>d?„ƒZ7ed dAdB„ƒZ8edCdD„ ƒZ9ed¡dFdG„ƒZ:edHdI„ ƒZ;d¢dJdK„Z<dLdM„ Z=d£dNdO„Z>d¤dPdQ„Z?d¥dRdS„Z@d¦dTdU„ZAdVdW„ ZBdXdY„ ZCdZd[„ ZDd\d]„ ZEeDZFeCZGd^d_„ ZHeed`œdadb„ƒZIdcdd„ ZJdedf„ ZKd§dgdh„ZLed¨didj„ƒZMeKZNdkdl„ ZOdmdn„ ZPdodp„ ZQdqdr„ ZRdsdt„ ZSd©dudv„ZTdwdx„ ZUdydz„ ZVdªd|d}„ZWd~d„ ZXd€d�„ ZYd‚dƒ„ ZZd„d…„ Z[d«d†d‡„Z\d¬dˆd‰„Z]dŠd‹„ Z^dŒd�„ Z_dŽd�„ Z`d�d‘„ Zad’d“„ Zbd”d•„ Zcd–d—„ Zdd˜d™„ ZedS )­z+
Generic helpers for LLVM code generation.
é    N)ÚcontextmanagerÚ	ExitStack)Úir)ÚutilsÚtypesÚconfigÚ	debuginfoé   é   é    c                 C   s   |   d|| d¡¡S )Nú!=r   )Úicmp_unsignedÚtype©ÚbuilderÚvalue© r   úO/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/core/cgutils.pyÚas_bool_bit   s    r   c                 C   sJ   |dkrt  dd„ |D ƒ¡}|t jƒ}t|ƒD ]\}}|  |||¡}q.|S )zH
    Create an anonymous struct containing the given LLVM *values*.
    Nc                 S   s   g | ]
}|j ‘qS r   ©r   ©Ú.0Úvr   r   r   Ú
<listcomp>%   s     z)make_anonymous_struct.<locals>.<listcomp>©r   ÚLiteralStructTypeÚ	UndefinedÚ	enumerateÚinsert_value)r   ÚvaluesZstruct_typeZ
struct_valÚir   r   r   r   Úmake_anonymous_struct    s    
r!   c                 C   s*   t | ƒ}t|ƒ}t t t d¡|¡|¡S )z0
    Make a byte array constant from *buf*.
    r
   )Ú	bytearrayÚlenr   ÚConstantÚ	ArrayTypeÚIntType)ÚbufÚbÚnr   r   r   Úmake_bytearray,   s    r*   r   c                 C   sb   | |f}t  |¡}|dkr^ttdœ| }|jd t| ƒ }|f}t| d�}t|||ƒ}|t |< |S )zK
    Returns a specialized StructProxy subclass for the given fe_type.
    N)r   ÚdataÚ_)Ú_fe_type)Ú_struct_proxy_cacheÚgetÚValueStructProxyÚDataStructProxyÚ__name__ÚstrÚdictr   )Zfe_typeÚkindÚ	cache_keyÚresÚbaseÚclsnameÚbasesZ
clsmembersr   r   r   Úcreate_struct_proxy8   s    
ÿþ
r;   c                 C   sV   |  ¡ }|jjD ]"}| |t||ƒ¡}t| ||ƒ q| ¡ D ]\}}t| ||ƒ q<| S )zJ
    Copy structure from *src* to *dst* with replacement from *repl*.
    )ÚcopyÚ
_datamodelÚ_fieldsÚpopÚgetattrÚsetattrÚitems)ÚdstÚsrcÚreplÚkr   r   r   r   Úcopy_structK   s    rG   c                       s–   e Zd ZdZdZd!dd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Z‡  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                 C   sØ   || _ | j j| j | _t| jtjjjƒs8t	d 
| j¡ƒ‚|| _|  | j¡| _t| jƒrZt‚|  |¡\}}|jj| jkrŽtd| j ¡ |jf ƒ‚|d k	rÈ|j|jjkrºtd|jj|jf ƒ‚| j ||¡ || _|| _d S )NzNot a structure model: {0}z!bad ref type: expected %s, got %sz#bad value type: expected %s, got %s)Ú_contextÚdata_model_managerr-   r=   Ú
isinstanceÚnumbaÚcoreÚ	datamodelZStructModelÚ	TypeErrorÚformatÚ_builderÚ_get_be_typeÚ_be_typeÚ
is_pointerÚAssertionErrorÚ
_make_refsr   ÚpointeeÚ
as_pointerÚstoreÚ_valueÚ
_outer_ref)ÚselfÚcontextr   r   ÚrefZ	outer_refr   r   r   Ú__init__c   s,    
ÿÿÿz_StructProxy.__init__c                 C   s"   |dkrt | j| jd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.
        NT©Úzfill)Úalloca_oncerQ   rS   )r\   r^   r   r   r   rV   |   s    z_StructProxy._make_refsc                 C   s   t ‚d S ©N©ÚNotImplementedError©r\   rN   r   r   r   rR   …   s    z_StructProxy._get_be_typec                 C   s   t ‚d S rc   rd   ©r\   ÚindexÚvalr   r   r   Ú_cast_member_to_valueˆ   s    z"_StructProxy._cast_member_to_valuec                 C   s   t ‚d S rc   rd   rg   r   r   r   Ú_cast_member_from_value‹   s    z$_StructProxy._cast_member_from_valuec                 C   s   t | j| jd|ƒS ©Nr   )Úgep_inboundsrQ   rZ   ©r\   rh   r   r   r   Ú_get_ptr_by_indexŽ   s    z_StructProxy._get_ptr_by_indexc                 C   s   | j  |¡}|  |¡S rc   )r=   Úget_field_positionro   )r\   Úattrnamerh   r   r   r   Ú_get_ptr_by_name‘   s    z_StructProxy._get_ptr_by_namec                 C   s&   |  d¡s| | j |¡ S t|ƒ‚dS ©z;
        Load the LLVM value of the named *field*.
        r,   N)Ú
startswithr=   rp   ÚAttributeError©r\   Úfieldr   r   r   Ú__getattr__•   s    
z_StructProxy.__getattr__c                    s0   |  d¡rtt| ƒ ||¡S || | j |¡< dS ©z@
        Store the LLVM *value* into the named *field*.
        r,   N)rt   ÚsuperrH   Ú__setattr__r=   rp   ©r\   rw   r   ©Ú	__class__r   r   r{   ž   s    
z_StructProxy.__setattr__c                 C   s   | j  |  |¡¡}|  ||¡S ©z>
        Load the LLVM value of the field at *index*.
        )rQ   Úloadro   rj   )r\   rh   Z
member_valr   r   r   Ú__getitem__¦   s    z_StructProxy.__getitem__c                 C   sŽ   |   |¡}|  ||¡}|j|jjkr|t|jƒrft|jjƒrf|jj|jjjkrf| j | j||jjj¡}nt	dj
||| |d�ƒ‚| j ||¡ dS )ú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   Úptrr\   rh   N)ro   rk   r   rW   rT   rI   ÚaddrspacecastrQ   Ú	addrspacerO   rP   rY   )r\   rh   r   rƒ   r   r   r   Ú__setitem__­   s"    
ÿ
þ  ûz_StructProxy.__setitem__c                 C   s   | j jS ©z.
        Return the number of fields.
        )r=   Zfield_count©r\   r   r   r   Ú__len__Ä   s    z_StructProxy.__len__c                 C   s   | j S ©zF
        Return the LLVM pointer to the underlying structure.
        )r[   rˆ   r   r   r   Ú_getpointerÊ   s    z_StructProxy._getpointerc                 C   s   | j  | j¡S ©zM
        Load and return the value of the underlying LLVM structure.
        )rQ   r€   r[   rˆ   r   r   r   Ú	_getvalueÐ   s    z_StructProxy._getvaluec                 C   s>   t |jƒrt‚|j| jks*t|j| jfƒ‚| j || j¡ dS )z4
        Store the value in this structure.
        N)rT   r   rU   rS   rQ   rY   rZ   ©r\   r   r   r   r   Ú	_setvalueÖ   s    z_StructProxy._setvalue)NN)r2   Ú
__module__Ú__qualname__Ú__doc__r-   r_   rV   rR   rj   rk   ro   rr   rx   r{   r�   r†   r‰   r‹   r�   r�   Ú__classcell__r   r   r}   r   rH   Z   s"   
		rH   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r0   zl
    Create a StructProxy suitable for accessing regular values
    (e.g. LLVM values or alloca slots).
    c                 C   s   |  ¡ S rc   )Zget_value_typerf   r   r   r   rR   ä   s    zValueStructProxy._get_be_typec                 C   s   |S rc   r   rg   r   r   r   rj   ç   s    z&ValueStructProxy._cast_member_to_valuec                 C   s   |S rc   r   rg   r   r   r   rk   ê   s    z(ValueStructProxy._cast_member_from_valueN©r2   r�   r‘   r’   rR   rj   rk   r   r   r   r   r0   ß   s   r0   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r1   zO
    Create a StructProxy suitable for accessing data persisted in memory.
    c                 C   s   |  ¡ S rc   )Úget_data_typerf   r   r   r   rR   ò   s    zDataStructProxy._get_be_typec                 C   s   | j  |¡}| | j|¡S rc   )r=   Ú	get_modelÚ	from_datarQ   ©r\   rh   ri   Úmodelr   r   r   rj   õ   s    z%DataStructProxy._cast_member_to_valuec                 C   s   | j  |¡}| | j|¡S rc   )r=   r–   Úas_datarQ   r˜   r   r   r   rk   ù   s    z'DataStructProxy._cast_member_from_valueNr”   r   r   r   r   r1   î   s   r1   c                       sr   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ Z‡ fdd„Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )Ú	Structurezs
    A high-level object wrapping a alloca'ed LLVM structure, including
    named fields and attribute access.
    NFc           
      C   s0  |  | ¡| _|| _|| _|d krtt|| jdd�| _|d k	rÐt|jƒrHt‚|j| jksdt|j| jfƒ‚| 	|| j¡ n\|d ks€t‚t|jƒsŽt‚| j|jj
krÊ|r´| || j ¡ ¡}ntd|jj
| jf ƒ‚|| _i | _g | _g | _tdƒ}t| jƒD ]6\}\}}	|| j|< | j |t|ƒf¡ | j |	¡ qôd S )NTr`   z-mismatching pointer type: got %s, expected %sr   )Úget_struct_typeÚ_typerI   rQ   rb   rZ   rT   r   rU   rY   rW   ÚbitcastrX   rO   Ú_namemapÚ_fdmapZ_typemapÚint32_tr   r>   Úappend)
r\   r]   r   r   r^   Zcast_refr8   r    rF   Útpr   r   r   r_     s8    ÿÿ
zStructure.__init__c                 C   s   | j j| j| j| dd�}|S )NT)Úinbounds)rQ   ÚgeprZ   r    )r\   rh   rƒ   r   r   r   ro   $  s    zStructure._get_ptr_by_indexc                 C   s   |   | j| ¡S rc   )ro   rŸ   )r\   rq   r   r   r   rr   (  s    zStructure._get_ptr_by_namec                 C   s$   |  d¡s| | j|  S t|ƒ‚dS rs   )rt   rŸ   ru   rv   r   r   r   rx   +  s    
zStructure.__getattr__c                    s.   |  d¡rtt| ƒ ||¡S || | j| < dS ry   )rt   rz   r›   r{   rŸ   r|   r}   r   r   r{   4  s    
zStructure.__setattr__c                 C   s   | j  |  |¡¡S r   )rQ   r€   ro   rn   r   r   r   r�   <  s    zStructure.__getitem__c                 C   sN   |   |¡}|jj|jkr<d}t||t|jjƒt|jƒf ƒ‚| j ||¡ dS )r‚   z:Type mismatch: __setitem__(%d, ...) expected %r but got %rN)ro   r   rW   rU   r3   rQ   rY   )r\   rh   r   rƒ   Úfmtr   r   r   r†   C  s    

þzStructure.__setitem__c                 C   s
   t | jƒS r‡   )r#   rŸ   rˆ   r   r   r   r‰   O  s    zStructure.__len__c                 C   s   | j S rŠ   )rZ   rˆ   r   r   r   r‹   U  s    zStructure._getpointerc                 C   s   | j  | j¡S rŒ   )rQ   r€   rZ   rˆ   r   r   r   r�   [  s    zStructure._getvaluec                 C   s>   t |jƒrt‚|j| jks*t|j| jfƒ‚| j || j¡ dS )z!Store the value in this structureN)rT   r   rU   r�   rQ   rY   rZ   rŽ   r   r   r   r�   a  s    zStructure._setvalue)NNF)r2   r�   r‘   r’   r_   ro   rr   rx   r{   r�   r†   r‰   r‹   r�   r�   r“   r   r   r}   r   r›   þ   s   
	r›   Ú Fc              
   C   sˆ   t |tƒrt t|¡}t | ¡�^ |  ¡ �& | j|||d�}|  	|dƒ|¡ W 5 Q R X |rn|  	|j
 d¡|¡ |W  5 Q R £ S Q R X dS )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)rK   Úintr   r$   Úintp_tr   Zsuspend_emissionÚgoto_entry_blockÚallocarY   r   rW   )r   Útyr¨   r©   ra   rƒ   r   r   r   rb   j  s    	

rb   c                 C   s$   |dƒ}|  tdƒg¡}|  |t¡S )zCompute sizeof using GEP
    Nr	   )r¥   r¡   Úptrtointr«   )r   Zptr_typeÚnullÚoffsetr   r   r   Úsizeofƒ  s    r²   c                 C   s    t | |j|d�}|  ||¡ |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.
    r`   )rb   r   rY   )r   r   r©   ra   Ústorager   r   r   Úalloca_once_value‹  s    r´   c                 C   s(   t | ||ƒ}|j d¡ |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©   Úfnr   r   r   Úinsert_pure_function–  s    r¾   c                 C   s(   | j  |d¡}|dkr$t | ||¡}|S )zm
    Get the function named *name* with type *fnty* from *module*, or insert it
    if it doesn't exist.
    N)Úglobalsr/   r   ÚFunctionrº   r   r   r   r·   ¡  s    r·   c                 C   s0   z|   |¡W S  tk
r*   |  |¡ Y S X d S rc   )Úget_named_metadataÚKeyErrorÚadd_named_metadata)r»   r©   r   r   r   Úget_or_insert_named_metadata¬  s    rÄ   c                 C   s   |   |¡}t | |||¡S rc   )Úget_unique_namer   ÚGlobalVariable)r»   r®   r©   r…   Úunique_namer   r   r   Úadd_global_variable³  s    
rÈ   c                 C   s   | j }|jd kr|  |¡ d S rc   )Úbasic_blockÚ
terminatorÚbranch)r   ÚbbendÚbbr   r   r   Ú	terminate¸  s    
rÎ   c                 C   s   | d ƒS rc   r   )Zltyper   r   r   Úget_null_value¾  s    rÏ   c                 C   s   t |jƒ}|  d||¡S )Nú==©rÏ   r   r   ©r   ri   r°   r   r   r   Úis_nullÂ  s    
rÓ   c                 C   s   t |jƒ}|  d||¡S )Nr   rÑ   rÒ   r   r   r   Úis_not_nullÇ  s    
rÔ   c                 C   s   | j |dd�S )NF©Úlikely©Úif_then©r   Úpredr   r   r   Úif_unlikelyÌ  s    rÛ   c                 C   s   | j |dd�S )NTrÕ   r×   rÙ   r   r   r   Ú	if_likelyÐ  s    rÜ   c                 C   s   |   |  |¡¡S rc   )rØ   Únot_rÙ   r   r   r   ÚifnotÔ  s    rÞ   c                 C   s   |  d¡}| j||dgd�S )z#
    Increment an index *val*.
    r	   Znsw)Úflags)r   r¹   )r   ri   Úoner   r   r   Úincrement_indexØ  s    
rá   ÚLoop)rh   Údo_breakc              	   #   s   |dkr|j }|dkr|dƒ}|}ˆ d¡}ˆ d¡}ˆ d¡‰ ‡ ‡fdd„}ˆj}ˆ |¡ ˆ |¡�0 ˆj|dd	�}	ˆ d
|	|¡}
ˆ |
|ˆ ¡ W 5 Q R X ˆ |¡�, t|	|ƒV  ˆj}t	ˆ|	ƒ}t
ˆ|ƒ W 5 Q R X |	 ||¡ |	 ||¡ ˆ ˆ ¡ dS )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                      s   ˆ  ˆ ¡ d S rc   )rË   r   ©rÌ   r   r   r   rã   ú  s    zfor_range.<locals>.do_breakú
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ã   Úbbstartrh   rÚ   Úincrr   rç   r   Ú	for_rangeæ  s.    





rú   Tc              	   c   s*  |dkr|j }|  d¡}|  d¡}|  d¡}| j}	|  |¡ |  |¡�R | j|dd�}
| j|dd�}|rx|  d|
|¡}n|  d	|
|¡}|  |||¡ W 5 Q R X |  |¡�6 |
|fV  | j}|  |
|¡}t	| |ƒ}t
| |ƒ W 5 Q R X |
 ||	¡ |
 ||¡ | t |d
¡|	¡ | ||¡ |  |¡ dS )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æ   rè   ré   z
loop.countrê   ú>r   )r   rë   rÉ   rË   rì   rí   rî   rï   r¹   rá   rÎ   rð   r   r$   rñ   )r   ró   rõ   Ústeprô   Úincrö   r÷   rÌ   rø   rh   rò   rÚ   rù   Z
next_countr   r   r   Úfor_range_slice  s2    





rþ   c              	   c   sˆ   |j }|  d|t |d¡¡}t| ||||dd�}t| ||||dd�}tdd„ ƒ}| j|dd�� \}	}
||	|ƒ||
|ƒfV  W 5 Q R X d	S )
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)rý   Fc              
   s   s*   | � |�}|V  W 5 Q R X W 5 Q R X d S rc   r   )ÚcondZinner_cmr   r   r   r   Úcm_cond`  s    z(for_range_slice_generic.<locals>.cm_condrÕ   N)r   rî   r   r$   rþ   r   Úif_else)r   ró   rõ   rü   rô   Zis_pos_stepZpos_for_rangeZneg_for_ranger  ÚthenÚ	otherwiser   r   r   Úfor_range_slice_genericL  s    
r  ÚCc              	   c   sp   |dkst ‚|sdV  nT|dkr*dd„ }ndd„ }t| ||ƒ|ƒ�$}t|ƒt|ƒksXt ‚||ƒV  W 5 Q R X dS )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                 S   s   | d d d… S )Néÿÿÿÿr   ©Úxr   r   r   Ú<lambda>~  ó    zloop_nest.<locals>.<lambda>c                 S   s   | S rc   r   r
  r   r   r   r  €  r  N)rU   Ú
_loop_nestr#   )r   Úshaperô   ÚorderÚ_swapÚindicesr   r   r   Ú	loop_nestj  s    
r  c              
   c   sh   t | |d |d��L}t|ƒdkrPt| |dd … |ƒ�}|jf| V  W 5 Q R X n
|jfV  W 5 Q R X d S )Nr   ©rô   r	   )rú   r#   r  rh   )r   r  rô   Úloopr  r   r   r   r  †  s
    r  c                 C   sP   t |ƒ}|dkr|d j}t ||¡tjƒ}t|ƒD ]\}}|  |||¡}q4|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.
    Nr   )r#   r   r   r%   r   r   r   )r   r   r®   r)   Úaryr    r   r   r   r   Ú
pack_array�  s    
r  c                 C   sB   t  dd„ |D ƒ¡}|t jƒ}t|ƒD ]\}}|  |||¡}q&|S )z7
    Pack a sequence of values into a LLVM struct.
    c                 S   s   g | ]
}|j ‘qS r   r   r   r   r   r   r   £  s     zpack_struct.<locals>.<listcomp>r   )r   r   ZstructtyÚstr    r   r   r   r   Úpack_structŸ  s
    
r  c                    s0   |dkrt ˆjjƒ}‡ ‡fdd„t|ƒD ƒ}|S )zH
    Unpack an array or structure of values, return a Python tuple.
    Nc                    s   g | ]}ˆ   ˆ|¡‘qS r   )Úextract_value)r   r    ©r   Útupr   r   r   ±  s   ÿz unpack_tuple.<locals>.<listcomp>)r#   r   ÚelementsÚrange)r   r  rò   Úvalsr   r  r   Úunpack_tupleª  s    ÿr   c           	      C   sB   t ||j|jd�}t ||j|jd�}t| ||j|||j|||d�	S )N)rò   )r+   r  ÚstridesÚlayoutÚindsÚ
wraparoundÚboundscheck)r   r  Úndimr!  Úget_item_pointer2r+   r"  )	r]   r   Zarytyr  r#  r$  r%  Úshapesr!  r   r   r   Úget_item_pointer¶  s       þr)  c           	   	      s¤   ‡ ‡‡‡fdd„}d}ˆ  dˆˆ¡}tˆ|ƒ�$ tjr<|ƒ  | j ˆt|f¡ W 5 Q R X ˆ  dˆˆ d¡¡}tˆ|ƒ�$ tjr„|ƒ  | j ˆt|f¡ W 5 Q R X d S )Nc                      sL   ˆ d k	r:t ˆ tƒr(tˆd ˆ ¡ˆˆƒ qHtˆdˆˆ ˆƒ ntˆdˆˆƒ d S )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
)rK   rª   ÚprintfrP   r   ©Úaxisr   ÚdimlenÚindr   r   Ú_dbgÃ  s$    
ÿ ÿ þ þzdo_boundscheck.<locals>._dbgzindex is out of boundsrÿ   rê   r   )rî   rÛ   r   ÚFULL_TRACEBACKSÚ	call_convÚreturn_user_excÚ
IndexErrorr   )	r]   r   r.  r-  r,  r/  ÚmsgZout_of_bounds_upperZout_of_bounds_lowerr   r+  r   Údo_boundscheckÂ  s    r5  c	                    sâ  |rVg }	t ||ƒD ]@\}
}ˆ  d|
|
 d¡¡}ˆ  ||
¡}ˆ  |||
¡}|	 |¡ qn|}	|rŠtt |	|ƒƒD ]\}\}
}t| ˆ |
||ƒ ql|	s ˆ  |t	dƒg¡S |	d j}|dk�r¬g }|dk�r
t
t|ƒƒD ]8}|dƒ}||d d … D ]}ˆ  ||¡}qê| |¡ qÎnZ|dk�r\t
t|ƒƒD ]8}|dƒ}|d |… D ]}ˆ  ||¡}�q8| |¡ �q ntdƒ‚|dƒ}t |	|ƒD ]"\}}ˆ  ||¡}ˆ  ||¡}�qvˆ  ||g¡}|S ‡ fdd	„t ||	ƒD ƒ}t ˆ j|¡}tˆ ||ƒS d S )
Nrê   r   r  r  r	   r  Úunreachablec                    s   g | ]\}}ˆ   ||¡‘qS r   )Úmul)r   Úsr    ©r   r   r   r     s     z%get_item_pointer2.<locals>.<listcomp>)Úziprî   r   r¹   Úselectr¢   r   r5  r¥   r¡   r  r#   r7  Ú	ExceptionÚ	functoolsÚreduceÚpointer_add)r]   r   r+   r  r!  r"  r#  r$  r%  r  r.  r-  ÚnegativeÚwrappedÚselectedr,  rô   Ústepsr    ÚlastÚjÚlocr8  Útmprƒ   Zdimoffsr±   r   r9  r   r'  à  sL    



r'  c                 C   s\   |  d¡}t|j tjtjfƒr*|||ƒ}n.t|j tjƒrH|  |||¡}ntd|j f ƒ‚|S )Nr   zunexpected value type %s)r   rK   r   Ú	FloatTypeÚ
DoubleTyper&   rî   rO   )r   r   ZfpredZicondZnullvalÚisnullr   r   r   Ú_scalar_pred_against_zero  s    
rK  c                 C   s   t | |t | jd¡dƒS )zK
    Return a predicate representing whether *value* is equal to zero.
    rÐ   ©rK  r=  ÚpartialÚfcmp_orderedr   r   r   r   Úis_scalar_zero%  s       ÿrO  c                 C   s   t | |t | 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   ©rK  r=  rM  Úfcmp_unorderedr   r   r   r   Úis_not_scalar_zero-  s       ÿrR  c                 C   s   t | |t | jd¡dƒS )z]
    Return a predicate representing whether *value* is equal to either zero
    or NaN.
    rÐ   rP  r   r   r   r   Úis_scalar_zero_or_nan6  s       ÿrS  c                 C   s   t | |t | jd¡dƒS )z:
    Is *value* negative?  Assumes *value* is signed.
    rê   rL  r   r   r   r   Úis_scalar_negC  s       ÿrT  )Ústackc              	   c   s<   |  | j|dd�¡\}}|� dV  W 5 Q R X |  |¡ dS )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_contextr  )r   rU  r   r  r  r   r   r   Úearly_exit_ifK  s    rW  c                 C   s   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``.
    )rW  rÓ   )r   rU  Úobjr   r   r   Úearly_exit_if_nullg  s    rY  c              	   C   sL   |j t||ƒdd��. |d }|dd… p,d}| j |||¡ W 5 Q R X dS )zu
    Guard against *value* being null or zero.
    *exc_tuple* should be a (exception type, arguments...) tuple.
    FrÕ   r   r	   N)rØ   rO  r1  r2  )r]   r   r   Z	exc_tupleÚexcÚexc_argsr   r   r   Ú
guard_nullo  s    r\  c              	   C   sZ   t |jtjƒst|jƒ‚|r"|fnd}|jt||ƒdd�� | j |t	|¡ W 5 Q R X dS )zG
    Guard against *pointer* being NULL (and raise a MemoryError).
    r   FrÕ   N)
rK   r   r   ÚPointerTyperU   rØ   rÓ   r1  r2  ÚMemoryError)r]   r   Úpointerr4  r[  r   r   r   Úguard_memory_errorz  s    r`  c              	   c   s*   | j t| |ƒ|d�� dV  W 5 Q R X dS )z>
    Execute the given block if the scalar value is zero.
    rÕ   N)rØ   rO  )r   r   rÖ   r   r   r   Úif_zero„  s    ra  c                 C   s   t | tjƒS )z7
    Whether the LLVM type *typ* is a struct type.
    )rK   r   r]  )Zltypr   r   r   rT   �  s    rT   c                 C   s.   t | |d|ƒ}t|jjƒrt‚|  || ¡ ¡S rl   )rm   rT   r   rW   rU   rž   rX   )r   Úrecordr±   ÚtypÚpvalr   r   r   Úget_record_member—  s    re  c                 C   s   |   d|| d¡¡S )Nrê   r   )rî   r   )r   ri   r   r   r   Ú
is_neg_int�  s    rf  c                 O   s   t | |f|žddi|—ŽS )z8
    Same as *gep*, but add the `inbounds` keyword.
    r¤   T)r¥   )r   rƒ   r#  Úkwsr   r   r   rm   ¡  s    rm   c           	      O   sb   |  dd¡}|  dd¡}|r t‚g }|D ]&}t|tƒr@t|ƒ}n|}| |¡ q(| j||||d�S )z‰
    Emit a getelementptr instruction for the given pointer and indices.
    The indices can be LLVM values or Python int constants.
    r©   r§   r¤   F)r©   r¤   )r?   rU   rK   rª   r¡   r¢   r¥   )	r   rƒ   r#  rg  r©   r¤   Úidxr    r.  r   r   r   r¥   ¨  s    

r¥   c                 C   s<   |   |t¡}t|tƒrt|ƒ}|  ||¡}|  ||p8|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«   rK   rª   r¹   Úinttoptrr   )r   rƒ   r±   Úreturn_typeZintptrr   r   r   r?  »  s
    
r?  c                 C   sN   | j  dt|jf¡}|  |t¡}t|tƒr2t|ƒ}|  ||||t	dƒg¡ dS )z=
    Fill *size* bytes starting from *ptr* with *value*.
    zllvm.memsetr   N)
r»   Údeclare_intrinsicÚ	voidptr_tr   rž   rK   rª   Úint8_tÚcallÚbool_t)r   rƒ   r¨   r   r½   r   r   r   ÚmemsetÊ  s
    
rp  c                 C   s0   |   |¡}t| |t| |jƒdƒ |  ||¡ dS )z7
    Fill padding bytes of the pointee with zeros.
    r   N)r€   rp  r²   r   rY   )r   rƒ   ri   r   r   r   Úmemset_paddingÕ  s    
rq  Úinternalc                 C   s<   t | tjƒr| }n| j}t||j|ƒ}||_d|_||_|S )zO
    Get or create a (LLVM module-)global constant with *name* or *value*.
    T)	rK   r   ÚModuler»   rÈ   r   ÚlinkageÚglobal_constantÚinitializer)Zbuilder_or_moduler©   r   rt  r»   r+   r   r   r   ru  á  s    ru  c           
   
   C   sÖ   |dkst ‚| |¡}| d¡}t| |jƒ}|  t| |ƒ¡�n\}}|� |  ||¡}|  ||¡ W 5 Q R X |�2 |  ||¡}|  ||¡}|  |  ||¡|¡ W 5 Q R X W 5 Q R X |  	|¡}|  ||  
||¡¡}	||	fS )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	   )rU   r   rb   r  rf  ÚsdivrY   r¹   Úsubr€   r7  )
r   ri   Zdivisorrà   ÚquotZif_negZif_posZquot_valZval_plus_oneZrem_valr   r   r   Údivmod_by_constantð  s    

(
rz  c                 C   s&   |   d¡}|  |||¡ |  |¡ |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)rë   rï   rñ   )r   r   ZbbtrueZbbcontr   r   r   Úcbranch_or_continue  s    

r{  c              	   C   sb   |j |j kst‚t| ||j d��8}|  ||jg¡}|  ||jg¡}|  |  |¡|¡ W 5 Q R X dS )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
    r  N)r   rU   rú   r¥   rh   rY   r€   )r   rC   rD   rò   r  Zout_ptrZin_ptrr   r   r   Úmemcpy  s
    r|  c           
   	   C   sd   |j }t|tƒrt ||¡}| j |tt|g¡}t}	|  	||  
|t¡|  
|t¡|  ||¡|	g¡ d S rc   )r   rK   rª   r   r$   r»   rk  rl  Ú	false_bitrn  rž   r7  )
r   Ú	func_namerC   rD   rò   ÚitemsizeÚalignÚsize_tr|  Zis_volatiler   r   r   Ú_raw_memcpy1  s    
ÿ

ýr‚  c                 C   s   t | d|||||ƒS )za
    Emit a raw memcpy() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memcpy©r‚  ©r   rC   rD   rò   r  r€  r   r   r   Ú
raw_memcpy?  s    r…  c                 C   s   t | d|||||ƒS )zb
    Emit a raw memmove() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memmoverƒ  r„  r   r   r   Úraw_memmoveG  s     ÿr†  c           
      C   sX   |   ||¡}|  |d¡}|  |d¡}|  ||¡}|  |d¡}|  ||  |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_overflowr  Úsadd_with_overflowÚor_)
r   Úar(   ÚcÚpÚprodZprod_ovfr8  r7   Zovfr   r   r   Úmuladd_with_overflowP  s    rŽ  c           
      G   sž   t |tƒst‚| j}t}t|d  d¡ƒ}t|d|ƒ}tj	t
|gdd�}z| d¡}W n$ tk
rz   tj||dd�}Y nX |  ||¡}	|  ||	gt|ƒ ¡S )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.
    ú ÚasciiZprintf_formatT©Úvar_argr*  ré   )rK   r3   rU   r»   rl  r*   Úencoderu  r   ÚFunctionTyper¡   Ú
get_globalrÂ   rÀ   rž   rn  Úlist)
r   rP   ÚargsÚmodÚcstringÚ	fmt_bytesÚ
global_fmtr¼   r½   Úptr_fmtr   r   r   r*  ^  s    	r*  c                 G   s¸   t |tƒst‚| j}t}t|d  d¡ƒ}t|d|ƒ}tj	t
|t|gdd�}	d}
tjr^d|
 }
z| |
¡}W n$ tk
r�   tj||	|
d�}Y nX |  ||¡}|  ||||gt|ƒ ¡S )	z8Calls libc snprintf(buffer, bufsz, format, ...args)
    r�  r�  Zsnprintf_formatTr‘  Úsnprintfr,   ré   )rK   r3   rU   r»   rl  r*   r“  ru  r   r”  r¡   r«   r   ÚIS_WIN32r•  rÂ   rÀ   rž   rn  r–  )r   ÚbufferÚbufszrP   r—  r˜  r™  rš  r›  r¼   Úsymbolr½   rœ  r   r   r   r�  x  s&      ÿr�  c                 G   sV   t |tƒst‚t t d¡|¡}t| |dd�}|  |t¡}t	| |t
|ƒ|f|žŽ  |S )z{Similar to `snprintf()` but the buffer is stack allocated to size
    *bufsz*.

    Returns the buffer pointer as i8*.
    r
   Tr`   )rK   rª   rU   r   r%   r&   rb   rž   rl  r�  r«   )r   r   rP   r—  ZspacetyÚspacerŸ  r   r   r   Úsnprintf_stackbuffer’  s    r£  c                 C   s   |   d¡ d¡S )zk
    Normalize the given string to latin1 compatible encoding that is
    suitable for use in LLVM IR.
    Úutf8Úlatin1)r“  Údecode)Útextr   r   r   Únormalize_ir_text   s    r¨  c           
   
   C   sÆ   d}|   |t¡}t| d||ƒ t d¡}|  || ¡ ¡}t| |ƒ�p}|  |j	t|ƒ¡}|  
d|tdƒ¡}|  |¡� t| dƒ W 5 Q R X |  ||j	g¡}|  |¡}	t| d|	ƒ W 5 Q R X t| dƒ dS )	zIDebug print the memory region in *ptr* to *ptr + nbytes*
    as hex.
    é   zhexdump p=%p n=%zur
   rÐ   r   Ú
z %02xN)Úzextr«   r*  r   r&   rž   rX   rú   Úuremrh   r   rØ   r¥   r€   )
r   rƒ   ÚnbytesZbytes_per_lineZbyte_trh  Zdiv_byZdo_new_liner±   ri   r   r   r   Úhexdump©  s"     ÿ

r®  c                 C   s    | dkpt | tjƒpt | tjƒS )z returns if 'ty' is none N)rK   r   ÚNoneTypeÚOmitted)r®   r   r   r   Úis_nonelikeÀ  s
    
ÿ
ýr±  c                 C   s   t  t  | 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®   ri   r   r   r   Úcreate_constant_arrayÉ  s    r²  )N)r   )Nr§   F)r§   F)r   )NN)NT)r  )N)N)FF)N)FF)N)F)N)rr  )r	   )r	   )fr’   ÚcollectionsÚ
contextlibr   r   r=  Úllvmliter   Ú
numba.corer   r   r   r   Znumba.core.datamodelrL   r&   ro  rm  r¡   ÚMACHINE_BITSr«   rX   rl  Ztrue_bitr}  Z	true_byteZ
false_byter   r!   r*   r.   r;   rG   ÚobjectrH   r0   r1   r›   rb   r²   r´   r¾   r·   rÄ   rÈ   rÎ   rÏ   rÓ   rÔ   rÛ   rÜ   rÞ   rá   Ú
namedtuplerâ   rú   rþ   r  r  r  r  r  r   r)  r5  r'  rK  rO  rR  rS  Úis_trueZis_falserT  rW  rY  r\  r`  ra  Z
guard_zerorT   re  rf  rm   r¥   r?  rp  rq  ru  rz  r{  r|  r‚  r…  r†  rŽ  r*  r�  r£  r¨  r®  r±  r²  r   r   r   r   Ú<module>   sÈ   



	
 l


+9

	

  ÿ

   ÿ
:		





			