*** empty log message ***
[oota-llvm.git] / tools / llc / llc.cpp
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/Optimizations/Normalize.h"
9 #include "llvm/Target/Sparc.h"
10 #include "llvm/Target/TargetMachine.h"
11 #include "llvm/Transforms/Instrumentation/TraceValues.h"
12 #include "llvm/Support/CommandLine.h"
13 #include "llvm/Module.h"
14 #include "llvm/Method.h"
15 #include <memory>
16 #include <string>
17 #include <fstream>
18
19 cl::String InputFilename ("", "Input filename", cl::NoFlags, "-");
20 cl::String OutputFilename("o", "Output filename", cl::NoFlags, "");
21 cl::Flag   Force         ("f", "Overwrite output files", cl::NoFlags, false);
22 cl::Flag   DumpAsm       ("d", "Print bytecode before native code generation", cl::Hidden,false);
23 cl::Flag   DoNotEmitAssembly("noasm", "Do not emit assembly code", cl::Hidden, false);
24 cl::Flag   TraceBBValues ("trace",
25                           "Trace values at basic block and method exits",
26                           cl::NoFlags, false);
27 cl::Flag   TraceMethodValues("tracem", "Trace values only at method exits",
28                              cl::NoFlags, false);
29
30 #include "llvm/Assembly/Writer.h"   // For DumpAsm
31
32 //-------------------------- Internal Functions ------------------------------//
33
34
35 /////
36 // TODO: Remove to external file.... When Chris gets back he'll do it
37 /////
38 #include "llvm/DerivedTypes.h"
39 #include "llvm/iMemory.h"
40 #include "llvm/iOther.h"
41 #include "llvm/SymbolTable.h"
42
43
44 Method *MallocMeth = 0, *FreeMeth = 0;
45
46 // InsertMallocFreeDecls - Insert an external declaration for malloc and an
47 // external declaration for free for use by the ReplaceMallocFree function.
48 //
49 static void InsertMallocFreeDecls(Module *M) {
50   const MethodType *MallocType = 
51     MethodType::get(PointerType::get(Type::UByteTy),
52                     vector<const Type*>(1, Type::UIntTy), false);
53
54   SymbolTable *SymTab = M->getSymbolTableSure();
55   
56   // Check for a definition of malloc
57   if (Value *V = SymTab->lookup(PointerType::get(MallocType), "malloc")) {
58     MallocMeth = cast<Method>(V);      // Yup, got it
59   } else {                             // Nope, add one
60     M->getMethodList().push_back(MallocMeth = new Method(MallocType, "malloc"));
61   }
62
63   const MethodType *FreeType = 
64     MethodType::get(Type::VoidTy,
65                     vector<const Type*>(1, PointerType::get(Type::UByteTy)),
66                     false);
67
68   // Check for a definition of free
69   if (Value *V = SymTab->lookup(PointerType::get(FreeType), "free")) {
70     FreeMeth = cast<Method>(V);      // Yup, got it
71   } else {                             // Nope, add one
72     M->getMethodList().push_back(FreeMeth = new Method(FreeType, "free"));
73   }
74 }
75
76
77 static void ReplaceMallocFree(Method *M, const TargetData &DataLayout) {
78   assert(MallocMeth && FreeMeth && M && "Must call InsertMallocFreeDecls!");
79
80   // Loop over all of the instructions, looking for malloc or free instructions
81   for (Method::iterator BBI = M->begin(), BBE = M->end(); BBI != BBE; ++BBI) {
82     BasicBlock *BB = *BBI;
83     for (unsigned i = 0; i < BB->size(); ++i) {
84       BasicBlock::InstListType &BBIL = BB->getInstList();
85       if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
86         BBIL.remove(BBIL.begin()+i);   // remove the malloc instr...
87         
88         const Type *AllocTy = cast<PointerType>(MI->getType())->getValueType();
89
90         // If the user is allocating an unsized array with a dynamic size arg,
91         // start by getting the size of one element.
92         //
93         if (const ArrayType *ATy = dyn_cast<ArrayType>(AllocTy)) 
94           if (ATy->isUnsized()) AllocTy = ATy->getElementType();
95
96         // Get the number of bytes to be allocated for one element of the
97         // requested type...
98         unsigned Size = DataLayout.getTypeSize(AllocTy);
99
100         // malloc(type) becomes sbyte *malloc(constint)
101         Value *MallocArg = ConstPoolUInt::get(Type::UIntTy, Size);
102         if (MI->getNumOperands() && Size == 1) {
103           MallocArg = MI->getOperand(0);         // Operand * 1 = Operand
104         } else if (MI->getNumOperands()) {
105           // Multiply it by the array size if neccesary...
106           MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
107                                              MallocArg);
108           BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
109         }
110
111         // Create the call to Malloc...
112         CallInst *MCall = new CallInst(MallocMeth,
113                                        vector<Value*>(1, MallocArg));
114         BBIL.insert(BBIL.begin()+i, MCall);
115
116         // Create a cast instruction to convert to the right type...
117         CastInst *MCast = new CastInst(MCall, MI->getType());
118         BBIL.insert(BBIL.begin()+i+1, MCast);
119
120         // Replace all uses of the old malloc inst with the cast inst
121         MI->replaceAllUsesWith(MCast);
122         delete MI;                          // Delete the malloc inst
123       } else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
124         BBIL.remove(BB->getInstList().begin()+i);
125
126         // Cast the argument to free into a ubyte*...
127         CastInst *MCast = new CastInst(FI->getOperand(0), 
128                                        PointerType::get(Type::UByteTy));
129         BBIL.insert(BBIL.begin()+i, MCast);
130
131         // Insert a call to the free function...
132         CallInst *FCall = new CallInst(FreeMeth,
133                                        vector<Value*>(1, MCast));
134         BBIL.insert(BBIL.begin()+i+1, FCall);
135
136         // Delete the old free instruction
137         delete FI;
138       }
139     }
140   }
141 }
142
143
144 // END TODO: Remove to external file....
145
146 static void NormalizeMethod(Method *M) {
147   NormalizePhiConstantArgs(M);
148 }
149
150 inline string
151 GetFileNameRoot(const string& InputFilename)
152 {
153   string IFN = InputFilename;
154   string outputFilename;
155   int Len = IFN.length();
156   if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
157     outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
158   } else {
159     outputFilename = IFN;   // Append a .s to it
160   }
161   return outputFilename;
162 }
163
164 inline string
165 GetTraceAssemblyFileName(const string& inFilename)
166 {
167   assert(inFilename != "-" && "files on stdin not supported with tracing");
168   string traceFileName = GetFileNameRoot(inFilename);
169   traceFileName += ".trace.ll"; 
170   return traceFileName;
171 }
172
173 //===---------------------------------------------------------------------===//
174 // Function PreprocessModule()
175 // 
176 // Normalization to simplify later passes.
177 //===---------------------------------------------------------------------===//
178
179 int
180 PreprocessModule(Module* module)
181 {
182   InsertMallocFreeDecls(module);
183   
184   for (Module::const_iterator MI=module->begin(); MI != module->end(); ++MI)
185     if (! (*MI)->isExternal())
186       NormalizeMethod(*MI);
187   
188   return 0;
189 }
190
191
192 //===---------------------------------------------------------------------===//
193 // Function OptimizeModule()
194 // 
195 // Module optimization.
196 //===---------------------------------------------------------------------===//
197
198 int
199 OptimizeModule(Module* module)
200 {
201   return 0;
202 }
203
204
205 //===---------------------------------------------------------------------===//
206 // Function GenerateCodeForModule()
207 // 
208 // Native code generation for a specified target.
209 //===---------------------------------------------------------------------===//
210
211 int
212 GenerateCodeForModule(Module* module, TargetMachine* target)
213 {
214   // Since any transformation pass may introduce external function decls
215   // into the method list, find current methods first and then walk only those.
216   // 
217   vector<Method*> initialMethods(module->begin(), module->end());
218   
219   
220   // Replace malloc and free instructions with library calls
221   // 
222   for (unsigned i=0, N = initialMethods.size(); i < N; i++)
223     if (! initialMethods[i]->isExternal())
224       ReplaceMallocFree(initialMethods[i], target->DataLayout);
225   
226   
227   // Insert trace code to assist debugging
228   // 
229   if (TraceBBValues || TraceMethodValues)
230     {
231       // Insert trace code in all methods in the module
232       for (unsigned i=0, N = initialMethods.size(); i < N; i++)
233         if (! initialMethods[i]->isExternal())
234           InsertCodeToTraceValues(initialMethods[i], TraceBBValues,
235                                   TraceBBValues || TraceMethodValues);
236       
237       // Then write the module with tracing code out in assembly form
238       string traceFileName = GetTraceAssemblyFileName(InputFilename);
239       ofstream* ofs = new ofstream(traceFileName.c_str(), 
240                                    (Force ? 0 : ios::noreplace)|ios::out);
241       if (!ofs->good()) {
242         cerr << "Error opening " << traceFileName << "!\n";
243         delete ofs;
244         return 1;
245       }
246       WriteToAssembly(module, *ofs);
247       delete ofs;
248     }
249   
250   
251   // Generate native target code for all methods
252   // 
253   for (unsigned i=0, N = initialMethods.size(); i < N; i++)
254     if (! initialMethods[i]->isExternal())
255       {
256         if (DumpAsm)
257           cerr << "Method after xformations: \n" << initialMethods[i];
258         
259         if (target->compileMethod(initialMethods[i])) {
260           cerr << "Error compiling " << InputFilename << "!\n";
261           return 1;
262         }
263       }
264   
265   return 0;
266 }
267
268
269 //===---------------------------------------------------------------------===//
270 // Function EmitAssemblyForModule()
271 // 
272 // Write assembly code to specified output file; <ModuleName>.s by default.
273 //===---------------------------------------------------------------------===//
274
275 int
276 EmitAssemblyForModule(Module* module, TargetMachine* target)
277 {
278   // Figure out where we are going to send the output...
279   ostream *Out = 0;
280   if (OutputFilename != "") {   // Specified an output filename?
281     Out = new ofstream(OutputFilename.c_str(), 
282                        (Force ? 0 : ios::noreplace)|ios::out);
283   } else {
284     if (InputFilename == "-") {
285       OutputFilename = "-";
286       Out = &cout;
287     } else {
288       string OutputFilename = GetFileNameRoot(InputFilename); 
289       OutputFilename += ".s";
290       Out = new ofstream(OutputFilename.c_str(), 
291                          (Force ? 0 : ios::noreplace)|ios::out);
292       if (!Out->good()) {
293         cerr << "Error opening " << OutputFilename << "!\n";
294         delete Out;
295         return 1;
296       }
297     }
298   }
299
300   // Emit the output...
301   target->emitAssembly(module, *Out);
302
303   if (Out != &cout) delete Out;
304
305   return 0;
306 }
307
308
309 //===---------------------------------------------------------------------===//
310 // Function main()
311 // 
312 // Entry point for the llc compiler.
313 //===---------------------------------------------------------------------===//
314
315 int
316 main(int argc, char **argv)
317 {
318   // Parse command line options...
319   cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
320   
321   // Allocate a target... in the future this will be controllable on the
322   // command line.
323   auto_ptr<TargetMachine> target(allocateSparcTargetMachine());
324   
325   // Load the module to be compiled...
326   auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
327   if (M.get() == 0) {
328     cerr << "bytecode didn't read correctly.\n";
329     return 1;
330   }
331   
332   int failed = PreprocessModule(M.get());
333   
334   if (!failed)
335     failed = OptimizeModule(M.get());
336   
337   if (!failed)
338     failed = GenerateCodeForModule(M.get(), target.get());
339   
340   if (!failed && ! DoNotEmitAssembly)
341     failed = EmitAssemblyForModule(M.get(), target.get());
342   
343   return failed;
344 }
345