Store intrinsic ID by value in Function instead of a string lookup. NFC.
[oota-llvm.git] / lib / IR / AsmWriter.cpp
index fe6770ea5c61d56241493c27364a57ae9788e91f..304221af400c6d054b6526b31ab192325495cec4 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/IR/Statepoint.h"
 #include "llvm/IR/TypeFinder.h"
 #include "llvm/IR/UseListOrder.h"
 #include "llvm/IR/ValueSymbolTable.h"
@@ -776,12 +777,12 @@ void SlotTracker::processFunction() {
     if (!BB.hasName())
       CreateFunctionSlot(&BB);
 
+    processFunctionMetadata(*TheFunction);
+
     for (auto &I : BB) {
       if (!I.getType()->isVoidTy() && !I.hasName())
         CreateFunctionSlot(&I);
 
-      processInstructionMetadata(I);
-
       // We allow direct calls to any llvm.foo function here, because the
       // target may not be linked into the optimizer.
       if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -804,9 +805,15 @@ void SlotTracker::processFunction() {
 }
 
 void SlotTracker::processFunctionMetadata(const Function &F) {
-  for (auto &BB : F)
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+  for (auto &BB : F) {
+    F.getAllMetadata(MDs);
+    for (auto &MD : MDs)
+      CreateMetadataSlot(MD.second);
+
     for (auto &I : BB)
       processInstructionMetadata(I);
+  }
 }
 
 void SlotTracker::processInstructionMetadata(const Instruction &I) {
@@ -1369,7 +1376,7 @@ struct MDFieldPrinter {
                  SlotTracker *Machine, const Module *Context)
       : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
   }
-  void printTag(const DebugNode *N);
+  void printTag(const DINode *N);
   void printString(StringRef Name, StringRef Value,
                    bool ShouldSkipEmpty = true);
   void printMetadata(StringRef Name, const Metadata *MD,
@@ -1384,7 +1391,7 @@ struct MDFieldPrinter {
 };
 } // end namespace
 
-void MDFieldPrinter::printTag(const DebugNode *N) {
+void MDFieldPrinter::printTag(const DINode *N) {
   Out << FS << "tag: ";
   if (const char *Tag = dwarf::TagString(N->getTag()))
     Out << Tag;
@@ -1441,11 +1448,11 @@ void MDFieldPrinter::printDIFlags(StringRef Name, unsigned Flags) {
   Out << FS << Name << ": ";
 
   SmallVector<unsigned, 8> SplitFlags;
-  unsigned Extra = DebugNode::splitFlags(Flags, SplitFlags);
+  unsigned Extra = DINode::splitFlags(Flags, SplitFlags);
 
   FieldSeparator FlagsFS(" | ");
   for (unsigned F : SplitFlags) {
-    const char *StringF = DebugNode::getFlagString(F);
+    const char *StringF = DINode::getFlagString(F);
     assert(StringF && "Expected valid flag");
     Out << FlagsFS << StringF;
   }
@@ -1466,10 +1473,10 @@ void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
     Out << Value;
 }
 
-static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
-                                  TypePrinting *TypePrinter,
-                                  SlotTracker *Machine, const Module *Context) {
-  Out << "!GenericDebugNode(";
+static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
+                               TypePrinting *TypePrinter, SlotTracker *Machine,
+                               const Module *Context) {
+  Out << "!GenericDINode(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printTag(N);
   Printer.printString("header", N->getHeader());
@@ -1485,10 +1492,10 @@ static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
   Out << ")";
 }
 
-static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
+static void writeDILocation(raw_ostream &Out, const DILocation *DL,
                             TypePrinting *TypePrinter, SlotTracker *Machine,
                             const Module *Context) {
-  Out << "!MDLocation(";
+  Out << "!DILocation(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   // Always output the line, since 0 is a relevant and important value for it.
   Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
@@ -1498,27 +1505,27 @@ static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
   Out << ")";
 }
 
-static void writeMDSubrange(raw_ostream &Out, const MDSubrange *N,
+static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
                             TypePrinting *, SlotTracker *, const Module *) {
-  Out << "!MDSubrange(";
+  Out << "!DISubrange(";
   MDFieldPrinter Printer(Out);
   Printer.printInt("count", N->getCount(), /* ShouldSkipZero */ false);
   Printer.printInt("lowerBound", N->getLowerBound());
   Out << ")";
 }
 
-static void writeMDEnumerator(raw_ostream &Out, const MDEnumerator *N,
+static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
                               TypePrinting *, SlotTracker *, const Module *) {
-  Out << "!MDEnumerator(";
+  Out << "!DIEnumerator(";
   MDFieldPrinter Printer(Out);
   Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
   Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
   Out << ")";
 }
 
-static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
+static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
                              TypePrinting *, SlotTracker *, const Module *) {
-  Out << "!MDBasicType(";
+  Out << "!DIBasicType(";
   MDFieldPrinter Printer(Out);
   if (N->getTag() != dwarf::DW_TAG_base_type)
     Printer.printTag(N);
@@ -1530,10 +1537,10 @@ static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
   Out << ")";
 }
 
-static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
+static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
                                TypePrinting *TypePrinter, SlotTracker *Machine,
                                const Module *Context) {
-  Out << "!MDDerivedType(";
+  Out << "!DIDerivedType(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printTag(N);
   Printer.printString("name", N->getName());
@@ -1550,10 +1557,10 @@ static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
   Out << ")";
 }
 
-static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
+static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
                                  TypePrinting *TypePrinter,
                                  SlotTracker *Machine, const Module *Context) {
-  Out << "!MDCompositeType(";
+  Out << "!DICompositeType(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printTag(N);
   Printer.printString("name", N->getName());
@@ -1574,10 +1581,10 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
   Out << ")";
 }
 
