summaryrefslogtreecommitdiffstats
path: root/lib/VMCore/AsmWriter.cpp
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-07-04 13:58:26 +0000
committered <ed@FreeBSD.org>2009-07-04 13:58:26 +0000
commit72621d11de5b873f1695f391eb95f0b336c3d2d4 (patch)
tree84360c8989c912127a383af37c4b1aa5767bd16e /lib/VMCore/AsmWriter.cpp
parentcf5cd875b51255602afaed29deb636b66b295671 (diff)
downloadFreeBSD-src-72621d11de5b873f1695f391eb95f0b336c3d2d4.zip
FreeBSD-src-72621d11de5b873f1695f391eb95f0b336c3d2d4.tar.gz
Import LLVM 74788.
Diffstat (limited to 'lib/VMCore/AsmWriter.cpp')
-rw-r--r--lib/VMCore/AsmWriter.cpp103
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);
OpenPOWER on IntegriCloud