MethodTypes take an explicit isVarArg argument
[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/Support/CommandLine.h"
12 #include "llvm/Module.h"
13 #include "llvm/Method.h"
14 #include <memory>
15 #include <fstream>
16
17 cl::String InputFilename ("", "Input filename", cl::NoFlags, "-");
18 cl::String OutputFilename("o", "Output filename", cl::NoFlags, "");
19 cl::Flag   Force         ("f", "Overwrite output files", cl::NoFlags, false);
20 cl::Flag   DumpAsm       ("d", "Print assembly as compiled", cl::Hidden, false);
21
22 #include "llvm/Assembly/Writer.h"   // For DumpAsm
23
24 //-------------------------- Internal Functions ------------------------------//
25
26
27 /////
28 // TODO: Remove to external file.... When Chris gets back he'll do it
29 /////
30 #include "llvm/DerivedTypes.h"
31 #include "llvm/iMemory.h"
32 #include "llvm/iOther.h"
33 #include "llvm/SymbolTable.h"
34
35
36 Method *MallocMeth = 0, *FreeMeth = 0;
37
38 // InsertMallocFreeDecls - Insert an external declaration for malloc and an
39 // external declaration for free for use by the ReplaceMallocFree function.
40 //
41 static void InsertMallocFreeDecls(Module *M) {
42   const MethodType *MallocType = 
43     MethodType::get(PointerType::get(Type::UByteTy),
44                     vector<const Type*>(1, Type::UIntTy), false);
45
46   SymbolTable *SymTab = M->getSymbolTableSure();
47   
48   // Check for a definition of malloc
49   if (Value *V = SymTab->lookup(PointerType::get(MallocType), "malloc")) {
50     MallocMeth = cast<Method>(V);      // Yup, got it
51   } else {                             // Nope, add one
52     M->getMethodList().push_back(MallocMeth = new Method(MallocType, "malloc"));
53   }
54
55   const MethodType *FreeType = 
56     MethodType::get(Type::VoidTy,
57                     vector<const Type*>(1, PointerType::get(Type::UByteTy)),
58                     false);
59
60   // Check for a definition of free
61   if (Value *V = SymTab->lookup(PointerType::get(FreeType), "free")) {
62     FreeMeth = cast<Method>(V);      // Yup, got it
63   } else {                             // Nope, add one
64     M->getMethodList().push_back(FreeMeth = new Method(FreeType, "free"));
65   }
66 }
67
68
69 static void ReplaceMallocFree(Method *M, const TargetData &DataLayout) {
70   assert(MallocMeth && FreeMeth && M && "Must call InsertMallocFreeDecls!");
71
72   // Loop over all of the instructions, looking for malloc or free instructions
73   for (Method::iterator BBI = M->begin(), BBE = M->end(); BBI != BBE; ++BBI) {
74     BasicBlock *BB = *BBI;
75     for (unsigned i = 0; i < BB->size(); ++i) {
76       BasicBlock::InstListType &BBIL = BB->getInstList();
77       if (MallocInst *MI = dyn_cast<MallocInst>(*(BBIL.begin()+i))) {
78         BBIL.remove(BBIL.begin()+i);   // remove the malloc instr...
79         
80         const Type *AllocTy = cast<PointerType>(MI->getType())->getValueType();
81
82         // If the user is allocating an unsized array with a dynamic size arg,
83         // start by getting the size of one element.
84         //
85         if (const ArrayType *ATy = dyn_cast<ArrayType>(AllocTy)) 
86           if (ATy->isUnsized()) AllocTy = ATy->getElementType();
87
88         // Get the number of bytes to be allocated for one element of the
89         // requested type...
90         unsigned Size = DataLayout.getTypeSize(AllocTy);
91
92         // malloc(type) becomes sbyte *malloc(constint)
93         Value *MallocArg = ConstPoolUInt::get(Type::UIntTy, Size);
94         if (MI->getNumOperands() && Size == 1) {
95           MallocArg = MI->getOperand(0);         // Operand * 1 = Operand
96         } else if (MI->getNumOperands()) {
97           // Multiply it by the array size if neccesary...
98           MallocArg = BinaryOperator::create(Instruction::Mul,MI->getOperand(0),
99                                              MallocArg);
100           BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
101         }
102
103         // Create the call to Malloc...
104         CallInst *MCall = new CallInst(MallocMeth,
105                                        vector<Value*>(1, MallocArg));
106         BBIL.insert(BBIL.begin()+i, MCall);
107
108         // Create a cast instruction to convert to the right type...
109         CastInst *MCast = new CastInst(MCall, MI->getType());
110         BBIL.insert(BBIL.begin()+i+1, MCast);
111
112         // Replace all uses of the old malloc inst with the cast inst
113         MI->replaceAllUsesWith(MCast);
114         delete MI;                          // Delete the malloc inst
115       } else if (FreeInst *FI = dyn_cast<FreeInst>(*(BBIL.begin()+i))) {
116         BBIL.remove(BB->getInstList().begin()+i);
117
118         // Cast the argument to free into a ubyte*...
119         CastInst *MCast = new CastInst(FI->getOperand(0), 
120                                        PointerType::get(Type::UByteTy));
121         BBIL.insert(BBIL.begin()+i, MCast);
122
123         // Insert a call to the free function...
124         CallInst *FCall = new CallInst(FreeMeth,
125                                        vector<Value*>(1, MCast));
126         BBIL.insert(BBIL.begin()+i+1, FCall);
127
128         // Delete the old free instruction
129         delete FI;
130       }
131     }
132   }
133 }
134
135
136 // END TODO: Remove to external file....
137
138 static void NormalizeMethod(Method *M) {
139   NormalizePhiConstantArgs(M);
140 }
141
142
143 //===---------------------------------------------------------------------===//
144 // Function main()
145 // 
146 // Entry point for the llc compiler.
147 //===---------------------------------------------------------------------===//
148
149 int main(int argc, char **argv) {
150   // Parse command line options...
151   cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
152
153   // Allocate a target... in the future this will be controllable on the
154   // command line.
155   auto_ptr<TargetMachine> Target(allocateSparcTargetMachine());
156
157   // Load the module to be compiled...
158   auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
159   if (M.get() == 0) {
160     cerr << "bytecode didn't read correctly.\n";
161     return 1;
162   }
163
164   InsertMallocFreeDecls(M.get());
165
166   // Loop over all of the methods in the module, compiling them.
167   for (Module::const_iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
168     Method *Meth = *MI;
169     
170     NormalizeMethod(Meth);
171     ReplaceMallocFree(Meth, Target->DataLayout);
172     
173     if (DumpAsm)
174       cerr << "Method after xformations: \n" << Meth;
175
176     if (Target->compileMethod(Meth)) {
177       cerr << "Error compiling " << InputFilename << "!\n";
178       return 1;
179     }
180   }
181   
182   // Figure out where we are going to send the output...
183   ostream *Out = 0;
184   if (OutputFilename != "") {   // Specified an output filename?
185     Out = new ofstream(OutputFilename.c_str(), 
186                        (Force ? 0 : ios::noreplace)|ios::out);
187   } else {
188     if (InputFilename == "-") {
189       OutputFilename = "-";
190       Out = &cout;
191     } else {
192       string IFN = InputFilename;
193       int Len = IFN.length();
194       if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
195         OutputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
196       } else {
197         OutputFilename = IFN;   // Append a .s to it
198       }
199       OutputFilename += ".s";
200       Out = new ofstream(OutputFilename.c_str(), 
201                          (Force ? 0 : ios::noreplace)|ios::out);
202       if (!Out->good()) {
203         cerr << "Error opening " << OutputFilename << "!\n";
204         delete Out;
205         return 1;
206       }
207     }
208   }
209
210   // Emit the output...
211   Target->emitAssembly(M.get(), *Out);
212
213   if (Out != &cout) delete Out;
214   return 0;
215 }
216
217