U
    +d	<                     @   s  d dl mZmZmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlZd dlmZ d dlmZ edd	ZG d
d deZG dd deZd ddZdd Zdd Zdd Zdd ZG dd de
ZG dd dejZG dd deZG dd deZejej j!_"ej#gej j$_%ejej j$_"ejgej j&_%ejej#gej j'_%eej j'_"ejej#eeegej j(_%eej j(_"ejgej j)_%eej j)_"ejgej j*_%eej j*_"ejej+gej j,_%eej j,_"ejej+eeegej j-_%eej j-_"ejgej j._%ejgej j/_%ejgej j0_%ejegej j1_%ejgej j2_%ejgej j3_%ejgej j4_%ejgej j5_%ejgej j6_%ejgej j7_%ejgej j8_%ejgej j9_%ejgej j:_%ejgej j;_%ejgej j<_%ejgej j=_%ejeegej j>_%dS )!    )c_boolc_char_pc_intc_size_t	Structurebyref)
namedtuple)IntFlag)ffiN)mkstemp)_encode_string
PruneStatsz&basicblock diamond fanout fanout_raisec                   @   s    e Zd ZdZdd Zdd ZdS )r   z4 Holds statistics from reference count pruning.
    c                 C   sN   t |ts d}t|t|t| j|j | j|j | j|j | j|j S )Nz;PruneStats can only be added to another PruneStats, got {}.	
isinstancer   	TypeErrorformattype
basicblockdiamondfanoutfanout_raiseselfothermsg r   A/tmp/pip-unpacked-wheel-stw2luzp/llvmlite/binding/passmanagers.py__add__   s    



zPruneStats.__add__c                 C   sN   t |ts d}t|t|t| j|j | j|j | j|j | j|j S )NzBPruneStats can only be subtracted from another PruneStats, got {}.r   r   r   r   r   __sub__   s    



zPruneStats.__sub__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   	c                   @   s(   e Zd ZdefdefdefdefgZdS )_c_PruneStatsr   r   r   r   N)r   r    r!   r   _fields_r   r   r   r   r#   %   s
   r#   Fc                 C   s>   t dddd}t| }tjt|| t|j|j|j	|j
S )z Returns a namedtuple containing the current values for the refop pruning
    statistics. If kwarg `printout` is True the stats are printed to stderr,
    default is False.
    r   )r#   r   r
   libZLLVMPY_DumpRefPruneStatsr   r   r   r   r   r   )ZprintoutstatsZdo_printr   r   r   dump_refprune_stats-   s    r'   c                 C   s   t jt|  dS )zEnable or disable the pass timers.

    Parameters
    ----------
    enable : bool
        Set to True to enable the pass timers.
        Set to False to disable the pass timers.
    N)r
   r%   ZLLVMPY_SetTimePassesr   )enabler   r   r   set_time_passes;   s    	r)   c               
   C   s4   t  "} t j|  t| W  5 Q R  S Q R X dS )a  Returns the pass timings report and resets the LLVM internal timers.

    Pass timers are enabled by ``set_time_passes()``. If the timers are not
    enabled, this function will return an empty string.

    Returns
    -------
    res : str
        LLVM generated timing report.
    N)r
   OutputStringr%   ZLLVMPY_ReportAndResetTimingsstr)bufr   r   r   report_and_reset_timingsG   s    
