llc.cpp revision 4aba5e34a10588ced9d9c068008e8b28016dfd62
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/TraceValues.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 177 // Load the module to be compiled... 178 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 179 if (M.get() == 0) 180 { 181 cerr << argv[0] << ": bytecode didn't read correctly.\n"; 182 return 1; 183 } 184 185 // Build up all of the passes that we want to do to the module... 186 PassManager Passes; 187 188 // Create a new optimization pass for each one specified on the command line 189 // Deal specially with tracing passes, which must be run differently than opt. 190 // 191 for (unsigned i = 0; i < OptimizationList.size(); ++i) 192 { 193 const PassInfo *Opt = OptimizationList[i]; 194 195 if (std::string(Opt->getPassArgument()) == "trace") 196 TraceFunctions = !(TraceBasicBlocks = true); 197 else if (std::string(Opt->getPassArgument()) == "tracem") 198 TraceFunctions = !(TraceBasicBlocks = false); 199 else 200 { // handle other passes as normal optimization passes 201 if (Opt->getNormalCtor()) 202 Passes.add(Opt->getNormalCtor()()); 203 else if (Opt->getDataCtor()) 204 Passes.add(Opt->getDataCtor()(Target.DataLayout)); 205 else if (Opt->getTargetCtor()) 206 Passes.add(Opt->getTargetCtor()(Target)); 207 else 208 cerr << argv[0] << ": cannot create pass: " 209 << Opt->getPassName() << "\n"; 210 } 211 } 212 213 // Run tracing passes after other optimization passes and before llc passes. 214 if (TraceFunctions || TraceBasicBlocks) 215 Passes.add(new InsertTracingCodePass); 216 217 // Decompose multi-dimensional refs into a sequence of 1D refs 218 Passes.add(createDecomposeMultiDimRefsPass()); 219 220 // Replace malloc and free instructions with library calls. 221 // Do this after tracing until lli implements these lib calls. 222 // For now, it will emulate malloc and free internally. 223 Passes.add(createLowerAllocationsPass()); 224 225 // If LLVM dumping after transformations is requested, add it to the pipeline 226 if (DumpAsm) 227 Passes.add(new PrintFunctionPass("Code after xformations: \n", &cerr)); 228 229 // Strip all of the symbols from the bytecode so that it will be smaller... 230 Passes.add(createSymbolStrippingPass()); 231 232 // Figure out where we are going to send the output... 233 std::ostream *Out = 0; 234 if (OutputFilename != "") 235 { // Specified an output filename? 236 if (!Force && std::ifstream(OutputFilename.c_str())) { 237 // If force is not specified, make sure not to overwrite a file! 238 cerr << argv[0] << ": error opening '" << OutputFilename 239 << "': file exists!\n" 240 << "Use -f command line argument to force output\n"; 241 return 1; 242 } 243 Out = new std::ofstream(OutputFilename.c_str()); 244 245 // Make sure that the Out file gets unlink'd from the disk if we get a 246 // SIGINT 247 RemoveFileOnSignal(OutputFilename); 248 } 249 else 250 { 251 if (InputFilename == "-") 252 { 253 OutputFilename = "-"; 254 Out = &std::cout; 255 } 256 else 257 { 258 string OutputFilename = GetFileNameRoot(InputFilename); 259 OutputFilename += ".s"; 260 261 if (!Force && std::ifstream(OutputFilename.c_str())) 262 { 263 // If force is not specified, make sure not to overwrite a file! 264 cerr << argv[0] << ": error opening '" << OutputFilename 265 << "': file exists!\n" 266 << "Use -f command line argument to force output\n"; 267 return 1; 268 } 269 270 Out = new std::ofstream(OutputFilename.c_str()); 271 if (!Out->good()) 272 { 273 cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; 274 delete Out; 275 return 1; 276 } 277 278 // Make sure that the Out file gets unlink'd from the disk if we get a 279 // SIGINT 280 RemoveFileOnSignal(OutputFilename); 281 } 282 } 283 284 Target.addPassesToEmitAssembly(Passes, *Out); 285 286 // Run our queue of passes all at once now, efficiently. 287 Passes.run(*M.get()); 288 289 // Delete the ostream if it's not a stdout stream 290 if (Out != &std::cout) delete Out; 291 292 return 0; 293} 294