llc.cpp revision 90c5b3d753cef1f731dbb66f151da75af1f024b4
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 19cl::String InputFilename ("", "Input filename", cl::NoFlags, "-"); 20cl::String OutputFilename("o", "Output filename", cl::NoFlags, ""); 21cl::Flag Force ("f", "Overwrite output files", cl::NoFlags, false); 22cl::Flag DumpAsm ("d", "Print bytecode before native code generation", cl::Hidden,false); 23cl::Flag DoNotEmitAssembly("noasm", "Do not emit assembly code", cl::Hidden, false); 24cl::Flag TraceBBValues ("trace", 25 "Trace values at basic block and method exits", 26 cl::NoFlags, false); 27cl::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 44Method *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// 49static 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 77static 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 146static void NormalizeMethod(Method *M) { 147 NormalizePhiConstantArgs(M); 148} 149 150inline string 151GetFileNameRoot(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 164inline string 165GetTraceAssemblyFileName(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 179int 180PreprocessModule(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 198int 199OptimizeModule(Module* module) 200{ 201 return 0; 202} 203 204 205//===---------------------------------------------------------------------===// 206// Function GenerateCodeForModule() 207// 208// Native code generation for a specified target. 209//===---------------------------------------------------------------------===// 210 211int 212GenerateCodeForModule(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 275int 276EmitAssemblyForModule(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 315int 316main(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 if (PreprocessModule(M.get())) return 1; 333 334 if (OptimizeModule(M.get())) return 1; 335 336 if (GenerateCodeForModule(M.get(), target.get())) return 1; 337 338 if (!DoNotEmitAssembly) 339 if (EmitAssemblyForModule(M.get(), target.get())) return 1; 340 341 return 0; 342} 343 344