blob: 9fbfea7564893638c3dd48e812cbad865d0b5f6e [file] [log] [blame]
Chris Lattner0eafc312001-10-18 06:05:15 +00001//===----------------------------------------------------------------------===//
Chris Lattner00950542001-06-06 20:29:01 +00002// LLVM 'OPT' UTILITY
3//
Chris Lattner00950542001-06-06 20:29:01 +00004// Optimizations may be specified an arbitrary number of times on the command
5// line, they are run in the order specified.
6//
Chris Lattner0eafc312001-10-18 06:05:15 +00007//===----------------------------------------------------------------------===//
Chris Lattner00950542001-06-06 20:29:01 +00008
Chris Lattner00950542001-06-06 20:29:01 +00009#include "llvm/Module.h"
Chris Lattnerfb1b3f12002-01-31 00:47:12 +000010#include "llvm/PassManager.h"
Chris Lattner00950542001-06-06 20:29:01 +000011#include "llvm/Bytecode/Reader.h"
Chris Lattnerfb1b3f12002-01-31 00:47:12 +000012#include "llvm/Bytecode/WriteBytecodePass.h"
Chris Lattnerffa6f9c2001-10-19 15:39:14 +000013#include "llvm/Assembly/PrintModulePass.h"
Chris Lattner22d26d72002-02-20 17:56:53 +000014#include "llvm/Analysis/Verifier.h"
Chris Lattnere04f4b62002-05-10 15:43:07 +000015#include "llvm/Target/TargetData.h"
Chris Lattnercee8f9a2001-11-27 00:03:19 +000016#include "Support/CommandLine.h"
Chris Lattner76d12292002-04-18 19:55:25 +000017#include "Support/Signals.h"
Chris Lattner73e11d72001-10-18 06:13:08 +000018#include <fstream>
Chris Lattner63202322001-11-26 19:22:39 +000019#include <memory>
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000020#include <algorithm>
Anand Shukla63aaa112002-06-25 21:43:28 +000021
22using std::cerr;
Chris Lattnerc7a09852002-07-25 16:31:09 +000023using std::string;
Chris Lattnere04f4b62002-05-10 15:43:07 +000024
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000025//===----------------------------------------------------------------------===//
26// PassNameParser class - Make use of the pass registration mechanism to
27// automatically add a command line argument to opt for each pass.
Chris Lattnerfb1b3f12002-01-31 00:47:12 +000028//
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000029namespace { // anonymous namespace for local class...
30class PassNameParser : public PassRegistrationListener,
31 public cl::parser<const PassInfo*> {
32 cl::Option *Opt;
33public:
34 PassNameParser() : Opt(0) {}
35
36 void initialize(cl::Option &O) {
37 Opt = &O;
38 cl::parser<const PassInfo*>::initialize(O);
Chris Lattner0be41012002-02-01 04:54:11 +000039
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000040 // Add all of the passes to the map that got initialized before 'this' did.
41 enumeratePasses();
42 }
Chris Lattnereeeaf522002-02-12 17:17:33 +000043
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000044 static inline bool ignorablePass(const PassInfo *P) {
45 // Ignore non-selectable and non-constructible passes!
46 return P->getPassArgument() == 0 ||
47 (P->getNormalCtor() == 0 && P->getDataCtor() == 0);
48 }
Chris Lattnereded4912002-02-26 20:04:59 +000049
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000050 // Implement the PassRegistrationListener callbacks used to populate our map
51 //
52 virtual void passRegistered(const PassInfo *P) {
53 if (ignorablePass(P) || !Opt) return;
54 assert(findOption(P->getPassArgument()) == getNumOptions() &&
55 "Two passes with the same argument attempted to be registered!");
56 addLiteralOption(P->getPassArgument(), P, P->getPassName());
57 Opt->addArgument(P->getPassArgument());
58 }
59 virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
Chris Lattnerc6d52e02002-04-28 05:49:53 +000060
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000061 virtual void passUnregistered(const PassInfo *P) {
62 if (ignorablePass(P) || !Opt) return;
63 assert(findOption(P->getPassArgument()) != getNumOptions() &&
64 "Registered Pass not in the pass map!");
65 removeLiteralOption(P->getPassArgument());
66 Opt->removeArgument(P->getPassArgument());
67 }
68
69 // ValLessThan - Provide a sorting comparator for Values elements...
70 typedef std::pair<const char*,
71 std::pair<const PassInfo*, const char*> > ValType;
72 static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
73 return std::string(VT1.first) < std::string(VT2.first);
74 }
75
76 // printOptionInfo - Print out information about this option. Override the
77 // default implementation to sort the table before we print...
78 virtual void printOptionInfo(const cl::Option &O, unsigned GlobalWidth) const{
79 PassNameParser *PNP = const_cast<PassNameParser*>(this);
80 std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
81 cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
82 }
Chris Lattner8f367bd2001-07-23 02:35:57 +000083};
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000084} // end anonymous namespace
Chris Lattner8f367bd2001-07-23 02:35:57 +000085
Chris Lattner9d6e7eb2002-04-12 18:21:13 +000086
Chris Lattnerc0ce68b2002-07-23 18:12:22 +000087// The OptimizationList is automatically populated with registered Passes by the
88// PassNameParser.
89//
90static cl::list<const PassInfo*, bool, PassNameParser>
91OptimizationList(cl::desc("Optimizations available:"));
92
93
94// Other command line options...
Chris Lattnerfb1b3f12002-01-31 00:47:12 +000095//
Chris Lattner5ff62e92002-07-22 02:10:13 +000096static cl::opt<string>
97InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
98
99static cl::opt<string>
100OutputFilename("o", cl::desc("Override output filename"),
101 cl::value_desc("filename"));
102
103static cl::opt<bool>
104Force("f", cl::desc("Overwrite output files"));
105
106static cl::opt<bool>
107PrintEachXForm("p", cl::desc("Print module after each transformation"));
108
109static cl::opt<bool>
110Quiet("q", cl::desc("Don't print modifying pass names"));
111
112static cl::alias
113QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
114
Chris Lattner0be41012002-02-01 04:54:11 +0000115
Chris Lattnerc0ce68b2002-07-23 18:12:22 +0000116//===----------------------------------------------------------------------===//
117// main for opt
118//
Chris Lattner00950542001-06-06 20:29:01 +0000119int main(int argc, char **argv) {
Chris Lattner8f367bd2001-07-23 02:35:57 +0000120 cl::ParseCommandLineOptions(argc, argv,
121 " llvm .bc -> .bc modular optimizer\n");
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000122
Chris Lattnerc0ce68b2002-07-23 18:12:22 +0000123 // FIXME: This should be parameterizable eventually for different target
124 // types...
125 TargetData TD("opt target");
126
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000127 // Load the input module...
Chris Lattner63202322001-11-26 19:22:39 +0000128 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
129 if (M.get() == 0) {
Chris Lattner00950542001-06-06 20:29:01 +0000130 cerr << "bytecode didn't read correctly.\n";
131 return 1;
132 }
133
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000134 // Figure out what stream we are supposed to write to...
Chris Lattner697954c2002-01-20 22:54:45 +0000135 std::ostream *Out = &std::cout; // Default to printing to stdout...
Chris Lattner1e78f362001-07-23 19:27:24 +0000136 if (OutputFilename != "") {
Chris Lattner888912d2002-01-22 21:07:24 +0000137 if (!Force && std::ifstream(OutputFilename.c_str())) {
Chris Lattner697954c2002-01-20 22:54:45 +0000138 // If force is not specified, make sure not to overwrite a file!
139 cerr << "Error opening '" << OutputFilename << "': File exists!\n"
140 << "Use -f command line argument to force output\n";
141 return 1;
142 }
143 Out = new std::ofstream(OutputFilename.c_str());
144
Chris Lattner00950542001-06-06 20:29:01 +0000145 if (!Out->good()) {
Chris Lattner1e78f362001-07-23 19:27:24 +0000146 cerr << "Error opening " << OutputFilename << "!\n";
Chris Lattner00950542001-06-06 20:29:01 +0000147 return 1;
148 }
Chris Lattner76d12292002-04-18 19:55:25 +0000149
150 // Make sure that the Output file gets unlink'd from the disk if we get a
151 // SIGINT
152 RemoveFileOnSignal(OutputFilename);
Chris Lattner00950542001-06-06 20:29:01 +0000153 }
154
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000155 // Create a PassManager to hold and optimize the collection of passes we are
156 // about to build...
157 //
158 PassManager Passes;
Chris Lattner00950542001-06-06 20:29:01 +0000159
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000160 // Create a new optimization pass for each one specified on the command line
161 for (unsigned i = 0; i < OptimizationList.size(); ++i) {
Chris Lattnerc0ce68b2002-07-23 18:12:22 +0000162 const PassInfo *Opt = OptimizationList[i];
163
164 if (Opt->getNormalCtor())
165 Passes.add(Opt->getNormalCtor()());
166 else if (Opt->getDataCtor())
167 Passes.add(Opt->getDataCtor()(TD)); // Pass dummy target data...
168 else
169 cerr << "Cannot create pass: " << Opt->getPassName() << "\n";
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000170
171 if (PrintEachXForm)
Chris Lattnerc0ce68b2002-07-23 18:12:22 +0000172 Passes.add(new PrintModulePass(&cerr));
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000173 }
174
Chris Lattner22d26d72002-02-20 17:56:53 +0000175 // Check that the module is well formed on completion of optimization
176 Passes.add(createVerifierPass());
177
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000178 // Write bytecode out to disk or cout as the last step...
179 Passes.add(new WriteBytecodePass(Out, Out != &std::cout));
180
181 // Now that we have all of the passes ready, run them.
Chris Lattner7e708292002-06-25 16:13:24 +0000182 if (Passes.run(*M.get()) && !Quiet)
Chris Lattnerfb1b3f12002-01-31 00:47:12 +0000183 cerr << "Program modified.\n";
184
Chris Lattner00950542001-06-06 20:29:01 +0000185 return 0;
186}