diff options
Diffstat (limited to 'lib/VMCore/AsmWriter.cpp')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 103 |
1 files changed, 82 insertions, 21 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 73b1ed6..cbf7070 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); } @@ -1117,6 +1103,7 @@ public: 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; } @@ -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,47 @@ 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()) @@ -1852,6 +1905,14 @@ 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)) { + TypePrinting TypePrinter; + TypePrinter.print(N->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); } else if (const Constant *C = dyn_cast<Constant>(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); |