U
    +dr#                     @   s4   d dl Z d dlmZmZmZmZ G dd deZdS )    N)contextvaluestypes_utilsc                   @   s   e Zd ZdejfddZdd Zdd Zdd	 Zd+ddZ	d,ddZ
dd Zedd Zedd Zdd Zdd Zd-ddZd.ddZdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* ZdS )/Module c                 C   sB   || _ || _d| _t | _d| _t | _	g | _
i | _i | _d S )Nr   zunknown-unknown-unknown)r   namedata_layoutr   Z	NameScopescopetriplecollectionsOrderedDictglobalsmetadatanamedmetadata_metadatacache)selfr   r    r   6/tmp/pip-unpacked-wheel-stw2luzp/llvmlite/ir/module.py__init__   s    

zModule.__init__c                 C   sb   g }|D ]T}|d kr"t  d }n0t|tr:t| |}nt|ttfrR| |}|	| q|S N)
r   MetaDataType
isinstancestrr   ZMetaDataStringlisttupleadd_metadataappend)r   operands	fixed_opsopr   r   r   _fix_metadata_operands   s    

zModule._fix_metadata_operandsc                 C   s<   g }|D ].\}}t |ttfr(| |}|||f q|S r   )r   r   r   r   r   )r   r   r   r   r    r   r   r   _fix_di_operands$   s    
zModule._fix_di_operandsc                 C   sp   t |ttfstd|f | |}t|}|| jkrbt| j}tj	| |t
|d}|| j|< n
| j| }|S )z
        Add an unnamed metadata to the module with the given *operands*
        (a sequence of values) or return a previous equivalent metadata.
        A MDValue instance is returned, it can then be associated to
        e.g. an instruction.
        z3expected a list or tuple of metadata values, got %rr   )r   r   r   	TypeErrorr!   r   lenr   r   ZMDValuer   )r   r   keynmdr   r   r   r   -   s    



zModule.add_metadataFc                 C   sf   t t| | }|||f}|| jkrXt| j}tj| |||t	|d}|| j|< n
| j| }|S )ak  
        Add debug information metadata to the module with the given
        *operands* (a dict of values with string keys) or return
        a previous equivalent metadata.  *kind* is a string of the
        debug information kind (e.g. "DICompileUnit").

        A DIValue instance is returned, it can then be associated to e.g.
        an instruction.
        r#   )
r   sortedr"   itemsr   r%   r   r   ZDIValuer   )r   kindr   Zis_distinctr&   r'   Zdir   r   r   add_debug_infoA   s    




zModule.add_debug_infoNc                 C   sr   || j kr| j | }nt|  }| j |< |dk	rnt|tjsH| |}t|jtjsdt	d|f |
| |S )a  
        Add a named metadata node to the module, if it doesn't exist,
        or return the existing node.
        If *element* is given, it will append a new element to
        the named metadata node.  If *element* is a sequence of values
        (rather than a metadata value), a new unnamed node will first be
        created.

        Example::
            module.add_named_metadata("llvm.ident", ["llvmlite/1.0"])
        Nz'wrong type for metadata element: got %r)r   r   ZNamedMetaDatar   Valuer   typer   r   r$   add)r   r   elementZnmdr   r   r   add_named_metadataU   s    


zModule.add_named_metadatac                 C   s
   | j | S )z
        Return the metadata node with the given *name*.  KeyError is raised
        if no such node exists (contrast with add_named_metadata()).
        )r   r   r   r   r   r   get_named_metadatan   s    zModule.get_named_metadatac                 C   s   dd | j  D S )zI
        A list of functions declared or defined in this module.
        c                 S   s   g | ]}t |tjr|qS r   )r   r   Function.0vr   r   r   
<listcomp>z   s    z$Module.functions.<locals>.<listcomp>r   r   r   r   r   r   	functionsu   s    zModule.functionsc                 C   s
   | j  S )z>
        An iterable of global values in this module.
        r9   r:   r   r   r   global_values}   s    zModule.global_valuesc                 C   s
   | j | S )z-
        Get a global value by name.
        )r   r2   r   r   r   
