Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/docs/source/user-guide/ir/ir-builder.rst
1154 views
===========
IR builders
===========

.. currentmodule:: llvmlite.ir

.. contents::
   :depth: 2
   :local:


:class:`IRBuilder` is the workhorse of LLVM :ref:`IR` generation.
It allows you to fill the :ref:`basic blocks <basic block>` of
your functions with LLVM instructions.

An :class:`IRBuilder` internally maintains a current basic block
and a pointer inside the block's list of instructions. When a
new instruction is added, it is inserted at that point, and then
the pointer is advanced after the new instruction.

A :class:`IRBuilder` also maintains a reference to metadata
describing the current source location, which is attached to all
inserted instructions.


Instantiation
==============

.. class:: IRBuilder(block=None)

   Create a new IR builder. If *block*---a :class:`Block`---is
   given, the builder starts at the end of this basic block.


Attributes
==========

:class:`IRBuilder` has the following attributes:

*  .. attribute:: IRBuilder.block

      The basic block that the builder is operating on.

*  .. attribute:: IRBuilder.function

      The function that the builder is operating on.

*  .. attribute:: IRBuilder.module

      The module that the builder's function is defined in.

*  .. attribute:: IRBuilder.debug_metadata

      If not ``None``, the metadata that is attached to any
      inserted instructions as ``!dbg``, unless the instruction
      already has ``!dbg`` set.


Utilities
=========

.. method:: IRBuilder.append_basic_block(name='')

   Append a basic block, with the given optional *name*, to the
   current function. The current block is not changed. A
   :class:`Block` is returned.


Positioning
===========

The following :class:`IRBuilder` methods help you move the
current instruction pointer:

* .. method:: IRBuilder.position_before(instruction)

     Position immediately before the given *instruction*. The
     current block is also changed to the instruction's basic
     block.

* .. method:: IRBuilder.position_after(instruction)

     Position immediately after the given *instruction*. The
     current block is also changed to the instruction's basic
     block.

* .. method:: IRBuilder.position_at_start(block)

     Position at the start of the basic *block*.

* .. method:: IRBuilder.position_at_end(block)

     Position at the end of the basic *block*.

The following context managers allow you to temporarily switch to
another basic block and then go back to where you were.

* .. method:: IRBuilder.goto_block(block)

     Position the builder either at the end of the
     basic *block*, if it is not terminated, or just before the
     *block*'s terminator::

        new_block = builder.append_basic_block('foo')
        with builder.goto_block(new_block):
           # Now the builder is at the end of *new_block*
           # ... add instructions

        # Now the builder has returned to its previous position

* .. method:: IRBuilder.goto_entry_block()

     The same as :meth:`goto_block`, but with the current
     function's entry block.


Flow control helpers
=====================

The following context managers make it easier to create
conditional code.

* .. method:: IRBuilder.if_then(pred, likely=None)

     Create a basic block whose execution is conditioned on
     predicate *pred*, a value of type ``IntType(1)``. Another
     basic block is created for instructions after the
     conditional block. The current basic block is terminated
     with a conditional branch based on *pred*.

     When the context manager is entered, the builder positions
     at the end of the conditional block. When the context
     manager is exited, the builder positions at the start of
     the continuation block.

     If likely is not ``None``, it indicates whether *pred* is
     likely to be ``True``, and metadata is emitted to specify
     branch weights accordingly.


* .. method:: IRBuilder.if_else(pred, likely=None)

     Set up 2 basic blocks whose execution is conditioned on
     predicate *pred*, a value of type ``IntType(1)``. *likely* has
     the same meaning as in ``if_then()``.

     A pair of context managers is yielded. Each of them acts as
     an :meth:`if_then()` context manager---the first for the
     block to be executed if pred is ``True`` and the second for
     the block to be executed if pred is ``False``.

     When the context manager is exited, the builder is
     positioned on a new continuation block that both
     conditional blocks jump into.

     Typical use:

     .. code-block:: Python

        with builder.if_else(pred) as (then, otherwise):
            with then:
                # emit instructions for when the predicate is true
            with otherwise:
                # emit instructions for when the predicate is false
        # emit instructions following the if-else block


Instruction building
=====================

The following methods insert a new instruction---an
:class:`Instruction` instance---at the current index in the
current block. The new instruction is returned.

An instruction's operands are almost always
:ref:`values <ir-values>`.

Many of these methods also take an optional *name* argument,
specifying the local *name* of the result value. If not given, a
unique name is automatically generated.


