Function

public class Function : IRGlobal

A Function represents a named function body in LLVM IR source. Functions in LLVM IR encapsulate a list of parameters and a sequence of basic blocks and provide a way to append to that sequence to build out its body.

A LLVM function definition contains a list of basic blocks, starting with a privileged first block called the “entry block”. After the entry blocks’ terminating instruction come zero or more other basic blocks. The path the flow of control can potentially take, from each block to its terminator and on to other blocks, forms the “Control Flow Graph” (CFG) for the function. The nodes of the CFG are the basic blocks, and the edges are directed from the terminator instruction of one block to any number of potential target blocks.

Additional basic blocks may be created and appended to the function at any time.

let module = Module(name: "Example")
let builder = IRBuilder(module: module)
let fun = builder.addFunction("example",
                              type: FunctionType([], VoidType()))
// Create and append the entry block
let entryBB = fun.appendBasicBlock(named: "entry")
// Create and append a standalone basic block
let freestanding = BasicBlock(name: "freestanding")
fun.append(freestanding)

An LLVM function always has the type FunctionType. This type is used to determine the number and kind of parameters to the function as well as its return value, if any. The parameter values, which would normally enter the entry block, are instead attached to the function and are accessible via the parameters property.

Calling Convention

By default, all functions in LLVM are invoked with the C calling convention but the exact calling convention of both a function declaration and a call instruction are fully configurable.

let module = Module(name: "Example")
let builder = IRBuilder(module: module)
let fun = builder.addFunction("example",
                              type: FunctionType([], VoidType()))
// Switch to swiftcc
fun.callingConvention = .swift

The calling convention of a function and a corresponding call instruction must match or the result is undefined.

Sections

A function may optionally state the section in the object file it should reside in through the use of a metadata attachment. This can be useful to satisfy target-specific data layout constraints, or to provide some hints to optimizers and linkers. LLVMSwift provides a convenience object called an MDBuilder to assist in the creation of this metadata.

let mdBuilder = MDBuilder()
// __attribute__((hot))
let hotAttr = mdBuilder.buildFunctionSectionPrefix(".hot")

let module = Module(name: "Example")
let builder = IRBuilder(module: module)
let fun = builder.addFunction("example",
                              type: FunctionType([], VoidType()))
// Attach the metadata
fun.addMetadata(hotAttr, kind: .sectionPrefix)

For targets that support it, a function may also specify a COMDAT section.

fun.comdat = module.comdat(named: "example")

Debug Information

