1
1
#if SWIFT_PACKAGE
2
2
import cllvm
3
+ import llvmshims
3
4
#endif
4
5
5
6
/// A `Function` represents a named function body in LLVM IR source. Functions
6
7
/// in LLVM IR encapsulate a list of parameters and a sequence of basic blocks
7
8
/// and provide a way to append to that sequence to build out its body.
9
+ ///
10
+ /// A LLVM function definition contains a list of basic blocks, starting with
11
+ /// a privileged first block called the "entry block". After the entry blocks'
12
+ /// terminating instruction come zero or more other basic blocks. The path the
13
+ /// flow of control can potentially take, from each block to its terminator
14
+ /// and on to other blocks, forms the "Control Flow Graph" (CFG) for the
15
+ /// function. The nodes of the CFG are the basic blocks, and the edges are
16
+ /// directed from the terminator instruction of one block to any number of
17
+ /// potential target blocks.
18
+ ///
19
+ /// Additional basic blocks may be created and appended to the function at
20
+ /// any time.
21
+ ///
22
+ /// let module = Module(name: "Example")
23
+ /// let builder = IRBuilder(module: module)
24
+ /// let fun = builder.addFunction("example",
25
+ /// type: FunctionType(argTypes: [],
26
+ /// returnType: VoidType()))
27
+ /// // Create and append the entry block
28
+ /// let entryBB = fun.appendBasicBlock(named: "entry")
29
+ /// // Create and append a standalone basic block
30
+ /// let freestanding = BasicBlock(name: "freestanding")
31
+ /// fun.append(freestanding)
32
+ ///
33
+ /// An LLVM function always has the type `FunctionType`. This type is used to
34
+ /// determine the number and kind of parameters to the function as well as its
35
+ /// return value, if any. The parameter values, which would normally enter
36
+ /// the entry block, are instead attached to the function and are accessible
37
+ /// via the `parameters` property.
38
+ ///
39
+ /// Calling Convention
40
+ /// ==================
41
+ ///
42
+ /// By default, all functions in LLVM are invoked with the C calling convention
43
+ /// but the exact calling convention of both a function declaration and a
44
+ /// `call` instruction are fully configurable.
45
+ ///
46
+ /// let module = Module(name: "Example")
47
+ /// let builder = IRBuilder(module: module)
48
+ /// let fun = builder.addFunction("example",
49
+ /// type: FunctionType(argTypes: [],
50
+ /// returnType: VoidType()))
51
+ /// // Switch to swiftcc
52
+ /// fun.callingConvention = .swift
53
+ ///
54
+ /// The calling convention of a function and a corresponding call instruction
55
+ /// must match or the result is undefined.
56
+ ///
57
+ /// Sections
58
+ /// ========
59
+ ///
60
+ /// A function may optionally state the section in the object file it
61
+ /// should reside in through the use of a metadata attachment. This can be
62
+ /// useful to satisfy target-specific data layout constraints, or to provide
63
+ /// some hints to optimizers and linkers. LLVMSwift provides a convenience
64
+ /// object called an `MDBuilder` to assist in the creation of this metadata.
65
+ ///
66
+ /// let mdBuilder = MDBuilder()
67
+ /// // __attribute__((hot))
68
+ /// let hotAttr = mdBuilder.buildFunctionSectionPrefix(".hot")
69
+ ///
70
+ /// let module = Module(name: "Example")
71
+ /// let builder = IRBuilder(module: module)
72
+ /// let fun = builder.addFunction("example",
73
+ /// type: FunctionType(argTypes: [],
74
+ /// returnType: VoidType()))
75
+ /// // Attach the metadata
76
+ /// fun.addMetadata(hotAttr, kind: .sectionPrefix)
77
+ ///
78
+ /// For targets that support it, a function may also specify a COMDAT section.
79
+ ///
80
+ /// fun.comdat = module.comdat(named: "example")
81
+ ///
82
+ /// Debug Information
83
+ /// =================
84
+ ///
85
+ /// A function may also carry debug information through special subprogram
86
+ /// nodes. These nodes are intended to capture the structure of the function
87
+ /// as it appears in the source so that it is available for inspection by a
88
+ /// debugger. See `DIBuilderr.buildFunction` for more information.
8
89
public class Function : IRGlobal {
9
90
internal let llvm : LLVMValueRef
10
91
internal init ( llvm: LLVMValueRef ) {
@@ -26,17 +107,6 @@ public class Function: IRGlobal {
26
107
}
27
108
28
109
/// Retrieves the entry block of this function.
29
- ///
30
- /// The first basic block in a function is special in two ways: it is
31
- /// immediately executed on entrance to the function, and it is not allowed to
32
- /// have predecessor basic blocks (i.e. there can not be any branches to the
33
- /// entry block of a function). Because the block can have no predecessors, it
34
- /// also cannot have any PHI nodes.
35
- ///
36
- /// The entry block is also special in that any static allocas emitted into it
37
- /// influence the layout of the stack frame of the function at code generation
38
- /// time. It is therefore often more efficient to emit static allocas in the
39
- /// entry block than anywhere else in the function.
40
110
public var entryBlock : BasicBlock ? {
41
111
guard let blockRef = LLVMGetEntryBasicBlock ( llvm) else { return nil }
42
112
return BasicBlock ( llvm: blockRef)
@@ -78,7 +148,7 @@ public class Function: IRGlobal {
78
148
79
149
/// Computes the address of the specified basic block in this function.
80
150
///
81
- /// Taking the address of the entry block is illegal.
151
+ /// - WARNING: Taking the address of the entry block is illegal.
82
152
///
83
153
/// This value only has defined behavior when used as an operand to the
84
154
/// `indirectbr` instruction, or for comparisons against null. Pointer
@@ -170,6 +240,13 @@ public class Function: IRGlobal {
170
240
return BasicBlock ( llvm: block)
171
241
}
172
242
243
+ /// Appends the named basic block to the body of this function.
244
+ ///
245
+ /// - parameter basicBlock: The block to append.
246
+ public func append( _ basicBlock: BasicBlock ) {
247
+ LLVMAppendExistingBasicBlock ( llvm, basicBlock. asLLVM ( ) )
248
+ }
249
+
173
250
/// Deletes the function from its containing module.
174
251
/// - note: This does not remove calls to this function from the
175
252
/// module. Ensure you have removed all instructions that reference
0 commit comments