| 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 | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 11 | #include "llvm/Transforms/LowerAllocations.h" | 
 | 12 | #include "llvm/Transforms/HoistPHIConstants.h" | 
 | 13 | #include "llvm/Transforms/PrintModulePass.h" | 
| Chris Lattner | 57dbb3a | 2001-07-23 17:46:59 +0000 | [diff] [blame] | 14 | #include "llvm/Support/CommandLine.h" | 
| Chris Lattner | 46ac43c | 2001-09-07 21:26:31 +0000 | [diff] [blame] | 15 | #include "llvm/Module.h" | 
 | 16 | #include "llvm/Method.h" | 
| Chris Lattner | da784ee | 2001-09-18 17:04:18 +0000 | [diff] [blame] | 17 | #include <memory> | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 18 | #include <string> | 
| Chris Lattner | 78f7e1a | 2001-09-19 16:52:09 +0000 | [diff] [blame] | 19 | #include <fstream> | 
| Chris Lattner | 8f367bd | 2001-07-23 02:35:57 +0000 | [diff] [blame] | 20 |  | 
| Chris Lattner | 1e78f36 | 2001-07-23 19:27:24 +0000 | [diff] [blame] | 21 | cl::String InputFilename ("", "Input filename", cl::NoFlags, "-"); | 
| Chris Lattner | 8f367bd | 2001-07-23 02:35:57 +0000 | [diff] [blame] | 22 | cl::String OutputFilename("o", "Output filename", cl::NoFlags, ""); | 
| Chris Lattner | 25c1229 | 2001-10-15 17:41:24 +0000 | [diff] [blame] | 23 | cl::Flag   Force         ("f", "Overwrite output files"); | 
 | 24 | cl::Flag   DumpAsm       ("d", "Print bytecode before native code generation", | 
 | 25 |                           cl::Hidden); | 
 | 26 | cl::Flag   DoNotEmitAssembly("noasm", "Do not emit assembly code", cl::Hidden); | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 27 | cl::Flag   TraceBBValues ("trace", | 
| Chris Lattner | 25c1229 | 2001-10-15 17:41:24 +0000 | [diff] [blame] | 28 |                           "Trace values at basic block and method exits"); | 
 | 29 | cl::Flag   TraceMethodValues("tracem", "Trace values only at method exits"); | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 30 | cl::Flag   DebugTrace    ("debugtrace", | 
 | 31 |                           "output trace code as assembly instead of bytecode"); | 
| Chris Lattner | 8f367bd | 2001-07-23 02:35:57 +0000 | [diff] [blame] | 32 |  | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 33 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 34 | // GetFileNameRoot - Helper function to get the basename of a filename... | 
 | 35 | static inline string GetFileNameRoot(const string &InputFilename) { | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 36 |   string IFN = InputFilename; | 
 | 37 |   string outputFilename; | 
 | 38 |   int Len = IFN.length(); | 
 | 39 |   if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { | 
 | 40 |     outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ | 
 | 41 |   } else { | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 42 |     outputFilename = IFN; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 43 |   } | 
 | 44 |   return outputFilename; | 
 | 45 | } | 
 | 46 |  | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 47 |  | 
 | 48 | //===---------------------------------------------------------------------===// | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 49 | // GenerateCodeForTarget Pass | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 50 | //  | 
 | 51 | // Native code generation for a specified target. | 
 | 52 | //===---------------------------------------------------------------------===// | 
 | 53 |  | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 54 | class GenerateCodeForTarget : public Pass { | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 55 |   TargetMachine &Target; | 
 | 56 | public: | 
 | 57 |   inline GenerateCodeForTarget(TargetMachine &T) : Target(T) {} | 
 | 58 |  | 
 | 59 |   // doPerMethodWork - This method does the actual work of generating code for | 
 | 60 |   // the specified method. | 
 | 61 |   // | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 62 |   bool doPerMethodWork(Method *M) { | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 63 |     if (!M->isExternal() && Target.compileMethod(M)) { | 
 | 64 |       cerr << "Error compiling " << InputFilename << "!\n"; | 
 | 65 |       return true; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 66 |     } | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 67 |      | 
 | 68 |     return false; | 
 | 69 |   } | 
 | 70 | }; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 71 |  | 
 | 72 |  | 
 | 73 | //===---------------------------------------------------------------------===// | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 74 | // EmitAssembly Pass | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 75 | //  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 76 | // Write assembly code to specified output stream | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 77 | //===---------------------------------------------------------------------===// | 
 | 78 |  | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 79 | class EmitAssembly : public Pass { | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 80 |   const TargetMachine &Target;   // Target to compile for | 
 | 81 |   ostream *Out;                  // Stream to print on | 
 | 82 |   bool DeleteStream;             // Delete stream in dtor? | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 83 | public: | 
 | 84 |   inline EmitAssembly(const TargetMachine &T, ostream *O, bool D) | 
 | 85 |     : Target(T), Out(O), DeleteStream(D) {} | 
 | 86 |  | 
| Chris Lattner | 78f7e1a | 2001-09-19 16:52:09 +0000 | [diff] [blame] | 87 |  | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 88 |   virtual bool doPassFinalization(Module *M) { | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 89 |     Target.emitAssembly(M, *Out); | 
| Chris Lattner | 78f7e1a | 2001-09-19 16:52:09 +0000 | [diff] [blame] | 90 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 91 |     if (DeleteStream) delete Out; | 
| Chris Lattner | 685639d | 2001-10-18 05:28:44 +0000 | [diff] [blame] | 92 |     return false; | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 93 |   } | 
 | 94 | }; | 