Arithmetic
------------

In the methods below, the *flags* argument is an optional sequence
of strings that modify the instruction's semantics. Examples
include the fast-math flags for floating-point operations, and
whether wraparound on overflow can be ignored on integer
operations.


Integer
^^^^^^^

* .. method:: IRBuilder.shl(lhs, rhs, name='', flags=())

     Left-shift *lhs* by *rhs* bits.

* .. method:: IRBuilder.lshr(lhs, rhs, name='', flags=())

     Logical right-shift *lhs* by *rhs* bits.

* .. method:: IRBuilder.ashr(lhs, rhs, name='', flags=())

     Arithmetic, signed, right-shift *lhs* by *rhs* bits.

* .. method:: IRBuilder.cttz(value, flag)

     Counts trailing zero bits in *value*. Boolean *flag* indicates whether the
     result is defined for ``0``.

* .. method:: IRBuilder.ctlz(value, flag)

     Counts leading zero bits in *value*. Boolean *flag* indicates whether the
     result is defined for ``0``.

* .. method:: IRBuilder.add(lhs, rhs, name='', flags=())

     Integer add *lhs* and *rhs*.

* .. method:: IRBuilder.sadd_with_overflow(lhs, rhs, name='', flags=())

     Integer add *lhs* and *rhs*. A ``{ result, overflow bit }``
     structure is returned.

* .. method:: IRBuilder.sub(lhs, rhs, name='', flags=())

     Integer subtract *rhs* from *lhs*.

* .. method:: IRBuilder.ssub_with_overflow(lhs, rhs, name='', flags=())

     Integer subtract *rhs* from *lhs*. A
     ``{ result, overflow bit }`` structure is returned.

* .. method:: IRBuilder.mul(lhs, rhs, name='', flags=())

     Integer multiply *lhs* with *rhs*.

* .. method:: IRBuilder.smul_with_overflow(lhs, rhs, name='', flags=())

     Integer multiply *lhs* with *rhs*. A
     ``{ result, overflow bit }`` structure is returned.

* .. method:: IRBuilder.sdiv(lhs, rhs, name='', flags=())

     Signed integer divide *lhs* by *rhs*.

* .. method:: IRBuilder.udiv(lhs, rhs, name='', flags=())

     Unsigned integer divide *lhs* by *rhs*.

* .. method:: IRBuilder.srem(lhs, rhs, name='', flags=())

     Signed integer remainder of *lhs* divided by *rhs*.

* .. method:: IRBuilder.urem(lhs, rhs, name='', flags=())

     Unsigned integer remainder of *lhs* divided by *rhs*.

* .. method:: IRBuilder.and_(lhs, rhs, name='', flags=())

     Bitwise AND *lhs* with *rhs*.

* .. method:: IRBuilder.or_(lhs, rhs, name='', flags=())

     Bitwise OR *lhs* with *rhs*.

* .. method:: IRBuilder.xor(lhs, rhs, name='', flags=())

     Bitwise XOR *lhs* with *rhs*.

* .. method:: IRBuilder.not_(value, name='')

     Bitwise complement *value*.

* .. method:: IRBuilder.neg(value, name='')

     Negate *value*.

Floating-point
^^^^^^^^^^^^^^

* .. method:: IRBuilder.fadd(lhs, rhs, name='', flags=())

     Floating-point add *lhs* and *rhs*.

* .. method:: IRBuilder.fsub(lhs, rhs, name='', flags=())

     Floating-point subtract *rhs* from *lhs*.

* .. method:: IRBuilder.fmul(lhs, rhs, name='', flags=())

     Floating-point multiply *lhs* by *rhs*.

* .. method:: IRBuilder.fdiv(lhs, rhs, name='', flags=())

     Floating-point divide *lhs* by *rhs*.

* .. method:: IRBuilder.frem(lhs, rhs, name='', flags=())

     Floating-point remainder of *lhs* divided by *rhs*.

* .. method:: IRBuilder.fneg(arg, name='', flags=())

     Floating-point negation of *arg*.


Conversions
-----------

* .. method:: IRBuilder.trunc(value, typ, name='')

     Truncate integer *value* to integer type *typ*.

* .. method:: IRBuilder.zext(value, typ, name='')

     Zero-extend integer *value* to integer type *typ*.

* .. method:: IRBuilder.sext(value, typ, name='')

     Sign-extend integer *value* to integer type *typ*.