-static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
+static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine, const Module *Context) {
-  Out << "!MDSubroutineType(";
+  Out << "!DISubroutineType(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printDIFlags("flags", N->getFlags());
   Printer.printMetadata("types", N->getRawTypeArray(),
@@ -1585,9 +1592,9 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
   Out << ")";
 }
 
-static void writeMDFile(raw_ostream &Out, const MDFile *N, TypePrinting *,
+static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
                         SlotTracker *, const Module *) {
-  Out << "!MDFile(";
+  Out << "!DIFile(";
   MDFieldPrinter Printer(Out);
   Printer.printString("filename", N->getFilename(),
                       /* ShouldSkipEmpty */ false);
@@ -1596,10 +1603,10 @@ static void writeMDFile(raw_ostream &Out, const MDFile *N, TypePrinting *,
   Out << ")";
 }
 
-static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
+static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
                                TypePrinting *TypePrinter, SlotTracker *Machine,
                                const Module *Context) {
-  Out << "!MDCompileUnit(";
+  Out << "!DICompileUnit(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printDwarfEnum("language", N->getSourceLanguage(),
                          dwarf::LanguageString, /* ShouldSkipZero */ false);
@@ -1620,10 +1627,10 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
   Out << ")";
 }
 
-static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
+static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
-  Out << "!MDSubprogram(";
+  Out << "!DISubprogram(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printString("name", N->getName());
   Printer.printString("linkageName", N->getLinkageName());
@@ -1647,10 +1654,10 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
   Out << ")";
 }
 
-static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
-                              TypePrinting *TypePrinter, SlotTracker *Machine,
-                              const Module *Context) {
-  Out << "!MDLexicalBlock(";
+static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
+                                TypePrinting *TypePrinter, SlotTracker *Machine,
+                                const Module *Context) {
+  Out << "!DILexicalBlock(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
   Printer.printMetadata("file", N->getRawFile());
@@ -1659,12 +1666,12 @@ static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
   Out << ")";
 }
 
