BasicBlock
public struct BasicBlock : IRValue
extension BasicBlock: Equatable
A BasicBlock
represents a basic block in an LLVM IR program. A basic
block contains a sequence of instructions, a pointer to its parent block and
its follower block, and an optional label that gives the basic block an
entry in the symbol table. Because of this label, the type of every basic
block is LabelType
.
A basic block can be thought of as a sequence of instructions, and indeed
its member instructions may be iterated over with a for-in
loop. A well-
formed basic block has as its last instruction a “terminator” that produces
a transfer of control flow and possibly yields a value. All other
instructions in the middle of the basic block may not be “terminator”
instructions. Basic blocks are not required to be well-formed until
code generation is complete.
Creating a Basic Block
By default, the initializer for a basic block merely creates the block but does not associate it with a function.
let module = Module(name: "Example")
let fun = builder.addFunction("example",
type: FunctionType([], VoidType()))
// This basic block is "floating" outside of a function.
let floatingBB = BasicBlock(name: "floating")
// Until we associate it with a function by calling `Function.append(_:)`.
fun.append(floatingBB)
A basic block may be created and automatically inserted at the end of a
function by calling Function.appendBasicBlock(named:in:)
.
let module = Module(name: "Example")
let fun = builder.addFunction("example",
type: FunctionType([], VoidType()))
// This basic block is "attached" to the example function.
let attachedBB = fun.appendBasicBlock(named: "attached")
The Address of a Basic Block
Basic blocks (except the entry block) may have their labels appear in the
symbol table. Naturally, these labels are associated with address values
in the final object file. The value of that address may be accessed for the
purpose of an indirect call or a direct comparisson by calling
Function.address(of:)
and providing one of the function’s child blocks as
an argument. Providing any other basic block outside of the function as an
argument value is undefined.
The Entry Block
The first basic block (the entry block) in a Function
is special:
- The entry block is immediately executed when the flow of control enters its parent function.
- The entry block is not allowed to have predecessor basic blocks (i.e. there cannot be any branches to the entry block of a function).
- The address of the entry block is not a well-defined value.
- The entry block cannot have PHI nodes. This is enforced structurally, as the entry block can have no predecessor blocks to serve as operands to the PHI node.
- Static
alloca
instructions situated in the entry block are treated specially by most LLVM backends. For example, FastISel keeps track of staticalloca
values in the entry block to more efficiently reference them from the base pointer of the stack frame.
-
Creates a
BasicBlock
from anLLVMBasicBlockRef
object.Declaration
Swift
public init(llvm: LLVMBasicBlockRef)
-
Creates a new basic block without a parent function.
The basic block should be inserted into a function or destroyed before the IR builder is finalized.
Declaration
Swift
public init(context: Context = .global, name: String = "")
-
Given that this block and a given block share a parent function, move this block before the given block in that function’s basic block list.
Declaration
Swift
public func move(before position: BasicBlock)
Parameters
position
The basic block that acts as a position before which this block will be moved.
-
Given that this block and a given block share a parent function, move this block after the given block in that function’s basic block list.
Declaration
Swift
public func move(after position: BasicBlock)
Parameters
position
The basic block that acts as a position after which this block will be moved.
-
Retrieves the underlying LLVM value object.
Declaration
Swift
public func asLLVM() -> LLVMValueRef
-
Retrieves the name of this basic block.
Declaration
Swift
public var name: String { get }
-
Returns the first instruction in the basic block, if it exists.
Declaration
Swift
public var firstInstruction: IRInstruction? { get }
-
Returns the first instruction in the basic block, if it exists.
Declaration
Swift
public var lastInstruction: IRInstruction? { get }
-
Returns the terminator instruction if this basic block is well formed or
nil
if it is not well formed.Declaration
Swift
public var terminator: TerminatorInstruction? { get }
-
Returns the parent function of this basic block, if it exists.
Declaration
Swift
public var parent: Function? { get }
-
Returns the basic block following this basic block, if it exists.
Declaration
Swift
public func next() -> BasicBlock?
-
Returns the basic block before this basic block, if it exists.
Declaration
Swift
public func previous() -> BasicBlock?
-
Returns a sequence of the Instructions that make up this basic block.
Declaration
Swift
public var instructions: AnySequence<IRInstruction> { get }
-
Removes this basic block from a function but keeps it alive.
Note
To ensure correct removal of the block, you must invalidate any references to it and its child instructions. The block must also have no successor blocks that make reference to it.Declaration
Swift
public func removeFromParent()
-
Moves this basic block before the given basic block.
Declaration
Swift
public func moveBefore(_ block: BasicBlock)
-
Moves this basic block after the given basic block.
Declaration
Swift
public func moveAfter(_ block: BasicBlock)
-
Declaration
Swift
public static func == (lhs: BasicBlock, rhs: BasicBlock) -> Bool