1 //===-- llc.cpp - Implement the LLVM Compiler -----------------------------===//
3 // This is the llc compiler driver.
5 //===----------------------------------------------------------------------===//
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"
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",
27 cl::Flag TraceMethodValues("tracem", "Trace values only at method exits",
30 #include "llvm/Assembly/Writer.h" // For DumpAsm
32 //-------------------------- Internal Functions ------------------------------//
36 // TODO: Remove to external file.... When Chris gets back he'll do it
38 #include "llvm/DerivedTypes.h"
39 #include "llvm/iMemory.h"
40 #include "llvm/iOther.h"
41 #include "llvm/SymbolTable.h"
44 Method *MallocMeth = 0, *FreeMeth = 0;
46 // InsertMallocFreeDecls - Insert an external declaration for malloc and an
47 // external declaration for free for use by the ReplaceMallocFree function.
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);
54 SymbolTable *SymTab = M->getSymbolTableSure();
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"));
63 const MethodType *FreeType =
64 MethodType::get(Type::VoidTy,
65 vector<const Type*>(1, PointerType::get(Type::UByteTy)),
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"));
77 static void ReplaceMallocFree(Method *M, const TargetData &DataLayout) {
78 assert(MallocMeth && FreeMeth && M && "Must call InsertMallocFreeDecls!");
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...
88 const Type *AllocTy = cast<PointerType>(MI->getType())->getValueType();
90 // If the user is allocating an unsized array with a dynamic size arg,
91 // start by getting the size of one element.
93 if (const ArrayType *ATy = dyn_cast<ArrayType>(AllocTy))
94 if (ATy->isUnsized()) AllocTy = ATy->getElementType();
96 // Get the number of bytes to be allocated for one element of the
98 unsigned Size = DataLayout.getTypeSize(AllocTy);
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),
108 BBIL.insert(BBIL.begin()+i++, cast<Instruction>(MallocArg));
111 // Create the call to Malloc...
112 CallInst *MCall = new CallInst(MallocMeth,
113 vector<Value*>(1, MallocArg));
114 BBIL.insert(BBIL.begin()+i, MCall);
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);
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);
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);
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);
136 // Delete the old free instruction
144 // END TODO: Remove to external file....
146 static void NormalizeMethod(Method *M) {
147 NormalizePhiConstantArgs(M);
151 GetFileNameRoot(const string& InputFilename)
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/
159 outputFilename = IFN; // Append a .s to it
161 return outputFilename;
165 GetTraceAssemblyFileName(const string& inFilename)
167 assert(inFilename != "-" && "files on stdin not supported with tracing");
168 string traceFileName = GetFileNameRoot(inFilename);
169 traceFileName += ".trace.ll";
170 return traceFileName;
173 //===---------------------------------------------------------------------===//
174 // Function PreprocessModule()
176 // Normalization to simplify later passes.
177 //===---------------------------------------------------------------------===//
180 PreprocessModule(Module* module)
182 InsertMallocFreeDecls(module);
184 for (Module::const_iterator MI=module->begin(); MI != module->end(); ++MI)
185 if (! (*MI)->isExternal())
186 NormalizeMethod(*MI);
192 //===---------------------------------------------------------------------===//
193 // Function OptimizeModule()
195 // Module optimization.
196 //===---------------------------------------------------------------------===//
199 OptimizeModule(Module* module)
205 //===---------------------------------------------------------------------===//
206 // Function GenerateCodeForModule()
208 // Native code generation for a specified target.
209 //===---------------------------------------------------------------------===//
212 GenerateCodeForModule(Module* module, TargetMachine* target)
214 // Since any transformation pass may introduce external function decls
215 // into the method list, find current methods first and then walk only those.
217 vector<Method*> initialMethods(module->begin(), module->end());
220 // Replace malloc and free instructions with library calls
222 for (unsigned i=0, N = initialMethods.size(); i < N; i++)
223 if (! initialMethods[i]->isExternal())
224 ReplaceMallocFree(initialMethods[i], target->DataLayout);
227 // Insert trace code to assist debugging
229 if (TraceBBValues || TraceMethodValues)
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);
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);
242 cerr << "Error opening " << traceFileName << "!\n";
246 WriteToAssembly(module, *ofs);
251 // Generate native target code for all methods
253 for (unsigned i=0, N = initialMethods.size(); i < N; i++)
254 if (! initialMethods[i]->isExternal())
257 cerr << "Method after xformations: \n" << initialMethods[i];
259 if (target->compileMethod(initialMethods[i])) {
260 cerr << "Error compiling " << InputFilename << "!\n";
269 //===---------------------------------------------------------------------===//
270 // Function EmitAssemblyForModule()
272 // Write assembly code to specified output file; <ModuleName>.s by default.
273 //===---------------------------------------------------------------------===//
276 EmitAssemblyForModule(Module* module, TargetMachine* target)
278 // Figure out where we are going to send the output...
280 if (OutputFilename != "") { // Specified an output filename?
281 Out = new ofstream(OutputFilename.c_str(),
282 (Force ? 0 : ios::noreplace)|ios::out);
284 if (InputFilename == "-") {
285 OutputFilename = "-";
288 string OutputFilename = GetFileNameRoot(InputFilename);
289 OutputFilename += ".s";
290 Out = new ofstream(OutputFilename.c_str(),
291 (Force ? 0 : ios::noreplace)|ios::out);
293 cerr << "Error opening " << OutputFilename << "!\n";
300 // Emit the output...
301 target->emitAssembly(module, *Out);
303 if (Out != &cout) delete Out;
309 //===---------------------------------------------------------------------===//
312 // Entry point for the llc compiler.
313 //===---------------------------------------------------------------------===//
316 main(int argc, char **argv)
318 // Parse command line options...
319 cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
321 // Allocate a target... in the future this will be controllable on the
323 auto_ptr<TargetMachine> target(allocateSparcTargetMachine());
325 // Load the module to be compiled...
326 auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
328 cerr << "bytecode didn't read correctly.\n";
332 if (PreprocessModule(M.get())) return 1;
334 if (OptimizeModule(M.get())) return 1;
336 if (GenerateCodeForModule(M.get(), target.get())) return 1;
338 if (!DoNotEmitAssembly)
339 if (EmitAssemblyForModule(M.get(), target.get())) return 1;