| Chris Lattner | 0e6530e | 2001-09-14 03:37:52 +0000 | [diff] [blame] | 95 |  | 
| Vikram S. Adve | 805eb96 | 2001-09-18 13:10:45 +0000 | [diff] [blame] | 96 |  | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 97 | //===---------------------------------------------------------------------===// | 
 | 98 | // Function main() | 
 | 99 | //  | 
 | 100 | // Entry point for the llc compiler. | 
 | 101 | //===---------------------------------------------------------------------===// | 
 | 102 |  | 
| Chris Lattner | 25c1229 | 2001-10-15 17:41:24 +0000 | [diff] [blame] | 103 | int main(int argc, char **argv) { | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 104 |   int retCode = 0; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 105 |   cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); | 
 | 106 |    | 
 | 107 |   // Allocate a target... in the future this will be controllable on the | 
 | 108 |   // command line. | 
 | 109 |   auto_ptr<TargetMachine> target(allocateSparcTargetMachine()); | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 110 |   assert(target.get() && "Could not allocate target machine!"); | 
 | 111 |  | 
 | 112 |   TargetMachine &Target = *target.get(); | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 113 |    | 
 | 114 |   // Load the module to be compiled... | 
 | 115 |   auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); | 
 | 116 |   if (M.get() == 0) { | 
 | 117 |     cerr << "bytecode didn't read correctly.\n"; | 
 | 118 |     return 1; | 
 | 119 |   } | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 120 |  | 
 | 121 |   // Build up all of the passes that we want to do to the module... | 
 | 122 |   vector<Pass*> Passes; | 
 | 123 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 124 |   // Hoist constants out of PHI nodes into predecessor BB's | 
 | 125 |   Passes.push_back(new HoistPHIConstants()); | 
 | 126 |  | 
 | 127 |   if (TraceBBValues || TraceMethodValues)    // If tracing enabled... | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 128 |     { | 
 | 129 |       // Insert trace code in all methods in the module | 
 | 130 |       Passes.push_back(new InsertTraceCode(TraceBBValues,  | 
 | 131 |                                            TraceBBValues ||TraceMethodValues)); | 
 | 132 |        | 
 | 133 |       // Then write out the module with tracing code before code generation  | 
 | 134 |       assert(InputFilename != "-" && | 
 | 135 |              "files on stdin not supported with tracing"); | 
 | 136 |       string traceFileName = GetFileNameRoot(InputFilename) | 
 | 137 |                              + (DebugTrace? ".trace.ll" : ".trace.bc"); | 
 | 138 |       ostream *os = new ofstream(traceFileName.c_str(),  | 
 | 139 |                                  (Force ? 0 : ios::noreplace)|ios::out); | 
 | 140 |       if (!os->good()) { | 
 | 141 |         cerr << "Error opening " << traceFileName | 
 | 142 |              << "! SKIPPING OUTPUT OF TRACE CODE\n"; | 
 | 143 |         delete os; | 
 | 144 |         retCode = 1; | 
| Chris Lattner | c9a1de6 | 2001-10-18 17:07:22 +0000 | [diff] [blame] | 145 |       } else { | 
 | 146 |         Passes.push_back(new PrintModulePass("", os, | 
 | 147 |                                              /*deleteStream*/ true, | 
| Vikram S. Adve | 712ac2b | 2001-10-18 18:20:20 +0000 | [diff] [blame^] | 148 |                                              /*printPerMethod*/ false, | 
 | 149 |                                              /*printAsBytecode*/ !DebugTrace)); | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 150 |       } | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 151 |     } | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 152 |    | 
