o
    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i386i486i586i686i786i886i986c                 C   s   |  dd }|tv S )N-r   )split_x86arch)triplearch r   P/home/ubuntu/transcripts/venv/lib/python3.10/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   LLVM_REFPRUNE_FLAGSr   stripgetattrll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/   r0   r,   lexerr   r   printerH   s   


zdump.<locals>.printerzP================================================================================P   r   )r   HIGHLIGHT_DUMPSpygmentsImportError
ValueErrorr,   pygments.lexersr-   r.   pygments.formattersr/   numba.misc.dump_styler0   r4   center)	headerbodylangr;   msg	gas_lexer
llvm_lexer	lexer_mapr8   r   r6   r   dump8   s(   
rI   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)selfrL   rM   rN   rR   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itemsr=   settype)_configkwargattrkvrE   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>orangemarkeryellowrc   greentruebrredfalsebrcyanr[   	turquoiser\   	lightpinkraiselightseagreenr_   purplereturn	rosybrownra   tomatorb   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mdmetadata_entryxr   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)rankdirnodenonez%s)shapefontsize)r   r&   r'   r   Digraphro   str)rM   fnamer   cmax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;)r   r   hashformathtmlescapereplace)r   nhsr   r   r   clean   s   
z"_CFG.pretty_printer.<locals>.cleanz\l... dot_json)r   utf-8objects)r   labelrM   _gvidr   r   z\l|z<<td BGCOLOR="{}" BORDER="1" ALIGN="center" PORT="{}">{}</td>)TFrt   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.
                Nr   r   r   zMarker %s, Line %s, column %srx   rc   )	r   r   r   getrd   r   appendrc   int)l	new_linesmatchedr   rx   
