o
    1&i                     @   s  d dl Z d dl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Z	 d dl
mZ d dlmZ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 d dlmZ d dlmZ d d	lmZ d d
l m!Z! e"g dZ#dd Z$dd Z%dd Z&G dd de'Z(G dd de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.G d!d" d"e'Z/G d#d$ d$edZ0G d%d& d&e0Z1G d'd( d(e1Z2G d)d* d*e1Z3d+d, Z4d-d. Z5dS )/    N)abstractmethodABCMeta)utilsconfigcgutils)create_pass_builder)remove_redundant_nrt_refct)rtsys)require_global_compiler_lock)NumbaInvalidConfigWarning)disassemble_elf_to_cfg)PassTimingsCollection)x86i386Zi486Zi586i686Zi786Zi886Zi986c                 C   s   |  dd }|tv S )N-r   )split_x86arch)triplearch r   =C:\wamp64\www\opt\env\Lib\site-packages\numba/core/codegen.py_is_x86   s   r   c               	   C   sj   t jd} | s
dS d}| D ]$}| }z|ttj| O }W q ty2   t	
d|t Y qw |S )zParse refprune flags from the `config`.

    Invalid values are ignored an warn via a `NumbaInvalidConfigWarning`
    category.

    Returns
    -------
    flags : llvmlite.binding.RefPruneSubpasses
    ,r   zinvalid refprune flags )r   ZLLVM_REFPRUNE_FLAGSr   stripgetattrllZRefPruneSubpassesupperAttributeErrorwarningswarnr   )flagsvalitemr   r   r   _parse_refprune_flags    s   
r$   c           	         s   t jrHzdd l}W n ty   d}t|w ddlm ddlm} ddlm} ddl	m
  ddlm ||d}||  fd	d
}nt}td t| dd || td d S )Nr   z0Please install pygments to see highlighted dumps)	highlight)GasLexer)	LlvmLexer)Terminal256Formatter)by_colorscheme)llvmasmc                    s   t |    d d S )N)style)print)argr(   r)   r%   lexerr   r   printerH   s   


zdump.<locals>.printerzP================================================================================P   r   )r   ZHIGHLIGHT_DUMPSpygmentsImportError
ValueErrorr%   Zpygments.lexersr&   r'   Zpygments.formattersr(   Znumba.misc.dump_styler)   r-   center)	headerbodylangr3   msgZ	gas_lexerZ
llvm_lexerZ	lexer_mapr1   r   r/   r   dump8   s(   
r;   c                   @   sD   e Zd ZdZdd Z				ddd	ZdddZ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                 K   s2   || _ || _|| _||}t|| _|| _d S N)cresnamepy_funcget_functionr   get_function_cfgdotkwargs)selfr>   r?   r@   rD   fnr   r   r   __init__[   s   

z_CFG.__init__NTF
   c	           K         sL  ddl ddlddl}	ddl}
