Use toplevel function pass manager as OnTheFly manager.
[oota-llvm.git] / tools / llvm-upgrade / llvm-upgrade.cpp
1 //===--- llvm-upgrade.cpp - The LLVM Assembly Upgrader --------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the 
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This utility will upgrade LLVM 1.9 Assembly to 2.0 format. It may be 
11 //  invoked as a filter, like this:
12 //    llvm-1.9/bin/llvm-dis < 1.9.bc | llvm-upgrade | llvm-as > 2.0.bc
13 //  
14 //  or, you can directly upgrade, like this:
15 //    llvm-upgrade -o 2.0.ll < 1.9.ll
16 //  
17 //  llvm-upgrade won't overwrite files by default. Use -f to force it to
18 //  overwrite the output file.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #include "UpgradeInternals.h"
23 #include "llvm/Module.h"
24 #include "llvm/Bytecode/Writer.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/ManagedStatic.h"
27 #include "llvm/Support/Streams.h"
28 #include "llvm/Support/SystemUtils.h"
29 #include "llvm/System/Signals.h"
30 #include <fstream>
31 #include <iostream>
32 #include <memory>
33 using namespace llvm;
34
35 static cl::opt<std::string>
36 InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
37
38 static cl::opt<std::string>
39 OutputFilename("o", cl::desc("Override output filename"),
40                cl::value_desc("filename"), cl::init("-"));
41
42 static cl::opt<bool>
43 Force("f", cl::desc("Overwrite output files"), cl::init(false));
44
45 static cl::opt<bool>
46 AddAttrs("add-attrs", cl::desc("Add function result and argument attributes"),
47          cl::init(false));
48
49 static cl::opt<bool>
50 Debug("debug-upgrade-yacc", cl::desc("Print debug output from yacc parser"),
51       cl::Hidden, cl::init(false));
52
53 static cl::opt<bool>
54 EmitByteCode("emit-bytecode", cl::desc("Emit bytecode instead of assembly"),
55     cl::init(false));
56
57 int main(int argc, char **argv) {
58   llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
59   cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n");
60   sys::PrintStackTraceOnErrorSignal();
61
62   int exitCode = 0;
63   std::ostream *Out = 0;
64   std::istream *In = 0;
65   try {
66     if (OutputFilename != "") {   // Specified an output filename?
67       if (OutputFilename != "-") {  // Not stdout?
68         if (!Force && std::ifstream(OutputFilename.c_str())) {
69           // If force is not specified, make sure not to overwrite a file!
70           cerr << argv[0] << ": error opening '" << OutputFilename
71                << "': file exists!\n"
72                << "Use -f command line argument to force output\n";
73           return 1;
74         }
75         Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
76                                 std::ios::trunc);
77       } else {                      // Specified stdout
78         Out = &std::cout;
79       }
80     } else {
81       if (InputFilename == "-") {
82         OutputFilename = "-";
83         Out = &std::cout;
84       } else {
85         std::string IFN = InputFilename;
86         int Len = IFN.length();
87         if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
88           // Source ends in .ll
89           OutputFilename = std::string(IFN.begin(), IFN.end()-3);
90         } else {
91           OutputFilename = IFN;   // Append to it
92         }
93         OutputFilename += ".llu";
94
95         if (!Force && std::ifstream(OutputFilename.c_str())) {
96           // If force is not specified, make sure not to overwrite a file!
97           cerr << argv[0] << ": error opening '" << OutputFilename
98                << "': file exists!\n"
99                << "Use -f command line argument to force output\n";
100           return 1;
101         }
102
103         Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
104                                 std::ios::trunc);
105         // Make sure that the Out file gets unlinked from the disk if we get a
106         // SIGINT
107         sys::RemoveFileOnSignal(sys::Path(OutputFilename));
108       }
109     }
110
111     if (InputFilename == "-") {
112       In = &std::cin;
113       InputFilename = "<stdin>";
114     } else {
115       In = new std::ifstream(InputFilename.c_str());
116     }
117
118     if (!Out->good()) {
119       cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
120       return 1;
121     }
122
123     if (!In->good()) {
124       cerr << argv[0] << ": error opening " << InputFilename << "!\n";
125       return 1;
126     }
127
128     Module *M = UpgradeAssembly(InputFilename, *In, Debug, AddAttrs);
129     if (!M) {
130       cerr << argv[0] << ": No module returned from assembly parsing\n";
131       if (!EmitByteCode)
132         *Out << argv[0] << ": parse failed.";
133       exit(1);
134     }
135
136     // Finally, print the module on the output stream.
137     if (EmitByteCode) {
138       OStream OS(*Out);
139       WriteBytecodeToFile(M, OS);
140     } else
141       M->print(Out);
142
143   } catch (const std::string& caught_message) {
144     cerr << argv[0] << ": " << caught_message << "\n";
145     exitCode = 1;
146   } catch (...) {
147     cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
148     exitCode = 1;
149   }
150
151   if (Out != &std::cout) delete Out;
152   return exitCode;
153 }
154