Skip to content

Commit 0a342be

Browse files
committed
Document PhiNode
1 parent 7f67a02 commit 0a342be

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

Sources/LLVMSwift/PhiNode.swift

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,47 @@
11
import cllvm
22

3+
/// A `PhiNode` object represents a PHI node.
4+
///
5+
/// Because all instructions in LLVM IR are in SSA (Single Static Assignment)
6+
/// form, a PHI node is necessary when the value of a variable assignment
7+
/// depends on the path the flow of control takes through the program. For
8+
/// example:
9+
///
10+
/// ```swift
11+
/// var a = 1
12+
/// if c == 42 {
13+
/// a = 2
14+
/// }
15+
/// let b = a
16+
/// ```
17+
///
18+
/// The value of `b` in this program depends on the value of the condition
19+
/// involving the variable `c`. Because `b` must be assigned to once, a PHI
20+
/// node is created and the program effectively is transformed into the
21+
/// following:
22+
///
23+
/// ```swift
24+
/// let aNoCond = 1
25+
/// if c == 42 {
26+
/// let aCondTrue = 2
27+
/// }
28+
/// let b = PHI(aNoCond, aCondTrue)
29+
/// ```
30+
///
31+
/// If the flow of control reaches `aCondTrue`, the value of `b` is `2`, else it
32+
/// is `1` and SSA semantics are preserved.
333
public struct PhiNode: IRValue {
434
internal let llvm: LLVMValueRef
5-
35+
36+
/// Adds a list of incoming value and their associated basic blocks to the end
37+
/// of the list of incoming values for this PHI node.
38+
///
39+
/// - parameter valueMap: A list of incoming values and their associated basic
40+
/// blocks.
641
public func addIncoming(_ valueMap: [(IRValue, BasicBlock)]) {
742
var values = valueMap.map { $0.0.asLLVM() as Optional }
843
var blocks = valueMap.map { $0.1.asLLVM() as Optional }
9-
44+
1045
values.withUnsafeMutableBufferPointer { valueBuf in
1146
blocks.withUnsafeMutableBufferPointer { blockBuf in
1247
LLVMAddIncoming(llvm,
@@ -16,27 +51,44 @@ public struct PhiNode: IRValue {
1651
}
1752
}
1853
}
19-
54+
55+
/// Obtain the incoming values and their associated basic blocks for this PHI
56+
/// node.
2057
public var incoming: [(IRValue, BasicBlock)] {
2158
let count = Int(LLVMCountIncoming(llvm))
2259
var values = [(IRValue, BasicBlock)]()
2360
for i in 0..<count {
2461
guard let value = incomingValue(at: i),
25-
let block = incomingBlock(at: i) else { continue }
62+
let block = incomingBlock(at: i) else { continue }
2663
values.append((value, block))
2764
}
2865
return values
2966
}
30-
67+
68+
/// Retrieves the incoming value for the given index for this PHI node, if it
69+
/// exists.
70+
///
71+
/// - parameter index: The index of the incoming value to retrieve.
72+
///
73+
/// - returns: A value representing the incoming value to this PHI node at
74+
/// the given index, if it exists.
3175
public func incomingValue(at index: Int) -> IRValue? {
3276
return LLVMGetIncomingValue(llvm, UInt32(index))
3377
}
34-
78+
79+
/// Retrieves the incoming basic block for the given index for this PHI node,
80+
/// if it exists.
81+
///
82+
/// - parameter index: The index of the incoming basic block to retrieve.
83+
///
84+
/// - returns: A value representing the incoming basic block to this PHI node
85+
/// at the given index, if it exists.
3586
public func incomingBlock(at index: Int) -> BasicBlock? {
3687
guard let blockRef = LLVMGetIncomingBlock(llvm, UInt32(index)) else { return nil }
3788
return BasicBlock(llvm: blockRef)
3889
}
39-
90+
91+
/// Retrieves the underlying LLVM value object.
4092
public func asLLVM() -> LLVMValueRef {
4193
return llvm
4294
}

0 commit comments

Comments
 (0)