U
    hâËdi˜  ã                   @   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   úK/home/sam/Atlas/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   Z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    rF   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)Ú_contextZ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_oncerO   rQ   )rZ   r\   r   r   r   rT   |   s    z_StructProxy._make_refsc                 C   s   t ‚d S ©N©ÚNotImplementedError©rZ   rL   r   r   r   rP   …   s    z_StructProxy._get_be_typec                 C   s   t ‚d S ra   rb   ©rZ   ÚindexÚvalr   r   r   Ú_cast_member_to_valueˆ   s    z"_StructProxy._cast_member_to_valuec                 C   s   t ‚d S ra   rb   re   r   r   r   Ú_cast_member_from_value‹   s    z$_StructProxy._cast_member_from_valuec                 C   s   t | j| jd|ƒS ©Nr   )Úgep_inboundsrO   rX   ©rZ   rf   r   r   r   Ú_get_ptr_by_indexŽ   s    z_StructProxy._get_ptr_by_indexc                 C   s   | j  |¡}|  |¡S ra   )r<   Úget_field_positionrm   )rZ   Úattrnamerf   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<   rn   ÚAttributeError©rZ   Ú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)rr   ÚsuperrG   Ú__setattr__r<   rn   ©rZ   ru   r   ©Ú	__class__r   r   ry   ž   s    
z_StructProxy.__setattr__c                 C   s   | j  |  |¡¡}|  ||¡S ©z>
        Load the LLVM value of the field at *index*.
        )rO   Úloadrm   rh   )rZ   rf   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   ÚptrrZ   rf   N)rm   ri   r   rU   rR   rH   ZaddrspacecastrO   Ú	addrspacerM   rN   rW   )rZ   rf   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©rZ   r   r   r   Ú__len__Ä   s    z_StructProxy.__len__c                 C   s   | j S ©zF
        Return the LLVM pointer to the underlying structure.
        )rY   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.
        )rO   r~   rY   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)rR   r   rS   rQ   rO   rW   rX   ©rZ   r   r   r   r   Ú	_setvalueÖ   s    z_StructProxy._setvalue)NN)r1   Ú
__module__Ú__qualname__Ú__doc__r,   r]   rT   rP   rh   ri   rm   rp   rv   ry   r   rƒ   r†   rˆ   rŠ   rŒ   Ú__classcell__r   r   r{   r   rG   Z   s"   
		rG   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r/   zl
    Create a StructProxy suitable for accessing regular values
    (e.g. LLVM values or alloca slots).
    c                 C   s   |  ¡ S ra   )Zget_value_typerd   r   r   r   rP   ä   s    zValueStructProxy._get_be_typec                 C   s   |S ra   r   re   r   r   r   rh   ç   s    z&ValueStructProxy._cast_member_to_valuec                 C   s   |S ra   r   re   r   r   r   ri   ê   s    z(ValueStructProxy._cast_member_from_valueN©r1   r�   rŽ   r�   rP   rh   ri   r   r   r   r   r/   ß   s   r/   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r0   zO
    Create a StructProxy suitable for accessing data persisted in memory.
    c                 C   s   |  ¡ S ra   )Zget_data_typerd   r   r   r   rP   ò   s    zDataStructProxy._get_be_typec                 C   s   | j  |¡}| | j|¡S ra   )r<   Ú	get_modelÚ	from_datarO   ©rZ   rf   rg   Úmodelr   r   r   rh   õ   s    z%DataStructProxy._cast_member_to_valuec                 C   s   | j  |¡}| | j|¡S ra   )r<   r’   Zas_datarO   r”   r   r   r   ri   ù   s    z'DataStructProxy._cast_member_from_valueNr‘   r   r   r   r   r0   î   s   r0   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   )Zget_struct_typeÚ_typerH   rO   r`   rX   rR   r   rS   rW   rU   ÚbitcastrV   rM   Ú_namemapÚ_fdmapZ_typemapÚint32_tr   r=   Úappend)
