llc.cpp revision 68492725a08ca3b356f24b90cdfc57a247abbeb3
1//===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
2//
3// This is the llc compiler driver.
4//
5//===----------------------------------------------------------------------===//
6
7#include "llvm/Bytecode/Reader.h"
8#include "llvm/Target/TargetMachineImpls.h"
9#include "llvm/Target/TargetMachine.h"
10#include "llvm/Transforms/Instrumentation.h"
11#include "llvm/Transforms/Scalar.h"
12#include "llvm/Transforms/Utils/Linker.h"
13#include "llvm/Assembly/PrintModulePass.h"
14#include "llvm/Bytecode/WriteBytecodePass.h"
15#include "llvm/Transforms/IPO.h"
16#include "llvm/Module.h"
17#include "llvm/PassManager.h"
18#include "llvm/Pass.h"
19#include "llvm/Support/PassNameParser.h"
20#include "Support/CommandLine.h"
21#include "Support/Signals.h"
22#include <memory>
23#include <fstream>
24
25//------------------------------------------------------------------------------
26// Option declarations for LLC.
27//------------------------------------------------------------------------------
28
29// Make all registered optimization passes available to llc.  These passes
30// will all be run before the simplification and lowering steps used by the
31// back-end code generator, and will be run in the order specified on the
32// command line. The OptimizationList is automatically populated with
33// registered Passes by the PassNameParser.
34//
35static cl::list<const PassInfo*, bool,
36                FilteredPassNameParser<PassInfo::Optimization> >
37OptimizationList(cl::desc("Optimizations available:"));
38
39
40// General options for llc.  Other pass-specific options are specified
41// within the corresponding llc passes, and target-specific options
42// and back-end code generation options are specified with the target machine.
43//
44static cl::opt<std::string>
45InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
46
47static cl::opt<std::string>
48OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
49
50static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
51
52static cl::opt<bool>
53DisableStrip("disable-strip",
54          cl::desc("Do not strip the LLVM bytecode included in the executable"));
55
56static cl::opt<bool>
57DumpAsm("d", cl::desc("Print bytecode before native code generation"),
58        cl::Hidden);
59
60static cl::opt<std::string>
61TraceLibPath("tracelibpath", cl::desc("Path to libinstr for trace code"),
62             cl::value_desc("directory"), cl::Hidden);
63
64
65// flags set from -tracem and -trace options to control tracing
66static bool TraceFunctions   = false;
67static bool TraceBasicBlocks = false;
68
69
70// GetFileNameRoot - Helper function to get the basename of a filename...
71static inline std::string
72GetFileNameRoot(const std::string &InputFilename)
73{
74  std::string IFN = InputFilename;
75  std::string outputFilename;
76  int Len = IFN.length();
77  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
78    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
79  } else {
80    outputFilename = IFN;
81  }
82  return outputFilename;
83}
84
85static bool
86insertTraceCodeFor(Module &M)
87{
88  PassManager Passes;
89
90  // Insert trace code in all functions in the module
91  if (TraceBasicBlocks)
92    Passes.add(createTraceValuesPassForBasicBlocks());
93  else if (TraceFunctions)
94    Passes.add(createTraceValuesPassForFunction());
95  else
96    return false;
97
98  // Eliminate duplication in constant pool
99  Passes.add(createConstantMergePass());
100
101  // Run passes to insert and clean up trace code...
102  Passes.run(M);
103
104  std::string ErrorMessage;
105
106  // Load the module that contains the runtime helper routines neccesary for
107  // pointer hashing and stuff...  link this module into the program if possible
108  //
109  Module *TraceModule = ParseBytecodeFile(TraceLibPath+"libinstr.bc");
110
111  // Check if the TraceLibPath contains a valid module.  If not, try to load
112  // the module from the current LLVM-GCC install directory.  This is kindof
113  // a hack, but allows people to not HAVE to have built the library.
114  //
115  if (TraceModule == 0)
116    TraceModule = ParseBytecodeFile("/home/vadve/lattner/cvs/gcc_install/lib/"
117                                    "gcc-lib/llvm/3.1/libinstr.bc");
118
119  // If we still didn't get it, cancel trying to link it in...
120  if (TraceModule == 0)
121    std::cerr <<"WARNING: couldn't load trace routines to link into program!\n";
122  else
123    {
124      // Link in the trace routines... if this fails, don't panic, because the
125      // compile should still succeed, but the native linker will probably fail.
126      //
127      std::auto_ptr<Module> TraceRoutines(TraceModule);
128      if (LinkModules(&M, TraceRoutines.get(), &ErrorMessage))
129        std::cerr << "WARNING: Error linking in trace routines: "
130                  << ErrorMessage << "\n";
131    }
132
133  // Write out the module with tracing code just before code generation
134  assert (InputFilename != "-"
135          && "Cannot write out traced bytecode when reading input from stdin");
136  std::string TraceFilename = GetFileNameRoot(InputFilename) + ".trace.bc";
137
138  std::ofstream Out(TraceFilename.c_str());
139  if (!Out.good())
140    std::cerr << "Error opening '" << TraceFilename
141              << "'!: Skipping output of trace code as bytecode\n";
142  else
143    {
144      std::cerr << "Emitting trace code to '" << TraceFilename
145                << "' for comparison...\n";
146      WriteBytecodeToFile(&M, Out);
147    }
148
149  return true;
150}
151
152// Making tracing a module pass so the entire module with tracing
153// can be written out before continuing.
154struct InsertTracingCodePass: public Pass {
155  virtual bool run(Module &M) {
156    return insertTraceCodeFor(M);
157  }
158};
159
160
161//===---------------------------------------------------------------------===//
162// Function main()
163//
164// Entry point for the llc compiler.
165//===---------------------------------------------------------------------===//
166
167int
168main(int argc, char **argv)
169{
170  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
171
172  // Allocate a target... in the future this will be controllable on the
173  // command line.
174  std::auto_ptr<TargetMachine> target(allocateSparcTargetMachine());
175  assert(target.get() && "Could not allocate target machine!");
176
177  TargetMachine &Target = *target.get();
178  const TargetData &TD = Target.getTargetData();
179
180  // Load the module to be compiled...
181  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
182  if (M.get() == 0)
183    {
184      std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
185      return 1;
186    }
187
188  // Build up all of the passes that we want to do to the module...
189  PassManager Passes;
190
191  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
192                            TD.getPointerAlignment(), TD.getDoubleAlignment()));
193
194  // Create a new optimization pass for each one specified on the command line
195  // Deal specially with tracing passes, which must be run differently than opt.
196  //
197  for (unsigned i = 0; i < OptimizationList.size(); ++i)
198    {
199      const PassInfo *Opt = OptimizationList[i];
200
201      if (std::string(Opt->getPassArgument()) == "trace")
202        TraceFunctions = !(TraceBasicBlocks = true);
203      else if (std::string(Opt->getPassArgument()) == "tracem")
204        TraceFunctions = !(TraceBasicBlocks = false);
205      else
206        { // handle other passes as normal optimization passes
207          if (Opt->getNormalCtor())
208            Passes.add(Opt->getNormalCtor()());
209          else if (Opt->getTargetCtor())
210            Passes.add(Opt->getTargetCtor()(Target));
211          else
212            std::cerr << argv[0] << ": cannot create pass: "
213                      << Opt->getPassName() << "\n";
214        }
215    }
216
217  // Run tracing passes after other optimization passes and before llc passes.
218  if (TraceFunctions || TraceBasicBlocks)
219    Passes.add(new InsertTracingCodePass);
220
221  // Decompose multi-dimensional refs into a sequence of 1D refs
222  Passes.add(createDecomposeMultiDimRefsPass());
223
224  // Replace malloc and free instructions with library calls.
225  // Do this after tracing until lli implements these lib calls.
226  // For now, it will emulate malloc and free internally.
227  Passes.add(createLowerAllocationsPass());
228
229  // If LLVM dumping after transformations is requested, add it to the pipeline
230  if (DumpAsm)
231    Passes.add(new PrintFunctionPass("Code after xformations: \n", &std::cerr));
232
233  // Strip all of the symbols from the bytecode so that it will be smaller...
234  if (!DisableStrip)
235    Passes.add(createSymbolStrippingPass());
236
237  // Figure out where we are going to send the output...
238  std::ostream *Out = 0;
239  if (OutputFilename != "")
240    {   // Specified an output filename?
241      if (!Force && std::ifstream(OutputFilename.c_str())) {
242        // If force is not specified, make sure not to overwrite a file!
243        std::cerr << argv[0] << ": error opening '" << OutputFilename
244                  << "': file exists!\n"
245                  << "Use -f command line argument to force output\n";
246        return 1;
247      }
248      Out = new std::ofstream(OutputFilename.c_str());
249
250      // Make sure that the Out file gets unlink'd from the disk if we get a
251      // SIGINT
252      RemoveFileOnSignal(OutputFilename);
253    }
254  else
255    {
256      if (InputFilename == "-")
257        {
258          OutputFilename = "-";
259          Out = &std::cout;
260        }
261      else
262        {
263          std::string OutputFilename = GetFileNameRoot(InputFilename);
264          OutputFilename += ".s";
265
266          if (!Force && std::ifstream(OutputFilename.c_str()))
267            {
268              // If force is not specified, make sure not to overwrite a file!
269              std::cerr << argv[0] << ": error opening '" << OutputFilename
270                        << "': file exists!\n"
271                        << "Use -f command line argument to force output\n";
272              return 1;
273            }
274
275          Out = new std::ofstream(OutputFilename.c_str());
276          if (!Out->good())
277            {
278              std::cerr << argv[0] << ": error opening " << OutputFilename
279                        << "!\n";
280              delete Out;
281              return 1;
282            }
283
284          // Make sure that the Out file gets unlink'd from the disk if we get a
285          // SIGINT
286          RemoveFileOnSignal(OutputFilename);
287        }
288    }
289
290  // Ask the target to add backend passes as neccesary
291  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
292    std::cerr << argv[0] << ": target '" << Target.getName()
293              << " does not support static compilation!\n";
294  } else {
295    // Run our queue of passes all at once now, efficiently.
296    Passes.run(*M.get());
297  }
298
299  // Delete the ostream if it's not a stdout stream
300  if (Out != &std::cout) delete Out;
301
302  return 0;
303}
304