B
      ›\!s  ã            	   @   s„  d dl mZmZmZ d dlZd dlZd dlZd dlZd dlZd dl	m
  mZ d dlm
  mZ d dlmZ d dlmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ e ddd	d
ddddgƒZ!dd„ Z"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(G dd„ de$ƒZ)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(„ Z/d)d*„ Z0dS )+é    )Úprint_functionÚdivisionÚabsolute_importN)ÚconfigÚutilsÚcgutils)Úremove_redundant_nrt_refct)Úrtsys)Úrequire_global_compiler_lockÚx86Zi386Zi486Zi586Zi686Zi786Zi886Zi986c             C   s   |   d¡d }|tkS )Nú-r   )ÚsplitÚ_x86arch)ÚtripleÚarch© r   ú4lib/python3.7/site-packages/numba/targets/codegen.pyÚ_is_x86   s    r   c             C   s$   t |  dd¡ƒ t |ƒ t dƒ d S )NéP   r   zP================================================================================)ÚprintÚcenter)ÚheaderZbodyr   r   r   Údump   s    r   c               @   s*   e Zd ZdZdd„ Zd
dd„Zdd	„ ZdS )Ú_CFGa  
    Wraps the CFG graph for different display method.

    Instance of the class can be stringified (``__repr__`` is defined) to get
    the graph in DOT format.  The ``.display()`` method plots the graph in
    PDF.  If in IPython notebook, the returned image can be inlined.
    c             C   s
   || _ d S )N)Údot)Úselfr   r   r   r   Ú__init__*   s    z_CFG.__init__NFc             C   s   t j| j||dS )aC  
        Plot the CFG.  In IPython notebook, the return image object can be
        inlined.

        The *filename* option can be set to a specific path for the rendered
        output to write to.  If *view* option is True, the plot is opened by
        the system default application for the image format (PDF).
        )ÚfilenameÚview)ÚllZview_dot_graphr   )r   r   r   r   r   r   Údisplay-   s    	z_CFG.displayc             C   s   | j S )N)r   )r   r   r   r   Ú__repr__8   s    z_CFG.__repr__)NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r    r!   r   r   r   r   r   "   s   
r   c               @   s4  e Zd ZdZdZdZdZdd„ Zedd„ ƒZ	edd„ ƒZ
d	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Z d5d6„ Z!e"d7d8„ ƒZ#e"d9d:„ ƒZ$e"d;d<„ ƒZ%d=d>„ Z&d?d@„ Z'e"dAdB„ ƒZ(dCS )DÚCodeLibraryzÒ
    An interface for bundling LLVM code together and compiling it.
    It is tied to a *codegen* instance (e.g. JITCPUCodegen) that will
    determine how the LLVM code is transformed and linked together.
    Fc             C   sN   || _ || _tƒ | _t t| j  | j¡ƒ¡| _t	 
| j¡| j_d | _g | _d S )N)Ú_codegenÚ_nameÚsetÚ_linking_librariesr   Úparse_assemblyÚstrÚ_create_empty_moduleÚ_final_moduler   Únormalize_ir_textÚnameÚ_shared_moduleÚ_dynamic_globals)r   Úcodegenr0   r   r   r   r   G   s    zCodeLibrary.__init__c             C   s   |   ¡  t| jƒdkS )Nr   )Ú_ensure_finalizedÚlenr2   )r   r   r   r   Úhas_dynamic_globalsR   s    zCodeLibrary.has_dynamic_globalsc             C   s   | j S )z9
        The codegen object owning this library.
        )r'   )r   r   r   r   r3   W   s    zCodeLibrary.codegenc             C   s   d| j t| ƒf S )Nz<Library %r at 0x%x>)r(   Úid)r   r   r   r   r!   ^   s    zCodeLibrary.__repr__c             C   s   | j rtd| f ƒ‚d S )Nz+operation impossible on finalized object %r)Ú
