opt.cpp revision 22d26d7c7d7c9666d0da0e51250586da5a0744da
10eafc31684d6c512c6a56868031b8c1cc4ab4ed6Chris Lattner//===----------------------------------------------------------------------===// 2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// LLVM 'OPT' UTILITY 3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// Optimizations may be specified an arbitrary number of times on the command 5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// line, they are run in the order specified. 6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 70eafc31684d6c512c6a56868031b8c1cc4ab4ed6Chris Lattner//===----------------------------------------------------------------------===// 8009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h" 10fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner#include "llvm/PassManager.h" 11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Bytecode/Reader.h" 12fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner#include "llvm/Bytecode/WriteBytecodePass.h" 13ffa6f9ca062d410ff25c8d11907f182d022f274dChris Lattner#include "llvm/Assembly/PrintModulePass.h" 1422d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner#include "llvm/Analysis/Verifier.h" 150be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner#include "llvm/Transforms/UnifyMethodExitNodes.h" 169effd69ca2fe4d20b8a0dcbf4f9d5d4a402c536dChris Lattner#include "llvm/Transforms/ConstantMerge.h" 17e166fe19103bf82c2e464b478c1735acd2bbcc59Chris Lattner#include "llvm/Transforms/CleanupGCCOutput.h" 18068f487ee59a703a6e52ed5b96e222cbf632374aChris Lattner#include "llvm/Transforms/LevelChange.h" 1959b6b8e0b3e51dd899da25bd25b0793cc8229eeaChris Lattner#include "llvm/Transforms/MethodInlining.h" 2059b6b8e0b3e51dd899da25bd25b0793cc8229eeaChris Lattner#include "llvm/Transforms/SymbolStripping.h" 21d7db863c1d03593bb633f67e76c6e9f8f0f40662Chris Lattner#include "llvm/Transforms/ChangeAllocations.h" 2204c85dcad8f67d2bb2e0e5d051d130f90e473d86Chris Lattner#include "llvm/Transforms/IPO/SimpleStructMutation.h" 2363202328d3dac33322f564889cd44126912102e6Chris Lattner#include "llvm/Transforms/IPO/GlobalDCE.h" 2459b6b8e0b3e51dd899da25bd25b0793cc8229eeaChris Lattner#include "llvm/Transforms/Scalar/DCE.h" 2559b6b8e0b3e51dd899da25bd25b0793cc8229eeaChris Lattner#include "llvm/Transforms/Scalar/ConstantProp.h" 26fe196cf98be05d5fe0ace90e5de8195f9d556f6dChris Lattner#include "llvm/Transforms/Scalar/IndVarSimplify.h" 27528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner#include "llvm/Transforms/Scalar/InstructionCombining.h" 28eeeaf52ab6918ce309ad5e14f1e226e5c1d2c9a9Chris Lattner#include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h" 2959b6b8e0b3e51dd899da25bd25b0793cc8229eeaChris Lattner#include "llvm/Transforms/Instrumentation/TraceValues.h" 30cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h" 3173e11d77aaa09d5b126aef0b600c31ebd1206c3dChris Lattner#include <fstream> 3263202328d3dac33322f564889cd44126912102e6Chris Lattner#include <memory> 3395781b6ca95ec63364853037fe974f0d827c4d5eChris Lattner 34fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// Opts enum - All of the transformations we can do... 358f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerenum Opts { 368f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner // Basic optimizations 370be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner dce, constprop, inlining, constmerge, strip, mstrip, mergereturn, 388f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner 390eafc31684d6c512c6a56868031b8c1cc4ab4ed6Chris Lattner // Miscellaneous Transformations 4022d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner trace, tracem, raiseallocs, cleangcc, 4122d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner 4222d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner // Printing and verifying... 4322d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner print, verify, 440eafc31684d6c512c6a56868031b8c1cc4ab4ed6Chris Lattner 458f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner // More powerful optimizations 46eeeaf52ab6918ce309ad5e14f1e226e5c1d2c9a9Chris Lattner indvars, instcombine, sccp, adce, raise, mem2reg, 4763202328d3dac33322f564889cd44126912102e6Chris Lattner 4863202328d3dac33322f564889cd44126912102e6Chris Lattner // Interprocedural optimizations... 49f4de63f65fa995e68e3cd268117ab065068be413Chris Lattner globaldce, swapstructs, sortstructs, 508f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner}; 518f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner 52fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 53fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// New template functions - Provide functions that return passes of specified 54fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// types, with specified arguments... 55fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// 56fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattnertemplate<class PassClass> 57fb1b3f119df25de495fcd53e675d6c9991f5664eChris LattnerPass *New() { 58fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner return new PassClass(); 59fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner} 60fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 61fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattnertemplate<class PassClass, typename ArgTy1, ArgTy1 Arg1> 62fb1b3f119df25de495fcd53e675d6c9991f5664eChris LattnerPass *New() { 63fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner return new PassClass(Arg1); 64fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner} 65fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 66fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattnertemplate<class PassClass, typename ArgTy1, ArgTy1 Arg1, 67fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner typename ArgTy2, ArgTy1 Arg2> 68fb1b3f119df25de495fcd53e675d6c9991f5664eChris LattnerPass *New() { 69fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner return new PassClass(Arg1, Arg2); 70fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner} 71fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 72fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattnerstatic Pass *NewPrintMethodPass() { 73fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner return new PrintMethodPass("Current Method: \n", &cerr); 74fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner} 75fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 76fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// OptTable - Correlate enum Opts to Pass constructors... 77fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// 78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerstruct { 798f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner enum Opts OptID; 80fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner Pass * (*PassCtor)(); 81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} OptTable[] = { 82fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { dce , New<DeadCodeElimination> }, 83fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { constprop , New<ConstantPropogation> }, 84fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { inlining , New<MethodInlining> }, 85fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { constmerge , New<ConstantMerge> }, 86fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { strip , New<SymbolStripping> }, 87fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { mstrip , New<FullSymbolStripping> }, 880be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner { mergereturn, New<UnifyMethodExitNodes> }, 890be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner 90fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { indvars , New<InductionVariableSimplify> }, 91fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { instcombine, New<InstructionCombining> }, 92fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { sccp , New<SCCPPass> }, 93fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { adce , New<AgressiveDCE> }, 94fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { raise , New<RaisePointerReferences> }, 95eeeaf52ab6918ce309ad5e14f1e226e5c1d2c9a9Chris Lattner { mem2reg , newPromoteMemoryToRegister }, 96eeeaf52ab6918ce309ad5e14f1e226e5c1d2c9a9Chris Lattner 97fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { trace , New<InsertTraceCode, bool, true, bool, true> }, 98fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { tracem , New<InsertTraceCode, bool, false, bool, true> }, 99fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { print , NewPrintMethodPass }, 10022d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner { verify , createVerifierPass }, 101fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { raiseallocs, New<RaiseAllocations> }, 102fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { cleangcc , New<CleanupGCCOutput> }, 103fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { globaldce , New<GlobalDCE> }, 104fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { swapstructs, New<SimpleStructMutation, SimpleStructMutation::Transform, 105fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner SimpleStructMutation::SwapElements>}, 106fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner { sortstructs, New<SimpleStructMutation, SimpleStructMutation::Transform, 107fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner SimpleStructMutation::SortElements>}, 108009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}; 109009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 110fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// Command line option handling code... 111fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner// 112a8e1fd30ed00fe36dce42d2e4a09dbf83f778152Chris Lattnercl::String InputFilename ("", "Load <arg> file to optimize", cl::NoFlags, "-"); 113a8e1fd30ed00fe36dce42d2e4a09dbf83f778152Chris Lattnercl::String OutputFilename("o", "Override output filename", cl::NoFlags, ""); 114a8e1fd30ed00fe36dce42d2e4a09dbf83f778152Chris Lattnercl::Flag Force ("f", "Overwrite output files", cl::NoFlags, false); 115fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattnercl::Flag PrintEachXForm("p", "Print module after each transformation"); 1168f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnercl::Flag Quiet ("q", "Don't print modifying pass names", 0, false); 117a8e1fd30ed00fe36dce42d2e4a09dbf83f778152Chris Lattnercl::Alias QuietA ("quiet", "Alias for -q", cl::NoFlags, Quiet); 1188f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnercl::EnumList<enum Opts> OptimizationList(cl::NoFlags, 119528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(dce , "Dead Code Elimination"), 1200be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner clEnumVal(constprop , "Simple constant propogation"), 1210be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner clEnumValN(inlining , "inline", "Method integration"), 122528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(constmerge , "Merge identical global constants"), 1230be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner clEnumVal(strip , "Strip symbols"), 1240be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner clEnumVal(mstrip , "Strip module symbols"), 1250be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner clEnumVal(mergereturn, "Unify method exit nodes"), 1260be4101d12bd134a3e707a47a2f3441ef06a26aeChris Lattner 127528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(indvars , "Simplify Induction Variables"), 128fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner clEnumVal(instcombine, "Combine redundant instructions"), 129528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(sccp , "Sparse Conditional Constant Propogation"), 130528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(adce , "Agressive DCE"), 131eeeaf52ab6918ce309ad5e14f1e226e5c1d2c9a9Chris Lattner clEnumVal(mem2reg , "Promote alloca locations to registers"), 132854acb996e63787623dd5a7e8c470ccf3624e77cChris Lattner 133528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(globaldce , "Remove unreachable globals"), 13463202328d3dac33322f564889cd44126912102e6Chris Lattner clEnumVal(swapstructs, "Swap structure types around"), 135f4de63f65fa995e68e3cd268117ab065068be413Chris Lattner clEnumVal(sortstructs, "Sort structure elements"), 13663202328d3dac33322f564889cd44126912102e6Chris Lattner 1375048c3b853b8be541479e300705a88375569c8b1Chris Lattner clEnumVal(raiseallocs, "Raise allocations from calls to instructions"), 138528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(cleangcc , "Cleanup GCC Output"), 139528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(raise , "Raise to Higher Level"), 140528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(trace , "Insert BB & Method trace code"), 141528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(tracem , "Insert Method trace code only"), 14222d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner 143528e8b58a52c6f5b6a2a694059679c04a49111c9Chris Lattner clEnumVal(print , "Print working method to stderr"), 14422d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner clEnumVal(verify , "Verify module is well formed"), 1458f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner0); 146009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 147fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 1498f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) { 1508f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner cl::ParseCommandLineOptions(argc, argv, 1518f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner " llvm .bc -> .bc modular optimizer\n"); 152fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 153fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Load the input module... 15463202328d3dac33322f564889cd44126912102e6Chris Lattner std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 15563202328d3dac33322f564889cd44126912102e6Chris Lattner if (M.get() == 0) { 156009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cerr << "bytecode didn't read correctly.\n"; 157009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 1; 158009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 159009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 160fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Figure out what stream we are supposed to write to... 161697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::ostream *Out = &std::cout; // Default to printing to stdout... 1621e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner if (OutputFilename != "") { 163888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner if (!Force && std::ifstream(OutputFilename.c_str())) { 164697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner // If force is not specified, make sure not to overwrite a file! 165697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "Error opening '" << OutputFilename << "': File exists!\n" 166697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << "Use -f command line argument to force output\n"; 167697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner return 1; 168697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } 169697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Out = new std::ofstream(OutputFilename.c_str()); 170697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner 171009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!Out->good()) { 1721e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner cerr << "Error opening " << OutputFilename << "!\n"; 173009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 1; 174009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 175009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 176009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 177fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Create a PassManager to hold and optimize the collection of passes we are 178fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // about to build... 179fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // 180fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner PassManager Passes; 181fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 182fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Create a new optimization pass for each one specified on the command line 183fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner for (unsigned i = 0; i < OptimizationList.size(); ++i) { 184fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner enum Opts Opt = OptimizationList[i]; 185fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner for (unsigned j = 0; j < sizeof(OptTable)/sizeof(OptTable[0]); ++j) 186fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner if (Opt == OptTable[j].OptID) { 187fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner Passes.add(OptTable[j].PassCtor()); 188fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner break; 189fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner } 190fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 191fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner if (PrintEachXForm) 192fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner Passes.add(new PrintModulePass(&std::cerr)); 193fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner } 194fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 19522d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner // Check that the module is well formed on completion of optimization 19622d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner Passes.add(createVerifierPass()); 19722d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner 198fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Write bytecode out to disk or cout as the last step... 199fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner Passes.add(new WriteBytecodePass(Out, Out != &std::cout)); 200fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner 201fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner // Now that we have all of the passes ready, run them. 202fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner if (Passes.run(M.get()) && !Quiet) 203fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner cerr << "Program modified.\n"; 204009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 205009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 0; 206009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 207