-static void writeMDLexicalBlockFile(raw_ostream &Out,
-                                    const MDLexicalBlockFile *N,
+static void writeDILexicalBlockFile(raw_ostream &Out,
+                                    const DILexicalBlockFile *N,
                                     TypePrinting *TypePrinter,
                                     SlotTracker *Machine,
                                     const Module *Context) {
-  Out << "!MDLexicalBlockFile(";
+  Out << "!DILexicalBlockFile(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
   Printer.printMetadata("file", N->getRawFile());
@@ -1673,10 +1680,10 @@ static void writeMDLexicalBlockFile(raw_ostream &Out,
   Out << ")";
 }
 
-static void writeMDNamespace(raw_ostream &Out, const MDNamespace *N,
+static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
                              TypePrinting *TypePrinter, SlotTracker *Machine,
                              const Module *Context) {
-  Out << "!MDNamespace(";
+  Out << "!DINamespace(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printString("name", N->getName());
   Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
@@ -1685,24 +1692,24 @@ static void writeMDNamespace(raw_ostream &Out, const MDNamespace *N,
   Out << ")";
 }
 
-static void writeMDTemplateTypeParameter(raw_ostream &Out,
-                                         const MDTemplateTypeParameter *N,
+static void writeDITemplateTypeParameter(raw_ostream &Out,
+                                         const DITemplateTypeParameter *N,
                                          TypePrinting *TypePrinter,
                                          SlotTracker *Machine,
                                          const Module *Context) {
-  Out << "!MDTemplateTypeParameter(";
+  Out << "!DITemplateTypeParameter(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printString("name", N->getName());
   Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
   Out << ")";
 }
 
-static void writeMDTemplateValueParameter(raw_ostream &Out,
-                                          const MDTemplateValueParameter *N,
+static void writeDITemplateValueParameter(raw_ostream &Out,
+                                          const DITemplateValueParameter *N,
                                           TypePrinting *TypePrinter,
                                           SlotTracker *Machine,
                                           const Module *Context) {
-  Out << "!MDTemplateValueParameter(";
+  Out << "!DITemplateValueParameter(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
     Printer.printTag(N);
@@ -1712,10 +1719,10 @@ static void writeMDTemplateValueParameter(raw_ostream &Out,
   Out << ")";
 }
 
-static void writeMDGlobalVariable(raw_ostream &Out, const MDGlobalVariable *N,
+static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine, const Module *Context) {
-  Out << "!MDGlobalVariable(";
+  Out << "!DIGlobalVariable(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printString("name", N->getName());
   Printer.printString("linkageName", N->getLinkageName());
@@ -1730,10 +1737,10 @@ static void writeMDGlobalVariable(raw_ostream &Out, const MDGlobalVariable *N,
   Out << ")";
 }
 
-static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
+static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
                                  TypePrinting *TypePrinter,
                                  SlotTracker *Machine, const Module *Context) {
-  Out << "!MDLocalVariable(";
+  Out << "!DILocalVariable(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printTag(N);
   Printer.printString("name", N->getName());
@@ -1748,10 +1755,10 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
   Out << ")";
 }
 
-static void writeMDExpression(raw_ostream &Out, const MDExpression *N,
+static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
                               TypePrinting *TypePrinter, SlotTracker *Machine,
                               const Module *Context) {
-  Out << "!MDExpression(";
+  Out << "!DIExpression(";
   FieldSeparator FS;
   if (N->isValid()) {
     for (auto I = N->expr_op_begin(), E = N->expr_op_end(); I != E; ++I) {
@@ -1769,10 +1776,10 @@ static void writeMDExpression(raw_ostream &Out, const MDExpression *N,
   Out << ")";
 }
 
-static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
+static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
                                 TypePrinting *TypePrinter, SlotTracker *Machine,
                                 const Module *Context) {
-  Out << "!MDObjCProperty(";
+  Out << "!DIObjCProperty(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printString("name", N->getName());
   Printer.printMetadata("file", N->getRawFile());
@@ -1784,10 +1791,10 @@ static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
   Out << ")";
 }
 
-static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N,
+static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
                                   TypePrinting *TypePrinter,
                                   SlotTracker *Machine, const Module *Context) {
-  Out << "!MDImportedEntity(";
+  Out << "!DIImportedEntity(";
   MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
   Printer.printTag(N);
   Printer.printString("name", N->getName());
@@ -1943,6 +1950,7 @@ class AssemblyWriter {
   SetVector<const Comdat *> Comdats;
   bool ShouldPreserveUseListOrder;
   UseListOrderStack UseListOrders;
+  SmallVector<StringRef, 8> MDNames;
 
 public:
   /// Construct an AssemblyWriter with an external SlotTracker
@@ -1987,9 +1995,18 @@ public:
 private:
   void init();
 
+  /// \brief Print out metadata attachments.
+  void printMetadataAttachments(
+      const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
+      StringRef Separator);
+
   // printInfoComment - Print a little comment after the instruction indicating
   // which slot it occupies.
   void printInfoComment(const Value &V);
+
+  // printGCRelocateComment - print comment after call to the gc.relocate
+  // intrinsic indicating base and derived pointer names.
+  void printGCRelocateComment(const Value &V);
 };
 } // namespace
 
@@ -2535,6 +2552,10 @@ void AssemblyWriter::printFunction(const Function *F) {
     writeOperand(F->getPrologueData(), true);
   }
 
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+  F->getAllMetadata(MDs);
+  printMetadataAttachments(MDs, " ");
+
   if (F->isDeclaration()) {
     Out << '\n';
   } else {
@@ -2626,10 +2647,26 @@ void AssemblyWriter::printInstructionLine(const Instruction &I) {
   Out << '\n';
 }
 
+/// printGCRelocateComment - print comment after call to the gc.relocate
+/// intrinsic indicating base and derived pointer names.
+void AssemblyWriter::printGCRelocateComment(const Value &V) {
+  assert(isGCRelocate(&V));
+  GCRelocateOperands GCOps(cast<Instruction>(&V));
+
+  Out << " ; (";
+  writeOperand(GCOps.getBasePtr(), false);
+  Out << ", ";
+  writeOperand(GCOps.getDerivedPtr(), false);
+  Out << ")";
+}
+
 /// printInfoComment - Print a little comment after the instruction indicating
 /// which slot it occupies.
 ///
 void AssemblyWriter::printInfoComment(const Value &V) {
+  if (isGCRelocate(&V))
+    printGCRelocateComment(V);
+
   if (AnnotationWriter)
     AnnotationWriter->printInfoComment(V, Out);
 }
@@ -2952,24 +2989,33 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
   // Print Metadata info.
   SmallVector<std::pair<unsigned, MDNode *>, 4> InstMD;
   I.getAllMetadata(InstMD);
-  if (!InstMD.empty()) {
-    SmallVector<StringRef, 8> 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 << ", !<unknown kind #" << Kind << ">";
-       }
-      Out << ' ';
-      WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine,
-                             TheModule);
-    }
-  }
+  printMetadataAttachments(InstMD, ", ");
+
+  // Print a nice comment.
   printInfoComment(I);
 }
 
+void AssemblyWriter::printMetadataAttachments(
+    const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
+    StringRef Separator) {
+  if (MDs.empty())
+    return;
+
+  if (MDNames.empty())
+    TheModule->getMDKindNames(MDNames);
+
+  for (const auto &I : MDs) {
+    unsigned Kind = I.first;
+    Out << Separator;
+    if (Kind < MDNames.size())
+      Out << "!" << MDNames[Kind];
+    else
+      Out << "!<unknown kind #" << Kind << ">";
+    Out << ' ';
+    WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule);
+  }
+}
+
 void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
   Out << '!' << Slot << " = ";
   printMDNodeBody(Node);