ddlm} ddlm} ddlm	} ddl
m} d}|||||||||d}|||d	 d
d }||| | | |dd dd< dd< dd< dd< dd< dd< dd< dd< dd< d d!< d"d#< | j| j}| j }fd$d%}||
fd&d'}|| j| j|}d(}d)}d*d+}|	d,}d-}d.}d/}d0}d1}d2} d3}!d4d5 }"d6d7 i }#i }$ jr|
| j\||d8d9}%|%jd:d;}&|	|&d<}'d}(|'d= D ]})d>\|)d? }*|)d@ }+|)dA },|+|#|,< |*dBdC }*|*dD}-g }.dBd9}/||-dC }0|-}1|0dur|0 d }2|2dE}3t|3dF}4g }5|jrld d dG}6ni }6|3D ]}7||7 \}8}9|6|9dH}:|5 |4!|:|8|9 qpd9"|5}/|-ddC }1dI};|. |;!dJ |1d #  dK 	
fdLdM}<|1dBd D ]}=||=rϐqň j$s׈ jr|<|=|.}>|>dur|>\|j%r|&|=rd }?n^|j'r|&|=rd }?nO|j(r|&|=rd }?n@|j)r!| &|=r!d }?n1|j*r0|!&|=r0d }?n"|j+r?|&|=r?d! }?n|j,rN|&|=rNd# }?ndJ }?|?dJ us\|sp|"|=D ]}@|. !|?|@ qbq|/r}|. dN!|/ d9"|.}A|ArdO|(|Af }BdP!|B}*nd9}*|j-|+|*dQ qdR|'v r|'dR D ]}C|CdA },|CdSd}D|CdT |CdU |Df|$|,< q|$. D ]&\},}C|#|CdB  }E|#|Cd  }F|CdV }G|Gdur|EdW|G 7 }E|/|E|F q|rg }H. D ]\}I}J|H dX!|J|I q|j-dYdZ!d9"|HdQ |dus|dur |j0|||d[ |jd\d;S )]z
        "Pretty" prints the DOT graph of the CFG.
        For explanation of the parameters see the docstring for
        numba.core.dispatcher::inspect_cfg.
        r   N)binding)List)SimpleNamespace)defaultdictF)increfdecrefreturnsraisesmeminfobranchesllvm_intrin_callsfunction_calls)pythonlineinfoc                 S   s   t |tr| jD ]}t| || qdS t |trC| D ]$\}}|| jvr+td| t |tr7t| || qd}t|||f dS t |tr`|D ]}|| jvrWtd| t| |d qJdS d}t|t| )z Parses the kwarg into a consistent format for use in configuring
            the Digraph rendering. _config is the configuration instance to
            update, kwarg is the kwarg on which to base the updates.
            zUnexpected key in kwarg: %sz$Unexpected value for key: %s, got:%sTz)Unhandled configuration type for kwarg %sN)	
isinstancebool__dict__setattrdictitemsr5   settype)_configkwargattrkvr:   r#   r   r   r   parse_config   s*   






z)_CFG.pretty_printer.<locals>.parse_configc                   S      dS )Nwhiter   r   r   r   r   <lambda>       z%_CFG.pretty_printer.<locals>.<lambda>ZorangemarkeryellowrU   greenZtruebrredZfalsebrcyanrM   Z	turquoiserN   Z	lightpinkraiseZlightseagreenrQ   purplereturnZ	rosybrownrS   tomatorT   c                    sb   i }  d}|  D ]#}||}|dur.| }|dur.t|dks&J |d ||d < q|S )z Gets the metadata entries from the LLVM IR, these look something
            like '!123 = INFORMATION'. Returns a map of metadata key to metadata
            value, i.e. from the example {'!123': INFORMATION}z(^[!][0-9]+)(\s+=\s+.*)N      r   )compile
splitlinesmatchgroupslen)llvm_strmdZmetadata_entryxrv   g)rer   r   get_metadata   s   

z)_CFG.pretty_printer.<locals>.get_metadatac                    sj   d}t ||krd| d}t|t |d | } j| |d}|jdd |jddd	t| d
 |S )N   zCFG output filename "z9" exceeds maximum supported length, it will be truncated.)filenameTB)Zrankdirnodenonez%s)shapefontsize)rx   r   r    r   ZDigraphra   str)r?   fnamer   ZcmaxZwstrf)gvr   r   init_digraph   s   z)_CFG.pretty_printer.<locals>.init_digraphz
.*{(.*)}.*z.*<(.*)>(.*)z.*!dbg\s+(![0-9]+).*z7.*!DILocation\(line:\s+([0-9]+),\s+column:\s+([0-9]),.*z.*call void @llvm.dbg.value.*z@NRT_incref\bz@NRT_decref\bz@NRT_MemInfoz.*call.*@llvm\..*z.*call.*@.*z"store .*\!numba_exception_output.*zret i32 [^1],?.*c                 S   s   t j| dddS )Nx   z... )widthsubsequent_indent)textwrapwrap)sr   r   r   r         z!_CFG.pretty_printer.<locals>.wrapc                 S   sz   d}t | |krtt| }d| d | |} t| } | dd} | dd} | dd} | d	d
} | dd} | S )Ni,  z{}...<hash={}>z\{z&#123;z\}z&#125;\z&#92;%z&#37;!z&#33;)rx   r   hashformathtmlescapereplace)r   nhsr   r   r   clean   s   
z"_CFG.pretty_printer.<locals>.cleanz\l... Zdot_json)r   utf-8objects)r   labelr?   Z_gvidrs   r   z\l|z<<td BGCOLOR="{}" BORDER="1" ALIGN="center" PORT="{}">{}</td>)TFrf   zF<tr><td BGCOLOR="{}" BORDER="1" ALIGN="left" COLSPAN="{}">{}</td></tr>defaultzF<tr><td BGCOLOR="{}" BORDER="0" ALIGN="left" COLSPAN="{}">{}</td></tr>c                    s.  
 | }|dur| }|durt|dksJ ||d }	|d}|dur |}|durt| dks>J || \}}|ksL|kr jrhd}	|	|||f }
d |
}||  jrt|d  }|d  }d |}|| ||fS dS dS dS dS dS )z
                Search line `l` for metadata associated with python or line info
                and inject it into `new_lines` if requested.
                Nrs   r   rr   zMarker %s, Line %s, column %sri   rU   )	rv   rw   rx   getrV   r   appendrU   int)l	new_linesmatchedr|   ri   Z
debug_dataldlinecolZmfmtZ	mark_linelnZlidxZsource_line)_interleaver   col_spancscur_colcur_linefirstlinenofmtlocation_entryrz   metadata_markersrc_coder   r   metadata_interleavei  sB   



z0_CFG.pretty_printer.<locals>.metadata_interleavez<tr>{}</tr>zS<table id="%s" BORDER="1" CELLBORDER="0" CELLPADDING="0" CELLSPACING="0">%s</table>z<{}>)r   edgesZtailportheadtailrr   z:%sz;<tr><td BGCOLOR="{}" BORDER="0" ALIGN="center">{}</td></tr>Keyzn<<table BORDER="1" CELLBORDER="1" CELLPADDING="2" CELLSPACING="1"><tr><td BORDER="0">Key:</td></tr>{}</table>>)r   viewr   svg)1graphvizr}   jsoninspectZllvmliterI   Znumba.typedrJ   typesrK   collectionsrL   r>   rA   r?   get_llvm_strrt   rU   getsourcelinesr@   rB   r   ZSourcepipeloadsdecoder   rv   rw   rx   rR   r   r   r   joinr   rV   rM   searchrN   rQ   rP   rO   rS   rT   r   r\   edgerender)KrE   r   r   render_formatr%   
interleaveZstrip_irZshow_keyr   r   r   r   rJ   rK   rL   _default
_highlightrd   rF   ry   r~   r   r   Z
port_matchZport_jmp_matchZlocation_exprZ	dbg_valueZ
nrt_increfZ
nrt_decrefZnrt_meminfoZll_intrin_callsZll_function_callZll_raiseZ	ll_returnr   Znode_idsZedge_idsZraw_dotZ
json_bytesZjzonZidcobjr   r?   Zgvidlinesr   Z	port_liner   Zsliced_linesZportsZports_tokensZtdfmtZtbl_datacolorstoktargetvaluecolorZ	fmtheaderr   r   Zupdated_lineinfocolourr{   Zdattabr   tpr   r   portZkey_tabrb   rc   r   )r   r   r   r   r   r   r   r   r   r   rz   r   r}   r   r   pretty_printerc   s>  	


















"+











z_CFG.pretty_printerpdfc                 C   s$   | j d|||d| j}|dS )a  
        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). *format* can
        be any valid format string accepted by graphviz, default is 'pdf'.
        )r   r   r   r   Nr   r   rD   r   )rE   r   r   r   Zrawbytr   r   r   display  s   


z_CFG.displayc                 C   s   | j di | jdS )Nr   r   r   rE   r   r   r   
_repr_svg_  s   z_CFG._repr_svg_c                 C      | j S r=   )rC   r   r   r   r   __repr__  s   z_CFG.__repr__)NNNTFFTrH   )Nr   F)	__name__
__module____qualname____doc__rG   r   r   r   r   r   r   r   r   r<   S   s    
   
r<   c                   @   s   e Zd ZdZdZdZdZdddefddZe	dd	 Z
e	d
d Ze	dd Ze	dd Zdd Zdd Zdd Zdd Zedd Zedd Zedd Zedd Zed d! Zed"d# Zd$d% Zd&d' Zd(d) Zd*S )+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.
    Fcodegen
CPUCodegenr?   c                 C   s6   || _ || _| jj d| jd}t|| _g | _d S )N())_codegen_name	__class__r   r   _recorded_timings_dynamic_globals)rE   r   r?   Zptc_namer   r   r   rG     s
   

zCodeLibrary.__init__c                 C   s   |    t| jdkS )Nr   )_ensure_finalizedrx   r   r   r   r   r   has_dynamic_globals  s   zCodeLibrary.has_dynamic_globalsc                 C   r   r=   )r   r   r   r   r   recorded_timings     zCodeLibrary.recorded_timingsc                 C   r   )z9
        The codegen object owning this library.
        )r   r   r   r   r   r   "     zCodeLibrary.codegenc                 C   r   r=   )r   r   r   r   r   r?   )  r   zCodeLibrary.namec                 C   s   d| j t| f S )Nz<Library %r at 0x%x>)r?   idr   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RuntimeErrorr   r   r   r   _raise_if_finalized0  s
   zCodeLibrary._raise_if_finalizedc                 C   s   | j s	|   d S d S r=   )r   finalizer   r   r   r   r   5  s   zCodeLibrary._ensure_finalizedc                 C   s   |    | j|}|S )zC
        Create an LLVM IR module for use by this library.
        )r   r   _create_empty_modulerE   r?   	ir_moduler   r   r   create_ir_module9  s   zCodeLibrary.create_ir_modulec                 C   re   )zk
        Add a library for linking into this library, without losing
        the original library.
        Nr   rE   libraryr   r   r   add_linking_libraryA  rh   zCodeLibrary.add_linking_libraryc                 C   re   )zC
        Add an LLVM IR module's contents to this library.
        Nr   )rE   r   r   r   r   add_ir_moduleH  rh   zCodeLibrary.add_ir_modulec                 C   re   )z
        Finalize the library.  After this call, nothing can be added anymore.
        Finalization involves various stages of code optimization and
        linking.
        Nr   r   r   r   r   r   N  rh   zCodeLibrary.finalizec                 C   re   )z5
        Return the function named ``name``.
        Nr   rE   r?   r   r   r   rA   V  rh   zCodeLibrary.get_functionc                 C   re   )zA
        Get the human-readable form of the LLVM module.
        Nr   r   r   r   r   r   \  rh   zCodeLibrary.get_llvm_strc                 C   re   )z2
        Get the human-readable assembly.
        Nr   r   r   r   r   get_asm_strb  rh   zCodeLibrary.get_asm_strc                 C   s   d| _ d | _d| _d S )NTF)_object_caching_enabled_compiled_object	_compiledr   r   r   r   enable_object_cachingl  s   
z!CodeLibrary.enable_object_cachingc                 C   s2   | j s
td| f | jd u rtd| f | jS )N object caching not enabled in %szno compiled object yet for %s)r  r5   r	  r   r   r   r   r   _get_compiled_objectq  s
   
z CodeLibrary._get_compiled_objectc                 C   s8   | j s
td| f | jrtd| f || _d| _d S )Nr  zlibrary already compiled: %sT)r  r5   r
  r	  _disable_inspection)rE   r   r   r   r   _set_compiled_objectx  s   
z CodeLibrary._set_compiled_objectN)r   r   r   r   r   r  r  r   rG   propertyr   r   r   r?   r   r   r   r  r   r  r  r   rA   r   r  r  r  r  r   r   r   r   r     sB    









	r   )	metaclassc                       s   e Zd Z f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d2d"d#Zd$d% Zed&d' Zed(d) Zed*d+ Zd,d- Zd.d/ Zed0d1 Z  ZS )3CPUCodeLibraryc                    sH   t  || g | _tt| j| j| _	t
| j| j	_d | _d S r=   )superrG   _linking_librariesr   parse_assemblyr   r   r   r?   _final_moduler   normalize_ir_text_shared_module)rE   r   r?   r   r   r   rG     s   
zCPUCodeLibrary.__init__c              	   C   sn   | j j|_|jD ],}| j  \}}d|j}| j|| ||| W d   n1 s/w   Y  qdS )zP
        Internal: run function-level optimizations inside *ll_module*.
        zFunction passes on N)	r   _data_layoutdata_layout	functions_function_pass_managerr?   r   recordrun)rE   	ll_modulefuncZfpmpbrb   r   r   r   _optimize_functions  s   

z"CPUCodeLibrary._optimize_functionsc                 C   s   | j j| j jd| j jdd\}}| j  \}}d}| j|| || j| W d   n1 s2w   Y  tj	s@t
| j| _d}| j|| || j| W d   dS 1 s\w   Y  dS )zA
        Internal: optimize this library's final module.
        Fcheap)loop_vectorizeslp_vectorizeoptcostz/Module passes (cheap optimization for refprune)Nz!Module passes (full optimization))r   _module_pass_manager	_loopvect
_opt_levelr   r  r  r  r   LLVM_REFPRUNE_PASSr   )rE   Z	mpm_cheapZ	mpb_cheapZmpm_fullZmpb_fullZ
cheap_nameZ	full_namer   r   r   _optimize_final_module  s"   
"z%CPUCodeLibrary._optimize_final_modulec                 C   s   |    | jdur| jS | j}g }d}|jD ]}|d7 }|js,|jtjjkr,|	|j
 q|dkr8td| f |rI| }|D ]}d||_q@|| _|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   rs   z7library unfit for linking: no available functions in %sZlinkonce_odr)r   r  r  r  is_declarationlinkager   ZLinkageexternalr   r?   r   clonerA   )rE   modZto_fixZnfuncsrF   r?   r   r   r   _get_module_for_linking  s*   	

z&CPUCodeLibrary._get_module_for_linkingc                 C   s   |   | j| d S r=   )r   r  r   r  r   r   r   r    s   z"CPUCodeLibrary.add_linking_libraryc                 C   sN   |    t|tjsJ tt|}t|}|j	|_	|
  | | d S r=   )r   rW   llvmirModuler   r  r   r   r  r?   verifyadd_llvm_module)rE   r   irr   r   r   r   r    s   
zCPUCodeLibrary.add_ir_modulec                 C   s(   |  | tjst|}| j| d S r=   )r#  r   r,  r   r  link_in)rE   r   r   r   r   r7    s   
zCPUCodeLibrary.add_llvm_modulec                 C   s   t   | j  |   tjrtd| j |  d t	 }| j
D ]}||vr5|| | jj| dd q |   | j  |   d S )NzFUNCTION OPTIMIZED DUMP %sr*   T)Zpreserve)r
   r   _check_llvm_bugsr   r   ZDUMP_FUNC_OPTr;   r?   r   r]   r  addr  r9  r3  r-  r6  _finalize_final_module)rE   seenr  r   r   r   r     s$   




zCPUCodeLibrary.finalizec                 C   s,   | j jD ]}|jdr| j|j qd S )Nznumba.dynamic.globals)r  global_variablesr?   
startswithr   r   )rE   r   r   r   r   _finalize_dynamic_globals  s
   z(CPUCodeLibrary._finalize_dynamic_globalsc                 C   s8   | j jD ]}|jr|jdrd}t||jqd S )NZ	_ZN5numbazSymbol {} not linked properly)r  r  r.  r?   r?  AssertionErrorr   )rE   rF   r:   r   r   r   _verify_declare_only_symbols  s   z+CPUCodeLibrary._verify_declare_only_symbolsc                 C   s   |    |   t| | j_| j| j}|rt| | | 	  d| _
tjr3td| j |  d tjrCtd| j |  d dS dS )z?
        Make the underlying LLVM module ready to use.
        TzOPTIMIZED DUMP %sr*   zASSEMBLY %sr+   N)r@  rB  weakrefproxyr  _CPUCodeLibrary__libraryr   _add_moduler   _finalize_specificr   r   ZDUMP_OPTIMIZEDr;   r?   r   ZDUMP_ASSEMBLYr  )rE   cleanupr   r   r   r<    s   z%CPUCodeLibrary._finalize_final_modulec                 c   s$    | j }|jD ]}|js|V  qdS )zj
        Get all functions defined in the library.  The library must have
        been finalized.
        N)r  r  r.  )rE   r2  rF   r   r   r   get_defined_functions.  s   
z$CPUCodeLibrary.get_defined_functionsc                 C   s   | j |S r=   )r  rA   r  r   r   r   rA   8  s   zCPUCodeLibrary.get_functionc                 C   s   | j r
td d S d S )Nz@Inspection disabled for cached code. Invalid result is returned.)r  r   r    r   r   r   r    _sentry_cache_disable_inspection;  s   z/CPUCodeLibrary._sentry_cache_disable_inspectionc                 C   s   |    t| jS r=   )rJ  r   r  r   r   r   r   r   @  s   
zCPUCodeLibrary.get_llvm_strc                 C   s   |    t| jj| jS r=   )rJ  r   r   _tmZemit_assemblyr  r   r   r   r   r  D  s   zCPUCodeLibrary.get_asm_strNc                 K   s   |    t| ||fi |S )z=
        Get control-flow graph of the LLVM function
        )rJ  r<   )rE   r?   r@   rD   r   r   r   rB   H  s   zCPUCodeLibrary.get_function_cfgc                 C   s   |   }t||S )aa  
        Get the CFG of the disassembly of the ELF object at symbol mangled_name.

        Requires python package: r2pipe
        Requires radare2 binary on $PATH.
        Notebook rendering requires python package: graphviz
        Optionally requires a compiler toolchain (via pycc) to link the ELF to
        get better disassembly results.
        )r  r   )rE   Zmangled_nameelfr   r   r   get_disasm_cfgO  s   

zCPUCodeLibrary.get_disasm_cfgc           	      C   s   ddl m} ddlm} ddlm} |||}td | D ]?}|d dkr_t|	 dd	 d
}td |D ]&}|j
s>q8td|j
 |d |d ||d d ||d d f  q8q 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   r   r=   r?   )symr   r   r   rg   i  s    z*CPUCodeLibrary._dump_elf.<locals>.<lambda>)keyz    symbols:z/    - %r: size=%d, value=0x%x, type=%s, bind=%sst_sizeZst_valueZst_infor^   bindN)Zelftools.elf.elffilerN  Zelftools.elfrO  iorP  r-   Ziter_sectionssortedZiter_symbolsr?   r   Zdescribe_symbol_typeZdescribe_symbol_bind)	clsbufrN  rO  rP  r   secsymbolsrR  r   r   r   	_dump_elf\  s,   
zCPUCodeLibrary._dump_elfc                 C   s:   z|j }W n
 ty   Y dS w |jrd|_||_dS dS )zB
        `ll_module` was compiled into object code `buf`.
        NT)rE  r   r  r
  r	  )rX  r   rY  rE   r   r   r   _object_compiled_hookw  s   

z$CPUCodeLibrary._object_compiled_hookc                 C   sD   z|j }W n
 ty   Y dS w |jr|jr |j}d|_|S dS dS )z>
        Return a cached object code for `ll_module`.
        N)rE  r   r  r	  )rX  r   rE   rY  r   r   r   _object_getbuffer_hook  s   
z%CPUCodeLibrary._object_getbuffer_hookc                 C   s   |    | jd| j fS )zX
        Serialize this library using its bitcode as the cached representation.
        bitcode)r   r?   r  
as_bitcoder   r   r   r   serialize_using_bitcode  s   z&CPUCodeLibrary.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)r   r  r3  r`  r?   )rE   datar   r   r   serialize_using_object_code  s
   