_finalizedÚRuntimeError)r   r   r   r   Ú_raise_if_finalizeda   s    zCodeLibrary._raise_if_finalizedc             C   s   | j s|  ¡  d S )N)r8   Úfinalize)r   r   r   r   r4   f   s    zCodeLibrary._ensure_finalizedc          	   C   sP   | j j|_| j  |¡0}x(|jD ]}| ¡  | |¡ | ¡  q W W dQ R X dS )zP
        Internal: run function-level optimizations inside *ll_module*.
        N)r'   Ú_data_layoutÚdata_layoutÚ_function_pass_managerÚ	functionsÚ
initializeÚrunr;   )r   Ú	ll_moduleZfpmÚfuncr   r   r   Ú_optimize_functionsj   s    

zCodeLibrary._optimize_functionsc             C   s    | j j | j¡ t| jƒ| _dS )zA
        Internal: optimize this library's final module.
        N)r'   Ú_mpmrA   r.   r   )r   r   r   r   Ú_optimize_final_modulex   s    z"CodeLibrary._optimize_final_modulec             C   s¤   |   ¡  | jdk	r| jS | j}g }d}x6|jD ],}|d7 }|js.|jtjjkr.| 	|j
¡ q.W |dkrttd| f ƒ‚|rš| ¡ }x|D ]}d| |¡_q†W || _|S )a:  
        Internal: get a LLVM module suitable for linking multiple times
        into another library.  Exported functions are made "linkonce_odr"
        to allow for multiple definitions, inlining, and removal of
        unused exports.

        See discussion in https://github.com/numba/numba/pull/890
        Nr   é   z7library unfit for linking: no available functions in %sZlinkonce_odr)r4   r1   r.   r?   Úis_declarationÚlinkager   ZLinkageÚexternalÚappendr0   r9   ZcloneÚget_function)r   ÚmodZto_fixZnfuncsÚfnr0   r   r   r   Ú_get_module_for_linking   s&    	


z#CodeLibrary._get_module_for_linkingc             C   s   |   ¡  | j |¡}|S )zB
        Create a LLVM IR module for use by this library.
        )r:   r'   r-   )r   r0   Ú	ir_moduler   r   r   Úcreate_ir_module¢   s    zCodeLibrary.create_ir_modulec             C   s   |  ¡  | j |¡ dS )zk
        Add a library for linking into this library, without losing
        the original library.
        N)r4   r*   Úadd)r   Úlibraryr   r   r   Úadd_linking_libraryª   s    zCodeLibrary.add_linking_libraryc             C   sN   |   ¡  t|tjƒst‚t t|ƒ¡}t 	|¡}|j
|_
| ¡  |  |¡ dS )zB
        Add a LLVM IR module's contents to this library.
        N)r:   Ú
isinstanceÚllvmirÚModuleÚAssertionErrorr   r/   r,   r   r+   r0   ÚverifyÚadd_llvm_module)r   rP   ÚirrB   r   r   r   Úadd_ir_module²   s    
zCodeLibrary.add_ir_modulec             C   s"   |   |¡ t|ƒ}| j |¡ d S )N)rD   r   r.   Úlink_in)r   rB   r   r   r   rZ   ¾   s    
zCodeLibrary.add_llvm_modulec             C   st   t ƒ  | j ¡  |  ¡  tjr2td| j |  ¡ ƒ x"| j	D ]}| j
j| ¡ dd q:W |  ¡  | j
 ¡  |  ¡  dS )z®
        Finalize the library.  After this call, nothing can be added anymore.
        Finalization involves various stages of code optimization and
        linking.
        zFUNCTION OPTIMIZED DUMP %sT)ZpreserveN)r
   r'   Ú_check_llvm_bugsr:   r   ZDUMP_FUNC_OPTr   r(   Úget_llvm_strr*   r.   r]   rO   rF   rY   Ú_finalize_final_module)r   rS   r   r   r   r;   Ä   s    

