X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=6c1aa5ed10c6f8d971344019522060606fb0bb16;hb=46510a73e977273ec67747eb34cbdb43f815e451;hp=fb1b1ac41c26e6d98355d77d201a68f733ebf43b;hpb=b5681b22937440dcb8007f4b125f3325d6341fe0;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index fb1b1ac41c2..6c1aa5ed10c 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -17,21 +17,22 @@ #include "llvm/Assembly/Writer.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Assembly/AsmAnnotationWriter.h" +#include "llvm/LLVMContext.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" -#include "llvm/Instruction.h" -#include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Operator.h" -#include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -59,9 +60,11 @@ static const Module *getModuleFromVal(const Value *V) { const Function *M = I->getParent() ? I->getParent()->getParent() : 0; return M ? M->getParent() : 0; } - + if (const GlobalValue *GV = dyn_cast(V)) return GV->getParent(); + if (const NamedMDNode *NMD = dyn_cast(V)) + return NMD->getParent(); return 0; } @@ -224,19 +227,36 @@ void TypePrinting::CalcTypeName(const Type *Ty, const StructType *STy = cast(Ty); if (STy->isPacked()) OS << '<'; - OS << "{ "; + OS << '{'; for (StructType::element_iterator I = STy->element_begin(), E = STy->element_end(); I != E; ++I) { + OS << ' '; CalcTypeName(*I, TypeStack, OS); - if (next(I) != STy->element_end()) + if (next(I) == STy->element_end()) + OS << ' '; + else OS << ','; - OS << ' '; } OS << '}'; if (STy->isPacked()) OS << '>'; break; } + case Type::UnionTyID: { + const UnionType *UTy = cast(Ty); + OS << "union {"; + for (StructType::element_iterator I = UTy->element_begin(), + E = UTy->element_end(); I != E; ++I) { + OS << ' '; + CalcTypeName(*I, TypeStack, OS); + if (next(I) == UTy->element_end()) + OS << ' '; + else + OS << ','; + } + OS << '}'; + break; + } case Type::PointerTyID: { const PointerType *PTy = cast(Ty); CalcTypeName(PTy->getElementType(), TypeStack, OS); @@ -361,8 +381,8 @@ namespace { return; // If this is a structure or opaque type, add a name for the type. - if (((isa(Ty) && cast(Ty)->getNumElements()) - || isa(Ty)) && !TP.hasTypeName(Ty)) { + if (((Ty->isStructTy() && cast(Ty)->getNumElements()) + || Ty->isOpaqueTy()) && !TP.hasTypeName(Ty)) { TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size()))); NumberedTypes.push_back(Ty); } @@ -416,13 +436,13 @@ static void AddModuleTypesToPrinter(TypePrinting &TP, // they are used too often to have a single useful name. if (const PointerType *PTy = dyn_cast(Ty)) { const Type *PETy = PTy->getElementType(); - if ((PETy->isPrimitiveType() || PETy->isInteger()) && - !isa(PETy)) + if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) && + !PETy->isOpaqueTy()) continue; } // Likewise don't insert primitives either. - if (Ty->isInteger() || Ty->isPrimitiveType()) + if (Ty->isIntegerTy() || Ty->isPrimitiveType()) continue; // Get the name as a string and insert it into TypeNames. @@ -474,12 +494,6 @@ private: const Function* TheFunction; bool FunctionProcessed; - /// 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; @@ -489,17 +503,13 @@ private: unsigned fNext; /// mdnMap - Map for MDNodes. - ValueMap mdnMap; + DenseMap 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. @@ -520,10 +530,11 @@ public: void purgeFunction(); /// 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(); } + typedef DenseMap::iterator mdn_iterator; + mdn_iterator mdn_begin() { return mdnMap.begin(); } + mdn_iterator mdn_end() { return mdnMap.end(); } + unsigned mdn_size() const { return mdnMap.size(); } + bool mdn_empty() const { return mdnMap.empty(); } /// This function does the actual initialization. inline void initialize(); @@ -546,12 +557,6 @@ private: /// 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 }; @@ -578,11 +583,14 @@ static SlotTracker *createSlotTracker(const Value *V) { if (const Function *Func = dyn_cast(V)) return new SlotTracker(Func); + if (isa(V)) + return new SlotTracker((Function *)0); + return 0; } #if 0 -#define ST_DEBUG(X) errs() << X +#define ST_DEBUG(X) dbgs() << X #else #define ST_DEBUG(X) #endif @@ -590,27 +598,15 @@ 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), TheMDNode(0), - TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { + : TheModule(M), TheFunction(0), FunctionProcessed(false), + 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), 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) { + mNext(0), fNext(0), mdnNext(0) { } inline void SlotTracker::initialize() { @@ -621,12 +617,6 @@ inline void SlotTracker::initialize() { if (TheFunction && !FunctionProcessed) processFunction(); - - if (TheMDNode) - processMDNode(); - - if (TheNamedMDNode) - processNamedMDNode(); } // Iterate through all the global variables, functions, and global @@ -639,10 +629,6 @@ void SlotTracker::processModule() { E = TheModule->global_end(); I != E; ++I) { if (!I->hasName()) CreateModuleSlot(I); - if (I->hasInitializer()) { - if (MDNode *N = dyn_cast(I->getInitializer())) - CreateMetadataSlot(N); - } } // Add metadata used by named metadata. @@ -650,9 +636,8 @@ void SlotTracker::processModule() { 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) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + if (MDNode *MD = NMD->getOperand(i)) CreateMetadataSlot(MD); } } @@ -679,28 +664,30 @@ void SlotTracker::processFunction() { ST_DEBUG("Inserting Instructions:\n"); - MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); + SmallVector, 4> MDForInst; // 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::getVoidTy(TheFunction->getContext()) && - !I->hasName()) + if (!I->getType()->isVoidTy() && !I->hasName()) CreateFunctionSlot(I); - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (MDNode *N = dyn_cast_or_null(I->getOperand(i))) - CreateMetadataSlot(N); + + // Intrinsics can directly use metadata. + if (isa(I)) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (MDNode *N = dyn_cast_or_null(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) - CreateMetadataSlot(MI->second); + I->getAllMetadata(MDForInst); + for (unsigned i = 0, e = MDForInst.size(); i != e; ++i) + CreateMetadataSlot(MDForInst[i].second); + MDForInst.clear(); } } @@ -709,28 +696,6 @@ void SlotTracker::processFunction() { 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(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. @@ -752,13 +717,13 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) { return MI == mMap.end() ? -1 : (int)MI->second; } -/// getGlobalSlot - Get the slot number of a MDNode. +/// getMetadataSlot - 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); + mdn_iterator MI = mdnMap.find(N); return MI == mdnMap.end() ? -1 : (int)MI->second; } @@ -778,8 +743,7 @@ 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::getVoidTy(V->getContext()) && - "Doesn't need a slot!"); + assert(!V->getType()->isVoidTy() && "Doesn't need a slot!"); assert(!V->hasName() && "Doesn't need a slot!"); unsigned DestSlot = mNext++; @@ -795,8 +759,7 @@ void SlotTracker::CreateModuleSlot(const GlobalValue *V) { /// CreateSlot - Create a new slot for the specified value if it has no name. void SlotTracker::CreateFunctionSlot(const Value *V) { - assert(V->getType() != Type::getVoidTy(TheFunction->getContext()) && - !V->hasName() && "Doesn't need a slot!"); + assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!"); unsigned DestSlot = fNext++; fMap[V] = DestSlot; @@ -810,19 +773,22 @@ void SlotTracker::CreateFunctionSlot(const Value *V) { void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); - ValueMap::iterator I = mdnMap.find(N); + // Don't insert if N is a function-local metadata, these are always printed + // inline. + if (N->isFunctionLocal()) + return; + + mdn_iterator I = mdnMap.find(N); if (I != mdnMap.end()) return; unsigned DestSlot = mdnNext++; mdnMap[N] = DestSlot; - for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { - const Value *TV = N->getElement(i); - if (TV) - if (const MDNode *N2 = dyn_cast(TV)) - CreateMetadataSlot(N2); - } + // Recursively add any MDNodes referenced by operands. + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) + if (const MDNode *Op = dyn_cast_or_null(N->getOperand(i))) + CreateMetadataSlot(Op); } //===----------------------------------------------------------------------===// @@ -838,95 +804,36 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, static const char *getPredicateText(unsigned predicate) { const char * pred = "unknown"; switch (predicate) { - case FCmpInst::FCMP_FALSE: pred = "false"; break; - case FCmpInst::FCMP_OEQ: pred = "oeq"; break; - case FCmpInst::FCMP_OGT: pred = "ogt"; break; - case FCmpInst::FCMP_OGE: pred = "oge"; break; - case FCmpInst::FCMP_OLT: pred = "olt"; break; - case FCmpInst::FCMP_OLE: pred = "ole"; break; - case FCmpInst::FCMP_ONE: pred = "one"; break; - case FCmpInst::FCMP_ORD: pred = "ord"; break; - case FCmpInst::FCMP_UNO: pred = "uno"; break; - case FCmpInst::FCMP_UEQ: pred = "ueq"; break; - case FCmpInst::FCMP_UGT: pred = "ugt"; break; - case FCmpInst::FCMP_UGE: pred = "uge"; break; - case FCmpInst::FCMP_ULT: pred = "ult"; break; - case FCmpInst::FCMP_ULE: pred = "ule"; break; - case FCmpInst::FCMP_UNE: pred = "une"; break; - case FCmpInst::FCMP_TRUE: pred = "true"; break; - case ICmpInst::ICMP_EQ: pred = "eq"; break; - case ICmpInst::ICMP_NE: pred = "ne"; break; - case ICmpInst::ICMP_SGT: pred = "sgt"; break; - case ICmpInst::ICMP_SGE: pred = "sge"; break; - case ICmpInst::ICMP_SLT: pred = "slt"; break; - case ICmpInst::ICMP_SLE: pred = "sle"; break; - case ICmpInst::ICMP_UGT: pred = "ugt"; break; - case ICmpInst::ICMP_UGE: pred = "uge"; break; - case ICmpInst::ICMP_ULT: pred = "ult"; break; - case ICmpInst::ICMP_ULE: pred = "ule"; break; + case FCmpInst::FCMP_FALSE: pred = "false"; break; + case FCmpInst::FCMP_OEQ: pred = "oeq"; break; + case FCmpInst::FCMP_OGT: pred = "ogt"; break; + case FCmpInst::FCMP_OGE: pred = "oge"; break; + case FCmpInst::FCMP_OLT: pred = "olt"; break; + case FCmpInst::FCMP_OLE: pred = "ole"; break; + case FCmpInst::FCMP_ONE: pred = "one"; break; + case FCmpInst::FCMP_ORD: pred = "ord"; break; + case FCmpInst::FCMP_UNO: pred = "uno"; break; + case FCmpInst::FCMP_UEQ: pred = "ueq"; break; + case FCmpInst::FCMP_UGT: pred = "ugt"; break; + case FCmpInst::FCMP_UGE: pred = "uge"; break; + case FCmpInst::FCMP_ULT: pred = "ult"; break; + case FCmpInst::FCMP_ULE: pred = "ule"; break; + case FCmpInst::FCMP_UNE: pred = "une"; break; + case FCmpInst::FCMP_TRUE: pred = "true"; break; + case ICmpInst::ICMP_EQ: pred = "eq"; break; + case ICmpInst::ICMP_NE: pred = "ne"; break; + case ICmpInst::ICMP_SGT: pred = "sgt"; break; + case ICmpInst::ICMP_SGE: pred = "sge"; break; + case ICmpInst::ICMP_SLT: pred = "slt"; break; + case ICmpInst::ICMP_SLE: pred = "sle"; break; + case ICmpInst::ICMP_UGT: pred = "ugt"; break; + case ICmpInst::ICMP_UGE: pred = "uge"; break; + case ICmpInst::ICMP_ULT: pred = "ult"; break; + case ICmpInst::ICMP_ULE: pred = "ule"; break; } return pred; } -static void WriteMDNodeComment(const MDNode *Node, - formatted_raw_ostream &Out) { - if (Node->getNumElements() < 1) - return; - ConstantInt *CI = dyn_cast_or_null(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 Nodes; - Nodes.resize(Machine.mdnSize()); - for (SlotTracker::ValueMap::iterator I = - Machine.mdnBegin(), E = Machine.mdnEnd(); I != E; ++I) - Nodes[I->second] = cast(I->first); - - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { - Out << '!' << i << " = metadata "; - const MDNode *Node = Nodes[i]; - Out << "!{"; - for (unsigned mi = 0, me = Node->getNumElements(); mi != me; ++mi) { - const Value *V = Node->getElement(mi); - if (!V) - Out << "null"; - else if (const MDNode *N = dyn_cast(V)) { - Out << "metadata "; - Out << '!' << Machine.getMetadataSlot(N); - } - else { - TypePrinter.print(V->getType(), Out); - Out << ' '; - WriteAsOperandInternal(Out, Node->getElement(mi), - &TypePrinter, &Machine); - } - if (mi + 1 != me) - Out << ", "; - } - - Out << "}"; - WriteMDNodeComment(Node, Out); - Out << "\n"; - } -} static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { if (const OverflowingBinaryOperator *OBO = @@ -947,7 +854,7 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinting &TypePrinter, SlotTracker *Machine) { if (const ConstantInt *CI = dyn_cast(CV)) { - if (CI->getType() == Type::getInt1Ty(CV->getContext())) { + if (CI->getType()->isIntegerTy(1)) { Out << (CI->getZExtValue() ? "true" : "false"); return; } @@ -967,7 +874,8 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble; double Val = isDouble ? CFP->getValueAPF().convertToDouble() : CFP->getValueAPF().convertToFloat(); - std::string StrVal = ftostr(CFP->getValueAPF()); + SmallString<128> StrVal; + raw_svector_ostream(StrVal) << Val; // 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 @@ -978,7 +886,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, (StrVal[1] >= '0' && StrVal[1] <= '9'))) { // Reparse stringized version! if (atof(StrVal.c_str()) == Val) { - Out << StrVal; + Out << StrVal.str(); return; } } @@ -1057,6 +965,15 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << "zeroinitializer"; return; } + + if (const BlockAddress *BA = dyn_cast(CV)) { + Out << "blockaddress("; + WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine); + Out << ", "; + WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine); + Out << ")"; + return; + } if (const ConstantArray *CA = dyn_cast(CV)) { // As a special case, print the array as a string if it is an array of @@ -1114,6 +1031,15 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, return; } + if (const ConstantUnion *CU = dyn_cast(CV)) { + Out << "{ "; + TypePrinter.print(CU->getOperand(0)->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, CU->getOperand(0), &TypePrinter, Machine); + Out << " }"; + return; + } + if (const ConstantVector *CP = dyn_cast(CV)) { const Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && @@ -1180,6 +1106,27 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ""; } +static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, + TypePrinting *TypePrinter, + SlotTracker *Machine) { + Out << "!{"; + for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) { + const Value *V = Node->getOperand(mi); + if (V == 0) + Out << "null"; + else { + TypePrinter->print(V->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, Node->getOperand(mi), + TypePrinter, Machine); + } + if (mi + 1 != me) + Out << ", "; + } + + Out << "}"; +} + /// 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 @@ -1215,6 +1162,14 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, } if (const MDNode *N = dyn_cast(V)) { + if (N->isFunctionLocal()) { + // Print metadata inline, not via slot reference number. + WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine); + return; + } + + if (!Machine) + Machine = createSlotTracker(V); Out << '!' << Machine->getMetadataSlot(N); return; } @@ -1226,7 +1181,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, return; } - if (V->getValueID() == Value::PseudoSourceValueVal) { + if (V->getValueID() == Value::PseudoSourceValueVal || + V->getValueID() == Value::FixedStackPseudoSourceValueVal) { V->print(Out); return; } @@ -1294,48 +1250,25 @@ class AssemblyWriter { TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; std::vector NumberedTypes; - DenseMap MDNames; - + public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW) : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); - // FIXME: Provide MDPrinter - if (M) { - MetadataContext &TheMetadata = M->getContext().getMetadata(); - SmallVector, 4> Names; - TheMetadata.getHandlerNames(Names); - for (SmallVector, 4>::iterator - I = Names.begin(), - E = Names.end(); I != E; ++I) { - MDNames[I->first] = I->second; - } - } - } - - void write(const Module *M) { printModule(M); } - - void write(const GlobalValue *G) { - if (const GlobalVariable *GV = dyn_cast(G)) - printGlobal(GV); - else if (const GlobalAlias *GA = dyn_cast(G)) - printAlias(GA); - else if (const Function *F = dyn_cast(G)) - printFunction(F); - else - llvm_unreachable("Unknown global"); } - void write(const BasicBlock *BB) { printBasicBlock(BB); } - void write(const Instruction *I) { printInstruction(*I); } + void printMDNodeBody(const MDNode *MD); + void printNamedMDNode(const NamedMDNode *NMD); + + void printModule(const Module *M); void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, Attributes Attrs); -private: - void printModule(const Module *M); + void writeAllMDNodes(); + void printTypeSymbolTable(const TypeSymbolTable &ST); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); @@ -1344,39 +1277,40 @@ private: void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); +private: // printInfoComment - Print a little comment after the instruction indicating // which slot it occupies. void printInfoComment(const Value &V); }; } // end of anonymous namespace - void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { if (Operand == 0) { Out << ""; - } else { - if (PrintType) { - TypePrinter.print(Operand->getType(), Out); - Out << ' '; - } - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + return; } + if (PrintType) { + TypePrinter.print(Operand->getType(), Out); + Out << ' '; + } + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } void AssemblyWriter::writeParamOperand(const Value *Operand, Attributes Attrs) { if (Operand == 0) { Out << ""; - } else { - // Print the type - TypePrinter.print(Operand->getType(), Out); - // Print parameter attributes list - if (Attrs != Attribute::None) - Out << ' ' << Attribute::getAsString(Attrs); - Out << ' '; - // Print the operand - WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); + return; } + + // Print the type + TypePrinter.print(Operand->getType(), Out); + // Print parameter attributes list + if (Attrs != Attribute::None) + Out << ' ' << Attribute::getAsString(Attrs); + Out << ' '; + // Print the operand + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } void AssemblyWriter::printModule(const Module *M) { @@ -1449,23 +1383,31 @@ void AssemblyWriter::printModule(const Module *M) { // 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(NMD->getElement(i)); - Out << '!' << Machine.getMetadataSlot(MD); - } - Out << "}\n"; - } + E = M->named_metadata_end(); I != E; ++I) + printNamedMDNode(I); // Output metadata. - if (!Machine.mdnEmpty()) Out << '\n'; - WriteMDNodes(Out, TypePrinter, Machine); + if (!Machine.mdn_empty()) { + Out << '\n'; + writeAllMDNodes(); + } } +void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { + Out << "!" << NMD->getName() << " = !{"; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + if (i) Out << ", "; + if (MDNode *MD = NMD->getOperand(i)) + Out << '!' << Machine.getMetadataSlot(MD); + else + Out << "null"; + } + Out << "}\n"; +} + + static void PrintLinkage(GlobalValue::LinkageTypes LT, formatted_raw_ostream &Out) { switch (LT) { @@ -1485,8 +1427,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::AvailableExternallyLinkage: Out << "available_externally "; break; - case GlobalValue::GhostLinkage: - llvm_unreachable("GhostLinkage not allowed in AsmWriter!"); } } @@ -1494,7 +1434,6 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, static void PrintVisibility(GlobalValue::VisibilityTypes Vis, formatted_raw_ostream &Out) { switch (Vis) { - default: llvm_unreachable("Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; case GlobalValue::ProtectedVisibility: Out << "protected "; break; @@ -1502,6 +1441,9 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { + if (GV->isMaterializable()) + Out << "; Materializable\n"; + WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine); Out << " = "; @@ -1532,6 +1474,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { } void AssemblyWriter::printAlias(const GlobalAlias *GA) { + if (GA->isMaterializable()) + Out << "; Materializable\n"; + // Don't crash when dumping partially built GA if (!GA->hasName()) Out << "<> = "; @@ -1605,6 +1550,9 @@ void AssemblyWriter::printFunction(const Function *F) { if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); + if (F->isMaterializable()) + Out << "; Materializable\n"; + if (F->isDeclaration()) Out << "declare "; else @@ -1623,6 +1571,7 @@ void AssemblyWriter::printFunction(const Function *F) { case CallingConv::ARM_APCS: Out << "arm_apcscc "; break; case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break; + case CallingConv::MSP430_INTR: Out << "msp430_intrcc "; break; default: Out << "cc" << F->getCallingConv() << " "; break; } @@ -1736,7 +1685,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { // Output predecessors for the block... Out.PadToColumn(50); Out << ";"; - pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB); + const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB); if (PI == PE) { Out << " No predecessors!"; @@ -1763,17 +1712,21 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } - /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// void AssemblyWriter::printInfoComment(const Value &V) { - if (V.getType() != Type::getVoidTy(V.getContext())) { - Out.PadToColumn(50); - Out << "; <"; - TypePrinter.print(V.getType(), Out); - Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses + if (AnnotationWriter) { + AnnotationWriter->printInfoComment(V, Out); + return; } + + if (V.getType()->isVoidTy()) return; + + Out.PadToColumn(50); + Out << "; <"; + TypePrinter.print(V.getType(), Out); + Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses } // This member is called for each Instruction in a function.. @@ -1787,7 +1740,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (I.hasName()) { PrintLLVMName(Out, &I); Out << " = "; - } else if (I.getType() != Type::getVoidTy(I.getContext())) { + } else if (!I.getType()->isVoidTy()) { // Print out the def slot taken. int SlotNum = Machine.getLocalSlot(&I); if (SlotNum == -1) @@ -1829,7 +1782,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { - // Special case switch statement to get formatting nice and correct... + // Special case switch instruction to get formatting nice and correct. Out << ' '; writeOperand(Operand , true); Out << ", "; @@ -1843,6 +1796,18 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(op+1), true); } Out << "\n ]"; + } else if (isa(I)) { + // Special case indirectbr instruction to get formatting nice and correct. + Out << ' '; + writeOperand(Operand, true); + Out << ", ["; + + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + if (i != 1) + Out << ", "; + writeOperand(I.getOperand(i), true); + } + Out << ']'; } else if (isa(I)) { Out << ' '; TypePrinter.print(I.getType(), Out); @@ -1878,6 +1843,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_APCS: Out << " arm_apcscc "; break; case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; + case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; default: Out << " cc" << CI->getCallingConv(); break; } @@ -1895,8 +1861,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Out << ' '; if (!FTy->isVarArg() && - (!isa(RetTy) || - !isa(cast(RetTy)->getElementType()))) { + (!RetTy->isPointerTy() || + !cast(RetTy)->getElementType()->isFunctionTy())) { TypePrinter.print(RetTy, Out); Out << ' '; writeOperand(Operand, false); @@ -1913,6 +1879,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.getFnAttributes() != Attribute::None) Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast(&I)) { + Operand = II->getCalledValue(); const PointerType *PTy = cast(Operand->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); @@ -1928,6 +1895,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::ARM_APCS: Out << " arm_apcscc "; break; case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break; case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break; + case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break; default: Out << " cc" << II->getCallingConv(); break; } @@ -1940,8 +1908,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Out << ' '; if (!FTy->isVarArg() && - (!isa(RetTy) || - !isa(cast(RetTy)->getElementType()))) { + (!RetTy->isPointerTy() || + !cast(RetTy)->getElementType()->isFunctionTy())) { TypePrinter.print(RetTy, Out); Out << ' '; writeOperand(Operand, false); @@ -1949,10 +1917,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(Operand, true); } Out << '('; - for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) { - if (op > 3) + for (unsigned op = 0, Eop = I.getNumOperands() - 3; op < Eop; ++op) { + if (op) Out << ", "; - writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2)); + writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op + 1)); } Out << ')'; @@ -1964,7 +1932,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " unwind "; writeOperand(II->getUnwindDest(), true); - } else if (const AllocationInst *AI = dyn_cast(&I)) { + } else if (const AllocaInst *AI = dyn_cast(&I)) { Out << ' '; TypePrinter.print(AI->getType()->getElementType(), Out); if (!AI->getArraySize() || AI->isArrayAllocation()) { @@ -2024,26 +1992,76 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } } - // Print post operand alignment for load/store + // Print post operand alignment for load/store. if (isa(I) && cast(I).getAlignment()) { Out << ", align " << cast(I).getAlignment(); } else if (isa(I) && cast(I).getAlignment()) { Out << ", align " << cast(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) - Out << ", !" << MDNames[MI->first] - << " !" << Machine.getMetadataSlot(MI->second); + // Print Metadata info. + SmallVector, 4> InstMD; + I.getAllMetadata(InstMD); + if (!InstMD.empty()) { + SmallVector MDNames; + I.getType()->getContext().getMDKindNames(MDNames); + for (unsigned i = 0, e = InstMD.size(); i != e; ++i) { + unsigned Kind = InstMD[i].first; + if (Kind < MDNames.size()) { + Out << ", !" << MDNames[Kind]; + } else { + Out << ", !"; + } + Out << " !" << Machine.getMetadataSlot(InstMD[i].second); + } } printInfoComment(I); } +static void WriteMDNodeComment(const MDNode *Node, + formatted_raw_ostream &Out) { + if (Node->getNumOperands() < 1) + return; + ConstantInt *CI = dyn_cast_or_null(Node->getOperand(0)); + if (!CI) return; + unsigned Val = CI->getZExtValue(); + unsigned Tag = Val & ~LLVMDebugVersionMask; + if (Val < LLVMDebugVersion) + return; + + Out.PadToColumn(50); + 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 if (const char *TagName = dwarf::TagString(Tag)) + Out << "; [ " << TagName << " ]"; +} + +void AssemblyWriter::writeAllMDNodes() { + SmallVector Nodes; + Nodes.resize(Machine.mdn_size()); + for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end(); + I != E; ++I) + Nodes[I->second] = cast(I->first); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Out << '!' << i << " = metadata "; + printMDNodeBody(Nodes[i]); + } +} + +void AssemblyWriter::printMDNodeBody(const MDNode *Node) { + WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine); + WriteMDNodeComment(Node, Out); + Out << "\n"; +} //===----------------------------------------------------------------------===// // External Interface declarations @@ -2053,7 +2071,7 @@ 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); + W.printModule(this); } void Type::print(raw_ostream &OS) const { @@ -2073,53 +2091,37 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { if (const Instruction *I = dyn_cast(this)) { const Function *F = I->getParent() ? I->getParent()->getParent() : 0; SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW); - W.write(I); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), AAW); + W.printInstruction(*I); } else if (const BasicBlock *BB = dyn_cast(this)) { SlotTracker SlotTable(BB->getParent()); - AssemblyWriter W(OS, SlotTable, - BB->getParent() ? BB->getParent()->getParent() : 0, AAW); - W.write(BB); + AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), AAW); + W.printBasicBlock(BB); } else if (const GlobalValue *GV = dyn_cast(this)) { SlotTracker SlotTable(GV->getParent()); AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW); - W.write(GV); - } else if (const MDString *MDS = dyn_cast(this)) { - TypePrinting TypePrinter; - TypePrinter.print(MDS->getType(), OS); - OS << ' '; - OS << "!\""; - PrintEscapedString(MDS->getString(), OS); - OS << '"'; + if (const GlobalVariable *V = dyn_cast(GV)) + W.printGlobal(V); + else if (const Function *F = dyn_cast(GV)) + W.printFunction(F); + else + W.printAlias(cast(GV)); } else if (const MDNode *N = dyn_cast(this)) { - SlotTracker SlotTable(N); - TypePrinting TypePrinter; - SlotTable.initialize(); - WriteMDNodes(OS, TypePrinter, SlotTable); + const Function *F = N->getFunction(); + SlotTracker SlotTable(F); + AssemblyWriter W(OS, SlotTable, F ? getModuleFromVal(F) : 0, AAW); + W.printMDNodeBody(N); } else if (const NamedMDNode *N = dyn_cast(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(N->getElement(i)); - if (MD) - OS << '!' << SlotTable.getMetadataSlot(MD); - else - OS << "null"; - } - OS << "}\n"; - WriteMDNodes(OS, TypePrinter, SlotTable); + SlotTracker SlotTable(N->getParent()); + AssemblyWriter W(OS, SlotTable, N->getParent(), AAW); + W.printNamedMDNode(N); } else if (const Constant *C = dyn_cast(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); OS << ' '; WriteConstantInt(OS, C, TypePrinter, 0); - } else if (const Argument *A = dyn_cast(this)) { - WriteAsOperand(OS, this, true, - A->getParent() ? A->getParent()->getParent() : 0); - } else if (isa(this)) { + } else if (isa(this) || isa(this) || + isa(this)) { WriteAsOperand(OS, this, true, 0); } else { // Otherwise we don't know what it is. Call the virtual function to @@ -2134,17 +2136,17 @@ void Value::printCustom(raw_ostream &OS) const { } // Value::dump - allow easy printing of Values from the debugger. -void Value::dump() const { print(errs()); errs() << '\n'; } +void Value::dump() const { print(dbgs()); dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. // This one uses type names from the given context module void Type::dump(const Module *Context) const { - WriteTypeSymbolic(errs(), this, Context); - errs() << '\n'; + WriteTypeSymbolic(dbgs(), this, Context); + dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. void Type::dump() const { dump(0); } // Module::dump() - Allow printing of Modules from the debugger. -void Module::dump() const { print(errs(), 0); } +void Module::dump() const { print(dbgs(), 0); }