| Vikram S. Adve | 712ac2b | 2001-10-18 18:20:20 +0000 | [diff] [blame^] | 153 |   // Replace malloc and free instructions with library calls. | 
 | 154 |   // Do this after tracing until lli implements these lib calls. | 
 | 155 |   // For now, it will emulate malloc and free internally. | 
 | 156 |   Passes.push_back(new LowerAllocations(Target.DataLayout)); | 
 | 157 |    | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 158 |   // If LLVM dumping after transformations is requested, add it to the pipeline | 
 | 159 |   if (DumpAsm) | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 160 |     Passes.push_back(new PrintModulePass("Code after xformations: \n",&cerr)); | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 161 |  | 
 | 162 |   // Generate Target code... | 
 | 163 |   Passes.push_back(new GenerateCodeForTarget(Target)); | 
 | 164 |  | 
 | 165 |   if (!DoNotEmitAssembly) {                // If asm output is enabled... | 
 | 166 |     // Figure out where we are going to send the output... | 
 | 167 |     ostream *Out = 0; | 
 | 168 |     if (OutputFilename != "") {   // Specified an output filename? | 
 | 169 |       Out = new ofstream(OutputFilename.c_str(),  | 
 | 170 |                          (Force ? 0 : ios::noreplace)|ios::out); | 
 | 171 |     } else { | 
 | 172 |       if (InputFilename == "-") { | 
 | 173 |         OutputFilename = "-"; | 
 | 174 |         Out = &cout; | 
 | 175 |       } else { | 
 | 176 |         string OutputFilename = GetFileNameRoot(InputFilename);  | 
 | 177 |         OutputFilename += ".s"; | 
 | 178 |         Out = new ofstream(OutputFilename.c_str(),  | 
 | 179 |                            (Force ? 0 : ios::noreplace)|ios::out); | 
 | 180 |         if (!Out->good()) { | 
 | 181 |           cerr << "Error opening " << OutputFilename << "!\n"; | 
 | 182 |           delete Out; | 
 | 183 |           return 1; | 
 | 184 |         } | 
 | 185 |       } | 
 | 186 |     } | 
 | 187 |      | 
 | 188 |     // Output assembly language to the .s file | 
 | 189 |     Passes.push_back(new EmitAssembly(Target, Out, Out != &cout)); | 
 | 190 |   } | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 191 |    | 
| Chris Lattner | 05e5e07 | 2001-10-18 01:31:22 +0000 | [diff] [blame] | 192 |   // Run our queue of passes all at once now, efficiently.  This form of | 
 | 193 |   // runAllPasses frees the Pass objects after runAllPasses completes. | 
 | 194 |   Pass::runAllPassesAndFree(M.get(), Passes); | 
 | 195 |  | 
| Vikram S. Adve | 79a3349 | 2001-10-18 13:51:20 +0000 | [diff] [blame] | 196 |   return retCode; | 
| Vikram S. Adve | 2f64f9f | 2001-10-14 23:29:28 +0000 | [diff] [blame] | 197 | } | 
 | 198 |  | 
| Chris Lattner | 3524fc2 | 2001-10-15 17:30:47 +0000 | [diff] [blame] | 199 |  |