| Chris Lattner | b79757c | 2001-10-04 01:40:53 +0000 | [diff] [blame] | 1 | //===-- llc.cpp - Implement the LLVM Compiler -----------------------------===// | 
| Chris Lattner | e737c7a | 2001-09-07 22:20:50 +0000 | [diff] [blame] | 2 | // | 
 | 3 | // This is the llc compiler driver. | 
 | 4 | // | 
| Chris Lattner | b79757c | 2001-10-04 01:40:53 +0000 | [diff] [blame] | 5 | //===----------------------------------------------------------------------===// | 
| Vikram S. Adve | cb465fc | 2001-07-21 12:42:29 +0000 | [diff] [blame] | 6 |  | 
| Vikram S. Adve | cb465fc | 2001-07-21 12:42:29 +0000 | [diff] [blame] | 7 | #include "llvm/Bytecode/Reader.h" | 
| Chris Lattner | b26bcc5 | 2001-09-14 05:34:53 +0000 | [diff] [blame] | 8 | #include "llvm/Target/Sparc.h" | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 9 | #include "llvm/Target/TargetMachine.h" | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 10 | #include "llvm/Transforms/Instrumentation/TraceValues.h" | 
| Chris Lattner | d7db863 | 2002-01-22 01:04:08 +0000 | [diff] [blame] | 11 | #include "llvm/Transforms/ChangeAllocations.h" | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 12 | #include "llvm/Transforms/HoistPHIConstants.h" | 
| Vikram S. Adve | d32e70a | 2002-03-24 03:19:54 +0000 | [diff] [blame] | 13 | #include "llvm/Transforms/Scalar/DecomposeMultiDimRefs.h" | 
| Chris Lattner | 2197d21 | 2001-10-18 20:32:07 +0000 | [diff] [blame] | 14 | #include "llvm/Assembly/PrintModulePass.h" | 
 | 15 | #include "llvm/Bytecode/WriteBytecodePass.h" | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 16 | #include "llvm/Transforms/ConstantMerge.h" | 
| Chris Lattner | 46ac43c | 2001-09-07 21:26:31 +0000 | [diff] [blame] | 17 | #include "llvm/Module.h" | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 18 | #include "llvm/Function.h" | 
| Chris Lattner | cd50d3f | 2002-01-31 00:46:45 +0000 | [diff] [blame] | 19 | #include "llvm/PassManager.h" | 
| Chris Lattner | cee8f9a | 2001-11-27 00:03:19 +0000 | [diff] [blame] | 20 | #include "Support/CommandLine.h" | 
| Chris Lattner | da784ee | 2001-09-18 17:04:18 +0000 | [diff] [blame] | 21 | #include <memory> | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 22 | #include <string> | 
| Chris Lattner | 78f7e1a | 2001-09-19 16:52:09 +0000 | [diff] [blame] | 23 | #include <fstream> | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 24 | using std::string; | 
| Chris Lattner | 8f367bd | 2001-07-23 02:35:57 +0000 | [diff] [blame] | 25 |  | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 26 | static cl::String InputFilename ("", "Input filename", cl::NoFlags, "-"); | 
 | 27 | static cl::String OutputFilename("o", "Output filename", cl::NoFlags, ""); | 
 | 28 | static cl::Flag   Force         ("f", "Overwrite output files"); | 
 | 29 | static cl::Flag   DumpAsm       ("d", "Print bytecode before native code generation", cl::Hidden); | 
 | 30 |  | 
 | 31 | enum TraceLevel { | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 32 |   TraceOff, TraceFunctions, TraceBasicBlocks | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 33 | }; | 
 | 34 |  | 
 | 35 | static cl::Enum<enum TraceLevel> TraceValues("trace", cl::NoFlags, | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 36 |   "Trace values through functions or basic blocks", | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 37 |   clEnumValN(TraceOff        , "off",        "Disable trace code"), | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 38 |   clEnumValN(TraceFunctions  , "function",   "Trace each function"), | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 39 |   clEnumValN(TraceBasicBlocks, "basicblock", "Trace each basic block"), 0); | 
