diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/VMCore/AsmWriter.cpp | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'lib/VMCore/AsmWriter.cpp')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 870 |
1 files changed, 536 insertions, 334 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index cbf7070..b5ae81b 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" @@ -31,8 +32,10 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" #include <algorithm> #include <cctype> #include <map> @@ -48,15 +51,15 @@ AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} static const Module *getModuleFromVal(const Value *V) { if (const Argument *MA = dyn_cast<Argument>(V)) return MA->getParent() ? MA->getParent()->getParent() : 0; - + if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) return BB->getParent() ? BB->getParent()->getParent() : 0; - + if (const Instruction *I = dyn_cast<Instruction>(V)) { const Function *M = I->getParent() ? I->getParent()->getParent() : 0; return M ? M->getParent() : 0; } - + if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV->getParent(); return 0; @@ -64,10 +67,10 @@ 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, +static void PrintEscapedString(const StringRef &Name, raw_ostream &Out) { - for (unsigned i = 0; i != Length; ++i) { - unsigned char C = Str[i]; + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + unsigned char C = Name[i]; if (isprint(C) && C != '\\' && C != '"') Out << C; else @@ -75,12 +78,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, @@ -91,39 +88,39 @@ 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: assert(0 && "Bad prefix!"); + default: llvm_unreachable("Bad prefix!"); case NoPrefix: break; case GlobalPrefix: OS << '@'; break; case LabelPrefix: break; case LocalPrefix: OS << '%'; break; } - + // 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; } } } - + // 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 << '"'; } @@ -131,7 +128,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<GlobalValue>(V) ? GlobalPrefix : LocalPrefix); } @@ -178,11 +175,11 @@ void TypePrinting::CalcTypeName(const Type *Ty, return; } } - + // Check to see if the Type is already on the stack... unsigned Slot = 0, CurSize = TypeStack.size(); while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type - + // This is another base case for the recursion. In this case, we know // that we have looped back to a type that we have previously visited. // Generate the appropriate upreference to handle this. @@ -190,9 +187,9 @@ void TypePrinting::CalcTypeName(const Type *Ty, OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference return; } - + TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. - + switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; case Type::FloatTyID: OS << "float"; break; @@ -205,7 +202,7 @@ void TypePrinting::CalcTypeName(const Type *Ty, case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); break; - + case Type::FunctionTyID: { const FunctionType *FTy = cast<FunctionType>(Ty); CalcTypeName(FTy->getReturnType(), TypeStack, OS); @@ -269,7 +266,7 @@ void TypePrinting::CalcTypeName(const Type *Ty, OS << "<unrecognized-type>"; break; } - + TypeStack.pop_back(); // Remove self from stack. } @@ -287,13 +284,13 @@ void TypePrinting::print(const Type *Ty, raw_ostream &OS, return; } } - + // Otherwise we have a type that has not been named but is a derived type. // Carefully recurse the type hierarchy to print out any contained symbolic // names. SmallVector<const Type *, 16> TypeStack; std::string TypeName; - + raw_string_ostream TypeOS(TypeName); CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName); OS << TypeOS.str(); @@ -309,13 +306,13 @@ namespace { // objects, we keep several helper maps. DenseSet<const Value*> VisitedConstants; DenseSet<const Type*> VisitedTypes; - + TypePrinting &TP; std::vector<const Type*> &NumberedTypes; public: TypeFinder(TypePrinting &tp, std::vector<const Type*> &numberedTypes) : TP(tp), NumberedTypes(numberedTypes) {} - + void Run(const Module &M) { // Get types from the type symbol table. This gets opaque types referened // only through derived named types. @@ -323,7 +320,7 @@ namespace { for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); TI != E; ++TI) IncorporateType(TI->second); - + // Get types from global variables. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { @@ -331,18 +328,18 @@ namespace { if (I->hasInitializer()) IncorporateValue(I->getInitializer()); } - + // Get types from aliases. for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { IncorporateType(I->getType()); IncorporateValue(I->getAliasee()); } - + // Get types from functions. for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { IncorporateType(FI->getType()); - + for (Function::const_iterator BB = FI->begin(), E = FI->end(); BB != E;++BB) for (BasicBlock::const_iterator II = BB->begin(), @@ -356,40 +353,40 @@ namespace { } } } - + private: void IncorporateType(const Type *Ty) { // Check to see if we're already visited this type. if (!VisitedTypes.insert(Ty).second) return; - + // If this is a structure or opaque type, add a name for the type. if (((isa<StructType>(Ty) && cast<StructType>(Ty)->getNumElements()) || isa<OpaqueType>(Ty)) && !TP.hasTypeName(Ty)) { TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size()))); NumberedTypes.push_back(Ty); } - + // Recursively walk all contained types. for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) - IncorporateType(*I); + IncorporateType(*I); } - + /// IncorporateValue - This method is used to walk operand lists finding /// types hiding in constant expressions and other operands that won't be /// walked in other ways. GlobalValues, basic blocks, instructions, and /// inst operands are all explicitly enumerated. void IncorporateValue(const Value *V) { if (V == 0 || !isa<Constant>(V) || isa<GlobalValue>(V)) return; - + // Already visited? if (!VisitedConstants.insert(V).second) return; - + // Check this type. IncorporateType(V->getType()); - + // Look in operands for types. const Constant *C = cast<Constant>(V); for (Constant::const_op_iterator I = C->op_begin(), @@ -403,18 +400,18 @@ namespace { /// AddModuleTypesToPrinter - Add all of the symbolic type names for types in /// the specified module to the TypePrinter and all numbered types to it and the /// NumberedTypes table. -static void AddModuleTypesToPrinter(TypePrinting &TP, +static void AddModuleTypesToPrinter(TypePrinting &TP, std::vector<const Type*> &NumberedTypes, const Module *M) { if (M == 0) return; - + // If the module has a symbol table, take all global types and stuff their // names into the TypeNames map. const TypeSymbolTable &ST = M->getTypeSymbolTable(); for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); TI != E; ++TI) { const Type *Ty = cast<Type>(TI->second); - + // As a heuristic, don't insert pointer to primitive types, because // they are used too often to have a single useful name. if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { @@ -423,18 +420,20 @@ static void AddModuleTypesToPrinter(TypePrinting &TP, !isa<OpaqueType>(PETy)) continue; } - + // Likewise don't insert primitives either. if (Ty->isInteger() || Ty->isPrimitiveType()) continue; - + // 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); - TP.addTypeName(Ty, NameOS.str()); + raw_string_ostream NameROS(NameStr); + formatted_raw_ostream NameOS(NameROS); + PrintLLVMName(NameOS, TI->first, LocalPrefix); + NameOS.flush(); + TP.addTypeName(Ty, NameStr); } - + // Walk the entire module to find references to unnamed structure and opaque // types. This is required for correctness by opaque types (because multiple // uses of an unnamed opaque type needs to be referred to by the same ID) and @@ -464,35 +463,49 @@ namespace { /// class SlotTracker { public: - /// ValueMap - A mapping of Values to slot numbers + /// ValueMap - A mapping of Values to slot numbers. typedef DenseMap<const Value*, unsigned> ValueMap; - -private: - /// TheModule - The module for which we are holding slot numbers + +private: + /// TheModule - The module for which we are holding slot numbers. const Module* TheModule; - - /// TheFunction - The function for which we are holding slot numbers + + /// TheFunction - The function for which we are holding slot numbers. const Function* TheFunction; bool FunctionProcessed; - - /// mMap - The TypePlanes map for the module level data + + /// 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; - - /// fMap - The TypePlanes map for the function level data + + /// fMap - The TypePlanes map for the function level data. ValueMap fMap; unsigned fNext; - + + /// mdnMap - Map for MDNodes. + ValueMap mdnMap; + unsigned mdnNext; public: /// Construct from a module explicit SlotTracker(const Module *M); /// Construct from a function, starting out in incorp state. 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. int getLocalSlot(const Value *V); int getGlobalSlot(const GlobalValue *V); + int getMetadataSlot(const MDNode *N); /// If you'd like to deal with a function instead of just a module, use /// this method to get its data into the SlotTracker. @@ -506,14 +519,23 @@ public: /// will reset the state of the machine back to just the module contents. void purgeFunction(); - // Implementation Details -private: + /// MDNode map iterators. + ValueMap::iterator mdnBegin() { return mdnMap.begin(); } + ValueMap::iterator mdnEnd() { return mdnMap.end(); } + unsigned mdnSize() const { return mdnMap.size(); } + bool mdnEmpty() const { return mdnMap.empty(); } + /// This function does the actual initialization. inline void initialize(); + // Implementation Details +private: /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void CreateModuleSlot(const GlobalValue *V); - + + /// CreateMetadataSlot - Insert the specified MDNode* into the slot table. + void CreateMetadataSlot(const MDNode *N); + /// CreateFunctionSlot - Insert the specified Value* into the slot table. void CreateFunctionSlot(const Value *V); @@ -521,9 +543,15 @@ private: /// and function declarations, but not the contents of those functions. void processModule(); - /// Add all of the functions arguments, basic blocks, and instructions + /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); + /// 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 }; @@ -534,27 +562,27 @@ private: static SlotTracker *createSlotTracker(const Value *V) { if (const Argument *FA = dyn_cast<Argument>(V)) return new SlotTracker(FA->getParent()); - + if (const Instruction *I = dyn_cast<Instruction>(V)) return new SlotTracker(I->getParent()->getParent()); - + if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) return new SlotTracker(BB->getParent()); - + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) return new SlotTracker(GV->getParent()); - + if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) - return new SlotTracker(GA->getParent()); - + return new SlotTracker(GA->getParent()); + if (const Function *Func = dyn_cast<Function>(V)) return new SlotTracker(Func); - + return 0; } #if 0 -#define ST_DEBUG(X) cerr << X +#define ST_DEBUG(X) errs() << X #else #define ST_DEBUG(X) #endif @@ -562,14 +590,27 @@ static SlotTracker *createSlotTracker(const Value *V) { // Module level constructor. Causes the contents of the Module (sans functions) // to be added to the slot table. SlotTracker::SlotTracker(const Module *M) - : TheModule(M), TheFunction(0), FunctionProcessed(false), mNext(0), fNext(0) { + : TheModule(M), TheFunction(0), FunctionProcessed(false), TheMDNode(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), - 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), + 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() { @@ -577,60 +618,120 @@ inline void SlotTracker::initialize() { processModule(); TheModule = 0; ///< Prevent re-processing next time we're called. } - + if (TheFunction && !FunctionProcessed) processFunction(); + + if (TheMDNode) + processMDNode(); + + if (TheNamedMDNode) + processNamedMDNode(); } // Iterate through all the global variables, functions, and global // variable initializers and create slots for them. void SlotTracker::processModule() { ST_DEBUG("begin processModule!\n"); - + // Add all of the unnamed global variables to the value table. for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) - if (!I->hasName()) + E = TheModule->global_end(); I != E; ++I) { + if (!I->hasName()) CreateModuleSlot(I); - + if (I->hasInitializer()) { + if (MDNode *N = dyn_cast<MDNode>(I->getInitializer())) + CreateMetadataSlot(N); + } + } + + // 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<MDNode>(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) if (!I->hasName()) CreateModuleSlot(I); - + ST_DEBUG("end processModule!\n"); } - // Process the arguments, basic blocks, and instructions of a function. void SlotTracker::processFunction() { ST_DEBUG("begin processFunction!\n"); fNext = 0; - + // Add all the function arguments with no names. for(Function::const_arg_iterator AI = TheFunction->arg_begin(), AE = TheFunction->arg_end(); AI != AE; ++AI) if (!AI->hasName()) CreateFunctionSlot(AI); - + ST_DEBUG("Inserting Instructions:\n"); - + + MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); + // Add all of the basic blocks and instructions with no names. for (Function::const_iterator BB = TheFunction->begin(), E = TheFunction->end(); BB != E; ++BB) { if (!BB->hasName()) CreateFunctionSlot(BB); - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (I->getType() != Type::VoidTy && !I->hasName()) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; + ++I) { + if (I->getType() != Type::getVoidTy(TheFunction->getContext()) && + !I->hasName()) CreateFunctionSlot(I); + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) + CreateMetadataSlot(N); + + // Process metadata attached with this instruction. + const MetadataContext::MDMapTy *MDs = TheMetadata.getMDs(I); + if (MDs) + for (MetadataContext::MDMapTy::const_iterator MI = MDs->begin(), + ME = MDs->end(); MI != ME; ++MI) + if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second)) + CreateMetadataSlot(MDN); + } } - + FunctionProcessed = true; - + ST_DEBUG("end processFunction!\n"); } +/// processMDNode - Process TheMDNode. +void SlotTracker::processMDNode() { + ST_DEBUG("begin processMDNode!\n"); + mdnNext = 0; + CreateMetadataSlot(TheMDNode); + TheMDNode = 0; + 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<MDNode>(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. @@ -646,20 +747,30 @@ void SlotTracker::purgeFunction() { int SlotTracker::getGlobalSlot(const GlobalValue *V) { // Check for uninitialized state and do lazy initialization. initialize(); - + // Find the type plane in the module map ValueMap::iterator MI = mMap.find(V); return MI == mMap.end() ? -1 : (int)MI->second; } +/// getGlobalSlot - Get the slot number of a MDNode. +int SlotTracker::getMetadataSlot(const MDNode *N) { + // Check for uninitialized state and do lazy initialization. + initialize(); + + // Find the type plane in the module map + ValueMap::iterator MI = mdnMap.find(N); + return MI == mdnMap.end() ? -1 : (int)MI->second; +} + /// getLocalSlot - Get the slot number for a value that is local to a function. int SlotTracker::getLocalSlot(const Value *V) { assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!"); - + // Check for uninitialized state and do lazy initialization. initialize(); - + ValueMap::iterator FI = fMap.find(V); return FI == fMap.end() ? -1 : (int)FI->second; } @@ -668,12 +779,13 @@ int SlotTracker::getLocalSlot(const Value *V) { /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void SlotTracker::CreateModuleSlot(const GlobalValue *V) { assert(V && "Can't insert a null Value into SlotTracker!"); - assert(V->getType() != Type::VoidTy && "Doesn't need a slot!"); + assert(V->getType() != Type::getVoidTy(V->getContext()) && + "Doesn't need a slot!"); assert(!V->hasName() && "Doesn't need a slot!"); - + unsigned DestSlot = mNext++; mMap[V] = DestSlot; - + ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" << DestSlot << " ["); // G = Global, F = Function, A = Alias, o = other @@ -682,28 +794,45 @@ void SlotTracker::CreateModuleSlot(const GlobalValue *V) { (isa<GlobalAlias>(V) ? 'A' : 'o'))) << "]\n"); } - /// CreateSlot - Create a new slot for the specified value if it has no name. void SlotTracker::CreateFunctionSlot(const Value *V) { - assert(V->getType() != Type::VoidTy && !V->hasName() && - "Doesn't need a slot!"); - + assert(V->getType() != Type::getVoidTy(TheFunction->getContext()) && + !V->hasName() && "Doesn't need a slot!"); + unsigned DestSlot = fNext++; fMap[V] = DestSlot; - + // G = Global, F = Function, o = other ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" << DestSlot << " [o]\n"); -} +} +/// CreateModuleSlot - Insert the specified MDNode* into the slot table. +void SlotTracker::CreateMetadataSlot(const MDNode *N) { + assert(N && "Can't insert a null Value into SlotTracker!"); + + ValueMap::iterator I = mdnMap.find(N); + if (I != mdnMap.end()) + return; + unsigned DestSlot = mdnNext++; + mdnMap[N] = DestSlot; + + for (MDNode::const_elem_iterator MDI = N->elem_begin(), + MDE = N->elem_end(); MDI != MDE; ++MDI) { + const Value *TV = *MDI; + if (TV) + if (const MDNode *N2 = dyn_cast<MDNode>(TV)) + CreateMetadataSlot(N2); + } +} //===----------------------------------------------------------------------===// // AsmWriter Implementation //===----------------------------------------------------------------------===// static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, - TypePrinting &TypePrinter, + TypePrinting *TypePrinter, SlotTracker *Machine); @@ -741,17 +870,93 @@ static const char *getPredicateText(unsigned predicate) { return pred; } +static void WriteMDNodeComment(const MDNode *Node, + formatted_raw_ostream &Out) { + if (Node->getNumElements() < 1) + return; + ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getElement(0)); + if (!CI) return; + unsigned Val = CI->getZExtValue(); + unsigned Tag = Val & ~LLVMDebugVersionMask; + if (Val >= LLVMDebugVersion) { + if (Tag == dwarf::DW_TAG_auto_variable) + Out << "; [ DW_TAG_auto_variable ]"; + else if (Tag == dwarf::DW_TAG_arg_variable) + Out << "; [ DW_TAG_arg_variable ]"; + else if (Tag == dwarf::DW_TAG_return_variable) + Out << "; [ DW_TAG_return_variable ]"; + else if (Tag == dwarf::DW_TAG_vector_type) + Out << "; [ DW_TAG_vector_type ]"; + else if (Tag == dwarf::DW_TAG_user_base) + Out << "; [ DW_TAG_user_base ]"; + else + Out << "; [" << dwarf::TagString(Tag) << " ]"; + } +} + +static void WriteMDNodes(formatted_raw_ostream &Out, TypePrinting &TypePrinter, + SlotTracker &Machine) { + SmallVector<const MDNode *, 16> Nodes; + Nodes.resize(Machine.mdnSize()); + for (SlotTracker::ValueMap::iterator I = + Machine.mdnBegin(), E = Machine.mdnEnd(); I != E; ++I) + Nodes[I->second] = cast<MDNode>(I->first); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Out << '!' << i << " = metadata "; + const MDNode *Node = Nodes[i]; + Out << "!{"; + for (MDNode::const_elem_iterator NI = Node->elem_begin(), + NE = Node->elem_end(); NI != NE;) { + const Value *V = *NI; + if (!V) + Out << "null"; + else if (const MDNode *N = dyn_cast<MDNode>(V)) { + Out << "metadata "; + Out << '!' << Machine.getMetadataSlot(N); + } + else { + TypePrinter.print((*NI)->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, *NI, &TypePrinter, &Machine); + } + if (++NI != NE) + Out << ", "; + } + + Out << "}"; + WriteMDNodeComment(Node, Out); + Out << "\n"; + } +} + +static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { + if (const OverflowingBinaryOperator *OBO = + dyn_cast<OverflowingBinaryOperator>(U)) { + if (OBO->hasNoUnsignedWrap()) + Out << " nuw"; + if (OBO->hasNoSignedWrap()) + Out << " nsw"; + } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) { + if (Div->isExact()) + Out << " exact"; + } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(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<ConstantInt>(CV)) { - if (CI->getType() == Type::Int1Ty) { + if (CI->getType() == Type::getInt1Ty(CV->getContext())) { Out << (CI->getZExtValue() ? "true" : "false"); return; } Out << CI->getValue(); return; } - + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble || &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { @@ -789,14 +994,14 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, APFloat apf = CFP->getValueAPF(); // Floats are represented in ASCII IR as double, convert. if (!isDouble) - apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, + apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); - Out << "0x" << - utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), + Out << "0x" << + utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), Buffer+40); return; } - + // Some form of long double. These appear as a magic letter identifying // the type, then a fixed number of hex digits. Out << "0x"; @@ -827,7 +1032,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) Out << 'M'; else - assert(0 && "Unsupported floating point type"); + llvm_unreachable("Unsupported floating point type"); // api needed to prevent premature destruction APInt api = CFP->getValueAPF().bitcastToAPInt(); const uint64_t* p = api.getRawData(); @@ -849,12 +1054,12 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } return; } - + if (isa<ConstantAggregateZero>(CV)) { Out << "zeroinitializer"; return; } - + if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) { // As a special case, print the array as a string if it is an array of // i8 with ConstantInt values. @@ -870,19 +1075,19 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinter.print(ETy, Out); Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(0), - TypePrinter, Machine); + &TypePrinter, Machine); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CA->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine); } } Out << ']'; } return; } - + if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) { if (CS->getType()->isPacked()) Out << '<'; @@ -893,24 +1098,24 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinter.print(CS->getOperand(0)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, CS->getOperand(0), TypePrinter, Machine); + WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine); for (unsigned i = 1; i < N; i++) { Out << ", "; TypePrinter.print(CS->getOperand(i)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, CS->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine); } Out << ' '; } - + Out << '}'; if (CS->getType()->isPacked()) Out << '>'; return; } - + if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { const Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && @@ -918,36 +1123,35 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << '<'; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(0), TypePrinter, Machine); + WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine); for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine); } Out << '>'; return; } - + if (isa<ConstantPointerNull>(CV)) { Out << "null"; return; } - + if (isa<UndefValue>(CV)) { Out << "undef"; return; } - - if (const MDString *S = dyn_cast<MDString>(CV)) { - Out << "!\""; - PrintEscapedString(S->begin(), S->size(), Out); - Out << '"'; + + if (const MDNode *Node = dyn_cast<MDNode>(CV)) { + Out << "!" << Machine->getMetadataSlot(Node); return; } if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { Out << CE->getOpcodeName(); + WriteOptimizationInfo(Out, CE); if (CE->isCompare()) Out << ' ' << getPredicateText(CE->getPredicate()); Out << " ("; @@ -955,7 +1159,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { TypePrinter.print((*OI)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, *OI, TypePrinter, Machine); + WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine); if (OI+1 != CE->op_end()) Out << ", "; } @@ -974,7 +1178,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ')'; return; } - + Out << "<placeholder or erroneous Constant>"; } @@ -984,23 +1188,26 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, /// the whole instruction that generated it. /// static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, - TypePrinting &TypePrinter, + TypePrinting *TypePrinter, SlotTracker *Machine) { if (V->hasName()) { PrintLLVMName(Out, V); return; } - + const Constant *CV = dyn_cast<Constant>(V); if (CV && !isa<GlobalValue>(CV)) { - WriteConstantInt(Out, CV, TypePrinter, Machine); + assert(TypePrinter && "Constants require TypePrinting!"); + WriteConstantInt(Out, CV, *TypePrinter, Machine); return; } - + if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { Out << "asm "; if (IA->hasSideEffects()) Out << "sideeffect "; + if (IA->isMsAsm()) + Out << "msasm "; Out << '"'; PrintEscapedString(IA->getAsmString(), Out); Out << "\", \""; @@ -1008,7 +1215,24 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << '"'; return; } - + + if (const MDNode *N = dyn_cast<MDNode>(V)) { + Out << '!' << Machine->getMetadataSlot(N); + return; + } + + if (const MDString *MDS = dyn_cast<MDString>(V)) { + Out << "!\""; + PrintEscapedString(MDS->getString(), Out); + Out << '"'; + return; + } + + if (V->getValueID() == Value::PseudoSourceValueVal) { + V->print(Out); + return; + } + char Prefix = '%'; int Slot; if (Machine) { @@ -1027,30 +1251,29 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, } else { Slot = Machine->getLocalSlot(V); } + delete Machine; } else { Slot = -1; } - delete Machine; } - + if (Slot != -1) Out << Prefix << Slot; else Out << "<badref>"; } -/// 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. -/// -void llvm::WriteAsOperand(std::ostream &Out, const Value *V, bool PrintType, - const Module *Context) { - raw_os_ostream OS(Out); - WriteAsOperand(OS, V, PrintType, Context); -} +void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, + bool PrintType, const Module *Context) { + + // Fast path: Don't construct and populate a TypePrinting object if we + // won't be needing any types printed. + if (!PrintType && + (!isa<Constant>(V) || V->hasName() || isa<GlobalValue>(V))) { + WriteAsOperandInternal(Out, V, 0, 0); + return; + } -void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType, - const Module *Context) { if (Context == 0) Context = getModuleFromVal(V); TypePrinting TypePrinter; @@ -1061,32 +1284,40 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType, Out << ' '; } - WriteAsOperandInternal(Out, V, TypePrinter, 0); + WriteAsOperandInternal(Out, V, &TypePrinter, 0); } - namespace { class AssemblyWriter { - raw_ostream &Out; + formatted_raw_ostream &Out; SlotTracker &Machine; const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; std::vector<const Type*> NumberedTypes; + DenseMap<unsigned, const char *> MDNames; - // Each MDNode is assigned unique MetadataIDNo. - std::map<const MDNode *, unsigned> MDNodes; - unsigned MetadataIDNo; public: - inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M, + inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, AssemblyAnnotationWriter *AAW) - : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) { + : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); + // FIXME: Provide MDPrinter + if (M) { + MetadataContext &TheMetadata = M->getContext().getMetadata(); + const StringMap<unsigned> *Names = TheMetadata.getHandlerNames(); + for (StringMapConstIterator<unsigned> I = Names->begin(), + E = Names->end(); I != E; ++I) { + const StringMapEntry<unsigned> &Entry = *I; + MDNames[I->second] = Entry.getKeyData(); + } + } } void write(const Module *M) { printModule(M); } - + void write(const GlobalValue *G) { if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) printGlobal(GV); @@ -1095,17 +1326,14 @@ public: else if (const Function *F = dyn_cast<Function>(G)) printFunction(F); else - assert(0 && "Unknown global"); + llvm_unreachable("Unknown global"); } - + void write(const BasicBlock *BB) { printBasicBlock(BB); } void write(const Instruction *I) { printInstruction(*I); } void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, Attributes Attrs); - void printMDNode(const MDNode *Node, bool StandAlone); - - const Module* getModule() { return TheModule; } private: void printModule(const Module *M); @@ -1132,11 +1360,11 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { TypePrinter.print(Operand->getType(), Out); Out << ' '; } - WriteAsOperandInternal(Out, Operand, TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } } -void AssemblyWriter::writeParamOperand(const Value *Operand, +void AssemblyWriter::writeParamOperand(const Value *Operand, Attributes Attrs) { if (Operand == 0) { Out << "<null operand!>"; @@ -1148,7 +1376,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, Out << ' ' << Attribute::getAsString(Attrs); Out << ' '; // Print the operand - WriteAsOperandInternal(Out, Operand, TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } } @@ -1169,6 +1397,7 @@ void AssemblyWriter::printModule(const Module *M) { std::string Asm = M->getModuleInlineAsm(); size_t CurPos = 0; size_t NewLine = Asm.find_first_of('\n', CurPos); + Out << '\n'; while (NewLine != std::string::npos) { // We found a newline, print the portion of the asm string from the // last newline up to this newline. @@ -1183,11 +1412,12 @@ void AssemblyWriter::printModule(const Module *M) { PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out); Out << "\"\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 << '\n'; Out << "deplibs = [ "; while (LI != LE) { Out << '"' << *LI << '"'; @@ -1195,16 +1425,19 @@ void AssemblyWriter::printModule(const Module *M) { if (LI != LE) Out << ", "; } - Out << " ]\n"; + Out << " ]"; } // Loop over the symbol table, emitting all id'd types. + if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n'; printTypeSymbolTable(M->getTypeSymbolTable()); + // Output all globals. + if (!M->global_empty()) Out << '\n'; for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) printGlobal(I); - + // Output all aliases. if (!M->alias_empty()) Out << "\n"; for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); @@ -1214,36 +1447,55 @@ void AssemblyWriter::printModule(const Module *M) { // Output all of the functions. for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) printFunction(I); + + // Output named metadata. + if (!M->named_metadata_empty()) Out << '\n'; + 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<MDNode>(NMD->getElement(i)); + Out << '!' << Machine.getMetadataSlot(MD); + } + Out << "}\n"; + } + + // Output metadata. + if (!Machine.mdnEmpty()) Out << '\n'; + WriteMDNodes(Out, TypePrinter, Machine); } -static void PrintLinkage(GlobalValue::LinkageTypes LT, raw_ostream &Out) { +static void PrintLinkage(GlobalValue::LinkageTypes LT, + formatted_raw_ostream &Out) { switch (LT) { - case GlobalValue::PrivateLinkage: Out << "private "; break; - case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::ExternalLinkage: break; + case GlobalValue::PrivateLinkage: Out << "private "; break; + case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break; + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; + case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; + case GlobalValue::WeakAnyLinkage: Out << "weak "; break; + case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; + case GlobalValue::CommonLinkage: Out << "common "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; + case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; + case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; case GlobalValue::AvailableExternallyLinkage: Out << "available_externally "; break; - case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; - case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; - case GlobalValue::WeakAnyLinkage: Out << "weak "; break; - case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; - case GlobalValue::CommonLinkage: Out << "common "; break; - case GlobalValue::AppendingLinkage: Out << "appending "; break; - case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; - case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; - case GlobalValue::ExternalLinkage: break; case GlobalValue::GhostLinkage: - Out << "GhostLinkage not allowed in AsmWriter!\n"; - abort(); + llvm_unreachable("GhostLinkage not allowed in AsmWriter!"); } } static void PrintVisibility(GlobalValue::VisibilityTypes Vis, - raw_ostream &Out) { + formatted_raw_ostream &Out) { switch (Vis) { - default: assert(0 && "Invalid visibility style!"); + default: llvm_unreachable("Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; case GlobalValue::ProtectedVisibility: Out << "protected "; break; @@ -1251,36 +1503,12 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { - if (GV->hasInitializer()) - // If GV is initialized using Metadata then separate out metadata - // operands used by the initializer. Note, MDNodes are not cyclic. - if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) { - SmallVector<const MDNode *, 4> WorkList; - // Collect MDNodes used by the initializer. - for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); - I != E; ++I) { - const Value *TV = *I; - if (TV) - if (const MDNode *NN = dyn_cast<MDNode>(TV)) - WorkList.push_back(NN); - } - - // Print MDNodes used by the initializer. - while (!WorkList.empty()) { - const MDNode *N = WorkList.back(); WorkList.pop_back(); - printMDNode(N, true); - Out << '\n'; - } - } - - if (GV->hasName()) { - PrintLLVMName(Out, GV); - Out << " = "; - } + WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine); + Out << " = "; if (!GV->hasInitializer() && GV->hasExternalLinkage()) Out << "external "; - + PrintLinkage(GV->getLinkage(), Out); PrintVisibility(GV->getVisibility(), Out); @@ -1292,12 +1520,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasInitializer()) { Out << ' '; - if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) - printMDNode(N, false); - else - writeOperand(GV->getInitializer(), false); + writeOperand(GV->getInitializer(), false); } - + if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; if (GV->getAlignment()) @@ -1307,47 +1532,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { Out << '\n'; } -void AssemblyWriter::printMDNode(const MDNode *Node, - bool StandAlone) { - std::map<const MDNode *, unsigned>::iterator MI = MDNodes.find(Node); - // If this node is already printed then just refer it using its Metadata - // id number. - if (MI != MDNodes.end()) { - if (!StandAlone) - Out << "!" << MI->second; - return; - } - - if (StandAlone) { - // Print standalone MDNode. - // !42 = !{ ... } - Out << "!" << MetadataIDNo << " = "; - Out << "constant metadata "; - } - - Out << "!{"; - for (MDNode::const_elem_iterator I = Node->elem_begin(), E = Node->elem_end(); - I != E;) { - const Value *TV = *I; - if (!TV) - Out << "null"; - else if (const MDNode *N = dyn_cast<MDNode>(TV)) { - TypePrinter.print(N->getType(), Out); - Out << ' '; - printMDNode(N, StandAlone); - } - else if (!*I) - Out << "null"; - else - writeOperand(*I, true); - if (++I != E) - Out << ", "; - } - Out << "}"; - - MDNodes[Node] = MetadataIDNo++; -} - void AssemblyWriter::printAlias(const GlobalAlias *GA) { // Don't crash when dumping partially built GA if (!GA->hasName()) @@ -1361,9 +1545,9 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << "alias "; PrintLinkage(GA->getLinkage(), Out); - + const Constant *Aliasee = GA->getAliasee(); - + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { TypePrinter.print(GV->getType(), Out); Out << ' '; @@ -1372,7 +1556,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { TypePrinter.print(F->getFunctionType(), Out); Out << "* "; - WriteAsOperandInternal(Out, F, TypePrinter, &Machine); + WriteAsOperandInternal(Out, F, &TypePrinter, &Machine); } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) { TypePrinter.print(GA->getType(), Out); Out << ' '; @@ -1385,7 +1569,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { "Unsupported aliasee"); writeOperand(CE, false); } - + printInfoComment(*GA); Out << '\n'; } @@ -1393,19 +1577,18 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { // Emit all numbered types. for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) { - Out << "\ttype "; - + Out << '%' << i << " = type "; + // Make sure we print out at least one level of the type structure, so // that we do not get %2 = type %2 TypePrinter.printAtLeastOneLevel(NumberedTypes[i], Out); - Out << "\t\t; type %" << i << '\n'; + Out << '\n'; } - + // Print the named types. 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 @@ -1427,7 +1610,7 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "declare "; else Out << "define "; - + PrintLinkage(F->getLinkage(), Out); PrintVisibility(F->getVisibility(), Out); @@ -1451,7 +1634,7 @@ void AssemblyWriter::printFunction(const Function *F) { Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' '; TypePrinter.print(F->getReturnType(), Out); Out << ' '; - WriteAsOperandInternal(Out, F, TypePrinter, &Machine); + WriteAsOperandInternal(Out, F, &TypePrinter, &Machine); Out << '('; Machine.incorporateFunction(F); @@ -1472,10 +1655,10 @@ void AssemblyWriter::printFunction(const Function *F) { for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { // Insert commas as we go... the first arg doesn't get a comma if (i) Out << ", "; - + // Output type... TypePrinter.print(FT->getParamType(i), Out); - + Attributes ArgAttrs = Attrs.getParamAttributes(i+1); if (ArgAttrs != Attribute::None) Out << ' ' << Attribute::getAsString(ArgAttrs); @@ -1515,7 +1698,7 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out /// -void AssemblyWriter::printArgument(const Argument *Arg, +void AssemblyWriter::printArgument(const Argument *Arg, Attributes Attrs) { // Output type... TypePrinter.print(Arg->getType(), Out); @@ -1536,7 +1719,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; <label>:"; @@ -1547,13 +1730,15 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { Out << "<badref>"; } - if (BB->getParent() == 0) - Out << "\t\t; Error: Block without parent!"; - else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block? + if (BB->getParent() == 0) { + Out.PadToColumn(50); + Out << "; Error: Block without parent!"; + } else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block? // Output predecessors for the block... - Out << "\t\t;"; + Out.PadToColumn(50); + Out << ";"; pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB); - + if (PI == PE) { Out << " No predecessors!"; } else { @@ -1571,8 +1756,10 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out); // Output all of the instructions in the basic block... - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { printInstruction(*I); + Out << '\n'; + } if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } @@ -1582,23 +1769,11 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { /// which slot it occupies. /// void AssemblyWriter::printInfoComment(const Value &V) { - if (V.getType() != Type::VoidTy) { - Out << "\t\t; <"; + if (V.getType() != Type::getVoidTy(V.getContext())) { + Out.PadToColumn(50); + Out << "; <"; TypePrinter.print(V.getType(), Out); - Out << '>'; - - if (!V.hasName() && !isa<Instruction>(V)) { - int SlotNum; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(&V)) - SlotNum = Machine.getGlobalSlot(GV); - else - SlotNum = Machine.getLocalSlot(&V); - if (SlotNum == -1) - Out << ":<badref>"; - else - Out << ':' << SlotNum; // Print out the def slot taken. - } - Out << " [#uses=" << V.getNumUses() << ']'; // Output # uses + Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses } } @@ -1606,13 +1781,14 @@ void AssemblyWriter::printInfoComment(const Value &V) { void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); - Out << '\t'; + // Print out indentation for an instruction. + Out << " "; // Print out name if it exists... if (I.hasName()) { PrintLLVMName(Out, &I); Out << " = "; - } else if (I.getType() != Type::VoidTy) { + } else if (I.getType() != Type::getVoidTy(I.getContext())) { // Print out the def slot taken. int SlotNum = Machine.getLocalSlot(&I); if (SlotNum == -1) @@ -1633,6 +1809,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Print out the opcode... Out << I.getOpcodeName(); + // Print out optimization information. + WriteOptimizationInfo(Out, &I); + // Print out the compare instruction predicates if (const CmpInst *CI = dyn_cast<CmpInst>(&I)) Out << ' ' << getPredicateText(CI->getPredicate()); @@ -1659,12 +1838,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " ["; for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) { - Out << "\n\t\t"; + Out << "\n "; writeOperand(I.getOperand(op ), true); Out << ", "; writeOperand(I.getOperand(op+1), true); } - Out << "\n\t]"; + Out << "\n ]"; } else if (isa<PHINode>(I)) { Out << ' '; TypePrinter.print(I.getType(), Out); @@ -1781,7 +1960,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.getFnAttributes() != Attribute::None) Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); - Out << "\n\t\t\tto "; + Out << "\n to "; writeOperand(II->getNormalDest(), true); Out << " unwind "; writeOperand(II->getUnwindDest(), true); @@ -1789,7 +1968,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) { Out << ' '; TypePrinter.print(AI->getType()->getElementType(), Out); - if (AI->isArrayAllocation()) { + if (!AI->getArraySize() || AI->isArrayAllocation()) { Out << ", "; writeOperand(AI->getArraySize(), true); } @@ -1845,7 +2024,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(i), PrintAllTypes); } } - + // Print post operand alignment for load/store if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) { Out << ", align " << cast<LoadInst>(I).getAlignment(); @@ -1853,8 +2032,18 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ", align " << cast<StoreInst>(I).getAlignment(); } + // Print Metadata info + if (!MDNames.empty()) { + MetadataContext &TheMetadata = I.getContext().getMetadata(); + const MetadataContext::MDMapTy *MDMap = TheMetadata.getMDs(&I); + if (MDMap) + for (MetadataContext::MDMapTy::const_iterator MI = MDMap->begin(), + ME = MDMap->end(); MI != ME; ++MI) + if (const MDNode *MD = dyn_cast_or_null<MDNode>(MI->second)) + Out << ", !" << MDNames[MI->first] + << " !" << Machine.getMetadataSlot(MD); + } printInfoComment(I); - Out << '\n'; } @@ -1862,21 +2051,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // External Interface declarations //===----------------------------------------------------------------------===// -void Module::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const { - raw_os_ostream OS(o); - print(OS, AAW); -} -void Module::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { +void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(this); + formatted_raw_ostream OS(ROS); AssemblyWriter W(OS, SlotTable, this, AAW); W.write(this); } -void Type::print(std::ostream &o) const { - raw_os_ostream OS(o); - print(OS); -} - void Type::print(raw_ostream &OS) const { if (this == 0) { OS << "<null Type>"; @@ -1885,12 +2066,12 @@ void Type::print(raw_ostream &OS) const { TypePrinting().print(this, OS); } -void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { +void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { if (this == 0) { - OS << "printing a <null> value\n"; + ROS << "printing a <null> value\n"; return; } - + formatted_raw_ostream OS(ROS); if (const Instruction *I = dyn_cast<Instruction>(this)) { const Function *F = I->getParent() ? I->getParent()->getParent() : 0; SlotTracker SlotTable(F); @@ -1905,14 +2086,33 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(GV->getParent()); AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW); W.write(GV); - } else if (const MDNode *N = dyn_cast<MDNode>(this)) { + } else if (const MDString *MDS = dyn_cast<MDString>(this)) { TypePrinting TypePrinter; - TypePrinter.print(N->getType(), OS); + TypePrinter.print(MDS->getType(), OS); OS << ' '; - // FIXME: Do we need a slot tracker for metadata ? - SlotTracker SlotTable((const Function *)NULL); - AssemblyWriter W(OS, SlotTable, NULL, AAW); - W.printMDNode(N, false); + OS << "!\""; + PrintEscapedString(MDS->getString(), OS); + OS << '"'; + } else if (const MDNode *N = dyn_cast<MDNode>(this)) { + SlotTracker SlotTable(N); + TypePrinting TypePrinter; + SlotTable.initialize(); + WriteMDNodes(OS, TypePrinter, SlotTable); + } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) { + SlotTracker SlotTable(N); + TypePrinting TypePrinter; + SlotTable.initialize(); + OS << "!" << N->getName() << " = !{"; + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { + if (i) OS << ", "; + MDNode *MD = dyn_cast_or_null<MDNode>(N->getElement(i)); + if (MD) + OS << '!' << SlotTable.getMetadataSlot(MD); + else + OS << "null"; + } + OS << "}\n"; + WriteMDNodes(OS, TypePrinter, SlotTable); } else if (const Constant *C = dyn_cast<Constant>(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); @@ -1924,13 +2124,15 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { } else if (isa<InlineAsm>(this)) { WriteAsOperand(OS, this, true, 0); } else { - assert(0 && "Unknown value to print out!"); + // Otherwise we don't know what it is. Call the virtual function to + // allow a subclass to print itself. + printCustom(OS); } } -void Value::print(std::ostream &O, AssemblyAnnotationWriter *AAW) const { - raw_os_ostream OS(O); - print(OS, AAW); +// Value::printCustom - subclasses should override this to implement printing. +void Value::printCustom(raw_ostream &OS) const { + llvm_unreachable("Unknown value to print out!"); } // Value::dump - allow easy printing of Values from the debugger. |