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