zCodeLibrary.finalizec             C   s0   x*| j jD ]}|j d¡r
| j |j¡ q
W d S )Nznumba.dynamic.globals)r.   Úglobal_variablesr0   Ú
startswithr2   rK   )r   Úgvr   r   r   Ú_finalize_dyanmic_globalsà   s    z%CodeLibrary._finalize_dyanmic_globalsc             C   s<   x6| j jD ]*}|jr
|j d¡r
d}t| |j¡ƒ‚q
W d S )NZ	_ZN5numbazSymbol {} not linked properly)r.   r?   rH   r0   rb   rX   Úformat)r   rN   Úmsgr   r   r   Ú_verify_declare_only_symbolsæ   s    z(CodeLibrary._verify_declare_only_symbolsc             C   sŽ   |   ¡  |  ¡  t | ¡| j_| j | j¡}|r<t 	| |¡ |  
¡  d| _tjrdtd| j |  ¡ ƒ tjrŠ|  ¡ }|rŠtd| j |  ¡ ƒ dS )z?
        Make the underlying LLVM module ready to use.
        TzOPTIMIZED DUMP %szASSEMBLY %sN)rd   rg   ÚweakrefÚproxyr.   Ú_CodeLibrary__libraryr'   Ú_add_moduler   r;   Ú_finalize_specificr8   r   ZDUMP_OPTIMIZEDr   r(   r_   ZDUMP_ASSEMBLYÚget_asm_str)r   ZcleanupZasmr   r   r   r`   î   s    z"CodeLibrary._finalize_final_modulec             c   s&   | j }x|jD ]}|js|V  qW dS )zj
        Get all functions defined in the library.  The library must have
        been finalized.
        N)r.   r?   rH   )r   rM   rN   r   r   r   Úget_defined_functions  s    z!CodeLibrary.get_defined_functionsc             C   s   | j  |¡S )N)r.   rL   )r   r0   r   r   r   rL     s    zCodeLibrary.get_functionc             C   s   | j rt d¡ d S )Nz@Inspection disabled for cached code. Invalid result is returned.)Ú_disable_inspectionÚwarningsÚwarn)r   r   r   r   Ú _sentry_cache_disable_inspection  s    z,CodeLibrary._sentry_cache_disable_inspectionc             C   s   |   ¡  t| jƒS )zA
        Get the human-readable form of the LLVM module.
        )rr   r,   r.   )r   r   r   r   r_     s    zCodeLibrary.get_llvm_strc             C   s   |   ¡  t| jj | j¡ƒS )z2
        Get the human-readable assembly.
        )rr   r,   r'   Ú_tmZemit_assemblyr.   )r   r   r   r   rm   %  s    zCodeLibrary.get_asm_strc             C   s$   |   ¡  |  |¡}t |¡}t|ƒS )z=
        Get control-flow graph of the LLVM function
        )rr   rL   r   Úget_function_cfgr   )r   r0   rN   r   r   r   r   rt   ,  s    

zCodeLibrary.get_function_cfgc             C   s   d| _ d | _d| _d S )NTF)Ú_object_caching_enabledÚ_compiled_objectÚ	_compiled)r   r   r   r   Úenable_object_caching9  s    z!CodeLibrary.enable_object_cachingc             C   s2   | j std| f ƒ‚| jd kr,td| f ƒ‚| jS )Nz object caching not enabled in %szno compiled object yet for %s)ru   Ú
ValueErrorrv   r9   )r   r   r   r   Ú_get_compiled_object>  s
    
z CodeLibrary._get_compiled_objectc             C   s8   | j std| f ƒ‚| jr(td| f ƒ‚|| _d| _d S )Nz object caching not enabled in %szlibrary already compiled: %sT)ru   ry   rw   rv   ro   )r   Úvaluer   r   r   Ú_set_compiled_objectE  s    z CodeLibrary._set_compiled_objectc       	      C   sÒ   ddl m} ddlm} ddlm} |||ƒƒ}tdƒ xŽ| ¡ D ]‚}|d dkrBt| 	¡ dd	„ d
}tdƒ xT|D ]L}|j
s€qttd|j
 ¡ |d |d | |d d ¡| |d d ¡f ƒ qtW qBW tƒ  dS )zw
        Dump the symbol table of an ELF file.
        Needs pyelftools (https://github.com/eliben/pyelftools)
        r   )ÚELFFile)Údescriptions)ÚBytesIOz	ELF file:Zsh_typeZ