z*CPUCodeLibrary.serialize_using_object_codec           	      C   s   |\}}}| |}t|| sJ |dkr!t||_|  |S |dkrF|\}}|  || t||_|  |j	j
|j |S td|f )Nr_  rb  z!unsupported serialization kind %r)create_libraryrW   r   Zparse_bitcoder  r<  r  r  r  r   _engine_load_defined_symbolsr5   )	rX  r   stater?   kindrc  rE   Zobject_codeZshared_bitcoder   r   r   _unserialize  s    


zCPUCodeLibrary._unserializer=   )r   r   r   rG   r#  r-  r3  r  r  r7  r   r@  rB  r<  rI  rA   rJ  r   r  rB   rM  classmethodr\  r]  r^  ra  rd  rj  __classcell__r   r   r  r   r    s:    #	




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().
        )r   r   rK  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().
        )r   r  r`  r   r   r   r   emit_bitcode  s   
zAOTCodeLibrary.emit_bitcodec                 C      d S r=   r   r   r   r   r   rG       z!AOTCodeLibrary._finalize_specificN)r   r   r   rn  ro  rG  r   r   r   r   rm    s    
	rm  c                   @   s   e Zd Zdd Zdd ZdS )JITCodeLibraryc                 C   s,   |    | jj}||sdS | jj|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   )r   r   rf  is_symbol_definedget_function_address)rE   r?   eer   r   r   get_pointer_to_function  s
   
z&JITCodeLibrary.get_pointer_to_functionc                 C   sL   | j | j | jd | j j  W d    d S 1 sw   Y  d S )NzFinalize object)r   _scan_and_fix_unresolved_refsr  r   Zrecord_legacyrf  finalize_objectr   r   r   r   rG    s   "z!JITCodeLibrary._finalize_specificN)r   r   r   rv  rG  r   r   r   r   rr    s    rr  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 r=   )r   Z
UniqueDict_unresolvedr]   _defined	_resolvedr   r   r   r   rG     s   

zRuntimeLinker.__init__c                 C   st   | j }|jD ]1}|j|r7|jt|d }||jrqtjd}t	
|}||t	| || j|< qdS )zr
        Scan and track all unresolved external symbols in the module and
        allocate memory for it.
        NZnrt_unresolved_abort)PREFIXr>  r?   r?  rx   rs  r	   r  rv  ctypesc_void_padd_global_mapping	addressofrz  )rE   moduleengineprefixr   rR  Zabortfnptrr   r   r   scan_unresolved_symbols  s   


z%RuntimeLinker.scan_unresolved_symbolsc                 C   s$   |j D ]}|js| j|j qdS )z5
        Scan and track all defined symbols.
        N)r  r.  r{  r;  r?   )rE   r  rF   r   r   r   scan_defined_symbols  s
   
z"RuntimeLinker.scan_defined_symbolsc                    sT    fdd j D }|D ]}||} j | }||_ j||f  j |= qdS )z=
        Fix unresolved symbols if they are defined.
        c                    s   g | ]	}| j v r|qS r   )r{  ).0r?   r   r   r   
<listcomp>  s    z)RuntimeLinker.resolve.<locals>.<listcomp>N)rz  rt  r   r|  r   )rE   r  pendingr?   fnptrr  r   r   r   resolve  s   


zRuntimeLinker.resolveN)	r   r   r   r   r}  rG   r  r  r  r   r   r   r   ry    s    ry  c                    s   t   fdd}|S )Nc                    s    | j g|R i |S r=   )_ee)rE   argsrD   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 )	JitEnginezWraps 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 r=   )r  r]   _defined_symbols)rE   ru  r   r   r   rG   4  s   
zJitEngine.__init__c                 C   s
   || j v S )z/Is the symbol defined in this session?
        )r  r  r   r   r   rs  A  s   
zJitEngine.is_symbol_definedc                 C   s.   |j |jfD ]}|  jdd |D O  _qdS )z(Extract symbols from the module
        c                 S   s   h | ]}|j s|jqS r   )r.  r?   )r  r   r   r   r   	<setcomp>J  s    z2JitEngine._load_defined_symbols.<locals>.<setcomp>N)r  r>  r  )rE   r2  Zgsetsr   r   r   rg  F  s   zJitEngine._load_defined_symbolsc                 C   s   |  | | j|S )zXOverride ExecutionEngine.add_module
        to keep info about defined symbols.
        )rg  r  
add_modulerE   r  r   r   r   r  M  s   
zJitEngine.add_modulec                 C   s   | j |j | j||S )z`Override ExecutionEngine.add_global_mapping
        to keep info about defined symbols.
        )r  r;  r?   r  r  )rE   r   addrr   r   r   r  T  s   zJitEngine.add_global_mappingN)r   r   r   r   rG   rs  rg  r  r  r  r   ZExecutionEngineset_object_cacherx  rt  get_global_value_addressr   r   r   r   r  /  s    
