U
    b»{ji˜  ã                   @   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   úQ/var/www/html/bwave/python/venv/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ÚbaseZclsnameÚbasesZ
clsmembersr   r   r   Úcreate_struct_proxy8   s    
ÿþ
r9   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    rE   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_oncerN   rP   )rY   r[   r   r   r   rS   |   s    z_StructProxy._make_refsc                 C   s   t ‚d S ©N©ÚNotImplementedError©rY   rK   r   r   r   rO   …   s    z_StructProxy._get_be_typec                 C   s   t ‚d S r`   ra   ©rY   ÚindexÚvalr   r   r   Ú_cast_member_to_valueˆ   s    z"_StructProxy._cast_member_to_valuec                 C   s   t ‚d S r`   ra   rd   r   r   r   Ú_cast_member_from_value‹   s    z$_StructProxy._cast_member_from_valuec                 C   s   t | j| jd|ƒS ©Nr   )Úgep_inboundsrN   rW   ©rY   re   r   r   r   Ú_get_ptr_by_indexŽ   s    z_StructProxy._get_ptr_by_indexc                 C   s   | j  |¡}|  |¡S r`   )r;   Úget_field_positionrl   )rY   Úattrnamere   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;   rm   ÚAttributeError©rY   Ú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)rq   ÚsuperrF   Ú__setattr__r;   rm   ©rY   rt   r   ©Ú	__class__r   r   rx   ž   s    
z_StructProxy.__setattr__c                 C   s   | j  |  |¡¡}|  ||¡S ©z>
        Load the LLVM value of the field at *index*.
        )rN   Úloadrl   rg   )rY   re   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   ÚptrrY   re   N)rl   rh   r   rT   rQ   rG   ZaddrspacecastrN   Ú	addrspacerL   rM   rV   )rY   re   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©rY   r   r   r   Ú__len__Ä   s    z_StructProxy.__len__c                 C   s   | j S ©zF
        Return the LLVM pointer to the underlying structure.
        )rX   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.
        )rN   r}   rX   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)rQ   r   rR   rP   rN   rV   rW   ©rY   r   r   r   r   Ú	_setvalueÖ   s    z_StructProxy._setvalue)NN)r1   Ú
__module__Ú__qualname__Ú__doc__r,   r\   rS   rO   rg   rh   rl   ro   ru   rx   r~   r‚   r…   r‡   r‰   r‹   Ú__classcell__r   r   rz   r   rF   Z   s"   
		rF   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 r`   )Zget_value_typerc   r   r   r   rO   ä   s    zValueStructProxy._get_be_typec                 C   s   |S r`   r   rd   r   r   r   rg   ç   s    z&ValueStructProxy._cast_member_to_valuec                 C   s   |S r`   r   rd   r   r   r   rh   ê   s    z(ValueStructProxy._cast_member_from_valueN©r1   rŒ   r�   rŽ   rO   rg   rh   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 r`   )Zget_data_typerc   r   r   r   rO   ò   s    zDataStructProxy._get_be_typec                 C   s   | j  |¡}| | j|¡S r`   )r;   Ú	get_modelÚ	from_datarN   ©rY   re   rf   Úmodelr   r   r   rg   õ   s    z%DataStructProxy._cast_member_to_valuec                 C   s   | j  |¡}| | j|¡S r`   )r;   r‘   Zas_datarN   r“   r   r   r   rh   ù   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Ú_typerG   rN   r_   rW   rQ   r   rR   rV   rT   ÚbitcastrU   rL   Ú_namemapÚ_fdmapZ_typemapÚint32_tr   r<   Úappend)
rY   rZ   r   r   r[   Zcast_refr7   r   rD   Útpr   r   r   r\     s8    ÿÿ
zStructure.__init__c                 C   s   | j j| j| j| dd�}|S )NT)Úinbounds)rN   ÚgeprW   r™   )rY   re   r€   r   r   r   rl   $  s    zStructure._get_ptr_by_indexc                 C   s   |   | j| ¡S r`   )rl   r˜   )rY   rn   r   r   r   ro   (  s    zStructure._get_ptr_by_namec                 C   s$   |  d¡s| | j|  S t|ƒ‚dS rp   )rq   r˜   rr   rs   r   r   r   ru   +  s    
zStructure.__getattr__c                    s.   |  d¡rtt| ƒ ||¡S || | j| < dS rv   )rq   rw   r•   rx   r˜   ry   rz   r   r   rx   4  s    
zStructure.__setattr__c                 C   s   | j  |  |¡¡S r|   )rN   r}   rl   rk   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)rl   r   rT   rR   r2   rN   rV   )rY   re   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†   )rW   r„   r   r   r   r‡   U  s    zStructure._getpointerc                 C   s   | j  | j¡S rˆ   )rN   r}   rW   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)rQ   r   rR   r–   rN   rV   rW   rŠ   r   r   r   r‹   a  s    zStructure._setvalue)NNF)r1   rŒ   r�   rŽ   r\   rl   ro   ru   rx   r~   r‚   r…   r‡   r‰   r‹   r�   r   r   rz   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)rH   Úintr   r#   Úintp_tr   Zsuspend_emissionZgoto_entry_blockZallocarV   r   rT   )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   rV   )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 r`   )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 r`   )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 r`   )Úbasic_blockÚ
terminatorÚbranch)r   ÚbbendZbbr   r   r   Ú	terminate¸  s    
r½   c                 C   s   | d ƒS r`   r   )Zltyper   r   r   Úget_null_value¾  s    r¾   c                 C   s   t |jƒ}|  d||¡S )Nú==©r¾   r   r   ©r   rf   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 r`   )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   rf   Úoner   r   r   Úincrement_indexØ  s    
rÐ   ÚLoop)re   Ú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 r`   )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Ò   Úbbstartre   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ç   re   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 r`   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 r`   r   rù   r   r   r   rû   €  rü   N)rR   Ú
_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ý   re   )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  )	rZ   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
)rH   r£   ÚprintfrM   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   )	rZ   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)rZ   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   rH   r   Z	FloatTypeZ
DoubleTyper%   rÝ   rL   )r   r   ZfpredZicondZnullvalZisnullr   r   r   Ú_scalar_pred_against_zero  s    
r2  c                 C   s   t | |t | jd¡dƒS )zK
    Return a predicate representing whether *value* is equal to zero.
    r¿   ©r2  r(  ÚpartialZfcmp_orderedr   r   r   r   Úis_scalar_zero%  s       ÿr5  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   ©r2  r(  r4  Zfcmp_unorderedr   r   r   r   Úis_not_scalar_zero-  s       ÿr7  c                 C   s   t | |t | jd¡dƒS )z]
    Return a predicate representing whether *value* is equal to either zero
    or NaN.
    r¿   r6  r   r   r   r   Úis_scalar_zero_or_nan6  s       ÿr8  c                 C   s   t | |t | jd¡dƒS )z:
    Is *value* negative?  Assumes *value* is signed.
    rÙ   r3  r   r   r   r   Úis_scalar_negC  s       ÿr9  )Ú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Ç   r5  r  r  )rZ   r   r   Ú	exc_tupleÚexcÚexc_argsr   r   r   Ú
guard_nullo  s    rB  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)
rH   r   r   ÚPointerTyperR   rÇ   rÂ   r  r  ÚMemoryError)rZ   r   Zpointerr   rA  r   r   r   Úguard_memory_errorz  s    rE  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Ç   r5  )r   r   rÅ   r   r   r   Úif_zero„  s    rF  c                 C   s   t | tjƒS )z7
    Whether the LLVM type *typ* is a struct type.
    )rH   r   rC  )Zltypr   r   r   rQ   �  s    rQ   c                 C   s.   t | |d|ƒ}t|jjƒrt‚|  || ¡ ¡S ri   )rj   rQ   r   rT   rR   r—   rU   )r   Úrecordr¨   ÚtypZpvalr   r   r   Úget_record_member—  s    rI  c                 C   s   |   d|| d¡¡S )NrÙ   r   )rÝ   r   )r   rf   r   r   r   Ú
is_neg_int�  s    rJ  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   rj   ¡  s    rj   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=   rR   rH   r£   rš   r›   rž   )	r   r€   r  rK  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¤   rH   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—   rH   r£   Úint8_tÚcallÚbool_t)r   r€   r¡   r   r²   r   r   r   ÚmemsetÊ  s
    
rS  c                 C   s0   |   |¡}t| |t| |jƒdƒ |  ||¡ dS )z7
    Fill padding bytes of the pointee with zeros.
    r   N)r}   rS  r©   r   rV   )r   r€   rf   r   r   r   Úmemset_paddingÕ  s    
rT  Ú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)	rH   r   ÚModuler°   r¸   r   ÚlinkageÚglobal_constantZinitializer)Zbuilder_or_moduler¢   r   rW  r°   r*   r   r   r   rX  á  s    rX  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	   )rR   r   r_   rñ   rJ  ZsdivrV   r®   Úsubr}   r"  )
r   rf   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   rR   ré   rž   re   rV   r}   )r   rA   rB   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 r`   )r   rH   r£   r   r#   r°   rN  rO  Ú	false_bitrQ  r—   r"  )
r   Ú	func_namerA   rB   rá   ÚitemsizeÚalignZsize_tr]  Zis_volatiler   r   r   Ú_raw_memcpy1  s    
ÿ

