X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FAsmWriter.cpp;h=2c9a77c834fb909e9fe668868fbaa40444ea3b64;hb=197ff79a8cd64d9eb059f0022e95ff74fceb8cf6;hp=97dcf45c3ccd901039726fbe88d05a4b5861a754;hpb=7a716addedc4938fa0ec6b77e5eeaced6eafc5d0;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 97dcf45c3cc..2c9a77c834f 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -6,34 +6,35 @@ // LLVM code, because of of the primary uses of it is for debugging // transformations. // -// TODO: print out the type name instead of the full type if a particular type -// is in the symbol table... -// //===----------------------------------------------------------------------===// #include "llvm/Assembly/CachedWriter.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/SlotCalculator.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instruction.h" #include "llvm/Module.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" -#include "llvm/BasicBlock.h" -#include "llvm/ConstantVals.h" +#include "llvm/Constants.h" #include "llvm/iMemory.h" #include "llvm/iTerminators.h" #include "llvm/iPHINode.h" #include "llvm/iOther.h" #include "llvm/SymbolTable.h" -#include "llvm/Argument.h" +#include "llvm/Support/CFG.h" #include "Support/StringExtras.h" #include "Support/STLExtras.h" #include -#include using std::string; using std::map; using std::vector; using std::ostream; +static RegisterPass +X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization); +static RegisterPass +Y("print","Print function to stderr",PassInfo::Analysis|PassInfo::Optimization); + static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName, map &TypeTable, SlotCalculator *Table); @@ -48,8 +49,6 @@ static const Module *getModuleFromVal(const Value *V) { return M ? M->getParent() : 0; } else if (const GlobalValue *GV = dyn_cast(V)) return GV->getParent(); - else if (const Module *Mod = dyn_cast(V)) - return Mod; return 0; } @@ -65,8 +64,6 @@ static SlotCalculator *createSlotCalculator(const Value *V) { return new SlotCalculator(GV->getParent(), true); } else if (const Function *Func = dyn_cast(V)) { return new SlotCalculator(Func, true); - } else if (const Module *Mod = dyn_cast(V)) { - return new SlotCalculator(Mod, true); } return 0; } @@ -77,20 +74,19 @@ static SlotCalculator *createSlotCalculator(const Value *V) { // static void fillTypeNameTable(const Module *M, map &TypeNames) { - if (M && M->hasSymbolTable()) { - const SymbolTable *ST = M->getSymbolTable(); - SymbolTable::const_iterator PI = ST->find(Type::TypeTy); - if (PI != ST->end()) { - SymbolTable::type_const_iterator I = PI->second.begin(); - for (; I != PI->second.end(); ++I) { - // As a heuristic, don't insert pointer to primitive types, because - // they are used too often to have a single useful name. - // - const Type *Ty = cast(I->second); - if (!isa(Ty) || - !cast(Ty)->getElementType()->isPrimitiveType()) - TypeNames.insert(std::make_pair(Ty, "%"+I->first)); - } + if (!M) return; + const SymbolTable &ST = M->getSymbolTable(); + SymbolTable::const_iterator PI = ST.find(Type::TypeTy); + if (PI != ST.end()) { + SymbolTable::type_const_iterator I = PI->second.begin(); + for (; I != PI->second.end(); ++I) { + // As a heuristic, don't insert pointer to primitive types, because + // they are used too often to have a single useful name. + // + const Type *Ty = cast(I->second); + if (!isa(Ty) || + !cast(Ty)->getElementType()->isPrimitiveType()) + TypeNames.insert(std::make_pair(Ty, "%"+I->first)); } } } @@ -161,8 +157,7 @@ static string calcTypeName(const Type *Ty, vector &TypeStack, break; } default: - assert(0 && "Unhandled case in getTypeProps!"); - Result = ""; + Result = ""; } TypeStack.pop_back(); // Remove self from stack... @@ -204,7 +199,7 @@ ostream &WriteTypeSymbolic(ostream &Out, const Type *Ty, const Module *M) { // If they want us to print out a type, attempt to make it symbolic if there // is a symbol table in the module... - if (M && M->hasSymbolTable()) { + if (M) { map TypeNames; fillTypeNameTable(M, TypeNames); @@ -217,20 +212,85 @@ ostream &WriteTypeSymbolic(ostream &Out, const Type *Ty, const Module *M) { static void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName, map &TypeTable, SlotCalculator *Table) { - if (const ConstantArray *CA = dyn_cast(CV)) { - const Type *SubType = CA->getType()->getElementType(); - if (SubType == Type::SByteTy) { - Out << CV->getStrValue(); // Output string format if possible... - } else { + if (const ConstantBool *CB = dyn_cast(CV)) { + Out << (CB == ConstantBool::True ? "true" : "false"); + } else if (const ConstantSInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantUInt *CI = dyn_cast(CV)) { + Out << CI->getValue(); + } else if (const ConstantFP *CFP = dyn_cast(CV)) { + // We would like to output the FP constant value in exponential notation, + // but we cannot do this if doing so will lose precision. Check here to + // make sure that we only output it in exponential format if we can parse + // the value back and get the same value. + // + std::string StrVal = ftostr(CFP->getValue()); + + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check that + // the string matches the "[-+]?[0-9]" regex. + // + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[0] >= '0' && StrVal[0] <= '9'))) + // Reparse stringized version! + if (atof(StrVal.c_str()) == CFP->getValue()) { + Out << StrVal; return; + } + + // Otherwise we could not reparse it to exactly the same value, so we must + // output the string in hexadecimal format! + // + // Behave nicely in the face of C TBAA rules... see: + // http://www.nullstone.com/htmls/category/aliastyp.htm + // + double Val = CFP->getValue(); + char *Ptr = (char*)&Val; + assert(sizeof(double) == sizeof(uint64_t) && sizeof(double) == 8 && + "assuming that double is 64 bits!"); + Out << "0x" << utohexstr(*(uint64_t*)Ptr); + + } else if (const ConstantArray *CA = dyn_cast(CV)) { + // As a special case, print the array as a string if it is an array of + // ubytes or an array of sbytes with positive values. + // + const Type *ETy = CA->getType()->getElementType(); + bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy); + + if (ETy == Type::SByteTy) + for (unsigned i = 0; i < CA->getNumOperands(); ++i) + if (cast(CA->getOperand(i))->getValue() < 0) { + isString = false; + break; + } + + if (isString) { + Out << "c\""; + for (unsigned i = 0; i < CA->getNumOperands(); ++i) { + unsigned char C = (ETy == Type::SByteTy) ? + (unsigned char)cast(CA->getOperand(i))->getValue() : + (unsigned char)cast(CA->getOperand(i))->getValue(); + + if (isprint(C) && C != '"' && C != '\\') { + Out << C; + } else { + Out << '\\' + << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) + << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); + } + } + Out << "\""; + + } else { // Cannot output in string format... Out << "["; if (CA->getNumOperands()) { Out << " "; - printTypeInt(Out, SubType, TypeTable); + printTypeInt(Out, ETy, TypeTable); WriteAsOperandInternal(Out, CA->getOperand(0), PrintName, TypeTable, Table); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { Out << ", "; - printTypeInt(Out, SubType, TypeTable); + printTypeInt(Out, ETy, TypeTable); WriteAsOperandInternal(Out, CA->getOperand(i), PrintName, TypeTable, Table); } @@ -259,9 +319,41 @@ static void WriteConstantInt(ostream &Out, const Constant *CV, bool PrintName, } else if (isa(CV)) { Out << "null"; - // FIXME: Handle ConstantPointerRef + lots of others... + } else if (const ConstantPointerRef *PR = dyn_cast(CV)) { + const GlobalValue *V = PR->getValue(); + if (V->hasName()) { + Out << "%" << V->getName(); + } else if (Table) { + int Slot = Table->getValSlot(V); + if (Slot >= 0) + Out << "%" << Slot; + else + Out << ""; + } else { + Out << ""; + } + + } else if (const ConstantExpr *CE = dyn_cast(CV)) { + Out << CE->getOpcodeName(); + + bool isGEP = CE->getOpcode() == Instruction::GetElementPtr; + Out << " ("; + + for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { + printTypeInt(Out, (*OI)->getType(), TypeTable); + WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Table); + if (OI+1 != CE->op_end()) + Out << ", "; + } + + if (CE->getOpcode() == Instruction::Cast) { + Out << " to "; + printTypeInt(Out, CE->getType(), TypeTable); + } + Out << ")"; + } else { - Out << CV->getStrValue(); + Out << ""; } } @@ -309,17 +401,17 @@ static void WriteAsOperandInternal(ostream &Out, const Value *V, bool PrintName, // whole instruction that generated it. // ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType, - bool PrintName, SlotCalculator *Table) { + bool PrintName, const Module *Context) { map TypeNames; - const Module *M = getModuleFromVal(V); + if (Context == 0) Context = getModuleFromVal(V); - if (M && M->hasSymbolTable()) - fillTypeNameTable(M, TypeNames); + if (Context) + fillTypeNameTable(Context, TypeNames); if (PrintType) printTypeInt(Out, V->getType(), TypeNames); - WriteAsOperandInternal(Out, V, PrintName, TypeNames, Table); + WriteAsOperandInternal(Out, V, PrintName, TypeNames, 0); return Out; } @@ -344,10 +436,12 @@ public: inline void write(const GlobalVariable *G) { printGlobal(G); } inline void write(const Function *F) { printFunction(F); } inline void write(const BasicBlock *BB) { printBasicBlock(BB); } - inline void write(const Instruction *I) { printInstruction(I); } + inline void write(const Instruction *I) { printInstruction(*I); } inline void write(const Constant *CPV) { printConstant(CPV); } inline void write(const Type *Ty) { printType(Ty); } + void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); + private : void printModule(const Module *M); void printSymbolTable(const SymbolTable &ST); @@ -356,7 +450,7 @@ private : void printFunction(const Function *F); void printArgument(const Argument *FA); void printBasicBlock(const BasicBlock *BB); - void printInstruction(const Instruction *I); + void printInstruction(const Instruction &I); // printType - Go to extreme measures to attempt to print out a short, // symbolic version of a type name. @@ -370,11 +464,9 @@ private : // ostream &printTypeAtLeastOneLevel(const Type *Ty); - void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); - // printInfoComment - Print a little comment after the instruction indicating // which slot it occupies. - void printInfoComment(const Value *V); + void printInfoComment(const Value &V); }; @@ -382,7 +474,7 @@ private : // without considering any symbolic types that we may have equal to it. // ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { - if (FunctionType *FTy = dyn_cast(Ty)) { + if (const FunctionType *FTy = dyn_cast(Ty)) { printType(FTy->getReturnType()) << " ("; for (FunctionType::ParamTypes::const_iterator I = FTy->getParamTypes().begin(), @@ -396,7 +488,7 @@ ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { Out << "..."; } Out << ")"; - } else if (StructType *STy = dyn_cast(Ty)) { + } else if (const StructType *STy = dyn_cast(Ty)) { Out << "{ "; for (StructType::ElementTypes::const_iterator I = STy->getElementTypes().begin(), @@ -406,13 +498,16 @@ ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { printType(*I); } Out << " }"; - } else if (PointerType *PTy = dyn_cast(Ty)) { + } else if (const PointerType *PTy = dyn_cast(Ty)) { printType(PTy->getElementType()) << "*"; - } else if (ArrayType *ATy = dyn_cast(Ty)) { + } else if (const ArrayType *ATy = dyn_cast(Ty)) { Out << "[" << ATy->getNumElements() << " x "; printType(ATy->getElementType()) << "]"; + } else if (const OpaqueType *OTy = dyn_cast(Ty)) { + Out << OTy->getDescription(); } else { - assert(Ty->isPrimitiveType() && "Unknown derived type!"); + if (!Ty->isPrimitiveType()) + Out << ""; printType(Ty); } return Out; @@ -428,23 +523,23 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, void AssemblyWriter::printModule(const Module *M) { // Loop over the symbol table, emitting all named constants... - if (M->hasSymbolTable()) - printSymbolTable(*M->getSymbolTable()); + printSymbolTable(M->getSymbolTable()); - for_each(M->gbegin(), M->gend(), - bind_obj(this, &AssemblyWriter::printGlobal)); + for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + printGlobal(I); - Out << "implementation\n"; + Out << "\nimplementation ; Functions:\n"; // Output all of the functions... - for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printFunction)); + for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) + printFunction(I); } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasName()) Out << "%" << GV->getName() << " = "; if (GV->hasInternalLinkage()) Out << "internal "; - if (!GV->hasInitializer()) Out << "uninitialized "; + if (!GV->hasInitializer()) Out << "external "; Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); @@ -452,7 +547,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasInitializer()) writeOperand(GV->getInitializer(), false, false); - printInfoComment(GV); + printInfoComment(*GV); Out << "\n"; } @@ -494,61 +589,42 @@ void AssemblyWriter::printConstant(const Constant *CPV) { // Write the value out now... writeOperand(CPV, true, false); - if (!CPV->hasName() && CPV->getType() != Type::VoidTy) { - int Slot = Table.getValSlot(CPV); // Print out the def slot taken... - Out << "\t\t; <"; - printType(CPV->getType()) << ">:"; - if (Slot >= 0) Out << Slot; - else Out << ""; - } - + printInfoComment(*CPV); Out << "\n"; } // printFunction - Print all aspects of a function. // -void AssemblyWriter::printFunction(const Function *M) { +void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name... - Out << "\n" << (M->isExternal() ? "declare " : "") - << (M->hasInternalLinkage() ? "internal " : ""); - printType(M->getReturnType()) << " \"" << M->getName() << "\"("; - Table.incorporateFunction(M); + Out << "\n" << (F->isExternal() ? "declare " : "") + << (F->hasInternalLinkage() ? "internal " : ""); + printType(F->getReturnType()) << " %" << F->getName() << "("; + Table.incorporateFunction(F); // Loop over the arguments, printing them... - const FunctionType *MT = M->getFunctionType(); + const FunctionType *FT = F->getFunctionType(); - if (!M->isExternal()) { - for_each(M->getArgumentList().begin(), M->getArgumentList().end(), - bind_obj(this, &AssemblyWriter::printArgument)); - } else { - // Loop over the arguments, printing them... - const FunctionType *MT = M->getFunctionType(); - for (FunctionType::ParamTypes::const_iterator I = MT->getParamTypes().begin(), - E = MT->getParamTypes().end(); I != E; ++I) { - if (I != MT->getParamTypes().begin()) Out << ", "; - printType(*I); - } - } + for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) + printArgument(I); // Finish printing arguments... - if (MT->isVarArg()) { - if (MT->getParamTypes().size()) Out << ", "; + if (FT->isVarArg()) { + if (FT->getParamTypes().size()) Out << ", "; Out << "..."; // Output varargs portion of signature! } - Out << ")\n"; - - if (!M->isExternal()) { - // Loop over the symbol table, emitting all named constants... - if (M->hasSymbolTable()) - printSymbolTable(*M->getSymbolTable()); + Out << ")"; - Out << "begin"; + if (F->isExternal()) { + Out << "\n"; + } else { + Out << " {"; // Output all of its basic blocks... for the function - for_each(M->begin(), M->end(), - bind_obj(this, &AssemblyWriter::printBasicBlock)); + for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) + printBasicBlock(I); - Out << "end\n"; + Out << "}\n"; } Table.purgeFunction(); @@ -559,7 +635,7 @@ void AssemblyWriter::printFunction(const Function *M) { // void AssemblyWriter::printArgument(const Argument *Arg) { // Insert commas as we go... the first arg doesn't get a comma - if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", "; + if (Arg != &Arg->getParent()->afront()) Out << ", "; // Output type... printType(Arg->getType()); @@ -576,7 +652,7 @@ void AssemblyWriter::printArgument(const Argument *Arg) { void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... Out << "\n" << BB->getName() << ":"; - } else { + } else if (!BB->use_empty()) { // Don't print block # of no uses... int Slot = Table.getValSlot(BB); Out << "\n;