X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=8824fd9244f915673ed85c4e019fd6217183e1bc;hb=98c65173bb27e1df4ebe87f8c864d6dc197209ca;hp=d5f211b14fd0663f0ccf585d8b53861150d5880a;hpb=3d10a5a75794356a0a568ce283713adc3a963200;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index d5f211b14fd..8824fd9244f 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -23,7 +23,8 @@ #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" -#include "llvm/MDNode.h" +#include "llvm/Operator.h" +#include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" @@ -33,7 +34,6 @@ #include "llvm/Support/CFG.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/Streams.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -66,10 +66,9 @@ static const Module *getModuleFromVal(const Value *V) { // PrintEscapedString - Print each character of the specified string, escaping // it if it is not printable or if it is an escape char. -static void PrintEscapedString(const char *Str, unsigned Length, - raw_ostream &Out) { - for (unsigned i = 0; i != Length; ++i) { - unsigned char C = Str[i]; +static void PrintEscapedString(const StringRef &Name, raw_ostream &Out) { + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + unsigned char C = Name[i]; if (isprint(C) && C != '\\' && C != '"') Out << C; else @@ -77,12 +76,6 @@ static void PrintEscapedString(const char *Str, unsigned Length, } } -// PrintEscapedString - Print each character of the specified string, escaping -// it if it is not printable or if it is an escape char. -static void PrintEscapedString(const std::string &Str, raw_ostream &Out) { - PrintEscapedString(Str.c_str(), Str.size(), Out); -} - enum PrefixType { GlobalPrefix, LabelPrefix, @@ -93,9 +86,9 @@ enum PrefixType { /// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either /// prefixed with % (if the string only contains simple characters) or is /// surrounded with ""'s (if it has special chars in it). Print it out. -static void PrintLLVMName(raw_ostream &OS, const char *NameStr, - unsigned NameLen, PrefixType Prefix) { - assert(NameStr && "Cannot get empty name!"); +static void PrintLLVMName(raw_ostream &OS, const StringRef &Name, + PrefixType Prefix) { + assert(Name.data() && "Cannot get empty name!"); switch (Prefix) { default: llvm_unreachable("Bad prefix!"); case NoPrefix: break; @@ -105,10 +98,10 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, } // Scan the name to see if it needs quotes first. - bool NeedsQuotes = isdigit(NameStr[0]); + bool NeedsQuotes = isdigit(Name[0]); if (!NeedsQuotes) { - for (unsigned i = 0; i != NameLen; ++i) { - char C = NameStr[i]; + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + char C = Name[i]; if (!isalnum(C) && C != '-' && C != '.' && C != '_') { NeedsQuotes = true; break; @@ -118,14 +111,14 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, // If we didn't need any quotes, just write out the name in one blast. if (!NeedsQuotes) { - OS.write(NameStr, NameLen); + OS << Name; return; } // Okay, we need quotes. Output the quotes and escape any scary characters as // needed. OS << '"'; - PrintEscapedString(NameStr, NameLen, OS); + PrintEscapedString(Name, OS); OS << '"'; } @@ -133,7 +126,7 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, /// prefixed with % (if the string only contains simple characters) or is /// surrounded with ""'s (if it has special chars in it). Print it out. static void PrintLLVMName(raw_ostream &OS, const Value *V) { - PrintLLVMName(OS, V->getNameStart(), V->getNameLen(), + PrintLLVMName(OS, V->getName(), isa(V) ? GlobalPrefix : LocalPrefix); } @@ -433,7 +426,7 @@ static void AddModuleTypesToPrinter(TypePrinting &TP, // Get the name as a string and insert it into TypeNames. std::string NameStr; raw_string_ostream NameOS(NameStr); - PrintLLVMName(NameOS, TI->first.c_str(), TI->first.length(), LocalPrefix); + PrintLLVMName(NameOS, TI->first, LocalPrefix); TP.addTypeName(Ty, NameOS.str()); } @@ -480,6 +473,9 @@ private: /// TheMDNode - The MDNode for which we are holding slot numbers. const MDNode *TheMDNode; + /// TheNamedMDNode - The MDNode for which we are holding slot numbers. + const NamedMDNode *TheNamedMDNode; + /// mMap - The TypePlanes map for the module level data. ValueMap mMap; unsigned mNext; @@ -498,6 +494,8 @@ public: explicit SlotTracker(const Function *F); /// Construct from a mdnode. explicit SlotTracker(const MDNode *N); + /// Construct from a named mdnode. + explicit SlotTracker(const NamedMDNode *N); /// Return the slot number of the specified value in it's type /// plane. If something is not in the SlotTracker, return -1. @@ -546,6 +544,9 @@ private: /// Add all MDNode operands. void processMDNode(); + /// Add all MDNode operands. + void processNamedMDNode(); + SlotTracker(const SlotTracker &); // DO NOT IMPLEMENT void operator=(const SlotTracker &); // DO NOT IMPLEMENT }; @@ -576,7 +577,7 @@ static SlotTracker *createSlotTracker(const Value *V) { } #if 0 -#define ST_DEBUG(X) cerr << X +#define ST_DEBUG(X) errs() << X #else #define ST_DEBUG(X) #endif @@ -585,20 +586,26 @@ static SlotTracker *createSlotTracker(const Value *V) { // to be added to the slot table. SlotTracker::SlotTracker(const Module *M) : TheModule(M), TheFunction(0), FunctionProcessed(false), TheMDNode(0), - mNext(0), fNext(0), mdnNext(0) { + TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { } // Function level constructor. Causes the contents of the Module and the one // function provided to be added to the slot table. SlotTracker::SlotTracker(const Function *F) : TheModule(F ? F->getParent() : 0), TheFunction(F), FunctionProcessed(false), - TheMDNode(0), mNext(0), fNext(0) { + TheMDNode(0), TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { } // Constructor to handle single MDNode. SlotTracker::SlotTracker(const MDNode *C) : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(C), - mNext(0), fNext(0), mdnNext(0) { + TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { +} + +// Constructor to handle single NamedMDNode. +SlotTracker::SlotTracker(const NamedMDNode *N) + : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(0), + TheNamedMDNode(N), mNext(0), fNext(0), mdnNext(0) { } inline void SlotTracker::initialize() { @@ -612,6 +619,9 @@ inline void SlotTracker::initialize() { if (TheMDNode) processMDNode(); + + if (TheNamedMDNode) + processNamedMDNode(); } // Iterate through all the global variables, functions, and global @@ -630,6 +640,18 @@ void SlotTracker::processModule() { } } + // Add metadata used by named metadata. + for (Module::const_named_metadata_iterator + I = TheModule->named_metadata_begin(), + E = TheModule->named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { + MDNode *MD = dyn_cast_or_null(NMD->getElement(i)); + if (MD) + CreateMetadataSlot(MD); + } + } + // Add all the unnamed functions to the table. for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); I != E; ++I) @@ -681,6 +703,19 @@ void SlotTracker::processMDNode() { ST_DEBUG("end processMDNode!\n"); } +/// processNamedMDNode - Process TheNamedMDNode. +void SlotTracker::processNamedMDNode() { + ST_DEBUG("begin processNamedMDNode!\n"); + mdnNext = 0; + for (unsigned i = 0, e = TheNamedMDNode->getNumElements(); i != e; ++i) { + MDNode *MD = dyn_cast_or_null(TheNamedMDNode->getElement(i)); + if (MD) + CreateMetadataSlot(MD); + } + TheNamedMDNode = 0; + ST_DEBUG("end processNamedMDNode!\n"); +} + /// Clean up after incorporating a function. This is the only way to get out of /// the function incorporation state that affects get*Slot/Create*Slot. Function /// incorporation state is indicated by TheFunction != 0. @@ -851,6 +886,22 @@ static void WriteMDNodes(raw_ostream &Out, TypePrinting &TypePrinter, } } +static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { + if (const OverflowingBinaryOperator *OBO = + dyn_cast(U)) { + if (OBO->hasNoUnsignedOverflow()) + Out << " nuw"; + if (OBO->hasNoSignedOverflow()) + Out << " nsw"; + } else if (const SDivOperator *Div = dyn_cast(U)) { + if (Div->isExact()) + Out << " exact"; + } else if (const GEPOperator *GEP = dyn_cast(U)) { + if (GEP->isInBounds()) + Out << " inbounds"; + } +} + static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinting &TypePrinter, SlotTracker *Machine) { if (const ConstantInt *CI = dyn_cast(CV)) { @@ -1049,13 +1100,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, return; } - if (const MDString *S = dyn_cast(CV)) { - Out << "!\""; - PrintEscapedString(S->begin(), S->size(), Out); - Out << '"'; - return; - } - if (const MDNode *Node = dyn_cast(CV)) { Out << "!" << Machine->getMetadataSlot(Node); return; @@ -1063,6 +1107,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, if (const ConstantExpr *CE = dyn_cast(CV)) { Out << CE->getOpcodeName(); + WriteOptimizationInfo(Out, CE); if (CE->isCompare()) Out << ' ' << getPredicateText(CE->getPredicate()); Out << " ("; @@ -1123,7 +1168,19 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << '"'; return; } - + + if (const MDNode *N = dyn_cast(V)) { + Out << '!' << Machine->getMetadataSlot(N); + return; + } + + if (const MDString *MDS = dyn_cast(V)) { + Out << "!\""; + PrintEscapedString(MDS->getString(), Out); + Out << '"'; + return; + } + char Prefix = '%'; int Slot; if (Machine) { @@ -1329,6 +1386,20 @@ void AssemblyWriter::printModule(const Module *M) { for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) printFunction(I); + // Output named metadata. + for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), + E = M->named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + Out << "!" << NMD->getName() << " = !{"; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { + if (i) Out << ", "; + MDNode *MD = dyn_cast_or_null(NMD->getElement(i)); + Out << '!' << Machine.getMetadataSlot(MD); + } + Out << "}\n"; + } + + // Output metadata. WriteMDNodes(Out, TypePrinter, Machine); } @@ -1455,7 +1526,7 @@ void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); TI != TE; ++TI) { Out << '\t'; - PrintLLVMName(Out, &TI->first[0], TI->first.size(), LocalPrefix); + PrintLLVMName(Out, TI->first, LocalPrefix); Out << " = type "; // Make sure we print out at least one level of the type structure, so @@ -1586,7 +1657,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"; - PrintLLVMName(Out, BB->getNameStart(), BB->getNameLen(), LabelPrefix); + PrintLLVMName(Out, BB->getName(), LabelPrefix); Out << ':'; } else if (!BB->use_empty()) { // Don't print block # of no uses... Out << "\n;