ýrb  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©rb  ©r   rA   rB   rá   r`  ra  r   r   r   Ú
raw_memcpy?  s    re  c                 C   s   t | d|||||ƒS )zb
    Emit a raw memmove() call for `count` items of size `itemsize`
    from `src` to `dest`.
    zllvm.memmoverc  rd  r   r   r   Úraw_memmoveG  s     ÿrf  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    rl  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Ø   )rH   r2   rR   r°   rO  r)   ÚencoderX  r   ÚFunctionTyperš   Ú
get_globalr¶   rµ   r—   rQ  Úlist)
r   rM   Ú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)
    rm  rn  Zsnprintf_formatTro  Úsnprintfr+   rØ   )rH   r2   rR   r°   rO  r)   rp  rX  r   rq  rš   r¤   r   ZIS_WIN32rr  r¶   rµ   r—   rQ  rs  )r   ÚbufferÚbufszrM   rt  ru  rv  rw  rx  r±   Úsymbolr²   ry  r   r   r   rz  x  s&      ÿrz  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]   )rH   r£   rR   r   r$   r%   r_   r—   rO  rz  r¤   )r   r|  rM   rt  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)rp  Ú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—   rU   ré   Zuremre   r   rÇ   rž   r}   )
r   r€   ÚnbytesZbytes_per_lineZbyte_trL  Zdiv_byZdo_new_liner¨   rf   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)rH   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¥   rf   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)rU  )r	   )r	   )frŽ   ÚcollectionsÚ
contextlibr   r   r(  Zllvmliter   Z
numba.corer   r   r   r   Znumba.core.datamodelrI   r%   rR  rP  rš   ZMACHINE_BITSr¤   rU   rO  Ztrue_bitr^  Z	true_byteZ
false_byter   r    r)   r-   r9   rE   ÚobjectrF   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  r2  r5  r7  r8  Zis_trueZis_falser9  r<  r>  rB  rE  rF  Z
guard_zerorQ   rI  rJ  rj   rž   r*  rS  rT  rX  r[  r\  r]  rb  re  rf  rl  r  rz  r  r„  rˆ  r‰  rŠ  r   r   r   r   Ú<module>   sÈ   



	
 l


+9

	

  ÿ

   ÿ
:		

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