* .. method:: IRBuilder.fptrunc(value, typ, name='')

     Truncate---approximate---floating-point *value* to
     floating-point type *typ*.

* .. method:: IRBuilder.fpext(value, typ, name='')

     Extend floating-point *value* to floating-point type *typ*.

* .. method:: IRBuilder.fptosi(value, typ, name='')

     Convert floating-point *value* to signed integer type *typ*.

* .. method:: IRBuilder.fptoui(value, typ, name='')

     Convert floating-point *value* to unsigned integer type *typ*.

* .. method:: IRBuilder.sitofp(value, typ, name='')

     Convert signed integer *value* to floating-point type *typ*.

* .. method:: IRBuilder.uitofp(value, typ, name='')

     Convert unsigned integer *value* to floating-point type *typ*.

* .. method:: IRBuilder.ptrtoint(value, typ, name='')

     Convert pointer *value* to integer type *typ*.

* .. method:: IRBuilder.inttoptr(value, typ, name='')

     Convert integer *value* to pointer type *typ*.

* .. method:: IRBuilder.bitcast(value, typ, name='')

     Convert pointer *value* to pointer type *typ*.

* .. method:: IRBuilder.addrspacecast(value, typ, name='')

     Convert pointer *value* to pointer type *typ* of different
     address space.


Comparisons
------------

* .. method:: IRBuilder.icmp_signed(cmpop, lhs, rhs, name='')

     Signed integer compare *lhs* with *rhs*. The string *cmpop* can
     be one of ``<``, ``<=``, ``==``, ``!=``, ``>=`` or ``>``.

* .. method:: IRBuilder.icmp_unsigned(cmpop, lhs, rhs, name='')

     Unsigned integer compare *lhs* with *rhs*. The string *cmpop* can
     be one of ``<``, ``<=``, ``==``, ``!=``, ``>=`` or ``>``.

* .. method:: IRBuilder.fcmp_ordered(cmpop, lhs, rhs, name='', flags=[])

     Floating-point ordered compare *lhs* with *rhs*.

     * The string *cmpop* can be one of ``<``, ``<=``, ``==``,
       ``!=``, ``>=``, ``>``, ``ord`` or ``uno``.
     * The *flags* list can include any of ``nnan``, ``ninf``,
       ``nsz``, ``arcp`` and ``fast``, which implies all
       previous flags.

* .. method:: IRBuilder.fcmp_unordered(cmpop, lhs, rhs, name='', flags=[])

     Floating-point unordered compare *lhs* with *rhs*.

     * The string *cmpop*, can  be one of ``<``, ``<=``, ``==``,
       ``!=``, ``>=``, ``>``, ``ord`` or ``uno``.
     * The *flags* list can include any of ``nnan``, ``ninf``,
       ``nsz``, ``arcp`` and ``fast``, which implies all
       previous flags.


Conditional move
-----------------

.. method:: IRBuilder.select(cond, lhs, rhs, name='')

   A 2-way select---*lhs* if *cond*, else *rhs*.


Phi
---

.. method:: IRBuilder.phi(typ, name='')

   Create a phi node. To add incoming edges and their values, use
   the :meth:`~PhiInstr.add_incoming` method on the return value.


Aggregate operations
---------------------

* .. method:: IRBuilder.extract_value(agg, index, name='')

     Extract the element at *index* of the
     :ref:`aggregate value <aggregate-types>` *agg*.

     * *index* may be an integer or a sequence of integers.
     * Indices must be constant.

* .. method:: IRBuilder.insert_value(agg, value, index, name='')

     Build a copy of :ref:`aggregate value <aggregate-types>`
     *agg* by setting the new *value* at *index*. The value for *index*
     can be of the same types as in :meth:`extract_value`.


Vector operations
-----------------

* .. method:: IRBuilder.extract_element(vector, idx, name='')

     Returns the *value* at position *idx*.

* .. method:: IRBuilder.insert_element(vector, value, idx, name='')

     Returns vector with ``vector[idx]`` replaced by ``value``.
     The result is undefined if the idx is larger or equal the vector length.

* .. method:: IRBuilder.shuffle_vector(vector1, vector2, mask, name='')

     Constructs a permutation of elements from *vector1* and *vector2*.
     Returns a new vector in the same length of *mask*.

     * *vector1* and *vector2* must have the same element type.
     * *mask* must be a constant vector of integer types.


Memory
-------

* .. method:: IRBuilder.alloca(typ, size=None, name='')

     Statically allocate a stack slot for *size* values of type
     *typ*. If *size* is not given, a stack slot for 1 value is
     allocated.