get_global   s    zModule.get_globalc                 C   s    |j | jkst|| j|j < dS )z)
        Add a new global value.
        N)r   r   AssertionError)r   Zglobalvaluer   r   r   
add_global   s    zModule.add_globalc                 C   s   | j |S )zJ
        Get a unique global name with the following *name* hint.
        )r
   Zdeduplicater2   r   r   r   get_unique_name   s    zModule.get_unique_namer   c                    s<   fdd} dkr$d j g}ndd D }d g| }|| jkrV| j| S |d k	rbntdkr dkrtt td	g}ntd	kr: d
krtd d tdg}np dkrtd d }nR dkr
td tdg}n. dkr(ttd}ntd }ntdkr dkrd tdd	 td	gtt }n4 dkrd td	gtd }n|  nrtdkr& dkrtd	g tt }n0 dkrd gd td }n|  n|  tj	| ||dS )Nc                      s   t d tf d S )Nz"unknown intrinsic %r with %d types)NotImplementedErrorr%   r   	intrinsictysr   r   _error   s    
z(Module.declare_intrinsic.<locals>._error>   	llvm.ctlzllvm.fma	llvm.cttzr   c                 S   s   g | ]
}|j qS r   )intrinsic_name)r6   tr   r   r   r8      s     z,Module.declare_intrinsic.<locals>.<listcomp>.zllvm.assume   z	llvm.powi    zllvm.pow   zllvm.convert.from.fp16   zllvm.convert.to.fp16zllvm.memset   >   rF   rH      )zllvm.memcpyzllvm.memmoverG   r#   )
rI   joinr   r%   r   FunctionTypeZVoidTypeZIntTyper   r4   )r   rC   rD   ZfntyrE   suffixesr   r   rB   r   declare_intrinsic   sR    

 





zModule.declare_intrinsicc                 C   s   | j jS r   )r   Zidentified_typesr:   r   r   r   get_identified_types   s    zModule.get_identified_typesc                 C   s2   dd |    D }|dd | j D 7 }|S )Nc                 S   s   g | ]}|  qS r   )Zget_declaration)r6   itr   r   r   r8      s   z*Module._get_body_lines.<locals>.<listcomp>c                 S   s   g | ]}t |qS r   )r   r5   r   r   r   r8      s     )rV   r   r   r   linesr   r   r   _get_body_lines   s
    
zModule._get_body_linesc              	   C   s\   g }| j  D ].\}}|dj|ddd |jD d q| jD ]}|t| qD|S )Nz!{name} = !{{ {operands} }}z, c                 s   s   | ]}|  V  qd S r   )Zget_reference)r6   ir   r   r   	<genexpr>   s   z-Module._get_metadata_lines.<locals>.<genexpr>)r   r   )r   r*   r   formatrR   r   r   r   )r   Zmdbufkr7   r(   r   r   r   _get_metadata_lines   s     


zModule._get_metadata_linesc                 C   s   d |  S N
)rR   rZ   r:   r   r   r   _stringify_body   s    zModule._stringify_bodyc                 C   s   d |  S r`   )rR   r_   r:   r   r   r   _stringify_metadata   s    zModule._stringify_metadatac                 C   sN   g }|d| j f d| jf d| jf dg7 }||  7 }||  7 }d|S )Nz; ModuleID = "%s"ztarget triple = "%s"ztarget datalayout = "%s"r   ra   )r   r   r	   rZ   r_   rR   rX   r   r   r   __repr__   s    


zModule.__repr__)F)N)r   )r   N)__name__
__module____qualname__r   Zglobal_contextr   r!   r"   r   r,   r1   r3   propertyr;   r<   r=   r?   r@   rU   rV   rZ   r_   rb   rc   rd   r   r   r   r   r      s*   	





5
r   )r   Zllvmlite.irr   r   r   r   objectr   r   r   r   r   <module>   s   