debug_dataldlinecolmfmt	mark_linelnlidxsource_line)_interleaver   col_spancscur_colcur_linefirstlinenofmtlocation_entryr   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   edgestailportheadtailr   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inspectllvmliterW   numba.typedrX   typesrY   collectionsrZ   rL   rO   rM   get_llvm_strr   rc   getsourcelinesrN   rP   r   Sourcepipeloadsdecoder   r   r   r   r`   r   r   r   joinr    rd   r[   searchr\   r_   r^   r]   ra   rb   r   rj   edgerender)KrS   r   r   render_formatr,   
interleavestrip_irshow_keyr   r   r   r"   rX   rY   rZ   _default
_highlightrr   rT   r   r   r   r   
port_matchport_jmp_matchlocation_expr	dbg_value
nrt_incref
nrt_decrefnrt_meminfoll_intrin_callsll_function_callll_raise	ll_returnr   node_idsedge_idsraw_dot
json_bytesjzonidcobjr   rM   gvidlinesr   	port_liner   sliced_linesportsports_tokenstdfmttbl_datacolorstoktargetvaluecolor	fmtheaderr   r   updated_lineinfocolourr   dattabr   tpr   r   portkey_tabrp   rq   r   )r   r   r   r   r   r   r   r   r   r   r   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!  rR   r   )rS   r   r   r   rawbytr   r   r   display  s   


z_CFG.displayc                 C   s   | j di | jdS )Nr   r   r#  rS   r   r   r   
_repr_svg_  s   z_CFG._repr_svg_c                 C      | j S rK   )rQ   r&  r   r   r   __repr__  s   z_CFG.__repr__)NNNTFFTrV   )Nr"  F)	__name__
__module____qualname____doc__rU   r!  r%  r'  r)  r   r   r   r   rJ   S   s    
   
rJ   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
CPUCodegenrM   c                 C   s>   || _ || _| jj d| jd}t|| _g | _t | _d S )N())	_codegen_name	__class__r*  r   _recorded_timings_dynamic_globalsrk   _reload_init)rS   r/  rM   ptc_namer   r   r   rU     s   
zCodeLibrary.__init__c                 C   s   |    t| jdkS )Nr   )_ensure_finalizedr   r7  r&  r   r   r   has_dynamic_globals  s   zCodeLibrary.has_dynamic_globalsc                 C   r(  rK   )r6  r&  r   r   r   recorded_timings      zCodeLibrary.recorded_timingsc                 C   r(  )z9
        The codegen object owning this library.
        )r3  r&  r   r   r   r/  $     zCodeLibrary.codegenc                 C   r(  rK   )r4  r&  r   r   r   rM   +  r=  zCodeLibrary.namec                 C   s   d| j t| f S )Nz<Library %r at 0x%x>)rM   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_finalized2  s
   zCodeLibrary._raise_if_finalizedc                 C   s   | j s	|   d S d S rK   )r@  finalizer&  r   r   r   r:  7  s   zCodeLibrary._ensure_finalizedc                 C   s   |    | j|}|S )zC
        Create an LLVM IR module for use by this library.
        )rB  r3  _create_empty_modulerS   rM   	ir_moduler   r   r   create_ir_module;  s   zCodeLibrary.create_ir_modulec                 C   rs   )zk
        Add a library for linking into this library, without losing
        the original library.
        Nr   rS   libraryr   r   r   add_linking_libraryC  rv   zCodeLibrary.add_linking_libraryc                 C   rs   )zC
        Add an LLVM IR module's contents to this library.
        Nr   )rS   rF  r   r   r   add_ir_moduleJ  rv   zCodeLibrary.add_ir_modulec                 C   rs   )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   rC  P  rv   zCodeLibrary.finalizec                 C   rs   )z5
        Return the function named ``name``.
        Nr   rS   rM   r   r   r   rO   X  rv   zCodeLibrary.get_functionc                 C   rs   )zA
        Get the human-readable form of the LLVM module.
        Nr   r&  r   r   r   r   ^  rv   zCodeLibrary.get_llvm_strc                 C   rs   )z2
        Get the human-readable assembly.
        Nr   r&  r   r   r   get_asm_strd  rv   zCodeLibrary.get_asm_strc                 C   s   d| _ d | _d| _d S )NTF)_object_caching_enabled_compiled_object	_compiledr&  r   r   r   enable_object_cachingn  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)rN  r=   rO  rA  r&  r   r   r   _get_compiled_objects  s
   
z CodeLibrary._get_compiled_objectc                 C   s8   | j s
td| f | jrtd| f || _d| _d S )NrR  zlibrary already compiled: %sT)rN  r=   rP  rO  _disable_inspection)rS   r  r   r   r   _set_compiled_objectz  s   
z CodeLibrary._set_compiled_objectN)r*  r+  r,  r-  r@  rN  rT  r   rU   propertyr;  r<  r/  rM   r)  rB  r:  rG  r   rJ  rK  rC  rO   r   rM  rQ  rS  rU  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 rK   )superrU   _linking_librariesr"   parse_assemblyr   r3  rD  rM   _final_moduler   normalize_ir_text_shared_module)rS   r/  rM   r5  r   r   rU     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)	r3  _data_layoutdata_layout	functions_function_pass_managerrM   r6  recordrun)rS   	ll_modulefuncfpmpbrp   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))r3  _module_pass_manager	_loopvect
_opt_levelr6  rd  re  r\  r   LLVM_REFPRUNE_PASSr   )rS   	mpm_cheap	mpb_cheapmpm_fullmpb_full
cheap_name	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   r   z7library unfit for linking: no available functions in %slinkonce_odr)r:  r^  r\  rb  is_declarationlinkager"   Linkageexternalr   rM   rA  clonerO   )rS   modto_fixnfuncsrT   rM   r   r   r   _get_module_for_linking  s*   	

z&CPUCodeLibrary._get_module_for_linkingc                 C   s   |   | j| d S rK   )r:  rZ  r   rH  r   r   r   rJ    s   z"CPUCodeLibrary.add_linking_libraryc                 C   sN   |    t|tjsJ tt|}t|}|j	|_	|
  | | d S rK   )rB  re   llvmirModuler   r]  r   r"   r[  rM   verifyadd_llvm_module)rS   rF  irrf  r   r   r   rK    s   
zCPUCodeLibrary.add_ir_modulec                 C   s(   |  | tjst|}| j| d S rK   )rj  r   rs  r   r\  link_in)rS   rf  r   r   r   r    s   
zCPUCodeLibrary.add_llvm_modulec                 C   s   t   | j  |   tjrtd| j |  d t	 }| j
D ]}||vr<| j|j || | jj| dd q |   | j  |   d S )NzFUNCTION OPTIMIZED DUMP %sr1   T)preserve)r
   r3  _check_llvm_bugsrB  r   DUMP_FUNC_OPTrI   rM   r   rk   rZ  r8  updateaddr\  r  r  rz  r  _finalize_final_module)rS   seenrI  r   r   r   rC    s&   




zCPUCodeLibrary.finalizec                 C   s,   | j jD ]}|jdr| j|j qd S )Nznumba.dynamic.globals)r\  global_variablesrM   
startswithr7  r   )rS   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 )N	_ZN5numbazSymbol {} not linked properly)r\  rb  r|  rM   r  AssertionErrorr   )rS   rT   rE   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 %sr1   zASSEMBLY %sr2   N)r  r  weakrefproxyr\  _CPUCodeLibrary__libraryr3  _add_modulerC  _finalize_specificr@  r   DUMP_OPTIMIZEDrI   rM   r   DUMP_ASSEMBLYrM  )rS   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\  rb  r|  )rS   r  rT   r   r   r   get_defined_functions2  s   
z$CPUCodeLibrary.get_defined_functionsc                 C   s   | j |S rK   )r\  rO   rL  r   r   r   rO   <  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.)rT  r&   r'   r&  r   r   r    _sentry_cache_disable_inspection?  s   z/CPUCodeLibrary._sentry_cache_disable_inspectionc                 C   s   |    t| jS rK   )r  r   r\  r&  r   r   r   r   D  s   
zCPUCodeLibrary.get_llvm_strc                 C   s   |    t| jj| jS rK   )r  r   r3  _tmemit_assemblyr\  r&  r   r   r   rM  H  s   zCPUCodeLibrary.get_asm_strNc                 K   s   |    t| ||fi |S )z=
        Get control-flow graph of the LLVM function
        )r  rJ   )rS   rM   rN   rR   r   r   r   rP   L  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.
        )rS  r   )rS   mangled_nameelfr   r   r   get_disasm_cfgS  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:sh_type
SHT_SYMTABc                 S   r(  rK   rM   )symr   r   r   ru   m  s    z*CPUCodeLibrary._dump_elf.<locals>.<lambda>)keyz    symbols:z/    - %r: size=%d, value=0x%x, type=%s, bind=%sst_sizest_valuest_inforl   bindN)elftools.elf.elffiler  elftools.elfr  ior  r4   iter_sectionssortediter_symbolsrM   r   describe_symbol_typedescribe_symbol_bind)	clsbufr  r  r  r   secsymbolsr  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)r  r%   rN  rP  rO  )r  rf  r  rS   r   r   r   _object_compiled_hook{  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)r  r%   rN  rO  )r  rf  rS   r  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:  rM   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:  rS  r  r  rM   )rS   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  r  z!unsupported serialization kind %r)create_libraryre   r"   parse_bitcoder\  r  rQ  rU  r^  r3  _engine_load_defined_symbolsr=   )	r  r/  staterM   kindr  rS   object_codeshared_bitcoder   r   r   _unserialize  s    


zCPUCodeLibrary._unserializerK   )r*  r+  r,  rU   rj  rz  r  rJ  rK  r  rC  r  r  r  r  rO   r  r   rM  rP   r  classmethodr  r  r  r  r  r  __classcell__r   r   r_  r   rX    s:    #	




rX  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:  r3  r  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 rK   r   r&  r   r   r   r       z!AOTCodeLibrary._finalize_specificN)r*  r+  r,  r  r  r  r   r   r   r   r    s    
	r  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:  r3  r  is_symbol_definedget_function_address)rS   rM   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)r3  _scan_and_fix_unresolved_refsr\  r6  record_legacyr  finalize_objectr&  r   r   r   r    s   "z!JITCodeLibrary._finalize_specificN)r*  r+  r,  r  r  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 rK   )r   
UniqueDict_unresolvedrk   _defined	_resolvedr&  r   r   r   rU     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.
        Nnrt_unresolved_abort)PREFIXr  rM   r  r   r  r	   rI  r  ctypesc_void_padd_global_mapping	addressofr  )rS   moduleengineprefixr   r  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)rb  r|  r  r  rM   )rS   r  rT   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  ).0rM   r&  r   r   
<listcomp>   s    z)RuntimeLinker.resolve.<locals>.<listcomp>N)r  r  r  r  r   )rS   r  pendingrM   fnptrr  r   r&  r   resolve  s   


zRuntimeLinker.resolveN)	r*  r+  r,  r-  r  rU   r  r  r  r   r   r   r   r    s    r  c                    s   t   fdd}|S )Nc                    s    | j g|R i |S rK   )_ee)rS   argsrR   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 rK   )r  rk   _defined_symbols)rS   r  r   r   r   rU   8  s   
zJitEngine.__init__c                 C   s
   || j v S )z/Is the symbol defined in this session?
        )r  rL  r   r   r   r  E  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|  rM   )r  r   r   r   r   	<setcomp>N  s    z2JitEngine._load_defined_symbols.<locals>.<setcomp>N)rb  r  r  )rS   r  gsetsr   r   r   r  J  s   zJitEngine._load_defined_symbolsc                 C   s   |  | | j|S )zXOverride ExecutionEngine.add_module
        to keep info about defined symbols.
        )r  r  
add_modulerS   r  r   r   r   r  Q  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  rM   r  r  )rS   r   addrr   r   r   r  X  s   zJitEngine.add_global_mappingN)r*  r+  r,  r-  rU   r  r  r  r  r  r"   ExecutionEngineset_object_cacher  r  get_global_value_addressr   r   r   r   r   3  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   rs   )zD
        Create a new empty module suitable for the target.
        Nr   rL  r   r   r   rD  u  rv   zCodegen._create_empty_modulec                 C   rs   )zu
        Add a module to the execution engine. Ownership of the module is
        transferred to the engine.
        Nr   r  r   r   r   r  {  rv   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)rS   rM   rR   r   r   r   r    s   zCodegen.create_libraryc                 C   s   | j | |S rK   )r  r  )rS   
serializedr   r   r   unserialize_library  s   zCodegen.unserialize_libraryN)r*  r+  r,  r-  r   rD  r  rV  r  r  r  r   r   r   r   r
  j  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 )r0  c                 C   sB   t   d | _tt| || _d| j_t | _	| 
| j d S )Nglobal_codegen_module)initialize_llvmr`  r"   r[  r   rD  _llvm_modulerM   r  	_rtlinker_init)rS   module_namer   r   r   rU     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)rn  )use_lmmT   Fr   r   )listr  r"   Targetfrom_tripleget_process_tripleri   r   OPT_customize_tm_features_tm_features_customize_tm_optionscreate_target_machineUSE_LLVMLITE_MEMORY_MANAGERcreate_mcjit_compilerENABLE_PROFILINGenable_jit_eventsr  r   r  r  r  r   r`  
is_opt_maxrq  rr  r  r  r  r  )rS   llvm_moduler  
tm_optionstmr  r  r   r   r   r    s,   


zCPUCodegen._initc                 C   s,   t t|}t |_| jr| j|_|S rK   )	r  r  r   r]  r"   r  r   r`  ra  rE  r   r   r   rD    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 )Nro  rk  r   r   )pop_pass_buildergetModulePassManagerr   r  add_loop_rotate_passadd_instruction_combine_passadd_jump_threading_passrs  add_refprune_passr+   )rS   rR   ro  ri  pmr   r   r   rp    s   zCPUCodegen._module_pass_managerc                 K   s2   | j di |}| }tjr|t  ||fS )Nr   )r*  getFunctionPassManagerr   rs  r/  r+   )rS   rR   ri  r0  r   r   r   rc    s
   z!CPUCodegen._function_pass_managerc                 K   sH   | dtj}| dtj}| dtj}t| jf|||d|}|S )Nrn  rl  rm  )rn  rl  rm  )r)  r   r  LOOP_VECTORIZESLP_VECTORIZEr   r  )rS   rR   	opt_levelrl  rm  ri  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	getlocalerA  r  )rS   r  r  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 rK   )r  r  r  r  r  r  r   r   r   r    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   r  r  )r  IntType