| Chris Lattner | 8f367bd | 2001-07-23 02:35:57 +0000 | [diff] [blame] | 40 |  | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 41 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 42 | // GetFileNameRoot - Helper function to get the basename of a filename... | 
 | 43 | static inline string GetFileNameRoot(const string &InputFilename) { | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 44 |   string IFN = InputFilename; | 
 | 45 |   string outputFilename; | 
 | 46 |   int Len = IFN.length(); | 
 | 47 |   if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { | 
 | 48 |     outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ | 
 | 49 |   } else { | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 50 |     outputFilename = IFN; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 51 |   } | 
 | 52 |   return outputFilename; | 
 | 53 | } | 
 | 54 |  | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 55 |  | 
 | 56 | //===---------------------------------------------------------------------===// | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 57 | // Function main() | 
 | 58 | //  | 
 | 59 | // Entry point for the llc compiler. | 
 | 60 | //===---------------------------------------------------------------------===// | 
 | 61 |  | 
| Chris Lattner | 25c1229 | 2001-10-15 17:41:24 +0000 | [diff] [blame] | 62 | int main(int argc, char **argv) { | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 63 |   cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); | 
 | 64 |    | 
 | 65 |   // Allocate a target... in the future this will be controllable on the | 
 | 66 |   // command line. | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 67 |   std::auto_ptr<TargetMachine> target(allocateSparcTargetMachine()); | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 68 |   assert(target.get() && "Could not allocate target machine!"); | 
 | 69 |  | 
 | 70 |   TargetMachine &Target = *target.get(); | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 71 |    | 
 | 72 |   // Load the module to be compiled... | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 73 |   std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 74 |   if (M.get() == 0) { | 
 | 75 |     cerr << "bytecode didn't read correctly.\n"; | 
 | 76 |     return 1; | 
 | 77 |   } | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 78 |  | 
 | 79 |   // Build up all of the passes that we want to do to the module... | 
| Chris Lattner | f4de63f | 2002-01-21 07:31:50 +0000 | [diff] [blame] | 80 |   PassManager Passes; | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 81 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 82 |   // Hoist constants out of PHI nodes into predecessor BB's | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 83 |   Passes.add(createHoistPHIConstantsPass()); | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 84 |  | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 85 |   if (TraceValues != TraceOff) {   // If tracing enabled... | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 86 |     // Insert trace code in all functions in the module | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 87 |     if (TraceValues == TraceBasicBlocks) | 
 | 88 |       Passes.add(createTraceValuesPassForBasicBlocks()); | 
| Chris Lattner | 2fbfdcf | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 89 |     else if (TraceValues == TraceFunctions) | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 90 |       Passes.add(createTraceValuesPassForMethod()); | 
 | 91 |     else | 
 | 92 |       assert(0 && "Bad value for TraceValues!"); | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 93 |  | 
 | 94 |     // Eliminate duplication in constant pool | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 95 |     Passes.add(createDynamicConstantMergePass()); | 
| Vikram S. Adve | d32e70a | 2002-03-24 03:19:54 +0000 | [diff] [blame] | 96 |   } | 
 | 97 |    | 
 | 98 |   // Decompose multi-dimensional refs into a sequence of 1D refs | 
 | 99 |   Passes.add(createDecomposeMultiDimRefsPass()); | 
 | 100 |    | 
 | 101 |   // Write out the module with tracing code just before code generation | 
 | 102 |   if (TraceValues != TraceOff) {   // If tracing enabled... | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 103 |     assert(InputFilename != "-" && | 
 | 104 |            "files on stdin not supported with tracing"); | 
 | 105 |     string traceFileName = GetFileNameRoot(InputFilename) + ".trace.bc"; | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 106 |  | 
| Chris Lattner | 888912d | 2002-01-22 21:07:24 +0000 | [diff] [blame] | 107 |     if (!Force && std::ifstream(OutputFilename.c_str())) { | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 108 |       // If force is not specified, make sure not to overwrite a file! | 
 | 109 |       cerr << "Error opening '" << OutputFilename << "': File exists!\n" | 
 | 110 |            << "Use -f command line argument to force output\n"; | 
 | 111 |       return 1; | 
 | 112 |     } | 
| Vikram S. Adve | d32e70a | 2002-03-24 03:19:54 +0000 | [diff] [blame] | 113 |      | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 114 |     std::ostream *os = new std::ofstream(traceFileName.c_str()); | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 115 |     if (!os->good()) { | 
 | 116 |       cerr << "Error opening " << traceFileName | 
 | 117 |            << "! SKIPPING OUTPUT OF TRACE CODE\n"; | 
 | 118 |       delete os; | 
 | 119 |       return 1; | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 120 |     } | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 121 |      | 