* .. method:: IRBuilder.load(ptr, name='', align=None)

     Load value from pointer *ptr*. If *align* is passed, it should
     be a Python integer specifying the guaranteed pointer
     alignment.

* .. method:: IRBuilder.store(value, ptr, align=None)

     Store *value* to pointer *ptr*. If *align* is passed, it should
     be a Python integer specifying the guaranteed pointer
     alignment.

* .. method:: IRBuilder.load_atomic(ptr, ordering, align, name='')

     Load value from pointer *ptr* as an atomic operation with the given
     *ordering*. *align* must be a Python integer specifying the guaranteed
     pointer alignment.

* .. method:: IRBuilder.store_atomic(value, ptr, ordering, align)

     Store *value* to pointer *ptr* as an atomic operation with the given
     *ordering*. *align* must be a Python integer specifying the guaranteed
     pointer alignment.

* .. method:: IRBuilder.gep(ptr, indices, inbounds=False, name='')

     The :ref:`getelementptr` instruction. Given a pointer *ptr*
     to an aggregate value, compute the address of the inner
     element given by the sequence of *indices*.

* .. method:: cmpxchg(ptr, cmp, val, ordering, failordering=None, name='')

     Atomic compare-and-swap at address *ptr*.

     * *cmp* is the value to compare the contents with.
     * *val* is the new value to be swapped into.
     * Optional *ordering* and *failordering* specify the memory
       model for this instruction.

* .. method:: atomic_rmw(op, ptr, val, ordering, name='')

     Atomic in-memory operation *op* at address *ptr*, with operand
     *val*.

     * The string *op* specifies the operation---for example,
       ``add`` or ``sub``.
     * The optional *ordering* specifies the memory model for this
       instruction.


Function call
---------------

.. method:: IRBuilder.call(fn, args, name='', cconv=None, tail=None, \
   fastmath=(), attrs=(), arg_attrs=None)

   Call function *fn* with arguments *args*, a sequence of values.

   * *cconv* is the optional calling convention.
   * *tail* controls tail-call optimization behavior. It may be one of:

     * ``None`` (the default): indicates no specific tail-call optimization
       behavior.
     * ``"tail"``: a hint that indicates that the call should be tail-call
       optimized, but may be ignored.
     * ``"musttail"``: indicates that the call must be tail-call optimized for
       program correctness.
     * ``"notail"``: indicates that the call should never be tail-call
       optimized.

     For backwards compatibility with previous versions, the following values
     are also accepted:

     * ``False`` is equivalent to ``None``, indicating no specific behavior.
     * ``True`` is equivalent to ``"tail"``, suggesting tail-call optimization.
   * *fastmath* is a string or a sequence of strings of names for
     `fast-math flags
     <http://llvm.org/docs/LangRef.html#fast-math-flags>`_.
   * *attrs* is a string or sequence of strings of function attributes to
     attach to the call site.
   * *arg_attrs* is a dictionary matching argument indices (as regular
     integers, starting at zero) to strings or sequences of strings giving
     the attributes to attach to the respective argument at this call site.
     If an index is not present in the dictionary, or *arg_attrs* is missing
     entirely, no attributes are emitted for the given argument.

     If some attributes, such as ``sret``, are specified at the function
     declaration, they must also be specified at each call site for
     correctness. (As of LLVM 11, this does not seem to be explicitly
     specified in the LLVM language reference.)


Branches
-----------

The following methods are all :ref:`terminators <terminator>`:

* .. method:: IRBuilder.branch(target)

     Unconditional jump to the *target*, a :class:`Block`.

* .. method:: IRBuilder.cbranch(cond, truebr, falsebr)

     Conditional jump to either *truebr* or *falsebr*---both
     :class:`Block` instances---depending on *cond*, a value of
     type ``IntType(1)``. This instruction is a
     :class:`PredictableInstr`.

* .. method:: IRBuilder.ret(value)

     Return the *value* from the current function.

* .. method:: IRBuilder.ret_void()

     Return from the current function without a value.

* .. method:: IRBuilder.switch(value, default)

     Switch to different blocks based on the *value*. *default* is
     the block to switch to if no other block is matched.

     To add non-default targets, use the
     :meth:`~SwitchInstr.add_case` method on the return value.

