blob: a6f3e8a5ec9343a3dc754d78d22f6f34660de6b0 [file] [log] [blame]
Chris Lattner5b836c42003-06-20 15:49:04 +00001//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
Misha Brukman3da94ae2005-04-22 00:00:37 +00002//
John Criswell7c0e0222003-10-20 17:47:21 +00003// 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.
Misha Brukman3da94ae2005-04-22 00:00:37 +00007//
John Criswell7c0e0222003-10-20 17:47:21 +00008//===----------------------------------------------------------------------===//
Chris Lattnere737c7a2001-09-07 22:20:50 +00009//
Brian Gaekee40eae72004-03-16 21:47:20 +000010// This is the llc code generator driver. It provides a convenient
Misha Brukman3da94ae2005-04-22 00:00:37 +000011// command-line interface for generating native assembly-language code
Brian Gaekee40eae72004-03-16 21:47:20 +000012// or C code, given LLVM bytecode.
Chris Lattnere737c7a2001-09-07 22:20:50 +000013//
Chris Lattnerb79757c2001-10-04 01:40:53 +000014//===----------------------------------------------------------------------===//
Vikram S. Advecb465fc2001-07-21 12:42:29 +000015
Vikram S. Advecb465fc2001-07-21 12:42:29 +000016#include "llvm/Bytecode/Reader.h"
Vikram S. Adve805eb962001-09-18 13:10:45 +000017#include "llvm/Target/TargetMachine.h"
Chris Lattnere45110e2004-07-11 04:03:24 +000018#include "llvm/Target/TargetMachineRegistry.h"
Chris Lattner65f1b892002-05-07 20:03:27 +000019#include "llvm/Transforms/Scalar.h"
Chris Lattner46ac43c2001-09-07 21:26:31 +000020#include "llvm/Module.h"
Chris Lattnercd50d3f2002-01-31 00:46:45 +000021#include "llvm/PassManager.h"
Vikram S. Adve7d0ba022002-09-16 16:35:34 +000022#include "llvm/Pass.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000023#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/PluginLoader.h"
Chris Lattnerbed85ff2004-05-27 05:41:36 +000025#include "llvm/System/Signals.h"
Chris Lattner78f7e1a2001-09-19 16:52:09 +000026#include <fstream>
Reid Spencer86f42bd2004-07-04 12:20:55 +000027#include <iostream>
28#include <memory>
Vikram S. Adve7d0ba022002-09-16 16:35:34 +000029
Brian Gaeked0fde302003-11-11 22:41:34 +000030using namespace llvm;
31
Vikram S. Adve7d0ba022002-09-16 16:35:34 +000032// 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.
Misha Brukman3da94ae2005-04-22 00:00:37 +000035//
Chris Lattnerb5881f12003-04-25 05:26:11 +000036static cl::opt<std::string>
Chris Lattner5ff62e92002-07-22 02:10:13 +000037InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
38
Chris Lattnerb5881f12003-04-25 05:26:11 +000039static cl::opt<std::string>
Chris Lattner5ff62e92002-07-22 02:10:13 +000040OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
41
42static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
43
Chris Lattnere45110e2004-07-11 04:03:24 +000044static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
Chris Lattnercbb34a72005-06-25 03:00:34 +000045MArch("march", cl::desc("Architecture to generate code for:"));
Misha Brukman3da94ae2005-04-22 00:00:37 +000046
Chris Lattner3524fc22001-10-15 17:30:47 +000047// GetFileNameRoot - Helper function to get the basename of a filename...
Chris Lattnerb5881f12003-04-25 05:26:11 +000048static inline std::string
Chris Lattnere45110e2004-07-11 04:03:24 +000049GetFileNameRoot(const std::string &InputFilename) {
Chris Lattnerb5881f12003-04-25 05:26:11 +000050 std::string IFN = InputFilename;
51 std::string outputFilename;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000052 int Len = IFN.length();
John Criswellb5d09bf2003-08-28 21:42:29 +000053 if ((Len > 2) &&
54 IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
Chris Lattnerb5881f12003-04-25 05:26:11 +000055 outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000056 } else {
Chris Lattner3524fc22001-10-15 17:30:47 +000057 outputFilename = IFN;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000058 }
59 return outputFilename;
60}
61
Vikram S. Adve805eb962001-09-18 13:10:45 +000062
Chris Lattner5b836c42003-06-20 15:49:04 +000063// main - Entry point for the llc compiler.
64//
65int main(int argc, char **argv) {
Reid Spencer1ef8bda2004-12-30 05:36:08 +000066 try {
67 cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
68 sys::PrintStackTraceOnErrorSignal();
Chris Lattner364d1202004-02-19 20:32:39 +000069
Reid Spencer1ef8bda2004-12-30 05:36:08 +000070 // 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";
Chris Lattnerbb433502003-08-24 14:02:14 +000074 return 1;
Chris Lattnere45110e2004-07-11 04:03:24 +000075 }
Reid Spencer1ef8bda2004-12-30 05:36:08 +000076 Module &mod = *M.get();
Chris Lattnere45110e2004-07-11 04:03:24 +000077
Reid Spencer1ef8bda2004-12-30 05:36:08 +000078 // 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";
Misha Brukman878ba7c2004-07-12 22:58:07 +000089 return 1;
Brian Gaeke5ce1a582003-06-18 21:43:33 +000090 }
Brian Gaeke5ce1a582003-06-18 21:43:33 +000091 }
Reid Spencer1ef8bda2004-12-30 05:36:08 +000092
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;
Chris Lattnercbb34a72005-06-25 03:00:34 +0000100 Passes.add(new TargetData(TD));
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000101
102 // Figure out where we are going to send the output...
103 std::ostream *Out = 0;
104 if (OutputFilename != "") {
105 if (OutputFilename != "-") {
106 // Specified an output filename?
107 if (!Force && std::ifstream(OutputFilename.c_str())) {
108 // If force is not specified, make sure not to overwrite a file!
109 std::cerr << argv[0] << ": error opening '" << OutputFilename
110 << "': file exists!\n"
111 << "Use -f command line argument to force output\n";
112 return 1;
113 }
114 Out = new std::ofstream(OutputFilename.c_str());
115
116 // Make sure that the Out file gets unlinked from the disk if we get a
117 // SIGINT
118 sys::RemoveFileOnSignal(sys::Path(OutputFilename));
119 } else {
120 Out = &std::cout;
121 }
Chris Lattnercccc28c2003-06-18 18:46:08 +0000122 } else {
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000123 if (InputFilename == "-") {
124 OutputFilename = "-";
125 Out = &std::cout;
126 } else {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000127 OutputFilename = GetFileNameRoot(InputFilename);
Chris Lattner74661c82004-02-15 22:54:19 +0000128
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000129 if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
130 OutputFilename += ".s";
131 else
132 OutputFilename += ".cbe.c";
Misha Brukman3da94ae2005-04-22 00:00:37 +0000133
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000134 if (!Force && std::ifstream(OutputFilename.c_str())) {
135 // If force is not specified, make sure not to overwrite a file!
136 std::cerr << argv[0] << ": error opening '" << OutputFilename
137 << "': file exists!\n"
138 << "Use -f command line argument to force output\n";
139 return 1;
140 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000141
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000142 Out = new std::ofstream(OutputFilename.c_str());
143 if (!Out->good()) {
144 std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
145 delete Out;
146 return 1;
147 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000148
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000149 // Make sure that the Out file gets unlinked from the disk if we get a
150 // SIGINT
151 sys::RemoveFileOnSignal(sys::Path(OutputFilename));
Chris Lattner697954c2002-01-20 22:54:45 +0000152 }
Chris Lattner3524fc22001-10-15 17:30:47 +0000153 }
Vikram S. Adve7d0ba022002-09-16 16:35:34 +0000154
Chris Lattnercbb34a72005-06-25 03:00:34 +0000155 // Ask the target to add backend passes as necessary.
Chris Lattner85141582005-06-25 02:50:35 +0000156 if (Target.addPassesToEmitFile(Passes, *Out, TargetMachine::AssemblyFile)) {
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000157 std::cerr << argv[0] << ": target '" << Target.getName()
158 << "' does not support static compilation!\n";
159 if (Out != &std::cout) delete Out;
160 // And the Out file is empty and useless, so remove it now.
161 std::remove(OutputFilename.c_str());
162 return 1;
163 } else {
164 // Run our queue of passes all at once now, efficiently.
165 Passes.run(*M.get());
166 }
167
168 // Delete the ostream if it's not a stdout stream
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000169 if (Out != &std::cout) delete Out;
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000170
171 return 0;
172 } catch (const std::string& msg) {
173 std::cerr << argv[0] << ": " << msg << "\n";
174 } catch (...) {
175 std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
Chris Lattner63342052002-10-29 21:12:46 +0000176 }
Reid Spencer1ef8bda2004-12-30 05:36:08 +0000177 return 1;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +0000178}