r  c                   @   sD   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
d Z
dS )CodegenaM  
    Base Codegen class. It is expected that subclasses set the class attribute
    ``_library_class``, indicating the CodeLibrary class for the target.

    Subclasses should also initialize:

    ``self._data_layout``: the data layout for the target.
    ``self._target_data``: the binding layer ``TargetData`` for the target.
    c                 C   re   )zD
        Create a new empty module suitable for the target.
        Nr   r  r   r   r   r   q  rh   zCodegen._create_empty_modulec                 C   re   )zu
        Add a module to the execution engine. Ownership of the module is
        transferred to the engine.
        Nr   r  r   r   r   rF  w  rh   zCodegen._add_modulec                 C   r   )zJ
        The LLVM "target data" object for this codegen instance.
        )_target_datar   r   r   r   target_data~  r   zCodegen.target_datac                 K   s   | j | |fi |S )zb
        Create a :class:`CodeLibrary` object for use with this codegen
        instance.
        )_library_class)rE   r?   rD   r   r   r   re    s   zCodegen.create_libraryc                 C   s   | j | |S r=   )r  rj  )rE   Z
serializedr   r   r   unserialize_library  s   zCodegen.unserialize_libraryN)r   r   r   r   r   r   rF  r  r  re  r  r   r   r   r   r  f  s    