SHT_SYMTABc             S   s   | j S )N)r0   )Úsymr   r   r   Ú<lambda>Z  s    z'CodeLibrary._dump_elf.<locals>.<lambda>)Úkeyz    symbols:z/    - %r: size=%d, value=0x%x, type=%s, bind=%sÚst_sizeZst_valueZst_infoÚtypeZbindN)Zelftools.elf.elffiler}   Zelftools.elfr~   Úior   r   Ziter_sectionsÚsortedZiter_symbolsr0   ÚdecodeZdescribe_symbol_typeZdescribe_symbol_bind)	ÚclsÚbufr}   r~   r   ÚfZsecZsymbolsr€   r   r   r   Ú	_dump_elfM  s&    
 zCodeLibrary._dump_elfc             C   s6   y
|j }W n tk
r   dS X |jr2d|_||_dS )zB
        `ll_module` was compiled into object code `buf`.
        NT)rj   ÚAttributeErrorru   rw   rv   )rˆ   rB   r‰   r   r   r   r   Ú_object_compiled_hookh  s    
z!CodeLibrary._object_compiled_hookc             C   s@   y
|j }W n tk
r   dS X |jr<|jr<|j}d|_|S dS )z>
        Return a cached object code for `ll_module`.
        N)rj   rŒ   ru   rv   )rˆ   rB   r   r‰   r   r   r   Ú_object_getbuffer_hooku  s    
z"CodeLibrary._object_getbuffer_hookc             C   s   |   ¡  | jd| j ¡ fS )zX
        Serialize this library using its bitcode as the cached representation.
        Úbitcode)r4   r(   r.   Ú
as_bitcode)r   r   r   r   Úserialize_using_bitcodeƒ  s    z#CodeLibrary.serialize_using_bitcodec             C   s(   |   ¡  |  ¡ |  ¡  ¡ f}| jd|fS )z´
        Serialize this library using its object code as the cached
        representation.  We also include its bitcode for further inlining
        with other libraries.
        Úobject)r4   rz   rO   r   r(   )r   Údatar   r   r   Úserialize_using_object_codeŠ  s    z'CodeLibrary.serialize_using_object_codec       	      C   sž   |\}}}|  |¡}t|| ƒs"t‚|dkrBt |¡|_| ¡  |S |dkrŒ|\}}| ¡  | |¡ t |¡|_	| ¡  |j
j |j	¡ |S td|f ƒ‚d S )Nr   r’   z!unsupported serialization kind %r)Úcreate_libraryrU   rX   r   Zparse_bitcoder.   r`   rx   r|   r1   r'   Ú_engineÚ_load_defined_symbolsry   )	rˆ   r3   Ústater0   Zkindr“   r   Zobject_codeZshared_bitcoder   r   r   Ú_unserialize•  s     


zCodeLibrary._unserializeN))r"   r#   r$   r%   r8   ru   ro   r   Úpropertyr6   r3   r!   r:   r4   rD   rF   rO   rQ   rT   r\   rZ   r;   rd   rg   r`   rn   rL   rr   r_   rm   rt   rx   rz   r|   Úclassmethodr‹   r   rŽ   r‘   r”   r™   r   r   r   r   r&   <   sH   #
r&   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚAOTCodeLibraryc             C   s   |   ¡  | jj | j¡S )z¤
        Return this library as a native object (a bytestring) -- for example
        ELF under Linux.

        This function implicitly calls .finalize().
        )r4   r'   rs   Zemit_objectr.   )r   r   r   r   Úemit_native_object®  s    z!AOTCodeLibrary.emit_native_objectc             C   s   |   ¡  | j ¡ S )zz
        Return this library as LLVM bitcode (a bytestring).

        This function implicitly calls .finalize().
        )r4   r.   r   )r   r   r   r   Úemit_bitcode¸  s    zAOTCodeLibrary.emit_bitcodec             C   s   d S )Nr   )r   r   r   r   rl   Á  s    z!AOTCodeLibrary._finalize_specificN)r"   r#   r$   r   rž   rl   r   r   r   r   rœ   ¬  s   
	rœ   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚJITCodeLibraryc             C   s0   |   ¡  | jj}| |¡sdS | jj |¡S dS )aˆ  
        Generate native code for function named *name* and return a pointer
        to the start of the function (as an integer).

        This function implicitly calls .finalize().

        Returns
        -------
        pointer : int
            - zero (null) if no symbol of *name* is defined by this code
              library.
            - non-zero if the symbol is defined.
        r   N)r4   r'   r–   Úis_symbol_definedÚget_function_address)r   r0   Úeer   r   r   Úget_pointer_to_functionÇ  s
    