r-   c                   C   s   t  S N)ModulePassManagerr   r   r   r   create_module_pass_managerW   s    r0   c                 C   s   t | S r.   )FunctionPassManager)moduler   r   r   create_function_pass_manager[   s    r3   c                   @   s,   e Zd ZdZdZdZdZeeB eB eB ZdS )RefPruneSubpasses            N)r   r    r!   ZPER_BBZDIAMONDZFANOUTZFANOUT_RAISEALLr   r   r   r   r4   _   s
   r4   c                   @   s   e Zd 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d Zdd Zdd Zd d! Zd"d# Zd$d% Zejd&fd'd(Zd)S )*PassManagerzPassManager
    c                 C   s   | j |  d S r.   )Z_capiLLVMPY_DisposePassManagerr   r   r   r   _disposek   s    zPassManager._disposec                 C   s   t j|  dS )zQSee http://llvm.org/docs/Passes.html#constmerge-merge-duplicate-global-constants.N)r
   r%   LLVMPY_AddConstantMergePassr<   r   r   r   add_constant_merge_passn   s    z#PassManager.add_constant_merge_passc                 C   s   t j|  dS )zKSee http://llvm.org/docs/Passes.html#deadargelim-dead-argument-elimination.N)r
   r%    LLVMPY_AddDeadArgEliminationPassr<   r   r   r   add_dead_arg_elimination_passr   s    z)PassManager.add_dead_arg_elimination_passc                 C   s   t j|  dS )zNSee http://llvm.org/docs/Passes.html#functionattrs-deduce-function-attributes.N)r
   r%   LLVMPY_AddFunctionAttrsPassr<   r   r   r   add_function_attrs_passv   s    z#PassManager.add_function_attrs_passc                 C   s   t j| | dS )zJSee http://llvm.org/docs/Passes.html#inline-function-integration-inlining.N)r
   r%   LLVMPY_AddFunctionInliningPass)r   	thresholdr   r   r   add_function_inlining_passz   s    z&PassManager.add_function_inlining_passc                 C   s   t j|  dS )zGSee http://llvm.org/docs/Passes.html#globaldce-dead-global-elimination.N)r
   r%   LLVMPY_AddGlobalDCEPassr<   r   r   r   add_global_dce_pass~   s    zPassManager.add_global_dce_passc                 C   s   t j|  dS )zISee http://llvm.org/docs/Passes.html#globalopt-global-variable-optimizer.N)r
   r%   LLVMPY_AddGlobalOptimizerPassr<   r   r   r   add_global_optimizer_pass   s    z%PassManager.add_global_optimizer_passc                 C   s   t j|  dS )zdSee http://llvm.org/docs/Passes.html#ipsccp-interprocedural-sparse-conditional-constant-propagation.N)r
   r%   LLVMPY_AddIPSCCPPassr<   r   r   r   add_ipsccp_pass   s    zPassManager.add_ipsccp_passc                 C   s   t j|  dS )z?See http://llvm.org/docs/Passes.html#dce-dead-code-elimination.N)r
   r%   !LLVMPY_AddDeadCodeEliminationPassr<   r   r   r   add_dead_code_elimination_pass   s    z*PassManager.add_dead_code_elimination_passc                 C   s   t j|  dS )zBSee http://llvm.org/docs/Passes.html#simplifycfg-simplify-the-cfg.N)r
   r%   LLVMPY_AddCFGSimplificationPassr<   r   r   r   add_cfg_simplification_pass   s    z'PassManager.add_cfg_simplification_passc                 C   s   t j|  dS )z@See http://llvm.org/docs/Passes.html#gvn-global-value-numbering.N)r
   r%   LLVMPY_AddGVNPassr<   r   r   r   add_gvn_pass   s    zPassManager.add_gvn_passc                 C   s   t j|  dS )z8See http://llvm.org/docs/Passes.html#passes-instcombine.N)r
   r%   "LLVMPY_AddInstructionCombiningPassr<   r   r   r   add_instruction_combining_pass   s    z*PassManager.add_instruction_combining_passc                 C   s   t j|  dS )zESee http://llvm.org/docs/Passes.html#licm-loop-invariant-code-motion.N)r
   r%   LLVMPY_AddLICMPassr<   r   r   r   add_licm_pass   s    zPassManager.add_licm_passc                 C   s   t j|  dS )zRSee http://llvm.org/docs/Passes.html#sccp-sparse-conditional-constant-propagation.N)r
   r%   LLVMPY_AddSCCPPassr<   r   r   r   add_sccp_pass   s    zPassManager.add_sccp_passc                 C   s   t j|  dS )zSee http://llvm.org/docs/Passes.html#scalarrepl-scalar-replacement-of-aggregates-dt.
        Note that this pass corresponds to the ``opt -sroa`` command-line option,
        despite the link above.N)r
   r%   LLVMPY_AddSROAPassr<   r   r   r   add_sroa_pass   s    zPassManager.add_sroa_passc                 C   s   t j|  d S r.   )r
   r%   $LLVMPY_AddTypeBasedAliasAnalysisPassr<   r   r   r   "add_type_based_alias_analysis_pass   s    z.PassManager.add_type_based_alias_analysis_passc                 C   s   t j|  dS )z=See http://llvm.org/docs/AliasAnalysis.html#the-basicaa-pass.N)r
   r%    LLVMPY_AddBasicAliasAnalysisPassr<   r   r   r   add_basic_alias_analysis_pass   s    z)PassManager.add_basic_alias_analysis_passc                 C   s   t j|  dS )z:http://llvm.org/docs/Passes.html#loop-rotate-rotate-loops.N)r
   r%   ZLLVMPY_LLVMAddLoopRotatePassr<   r   r   r   add_loop_rotate_pass   s    z PassManager.add_loop_rotate_passi  c                 C   s   t |}tj| || dS )a  Add Numba specific Reference count pruning pass.

        Parameters
        ----------
        subpasses_flags : RefPruneSubpasses
            A bitmask to control the subpasses to be enabled.
        subgraph_limit : int
            Limit the fanout pruners to working on a subgraph no bigger than
            this number of basic-blocks to avoid spending too much time in very
            large graphs. Default is 1000. Subject to change in future
            versions.
        N)r4   r
   r%   LLVMPY_AddRefPrunePass)r   Zsubpasses_flagsZsubgraph_limitZiflagsr   r   r   add_refprune_pass   s    zPassManager.add_refprune_passN)r   r    r!   r"   r=   r?   rA   rC   rF   rH   rJ   rL   rN   rP   rR   rT   rV   rX   rZ   r\   r^   r_   r4   r9   ra   r   r   r   r   r:   g   s,   r:   c                   @   s*   e Zd Zd
