a53e484deda581314a91101e46da75bcc199d483
[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/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/iTerminators.h"
23 #include "llvm/SymbolTable.h"
24 #include "llvm/Support/STLExtras.h"
25 #include "llvm/Support/StringExtras.h"
26 #include <algorithm>
27 #include <map>
28
29 static const Module *getModuleFromVal(const Value *V) {
30   if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V))
31     return MA->getParent() ? MA->getParent()->getParent() : 0;
32   else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V))
33     return BB->getParent() ? BB->getParent()->getParent() : 0;
34   else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
35     const Method *M = I->getParent() ? I->getParent()->getParent() : 0;
36     return M ? M->getParent() : 0;
37   } else if (const GlobalValue *GV =dyn_cast<const GlobalValue>(V))
38     return GV->getParent();
39   else if (const Module *Mod  = dyn_cast<const Module>(V))
40     return Mod;
41   return 0;
42 }
43
44 static SlotCalculator *createSlotCalculator(const Value *V) {
45   assert(!isa<Type>(V) && "Can't create an SC for a type!");
46   if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V)){
47     return new SlotCalculator(MA->getParent(), true);
48   } else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
49     return new SlotCalculator(I->getParent()->getParent(), true);
50   } else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
51     return new SlotCalculator(BB->getParent(), true);
52   } else if (const GlobalVariable *GV =dyn_cast<const GlobalVariable>(V)){
53     return new SlotCalculator(GV->getParent(), true);
54   } else if (const Method *Meth = dyn_cast<const Method>(V)) {
55     return new SlotCalculator(Meth, true);
56   } else if (const Module *Mod  = dyn_cast<const Module>(V)) {
57     return new SlotCalculator(Mod, true);
58   }
59   return 0;
60 }
61
62 // WriteAsOperand - Write the name of the specified value out to the specified
63 // ostream.  This can be useful when you just want to print int %reg126, not the
64 // whole instruction that generated it.
65 //
66 static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName,
67                                    SlotCalculator *Table) {
68   if (PrintName && V->hasName()) {
69     Out << " %" << V->getName();
70   } else {
71     if (const ConstPoolVal *CPV = dyn_cast<const ConstPoolVal>(V)) {
72       Out << " " << CPV->getStrValue();
73     } else {
74       int Slot;
75       if (Table) {
76         Slot = Table->getValSlot(V);
77       } else {
78         if (const Type *Ty = dyn_cast<const Type>(V)) {
79           Out << " " << Ty->getDescription();
80           return;
81         }
82
83         Table = createSlotCalculator(V);
84         if (Table == 0) { Out << "BAD VALUE TYPE!"; return; }
85
86         Slot = Table->getValSlot(V);
87         delete Table;
88       }
89       if (Slot >= 0)  Out << " %" << Slot;
90       else if (PrintName)
91         Out << "<badref>";     // Not embeded into a location?
92     }
93   }
94 }
95
96
97 // If the module has a symbol table, take all global types and stuff their
98 // names into the TypeNames map.
99 //
100 static void fillTypeNameTable(const Module *M,
101                               map<const Type *, string> &TypeNames) {
102   if (M && M->hasSymbolTable()) {
103     const SymbolTable *ST = M->getSymbolTable();
104     SymbolTable::const_iterator PI = ST->find(Type::TypeTy);
105     if (PI != ST->end()) {
106       SymbolTable::type_const_iterator I = PI->second.begin();
107       for (; I != PI->second.end(); ++I) {
108         // As a heuristic, don't insert pointer to primitive types, because
109         // they are used too often to have a single useful name.
110         //
111         const Type *Ty = cast<const Type>(I->second);
112         if (!isa<PointerType>(Ty) ||
113             !cast<PointerType>(Ty)->getValueType()->isPrimitiveType())
114           TypeNames.insert(make_pair(Ty, "%"+I->first));
115       }
116     }
117   }
118 }
119
120
121
122 static string calcTypeName(const Type *Ty, vector<const Type *> &TypeStack,
123                            map<const Type *, string> &TypeNames) {
124   if (Ty->isPrimitiveType()) return Ty->getDescription();  // Base case
125
126   // Check to see if the type is named.
127   map<const Type *, string>::iterator I = TypeNames.find(Ty);
128   if (I != TypeNames.end()) return I->second;
129
130   // Check to see if the Type is already on the stack...
131   unsigned Slot = 0, CurSize = TypeStack.size();
132   while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
133
134   // This is another base case for the recursion.  In this case, we know 
135   // that we have looped back to a type that we have previously visited.
136   // Generate the appropriate upreference to handle this.
137   // 
138   if (Slot < CurSize)
139     return "\\" + utostr(CurSize-Slot);       // Here's the upreference
140
141   TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
142   
143   string Result;
144   switch (Ty->getPrimitiveID()) {
145   case Type::MethodTyID: {
146     const MethodType *MTy = cast<const MethodType>(Ty);
147     Result = calcTypeName(MTy->getReturnType(), TypeStack, TypeNames) + " (";
148     for (MethodType::ParamTypes::const_iterator
149            I = MTy->getParamTypes().begin(),
150            E = MTy->getParamTypes().end(); I != E; ++I) {
151       if (I != MTy->getParamTypes().begin())
152         Result += ", ";
153       Result += calcTypeName(*I, TypeStack, TypeNames);
154     }
155     if (MTy->isVarArg()) {
156       if (!MTy->getParamTypes().empty()) Result += ", ";
157       Result += "...";
158     }
159     Result += ")";
160     break;
161   }
162   case Type::StructTyID: {
163     const StructType *STy = cast<const StructType>(Ty);
164     Result = "{ ";
165     for (StructType::ElementTypes::const_iterator
166            I = STy->getElementTypes().begin(),
167            E = STy->getElementTypes().end(); I != E; ++I) {
168       if (I != STy->getElementTypes().begin())
169         Result += ", ";
170       Result += calcTypeName(*I, TypeStack, TypeNames);
171     }
172     Result += " }";
173     break;
174   }
175   case Type::PointerTyID:
176     Result = calcTypeName(cast<const PointerType>(Ty)->getValueType(), 
177                           TypeStack, TypeNames) + " *";
178     break;
179   case Type::ArrayTyID: {
180     const ArrayType *ATy = cast<const ArrayType>(Ty);
181     int NumElements = ATy->getNumElements();
182     Result = "[";
183     if (NumElements != -1) Result += itostr(NumElements) + " x ";
184     Result += calcTypeName(ATy->getElementType(), TypeStack, TypeNames) + "]";
185     break;
186   }
187   default:
188     assert(0 && "Unhandled case in getTypeProps!");
189     Result = "<error>";
190   }
191
192   TypeStack.pop_back();       // Remove self from stack...
193   return Result;
194 }
195
196
197 // printTypeInt - The internal guts of printing out a type that has a
198 // potentially named portion.
199 //
200 static ostream &printTypeInt(ostream &Out, const Type *Ty,
201                              map<const Type *, string> &TypeNames) {
202   // Primitive types always print out their description, regardless of whether
203   // they have been named or not.
204   //
205   if (Ty->isPrimitiveType()) return Out << Ty->getDescription();
206
207   // Check to see if the type is named.
208   map<const Type *, string>::iterator I = TypeNames.find(Ty);
209   if (I != TypeNames.end()) return Out << I->second;
210
211   // Otherwise we have a type that has not been named but is a derived type.
212   // Carefully recurse the type hierarchy to print out any contained symbolic
213   // names.
214   //
215   vector<const Type *> TypeStack;
216   string TypeName = calcTypeName(Ty, TypeStack, TypeNames);
217   TypeNames.insert(make_pair(Ty, TypeName));   // Cache type name for later use
218   return Out << TypeName;
219 }
220
221 // WriteTypeSymbolic - This attempts to write the specified type as a symbolic
222 // type, iff there is an entry in the modules symbol table for the specified
223 // type or one of it's component types.  This is slower than a simple x << Type;
224 //
225 ostream &WriteTypeSymbolic(ostream &Out, const Type *Ty, const Module *M) {
226   Out << " "; 
227
228   // If they want us to print out a type, attempt to make it symbolic if there
229   // is a symbol table in the module...
230   if (M && M->hasSymbolTable()) {
231     map<const Type *, string> TypeNames;
232     fillTypeNameTable(M, TypeNames);
233     
234     return printTypeInt(Out, Ty, TypeNames);
235   } else {
236     return Out << Ty->getDescription();
237   }
238 }
239
240
241 // WriteAsOperand - Write the name of the specified value out to the specified
242 // ostream.  This can be useful when you just want to print int %reg126, not the
243 // whole instruction that generated it.
244 //
245 ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType, 
246                         bool PrintName, SlotCalculator *Table) {
247   if (PrintType)
248     WriteTypeSymbolic(Out, V->getType(), getModuleFromVal(V));
249
250   WriteAsOperandInternal(Out, V, PrintName, Table);
251   return Out;
252 }
253
254
255
256 class AssemblyWriter {
257   ostream &Out;
258   SlotCalculator &Table;
259   const Module *TheModule;
260   map<const Type *, string> TypeNames;
261 public:
262   inline AssemblyWriter(ostream &o, SlotCalculator &Tab, const Module *M)
263     : Out(o), Table(Tab), TheModule(M) {
264
265     // If the module has a symbol table, take all global types and stuff their
266     // names into the TypeNames map.
267     //
268     fillTypeNameTable(M, TypeNames);
269   }
270
271   inline void write(const Module *M)         { printModule(M);      }
272   inline void write(const GlobalVariable *G) { printGlobal(G);      }
273   inline void write(const Method *M)         { printMethod(M);      }
274   inline void write(const BasicBlock *BB)    { printBasicBlock(BB); }
275   inline void write(const Instruction *I)    { printInstruction(I); }
276   inline void write(const ConstPoolVal *CPV) { printConstant(CPV);  }
277
278 private :
279   void printModule(const Module *M);
280   void printSymbolTable(const SymbolTable &ST);
281   void printConstant(const ConstPoolVal *CPV);
282   void printGlobal(const GlobalVariable *GV);
283   void printMethod(const Method *M);
284   void printMethodArgument(const MethodArgument *MA);
285   void printBasicBlock(const BasicBlock *BB);
286   void printInstruction(const Instruction *I);
287   ostream &printType(const Type *Ty);
288
289   void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
290
291   // printInfoComment - Print a little comment after the instruction indicating
292   // which slot it occupies.
293   void printInfoComment(const Value *V);
294 };
295
296
297 void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, 
298                                   bool PrintName) {
299   if (PrintType) { Out << " "; printType(Operand->getType()); }
300   WriteAsOperandInternal(Out, Operand, PrintName, &Table);
301 }
302
303
304 void AssemblyWriter::printModule(const Module *M) {
305   // Loop over the symbol table, emitting all named constants...
306   if (M->hasSymbolTable())
307     printSymbolTable(*M->getSymbolTable());
308   
309   for_each(M->gbegin(), M->gend(), 
310            bind_obj(this, &AssemblyWriter::printGlobal));
311
312   Out << "implementation\n";
313   
314   // Output all of the methods...
315   for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printMethod));
316 }
317
318 void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
319   if (GV->hasName()) Out << "%" << GV->getName() << " = ";
320
321   if (!GV->hasInitializer()) Out << "uninitialized ";
322
323   Out << (GV->isConstant() ? "constant " : "global ");
324   printType(GV->getType()->getValueType());
325
326   if (GV->hasInitializer())
327     writeOperand(GV->getInitializer(), false, false);
328
329   printInfoComment(GV);
330   Out << endl;
331 }
332
333
334 // printSymbolTable - Run through symbol table looking for named constants
335 // if a named constant is found, emit it's declaration...
336 //
337 void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
338   for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
339     SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
340     SymbolTable::type_const_iterator End = ST.type_end(TI->first);
341     
342     for (; I != End; ++I) {
343       const Value *V = I->second;
344       if (const ConstPoolVal *CPV = dyn_cast<const ConstPoolVal>(V)) {
345         printConstant(CPV);
346       } else if (const Type *Ty = dyn_cast<const Type>(V)) {
347         Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl;
348       }
349     }
350   }
351 }
352
353
354 // printConstant - Print out a constant pool entry...
355 //
356 void AssemblyWriter::printConstant(const ConstPoolVal *CPV) {
357   // Don't print out unnamed constants, they will be inlined
358   if (!CPV->hasName()) return;
359
360   // Print out name...
361   Out << "\t%" << CPV->getName() << " = ";
362
363   // Print out the constant type...
364   printType(CPV->getType());
365
366   // Write the value out now...
367   writeOperand(CPV, false, false);
368
369   if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
370     int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
371     Out << "\t\t; <";
372     printType(CPV->getType()) << ">:";
373     if (Slot >= 0) Out << Slot;
374     else Out << "<badref>";
375   } 
376
377   Out << endl;
378 }
379
380 // printMethod - Print all aspects of a method.
381 //
382 void AssemblyWriter::printMethod(const Method *M) {
383   // Print out the return type and name...
384   Out << "\n" << (M->isExternal() ? "declare " : "");
385   printType(M->getReturnType()) << " \"" << M->getName() << "\"(";
386   Table.incorporateMethod(M);
387
388   // Loop over the arguments, printing them...
389   const MethodType *MT = cast<const MethodType>(M->getMethodType());
390
391   if (!M->isExternal()) {
392     for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
393              bind_obj(this, &AssemblyWriter::printMethodArgument));
394   } else {
395     // Loop over the arguments, printing them...
396     const MethodType *MT = cast<const MethodType>(M->getMethodType());
397     for (MethodType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
398            E = MT->getParamTypes().end(); I != E; ++I) {
399       if (I != MT->getParamTypes().begin()) Out << ", ";
400       printType(*I);
401     }
402   }
403
404   // Finish printing arguments...
405   if (MT->isVarArg()) {
406     if (MT->getParamTypes().size()) Out << ", ";
407     Out << "...";  // Output varargs portion of signature!
408   }
409   Out << ")\n";
410
411   if (!M->isExternal()) {
412     // Loop over the symbol table, emitting all named constants...
413     if (M->hasSymbolTable())
414       printSymbolTable(*M->getSymbolTable());
415
416     Out << "begin";
417   
418     // Output all of its basic blocks... for the method
419     for_each(M->begin(), M->end(),
420              bind_obj(this, &AssemblyWriter::printBasicBlock));
421
422     Out << "end\n";
423   }
424
425   Table.purgeMethod();
426 }
427
428 // printMethodArgument - This member is called for every argument that 
429 // is passed into the method.  Simply print it out
430 //
431 void AssemblyWriter::printMethodArgument(const MethodArgument *Arg) {
432   // Insert commas as we go... the first arg doesn't get a comma
433   if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
434
435   // Output type...
436   printType(Arg->getType());
437   
438   // Output name, if available...
439   if (Arg->hasName())
440     Out << " %" << Arg->getName();
441   else if (Table.getValSlot(Arg) < 0)
442     Out << "<badref>";
443 }
444
445 // printBasicBlock - This member is called for each basic block in a methd.
446 //
447 void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
448   if (BB->hasName()) {              // Print out the label if it exists...
449     Out << "\n" << BB->getName() << ":";
450   } else {
451     int Slot = Table.getValSlot(BB);
452     Out << "\n; <label>:";
453     if (Slot >= 0) 
454       Out << Slot;         // Extra newline seperates out label's
455     else 
456       Out << "<badref>"; 
457   }
458   Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n";  // Output # uses
459
460   // Output all of the instructions in the basic block...
461   for_each(BB->begin(), BB->end(),
462            bind_obj(this, &AssemblyWriter::printInstruction));
463 }
464
465
466 // printInfoComment - Print a little comment after the instruction indicating
467 // which slot it occupies.
468 //
469 void AssemblyWriter::printInfoComment(const Value *V) {
470   if (V->getType() != Type::VoidTy) {
471     Out << "\t\t; <";
472     printType(V->getType()) << ">";
473
474     if (!V->hasName()) {
475       int Slot = Table.getValSlot(V); // Print out the def slot taken...
476       if (Slot >= 0) Out << ":" << Slot;
477       else Out << ":<badref>";
478     }
479     Out << "\t[#uses=" << V->use_size() << "]";  // Output # uses
480   }
481 }
482
483 // printInstruction - This member is called for each Instruction in a methd.
484 //
485 void AssemblyWriter::printInstruction(const Instruction *I) {
486   Out << "\t";
487
488   // Print out name if it exists...
489   if (I && I->hasName())
490     Out << "%" << I->getName() << " = ";
491
492   // Print out the opcode...
493   Out << I->getOpcodeName();
494
495   // Print out the type of the operands...
496   const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
497
498   // Special case conditional branches to swizzle the condition out to the front
499   if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
500     writeOperand(I->getOperand(2), true);
501     Out << ",";
502     writeOperand(Operand, true);
503     Out << ",";
504     writeOperand(I->getOperand(1), true);
505
506   } else if (I->getOpcode() == Instruction::Switch) {
507     // Special case switch statement to get formatting nice and correct...
508     writeOperand(Operand         , true); Out << ",";
509     writeOperand(I->getOperand(1), true); Out << " [";
510
511     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
512       Out << "\n\t\t";
513       writeOperand(I->getOperand(op  ), true); Out << ",";
514       writeOperand(I->getOperand(op+1), true);
515     }
516     Out << "\n\t]";
517   } else if (isa<PHINode>(I)) {
518     Out << " ";
519     printType(Operand->getType());
520
521     Out << " [";  writeOperand(Operand, false); Out << ",";
522     writeOperand(I->getOperand(1), false); Out << " ]";
523     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
524       Out << ", [";  
525       writeOperand(I->getOperand(op  ), false); Out << ",";
526       writeOperand(I->getOperand(op+1), false); Out << " ]";
527     }
528   } else if (isa<ReturnInst>(I) && !Operand) {
529     Out << " void";
530   } else if (isa<CallInst>(I)) {
531     // TODO: Should try to print out short form of the Call instruction
532     writeOperand(Operand, true);
533     Out << "(";
534     if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
535     for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
536       Out << ",";
537       writeOperand(I->getOperand(op), true);
538     }
539
540     Out << " )";
541   } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
542     // TODO: Should try to print out short form of the Invoke instruction
543     writeOperand(Operand, true);
544     Out << "(";
545     if (I->getNumOperands() > 3) writeOperand(I->getOperand(3), true);
546     for (unsigned op = 4, Eop = I->getNumOperands(); op < Eop; ++op) {
547       Out << ",";
548       writeOperand(I->getOperand(op), true);
549     }
550
551     Out << " )\n\t\t\tto";
552     writeOperand(II->getNormalDest(), true);
553     Out << " except";
554     writeOperand(II->getExceptionalDest(), true);
555
556   } else if (I->getOpcode() == Instruction::Malloc || 
557              I->getOpcode() == Instruction::Alloca) {
558     Out << " ";
559     printType(cast<const PointerType>(I->getType())->getValueType());
560     if (I->getNumOperands()) {
561       Out << ",";
562       writeOperand(I->getOperand(0), true);
563     }
564   } else if (isa<CastInst>(I)) {
565     writeOperand(Operand, true);
566     Out << " to ";
567     printType(I->getType());
568   } else if (Operand) {   // Print the normal way...
569
570     // PrintAllTypes - Instructions who have operands of all the same type 
571     // omit the type from all but the first operand.  If the instruction has
572     // different type operands (for example br), then they are all printed.
573     bool PrintAllTypes = false;
574     const Type *TheType = Operand->getType();
575
576     for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
577       Operand = I->getOperand(i);
578       if (Operand->getType() != TheType) {
579         PrintAllTypes = true;       // We have differing types!  Print them all!
580         break;
581       }
582     }
583
584     // Shift Left & Right print both types even for Ubyte LHS
585     if (isa<ShiftInst>(I)) PrintAllTypes = true;
586
587     if (!PrintAllTypes) {
588       Out << " ";
589       printType(I->getOperand(0)->getType());
590     }
591
592     for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
593       if (i) Out << ",";
594       writeOperand(I->getOperand(i), PrintAllTypes);
595     }
596   }
597
598   printInfoComment(I);
599   Out << endl;
600 }
601
602
603 // printType - Go to extreme measures to attempt to print out a short, symbolic
604 // version of a type name.
605 //
606 ostream &AssemblyWriter::printType(const Type *Ty) {
607   return printTypeInt(Out, Ty, TypeNames);
608 }
609
610
611 //===----------------------------------------------------------------------===//
612 //                       External Interface declarations
613 //===----------------------------------------------------------------------===//
614
615
616
617 void WriteToAssembly(const Module *M, ostream &o) {
618   if (M == 0) { o << "<null> module\n"; return; }
619   SlotCalculator SlotTable(M, true);
620   AssemblyWriter W(o, SlotTable, M);
621
622   W.write(M);
623 }
624
625 void WriteToAssembly(const GlobalVariable *G, ostream &o) {
626   if (G == 0) { o << "<null> global variable\n"; return; }
627   SlotCalculator SlotTable(G->getParent(), true);
628   AssemblyWriter W(o, SlotTable, G->getParent());
629   W.write(G);
630 }
631
632 void WriteToAssembly(const Method *M, ostream &o) {
633   if (M == 0) { o << "<null> method\n"; return; }
634   SlotCalculator SlotTable(M->getParent(), true);
635   AssemblyWriter W(o, SlotTable, M->getParent());
636
637   W.write(M);
638 }
639
640
641 void WriteToAssembly(const BasicBlock *BB, ostream &o) {
642   if (BB == 0) { o << "<null> basic block\n"; return; }
643
644   SlotCalculator SlotTable(BB->getParent(), true);
645   AssemblyWriter W(o, SlotTable, 
646                    BB->getParent() ? BB->getParent()->getParent() : 0);
647
648   W.write(BB);
649 }
650
651 void WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
652   if (CPV == 0) { o << "<null> constant pool value\n"; return; }
653   o << " " << CPV->getType()->getDescription() << " " << CPV->getStrValue();
654 }
655
656 void WriteToAssembly(const Instruction *I, ostream &o) {
657   if (I == 0) { o << "<null> instruction\n"; return; }
658
659   const Method *M = I->getParent() ? I->getParent()->getParent() : 0;
660   SlotCalculator SlotTable(M, true);
661   AssemblyWriter W(o, SlotTable, M ? M->getParent() : 0);
662
663   W.write(I);
664 }