X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=b109cb006eb6cfc9453b4d251a42514d9b0a3a10;hb=5527c0b6d1bda2c63212f91837792663469fd764;hp=570d5b3d4f30454eff3a7f3d87674b92b12487ca;hpb=d1cd3285601d4accf370779ac520c1e494a08b87;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 570d5b3d4f3..b109cb006eb 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -21,10 +21,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instruction.h" -#include "llvm/iMemory.h" -#include "llvm/iTerminators.h" -#include "llvm/iPHINode.h" -#include "llvm/iOther.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" #include "llvm/Assembly/Writer.h" @@ -34,7 +31,7 @@ #include using namespace llvm; -namespace { +namespace llvm { /// This class provides computation of slot numbers for LLVM Assembly writing. /// @brief LLVM Assembly Writing Slot Computation. @@ -46,16 +43,24 @@ public: /// @brief A mapping of Values to slot numbers typedef std::map ValueMap; + typedef std::map TypeMap; /// @brief A plane with next slot number and ValueMap - struct Plane { + struct ValuePlane { unsigned next_slot; ///< The next slot number to use ValueMap map; ///< The map of Value* -> unsigned - Plane() { next_slot = 0; } ///< Make sure we start at 0 + ValuePlane() { next_slot = 0; } ///< Make sure we start at 0 + }; + + struct TypePlane { + unsigned next_slot; + TypeMap map; + TypePlane() { next_slot = 0; } + void clear() { map.clear(); next_slot = 0; } }; /// @brief The map of planes by Type - typedef std::map TypedPlanes; + typedef std::map TypedPlanes; /// @} /// @name Constructors @@ -75,9 +80,11 @@ public: /// plane. Its an error to ask for something not in the SlotMachine. /// Its an error to ask for a Type* int getSlot(const Value *V); + int getSlot(const Type*Ty); /// Determine if a Value has a slot or not bool hasSlot(const Value* V); + bool hasSlot(const Type* Ty); /// @} /// @name Mutators @@ -85,7 +92,10 @@ public: public: /// If you'd like to deal with a function instead of just a module, use /// this method to get its data into the SlotMachine. - void incorporateFunction(const Function *F) { TheFunction = F; } + void incorporateFunction(const Function *F) { + TheFunction = F; + FunctionProcessed = false; + } /// After calling incorporateFunction, use this method to remove the /// most recently incorporated function from the SlotMachine. This @@ -103,11 +113,13 @@ private: /// been inserted already, they get inserted, otherwise they are ignored. /// Either way, the slot number for the Value* is returned. unsigned createSlot(const Value *V); + unsigned createSlot(const Type* Ty); /// Insert a value into the value table. Return the slot number /// that it now occupies. BadThings(TM) will happen if you insert a /// Value that's already been inserted. unsigned insertValue( const Value *V ); + unsigned insertValue( const Type* Ty); /// Add all of the module level global variables (and their initializers) /// and function declarations, but not the contents of those functions. @@ -129,18 +141,21 @@ public: /// @brief The function for which we are holding slot numbers const Function* TheFunction; + bool FunctionProcessed; /// @brief The TypePlanes map for the module level data TypedPlanes mMap; + TypePlane mTypes; /// @brief The TypePlanes map for the function level data TypedPlanes fMap; + TypePlane fTypes; /// @} }; -} +} // end namespace llvm static RegisterPass X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization); @@ -152,6 +167,11 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V, std::map &TypeTable, SlotMachine *Machine); +static void WriteAsOperandInternal(std::ostream &Out, const Type *T, + bool PrintName, + std::map &TypeTable, + SlotMachine *Machine); + static const Module *getModuleFromVal(const Value *V) { if (const Argument *MA = dyn_cast(V)) return MA->getParent() ? MA->getParent()->getParent() : 0; @@ -166,7 +186,6 @@ static const Module *getModuleFromVal(const Value *V) { } static SlotMachine *createSlotMachine(const Value *V) { - assert(!isa(V) && "Can't create an SC for a type!"); if (const Argument *FA = dyn_cast(V)) { return new SlotMachine(FA->getParent()); } else if (const Instruction *I = dyn_cast(V)) { @@ -262,7 +281,7 @@ static void calcTypeName(const Type *Ty, TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. - switch (Ty->getPrimitiveID()) { + switch (Ty->getTypeID()) { case Type::FunctionTyID: { const FunctionType *FTy = cast(Ty); calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result); @@ -304,6 +323,13 @@ static void calcTypeName(const Type *Ty, Result += "]"; break; } + case Type::PackedTyID: { + const PackedType *PTy = cast(Ty); + Result += "<" + utostr(PTy->getNumElements()) + " x "; + calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result); + Result += ">"; + break; + } case Type::OpaqueTyID: Result += "opaque"; break; @@ -363,6 +389,7 @@ std::ostream &llvm::WriteTypeSymbolic(std::ostream &Out, const Type *Ty, } } +/// @brief Internal constant writer. static void WriteConstantInt(std::ostream &Out, const Constant *CV, bool PrintName, std::map &TypeTable, @@ -472,12 +499,25 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, } Out << " }"; + } else if (const ConstantPacked *CP = dyn_cast(CV)) { + const Type *ETy = CP->getType()->getElementType(); + assert(CP->getNumOperands() > 0 && + "Number of operands for a PackedConst must be > 0"); + Out << '<'; + Out << ' '; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(0), + PrintName, TypeTable, Machine); + for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { + Out << ", "; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(i), PrintName, + TypeTable, Machine); + } + Out << " >"; } else if (isa(CV)) { Out << "null"; - } else if (const ConstantPointerRef *PR = dyn_cast(CV)) { - WriteAsOperandInternal(Out, PR->getValue(), true, TypeTable, Machine); - } else if (const ConstantExpr *CE = dyn_cast(CV)) { Out << CE->getOpcodeName() << " ("; @@ -509,21 +549,17 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V, std::map &TypeTable, SlotMachine *Machine) { Out << ' '; - if (PrintName && V->hasName()) { + if ((PrintName || isa(V)) && V->hasName()) Out << getLLVMName(V->getName()); - } else { - if (const Constant *CV = dyn_cast(V)) { + else { + const Constant *CV = dyn_cast(V); + if (CV && !isa(CV)) WriteConstantInt(Out, CV, PrintName, TypeTable, Machine); - } else { + else { int Slot; if (Machine) { Slot = Machine->getSlot(V); } else { - if (const Type *Ty = dyn_cast(V)) { - Out << Ty->getDescription(); - return; - } - Machine = createSlotMachine(V); if (Machine == 0) Slot = Machine->getSlot(V); @@ -539,7 +575,6 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V, } } - /// WriteAsOperand - Write the name of the specified value out to the specified /// ostream. This can be useful when you just want to print int %reg126, not /// the whole instruction that generated it. @@ -556,17 +591,56 @@ std::ostream &llvm::WriteAsOperand(std::ostream &Out, const Value *V, if (PrintType) printTypeInt(Out, V->getType(), TypeNames); - if (const Type *Ty = dyn_cast (V)) - printTypeInt(Out, Ty, TypeNames); - WriteAsOperandInternal(Out, V, PrintName, TypeNames, 0); return Out; } +/// WriteAsOperandInternal - Write the name of the specified value out to +/// the specified ostream. This can be useful when you just want to print +/// int %reg126, not the whole instruction that generated it. +/// +static void WriteAsOperandInternal(std::ostream &Out, const Type *T, + bool PrintName, + std::map &TypeTable, + SlotMachine *Machine) { + Out << ' '; + int Slot; + if (Machine) { + Slot = Machine->getSlot(T); + if (Slot != -1) + Out << '%' << Slot; + else + Out << ""; + } else { + Out << T->getDescription(); + } +} + +/// WriteAsOperand - Write the name of the specified value out to the specified +/// ostream. This can be useful when you just want to print int %reg126, not +/// the whole instruction that generated it. +/// +std::ostream &llvm::WriteAsOperand(std::ostream &Out, const Type *Ty, + bool PrintType, bool PrintName, + const Module *Context) { + std::map TypeNames; + assert(Context != 0 && "Can't write types as operand without module context"); + + fillTypeNameTable(Context, TypeNames); + + // if (PrintType) + // printTypeInt(Out, V->getType(), TypeNames); + + printTypeInt(Out, Ty, TypeNames); + + WriteAsOperandInternal(Out, Ty, PrintName, TypeNames, 0); + return Out; +} + namespace llvm { class AssemblyWriter { - std::ostream *Out; + std::ostream &Out; SlotMachine &Machine; const Module *TheModule; std::map TypeNames; @@ -574,7 +648,7 @@ class AssemblyWriter { public: inline AssemblyWriter(std::ostream &o, SlotMachine &Mac, const Module *M, AssemblyAnnotationWriter *AAW) - : Out(&o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { + : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { // If the module has a symbol table, take all global types and stuff their // names into the TypeNames map. @@ -593,7 +667,6 @@ public: void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); const Module* getModule() { return TheModule; } - void setStream(std::ostream &os) { Out = &os; } private : void printModule(const Module *M); @@ -609,7 +682,7 @@ private : // symbolic version of a type name. // std::ostream &printType(const Type *Ty) { - return printTypeInt(*Out, Ty, TypeNames); + return printTypeInt(Out, Ty, TypeNames); } // printTypeAtLeastOneLevel - Print out one level of the possibly complex type @@ -632,57 +705,77 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) - *Out << ", "; + Out << ", "; printType(*I); } if (FTy->isVarArg()) { - if (FTy->getNumParams()) *Out << ", "; - *Out << "..."; + if (FTy->getNumParams()) Out << ", "; + Out << "..."; } - *Out << ')'; + Out << ')'; } else if (const StructType *STy = dyn_cast(Ty)) { - *Out << "{ "; + Out << "{ "; for (StructType::element_iterator I = STy->element_begin(), E = STy->element_end(); I != E; ++I) { if (I != STy->element_begin()) - *Out << ", "; + Out << ", "; printType(*I); } - *Out << " }"; + Out << " }"; } else if (const PointerType *PTy = dyn_cast(Ty)) { printType(PTy->getElementType()) << '*'; } else if (const ArrayType *ATy = dyn_cast(Ty)) { - *Out << '[' << ATy->getNumElements() << " x "; + Out << '[' << ATy->getNumElements() << " x "; printType(ATy->getElementType()) << ']'; - } else if (const OpaqueType *OTy = dyn_cast(Ty)) { - *Out << "opaque"; + } else if (const PackedType *PTy = dyn_cast(Ty)) { + Out << '<' << PTy->getNumElements() << " x "; + printType(PTy->getElementType()) << '>'; + } + else if (const OpaqueType *OTy = dyn_cast(Ty)) { + Out << "opaque"; } else { if (!Ty->isPrimitiveType()) - *Out << ""; + Out << ""; printType(Ty); } - return *Out; + return Out; } void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, bool PrintName) { - if (PrintType) { *Out << ' '; printType(Operand->getType()); } - WriteAsOperandInternal(*Out, Operand, PrintName, TypeNames, &Machine); + if (PrintType) { Out << ' '; printType(Operand->getType()); } + WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Machine); } void AssemblyWriter::printModule(const Module *M) { switch (M->getEndianness()) { - case Module::LittleEndian: *Out << "target endian = little\n"; break; - case Module::BigEndian: *Out << "target endian = big\n"; break; + case Module::LittleEndian: Out << "target endian = little\n"; break; + case Module::BigEndian: Out << "target endian = big\n"; break; case Module::AnyEndianness: break; } switch (M->getPointerSize()) { - case Module::Pointer32: *Out << "target pointersize = 32\n"; break; - case Module::Pointer64: *Out << "target pointersize = 64\n"; break; + case Module::Pointer32: Out << "target pointersize = 32\n"; break; + case Module::Pointer64: Out << "target pointersize = 64\n"; break; case Module::AnyPointerSize: break; } + if (!M->getTargetTriple().empty()) + Out << "target triple = \"" << M->getTargetTriple() << "\"\n"; + + // Loop over the dependent libraries and emit them + Module::lib_iterator LI= M->lib_begin(); + Module::lib_iterator LE= M->lib_end(); + if (LI != LE) { + Out << "deplibs = [\n"; + while ( LI != LE ) { + Out << "\"" << *LI << "\""; + ++LI; + if ( LI != LE ) + Out << ",\n"; + } + Out << " ]\n"; + } // Loop over the symbol table, emitting all named constants... printSymbolTable(M->getSymbolTable()); @@ -690,7 +783,7 @@ void AssemblyWriter::printModule(const Module *M) { for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) printGlobal(I); - *Out << "\nimplementation ; Functions:\n"; + Out << "\nimplementation ; Functions:\n"; // Output all of the functions... for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) @@ -698,27 +791,30 @@ void AssemblyWriter::printModule(const Module *M) { } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { - if (GV->hasName()) *Out << getLLVMName(GV->getName()) << " = "; + if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = "; if (!GV->hasInitializer()) - *Out << "external "; + Out << "external "; else switch (GV->getLinkage()) { - case GlobalValue::InternalLinkage: *Out << "internal "; break; - case GlobalValue::LinkOnceLinkage: *Out << "linkonce "; break; - case GlobalValue::WeakLinkage: *Out << "weak "; break; - case GlobalValue::AppendingLinkage: *Out << "appending "; break; + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::WeakLinkage: Out << "weak "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::ExternalLinkage: break; } - *Out << (GV->isConstant() ? "constant " : "global "); + Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); - if (GV->hasInitializer()) - writeOperand(GV->getInitializer(), false, false); + if (GV->hasInitializer()) { + Constant* C = cast(GV->getInitializer()); + assert(C && "GlobalVar initializer isn't constant?"); + writeOperand(GV->getInitializer(), false, isa(C)); + } printInfoComment(*GV); - *Out << "\n"; + Out << "\n"; } @@ -729,7 +825,7 @@ void AssemblyWriter::printSymbolTable(const SymbolTable &ST) { // Print the types. for (SymbolTable::type_const_iterator TI = ST.type_begin(); TI != ST.type_end(); ++TI ) { - *Out << "\t" << getLLVMName(TI->first) << " = type "; + Out << "\t" << getLLVMName(TI->first) << " = type "; // Make sure we print out at least one level of the type structure, so // that we do not get %FILE = type %FILE @@ -744,8 +840,9 @@ void AssemblyWriter::printSymbolTable(const SymbolTable &ST) { SymbolTable::value_const_iterator VE = ST.value_end(PI->first); for (; VI != VE; ++VI) { - const Value *V = VI->second; - if (const Constant *CPV = dyn_cast(V)) { + const Value* V = VI->second; + const Constant *CPV = dyn_cast(V) ; + if (CPV && !isa(V)) { printConstant(CPV); } } @@ -760,40 +857,40 @@ void AssemblyWriter::printConstant(const Constant *CPV) { if (!CPV->hasName()) return; // Print out name... - *Out << "\t" << getLLVMName(CPV->getName()) << " ="; + Out << "\t" << getLLVMName(CPV->getName()) << " ="; // Write the value out now... writeOperand(CPV, true, false); printInfoComment(*CPV); - *Out << "\n"; + Out << "\n"; } /// printFunction - Print all aspects of a function. /// void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name... - *Out << "\n"; + Out << "\n"; - if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, *Out); + if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); if (F->isExternal()) - *Out << "declare "; + Out << "declare "; else switch (F->getLinkage()) { - case GlobalValue::InternalLinkage: *Out << "internal "; break; - case GlobalValue::LinkOnceLinkage: *Out << "linkonce "; break; - case GlobalValue::WeakLinkage: *Out << "weak "; break; - case GlobalValue::AppendingLinkage: *Out << "appending "; break; + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::WeakLinkage: Out << "weak "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; case GlobalValue::ExternalLinkage: break; } printType(F->getReturnType()) << ' '; if (!F->getName().empty()) - *Out << getLLVMName(F->getName()); + Out << getLLVMName(F->getName()); else - *Out << "\"\""; - *Out << '('; + Out << "\"\""; + Out << '('; Machine.incorporateFunction(F); // Loop over the arguments, printing them... @@ -804,21 +901,21 @@ void AssemblyWriter::printFunction(const Function *F) { // Finish printing arguments... if (FT->isVarArg()) { - if (FT->getNumParams()) *Out << ", "; - *Out << "..."; // Output varargs portion of signature! + if (FT->getNumParams()) Out << ", "; + Out << "..."; // Output varargs portion of signature! } - *Out << ')'; + Out << ')'; if (F->isExternal()) { - *Out << "\n"; + Out << "\n"; } else { - *Out << " {"; + Out << " {"; // Output all of its basic blocks... for the function for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) printBasicBlock(I); - *Out << "}\n"; + Out << "}\n"; } Machine.purgeFunction(); @@ -829,60 +926,60 @@ void AssemblyWriter::printFunction(const Function *F) { /// void AssemblyWriter::printArgument(const Argument *Arg) { // Insert commas as we go... the first arg doesn't get a comma - if (Arg != &Arg->getParent()->afront()) *Out << ", "; + if (Arg != &Arg->getParent()->afront()) Out << ", "; // Output type... printType(Arg->getType()); // Output name, if available... if (Arg->hasName()) - *Out << ' ' << getLLVMName(Arg->getName()); + Out << ' ' << getLLVMName(Arg->getName()); } /// printBasicBlock - This member is called for each basic block in a method. /// void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... - *Out << "\n" << BB->getName() << ':'; + Out << "\n" << BB->getName() << ':'; } else if (!BB->use_empty()) { // Don't print block # of no uses... - *Out << "\n;