r  c                   @   sl   e Z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S )r   c                 C   sB   t   d | _tt| || _d| j_t | _	| 
| j d S )NZglobal_codegen_module)initialize_llvmr  r   r  r   r   _llvm_moduler?   ry  	_rtlinker_init)rE   module_namer   r   r   rG     s   zCPUCodegen.__init__c                 C   s   t |jg ksJ dtjt }ttjd}| 	 | _
| | |jdi |}tj}tj|||d}tjr=|  || _t|| _|j| _t| j| _tjjrZd| _d| _nd| _d| _| j| jj| jj d S )	NzModule isn't empty)r'  )use_lmmT   Fr   r   )listr>  r   TargetZfrom_tripleget_process_tripler[   r   OPT_customize_tm_features_tm_features_customize_tm_optionscreate_target_machineZUSE_LLVMLITE_MEMORY_MANAGERZcreate_mcjit_compilerZENABLE_PROFILINGZenable_jit_eventsrK  r  rf  r  r  r   r  Z
is_opt_maxr*  r+  r  r  r]  r^  )rE   Zllvm_moduler   Z
tm_optionstmr  r  r   r   r   r    s,   


zCPUCodegen._initc                 C   s,   t t|}t |_| jr| j|_|S r=   )	r4  r5  r   r  r   r  r   r  r  r   r   r   r   r     s
   
