From 449c3103c5d8a3105ac1a46187ac1c7e1bdc0ba2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 1 Apr 2010 05:14:45 +0000 Subject: rewrite handling of forward ref'd instruction metadata 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 | 60 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'lib/AsmParser/LLParser.cpp') diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 5dc5a5e119..cdad0770a3 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -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 >::iterator + I = ForwardRefInstMetadata.begin(), E = ForwardRefInstMetadata.end(); + I != E; ++I) { + Instruction *Inst = I->first; + const std::vector &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)); -- cgit v1.2.3