z&JITCodeLibrary.get_pointer_to_functionc             C   s   | j  | j¡ | j j ¡  d S )N)r'   Ú_scan_and_fix_unresolved_refsr.   r–   Úfinalize_object)r   r   r   r   rl   Ü  s    z!JITCodeLibrary._finalize_specificN)r"   r#   r$   r£   rl   r   r   r   r   rŸ   Å  s   rŸ   c               @   s4   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚRuntimeLinkerzP
    For tracking unresolved symbols generated at runtime due to recursion.
    z.numba.unresolved$c             C   s   t  ¡ | _tƒ | _g | _d S )N)r   Z
UniqueDictÚ_unresolvedr)   Ú_definedÚ	_resolved)r   r   r   r   r   ç  s    
zRuntimeLinker.__init__c             C   sx   | j }xl|jD ]b}|j |¡r|jt|ƒd… }| |j¡r>qtj d¡}t	 
|¡}| |t	 |¡¡ || j|< qW dS )zr
        Scan and track all unresolved external symbols in the module and
        allocate memory for it.
        NZnrt_unresolved_abort)ÚPREFIXra   r0   rb   r5   r    r	   rS   r£   ÚctypesÚc_void_pÚadd_global_mappingZ	addressofr§   )r   ÚmoduleÚengineÚprefixrc   r€   ZabortfnÚptrr   r   r   Úscan_unresolved_symbolsì  s    
z%RuntimeLinker.scan_unresolved_symbolsc             C   s(   x"|j D ]}|js| j |j¡ qW dS )z5
        Scan and track all defined symbols.
        N)r?   rH   r¨   rR   r0   )r   r®   rN   r   r   r   Úscan_defined_symbolsÿ  s    z"RuntimeLinker.scan_defined_symbolsc                sX   ‡ fdd„ˆ j D ƒ}x>|D ]6}| |¡}ˆ j | }||_ˆ j ||f¡ ˆ j |= qW dS )z=
        Fix unresolved symbols if they are defined.
        c                s   g | ]}|ˆ j kr|‘qS r   )r¨   )Ú.0r0   )r   r   r   ú
<listcomp>  s    z)RuntimeLinker.resolve.<locals>.<listcomp>N)r§   r¡   r{   r©   rK   )r   r¯   Úpendingr0   Úfnptrr±   r   )r   r   Úresolve  s    


zRuntimeLinker.resolveN)	r"   r#   r$   r%   rª   r   r²   r³   r¸   r   r   r   r   r¦   á  s   r¦   c                s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                s   ˆ | j f|ž|ŽS )N)Ú_ee)r   ÚargsÚkwargs)Úoldr   r   Úwrapper  s    z_proxy.<locals>.wrapper)Ú	functoolsÚwraps)r¼   r½   r   )r¼   r   Ú_proxy  s    rÀ   c               @   sh   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Ze	e
jjƒZe	e
jjƒZe	e
jjƒZe	e
jjƒZdS )Ú	JitEnginez»Wraps an ExecutionEngine to provide custom symbol tracking.
    Since the symbol tracking is incomplete  (doesn't consider
    loaded code object), we are not putting it in llvmlite.
    c             C   s   || _ tƒ | _d S )N)r¹   r)   Ú_defined_symbols)r   r¢   r   r   r   r   %  s    
