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
This commit is contained in:
Chris Lattner 2010-04-01 05:14:45 +00:00
parent e6bb172f7e
commit 449c3103c5
2 changed files with 60 additions and 9 deletions

View 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));

View 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);