|
1 | 1 | import cllvm
|
2 | 2 |
|
| 3 | +/// A subset of supported LLVM IR optimizer passes. |
3 | 4 | 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 |
41 | 127 | }
|
42 | 128 |
|
| 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. |
43 | 132 | 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) |
99 | 188 | }
|
| 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 | + } |
100 | 197 | }
|
0 commit comments