zJitEngine.__init__c             C   s
   || j kS )z/Is the symbol defined in this session?
        )rÂ   )r   r0   r   r   r   r    2  s    zJitEngine.is_symbol_definedc             C   s2   x,|j |jfD ]}|  jdd„ |D ƒO  _qW dS )z(Extract symbols from the module
        c             S   s   h | ]}|j s|j’qS r   )rH   r0   )r´   rc   r   r   r   ú	<setcomp>;  s    z2JitEngine._load_defined_symbols.<locals>.<setcomp>N)r?   ra   rÂ   )r   rM   Zgsetsr   r   r   r—   7  s    zJitEngine._load_defined_symbolsc             C   s   |   |¡ | j |¡S )zXOverride ExecutionEngine.add_module
        to keep info about defined symbols.
        )r—   r¹   Ú
add_module)r   r®   r   r   r   rÄ   >  s    
zJitEngine.add_modulec             C   s   | j  |j¡ | j ||¡S )z`Override ExecutionEngine.add_global_mapping
        to keep info about defined symbols.
        )rÂ   rR   r0   r¹   r­   )r   rc   Zaddrr   r   r   r­   E  s    zJitEngine.add_global_mappingN)r"   r#   r$   r%   r   r    r—   rÄ   r­   rÀ   r   ZExecutionEngineÚset_object_cacher¥   r¡   Úget_global_value_addressr   r   r   r   rÁ      s   
rÁ   c               @   sˆ   e Zd Zdd„ Zdd„ Zdd„ Zedd„ ƒZd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS ) ÚBaseCPUCodegenc             C   sB   t ƒ  d | _t t|  |¡ƒ¡| _d| j_tƒ | _	|  
| j¡ d S )NZglobal_codegen_module)Úinitialize_llvmr<   r   r+   r,   r-   Ú_llvm_moduler0   r¦   Ú	_rtlinkerÚ_init)r   Úmodule_namer   r   r   r   X  s    zBaseCPUCodegen.__init__c             C   s´   t |jƒg kstdƒ‚tj t ¡ ¡}ttj	d}|  
¡ | _|  |¡ |jf |Ž}t ||¡}tjrl| ¡  || _t|ƒ| _|j| _t| jƒ| _|  ¡ | _| j | jj| jj¡ d S )NzModule isn't empty)Úopt)Úlistra   rX   r   ÚTargetZfrom_tripleÚget_process_tripleÚdictr   ÚOPTÚ_customize_tm_featuresÚ_tm_featuresÚ_customize_tm_optionsZcreate_target_machineZcreate_mcjit_compilerZENABLE_PROFILINGZenable_jit_eventsrs   rÁ   r–   Útarget_dataÚ_target_datar,   r<   Ú_module_pass_managerrE   rÅ   Ú_library_classr   rŽ   )r   Úllvm_moduleÚtargetZ
tm_optionsZtmr¯   r   r   r   rË   b  s     



zBaseCPUCodegen._initc             C   s,   t  t |¡¡}t ¡ |_| jr(| j|_|S )N)	ÚlcrW   r   r/   r   rÐ   r   r<   r=   )r   r0   rP   r   r   r   r-   x  s
    
z#BaseCPUCodegen._create_empty_modulec             C   s   | j S )zJ
        The LLVM "target data" object for this codegen instance.
        )r×   )r   r   r   r   rÖ     s    zBaseCPUCodegen.target_datac             C   s   |   | |¡S )zb
        Create a :class:`CodeLibrary` object for use with this codegen
        instance.
        )rÙ   )r   r0   r   r   r   r•   †  s    zBaseCPUCodegen.create_libraryc             C   s   | j  | |¡S )N)rÙ   r™   )r   Z
serializedr   r   r   Úunserialize_library  s    z"BaseCPUCodegen.unserialize_libraryc          	   C   s6   t  ¡ }| j |¡ |  ¡ }| |¡ W d Q R X |S )N)r   Zcreate_module_pass_managerrs   Úadd_analysis_passesÚ_pass_manager_builderÚpopulate)r   ÚpmÚpmbr   r   r   rØ     s
    
z#BaseCPUCodegen._module_pass_managerc          	   C   s8   t  |¡}| j |¡ |  ¡ }| |¡ W d Q R X |S )N)r   Zcreate_function_pass_managerrs   rÞ   rß   rà   )r   rÚ   rá   râ   r   r   r   r>   —  s
    

z%BaseCPUCodegen._function_pass_managerc             C   s   t jtjtjd}|S )a  
        Create a PassManagerBuilder.

        Note: a PassManagerBuilder seems good only for one use, so you
        should call this method each time you want to populate a module
        or function pass manager.  Otherwise some optimizations will be
        missed...
        )rÍ   Zloop_vectorize)ÚlpZcreate_pass_manager_builderr   rÒ   ZLOOP_VECTORIZE)r   râ   r   r   r   rß   ž  s    	z$BaseCPUCodegen._pass_manager_builderc             C   sZ   d}t  |¡}t|ƒ}d|ks&d|kr*dS d|krHt ¡ }td|f ƒ‚td|f ƒ‚dS )z<
        Guard against some well-known LLVM bug(s).
        zo
            define double @func()
            {
                ret double 1.23e+01
            }
            z12.3z1.23Nz1.0z¯LLVM will produce incorrect floating-point code in the current locale %s.
Please read http://numba.pydata.org/numba-doc/dev/user/faq.html#llvm-locale-bug for more information.zUnexpected IR:
%s
)r   r+   r,   ÚlocaleZ	getlocaler9   rX   )r   r[   rM   Zir_outZlocr   r   r   r^   «  s    

zBaseCPUCodegen._check_llvm_bugsc             C   s   | j j|  ¡ | jfS )zP
        Return a tuple unambiguously describing the codegen behaviour.
        )rÉ   r   Ú_get_host_cpu_namerÔ   )r   r   r   r   Úmagic_tupleÉ  s    zBaseCPUCodegen.magic_tuplec             C   s.   | j  || j¡ | j  |¡ | j  | j¡ d S )N)rÊ   r²   r–   r³   r¸   )r   r®   r   r   r   r¤   Ð  s    z,BaseCPUCodegen._scan_and_fix_unresolved_refsc             C   sp   t  d¡ ¡ }| jj| }|j}y| |¡}W n* tk
rX   t j|||d}d|_	Y nX | 
| |¡| ¡ ¡S )Né   )r0   rJ   )rV   ZIntTypeZ
as_pointerrÊ   rª   r®   Z
get_globalÚKeyErrorZGlobalVariablerI   ZbitcastÚload)r   ZbuilderZfntyr0   ZvoidptrZptrnameZllvm_modr·   r   r   r   Úinsert_unresolved_refÕ  s    z$BaseCPUCodegen.insert_unresolved_refc             C   s   t jd krt ¡ S t jS )N)r   ZCPU_NAMEr   Zget_host_cpu_name)r   r   r   r   rå   á  s    z!BaseCPUCodegen._get_host_cpu_namec             C   s   t jd k	rt jS tƒ S )N)r   ZCPU_FEATURESÚget_host_cpu_features)r   r   r   r   Ú_get_host_cpu_featuresæ  s    
z%BaseCPUCodegen._get_host_cpu_featuresN)r"   r#   r$   r   rË   r-   rš   rÖ   r•   rÝ   rØ   r>   rß   r^   ræ   r¤   rê   rå   rì   r   r   r   r   rÇ   V  s   
rÇ   c               @   s6   e Zd ZdZeZddd„Zdd„ Zdd„ Zd	d
„ Z	dS )ÚAOTCPUCodegenzp
    A codegen implementation suitable for Ahead-Of-Time compilation
    (e.g. generation of object files).
    Nc             C   s   |pd| _ t | |¡ d S )NÚ )Ú	_cpu_namerÇ   r   )r   rÌ   Úcpu_namer   r   r   r   ó  s    
zAOTCPUCodegen.__init__c             C   s<   | j }|dkr|  ¡ }||d< d|d< d|d< | j|d< d S )NZhostÚcpuZpicÚrelocÚdefaultÚ	codemodelÚfeatures)rï   rå   rÔ   )r   Úoptionsrð   r   r   r   rÕ   ø  s    z#AOTCPUCodegen._customize_tm_optionsc             C   s   dS )Nrî   r   )r   r   r   r   rÓ     s    z$AOTCPUCodegen._customize_tm_featuresc             C   s   d S )Nr   )r   r®   r   r   r   rk     s    zAOTCPUCodegen._add_module)N)
r"   r#   r$   r%   rœ   rÙ   r   rÕ   rÓ   rk   r   r   r   r   rí   ë  s   
	rí   c               @   s4   e Zd ZdZeZdd„ Zdd„ Zdd„ Zdd	„ Z	d
S )ÚJITCPUCodegenzI
    A codegen implementation suitable for Just-In-Time compilation.
    c             C   sR   |   ¡ |d< tj ¡ j}| d¡r(d}nd}||d< d|d< | j|d< d	|d
< d S )Nrñ   r   Zstaticró   rò   Z
jitdefaultrô   rõ   TZjitdebug)rå   r   rÏ   Zfrom_default_tripler0   rb   rÔ   )r   rö   r   Zreloc_modelr   r   r   rÕ     s    

z#JITCPUCodegen._customize_tm_optionsc             C   s   |   ¡ S )N)rì   )r   r   r   r   rÓ   '  s    z$JITCPUCodegen._customize_tm_featuresc             C   s   | j  |¡ d S )N)r–   rÄ   )r   r®   r   r   r   rk   +  s    zJITCPUCodegen._add_modulec             C   s2   | j  |¡}tjd  |¡}t t|ƒ¡|d< dS )zrSet the environment address.

        Update the GlobalVariable named *env_name* to the address of *env*.
        rG   r   N)r–   rÆ   r«   r¬   Zfrom_addressr7   )r   Zenv_nameÚenvZgvaddrZenvptrr   r   r   Úset_env3  s    zJITCPUCodegen.set_envN)
r"   r#   r$   r%   rŸ   rÙ   rÕ   rÓ   rk   rù   r   r   r   r   r÷   
  s   r÷   c               C   s   t  ¡  t  ¡  t  ¡  dS )z Safe to use multiple times.
    N)r   r@   Zinitialize_native_targetZinitialize_native_asmprinterr   r   r   r   rÈ   =  s    rÈ   c              C   sT   yt  ¡ } W n tk
r    dS X tjsHx| D ]}| d¡r.d| |< q.W |  ¡ S dS )z~Get host CPU features using LLVM.

    The features may be modified due to user setting.
    See numba.config.ENABLE_AVX.
    rî   ZavxFN)r   rë   r9   r   Z
ENABLE_AVXrb   Zflatten)rõ   Úkr   r   r   rë   E  s    

rë   )1Z
__future__r   r   r   rp   r¾   rä   rh   r«   Zllvmlite.llvmpy.coreZllvmpyZcorerÜ   Zllvmlite.llvmpy.passesZpassesrã   Zllvmlite.bindingZbindingr   Zllvmlite.irr[   rV   Znumbar   r   r   Znumba.runtime.nrtoptr   Znumba.runtimer	   Znumba.compiler_lockr
   Ú	frozensetr   r   r   r’   r   r&   rœ   rŸ   r¦   rÀ   rÁ   rÇ   rí   r÷   rÈ   rë   r   r   r   r   Ú<module>   s@   
  r86 3