opt.cpp revision 452fea997232437902385e88366482b01957eeef
10eafc31684d6c512c6a56868031b8c1cc4ab4ed6Chris Lattner//===----------------------------------------------------------------------===//
2d4c7f2766bcf2cf87e562ea4e71cb4b54d81b74eChris Lattner// LLVM Modular Optimizer Utility: opt
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"
1518fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve#include "llvm/Target/TargetMachine.h"
166560b6b101635203068b0b32f544c2b3b577b59bChris Lattner#include "llvm/Target/TargetMachineImpls.h"
172053a2a2720ea93550b230da6ceac371014c20c2Chris Lattner#include "llvm/Support/PassNameParser.h"
1876d12299b5333d71bfc079614031f97c97aa5148Chris Lattner#include "Support/Signals.h"
1973e11d77aaa09d5b126aef0b600c31ebd1206c3dChris Lattner#include <fstream>
2063202328d3dac33322f564889cd44126912102e6Chris Lattner#include <memory>
21c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner#include <algorithm>
2263aaa11506f1edcd6e6073b1dbdbe02d678c8cfaAnand Shukla
2330af36808263fc256ead4fc50b639420b016a58dChris Lattner
24c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner// The OptimizationList is automatically populated with registered Passes by the
25c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner// PassNameParser.
26fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner//
272053a2a2720ea93550b230da6ceac371014c20c2Chris Lattnerstatic cl::list<const PassInfo*, bool,
282053a2a2720ea93550b230da6ceac371014c20c2Chris Lattner                FilteredPassNameParser<PassInfo::Optimization> >
29c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris LattnerOptimizationList(cl::desc("Optimizations available:"));
30009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
319d6e7eb74fce8dccaeb3f42c6392de727baff310Chris Lattner
32c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner// Other command line options...
33fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner//
346c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattnerstatic cl::opt<std::string>
355ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerInputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
365ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
376c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattnerstatic cl::opt<std::string>
385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Override output filename"),
395ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner               cl::value_desc("filename"));
405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
415ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerForce("f", cl::desc("Overwrite output files"));
435ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
445ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
455ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerPrintEachXForm("p", cl::desc("Print module after each transformation"));
465ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
475ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
48ddd5b417c6eb7ee480976ec479e7c9e6a466f176Chris LattnerNoOutput("disable-output",
49ddd5b417c6eb7ee480976ec479e7c9e6a466f176Chris Lattner         cl::desc("Do not write result bytecode file"), cl::Hidden);
50d70b68ebd01baf2c5308ee7bc0881bb3fb999c56Chris Lattner
51d70b68ebd01baf2c5308ee7bc0881bb3fb999c56Chris Lattnerstatic cl::opt<bool>
52ddd5b417c6eb7ee480976ec479e7c9e6a466f176Chris LattnerNoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden);
53f3bafc10438a70d5a65d65b7bc42d7798b7fe14bChris Lattner
54f3bafc10438a70d5a65d65b7bc42d7798b7fe14bChris Lattnerstatic cl::opt<bool>
55f9e173e85ab1e4062cc723cab6db0b86ed2578b8Chris LattnerQuiet("q", cl::desc("Don't print 'program modified' message"));
565ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
575ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::alias
585ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerQuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
595ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
60009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
61c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner//===----------------------------------------------------------------------===//
62c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner// main for opt
63c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner//
648f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) {
658f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner  cl::ParseCommandLineOptions(argc, argv,
668f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner			      " llvm .bc -> .bc modular optimizer\n");
67fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner
6818fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve  // Allocate a full target machine description only if necessary...
6918fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve  // FIXME: The choice of target should be controllable on the command line.
7018fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve  std::auto_ptr<TargetMachine> target;
7118fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve
7218fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve  TargetMachine* TM = NULL;
7356620da5b486225dfbb0db02d5cbc5c976d0dc02Chris Lattner  std::string ErrorMessage;
7418fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve
75fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Load the input module...
7656620da5b486225dfbb0db02d5cbc5c976d0dc02Chris Lattner  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
7763202328d3dac33322f564889cd44126912102e6Chris Lattner  if (M.get() == 0) {
786c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner    std::cerr << argv[0] << ": ";
7956620da5b486225dfbb0db02d5cbc5c976d0dc02Chris Lattner    if (ErrorMessage.size())
806c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      std::cerr << ErrorMessage << "\n";
8156620da5b486225dfbb0db02d5cbc5c976d0dc02Chris Lattner    else
826c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      std::cerr << "bytecode didn't read correctly.\n";
83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    return 1;
84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
86fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Figure out what stream we are supposed to write to...
87697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::ostream *Out = &std::cout;  // Default to printing to stdout...
881e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner  if (OutputFilename != "") {
89888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner    if (!Force && std::ifstream(OutputFilename.c_str())) {
90697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      // If force is not specified, make sure not to overwrite a file!
916c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      std::cerr << argv[0] << ": error opening '" << OutputFilename
926c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner                << "': file exists!\n"
936c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner                << "Use -f command line argument to force output\n";
94697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      return 1;
95697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner    }
96697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner    Out = new std::ofstream(OutputFilename.c_str());
97697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner
98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (!Out->good()) {
996c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      return 1;
101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
10276d12299b5333d71bfc079614031f97c97aa5148Chris Lattner
103452fea997232437902385e88366482b01957eeefMisha Brukman    // Make sure that the Output file gets unlinked from the disk if we get a
10476d12299b5333d71bfc079614031f97c97aa5148Chris Lattner    // SIGINT
10576d12299b5333d71bfc079614031f97c97aa5148Chris Lattner    RemoveFileOnSignal(OutputFilename);
106009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
107009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
108fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Create a PassManager to hold and optimize the collection of passes we are
109fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // about to build...
110fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  //
111fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  PassManager Passes;
112fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner
1139c3b55ea9f5fe17c5713757e97aa62e0fb356dcfChris Lattner  // Add an appropriate TargetData instance for this module...
1149c3b55ea9f5fe17c5713757e97aa62e0fb356dcfChris Lattner  Passes.add(new TargetData("opt", M.get()));
1159c3b55ea9f5fe17c5713757e97aa62e0fb356dcfChris Lattner
116fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Create a new optimization pass for each one specified on the command line
117fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  for (unsigned i = 0; i < OptimizationList.size(); ++i) {
118c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner    const PassInfo *Opt = OptimizationList[i];
119c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner
120c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner    if (Opt->getNormalCtor())
121c0ce68bf4a497dac2e5b22d54de68e6ad495815fChris Lattner      Passes.add(Opt->getNormalCtor()());
12218fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve    else if (Opt->getTargetCtor()) {
1230af1e8e3a41285772d2a8d0f26c139cf5332dde3Chris Lattner#if 0
12418fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve      if (target.get() == NULL)
12518fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve        target.reset(allocateSparcTargetMachine()); // FIXME: target option
1260af1e8e3a41285772d2a8d0f26c139cf5332dde3Chris Lattner#endif
12718fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve      assert(target.get() && "Could not allocate target machine!");
12818fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve      Passes.add(Opt->getTargetCtor()(*target.get()));
12918fdfc4eed5466e0a7e16cac594804c82aa4442bVikram S. Adve    } else
1306c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      std::cerr << argv[0] << ": cannot create pass: " << Opt->getPassName()
1316c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner                << "\n";
132fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner
133fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner    if (PrintEachXForm)
1346c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner      Passes.add(new PrintModulePass(&std::cerr));
135fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  }
136fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner
13722d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner  // Check that the module is well formed on completion of optimization
138f3bafc10438a70d5a65d65b7bc42d7798b7fe14bChris Lattner  if (!NoVerify)
139f3bafc10438a70d5a65d65b7bc42d7798b7fe14bChris Lattner    Passes.add(createVerifierPass());
14022d26d7c7d7c9666d0da0e51250586da5a0744daChris Lattner
141fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Write bytecode out to disk or cout as the last step...
142d70b68ebd01baf2c5308ee7bc0881bb3fb999c56Chris Lattner  if (!NoOutput)
143d70b68ebd01baf2c5308ee7bc0881bb3fb999c56Chris Lattner    Passes.add(new WriteBytecodePass(Out, Out != &std::cout));
144fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner
145fb1b3f119df25de495fcd53e675d6c9991f5664eChris Lattner  // Now that we have all of the passes ready, run them.
1467e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (Passes.run(*M.get()) && !Quiet)
1476c8103f7ddb734d128739a463bcd0667d73c62aaChris Lattner    std::cerr << "Program modified.\n";
148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
149009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return 0;
150009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
151