zCPUCodegen._create_empty_modulec                 K   sp   | dd }| jdi |}| }|d ur+|dkr+tjdkr+|  |  |  tjr4|	t
  ||fS )Nr(  r$  r   r   )pop_pass_builderZgetModulePassManagerr   r  Zadd_loop_rotate_passZadd_instruction_combine_passZadd_jump_threading_passr,  add_refprune_passr$   )rE   rD   r(  r"  pmr   r   r   r)    s   zCPUCodegen._module_pass_managerc                 K   s2   | j di |}| }tjr|t  ||fS )Nr   )r  ZgetFunctionPassManagerr   r,  r  r$   )rE   rD   r"  r  r   r   r   r    s
   z!CPUCodegen._function_pass_managerc                 K   sH   | dtj}| dtj}| dtj}t| jf|||d|}|S )Nr'  r%  r&  )r'  r%  r&  )r  r   r  ZLOOP_VECTORIZEZSLP_VECTORIZEr   rK  )rE   rD   	opt_levelr%  r&  r"  r   r   r   r    s   
zCPUCodegen._pass_builderc                 C   sV   d}t |}t|}d|v sd|v rdS d|v r$t }td|f td|f )z<
        Guard against some well-known LLVM bug(s).
        zo
            define double @func()
            {
                ret double 1.23e+01
            }
            z12.3z1.23Nz1.0zLLVM will produce incorrect floating-point code in the current locale %s.