| Chris Lattner | f4de63f | 2002-01-21 07:31:50 +0000 | [diff] [blame] | 122 |     Passes.add(new WriteBytecodePass(os, true)); | 
| Chris Lattner | c2c9dd1 | 2001-10-18 20:06:31 +0000 | [diff] [blame] | 123 |   } | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 124 |    | 
| Vikram S. Adve | 712ac2b | 2001-10-18 18:20:20 +0000 | [diff] [blame] | 125 |   // Replace malloc and free instructions with library calls. | 
 | 126 |   // Do this after tracing until lli implements these lib calls. | 
 | 127 |   // For now, it will emulate malloc and free internally. | 
| Chris Lattner | 4ddcd54 | 2002-02-26 21:36:53 +0000 | [diff] [blame] | 128 |   Passes.add(createLowerAllocationsPass(Target.DataLayout)); | 
| Vikram S. Adve | 712ac2b | 2001-10-18 18:20:20 +0000 | [diff] [blame] | 129 |    | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 130 |   // If LLVM dumping after transformations is requested, add it to the pipeline | 
 | 131 |   if (DumpAsm) | 
| Chris Lattner | 02d6ef8 | 2002-04-08 22:05:01 +0000 | [diff] [blame^] | 132 |     Passes.add(new PrintFunctionPass("Code after xformations: \n", &cerr)); | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 133 |  | 
| Chris Lattner | e41576d | 2002-02-03 23:43:19 +0000 | [diff] [blame] | 134 |   // Figure out where we are going to send the output... | 
 | 135 |   std::ostream *Out = 0; | 
 | 136 |   if (OutputFilename != "") {   // Specified an output filename? | 
 | 137 |     if (!Force && std::ifstream(OutputFilename.c_str())) { | 
 | 138 |       // If force is not specified, make sure not to overwrite a file! | 
 | 139 |       cerr << "Error opening '" << OutputFilename << "': File exists!\n" | 
 | 140 |            << "Use -f command line argument to force output\n"; | 
 | 141 |       return 1; | 
 | 142 |     } | 
 | 143 |     Out = new std::ofstream(OutputFilename.c_str()); | 
 | 144 |   } else { | 
 | 145 |     if (InputFilename == "-") { | 
 | 146 |       OutputFilename = "-"; | 
 | 147 |       Out = &std::cout; | 
 | 148 |     } else { | 
 | 149 |       string OutputFilename = GetFileNameRoot(InputFilename);  | 
 | 150 |       OutputFilename += ".s"; | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 151 |  | 
| Chris Lattner | 888912d | 2002-01-22 21:07:24 +0000 | [diff] [blame] | 152 |       if (!Force && std::ifstream(OutputFilename.c_str())) { | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 153 |         // If force is not specified, make sure not to overwrite a file! | 
 | 154 |         cerr << "Error opening '" << OutputFilename << "': File exists!\n" | 
 | 155 |              << "Use -f command line argument to force output\n"; | 
 | 156 |         return 1; | 
 | 157 |       } | 
| Chris Lattner | e41576d | 2002-02-03 23:43:19 +0000 | [diff] [blame] | 158 |  | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 159 |       Out = new std::ofstream(OutputFilename.c_str()); | 
| Chris Lattner | e41576d | 2002-02-03 23:43:19 +0000 | [diff] [blame] | 160 |       if (!Out->good()) { | 
 | 161 |         cerr << "Error opening " << OutputFilename << "!\n"; | 
 | 162 |         delete Out; | 
 | 163 |         return 1; | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 164 |       } | 
 | 165 |     } | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 166 |   } | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 167 |    | 
| Chris Lattner | e41576d | 2002-02-03 23:43:19 +0000 | [diff] [blame] | 168 |   Target.addPassesToEmitAssembly(Passes, *Out); | 
 | 169 |    | 
| Chris Lattner | f4de63f | 2002-01-21 07:31:50 +0000 | [diff] [blame] | 170 |   // Run our queue of passes all at once now, efficiently. | 
 | 171 |   Passes.run(M.get()); | 
| Chris Lattner | 05e5e07 | 2001-10-18 01:31:22 +0000 | [diff] [blame] | 172 |  | 
| Chris Lattner | e41576d | 2002-02-03 23:43:19 +0000 | [diff] [blame] | 173 |   if (Out != &std::cout) delete Out; | 
 | 174 |  | 
| Chris Lattner | d7477ee | 2001-10-18 20:33:21 +0000 | [diff] [blame] | 175 |   return 0; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 176 | } |