llc.cpp revision e45110e01282862e95c3d28c489dedd9a08ffa31
15b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
27c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// This file was developed by the LLVM research group and is distributed under
67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
77c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner//
10e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// This is the llc code generator driver. It provides a convenient
11e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// command-line interface for generating native assembly-language code
12e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// or C code, given LLVM bytecode.
13e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner//
14b79757c621c83dc3f410aacdc6db7639f9e47c6eChris Lattner//===----------------------------------------------------------------------===//
15cb465fc71ecb64d3d168a0cf754fa442abb0f6f9Vikram S. Adve
16cb465fc71ecb64d3d168a0cf754fa442abb0f6f9Vikram S. Adve#include "llvm/Bytecode/Reader.h"
17805eb96727fc07c4b599528f91370841d722bffaVikram S. Adve#include "llvm/Target/TargetMachine.h"
18e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner#include "llvm/Target/TargetMachineRegistry.h"
1965f1b895bb1c196409747c60373b2fbfbf5fe6b4Chris Lattner#include "llvm/Transforms/Scalar.h"
2046ac43c1bbdf010507f61750368297889ac1b6c6Chris Lattner#include "llvm/Module.h"
21cd50d3fafabec10c09f3ed0466924a951943d6d0Chris Lattner#include "llvm/PassManager.h"
227d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve#include "llvm/Pass.h"
23cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h"
24e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner#include "Support/PluginLoader.h"
25bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h"
2678f7e1a9cdc9a373c9a18598cd5e47ac5476bfe6Chris Lattner#include <fstream>
2786f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <iostream>
2886f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <memory>
297d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve
30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
31d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
327d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// General options for llc.  Other pass-specific options are specified
337d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// within the corresponding llc passes, and target-specific options
347d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// and back-end code generation options are specified with the target machine.
357d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve//
36b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
375ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerInputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
39b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
415ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
435ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
445ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
45e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattnerstatic cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
46e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerMArch("march", cl::desc("Architecture to generate assembly for:"));
47e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner
483524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner// GetFileNameRoot - Helper function to get the basename of a filename...
49b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic inline std::string
50e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerGetFileNameRoot(const std::string &InputFilename) {
51b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string IFN = InputFilename;
52b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string outputFilename;
532f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  int Len = IFN.length();
54b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell  if ((Len > 2) &&
55b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell      IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
56b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
572f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  } else {
583524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner    outputFilename = IFN;
592f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  }
602f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  return outputFilename;
612f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
622f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve
63da784ee81f082781fb61258546fec7c82ba6a8f0Chris Lattner
645b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// main - Entry point for the llc compiler.
655b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//
665b836c4a06c584544647d5b013b193510ac5ced5Chris Lattnerint main(int argc, char **argv) {
672f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
68364d1203e7adaededf3c01f58bd968ee61f4a316Chris Lattner  PrintStackTraceOnErrorSignal();
69364d1203e7adaededf3c01f58bd968ee61f4a316Chris Lattner
702f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  // Load the module to be compiled...
71697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
725b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner  if (M.get() == 0) {
735b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
745b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner    return 1;
755b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner  }
762e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  Module &mod = *M.get();
772e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke
782e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  // Allocate target machine.  First, check whether the user has
792e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  // explicitly specified an architecture to compile for.
806fb6ce3148ec4a9aaab47800da2365d7f60a6f5bChris Lattner  TargetMachine* (*TargetMachineAllocator)(const Module&,
816fb6ce3148ec4a9aaab47800da2365d7f60a6f5bChris Lattner                                           IntrinsicLowering *) = 0;
82e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner  if (MArch == 0) {
83e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner    std::string Err;
84e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner    MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
85e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner    if (MArch == 0) {
86e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner      std::cerr << argv[0] << ": error auto-selecting target for module '"
87e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner                << Err << "'.  Please use the -march option to explicitly "
88e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner                << "pick a target.\n";
89bb43350e32c949ff9465eb898a2ed5ad9d1f3f9fChris Lattner      return 1;
90e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner    }
912e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  }
92e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner
93e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner  std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
942e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  assert(target.get() && "Could not allocate target machine!");
952e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  TargetMachine &Target = *target.get();
962e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  const TargetData &TD = Target.getTargetData();
9739fd659d683592df13ccfa39f1825b1173a9ff04Chris Lattner
983524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner  // Build up all of the passes that we want to do to the module...
99f4de63f65fa995e68e3cd268117ab065068be413Chris Lattner  PassManager Passes;
1003524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner
10110daaa141661d96843f3d8ece0e5a4c2da4b6e87Chris Lattner  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
102bc19466912f4074bc0dc20d389fb1775a674dfd6Chris Lattner                            TD.getPointerAlignment(), TD.getDoubleAlignment()));
1032b5f2c1a648895d4075f0f35c8a37bd485b9eab0Chris Lattner
104e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner  // Figure out where we are going to send the output...
105e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner  std::ostream *Out = 0;
106cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner  if (OutputFilename != "") {
1075ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke    if (OutputFilename != "-") {
1085ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      // Specified an output filename?
1095ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      if (!Force && std::ifstream(OutputFilename.c_str())) {
1105ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke	// If force is not specified, make sure not to overwrite a file!
1115ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke	std::cerr << argv[0] << ": error opening '" << OutputFilename
1125ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke		  << "': file exists!\n"
1135ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke		  << "Use -f command line argument to force output\n";
1145ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke	return 1;
1155ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      }
1165ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      Out = new std::ofstream(OutputFilename.c_str());
1175ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke
118452fea997232437902385e88366482b01957eeefMisha Brukman      // Make sure that the Out file gets unlinked from the disk if we get a
1195ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      // SIGINT
1205ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      RemoveFileOnSignal(OutputFilename);
1215ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke    } else {
1225ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke      Out = &std::cout;
123cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner    }
124cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner  } else {
125cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner    if (InputFilename == "-") {
126cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner      OutputFilename = "-";
127cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner      Out = &std::cout;
128cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner    } else {
1292e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke      OutputFilename = GetFileNameRoot(InputFilename);
13074661c838c66f8e30226da8a1f3b77548a584203Chris Lattner
131e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner      if (MArch->Name[0] != 'c' || MArch->Name[1] != 0)  // not CBE
13274661c838c66f8e30226da8a1f3b77548a584203Chris Lattner        OutputFilename += ".s";
13374661c838c66f8e30226da8a1f3b77548a584203Chris Lattner      else
13474661c838c66f8e30226da8a1f3b77548a584203Chris Lattner        OutputFilename += ".cbe.c";
135cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner
136888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner      if (!Force && std::ifstream(OutputFilename.c_str())) {
137697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        // If force is not specified, make sure not to overwrite a file!
138b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner        std::cerr << argv[0] << ": error opening '" << OutputFilename
139b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner                  << "': file exists!\n"
140b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner                  << "Use -f command line argument to force output\n";
141697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        return 1;
142697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      }
143cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner
144697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner      Out = new std::ofstream(OutputFilename.c_str());
145cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner      if (!Out->good()) {
146cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
147cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner        delete Out;
148cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner        return 1;
149cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner      }
150cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner
151452fea997232437902385e88366482b01957eeefMisha Brukman      // Make sure that the Out file gets unlinked from the disk if we get a
1520f82df410caf8242406fa7e8bbd555e4854ffe48Chris Lattner      // SIGINT
15376d12299b5333d71bfc079614031f97c97aa5148Chris Lattner      RemoveFileOnSignal(OutputFilename);
1543524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner    }
155cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner  }
1567d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve
1572e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke  // Ask the target to add backend passes as necessary
1586334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
159b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner    std::cerr << argv[0] << ": target '" << Target.getName()
1602e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke              << "' does not support static compilation!\n";
1612e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke    if (Out != &std::cout) delete Out;
1622e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke    // And the Out file is empty and useless, so remove it now.
1632e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke    std::remove(OutputFilename.c_str());
1642e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke    return 1;
1656334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner  } else {
1666334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner    // Run our queue of passes all at once now, efficiently.
1676334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner    Passes.run(*M.get());
1686334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner  }
16905e5e070ee73309025e11bea0c15d7fc9c25fea6Chris Lattner
1700f82df410caf8242406fa7e8bbd555e4854ffe48Chris Lattner  // Delete the ostream if it's not a stdout stream
171e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner  if (Out != &std::cout) delete Out;
172e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner
173d7477ee9d97f80fd5dac252dad4f1c1f83660115Chris Lattner  return 0;
1742f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
175