Please read https://numba.readthedocs.io/en/stable/user/faq.html#llvm-locale-bug for more information.zUnexpected IR:
%s
)r   r  r   locale	getlocaler   rA  )rE   r8  r2  Zir_outlocr   r   r   r:    s   	
zCPUCodegen._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CPUCodegen.magic_tuplec                 C   s.   | j || j | j | | j | j d S r=   )r  r  rf  r  r  r  r   r   r   rw    s   z(CPUCodegen._scan_and_fix_unresolved_refsc                 C   sn   t d }| jj| }|j}z||}W n ty+   t j|||d}d|_	Y nw |
||| S )N   rQ  r0  )r4  ZIntTypeZ
as_pointerr  r}  r  Z
get_globalKeyErrorZGlobalVariabler/  Zbitcastload)rE   ZbuilderZfntyr?   ZvoidptrZptrnameZllvm_modr  r   r   r   insert_unresolved_ref  s   
z CPUCodegen.insert_unresolved_refc                 C   s   t jd u r	t S t jS r=   )r   ZCPU_NAMEr   Zget_host_cpu_namer   r   r   r   r  &  s   
zCPUCodegen._get_host_cpu_namec                 C   s   t jd urt jS t S r=   )r   ZCPU_FEATURESget_host_cpu_featuresr   r   r   r   _get_host_cpu_features+  s   
z!CPUCodegen._get_host_cpu_featuresN)r   r   r   rG   r  r   r)  r  r  r:  r  rw  r  r  r  r   r   r   r   r     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 Nr   )	_cpu_namer   rG   )rE   r  cpu_namer   r   r   rG   9  s   
zAOTCPUCodegen.__init__c                 C   s<   | j }|dkr|  }||d< d|d< d|d< | j|d< d S )Nhostcpupicrelocr   	codemodelfeatures)r  r  r  )rE   optionsr  r   r   r   r  >  s   z#AOTCPUCodegen._customize_tm_optionsc                 C   re   r  r   r   r   r   r   r  G  s   z$AOTCPUCodegen._customize_tm_featuresc                 C   rp  r=   r   r  r   r   r   rF  L  rq  zAOTCPUCodegen._add_moduler=   )
r   r   r   r   rm  r  rG   r  r  rF  r   r   r   r   r  1  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   s~   |   |d< tj j}|drd}n
|drd}nd}||d< d|d	< | j|d
< ttjj	}d|j
v r=d|d< d S d S )Nr  r   Zstaticppcr  r   r  Z
jitdefaultr  r  ZjitT)r  r   r  Zfrom_default_tripler?   r?  r  r   Zpysignaturer  
parameters)rE   r  r   Zreloc_modelsigr   r   r   r  W  s   



