d84cba0752bb525778e3a907726e93ff6930f8ea
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
1 //===-- Writer.cpp - Library for Printing VM assembly files ------*- C++ -*--=//
2 //
3 // This library implements the functionality defined in llvm/Assembly/Writer.h
4 //
5 // This library uses the Analysis library to figure out offsets for
6 // variables in the method tables...
7 //
8 // TODO: print out the type name instead of the full type if a particular type
9 //       is in the symbol table...
10 //
11 //===----------------------------------------------------------------------===//
12
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/BasicBlock.h"
18 #include "llvm/ConstPoolVals.h"
19 #include "llvm/iOther.h"
20 #include "llvm/iMemory.h"
21
22 class AssemblyWriter : public ModuleAnalyzer {
23   ostream &Out;
24   SlotCalculator &Table;
25 public:
26   inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) {
27   }
28
29   inline void write(const Module *M)         { processModule(M);      }
30   inline void write(const Method *M)         { processMethod(M);      }
31   inline void write(const BasicBlock *BB)    { processBasicBlock(BB); }
32   inline void write(const Instruction *I)    { processInstruction(I); }
33   inline void write(const ConstPoolVal *CPV) { processConstant(CPV);  }
34
35 protected:
36   virtual bool visitMethod(const Method *M);
37   virtual bool processConstPool(const ConstantPool &CP, bool isMethod);
38   virtual bool processConstant(const ConstPoolVal *CPV);
39   virtual bool processMethod(const Method *M);
40   virtual bool processMethodArgument(const MethodArgument *MA);
41   virtual bool processBasicBlock(const BasicBlock *BB);
42   virtual bool processInstruction(const Instruction *I);
43
44 private :
45   void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
46 };
47
48
49
50 // visitMethod - This member is called after the above two steps, visting each
51 // method, because they are effectively values that go into the constant pool.
52 //
53 bool AssemblyWriter::visitMethod(const Method *M) {
54   return false;
55 }
56
57 bool AssemblyWriter::processConstPool(const ConstantPool &CP, bool isMethod) {
58   // Done printing arguments...
59   if (isMethod) Out << ")\n";
60
61   ModuleAnalyzer::processConstPool(CP, isMethod);
62   
63   if (isMethod)
64     Out << "begin";
65   else
66     Out << "implementation\n";
67   return false;
68 }
69
70
71 // processConstant - Print out a constant pool entry...
72 //
73 bool AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
74   Out << "\t";
75
76   // Print out name if it exists...
77   if (CPV->hasName())
78     Out << "%" << CPV->getName() << " = ";
79
80   // Print out the opcode...
81   Out << CPV->getType();
82
83   // Write the value out now...
84   writeOperand(CPV, false, false);
85
86   if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
87     int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
88     Out << "\t\t; <" << CPV->getType() << ">:";
89     if (Slot >= 0) Out << Slot;
90     else Out << "<badref>";
91   } 
92
93   Out << endl;
94   return false;
95 }
96
97 // processMethod - Process all aspects of a method.
98 //
99 bool AssemblyWriter::processMethod(const Method *M) {
100   // Print out the return type and name...
101   Out << "\n" << M->getReturnType() << " \"" << M->getName() << "\"(";
102   Table.incorporateMethod(M);
103   ModuleAnalyzer::processMethod(M);
104   Table.purgeMethod();
105   Out << "end\n";
106   return false;
107 }
108
109 // processMethodArgument - This member is called for every argument that 
110 // is passed into the method.  Simply print it out
111 //
112 bool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
113   // Insert commas as we go... the first arg doesn't get a comma
114   if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
115
116   // Output type...
117   Out << Arg->getType();
118   
119   // Output name, if available...
120   if (Arg->hasName())
121     Out << " %" << Arg->getName();
122   else if (Table.getValSlot(Arg) < 0)
123     Out << "<badref>";
124   
125   return false;
126 }
127
128 // processBasicBlock - This member is called for each basic block in a methd.
129 //
130 bool AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
131   if (BB->hasName()) {              // Print out the label if it exists...
132     Out << "\n" << BB->getName() << ":";
133   } else {
134     int Slot = Table.getValSlot(BB);
135     Out << "\n; <label>:";
136     if (Slot >= 0) 
137       Out << Slot;         // Extra newline seperates out label's
138     else 
139       Out << "<badref>"; 
140   }
141   Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n";  // Output # uses
142
143   ModuleAnalyzer::processBasicBlock(BB);
144   return false;
145 }
146
147 // processInstruction - This member is called for each Instruction in a methd.
148 //
149 bool AssemblyWriter::processInstruction(const Instruction *I) {
150   Out << "\t";
151
152   // Print out name if it exists...
153   if (I && I->hasName())
154     Out << "%" << I->getName() << " = ";
155
156   // Print out the opcode...
157   Out << I->getOpcodeName();
158
159   // Print out the type of the operands...
160   const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
161
162   // Special case conditional branches to swizzle the condition out to the front
163   if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
164     writeOperand(I->getOperand(2), true);
165     Out << ",";
166     writeOperand(Operand, true);
167     Out << ",";
168     writeOperand(I->getOperand(1), true);
169
170   } else if (I->getOpcode() == Instruction::Switch) {
171     // Special case switch statement to get formatting nice and correct...
172     writeOperand(Operand         , true); Out << ",";
173     writeOperand(I->getOperand(1), true); Out << " [";
174
175     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
176       Out << "\n\t\t";
177       writeOperand(I->getOperand(op  ), true); Out << ",";
178       writeOperand(I->getOperand(op+1), true);
179     }
180     Out << "\n\t]";
181   } else if (I->isPHINode()) {
182     Out << " " << Operand->getType();
183
184     Out << " [";  writeOperand(Operand, false); Out << ",";
185     writeOperand(I->getOperand(1), false); Out << " ]";
186     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
187       Out << ", [";  
188       writeOperand(I->getOperand(op  ), false); Out << ",";
189       writeOperand(I->getOperand(op+1), false); Out << " ]";
190     }
191   } else if (I->getOpcode() == Instruction::Ret && !Operand) {
192     Out << " void";
193   } else if (I->getOpcode() == Instruction::Call) {
194     writeOperand(Operand, true);
195     Out << "(";
196     if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
197     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
198       Out << ",";
199       writeOperand(I->getOperand(op), true);
200     }
201
202     Out << " )";
203   } else if (I->getOpcode() == Instruction::Malloc || 
204              I->getOpcode() == Instruction::Alloca) {
205     Out << " " << ((const PointerType*)I->getType())->getValueType();
206     if (I->getNumOperands()) {
207       Out << ",";
208       writeOperand(I->getOperand(0), true);
209     }
210   } else if (I->getOpcode() == Instruction::Cast) {
211     writeOperand(Operand, true);
212     Out << " to " << I->getType();
213   } else if (Operand) {   // Print the normal way...
214
215     // PrintAllTypes - Instructions who have operands of all the same type 
216     // omit the type from all but the first operand.  If the instruction has
217     // different type operands (for example br), then they are all printed.
218     bool PrintAllTypes = false;
219     const Type *TheType = Operand->getType();
220
221     for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
222       Operand = I->getOperand(i);
223       if (Operand->getType() != TheType) {
224         PrintAllTypes = true;       // We have differing types!  Print them all!
225         break;
226       }
227     }
228
229     if (!PrintAllTypes)
230       Out << " " << I->getOperand(0)->getType();
231
232     for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
233       if (i) Out << ",";
234       writeOperand(I->getOperand(i), PrintAllTypes);
235     }
236   }
237
238   // Print a little comment after the instruction indicating which slot it
239   // occupies.
240   //
241   if (I->getType() != Type::VoidTy) {
242     Out << "\t\t; <" << I->getType() << ">";
243
244     if (!I->hasName()) {
245       int Slot = Table.getValSlot(I); // Print out the def slot taken...
246       if (Slot >= 0) Out << ":" << Slot;
247       else Out << ":<badref>";
248     }
249     Out << "\t[#uses=" << I->use_size() << "]";  // Output # uses
250   }
251   Out << endl;
252
253   return false;
254 }
255
256
257 void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, 
258                                   bool PrintName) {
259   if (PrintType)
260     Out << " " << Operand->getType();
261   
262   if (Operand->hasName() && PrintName) {
263     Out << " %" << Operand->getName();
264   } else {
265     int Slot = Table.getValSlot(Operand);
266     
267     if (const ConstPoolVal *CPV = Operand->castConstant()) {
268       Out << " " << CPV->getStrValue();
269     } else {
270       if (Slot >= 0)  Out << " %" << Slot;
271       else if (PrintName)
272         Out << "<badref>";     // Not embeded into a location?
273     }
274   }
275 }
276
277
278 //===----------------------------------------------------------------------===//
279 //                       External Interface declarations
280 //===----------------------------------------------------------------------===//
281
282
283
284 void WriteToAssembly(const Module *M, ostream &o) {
285   if (M == 0) { o << "<null> module\n"; return; }
286   SlotCalculator SlotTable(M, true);
287   AssemblyWriter W(o, SlotTable);
288
289   W.write(M);
290 }
291
292 void WriteToAssembly(const Method *M, ostream &o) {
293   if (M == 0) { o << "<null> method\n"; return; }
294   SlotCalculator SlotTable(M->getParent(), true);
295   AssemblyWriter W(o, SlotTable);
296
297   W.write(M);
298 }
299
300
301 void WriteToAssembly(const BasicBlock *BB, ostream &o) {
302   if (BB == 0) { o << "<null> basic block\n"; return; }
303
304   SlotCalculator SlotTable(BB->getParent(), true);
305   AssemblyWriter W(o, SlotTable);
306
307   W.write(BB);
308 }
309
310 void WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
311   if (CPV == 0) { o << "<null> constant pool value\n"; return; }
312
313   SlotCalculator *SlotTable;
314
315   // A Constant pool value may have a parent that is either a method or a 
316   // module.  Untangle this now...
317   //
318   if (CPV->getParent() == 0 || CPV->getParent()->isMethod()) {
319     SlotTable = new SlotCalculator((Method*)CPV->getParent(), true);
320   } else {
321     SlotTable =
322       new SlotCalculator(CPV->getParent()->castModuleAsserting(), true);
323   }
324
325   AssemblyWriter W(o, *SlotTable);
326   W.write(CPV);
327
328   delete SlotTable;
329 }
330
331 void WriteToAssembly(const Instruction *I, ostream &o) {
332   if (I == 0) { o << "<null> instruction\n"; return; }
333
334   SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0, 
335                            true);
336   AssemblyWriter W(o, SlotTable);
337
338   W.write(I);
339 }