blob: f845782946cbdcc7c4a99cb569375c16ffc4b22d [file] [log] [blame]
Chris Lattner5b836c42003-06-20 15:49:04 +00001//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
John Criswell7c0e0222003-10-20 17:47:21 +00002//
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//===----------------------------------------------------------------------===//
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
11// command-line interface for generating native assembly-language code
12// 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"
Chris Lattnercee8f9a2001-11-27 00:03:19 +000023#include "Support/CommandLine.h"
Chris Lattnere45110e2004-07-11 04:03:24 +000024#include "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.
35//
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 Lattner68492722003-04-28 03:28:56 +000044
Chris Lattnere45110e2004-07-11 04:03:24 +000045static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
46MArch("march", cl::desc("Architecture to generate assembly for:"));
47
Chris Lattner3524fc22001-10-15 17:30:47 +000048// GetFileNameRoot - Helper function to get the basename of a filename...
Chris Lattnerb5881f12003-04-25 05:26:11 +000049static inline std::string
Chris Lattnere45110e2004-07-11 04:03:24 +000050GetFileNameRoot(const std::string &InputFilename) {
Chris Lattnerb5881f12003-04-25 05:26:11 +000051 std::string IFN = InputFilename;
52 std::string outputFilename;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000053 int Len = IFN.length();
John Criswellb5d09bf2003-08-28 21:42:29 +000054 if ((Len > 2) &&
55 IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
Chris Lattnerb5881f12003-04-25 05:26:11 +000056 outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000057 } else {
Chris Lattner3524fc22001-10-15 17:30:47 +000058 outputFilename = IFN;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000059 }
60 return outputFilename;
61}
62
Vikram S. Adve805eb962001-09-18 13:10:45 +000063
Chris Lattner5b836c42003-06-20 15:49:04 +000064// main - Entry point for the llc compiler.
65//
66int main(int argc, char **argv) {
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000067 cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
Chris Lattner364d1202004-02-19 20:32:39 +000068 PrintStackTraceOnErrorSignal();
69
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +000070 // Load the module to be compiled...
Chris Lattner697954c2002-01-20 22:54:45 +000071 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
Chris Lattner5b836c42003-06-20 15:49:04 +000072 if (M.get() == 0) {
73 std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
74 return 1;
75 }
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +000076 Module &mod = *M.get();
77
78 // Allocate target machine. First, check whether the user has
79 // explicitly specified an architecture to compile for.
Chris Lattner6fb6ce32003-12-28 09:51:04 +000080 TargetMachine* (*TargetMachineAllocator)(const Module&,
81 IntrinsicLowering *) = 0;
Chris Lattnere45110e2004-07-11 04:03:24 +000082 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";
Chris Lattnerbb433502003-08-24 14:02:14 +000089 return 1;
Chris Lattnere45110e2004-07-11 04:03:24 +000090 }
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +000091 }
Chris Lattnere45110e2004-07-11 04:03:24 +000092
93 std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +000094 assert(target.get() && "Could not allocate target machine!");
95 TargetMachine &Target = *target.get();
96 const TargetData &TD = Target.getTargetData();
Chris Lattner39fd6592002-05-20 21:20:08 +000097
Chris Lattner3524fc22001-10-15 17:30:47 +000098 // Build up all of the passes that we want to do to the module...
Chris Lattnerf4de63f2002-01-21 07:31:50 +000099 PassManager Passes;
Chris Lattner3524fc22001-10-15 17:30:47 +0000100
Chris Lattner10daaa12003-04-26 20:11:09 +0000101 Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
Chris Lattnerbc194662003-04-25 06:06:13 +0000102 TD.getPointerAlignment(), TD.getDoubleAlignment()));
Chris Lattner2b5f2c12003-04-25 05:22:29 +0000103
Chris Lattnere41576d2002-02-03 23:43:19 +0000104 // Figure out where we are going to send the output...
105 std::ostream *Out = 0;
Chris Lattnercccc28c2003-06-18 18:46:08 +0000106 if (OutputFilename != "") {
Brian Gaeke5ce1a582003-06-18 21:43:33 +0000107 if (OutputFilename != "-") {
108 // Specified an output filename?
109 if (!Force && std::ifstream(OutputFilename.c_str())) {
110 // If force is not specified, make sure not to overwrite a file!
111 std::cerr << argv[0] << ": error opening '" << OutputFilename
112 << "': file exists!\n"
113 << "Use -f command line argument to force output\n";
114 return 1;
115 }
116 Out = new std::ofstream(OutputFilename.c_str());
Chris Lattnercccc28c2003-06-18 18:46:08 +0000117
Misha Brukman452fea92003-10-10 17:56:49 +0000118 // Make sure that the Out file gets unlinked from the disk if we get a
Brian Gaeke5ce1a582003-06-18 21:43:33 +0000119 // SIGINT
120 RemoveFileOnSignal(OutputFilename);
121 } else {
122 Out = &std::cout;
123 }
Chris Lattnercccc28c2003-06-18 18:46:08 +0000124 } else {
125 if (InputFilename == "-") {
126 OutputFilename = "-";
127 Out = &std::cout;
128 } else {
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000129 OutputFilename = GetFileNameRoot(InputFilename);
Chris Lattner74661c82004-02-15 22:54:19 +0000130
Chris Lattnere45110e2004-07-11 04:03:24 +0000131 if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
Chris Lattner74661c82004-02-15 22:54:19 +0000132 OutputFilename += ".s";
133 else
134 OutputFilename += ".cbe.c";
Chris Lattnercccc28c2003-06-18 18:46:08 +0000135
Chris Lattner888912d2002-01-22 21:07:24 +0000136 if (!Force && std::ifstream(OutputFilename.c_str())) {
Chris Lattner697954c2002-01-20 22:54:45 +0000137 // If force is not specified, make sure not to overwrite a file!
Chris Lattnerb5881f12003-04-25 05:26:11 +0000138 std::cerr << argv[0] << ": error opening '" << OutputFilename
139 << "': file exists!\n"
140 << "Use -f command line argument to force output\n";
Chris Lattner697954c2002-01-20 22:54:45 +0000141 return 1;
142 }
Chris Lattnercccc28c2003-06-18 18:46:08 +0000143
Chris Lattner697954c2002-01-20 22:54:45 +0000144 Out = new std::ofstream(OutputFilename.c_str());
Chris Lattnercccc28c2003-06-18 18:46:08 +0000145 if (!Out->good()) {
146 std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
147 delete Out;
148 return 1;
149 }
150
Misha Brukman452fea92003-10-10 17:56:49 +0000151 // Make sure that the Out file gets unlinked from the disk if we get a
Chris Lattner0f82df42002-09-19 16:06:28 +0000152 // SIGINT
Chris Lattner76d12292002-04-18 19:55:25 +0000153 RemoveFileOnSignal(OutputFilename);
Chris Lattner3524fc22001-10-15 17:30:47 +0000154 }
Chris Lattnercccc28c2003-06-18 18:46:08 +0000155 }
Vikram S. Adve7d0ba022002-09-16 16:35:34 +0000156
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000157 // Ask the target to add backend passes as necessary
Chris Lattner63342052002-10-29 21:12:46 +0000158 if (Target.addPassesToEmitAssembly(Passes, *Out)) {
Chris Lattnerb5881f12003-04-25 05:26:11 +0000159 std::cerr << argv[0] << ": target '" << Target.getName()
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000160 << "' does not support static compilation!\n";
161 if (Out != &std::cout) delete Out;
162 // And the Out file is empty and useless, so remove it now.
163 std::remove(OutputFilename.c_str());
164 return 1;
Chris Lattner63342052002-10-29 21:12:46 +0000165 } else {
166 // Run our queue of passes all at once now, efficiently.
167 Passes.run(*M.get());
168 }
Chris Lattner05e5e072001-10-18 01:31:22 +0000169
Chris Lattner0f82df42002-09-19 16:06:28 +0000170 // Delete the ostream if it's not a stdout stream
Chris Lattnere41576d2002-02-03 23:43:19 +0000171 if (Out != &std::cout) delete Out;
172
Chris Lattnerd7477ee2001-10-18 20:33:21 +0000173 return 0;
Vikram S. Adve2f64f9f2001-10-14 23:29:28 +0000174}