z#JITCPUCodegen._customize_tm_optionsc                 C   s   |   S r=   )r  r   r   r   r   r  r  s   z$JITCPUCodegen._customize_tm_featuresc                 C   s   | j | d S r=   )rf  r  r  r   r   r   rF  v  r   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*.
        rs   r   N)rf  r  r~  r  from_addressr   )rE   env_nameenvZgvaddrZenvptrr   r   r   set_env~  s   zJITCPUCodegen.set_envN)
r   r   r   r   rr  r  r  r  rF  r  r   r   r   r   r  P  s    r  c                   C   s   t   t   dS )z Safe to use multiple times.
    N)r   Zinitialize_native_targetZinitialize_native_asmprinterr   r   r   r   r    s   r  c                  C   sL   zt  } W n
 ty   Y dS w tjs"| D ]}|dr!d| |< q|  S )z~Get host CPU features using LLVM.

    The features may be modified due to user setting.
    See numba.config.ENABLE_AVX.
    r   ZavxF)r   r  r   r   Z
ENABLE_AVXr?  flatten)r  rb   r   r   r   r    s   
r  )6r   r  r  rC  r~  r   r   Zllvmlite.bindingrI   r   Zllvmlite.irr8  r4  abcr   r   Z
numba.corer   r   r   Znumba.core.llvm_bindingsr   Znumba.core.runtime.nrtoptr   Znumba.core.runtimer	   Znumba.core.compiler_lockr
   Znumba.core.errorsr   Znumba.misc.inspectionr   Znumba.misc.llvm_pass_timingsr   	frozensetr   r   r$   r;   rb  r<   r   r  rm  rr  ry  r  r  r  r   r  r  r  r  r   r   r   r   <module>   sT       6{  <77* "8