AsmWriter.cpp revision d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfa
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" 21009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 22d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattnervoid DebugValue(const Value *V) { 23d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner cerr << V << endl; 24d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner} 25d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner 26d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner 27009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerclass AssemblyWriter : public ModuleAnalyzer { 28009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ostream &Out; 29009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator &Table; 30009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic: 31009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) { 32009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 33009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 34009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Module *M) { processModule(M); } 35009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Method *M) { processMethod(M); } 36009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const BasicBlock *BB) { processBasicBlock(BB); } 37009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Instruction *I) { processInstruction(I); } 38009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const ConstPoolVal *CPV) { processConstant(CPV); } 39009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 40009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprotected: 41009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool visitMethod(const Method *M); 42009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processConstPool(const ConstantPool &CP, bool isMethod); 43009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processConstant(const ConstPoolVal *CPV); 44009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processMethod(const Method *M); 45009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processMethodArgument(const MethodArgument *MA); 46009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processBasicBlock(const BasicBlock *BB); 47009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner virtual bool processInstruction(const Instruction *I); 48009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 49009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate : 50009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); 51009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}; 52009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 53009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// visitMethod - This member is called after the above two steps, visting each 56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// method, because they are effectively values that go into the constant pool. 57009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 58009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::visitMethod(const Method *M) { 59009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 60009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 61009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 62009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processConstPool(const ConstantPool &CP, bool isMethod) { 63009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Done printing arguments... 64009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (isMethod) Out << ")\n"; 65009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 66009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ModuleAnalyzer::processConstPool(CP, isMethod); 67009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 68009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (isMethod) 69009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "begin"; 70009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else 71009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "implementation\n"; 72009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 73009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 74009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 75009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processConstant - Print out a constant pool entry... 77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processConstant(const ConstPoolVal *CPV) { 79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t"; 80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out name if it exists... 82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (CPV->hasName()) 83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "%" << CPV->getName() << " = "; 84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the opcode... 86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << CPV->getType(); 87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Write the value out now... 89009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(CPV, false, false); 90009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 91009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!CPV->hasName() && CPV->getType() != Type::VoidTy) { 92009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner int Slot = Table.getValSlot(CPV); // Print out the def slot taken... 93009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t\t; <" << CPV->getType() << ">:"; 94009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Slot >= 0) Out << Slot; 95009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else Out << "<badref>"; 96009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 97009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << endl; 99009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 102009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethod - Process all aspects of a method. 103009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 104009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processMethod(const Method *M) { 105009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the return type and name... 106009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\n" << M->getReturnType() << " \"" << M->getName() << "\"("; 107009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Table.incorporateMethod(M); 108009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ModuleAnalyzer::processMethod(M); 109009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Table.purgeMethod(); 110009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "end\n"; 111009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 112009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 113009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 114009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethodArgument - This member is called for every argument that 115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// is passed into the method. Simply print it out 116009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 117009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) { 118009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Insert commas as we go... the first arg doesn't get a comma 119009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", "; 120009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 121009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Output type... 122009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << Arg->getType(); 123009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 124009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Output name, if available... 125009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Arg->hasName()) 126009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " %" << Arg->getName(); 127009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else if (Table.getValSlot(Arg) < 0) 128009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "<badref>"; 129009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 130009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 131009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 132009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 133009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processBasicBlock - This member is called for each basic block in a methd. 134009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 135009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processBasicBlock(const BasicBlock *BB) { 136009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (BB->hasName()) { // Print out the label if it exists... 137b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\n" << BB->getName() << ":"; 138009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else { 139009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner int Slot = Table.getValSlot(BB); 140b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\n; <label>:"; 141009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Slot >= 0) 142b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << Slot; // Extra newline seperates out label's 143009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else 144b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "<badref>"; 145009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 146b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n"; // Output # uses 147009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ModuleAnalyzer::processBasicBlock(BB); 149009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 150009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 151009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 152009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processInstruction - This member is called for each Instruction in a methd. 153009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 154009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processInstruction(const Instruction *I) { 155009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t"; 156009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 157009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out name if it exists... 158009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (I && I->hasName()) 159009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "%" << I->getName() << " = "; 160009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 161009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the opcode... 162a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner Out << I->getOpcodeName(); 163009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 164009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the type of the operands... 165c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0; 166009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 167009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Special case conditional branches to swizzle the condition out to the front 168a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) { 169009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(2), true); 170009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 171009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand, true); 172009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 173009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(1), true); 174009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 175a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Switch) { 176009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Special case switch statement to get formatting nice and correct... 177009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand , true); Out << ","; 178009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(1), true); Out << " ["; 179009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 180c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { 181009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\n\t\t"; 182c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op ), true); Out << ","; 183009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(op+1), true); 184009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 185009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\n\t]"; 1867fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner } else if (I->isPHINode()) { 187c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner Out << " " << Operand->getType(); 188009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 189c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner Out << " ["; writeOperand(Operand, false); Out << ","; 19028d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner writeOperand(I->getOperand(1), false); Out << " ]"; 191c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { 192c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << ", ["; 193c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op ), false); Out << ","; 19428d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner writeOperand(I->getOperand(op+1), false); Out << " ]"; 195c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner } 196a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Ret && !Operand) { 197009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " void"; 198a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Call) { 199009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand, true); 200009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "("; 201c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true); 202c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) { 203009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 204c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op), true); 205009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 206009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 207009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " )"; 208a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Malloc || 209a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner I->getOpcode() == Instruction::Alloca) { 210c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << " " << ((const PointerType*)I->getType())->getValueType(); 211c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner if (I->getNumOperands()) { 212c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << ","; 213c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(0), true); 214009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 2150908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner } else if (I->getOpcode() == Instruction::Cast) { 2160908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner writeOperand(Operand, true); 2170908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner Out << " to " << I->getType(); 218009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else if (Operand) { // Print the normal way... 219009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 220009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // PrintAllTypes - Instructions who have operands of all the same type 221009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // omit the type from all but the first operand. If the instruction has 222009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // different type operands (for example br), then they are all printed. 223009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner bool PrintAllTypes = false; 224009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const Type *TheType = Operand->getType(); 225009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 226c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) { 227c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Operand = I->getOperand(i); 228009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Operand->getType() != TheType) { 229009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner PrintAllTypes = true; // We have differing types! Print them all! 230009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner break; 231009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 232009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 233009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 234009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!PrintAllTypes) 235009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " " << I->getOperand(0)->getType(); 236009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 237c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) { 238009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (i) Out << ","; 239c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(i), PrintAllTypes); 240009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 241009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 242009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 243009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print a little comment after the instruction indicating which slot it 244009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // occupies. 245009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // 246b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (I->getType() != Type::VoidTy) { 247b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\t\t; <" << I->getType() << ">"; 248009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 249b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (!I->hasName()) { 250b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner int Slot = Table.getValSlot(I); // Print out the def slot taken... 251b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (Slot >= 0) Out << ":" << Slot; 252b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner else Out << ":<badref>"; 253b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner } 254009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses 255009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 256009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << endl; 257009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 258009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return false; 259009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 260009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 261009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 262009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, 263009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner bool PrintName) { 264009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (PrintType) 265009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " " << Operand->getType(); 266009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 267009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Operand->hasName() && PrintName) { 268009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " %" << Operand->getName(); 269009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else { 270009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner int Slot = Table.getValSlot(Operand); 271009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 272c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner if (const ConstPoolVal *CPV = Operand->castConstant()) { 273c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << " " << CPV->getStrValue(); 274009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else { 275009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Slot >= 0) Out << " %" << Slot; 276009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else if (PrintName) 277009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "<badref>"; // Not embeded into a location? 278009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 279009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 280009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 281009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 282009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 283009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 284009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// External Interface declarations 285009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 286009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 287009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 288009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 289009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Module *M, ostream &o) { 290009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (M == 0) { o << "<null> module\n"; return; } 291009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(M, true); 292009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 293009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 294009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(M); 295009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 296009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 297009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Method *M, ostream &o) { 298009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (M == 0) { o << "<null> method\n"; return; } 299009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(M->getParent(), true); 300009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 301009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 302009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(M); 303009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 304009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 305009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 306009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const BasicBlock *BB, ostream &o) { 307009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (BB == 0) { o << "<null> basic block\n"; return; } 308009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 309009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(BB->getParent(), true); 310009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 311009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 312009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(BB); 313009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 314009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 315009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const ConstPoolVal *CPV, ostream &o) { 316009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (CPV == 0) { o << "<null> constant pool value\n"; return; } 317009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 318009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator *SlotTable; 319009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 320009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // A Constant pool value may have a parent that is either a method or a 321009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // module. Untangle this now... 322009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // 3237fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner if (CPV->getParent() == 0 || CPV->getParent()->isMethod()) { 324009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotTable = new SlotCalculator((Method*)CPV->getParent(), true); 325009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else { 3267fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner SlotTable = 3277fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner new SlotCalculator(CPV->getParent()->castModuleAsserting(), true); 328009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 329009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 330009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, *SlotTable); 331009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(CPV); 332009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 333009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner delete SlotTable; 334009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 335009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 336009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Instruction *I, ostream &o) { 337009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (I == 0) { o << "<null> instruction\n"; return; } 338009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 339009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0, 340009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner true); 341009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 342009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 343009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(I); 344009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 345