B
    Ꮚ\"                 @   sD   d dl mZmZ d dlZddlmZmZmZmZ G dd de	Z
dS )    )print_functionabsolute_importN   )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   1lib/python3.7/site-packages/llvmlite/ir/module.py__init__	   s    

zModule.__init__c             C   sf   g }x\|D ]T}|d kr$t  d }n0t|tr<t| |}nt|ttfrT| |}|	| q
W |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 }x6|D ].\}}t |ttfr*| |}|||f q
W |S )N)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   Zkindr    Zis_distinctr'   r(   Zdir   r   r   add_debug_infoC   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   ZValuer   typer   r   r%   add)r   r   elementZnmdr   r   r   add_named_metadataW   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_metadatap   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>|   s    z$Module.functions.<locals>.<listcomp>)r   r   )r   r   r   r   	functionsw   s    zModule.functionsc             C   s
   | j  S )z>
        An iterable of global values in this module.
        )r   r   )r   r   r   r   global_values   s    zModule.global_valuesc             C   s
   | j | S )z-
        Get a global value by name.
        )r   )r   r   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deduplicate)r   r   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}nhtd	kr d
krtd d tdg}n. dkrtd d }ntd }ntdkr dkrJd tdd	 tdtd	gtt }n4 dkrxd td	gtd }n|  nztdkr dkrtd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.fma	llvm.cttz	llvm.ctlzr   c             S   s   g | ]
}|j qS r   )intrinsic_name)r3   tr   r   r   r5      s    z,Module.declare_intrinsic.<locals>.<listcomp>.zllvm.assumer   z	llvm.powi    zllvm.pow   zllvm.memset   >   	llvm.cttz	llvm.ctlz   )zllvm.memcpyzllvm.memmovezllvm.fma)r   )
rC   joinr   r&   r   FunctionTypeZVoidTypeZIntTyper   r2   )r   r=   r>   Zfntyr?   suffixesr   r   )r=   r>   r   declare_intrinsic   sH    

 



zModule.declare_intrinsicc             C   s   | j jS )N)r   Zidentified_types)r   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)r3   itr   r   r   r5      s   z*Module._get_body_lines.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r   )r3   r4   r   r   r   r5      s    )rP   r   r   )r   linesr   r   r   _get_body_lines   s    zModule._get_body_linesc          	   C   sd   g }x<| j  D ].\}}|dj|ddd |jD d qW x| jD ]}|t| qJW |S )Nz!{name} = !{{ {operands} }}z, c             s   s   | ]}|  V  qd S )N)Zget_reference)r3   ir   r   r   	<genexpr>   s   z-Module._get_metadata_lines.<locals>.<genexpr>)r   r    )r   r+   r   formatrL   r    r   r   )r   Zmdbufkr4   r)   r   r   r   _get_metadata_lines   s    zModule._get_metadata_linesc             C   s   d |  S )N
)rL   rS   )r   r   r   r   _stringify_body   s    zModule._stringify_bodyc             C   s   d |  S )NrY   )rL   rX   )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
   rY   )r   r   r   rS   rX   rL   )r   rR   r   r   r   __repr__   s    


zModule.__repr__)F)N)r
   )r   N)__name__
__module____qualname__r   Zglobal_contextr   r#   r$   r   r,   r0   r1   propertyr6   r7   r8   r:   r;   rO   rP   rS   rX   rZ   r[   r\   r   r   r   r   r	      s&   	



1
r	   )Z
__future__r   r   r   r
   r   r   r   r   objectr	   r   r   r   r   <module>   s   