A function may also carry debug information through special subprogram nodes. These nodes are intended to capture the structure of the function as it appears in the source so that it is available for inspection by a debugger. See DIBuilderr.buildFunction for more information.

  • Accesses the metadata associated with this function.

    To build new function metadata, see DIBuilder.buildFunction.

    Declaration

    Swift

    public var metadata: FunctionMetadata { get set }
  • Accesses the calling convention for this function.

    Declaration

    Swift

    public var callingConvention: CallingConvention { get set }
  • Retrieves the entry block of this function.

    Declaration

    Swift

    public var entryBlock: BasicBlock? { get }
  • Retrieves the first basic block in this function’s body.

    The first basic block in a function is special in two ways: it is immediately executed on entrance to the function, and it is not allowed to have predecessor basic blocks (i.e. there can not be any branches to the entry block of a function). Because the block can have no predecessors, it also cannot have any PHI nodes.

    Declaration

    Swift

    public var firstBlock: BasicBlock? { get }
  • Retrieves the last basic block in this function’s body.

    Declaration

    Swift

    public var lastBlock: BasicBlock? { get }
  • Retrieves the sequence of basic blocks that make up this function’s body.

    Declaration

    Swift

    public var basicBlocks: AnySequence<BasicBlock> { get }
  • Retrieves the number of basic blocks in this function

    Declaration

    Swift

    public var basicBlockCount: Int { get }
  • Computes the address of the specified basic block in this function.

    Warning

    Taking the address of the entry block is illegal.

    This value only has defined behavior when used as an operand to the indirectbr instruction, or for comparisons against null. Pointer equality tests between labels addresses results in undefined behavior. Though, again, comparison against null is ok, and no label is equal to the null pointer. This may be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows ptrtoint and arithmetic to be performed on these values so long as the original value is reconstituted before the indirectbr instruction.

    Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target specific.

    Declaration

    Swift

    public func address(of block: BasicBlock) -> BasicBlock.Address?

    Parameters

    block

    The basic block to compute the address of.

    Return Value

    An IRValue representing the address of the given basic block in this function, else nil if the address cannot be computed or the basic block does not reside in this function.

  • Retrieves the previous function in the module, if there is one.

    Declaration

    Swift

    public func previous() -> Function?
  • Retrieves the next function in the module, if there is one.

    Declaration

    Swift

    public func next() -> Function?
  • Retrieves a parameter at the given index, if it exists.

    Declaration

    Swift

    public func parameter(at index: Int) -> Parameter?

    Parameters

    index

    The index of the parameter to retrieve.

    Return Value

    The parameter at the specified index if it exists, else nil.

  • Retrieves a parameter at the first index, if it exists.

    Declaration

    Swift

    public var firstParameter: Parameter? { get }
  • Retrieves a parameter at the last index, if it exists.

    Declaration

    Swift

    public var lastParameter: Parameter? { get }
  • Retrieves the list of all parameters for this function, in order.

    Declaration

    Swift

    public var parameters: [IRValue] { get }
  • Retrieves the number of parameter values in this function.

    Declaration

    Swift

    public var parameterCount: Int { get }
  • Appends the named basic block to the body of this function.

    Declaration

    Swift

    public func appendBasicBlock(named name: String, in context: Context? = nil) -> BasicBlock

    Parameters

    name

    The name associated with this basic block.

    context

    An optional context into which the basic block can be inserted into. If no context is provided, the block is inserted into the global context.

  • Appends the named basic block to the body of this function.

    Declaration

    Swift

    public func append(_ basicBlock: BasicBlock)

    Parameters

    basicBlock

    The block to append.

  • Deletes the function from its containing module.

    Note

    This does not remove calls to this function from the module. Ensure you have removed all instructions that reference this function before deleting it.

    Declaration

    Swift

    public func delete()
  • Retrieves the underlying LLVM value object.

    Declaration

    Swift

    public func asLLVM() -> LLVMValueRef
  • Adds an enum attribute to the function, its return value or one of its parameters.

    Declaration

    Swift

    @discardableResult
    public func addAttribute(_ attrKind: AttributeKind, value: UInt64 = 0, to index: AttributeIndex) -> EnumAttribute

    Parameters

    attrKind

    The kind of the attribute to add.

    value

    The optional value of the attribute.

    index

    The index representing the function, its return value or one of its parameters.

  • Adds a string attribute to the function, its return value or one of its parameters.

    Declaration

    Swift

    @discardableResult
    public func addAttribute(_ name: String, value: String = "", to index: AttributeIndex) -> StringAttribute

    Parameters

    name

    The name of the attribute to add.

    value

    The optional value of the attribute.

    index

    The index representing the function, its return value or one of its parameters.

  • Removes an attribute from the function, its return value or one of its parameters.

    Declaration

    Swift

    public func removeAttribute(_ attr: Attribute, from index: AttributeIndex)

    Parameters

    attr

    The attribute to remove.

    index

    The index representing the function, its return value or one of its parameters.

  • Removes an enum attribute from the function, its return value or one of its parameters.

    Declaration

    Swift

    public func removeAttribute(_ attrKind: AttributeKind, from index: AttributeIndex)

    Parameters

    attr

    The kind of the attribute to remove.

    index

    The index representing the function, its return value or one of its parameters.

  • Removes a string attribute from the function, its return value or one of its parameters.

    Declaration

    Swift

    public func removeAttribute(_ name: String, from index: AttributeIndex)

    Parameters

    name

    The name of the attribute to remove.

    index

    The index representing the function, its return value or one of its parameters.

  • Gets the attributes of the function, its return value or its parameters.

    Declaration

    Swift

    public func attributes(at index: AttributeIndex) -> [Attribute]