klee
Optimize.cpp
Go to the documentation of this file.
1// FIXME: This file is a bastard child of opt.cpp and llvm-ld's
2// Optimize.cpp. This stuff should live in common code.
3
4
5//===- Optimize.cpp - Optimize a complete program -------------------------===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is distributed under the University of Illinois Open Source
10// License. See LICENSE.TXT for details.
11//
12//===----------------------------------------------------------------------===//
13//
14// This file implements all optimization of the linked module for llvm-ld.
15//
16//===----------------------------------------------------------------------===//
17
18#include "klee/Config/Version.h"
20
21#ifdef USE_WORKAROUND_LLVM_PR39177
22#include "Passes.h"
23#endif
24
25#include "llvm/Analysis/GlobalsModRef.h"
26#include "llvm/Analysis/Passes.h"
27#include "llvm/Analysis/LoopPass.h"
28#include "llvm/IR/Module.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/LegacyPassManager.h"
31#include "llvm/IR/Verifier.h"
32#include "llvm/Support/CommandLine.h"
33#include "llvm/Support/DynamicLibrary.h"
34#include "llvm/Support/PluginLoader.h"
35#include "llvm/Target/TargetMachine.h"
36#include "llvm/Transforms/IPO.h"
37#include "llvm/Transforms/IPO/FunctionAttrs.h"
38#include "llvm/Transforms/Scalar.h"
39#include "llvm/Transforms/Scalar/GVN.h"
40
41#if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
42#include "llvm/Transforms/Utils.h"
43#include "llvm/Transforms/InstCombine/InstCombine.h"
44#endif
45
46using namespace llvm;
47
48static cl::opt<bool>
49 DisableInline("disable-inlining",
50 cl::desc("Do not run the inliner pass (default=false)"),
51 cl::init(false), cl::cat(klee::ModuleCat));
52
53static cl::opt<bool> DisableInternalize(
54 "disable-internalize",
55 cl::desc("Do not mark all symbols as internal (default=false)"),
56 cl::init(false), cl::cat(klee::ModuleCat));
57
58static cl::opt<bool> VerifyEach(
59 "verify-each",
60 cl::desc("Verify intermediate results of all optimization passes (default=false)"),
61 cl::init(false),
62 cl::cat(klee::ModuleCat));
63
64static cl::alias ExportDynamic("export-dynamic",
65 cl::aliasopt(DisableInternalize),
66 cl::desc("Alias for -disable-internalize"));
67
68static cl::opt<bool>
69 Strip("strip-all", cl::desc("Strip all symbol information from executable"),
70 cl::init(false), cl::cat(klee::ModuleCat));
71
72static cl::alias A0("s", cl::desc("Alias for --strip-all"),
73 cl::aliasopt(Strip));
74
75static cl::opt<bool>
76 StripDebug("strip-debug",
77 cl::desc("Strip debugger symbol info from executable"),
78 cl::init(false), cl::cat(klee::ModuleCat));
79
80static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
81 cl::aliasopt(StripDebug));
82
83// A utility function that adds a pass to the pass manager but will also add
84// a verifier pass after if we're supposed to verify.
85static inline void addPass(legacy::PassManager &PM, Pass *P) {
86 // Add the pass to the pass manager...
87 PM.add(P);
88
89 // If we are verifying all of the intermediate steps, add the verifier...
90 if (VerifyEach)
91 PM.add(createVerifierPass());
92}
93
94namespace llvm {
95
96
97static void AddStandardCompilePasses(legacy::PassManager &PM) {
98 PM.add(createVerifierPass()); // Verify that input is correct
99
100 // If the -strip-debug command line option was specified, do it.
101 if (StripDebug)
102 addPass(PM, createStripSymbolsPass(true));
103
104 addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
105 addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
106 addPass(PM, createGlobalOptimizerPass()); // Optimize out global vars
107 addPass(PM, createGlobalDCEPass()); // Remove unused fns and globs
108#if LLVM_VERSION_CODE >= LLVM_VERSION(11, 0)
109 addPass(PM, createSCCPPass()); // Constant prop with SCCP
110#else
111 addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
112#endif
113 addPass(PM, createDeadArgEliminationPass()); // Dead argument elimination
114 addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
115 addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE
116
117 addPass(PM, createPruneEHPass()); // Remove dead EH info
118 addPass(PM, createPostOrderFunctionAttrsLegacyPass());
119 addPass(PM, createReversePostOrderFunctionAttrsPass()); // Deduce function attrs
120
121 if (!DisableInline)
122 addPass(PM, createFunctionInliningPass()); // Inline small functions
123 addPass(PM, createArgumentPromotionPass()); // Scalarize uninlined fn args
124
125 addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
126 addPass(PM, createJumpThreadingPass()); // Thread jumps.
127 addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
128 addPass(PM, createSROAPass()); // Break up aggregate allocas
129 addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
130
131 addPass(PM, createTailCallEliminationPass()); // Eliminate tail calls
132 addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
133 addPass(PM, createReassociatePass()); // Reassociate expressions
134 addPass(PM, createLoopRotatePass());
135 addPass(PM, createLICMPass()); // Hoist loop invariants
136 addPass(PM, createLoopUnswitchPass()); // Unswitch loops.
137 // FIXME : Removing instcombine causes nestedloop regression.
138 addPass(PM, createInstructionCombiningPass());
139 addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
140 addPass(PM, createLoopDeletionPass()); // Delete dead loops
141 addPass(PM, createLoopUnrollPass()); // Unroll small loops
142 addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
143 addPass(PM, createGVNPass()); // Remove redundancies
144 addPass(PM, createMemCpyOptPass()); // Remove memcpy / form memset
145 addPass(PM, createSCCPPass()); // Constant prop with SCCP
146
147 // Run instcombine after redundancy elimination to exploit opportunities
148 // opened up by them.
149 addPass(PM, createInstructionCombiningPass());
150
151 addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores
152 addPass(PM, createAggressiveDCEPass()); // Delete dead instructions
153 addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
154 addPass(PM, createStripDeadPrototypesPass()); // Get rid of dead prototypes
155 addPass(PM, createConstantMergePass()); // Merge dup global constants
156}
157
161void Optimize(Module *M, llvm::ArrayRef<const char *> preservedFunctions) {
162
163 // Instantiate the pass manager to organize the passes.
164 legacy::PassManager Passes;
165
166 // If we're verifying, start off with a verification pass.
167 if (VerifyEach)
168 Passes.add(createVerifierPass());
169
170#ifdef USE_WORKAROUND_LLVM_PR39177
171 addPass(Passes, new klee::WorkaroundLLVMPR39177Pass());
172#endif
173
174 // DWD - Run the opt standard pass list as well.
176
177 // Now that composite has been compiled, scan through the module, looking
178 // for a main function. If main is defined, mark all other functions
179 // internal.
180 if (!DisableInternalize) {
181 auto PreserveFunctions = [=](const GlobalValue &GV) {
182 StringRef GVName = GV.getName();
183
184 for (const char *fun : preservedFunctions)
185 if (GVName.equals(fun))
186 return true;
187
188 return false;
189 };
190 ModulePass *pass = createInternalizePass(PreserveFunctions);
191 addPass(Passes, pass);
192 }
193
194 // Propagate constants at call sites into the functions they call. This
195 // opens opportunities for globalopt (and inlining) by substituting function
196 // pointers passed as arguments to direct uses of functions.
197 addPass(Passes, createIPSCCPPass());
198
199 // Now that we internalized some globals, see if we can hack on them!
200 addPass(Passes, createGlobalOptimizerPass());
201
202 // Linking modules together can lead to duplicated global constants, only
203 // keep one copy of each constant...
204 addPass(Passes, createConstantMergePass());
205
206 // Remove unused arguments from functions...
207 addPass(Passes, createDeadArgEliminationPass());
208
209 // Reduce the code after globalopt and ipsccp. Both can open up significant
210 // simplification opportunities, and both can propagate functions through
211 // function pointers. When this happens, we often have to resolve varargs
212 // calls, etc, so let instcombine do this.
213 addPass(Passes, createInstructionCombiningPass());
214
215 if (!DisableInline)
216 addPass(Passes, createFunctionInliningPass()); // Inline small functions
217
218 addPass(Passes, createPruneEHPass()); // Remove dead EH info
219 addPass(Passes, createGlobalOptimizerPass()); // Optimize globals again.
220 addPass(Passes, createGlobalDCEPass()); // Remove dead functions
221
222 // If we didn't decide to inline a function, check to see if we can
223 // transform it to pass arguments by value instead of by reference.
224 addPass(Passes, createArgumentPromotionPass());
225
226 // The IPO passes may leave cruft around. Clean up after them.
227 addPass(Passes, createInstructionCombiningPass());
228 addPass(Passes, createJumpThreadingPass()); // Thread jumps.
229 addPass(Passes, createSROAPass()); // Break up allocas
230
231 // Run a few AA driven optimizations here and now, to cleanup the code.
232 addPass(Passes, createPostOrderFunctionAttrsLegacyPass());
233 addPass(Passes, createReversePostOrderFunctionAttrsPass()); // Add nocapture
234 addPass(Passes, createGlobalsAAWrapperPass()); // IP alias analysis
235
236 addPass(Passes, createLICMPass()); // Hoist loop invariants
237 addPass(Passes, createGVNPass()); // Remove redundancies
238 addPass(Passes, createMemCpyOptPass()); // Remove dead memcpy's
239 addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores
240
241 // Cleanup and simplify the code after the scalar optimizations.
242 addPass(Passes, createInstructionCombiningPass());
243
244 addPass(Passes, createJumpThreadingPass()); // Thread jumps.
245 addPass(Passes, createPromoteMemoryToRegisterPass()); // Cleanup jumpthread.
246
247 // Delete basic blocks, which optimization passes may have killed...
248 addPass(Passes, createCFGSimplificationPass());
249
250 // Now that we have optimized the program, discard unreachable functions...
251 addPass(Passes, createGlobalDCEPass());
252
253 // If the -s or -S command line options were specified, strip the symbols out
254 // of the resulting program to make it smaller. -s and -S are GNU ld options
255 // that we are supporting; they alias -strip-all and -strip-debug.
256 if (Strip || StripDebug)
257 addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));
258
259 // The user's passes may leave cruft around; clean up after them.
260 addPass(Passes, createInstructionCombiningPass());
261 addPass(Passes, createCFGSimplificationPass());
262 addPass(Passes, createAggressiveDCEPass());
263 addPass(Passes, createGlobalDCEPass());
264
265 // Run our queue of passes all at once now, efficiently.
266 Passes.run(*M);
267}
268}
static cl::opt< bool > Strip("strip-all", cl::desc("Strip all symbol information from executable"), cl::init(false), cl::cat(klee::ModuleCat))
static cl::opt< bool > StripDebug("strip-debug", cl::desc("Strip debugger symbol info from executable"), cl::init(false), cl::cat(klee::ModuleCat))
static void addPass(legacy::PassManager &PM, Pass *P)
Definition: Optimize.cpp:85
static cl::opt< bool > DisableInline("disable-inlining", cl::desc("Do not run the inliner pass (default=false)"), cl::init(false), cl::cat(klee::ModuleCat))
static cl::alias A1("S", cl::desc("Alias for --strip-debug"), cl::aliasopt(StripDebug))
static cl::alias A0("s", cl::desc("Alias for --strip-all"), cl::aliasopt(Strip))
static cl::opt< bool > DisableInternalize("disable-internalize", cl::desc("Do not mark all symbols as internal (default=false)"), cl::init(false), cl::cat(klee::ModuleCat))
static cl::alias ExportDynamic("export-dynamic", cl::aliasopt(DisableInternalize), cl::desc("Alias for -disable-internalize"))
static cl::opt< bool > VerifyEach("verify-each", cl::desc("Verify intermediate results of all optimization passes (default=false)"), cl::init(false), cl::cat(klee::ModuleCat))
llvm::cl::OptionCategory ModuleCat
static void AddStandardCompilePasses(legacy::PassManager &PM)
Definition: Optimize.cpp:97
void Optimize(Module *, llvm::ArrayRef< const char * > preservedFunctions)
Definition: Optimize.cpp:161