ddZdddZddd	ZdS )r/   Nc                 C   s"   |d krt j }t| | d S r.   )r
   r%   LLVMPY_CreatePassManagerr:   __init__)r   ptrr   r   r   rc      s    
zModulePassManager.__init__yaml c                 C   sR   |dkrt j| |S t j| |t|t|t|}|dkrFtd|dkS dS )a  
        Run optimization passes on the given module.

        Parameters
        ----------
        module : llvmlite.binding.ModuleRef
            The module to be optimized inplace
        remarks_file : str; optional
            If not `None`, it is the file to store the optimization remarks.
        remarks_format : str; optional
            The format to write; YAML is default
        remarks_filter : str; optional
            The filter that should be applied to the remarks output.
        N"Failed to initialize remarks file.r   )r
   r%   LLVMPY_RunPassManager LLVMPY_RunPassManagerWithRemarksr   IOError)r   r2   remarks_fileremarks_formatremarks_filterrr   r   r   run   s      zModulePassManager.runc              
   C   s   t  \}}zlt|d W 5 Q R X | ||||}|dkrDtdt|"}t|| fW  5 Q R  W S Q R X W 5 t| X dS )a  
        Run optimization passes on the given module and returns the result and
        the remarks data.

        Parameters
        ----------
        module : llvmlite.binding.ModuleRef
            The module to be optimized
        remarks_format : str
            The remarks output; YAML is the default
        remarks_filter : str; optional
            The filter that should be applied to the remarks output.
        ro   rg   rh   N	r   osunlinkfdopenrp   rk   openboolread)r   r2   rm   rn   
remarkdesc
remarkfilero   fr   r   r   run_with_remarks   s    


*z"ModulePassManager.run_with_remarks)N)Nre   rf   )re   rf   )r   r    r!   rc   rp   r{   r   r   r   r   r/      s   
  
  r/   c                   @   s8   e Zd Zdd Zdd Zdd Zdd
dZdddZdS )r1   c                 C   s(   t j|}|| _d|_t| | d S )NT)r
   r%    LLVMPY_CreateFunctionPassManager_moduleZ_ownedr:   rc   )r   r2   rd   r   r   r   rc     s    zFunctionPassManager.__init__c                 C   s   t j| S )zk
        Initialize the FunctionPassManager.  Returns True if it produced
        any changes (?).
        )r
   r%   $LLVMPY_InitializeFunctionPassManagerr<   r   r   r   
initialize  s    zFunctionPassManager.initializec                 C   s   t j| S )zi
        Finalize the FunctionPassManager.  Returns True if it produced
        any changes (?).
        )r
   r%   "LLVMPY_FinalizeFunctionPassManagerr<   r   r   r   finalize  s    zFunctionPassManager.finalizeNre   rf   c                 C   sR   |dkrt j| |S t j| |t|t|t|}|dkrFtdt|S dS )a  
        Run optimization passes on the given function.

        Parameters
        ----------
        function : llvmlite.binding.FunctionRef
            The function to be optimized inplace
        remarks_file : str; optional
            If not `None`, it is the file to store the optimization remarks.
        remarks_format : str; optional
            The format of the remarks file; the default is YAML
        remarks_filter : str; optional
            The filter that should be applied to the remarks output.
        Nrg   rh   )r
   r%   LLVMPY_RunFunctionPassManager(LLVMPY_RunFunctionPassManagerWithRemarksr   rk   rv   )r   functionrl   rm   rn   ro   r   r   r   rp     s      zFunctionPassManager.runc              
   C   s   t  \}}zlt|d W 5 Q R X | ||||}|dkrDtdt|"}t|| fW  5 Q R  W S Q R X W 5 t| X dS )a  
        Run optimization passes on the given function and returns the result
        and the remarks data.

        Parameters
        ----------
        function : llvmlite.binding.FunctionRef
            The function to be optimized inplace
        remarks_format : str; optional
            The format of the remarks file; the default is YAML
        remarks_filter : str; optional
            The filter that should be applied to the remarks output.
        ro   rg   rh   Nrq   )r   r   rm   rn   rx   ry   ro   rz   r   r   r   r{   6  s    


*z$FunctionPassManager.run_with_remarks)Nre   rf   )re   rf   )r   r    r!   rc   r   r   rp   r{   r   r   r   r   r1     s     
  r1   )F)?ctypesr   r   r   r   r   r   collectionsr   enumr	   Zllvmlite.bindingr
   rr   tempfiler   Zllvmlite.binding.commonr   Z_prunestatsr   r#   r'   r)   r-   r0   r3   r4   Z	ObjectRefr:   r/   r1   ZLLVMPassManagerRefr%   rb   restypeZLLVMModuleRefr|   argtypesr;   ri   rj   r~   r   ZLLVMValueRefr   r   r>   r@   rB   rD   rG   rI   rK   rM   rO   rQ   rS   rU   rW   rY   r[   r]   r`   r   r   r   r   <module>   s    
`>T







    

 
