Skip to content

Commit 6f81801

Browse files
CodaFiharlanhaskins
authored andcommitted
Document the pass manager (#5)
1 parent 0ad6b1c commit 6f81801

File tree

1 file changed

+189
-92
lines changed

1 file changed

+189
-92
lines changed

Sources/LLVMSwift/PassManager.swift

Lines changed: 189 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,197 @@
11
import cllvm
22

3+
/// A subset of supported LLVM IR optimizer passes.
34
public enum FunctionPass {
4-
case aggressiveDCE
5-
case bitTrackingDCE
6-
case alignmentFromAssumptions
7-
case cfgSimplification
8-
case deadStoreElimination
9-
case scalarizer
10-
case mergedLoadStoreMotion
11-
case gvn
12-
case indVarSimplify
13-
case instructionCombining
14-
case jumpThreading
15-
case licm
16-
case loopDeletion
17-
case loopIdiom
18-
case loopRotate
19-
case loopReroll
20-
case loopUnroll
21-
case loopUnswitch
22-
case memCpyOpt
23-
case partiallyInlineLibCalls
24-
case lowerSwitch
25-
case promoteMemoryToRegister
26-
case reassociate
27-
case sccp
28-
case scalarReplAggregates
29-
case scalarReplAggregatesSSA
30-
case simplifyLibCalls
31-
case tailCallElimination
32-
case constantPropagation
33-
case demoteMemoryToRegister
34-
case verifier
35-
case correlatedValuePropagation
36-
case earlyCSE
37-
case lowerExpectIntrinsic
38-
case typeBasedAliasAnalysis
39-
case scopedNoAliasAA
40-
case basicAliasAnalysis
5+
/// This pass uses the SSA based Aggressive DCE algorithm. This algorithm
6+
/// assumes instructions are dead until proven otherwise, which makes
7+
/// it more successful are removing non-obviously dead instructions.
8+
case aggressiveDCE
9+
/// This pass uses a bit-tracking DCE algorithm in order to remove
10+
/// computations of dead bits.
11+
case bitTrackingDCE
12+
/// Use assume intrinsics to set load/store alignments.
13+
case alignmentFromAssumptions
14+
/// Merge basic blocks, eliminate unreachable blocks, simplify terminator
15+
/// instructions, etc.
16+
case cfgSimplification
17+
/// This pass deletes stores that are post-dominated by must-aliased stores
18+
/// and are not loaded used between the stores.
19+
case deadStoreElimination
20+
/// Converts vector operations into scalar operations.
21+
case scalarizer
22+
/// This pass merges loads and stores in diamonds. Loads are hoisted into the
23+
/// header, while stores sink into the footer.
24+
case mergedLoadStoreMotion
25+
/// This pass performs global value numbering and redundant load elimination
26+
/// cotemporaneously.
27+
case gvn
28+
/// Transform induction variables in a program to all use a single canonical
29+
/// induction variable per loop.
30+
case indVarSimplify
31+
/// Combine instructions to form fewer, simple instructions. This pass does
32+
/// not modify the CFG, and has a tendency to make instructions dead, so a
33+
/// subsequent DCE pass is useful.
34+
///
35+
/// This pass combines things like:
36+
/// ```asm
37+
/// %Y = add int 1, %X
38+
/// %Z = add int 1, %Y
39+
/// ```
40+
/// into:
41+
/// ```asm
42+
/// %Z = add int 2, %X
43+
/// ```
44+
case instructionCombining
45+
/// Thread control through mult-pred/multi-succ blocks where some preds
46+
/// always go to some succ. Thresholds other than minus one override the
47+
/// internal BB duplication default threshold.
48+
case jumpThreading
49+
/// This pass is a loop invariant code motion and memory promotion pass.
50+
case licm
51+
/// This pass performs DCE of non-infinite loops that it can prove are dead.
52+
case loopDeletion
53+
/// This pass recognizes and replaces idioms in loops.
54+
case loopIdiom
55+
/// This pass is a simple loop rotating pass.
56+
case loopRotate
57+
/// This pass is a simple loop rerolling pass.
58+
case loopReroll
59+
/// This pass is a simple loop unrolling pass.
60+
case loopUnroll
61+
/// This pass is a simple loop unswitching pass.
62+
case loopUnswitch
63+
/// This pass performs optimizations related to eliminating `memcpy` calls
64+
/// and/or combining multiple stores into memset's.
65+
case memCpyOpt
66+
/// Tries to inline the fast path of library calls such as sqrt.
67+
case partiallyInlineLibCalls
68+
/// This pass converts SwitchInst instructions into a sequence of chained
69+
/// binary branch instructions.
70+
case lowerSwitch
71+
/// This pass is used to promote memory references to
72+
/// be register references. A simple example of the transformation performed
73+
/// by this pass is going from code like this:
74+
///
75+
/// ```asm
76+
/// %X = alloca i32, i32 1
77+
/// store i32 42, i32 *%X
78+
/// %Y = load i32* %X
79+
/// ret i32 %Y
80+
/// ```
81+
///
82+
/// To code like this:
83+
///
84+
/// ```asm
85+
/// ret i32 42
86+
/// ```
87+
case promoteMemoryToRegister
88+
/// This pass reassociates commutative expressions in an order that
89+
/// is designed to promote better constant propagation, GCSE, LICM, PRE, etc.
90+
///
91+
/// For example:
92+
/// ```
93+
/// 4 + (x + 5) -> x + (4 + 5)
94+
/// ```
95+
case reassociate
96+
/// Sparse conditional constant propagation.
97+
case sccp
98+
/// Replace aggregates or pieces of aggregates with scalar SSA values.
99+
case scalarReplAggregates
100+
/// Replace aggregates or pieces of aggregates with scalar SSA values.
101+
case scalarReplAggregatesSSA
102+
/// Tries to inline the fast path of library calls such as sqrt.
103+
case simplifyLibCalls
104+
/// This pass eliminates call instructions to the current function which occur
105+
/// immediately before return instructions.
106+
case tailCallElimination
107+
/// A worklist driven constant propagation pass.
108+
case constantPropagation
109+
/// This pass is used to demote registers to memory references. It basically
110+
/// undoes the `.promoteMemoryToRegister` pass to make CFG hacking easier.
111+
case demoteMemoryToRegister
112+
/// Propagate CFG-derived value information
113+
case correlatedValuePropagation
114+
/// This pass performs a simple and fast CSE pass over the dominator tree.
115+
case earlyCSE
116+
/// Removes `llvm.expect` intrinsics and creates "block_weights" metadata.
117+
case lowerExpectIntrinsic
118+
/// Adds metadata to LLVM IR types and performs metadata-based TBAA.
119+
case typeBasedAliasAnalysis
120+
/// Adds metadata to LLVM IR types and performs metadata-based scoped no-alias
121+
/// analysis.
122+
case scopedNoAliasAA
123+
/// LLVM's primary stateless and local alias analysis.
124+
case basicAliasAnalysis
125+
/// Runs the LLVM IR Verifier to sanity check the results of passes.
126+
case verifier
41127
}
42128

129+
/// A `FunctionPassManager` is an object that collects a sequence of passes
130+
/// which run over a particular IR construct, and runs each of them in sequence
131+
/// over each such construct.
43132
public class FunctionPassManager {
44-
internal let llvm: LLVMPassManagerRef
45-
46-
private static let passMapping: [FunctionPass: (LLVMPassManagerRef) -> Void] = [
47-
.aggressiveDCE: LLVMAddAggressiveDCEPass,
48-
.bitTrackingDCE: LLVMAddBitTrackingDCEPass,
49-
.alignmentFromAssumptions: LLVMAddAlignmentFromAssumptionsPass,
50-
.cfgSimplification: LLVMAddCFGSimplificationPass,
51-
.deadStoreElimination: LLVMAddDeadStoreEliminationPass,
52-
.scalarizer: LLVMAddScalarizerPass,
53-
.mergedLoadStoreMotion: LLVMAddMergedLoadStoreMotionPass,
54-
.gvn: LLVMAddGVNPass,
55-
.indVarSimplify: LLVMAddIndVarSimplifyPass,
56-
.instructionCombining: LLVMAddInstructionCombiningPass,
57-
.jumpThreading: LLVMAddJumpThreadingPass,
58-
.licm: LLVMAddLICMPass,
59-
.loopDeletion: LLVMAddLoopDeletionPass,
60-
.loopIdiom: LLVMAddLoopIdiomPass,
61-
.loopRotate: LLVMAddLoopRotatePass,
62-
.loopReroll: LLVMAddLoopRerollPass,
63-
.loopUnroll: LLVMAddLoopUnrollPass,
64-
.loopUnswitch: LLVMAddLoopUnswitchPass,
65-
.memCpyOpt: LLVMAddMemCpyOptPass,
66-
.partiallyInlineLibCalls: LLVMAddPartiallyInlineLibCallsPass,
67-
.lowerSwitch: LLVMAddLowerSwitchPass,
68-
.promoteMemoryToRegister: LLVMAddPromoteMemoryToRegisterPass,
69-
.reassociate: LLVMAddReassociatePass,
70-
.sccp: LLVMAddSCCPPass,
71-
.scalarReplAggregates: LLVMAddScalarReplAggregatesPass,
72-
.scalarReplAggregatesSSA: LLVMAddScalarReplAggregatesPassSSA,
73-
.simplifyLibCalls: LLVMAddSimplifyLibCallsPass,
74-
.tailCallElimination: LLVMAddTailCallEliminationPass,
75-
.constantPropagation: LLVMAddConstantPropagationPass,
76-
.demoteMemoryToRegister: LLVMAddDemoteMemoryToRegisterPass,
77-
.verifier: LLVMAddVerifierPass,
78-
.correlatedValuePropagation: LLVMAddCorrelatedValuePropagationPass,
79-
.earlyCSE: LLVMAddEarlyCSEPass,
80-
.lowerExpectIntrinsic: LLVMAddLowerExpectIntrinsicPass,
81-
.typeBasedAliasAnalysis: LLVMAddTypeBasedAliasAnalysisPass,
82-
.scopedNoAliasAA: LLVMAddScopedNoAliasAAPass,
83-
.basicAliasAnalysis: LLVMAddBasicAliasAnalysisPass,
84-
]
85-
86-
public init(module: Module) {
87-
llvm = LLVMCreateFunctionPassManagerForModule(module.llvm)!
88-
LLVMInitializeFunctionPassManager(llvm)
89-
}
90-
91-
public func add(_ passes: FunctionPass...) {
92-
for pass in passes {
93-
FunctionPassManager.passMapping[pass]!(llvm)
94-
}
95-
}
96-
97-
public func run(on function: Function) {
98-
LLVMRunFunctionPassManager(llvm, function.asLLVM())
133+
internal let llvm: LLVMPassManagerRef
134+
135+
private static let passMapping: [FunctionPass: (LLVMPassManagerRef) -> Void] = [
136+
.aggressiveDCE: LLVMAddAggressiveDCEPass,
137+
.bitTrackingDCE: LLVMAddBitTrackingDCEPass,
138+
.alignmentFromAssumptions: LLVMAddAlignmentFromAssumptionsPass,
139+
.cfgSimplification: LLVMAddCFGSimplificationPass,
140+
.deadStoreElimination: LLVMAddDeadStoreEliminationPass,
141+
.scalarizer: LLVMAddScalarizerPass,
142+
.mergedLoadStoreMotion: LLVMAddMergedLoadStoreMotionPass,
143+
.gvn: LLVMAddGVNPass,
144+
.indVarSimplify: LLVMAddIndVarSimplifyPass,
145+
.instructionCombining: LLVMAddInstructionCombiningPass,
146+
.jumpThreading: LLVMAddJumpThreadingPass,
147+
.licm: LLVMAddLICMPass,
148+
.loopDeletion: LLVMAddLoopDeletionPass,
149+
.loopIdiom: LLVMAddLoopIdiomPass,
150+
.loopRotate: LLVMAddLoopRotatePass,
151+
.loopReroll: LLVMAddLoopRerollPass,
152+
.loopUnroll: LLVMAddLoopUnrollPass,
153+
.loopUnswitch: LLVMAddLoopUnswitchPass,
154+
.memCpyOpt: LLVMAddMemCpyOptPass,
155+
.partiallyInlineLibCalls: LLVMAddPartiallyInlineLibCallsPass,
156+
.lowerSwitch: LLVMAddLowerSwitchPass,
157+
.promoteMemoryToRegister: LLVMAddPromoteMemoryToRegisterPass,
158+
.reassociate: LLVMAddReassociatePass,
159+
.sccp: LLVMAddSCCPPass,
160+
.scalarReplAggregates: LLVMAddScalarReplAggregatesPass,
161+
.scalarReplAggregatesSSA: LLVMAddScalarReplAggregatesPassSSA,
162+
.simplifyLibCalls: LLVMAddSimplifyLibCallsPass,
163+
.tailCallElimination: LLVMAddTailCallEliminationPass,
164+
.constantPropagation: LLVMAddConstantPropagationPass,
165+
.demoteMemoryToRegister: LLVMAddDemoteMemoryToRegisterPass,
166+
.verifier: LLVMAddVerifierPass,
167+
.correlatedValuePropagation: LLVMAddCorrelatedValuePropagationPass,
168+
.earlyCSE: LLVMAddEarlyCSEPass,
169+
.lowerExpectIntrinsic: LLVMAddLowerExpectIntrinsicPass,
170+
.typeBasedAliasAnalysis: LLVMAddTypeBasedAliasAnalysisPass,
171+
.scopedNoAliasAA: LLVMAddScopedNoAliasAAPass,
172+
.basicAliasAnalysis: LLVMAddBasicAliasAnalysisPass,
173+
]
174+
175+
/// Creates a `FunctionPassManager` bound to the given module's IR.
176+
public init(module: Module) {
177+
llvm = LLVMCreateFunctionPassManagerForModule(module.llvm)!
178+
LLVMInitializeFunctionPassManager(llvm)
179+
}
180+
181+
/// Adds the given passes to the pass manager.
182+
///
183+
/// - parameter passes: A list of function passes to add to the pass manager's
184+
/// list of passes to run.
185+
public func add(_ passes: FunctionPass...) {
186+
for pass in passes {
187+
FunctionPassManager.passMapping[pass]!(llvm)
99188
}
189+
}
190+
191+
/// Runs all listed functions in the pass manager on the given function.
192+
///
193+
/// - parameter function: The function to run listed passes on.
194+
public func run(on function: Function) {
195+
LLVMRunFunctionPassManager(llvm, function.asLLVM())
196+
}
100197
}

0 commit comments

Comments
 (0)