rZ   r[   r   r   r\   Zcast_refr7   r   rE   Útpr   r   r   r]     s8    ÿÿ
zStructure.__init__c                 C   s   | j j| j| j| dd�}|S )NT)Úinbounds)rO   ÚgeprX   rš   )rZ   rf   r�   r   r   r   rm   $  s    zStructure._get_ptr_by_indexc                 C   s   |   | j| ¡S ra   )rm   r™   )rZ   ro   r   r   r   rp   (  s    zStructure._get_ptr_by_namec                 C   s$   |  d¡s| | j|  S t|ƒ‚dS rq   )rr   r™   rs   rt   r   r   r   rv   +  s    
zStructure.__getattr__c                    s.   |  d¡rtt| ƒ ||¡S || | j| < dS rw   )rr   rx   r–   ry   r™   rz   r{   r   r   ry   4  s    
zStructure.__setattr__c                 C   s   | j  |  |¡¡S r}   )rO   r~   rm   rl   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)rm   r   rU   rS   r2   rO   rW   )rZ   rf   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‡   )rX   r…   r   r   r   rˆ   U  s    zStructure._getpointerc                 C   s   | j  | j¡S r‰   )rO   r~   rX   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)rR   r   rS   r—   rO   rW   rX   r‹   r   r   r   rŒ   a  s    zStructure._setvalue)NNF)r1   r�   rŽ   r�   r]   rm   rp   rv   ry   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)rI   Úintr   r#   Úintp_tr   Zsuspend_emissionZgoto_entry_blockZallocarW   r   rU   )r   Útyr¢   r£   r_   r�   r   r   r   r`   j  s    	

r`   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^   )r`   r   rW   )r   r   r£   r_   Z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.
    ÚreadonlyZ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 ra   )Zget_named_metadataÚKeyErrorZadd_named_metadata)r±   r£   r   r   r   Úget_or_insert_named_metadata¬  s    r¸   c                 C   s   |   |¡}t | |||¡S ra   )Zget_unique_namer   ZGlobalVariable)r±   r¦   r£   r‚   Zunique_namer   r   r   Úadd_global_variable³  s    
r¹   c                 C   s   | j }|jd kr|  |¡ d S ra   )Úbasic_blockÚ
terminatorÚbranch)r   ÚbbendZbbr   r   r   Ú	terminate¸  s    
r¾   c                 C   s   | d ƒS ra   r   )Zltyper   r   r   Úget_null_value¾  s    r¿   c                 C   s   t |jƒ}|  d||¡S )Nú==©r¿   r   r   ©r   rg   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 ra   )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   rg   Úoner   r   r   Úincrement_indexØ  s    
rÑ   ÚLoop)rf   Ú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 ra   )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Ó   Úbbstartrf   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è   rf   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 ra   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 ra   r   rú   r   r   r   rü   €  rý   N)rS   Ú
_loop_nestr"   )r   Úshaperä   ÚorderZ_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þ   rf   )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  Z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
)rI   r¤   ÚprintfrN   r   ©Úaxisr   ÚdimlenÚindr   r   Ú_dbgÃ  s$    
ÿ ÿ þ þzdo_boundscheck.<locals>._dbgzindex is out of boundsrï   rÚ   r   )rÞ   rË   r   Z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    r"  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ø   Z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   r"  rŸ   r›   r  r"   r#  Ú	ExceptionÚ	functoolsÚreduceÚpointer_add)r[   r   r*   rÿ   r  r  r  r  r  r  r  r  ÚnegativeÚwrappedÚselectedr  rä   Zstepsr   ÚlastÚjÚlocr$  Útmpr�   Zdimoffsr©   r   r%  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   rI   r   Z	FloatTypeZ
DoubleTyper%   rÞ   rM   )r   r   ZfpredZicondZnullvalZisnullr   r   r   Ú_scalar_pred_against_zero  s    
r3  c                 C   s   t | |t | jd¡dƒS )zK
    Return a predicate representing whether *value* is equal to zero.
    rÀ   ©r3  r)  ÚpartialZfcmp_orderedr   r   r   r   Úis_scalar_zero%  s       ÿr6  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   ©r3  r)  r5  Zfcmp_unorderedr   r   r   r   Úis_not_scalar_zero-  s       ÿr8  c                 C   s   t | |t | jd¡dƒS )z]
    Return a predicate representing whether *value* is equal to either zero
    or NaN.
    rÀ   r7  r   r   r   r   Úis_scalar_zero_or_nan6  s       ÿr9  c                 C   s   t | |t | jd¡dƒS )z:
    Is *value* negative?  Assumes *value* is signed.
    rÚ   r4  r   r   r   r   Úis_scalar_negC  s       ÿr:  )Ú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   r;  rð   ró   rô   r   r   r   Úearly_exit_ifK  s    r=  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``.
    )r=  rÃ   )r   r;  Úobjr   r   r   Úearly_exit_if_nullg  s    r?  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È   r6  r  r  )r[   r   r   Ú	exc_tupleÚexcÚexc_argsr   r   r   Ú
guard_nullo  s    rC  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)
rI   r   r   ÚPointerTyperS   rÈ   rÃ   r  r  ÚMemoryError)r[   r   Zpointerr!  rB  r   r   r   Úguard_memory_errorz  s    rF  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È   r6  )r   r   rÆ   r   r   r   Úif_zero„  s    rG  c                 C   s   t | tjƒS )z7
    Whether the LLVM type *typ* is a struct type.
    )rI   r   rD  )Zltypr   r   r   rR   �  s    rR   c                 C   s.   t | |d|ƒ}t|jjƒrt‚|  || ¡ ¡S rj   )rk   rR   r   rU   rS   r˜   rV   )r   Úrecordr©   ÚtypZpvalr   r   r   Úget_record_member—  s    rJ  c                 C   s   |   d|| d¡¡S )NrÚ   r   )rÞ   r   )r   rg   r   r   r   Ú
