rewrite handling of forward ref'd instruction metadata
authorChris Lattner <sabre@nondot.org>
Thu, 1 Apr 2010 05:14:45 +0000 (05:14 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 1 Apr 2010 05:14:45 +0000 (05:14 +0000)
to used deferred resolution instead of creating a temporary
node + rauw.  There is no reason to create the temporary
mdnode, then do rauw, then destroy it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100086 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h

index 5dc5a5e1194dd499789dab56be65217a428c3f69..cdad0770a38af9bebe71b204cdea728d42a62d73 100644 (file)
@@ -39,6 +39,27 @@ bool LLParser::Run() {
 /// ValidateEndOfModule - Do final validity and sanity checks at the end of the
 /// module.
 bool LLParser::ValidateEndOfModule() {
+  // Handle any instruction metadata forward references.
+  if (!ForwardRefInstMetadata.empty()) {
+    for (DenseMap<Instruction*, std::vector<MDRef> >::iterator
+         I = ForwardRefInstMetadata.begin(), E = ForwardRefInstMetadata.end();
+         I != E; ++I) {
+      Instruction *Inst = I->first;
+      const std::vector<MDRef> &MDList = I->second;
+      
+      for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
+        unsigned SlotNo = MDList[i].MDSlot;
+        
+        if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
+          return Error(MDList[i].Loc, "use of undefined metadata '!" +
+                       utostr(SlotNo) + "'");
+        Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
+      }
+    }
+    ForwardRefInstMetadata.clear();
+  }
+  
+  
   // Update auto-upgraded malloc calls to "malloc".
   // FIXME: Remove in LLVM 3.0.
   if (MallocF) {
@@ -472,18 +493,30 @@ bool LLParser::ParseMDString(MDString *&Result) {
 
 // MDNode:
 //   ::= '!' MDNodeNumber
+//
+/// This version of ParseMDNodeID returns the slot number and null in the case
+/// of a forward reference.
+bool LLParser::ParseMDNodeID(MDNode *&Result, unsigned &SlotNo) {
+  // !{ ..., !42, ... }
+  if (ParseUInt32(SlotNo)) return true;
+
+  // Check existing MDNode.
+  if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != 0)
+    Result = NumberedMetadata[SlotNo];
+  else
+    Result = 0;
+  return false;
+}
+
 bool LLParser::ParseMDNodeID(MDNode *&Result) {
   // !{ ..., !42, ... }
   unsigned MID = 0;
-  if (ParseUInt32(MID)) return true;
+  if (ParseMDNodeID(Result, MID)) return true;
 
-  // Check existing MDNode.
-  if (MID < NumberedMetadata.size() && NumberedMetadata[MID] != 0) {
-    Result = NumberedMetadata[MID];
-    return false;
-  }
+  // If not a forward reference, just return it now.
+  if (Result) return false;
 
-  // Create MDNode forward reference.
+  // Otherwise, create MDNode forward reference.
 
   // FIXME: This is not unique enough!
   std::string FwdRefName = "llvm.mdnode.fwdref." + utostr(MID);
@@ -1087,12 +1120,21 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst) {
     Lex.Lex();
 
     MDNode *Node;
+    unsigned NodeID;
+    SMLoc Loc = Lex.getLoc();
     if (ParseToken(lltok::exclaim, "expected '!' here") ||
-        ParseMDNodeID(Node))
+        ParseMDNodeID(Node, NodeID))
       return true;
 
     unsigned MDK = M->getMDKindID(Name.c_str());
-    Inst->setMetadata(MDK, Node);
+    if (Node) {
+      // If we got the node, add it to the instruction.
+      Inst->setMetadata(MDK, Node);
+    } else {
+      MDRef R = { Loc, MDK, NodeID };
+      // Otherwise, remember that this should be resolved later.
+      ForwardRefInstMetadata[Inst].push_back(R);
+    }
 
     // If this is the end of the list, we're done.
   } while (EatIfPresent(lltok::comma));
index 85cd086606620baa2722c1eaf42d4aba31f470c6..0610fc8bbd54eeadc5aa9c465d6130b1d5e69bc3 100644 (file)
@@ -76,6 +76,14 @@ namespace llvm {
     LLVMContext& Context;
     LLLexer Lex;
     Module *M;
+    
+    // Instruction metadata resolution.  Each instruction can have a list of
+    // MDRef info associated with them.
+    struct MDRef {
+      SMLoc Loc;
+      unsigned MDKind, MDSlot;
+    };
+    DenseMap<Instruction*, std::vector<MDRef> > ForwardRefInstMetadata;
 
     // Type resolution handling data structures.
     std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes;
@@ -203,6 +211,7 @@ namespace llvm {
     bool ParseNamedMetadata();
     bool ParseMDString(MDString *&Result);
     bool ParseMDNodeID(MDNode *&Result);
+    bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo);
 
     // Type Parsing.
     bool ParseType(PATypeHolder &Result, bool AllowVoid = false);