as_pointerr  r  r  
get_globalKeyErrorGlobalVariabler}  bitcastload)rS   builderfntyrM   voidptrptrname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 rK   )r   CPU_NAMEr"   get_host_cpu_namer&  r   r   r   r9  *  s   
zCPUCodegen._get_host_cpu_namec                 C   s   t jd urt jS t S rK   )r   CPU_FEATURESget_host_cpu_featuresr&  r   r   r   _get_host_cpu_features/  s   
z!CPUCodegen._get_host_cpu_featuresN)r*  r+  r,  rU   r  rD  rp  rc  r*  r  r:  r  rH  r9  rM  r   r   r   r   r0    s    
(r0  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_namer0  rU   )rS   r  cpu_namer   r   r   rU   =  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)rP  r9  r  )rS   optionsrQ  r   r   r   r  B  s   z#AOTCPUCodegen._customize_tm_optionsc                 C   rs   rO  r   r&  r   r   r   r  K  s   z$AOTCPUCodegen._customize_tm_featuresc                 C   r  rK   r   r  r   r   r   r  P  r  zAOTCPUCodegen._add_modulerK   )
r*  r+  r,  r-  r  r  rU   r  r  r  r   r   r   r   rN  5  s    
	rN  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 )NrS  r   staticppcrT  r   rU  
