summaryrefslogtreecommitdiff
path: root/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-04-01 05:14:45 +0000
committerChris Lattner <sabre@nondot.org>2010-04-01 05:14:45 +0000
commit449c3103c5d8a3105ac1a46187ac1c7e1bdc0ba2 (patch)
treec88af10d7034596af40c36c6202f7b87a9924cf2 /lib/AsmParser/LLParser.cpp
parente6bb172f7ecb340051cd755f1ea65737b2c4bf26 (diff)
downloadllvm-449c3103c5d8a3105ac1a46187ac1c7e1bdc0ba2.tar.gz
llvm-449c3103c5d8a3105ac1a46187ac1c7e1bdc0ba2.tar.bz2
llvm-449c3103c5d8a3105ac1a46187ac1c7e1bdc0ba2.tar.xz
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
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r--lib/AsmParser/LLParser.cpp60
1 files changed, 51 insertions, 9 deletions
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<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));