llc.cpp revision 212793
1//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// 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 bitcode. 13// 14//===----------------------------------------------------------------------===// 15 16#include "llvm/LLVMContext.h" 17#include "llvm/Module.h" 18#include "llvm/PassManager.h" 19#include "llvm/Pass.h" 20#include "llvm/ADT/Triple.h" 21#include "llvm/Support/IRReader.h" 22#include "llvm/CodeGen/LinkAllAsmWriterComponents.h" 23#include "llvm/CodeGen/LinkAllCodegenComponents.h" 24#include "llvm/Config/config.h" 25#include "llvm/Support/CommandLine.h" 26#include "llvm/Support/Debug.h" 27#include "llvm/Support/FormattedStream.h" 28#include "llvm/Support/ManagedStatic.h" 29#include "llvm/Support/PluginLoader.h" 30#include "llvm/Support/PrettyStackTrace.h" 31#include "llvm/System/Host.h" 32#include "llvm/System/Signals.h" 33#include "llvm/Target/SubtargetFeature.h" 34#include "llvm/Target/TargetData.h" 35#include "llvm/Target/TargetMachine.h" 36#include "llvm/Target/TargetRegistry.h" 37#include "llvm/Target/TargetSelect.h" 38#include <memory> 39using namespace llvm; 40 41// General options for llc. Other pass-specific options are specified 42// within the corresponding llc passes, and target-specific options 43// and back-end code generation options are specified with the target machine. 44// 45static cl::opt<std::string> 46InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 47 48static cl::opt<std::string> 49OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); 50 51// Determine optimization level. 52static cl::opt<char> 53OptLevel("O", 54 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " 55 "(default = '-O2')"), 56 cl::Prefix, 57 cl::ZeroOrMore, 58 cl::init(' ')); 59 60static cl::opt<std::string> 61TargetTriple("mtriple", cl::desc("Override target triple for module")); 62 63static cl::opt<std::string> 64MArch("march", cl::desc("Architecture to generate code for (see --version)")); 65 66static cl::opt<std::string> 67MCPU("mcpu", 68 cl::desc("Target a specific cpu type (-mcpu=help for details)"), 69 cl::value_desc("cpu-name"), 70 cl::init("")); 71 72static cl::list<std::string> 73MAttrs("mattr", 74 cl::CommaSeparated, 75 cl::desc("Target specific attributes (-mattr=help for details)"), 76 cl::value_desc("a1,+a2,-a3,...")); 77 78static cl::opt<bool> 79RelaxAll("mc-relax-all", 80 cl::desc("When used with filetype=obj, " 81 "relax all fixups in the emitted object file")); 82 83cl::opt<TargetMachine::CodeGenFileType> 84FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), 85 cl::desc("Choose a file type (not all types are supported by all targets):"), 86 cl::values( 87 clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm", 88 "Emit an assembly ('.s') file"), 89 clEnumValN(TargetMachine::CGFT_ObjectFile, "obj", 90 "Emit a native object ('.o') file [experimental]"), 91 clEnumValN(TargetMachine::CGFT_Null, "null", 92 "Emit nothing, for performance testing"), 93 clEnumValEnd)); 94 95cl::opt<bool> NoVerify("disable-verify", cl::Hidden, 96 cl::desc("Do not verify input module")); 97 98 99static cl::opt<bool> 100DisableRedZone("disable-red-zone", 101 cl::desc("Do not emit code that uses the red zone."), 102 cl::init(false)); 103 104static cl::opt<bool> 105NoImplicitFloats("no-implicit-float", 106 cl::desc("Don't generate implicit floating point instructions (x86-only)"), 107 cl::init(false)); 108 109// GetFileNameRoot - Helper function to get the basename of a filename. 110static inline std::string 111GetFileNameRoot(const std::string &InputFilename) { 112 std::string IFN = InputFilename; 113 std::string outputFilename; 114 int Len = IFN.length(); 115 if ((Len > 2) && 116 IFN[Len-3] == '.' && 117 ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') || 118 (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) { 119 outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ 120 } else { 121 outputFilename = IFN; 122 } 123 return outputFilename; 124} 125 126static tool_output_file *GetOutputStream(const char *TargetName, 127 Triple::OSType OS, 128 const char *ProgName) { 129 // If we don't yet have an output filename, make one. 130 if (OutputFilename.empty()) { 131 if (InputFilename == "-") 132 OutputFilename = "-"; 133 else { 134 OutputFilename = GetFileNameRoot(InputFilename); 135 136 switch (FileType) { 137 default: assert(0 && "Unknown file type"); 138 case TargetMachine::CGFT_AssemblyFile: 139 if (TargetName[0] == 'c') { 140 if (TargetName[1] == 0) 141 OutputFilename += ".cbe.c"; 142 else if (TargetName[1] == 'p' && TargetName[2] == 'p') 143 OutputFilename += ".cpp"; 144 else 145 OutputFilename += ".s"; 146 } else 147 OutputFilename += ".s"; 148 break; 149 case TargetMachine::CGFT_ObjectFile: 150 if (OS == Triple::Win32) 151 OutputFilename += ".obj"; 152 else 153 OutputFilename += ".o"; 154 break; 155 case TargetMachine::CGFT_Null: 156 OutputFilename += ".null"; 157 break; 158 } 159 } 160 } 161 162 // Decide if we need "binary" output. 163 bool Binary = false; 164 switch (FileType) { 165 default: assert(0 && "Unknown file type"); 166 case TargetMachine::CGFT_AssemblyFile: 167 break; 168 case TargetMachine::CGFT_ObjectFile: 169 case TargetMachine::CGFT_Null: 170 Binary = true; 171 break; 172 } 173 174 // Open the file. 175 std::string error; 176 unsigned OpenFlags = 0; 177 if (Binary) OpenFlags |= raw_fd_ostream::F_Binary; 178 tool_output_file *FDOut = new tool_output_file(OutputFilename.c_str(), error, 179 OpenFlags); 180 if (!error.empty()) { 181 errs() << error << '\n'; 182 delete FDOut; 183 return 0; 184 } 185 186 return FDOut; 187} 188 189// main - Entry point for the llc compiler. 190// 191int main(int argc, char **argv) { 192 sys::PrintStackTraceOnErrorSignal(); 193 PrettyStackTraceProgram X(argc, argv); 194 195 // Enable debug stream buffering. 196 EnableDebugBuffering = true; 197 198 LLVMContext &Context = getGlobalContext(); 199 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 200 201 // Initialize targets first, so that --version shows registered targets. 202 InitializeAllTargets(); 203 InitializeAllAsmPrinters(); 204 InitializeAllAsmParsers(); 205 206 cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); 207 208 // Load the module to be compiled... 209 SMDiagnostic Err; 210 std::auto_ptr<Module> M; 211 212 M.reset(ParseIRFile(InputFilename, Err, Context)); 213 if (M.get() == 0) { 214 Err.Print(argv[0], errs()); 215 return 1; 216 } 217 Module &mod = *M.get(); 218 219 // If we are supposed to override the target triple, do so now. 220 if (!TargetTriple.empty()) 221 mod.setTargetTriple(Triple::normalize(TargetTriple)); 222 223 Triple TheTriple(mod.getTargetTriple()); 224 if (TheTriple.getTriple().empty()) 225 TheTriple.setTriple(sys::getHostTriple()); 226 227 // Allocate target machine. First, check whether the user has explicitly 228 // specified an architecture to compile for. If so we have to look it up by 229 // name, because it might be a backend that has no mapping to a target triple. 230 const Target *TheTarget = 0; 231 if (!MArch.empty()) { 232 for (TargetRegistry::iterator it = TargetRegistry::begin(), 233 ie = TargetRegistry::end(); it != ie; ++it) { 234 if (MArch == it->getName()) { 235 TheTarget = &*it; 236 break; 237 } 238 } 239 240 if (!TheTarget) { 241 errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; 242 return 1; 243 } 244 245 // Adjust the triple to match (if known), otherwise stick with the 246 // module/host triple. 247 Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); 248 if (Type != Triple::UnknownArch) 249 TheTriple.setArch(Type); 250 } else { 251 std::string Err; 252 TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); 253 if (TheTarget == 0) { 254 errs() << argv[0] << ": error auto-selecting target for module '" 255 << Err << "'. Please use the -march option to explicitly " 256 << "pick a target.\n"; 257 return 1; 258 } 259 } 260 261 // Package up features to be passed to target/subtarget 262 std::string FeaturesStr; 263 if (MCPU.size() || MAttrs.size()) { 264 SubtargetFeatures Features; 265 Features.setCPU(MCPU); 266 for (unsigned i = 0; i != MAttrs.size(); ++i) 267 Features.AddFeature(MAttrs[i]); 268 FeaturesStr = Features.getString(); 269 } 270 271 std::auto_ptr<TargetMachine> 272 target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); 273 assert(target.get() && "Could not allocate target machine!"); 274 TargetMachine &Target = *target.get(); 275 276 // Figure out where we are going to send the output... 277 OwningPtr<tool_output_file> Out 278 (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); 279 if (!Out) return 1; 280 281 CodeGenOpt::Level OLvl = CodeGenOpt::Default; 282 switch (OptLevel) { 283 default: 284 errs() << argv[0] << ": invalid optimization level.\n"; 285 return 1; 286 case ' ': break; 287 case '0': OLvl = CodeGenOpt::None; break; 288 case '1': OLvl = CodeGenOpt::Less; break; 289 case '2': OLvl = CodeGenOpt::Default; break; 290 case '3': OLvl = CodeGenOpt::Aggressive; break; 291 } 292 293 // Build up all of the passes that we want to do to the module. 294 PassManager PM; 295 296 // Add the target data from the target machine, if it exists, or the module. 297 if (const TargetData *TD = Target.getTargetData()) 298 PM.add(new TargetData(*TD)); 299 else 300 PM.add(new TargetData(&mod)); 301 302 // Override default to generate verbose assembly. 303 Target.setAsmVerbosityDefault(true); 304 305 if (RelaxAll) { 306 if (FileType != TargetMachine::CGFT_ObjectFile) 307 errs() << argv[0] 308 << ": warning: ignoring -mc-relax-all because filetype != obj"; 309 else 310 Target.setMCRelaxAll(true); 311 } 312 313 { 314 formatted_raw_ostream FOS(Out->os()); 315 316 // Ask the target to add backend passes as necessary. 317 if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) { 318 errs() << argv[0] << ": target does not support generation of this" 319 << " file type!\n"; 320 return 1; 321 } 322 323 PM.run(mod); 324 } 325 326 // Declare success. 327 Out->keep(); 328 329 return 0; 330} 331