Remove trailing whitespace
[oota-llvm.git] / tools / llc / llc.cpp
1 //===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is the llc code generator driver. It provides a convenient
11 // command-line interface for generating native assembly-language code
12 // or C code, given LLVM bytecode.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Bytecode/Reader.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/TargetMachineRegistry.h"
19 #include "llvm/Transforms/Scalar.h"
20 #include "llvm/Module.h"
21 #include "llvm/PassManager.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/PluginLoader.h"
25 #include "llvm/System/Signals.h"
26 #include <fstream>
27 #include <iostream>
28 #include <memory>
29
30 using namespace llvm;
31
32 // General options for llc.  Other pass-specific options are specified
33 // within the corresponding llc passes, and target-specific options
34 // and back-end code generation options are specified with the target machine.
35 //
36 static cl::opt<std::string>
37 InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
38
39 static cl::opt<std::string>
40 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
41
42 static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
43
44 static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
45 MArch("march", cl::desc("Architecture to generate assembly for:"));
46
47 // GetFileNameRoot - Helper function to get the basename of a filename...
48 static inline std::string
49 GetFileNameRoot(const std::string &InputFilename) {
50   std::string IFN = InputFilename;
51   std::string outputFilename;
52   int Len = IFN.length();
53   if ((Len > 2) &&
54       IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
55     outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
56   } else {
57     outputFilename = IFN;
58   }
59   return outputFilename;
60 }
61
62
63 // main - Entry point for the llc compiler.
64 //
65 int main(int argc, char **argv) {
66   try {
67     cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
68     sys::PrintStackTraceOnErrorSignal();
69
70     // Load the module to be compiled...
71     std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
72     if (M.get() == 0) {
73       std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
74       return 1;
75     }
76     Module &mod = *M.get();
77
78     // Allocate target machine.  First, check whether the user has
79     // explicitly specified an architecture to compile for.
80     TargetMachine* (*TargetMachineAllocator)(const Module&,
81                                              IntrinsicLowering *) = 0;
82     if (MArch == 0) {
83       std::string Err;
84       MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
85       if (MArch == 0) {
86         std::cerr << argv[0] << ": error auto-selecting target for module '"
87                   << Err << "'.  Please use the -march option to explicitly "
88                   << "pick a target.\n";
89         return 1;
90       }
91     }
92
93     std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
94     assert(target.get() && "Could not allocate target machine!");
95     TargetMachine &Target = *target.get();
96     const TargetData &TD = Target.getTargetData();
97
98     // Build up all of the passes that we want to do to the module...
99     PassManager Passes;
100     Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
101                               TD.getPointerAlignment(), TD.getDoubleAlignment()));
102
103     // Figure out where we are going to send the output...
104     std::ostream *Out = 0;
105     if (OutputFilename != "") {
106       if (OutputFilename != "-") {
107         // Specified an output filename?
108         if (!Force && std::ifstream(OutputFilename.c_str())) {
109           // If force is not specified, make sure not to overwrite a file!
110           std::cerr << argv[0] << ": error opening '" << OutputFilename
111                     << "': file exists!\n"
112                     << "Use -f command line argument to force output\n";
113           return 1;
114         }
115         Out = new std::ofstream(OutputFilename.c_str());
116
117         // Make sure that the Out file gets unlinked from the disk if we get a
118         // SIGINT
119         sys::RemoveFileOnSignal(sys::Path(OutputFilename));
120       } else {
121         Out = &std::cout;
122       }
123     } else {
124       if (InputFilename == "-") {
125         OutputFilename = "-";
126         Out = &std::cout;
127       } else {
128         OutputFilename = GetFileNameRoot(InputFilename);
129
130         if (MArch->Name[0] != 'c' || MArch->Name[1] != 0)  // not CBE
131           OutputFilename += ".s";
132         else
133           OutputFilename += ".cbe.c";
134
135         if (!Force && std::ifstream(OutputFilename.c_str())) {
136           // If force is not specified, make sure not to overwrite a file!
137           std::cerr << argv[0] << ": error opening '" << OutputFilename
138                     << "': file exists!\n"
139                     << "Use -f command line argument to force output\n";
140           return 1;
141         }
142
143         Out = new std::ofstream(OutputFilename.c_str());
144         if (!Out->good()) {
145           std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
146           delete Out;
147           return 1;
148         }
149
150         // Make sure that the Out file gets unlinked from the disk if we get a
151         // SIGINT
152         sys::RemoveFileOnSignal(sys::Path(OutputFilename));
153       }
154     }
155
156     // Ask the target to add backend passes as necessary
157     if (Target.addPassesToEmitAssembly(Passes, *Out)) {
158       std::cerr << argv[0] << ": target '" << Target.getName()
159                 << "' does not support static compilation!\n";
160       if (Out != &std::cout) delete Out;
161       // And the Out file is empty and useless, so remove it now.
162       std::remove(OutputFilename.c_str());
163       return 1;
164     } else {
165       // Run our queue of passes all at once now, efficiently.
166       Passes.run(*M.get());
167     }
168
169     // Delete the ostream if it's not a stdout stream
170     if (Out != &std::cout) delete Out;
171
172     return 0;
173   } catch (const std::string& msg) {
174     std::cerr << argv[0] << ": " << msg << "\n";
175   } catch (...) {
176     std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
177   }
178   return 1;
179 }