AsmWriter.cpp revision 007377f381e253cc559db8d3c94fa89b0eb55fad
1009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===-- Writer.cpp - Library for Printing VM assembly files ------*- C++ -*--=//
2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library implements the functionality defined in llvm/Assembly/Writer.h
4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library uses the Analysis library to figure out offsets for
6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// variables in the method tables...
7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
8009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// TODO: print out the type name instead of the full type if a particular type
9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//       is in the symbol table...
10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
12009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Assembly/Writer.h"
14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Analysis/SlotCalculator.h"
15009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h"
16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Method.h"
17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/BasicBlock.h"
18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/ConstPoolVals.h"
19009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/iOther.h"
20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/iMemory.h"
21007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include "llvm/Support/STLExtras.h"
22007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include "llvm/SymbolTable.h"
23007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include <algorithm>
24009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
25d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattnervoid DebugValue(const Value *V) {
26d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner  cerr << V << endl;
27d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner}
28d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner
29622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// WriteAsOperand - Write the name of the specified value out to the specified
30622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// ostream.  This can be useful when you just want to print int %reg126, not the
31622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// whole instruction that generated it.
32622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner//
33622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattnerostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
34622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner			bool PrintName, SlotCalculator *Table) {
35622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner  if (PrintType)
36622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner    Out << " " << V->getType();
37622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner
38007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (PrintName && V->hasName()) {
39622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner    Out << " %" << V->getName();
40622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner  } else {
41622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner    if (const ConstPoolVal *CPV = V->castConstant()) {
42622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      Out << " " << CPV->getStrValue();
43622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner    } else {
44622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      int Slot;
45622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      if (Table) {
46622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	Slot = Table->getValSlot(V);
47622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      } else {
48622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	if (const Type *Ty = V->castType()) {
49622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  return Out << " " << Ty;
50622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else if (const MethodArgument *MA = V->castMethodArgument()) {
51622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  Table = new SlotCalculator(MA->getParent(), true);
52622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else if (const Instruction *I = V->castInstruction()) {
53622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  Table = new SlotCalculator(I->getParent()->getParent(), true);
54622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else if (const BasicBlock *BB = V->castBasicBlock()) {
55622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  Table = new SlotCalculator(BB->getParent(), true);
56622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else if (const Method *Meth = V->castMethod()) {
57622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  Table = new SlotCalculator(Meth, true);
58622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else if (const Module *Mod  = V->castModule()) {
59622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  Table = new SlotCalculator(Mod, true);
60622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	} else {
61622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	  return Out << "BAD VALUE TYPE!";
62622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	}
63622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	Slot = Table->getValSlot(V);
64622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner	delete Table;
65622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      }
66622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      if (Slot >= 0)  Out << " %" << Slot;
67622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner      else if (PrintName)
68622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner        Out << "<badref>";     // Not embeded into a location?
69622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner    }
70622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner  }
71622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner  return Out;
72622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner}
73622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner
74622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner
75d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner
76007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnerclass AssemblyWriter {
77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ostream &Out;
78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator &Table;
79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic:
80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) {
81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Module *M)         { processModule(M);      }
84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Method *M)         { processMethod(M);      }
85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const BasicBlock *BB)    { processBasicBlock(BB); }
86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Instruction *I)    { processInstruction(I); }
87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const ConstPoolVal *CPV) { processConstant(CPV);  }
88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
89009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate :
90007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processModule(const Module *M);
91007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processSymbolTable(const SymbolTable &ST);
92007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processConstant(const ConstPoolVal *CPV);
93007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processMethod(const Method *M);
94007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processMethodArgument(const MethodArgument *MA);
95007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processBasicBlock(const BasicBlock *BB);
96007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  void processInstruction(const Instruction *I);
97007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
99009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner};
100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
102007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
103007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner				  bool PrintName) {
104007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  WriteAsOperand(Out, Operand, PrintType, PrintName, &Table);
105007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner}
106007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
107007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
108007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processModule(const Module *M) {
109007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Loop over the symbol table, emitting all named constants...
110007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (M->hasSymbolTable())
111007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    processSymbolTable(*M->getSymbolTable());
112009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
113007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  Out << "implementation\n";
114007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
115007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Output all of the methods...
116007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::processMethod));
117009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
118009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
119009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
120007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// processSymbolTable - Run through symbol table looking for named constants
121007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// if a named constant is found, emit it's declaration...
122007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner//
123007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processSymbolTable(const SymbolTable &ST) {
124007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
125007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
126007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    SymbolTable::type_const_iterator End = ST.type_end(TI->first);
127007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
128007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    for (; I != End; ++I) {
129007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      const Value *V = I->second;
130007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      if (const ConstPoolVal *CPV = V->castConstant()) {
131007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner	processConstant(CPV);
132007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      } else if (const Type *Ty = V->castType()) {
133007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner	Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl;
134007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      }
135007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    }
136739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner  }
137009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
138009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
139009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
140009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processConstant - Print out a constant pool entry...
141009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
142007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
143007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Don't print out unnamed constants, they will be inlined
144007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (!CPV->hasName()) return;
145009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
1461333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner  // Print out name...
1471333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner  Out << "\t%" << CPV->getName() << " = ";
148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
1491333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner  // Print out the constant type...
150009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << CPV->getType();
151009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
152009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Write the value out now...
153009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  writeOperand(CPV, false, false);
154009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
155009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
156009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
157009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\t\t; <" << CPV->getType() << ">:";
158009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0) Out << Slot;
159009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else Out << "<badref>";
160009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
161009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
162009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << endl;
163009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
164009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
165009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethod - Process all aspects of a method.
166009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
167007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processMethod(const Method *M) {
168009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the return type and name...
169739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner  Out << "\n" << (M->isExternal() ? "declare " : "")
170739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner      << M->getReturnType() << " \"" << M->getName() << "\"(";
171009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Table.incorporateMethod(M);
172007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
173007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Loop over the arguments, processing them...
174007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
175007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner	   bind_obj(this, &AssemblyWriter::processMethodArgument));
176007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
177007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
178007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Finish printing arguments...
179007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  const MethodType *MT = (const MethodType*)M->getType();
180007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (MT->isVarArg()) {
181007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    if (MT->getParamTypes().size()) Out << ", ";
182007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    Out << "...";  // Output varargs portion of signature!
183007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  }
184007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  Out << ")\n";
185007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
186007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  if (!M->isExternal()) {
187007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    // Loop over the symbol table, emitting all named constants...
188007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    if (M->hasSymbolTable())
189007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner      processSymbolTable(*M->getSymbolTable());
190007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
191007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    Out << "begin";
192007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
193007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    // Output all of its basic blocks... for the method
194007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner    for_each(M->begin(), M->end(),
195007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner	     bind_obj(this, &AssemblyWriter::processBasicBlock));
196007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
197739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner    Out << "end\n";
198007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  }
199007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner
200007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  Table.purgeMethod();
201009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
202009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
203009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethodArgument - This member is called for every argument that
204009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// is passed into the method.  Simply print it out
205009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
206007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
207009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Insert commas as we go... the first arg doesn't get a comma
208009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
209009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
210009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output type...
211009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << Arg->getType();
212009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
213009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output name, if available...
214009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg->hasName())
215009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " %" << Arg->getName();
216009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  else if (Table.getValSlot(Arg) < 0)
217009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "<badref>";
218009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
219009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
220009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processBasicBlock - This member is called for each basic block in a methd.
221009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
222007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
223009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (BB->hasName()) {              // Print out the label if it exists...
224b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n" << BB->getName() << ":";
225009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else {
226009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(BB);
227b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n; <label>:";
228009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0)
229b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << Slot;         // Extra newline seperates out label's
230009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else
231b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << "<badref>";
232009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
233b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner  Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n";  // Output # uses
234009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
235007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  // Output all of the instructions in the basic block...
236007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner  for_each(BB->begin(), BB->end(),
237007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner	   bind_obj(this, &AssemblyWriter::processInstruction));
238009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
239009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
240009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processInstruction - This member is called for each Instruction in a methd.
241009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
242007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processInstruction(const Instruction *I) {
243009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "\t";
244009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
245009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out name if it exists...
246009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (I && I->hasName())
247009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "%" << I->getName() << " = ";
248009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
249009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the opcode...
250a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  Out << I->getOpcodeName();
251009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
252009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the type of the operands...
253c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner  const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
254009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
255009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Special case conditional branches to swizzle the condition out to the front
256a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
257009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(2), true);
258009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
259009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand, true);
260009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
261009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true);
262009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
263a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Switch) {
264009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // Special case switch statement to get formatting nice and correct...
265009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand         , true); Out << ",";
266009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true); Out << " [";
267009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
268c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
269009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << "\n\t\t";
270c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), true); Out << ",";
271009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      writeOperand(I->getOperand(op+1), true);
272009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
273009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\n\t]";
2747fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner  } else if (I->isPHINode()) {
275c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    Out << " " << Operand->getType();
276009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
277c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    Out << " [";  writeOperand(Operand, false); Out << ",";
27828d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner    writeOperand(I->getOperand(1), false); Out << " ]";
279c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
280c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << ", [";
281c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), false); Out << ",";
28228d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner      writeOperand(I->getOperand(op+1), false); Out << " ]";
283c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    }
284a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Ret && !Operand) {
285009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " void";
286a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Call) {
287009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand, true);
288009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "(";
289c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
290c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
291009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << ",";
292c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op), true);
293009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
294009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
295009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " )";
296a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Malloc ||
297a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner	     I->getOpcode() == Instruction::Alloca) {
298c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    Out << " " << ((const PointerType*)I->getType())->getValueType();
299c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (I->getNumOperands()) {
300c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << ",";
301c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(0), true);
302009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
3030908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner  } else if (I->getOpcode() == Instruction::Cast) {
3040908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner    writeOperand(Operand, true);
3050908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner    Out << " to " << I->getType();
306009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else if (Operand) {   // Print the normal way...
307009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
308009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // PrintAllTypes - Instructions who have operands of all the same type
309009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // omit the type from all but the first operand.  If the instruction has
310009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // different type operands (for example br), then they are all printed.
311009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    bool PrintAllTypes = false;
312009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    const Type *TheType = Operand->getType();
313009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
314c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
315c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Operand = I->getOperand(i);
316009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (Operand->getType() != TheType) {
317009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	PrintAllTypes = true;       // We have differing types!  Print them all!
318009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	break;
319009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      }
320009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
321009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
322009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (!PrintAllTypes)
323009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << " " << I->getOperand(0)->getType();
324009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
325c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
326009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (i) Out << ",";
327c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(i), PrintAllTypes);
328009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
329009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
330009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
331009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print a little comment after the instruction indicating which slot it
332009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // occupies.
333009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  //
334b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner  if (I->getType() != Type::VoidTy) {
335b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\t\t; <" << I->getType() << ">";
336009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
337b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    if (!I->hasName()) {
338b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      int Slot = Table.getValSlot(I); // Print out the def slot taken...
339b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      if (Slot >= 0) Out << ":" << Slot;
340b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      else Out << ":<badref>";
341b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    }
342009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\t[#uses=" << I->use_size() << "]";  // Output # uses
343009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
344009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << endl;
345009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
346009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
347009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
348009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
349009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//                       External Interface declarations
350009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
351009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
352009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
353009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
354009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Module *M, ostream &o) {
355009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (M == 0) { o << "<null> module\n"; return; }
356009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(M, true);
357009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
358009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
359009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(M);
360009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
361009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
362009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Method *M, ostream &o) {
363009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (M == 0) { o << "<null> method\n"; return; }
364009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(M->getParent(), true);
365009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
366009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
367009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(M);
368009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
369009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
370009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
371009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const BasicBlock *BB, ostream &o) {
372009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (BB == 0) { o << "<null> basic block\n"; return; }
373009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
374009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(BB->getParent(), true);
375009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
376009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
377009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(BB);
378009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
379009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
380009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
381009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (CPV == 0) { o << "<null> constant pool value\n"; return; }
38281e29632f70bcd789af6d27b4622ea3cba162abaChris Lattner  WriteAsOperand(o, CPV, true, true, 0);
383009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
384009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
385009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Instruction *I, ostream &o) {
386009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (I == 0) { o << "<null> instruction\n"; return; }
387009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
388009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0,
389009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner			   true);
390009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
391009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
392009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(I);
393009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
394