jitdefaultrV  rW  jitT)r9  r"   r  from_default_triplerM   r  r  r   pysignaturer   
parameters)rS   rX  r   reloc_modelsigr   r   r   r  [  s   



z#JITCPUCodegen._customize_tm_optionsc                 C   s   |   S rK   )rM  r&  r   r   r   r  v  s   z$JITCPUCodegen._customize_tm_featuresc                 C   s   | j | d S rK   )r  r  r  r   r   r   r  z  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*.
        r   r   N)r  r	  r  r  from_addressr?  )rS   env_nameenvgvaddrenvptrr   r   r   set_env  s   zJITCPUCodegen.set_envN)
r*  r+  r,  r-  r  r  r  r  r  rh  r   r   r   r   rY  T  s    rY  c                   C   s   t   t   dS )z Safe to use multiple times.
    N)r"   initialize_native_target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   avxF)r"   rL  rA  r   
ENABLE_AVXr  flatten)rW  rp   r   r   r   rL    s   
rL  )6r&   r  r5  r  r  r   r   llvmlite.bindingrW   r"   llvmlite.irr  r  abcr   r   
numba.corer   r   r   numba.core.llvm_bindingsr   numba.core.runtime.nrtoptr   numba.core.runtimer	   numba.core.compiler_lockr
   numba.core.errorsr   numba.misc.inspectionr   numba.misc.llvm_pass_timingsr   	frozensetr   r   r+   rI   r  rJ   r.  rX  r  r  r  r  r   r
  r0  rN  rY  r  rL  r   r   r   r   <module>   sT       6}  >77* "8