* .. method:: IRBuilder.branch_indirect(address)

     Jump to the basic block with the address *address*, a value
     of type `IntType(8).as_pointer()`.

     To obtain a block address, use the
     :class:`BlockAddress` constant.

     To add all possible jump destinations, use
     the :meth:`~IndirectBranch.add_destination` method on the
     return value.


Exception handling
------------------

* .. method:: IRBuilder.invoke(fn, args, normal_to, unwind_to, name='', \
     cconv=None, fastmath=(), attrs=(), arg_attrs=None)

     Call function *fn* with arguments *args*, a sequence of values.

     If the function *fn* returns normally, control is transferred
     to *normal_to*. Otherwise, it is transferred to *unwind_to*,
     whose first non-phi instruction must be :class:`LandingPad`.

     The remaining arguments give additional attributes to specify
     at the call site; see :meth:`call` for a description.

* .. method:: IRBuilder.landingpad(typ, personality, name='', cleanup=False)

     Describe which exceptions this basic block can handle.

     * *typ* specifies the return type of the landing pad. It is a
       structure with 2 pointer-sized fields.
     * *personality* specifies an exception personality function.
     * *cleanup* specifies whether control should always be
       transferred to this landing pad, even when no matching
       exception is caught.

     To add landing pad clauses, use the
     :meth:`~LandingPad.add_clause` method on the return value.

     There are 2 kinds of landing pad clauses:

     * A :class:`CatchClause`, which specifies a typeinfo for
       a single exception to be caught. The typeinfo is a value
       of type `IntType(8).as_pointer().as_pointer()`;

     * A :class:`FilterClause`, which specifies an array of
       typeinfos.

     Every landing pad must either contain at least 1 clause
     or be marked for cleanup.

     The semantics of a landing pad are entirely determined by
     the personality function. For details on the way LLVM
     handles landing pads in the optimizer, see
     `Exception handling in
     LLVM <http://llvm.org/docs/ExceptionHandling.html>`_.
     For details on the implementation of personality functions,
     see `Itanium exception handling
     ABI <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>`_.


* .. method:: IRBuilder.resume(landingpad)

     Resume an exception caught by *landingpad*. Used to indicate
     that the landing pad did not catch the exception after all,
     perhaps because it only performed cleanup.


Inline assembler
-----------------

* .. method:: IRBuilder.asm(ftype, asm, constraint, args, side_effect, name='')

     Add an inline assembler call instruction. For example, this
     is used in :meth:`load_reg` and :meth:`store_reg`.

     Arguments:

     * *ftype* is a function type specifying the inputs and output
       of the inline assembler call.
     * *asm* is the inline assembler snippet---for example,
       ``"mov $2, $0\nadd $1, $0"``. x86 inline ASM uses the
       AT&T syntax.
     * *constraint* defines the input/output constraints---for
       example ``=r,r,r``.
     * *args* is the list of inputs, as IR values.
     * *side_effect* is a boolean that specifies whether or not
       this instruction has side effects not visible in the
       constraint list.
     * *name* is the optional name of the returned LLVM value.

     For more information about these parameters, see the
     `official LLVM documentation <http://llvm.org/docs/LangRef.html#inline-asm-constraint-string>`_.

     EXAMPLE: Adding 2 64-bit values on x86::

        fty = FunctionType(IntType(64), [IntType(64),IntType(64)])
        add = builder.asm(fty, "mov $2, $0\nadd $1, $0", "=r,r,r",
                          (arg_0, arg_1), True, name="asm_add")


* .. method:: IRBuilder.load_reg(reg_type, reg_name, name='')

     Load a register value into an LLVM value.

     EXAMPLE: Obtaining the value of the ``rax`` register::

          builder.load_reg(IntType(64), "rax")

* .. method:: IRBuilder.store_reg(value, reg_type, reg_name, name='')

     Store an LLVM value inside a register.

     EXAMPLE: Storing ``0xAAAAAAAAAAAAAAAA`` into the ``rax``
     register::

        builder.store_reg(Constant(IntType(64), 0xAAAAAAAAAAAAAAAA), IntType(64), "rax")


Miscellaneous
--------------

* .. method:: IRBuilder.assume(cond)

     Let the LLVM optimizer assume that *cond*---a value of type
     ``IntType(1)``---is ``True``.

* .. method:: IRBuilder.unreachable()

     Mark an unreachable point in the code.

* .. method:: IRBuilder.comment(text)

     Puts a single-line comment into the generated IR. This will be ignored by
     LLVM, but can be useful for debugging the output of a compiler.

     Arguments:

     * *text* is a string that does not contain new line characters.