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