1 //===-- Writer.cpp - Library for Printing VM assembly files ------*- C++ -*--=//
3 // This library implements the functionality defined in llvm/Assembly/Writer.h
5 // This library uses the Analysis library to figure out offsets for
6 // variables in the method tables...
8 // TODO: print out the type name instead of the full type if a particular type
9 // is in the symbol table...
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Assembly/Writer.h"
14 #include "llvm/Analysis/SlotCalculator.h"
15 #include "llvm/Module.h"
16 #include "llvm/Method.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/BasicBlock.h"
19 #include "llvm/ConstPoolVals.h"
20 #include "llvm/iOther.h"
21 #include "llvm/iMemory.h"
22 #include "llvm/Support/STLExtras.h"
23 #include "llvm/SymbolTable.h"
26 // WriteAsOperand - Write the name of the specified value out to the specified
27 // ostream. This can be useful when you just want to print int %reg126, not the
28 // whole instruction that generated it.
30 ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
31 bool PrintName, SlotCalculator *Table) {
33 Out << " " << V->getType();
35 if (PrintName && V->hasName()) {
36 Out << " %" << V->getName();
38 if (const ConstPoolVal *CPV = dyn_cast<const ConstPoolVal>(V)) {
39 Out << " " << CPV->getStrValue();
43 Slot = Table->getValSlot(V);
45 if (const Type *Ty = dyn_cast<const Type>(V)) {
46 return Out << " " << Ty;
47 } else if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V)){
48 Table = new SlotCalculator(MA->getParent(), true);
49 } else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
50 Table = new SlotCalculator(I->getParent()->getParent(), true);
51 } else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
52 Table = new SlotCalculator(BB->getParent(), true);
53 } else if (const Method *Meth = dyn_cast<const Method>(V)) {
54 Table = new SlotCalculator(Meth, true);
55 } else if (const Module *Mod = dyn_cast<const Module>(V)) {
56 Table = new SlotCalculator(Mod, true);
58 return Out << "BAD VALUE TYPE!";
60 Slot = Table->getValSlot(V);
63 if (Slot >= 0) Out << " %" << Slot;
65 Out << "<badref>"; // Not embeded into a location?
73 class AssemblyWriter {
75 SlotCalculator &Table;
77 inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) {
80 inline void write(const Module *M) { processModule(M); }
81 inline void write(const GlobalVariable *G) { processGlobal(G); }
82 inline void write(const Method *M) { processMethod(M); }
83 inline void write(const BasicBlock *BB) { processBasicBlock(BB); }
84 inline void write(const Instruction *I) { processInstruction(I); }
85 inline void write(const ConstPoolVal *CPV) { processConstant(CPV); }
88 void processModule(const Module *M);
89 void processSymbolTable(const SymbolTable &ST);
90 void processConstant(const ConstPoolVal *CPV);
91 void processGlobal(const GlobalVariable *GV);
92 void processMethod(const Method *M);
93 void processMethodArgument(const MethodArgument *MA);
94 void processBasicBlock(const BasicBlock *BB);
95 void processInstruction(const Instruction *I);
97 void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
101 void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
103 WriteAsOperand(Out, Operand, PrintType, PrintName, &Table);
107 void AssemblyWriter::processModule(const Module *M) {
108 // Loop over the symbol table, emitting all named constants...
109 if (M->hasSymbolTable())
110 processSymbolTable(*M->getSymbolTable());
112 for_each(M->gbegin(), M->gend(),
113 bind_obj(this, &AssemblyWriter::processGlobal));
115 Out << "implementation\n";
117 // Output all of the methods...
118 for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::processMethod));
121 void AssemblyWriter::processGlobal(const GlobalVariable *GV) {
122 if (GV->hasName()) Out << "%" << GV->getName() << " = ";
124 if (!GV->hasInitializer()) Out << "uninitialized ";
126 Out << (GV->isConstant() ? "constant " : "global ")
127 << GV->getType()->getValueType()->getDescription();
129 if (GV->hasInitializer())
130 writeOperand(GV->getInitializer(), false, false);
136 // processSymbolTable - Run through symbol table looking for named constants
137 // if a named constant is found, emit it's declaration...
139 void AssemblyWriter::processSymbolTable(const SymbolTable &ST) {
140 for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
141 SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
142 SymbolTable::type_const_iterator End = ST.type_end(TI->first);
144 for (; I != End; ++I) {
145 const Value *V = I->second;
146 if (const ConstPoolVal *CPV = cast<const ConstPoolVal>(V)) {
147 processConstant(CPV);
148 } else if (const Type *Ty = cast<const Type>(V)) {
149 Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl;
156 // processConstant - Print out a constant pool entry...
158 void AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
159 // Don't print out unnamed constants, they will be inlined
160 if (!CPV->hasName()) return;
163 Out << "\t%" << CPV->getName() << " = ";
165 // Print out the constant type...
166 Out << CPV->getType();
168 // Write the value out now...
169 writeOperand(CPV, false, false);
171 if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
172 int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
173 Out << "\t\t; <" << CPV->getType() << ">:";
174 if (Slot >= 0) Out << Slot;
175 else Out << "<badref>";
181 // processMethod - Process all aspects of a method.
183 void AssemblyWriter::processMethod(const Method *M) {
184 // Print out the return type and name...
185 Out << "\n" << (M->isExternal() ? "declare " : "")
186 << M->getReturnType() << " \"" << M->getName() << "\"(";
187 Table.incorporateMethod(M);
189 // Loop over the arguments, processing them...
190 for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
191 bind_obj(this, &AssemblyWriter::processMethodArgument));
194 // Finish printing arguments...
195 const MethodType *MT = (const MethodType*)M->getType();
196 if (MT->isVarArg()) {
197 if (MT->getParamTypes().size()) Out << ", ";
198 Out << "..."; // Output varargs portion of signature!
202 if (!M->isExternal()) {
203 // Loop over the symbol table, emitting all named constants...
204 if (M->hasSymbolTable())
205 processSymbolTable(*M->getSymbolTable());
209 // Output all of its basic blocks... for the method
210 for_each(M->begin(), M->end(),
211 bind_obj(this, &AssemblyWriter::processBasicBlock));
219 // processMethodArgument - This member is called for every argument that
220 // is passed into the method. Simply print it out
222 void AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
223 // Insert commas as we go... the first arg doesn't get a comma
224 if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
227 Out << Arg->getType();
229 // Output name, if available...
231 Out << " %" << Arg->getName();
232 else if (Table.getValSlot(Arg) < 0)
236 // processBasicBlock - This member is called for each basic block in a methd.
238 void AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
239 if (BB->hasName()) { // Print out the label if it exists...
240 Out << "\n" << BB->getName() << ":";
242 int Slot = Table.getValSlot(BB);
243 Out << "\n; <label>:";
245 Out << Slot; // Extra newline seperates out label's
249 Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n"; // Output # uses
251 // Output all of the instructions in the basic block...
252 for_each(BB->begin(), BB->end(),
253 bind_obj(this, &AssemblyWriter::processInstruction));
256 // processInstruction - This member is called for each Instruction in a methd.
258 void AssemblyWriter::processInstruction(const Instruction *I) {
261 // Print out name if it exists...
262 if (I && I->hasName())
263 Out << "%" << I->getName() << " = ";
265 // Print out the opcode...
266 Out << I->getOpcodeName();
268 // Print out the type of the operands...
269 const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
271 // Special case conditional branches to swizzle the condition out to the front
272 if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
273 writeOperand(I->getOperand(2), true);
275 writeOperand(Operand, true);
277 writeOperand(I->getOperand(1), true);
279 } else if (I->getOpcode() == Instruction::Switch) {
280 // Special case switch statement to get formatting nice and correct...
281 writeOperand(Operand , true); Out << ",";
282 writeOperand(I->getOperand(1), true); Out << " [";
284 for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
286 writeOperand(I->getOperand(op ), true); Out << ",";
287 writeOperand(I->getOperand(op+1), true);
290 } else if (I->isPHINode()) {
291 Out << " " << Operand->getType();
293 Out << " ["; writeOperand(Operand, false); Out << ",";
294 writeOperand(I->getOperand(1), false); Out << " ]";
295 for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
297 writeOperand(I->getOperand(op ), false); Out << ",";
298 writeOperand(I->getOperand(op+1), false); Out << " ]";
300 } else if (I->getOpcode() == Instruction::Ret && !Operand) {
302 } else if (I->getOpcode() == Instruction::Call) {
303 writeOperand(Operand, true);
305 if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
306 for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
308 writeOperand(I->getOperand(op), true);
312 } else if (I->getOpcode() == Instruction::Malloc ||
313 I->getOpcode() == Instruction::Alloca) {
314 Out << " " << ((const PointerType*)I->getType())->getValueType();
315 if (I->getNumOperands()) {
317 writeOperand(I->getOperand(0), true);
319 } else if (I->getOpcode() == Instruction::Cast) {
320 writeOperand(Operand, true);
321 Out << " to " << I->getType();
322 } else if (Operand) { // Print the normal way...
324 // PrintAllTypes - Instructions who have operands of all the same type
325 // omit the type from all but the first operand. If the instruction has
326 // different type operands (for example br), then they are all printed.
327 bool PrintAllTypes = false;
328 const Type *TheType = Operand->getType();
330 for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
331 Operand = I->getOperand(i);
332 if (Operand->getType() != TheType) {
333 PrintAllTypes = true; // We have differing types! Print them all!
339 Out << " " << I->getOperand(0)->getType();
341 for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
343 writeOperand(I->getOperand(i), PrintAllTypes);
347 // Print a little comment after the instruction indicating which slot it
350 if (I->getType() != Type::VoidTy) {
351 Out << "\t\t; <" << I->getType() << ">";
354 int Slot = Table.getValSlot(I); // Print out the def slot taken...
355 if (Slot >= 0) Out << ":" << Slot;
356 else Out << ":<badref>";
358 Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses
364 //===----------------------------------------------------------------------===//
365 // External Interface declarations
366 //===----------------------------------------------------------------------===//
370 void WriteToAssembly(const Module *M, ostream &o) {
371 if (M == 0) { o << "<null> module\n"; return; }
372 SlotCalculator SlotTable(M, true);
373 AssemblyWriter W(o, SlotTable);
378 void WriteToAssembly(const GlobalVariable *G, ostream &o) {
379 if (G == 0) { o << "<null> global variable\n"; return; }
380 SlotCalculator SlotTable(G->getParent(), true);
381 AssemblyWriter W(o, SlotTable);
385 void WriteToAssembly(const Method *M, ostream &o) {
386 if (M == 0) { o << "<null> method\n"; return; }
387 SlotCalculator SlotTable(M->getParent(), true);
388 AssemblyWriter W(o, SlotTable);
394 void WriteToAssembly(const BasicBlock *BB, ostream &o) {
395 if (BB == 0) { o << "<null> basic block\n"; return; }
397 SlotCalculator SlotTable(BB->getParent(), true);
398 AssemblyWriter W(o, SlotTable);
403 void WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
404 if (CPV == 0) { o << "<null> constant pool value\n"; return; }
405 WriteAsOperand(o, CPV, true, true, 0);
408 void WriteToAssembly(const Instruction *I, ostream &o) {
409 if (I == 0) { o << "<null> instruction\n"; return; }
411 SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0,
413 AssemblyWriter W(o, SlotTable);