is_neg_int�  s    rK  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   rk   ¡  s    rk   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>   rS   rI   r¤   r›   rœ   rŸ   )	r   r�   r  rL  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¥   rI   r¤   r¯   Z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˜   rI   r¤   Úint8_tÚcallÚbool_t)r   r�   r¢   r   r³   r   r   r   ÚmemsetÊ  s
    
rT  c                 C   s0   |   |¡}t| |t| |jƒdƒ |  ||¡ dS )z7
    Fill padding bytes of the pointee with zeros.
    r   N)r~   rT  rª   r   rW   )r   r�   rg   r   r   r   Úmemset_paddingÕ  s    
rU  Ú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)	rI   r   ÚModuler±   r¹   r   ÚlinkageÚglobal_constantZinitializer)Zbuilder_or_moduler£   r   rX  r±   r*   r   r   r   rY  á  s    rY  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	   )rS   r   r`   rò   rK  ZsdivrW   r¯   Úsubr~   r#  )
r   rg   ZdivisorrÐ   ÚquotZif_negZif_posZquot_valZval_plus_oneZrem_valr   r   r   Údivmod_by_constantð  s    

(
r\  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   rS   rê   rŸ   rf   rW   r~   )r   rB   rC   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 ra   )r   rI   r¤   r   r#   r±   rO  rP  Ú	false_bitrR  r˜   r#  )
r   Ú	func_namerB   rC   râ   ÚitemsizeÚalignZsize_tr^  Zis_volatiler   r   r   Ú_raw_memcpy1  s    
ÿ

ýrc  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©rc  ©r   rB   rC   râ   ra  rb  r   r   r   Ú
raw_memcpy?  s    rf  c                 C   s   t | d|||||ƒS )zb
    Emit a raw memmove() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memmoverd  re  r   r   r   Úraw_memmoveG  s     ÿrg  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	   )Zsmul_with_overflowr	  Zsadd_with_overflowÚor_)
r   Úar'   ÚcÚpÚprodZprod_ovfr$  r6   Zovfr   r   r   Úmuladd_with_overflowP  s    rm  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©Zvar_argr  rÙ   )rI   r2   rS   r±   rP  r)   ÚencoderY  r   ÚFunctionTyper›   Ú
get_globalr·   r¶   r˜   rR  Úlist)
r   rN   Ú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)
    rn  ro  Zsnprintf_formatTrp  Úsnprintfr+   rÙ   )rI   r2   rS   r±   rP  r)   rq  rY  r   rr  r›   r¥   r   ZIS_WIN32rs  r·   r¶   r˜   rR  rt  )r   ÚbufferÚbufszrN   ru  rv  rw  rx  ry  r²   Úsymbolr³   rz  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^   )rI   r¤   rS   r   r$   r%   r`   r˜   rP  r{  r¥   )r   r}  rN   ru  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)rq  Ú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)Zzextr¥   r  r   r%   r˜   rV   rê   Zuremrf   r   rÈ   rŸ   r~   )
r   r�   ÚnbytesZbytes_per_lineZbyte_trM  Zdiv_byZdo_new_liner©   rg   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)rI   r   ZNoneTypeZ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¦   rg   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)rV  )r	   )r	   )fr�   ÚcollectionsÚ
contextlibr   r   r)  Zllvmliter   Z
numba.corer   r   r   r   Znumba.core.datamodelrJ   r%   rS  rQ  r›   ZMACHINE_BITSr¥   rV   rP  Ztrue_bitr_  Z	true_byteZ
false_byter   r    r)   r-   r:   rF   ÚobjectrG   r/   r0   r–   r`   rª   r«   r´   r­   r¸   r¹   r¾   r¿   rÃ   rÄ   rË   rÌ   rÎ   rÑ   Ú
namedtuplerÒ   rê   rî   rõ   r  rþ   r  r  r  r  r"  r  r3  r6  r8  r9  Zis_trueZis_falser:  r=  r?  rC  rF  rG  Z
guard_zerorR   rJ  rK  rk   rŸ   r+  rT  rU  rY  r\  r]  r^  rc  rf  rg  rm  r  r{  r€  r…  r‰  rŠ  r‹  r   r   r   r   Ú<module>   sÈ   



	
 l


+9

	

  ÿ

   ÿ
:		

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