diff options
author | Devang Patel <dpatel@apple.com> | 2009-07-01 19:21:12 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-07-01 19:21:12 +0000 |
commit | 923078c65d5a37a4f135705300c9feea49487de5 (patch) | |
tree | 6285a68712afb1375dd95806f12acfabcf9c6983 /lib/VMCore/AsmWriter.cpp | |
parent | 6d9148ce3d42a3f81c2828754a720278061c7aa7 (diff) | |
download | llvm-923078c65d5a37a4f135705300c9feea49487de5.tar.gz llvm-923078c65d5a37a4f135705300c9feea49487de5.tar.bz2 llvm-923078c65d5a37a4f135705300c9feea49487de5.tar.xz |
Support stand alone metadata syntax.
!0 = constant metadata !{i32 21, i32 22}
@llvm.blah = constant metadata !{i32 1000, i16 200, metadata !0}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74630 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/AsmWriter.cpp')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 90 |
1 files changed, 69 insertions, 21 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 73b1ed656d..361096f94d 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -35,6 +35,7 @@ #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cctype> +#include <map> using namespace llvm; // Make virtual table appear in this compilation unit. @@ -945,25 +946,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, return; } - if (const MDNode *N = dyn_cast<MDNode>(CV)) { - Out << "!{"; - for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); - I != E;) { - if (!*I) { - Out << "null"; - } else { - TypePrinter.print((*I)->getType(), Out); - Out << ' '; - WriteAsOperandInternal(Out, *I, TypePrinter, Machine); - } - - if (++I != E) - Out << ", "; - } - Out << "}"; - return; - } - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { Out << CE->getOpcodeName(); if (CE->isCompare()) @@ -1092,10 +1074,14 @@ class AssemblyWriter { TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; std::vector<const Type*> NumberedTypes; + + // 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, AssemblyAnnotationWriter *AAW) - : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { + : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) { AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); } @@ -1124,6 +1110,7 @@ private: void printModule(const Module *M); void printTypeSymbolTable(const TypeSymbolTable &ST); void printGlobal(const GlobalVariable *GV); + void printMDNode(const MDNode *Node, bool StandAlone); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); void printArgument(const Argument *FA, Attributes Attrs); @@ -1264,6 +1251,28 @@ 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 << " = "; @@ -1283,7 +1292,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasInitializer()) { Out << ' '; - writeOperand(GV->getInitializer(), false); + if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) + printMDNode(N, false); + else + writeOperand(GV->getInitializer(), false); } if (GV->hasSection()) @@ -1295,6 +1307,42 @@ 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()) { + Out << "metadata !" << 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)) + 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()) |