From 24e64df7ec25b55aa872c2ef33728dfbb8c353c4 Mon Sep 17 00:00:00 2001 From: Victor Hernandez Date: Sun, 10 Jan 2010 07:14:18 +0000 Subject: [PATCH] Compute isFunctionLocal in MDNode ctor or via argument in new function getWhenValsUnresolved(). Document PFS argument to ParseValID() and ConvertGlobalOrMetadataValIDToValue(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93108 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/LLVMBitCodes.h | 9 +++---- include/llvm/Metadata.h | 18 ++++++++++++-- lib/AsmParser/LLParser.cpp | 29 ++++++++++++----------- lib/AsmParser/LLParser.h | 6 ++--- lib/Bitcode/Reader/BitcodeReader.cpp | 8 ++++++- lib/Bitcode/Writer/BitcodeWriter.cpp | 4 +++- lib/VMCore/Metadata.cpp | 35 +++++++++++++++++++++++++--- 7 files changed, 80 insertions(+), 29 deletions(-) diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index c037399b96d..9bb50d4b3bd 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -111,10 +111,11 @@ namespace bitc { enum MetadataCodes { METADATA_STRING = 1, // MDSTRING: [values] METADATA_NODE = 2, // MDNODE: [n x (type num, value num)] - METADATA_NAME = 3, // STRING: [values] - METADATA_NAMED_NODE = 4, // NAMEDMDNODE: [n x mdnodes] - METADATA_KIND = 5, // [n x [id, name]] - METADATA_ATTACHMENT = 6 // [m x [value, [n x [id, mdnode]]] + METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)] + METADATA_NAME = 4, // STRING: [values] + METADATA_NAMED_NODE = 5, // NAMEDMDNODE: [n x mdnodes] + METADATA_KIND = 6, // [n x [id, name]] + METADATA_ATTACHMENT = 7 // [m x [value, [n x [id, mdnode]]] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each // constant and maintains an implicit current type value. diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 4d4e4999e94..282ee85e583 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -112,6 +112,13 @@ class MDNode : public MetadataBase, public FoldingSetNode { DestroyFlag = 1 << 2 }; + // FunctionLocal enums. + enum FunctionLocalness { + FL_Unknown = -1, + FL_No = 0, + FL_Yes = 1 + }; + // Replace each instance of F from the operand list of this node with T. void replaceOperand(MDNodeOperand *Op, Value *NewVal); ~MDNode(); @@ -119,10 +126,17 @@ class MDNode : public MetadataBase, public FoldingSetNode { protected: explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, bool isFunctionLocal); + + static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, + FunctionLocalness FL); public: // Constructors and destructors. - static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals, - bool isFunctionLocal = false); + static MDNode *get(LLVMContext &Context, Value *const *Vals, + unsigned NumVals); + // getWhenValsUnresolved - Construct MDNode determining function-localness + // from isFunctionLocal argument, not by analyzing Vals. + static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals, + unsigned NumVals, bool isFunctionLocal); /// getOperand - Return specified operand. Value *getOperand(unsigned i) const; diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 9de1ff940e8..b94aaeb7487 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -548,7 +548,7 @@ bool LLParser::ParseStandaloneMetadata() { ParseType(Ty, TyLoc) || ParseToken(lltok::exclaim, "Expected '!' here") || ParseToken(lltok::lbrace, "Expected '{' here") || - ParseMDNodeVector(Elts, NULL, NULL) || + ParseMDNodeVector(Elts, NULL) || ParseToken(lltok::rbrace, "expected end of metadata node")) return true; @@ -1884,7 +1884,9 @@ BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name, /// ParseValID - Parse an abstract value that doesn't necessarily have a /// type implied. For example, if we parse "4" we don't know what integer type /// it has. The value will later be combined with its type and checked for -/// sanity. +/// sanity. PFS is used to convert function-local operands of metadata (since +/// metadata operands are not just parsed here but also converted to values). +/// PFS can be null when we are not parsing metadata values inside a function. bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Loc = Lex.getLoc(); switch (Lex.getKind()) { @@ -1911,13 +1913,11 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (EatIfPresent(lltok::lbrace)) { SmallVector Elts; - bool isFunctionLocal = false; - if (ParseMDNodeVector(Elts, PFS, &isFunctionLocal) || + if (ParseMDNodeVector(Elts, PFS) || ParseToken(lltok::rbrace, "expected end of metadata node")) return true; - ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size(), - isFunctionLocal); + ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size()); ID.Kind = ValID::t_MDNode; return false; } @@ -2446,11 +2446,13 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, } /// ConvertGlobalOrMetadataValIDToValue - Apply a type to a ValID to get a fully -/// resolved constant, metadata, or function-local value +/// resolved constant, metadata, or function-local value. PFS is used to +/// convert a function-local ValID and can be null when parsing a global or a +/// non-function-local metadata ValID. + bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID, Value *&V, - PerFunctionState *PFS, - bool *isFunctionLocal) { + PerFunctionState *PFS) { switch (ID.Kind) { case ValID::t_MDNode: if (!Ty->isMetadataTy()) @@ -2464,10 +2466,9 @@ bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID, return false; case ValID::t_LocalID: case ValID::t_LocalName: - if (!PFS || !isFunctionLocal) + if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); if (ConvertValIDToValue(Ty, ID, V, *PFS)) return true; - *isFunctionLocal = true; return false; default: Constant *C; @@ -2527,7 +2528,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return false; } default: - return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, &PFS, NULL); + return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, &PFS); } return V == 0; @@ -3858,7 +3859,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { /// Element /// ::= 'null' | TypeAndValue bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, - PerFunctionState *PFS, bool *isFunctionLocal) { + PerFunctionState *PFS) { do { // Null is a special case since it is typeless. if (EatIfPresent(lltok::kw_null)) { @@ -3870,7 +3871,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, PATypeHolder Ty(Type::getVoidTy(Context)); ValID ID; if (ParseType(Ty) || ParseValID(ID, PFS) || - ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, PFS, isFunctionLocal)) + ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, PFS)) return true; Elts.push_back(V); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index d532081c5b8..595267b7ff1 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -294,13 +294,11 @@ namespace llvm { bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL); bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V); bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID, - Value *&V, PerFunctionState *PFS, - bool *isFunctionLocal); + Value *&V, PerFunctionState *PFS); bool ParseGlobalValue(const Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl &Elts); - bool ParseMDNodeVector(SmallVectorImpl &, PerFunctionState *PFS, - bool *isFunctionLocal); + bool ParseMDNodeVector(SmallVectorImpl &, PerFunctionState *PFS); // Function Parsing. struct ArgInfo { diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 87c4fd77f36..a417c684dec 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -766,6 +766,7 @@ bool BitcodeReader::ParseMetadata() { continue; } + bool IsFunctionLocal = false; // Read a record. Record.clear(); switch (Stream.ReadRecord(Code, Record)) { @@ -804,6 +805,9 @@ bool BitcodeReader::ParseMetadata() { MDValueList.AssignValue(V, NextValueNo++); break; } + case bitc::METADATA_FN_NODE: + IsFunctionLocal = true; + // fall-through case bitc::METADATA_NODE: { if (Record.empty() || Record.size() % 2 == 1) return Error("Invalid METADATA_NODE record"); @@ -819,7 +823,9 @@ bool BitcodeReader::ParseMetadata() { else Elts.push_back(NULL); } - Value *V = MDNode::get(Context, &Elts[0], Elts.size()); + Value *V = MDNode::getWhenValsUnresolved(Context, &Elts[0], Elts.size(), + IsFunctionLocal); + IsFunctionLocal = false; MDValueList.AssignValue(V, NextValueNo++); break; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index d34e24ccb5a..26c922a7810 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -484,7 +484,9 @@ static void WriteMDNode(const MDNode *N, Record.push_back(0); } } - Stream.EmitRecord(bitc::METADATA_NODE, Record, 0); + unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE : + bitc::METADATA_NODE; + Stream.EmitRecord(MDCode, Record, 0); Record.clear(); } diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 87ffaff5724..fb1da998ade 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -128,9 +128,8 @@ void MDNode::destroy() { free(this); } - -MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, - bool isFunctionLocal) { +MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals, + unsigned NumVals, FunctionLocalness FL) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; for (unsigned i = 0; i != NumVals; ++i) @@ -139,6 +138,27 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); if (!N) { + bool isFunctionLocal = false; + switch (FL) { + case FL_Unknown: + for (unsigned i = 0; i != NumVals; ++i) { + Value *V = Vals[i]; + if (!V) continue; + if (isa(V) || isa(V) || isa(V) || + isa(V) && cast(V)->isFunctionLocal()) { + isFunctionLocal = true; + break; + } + } + break; + case FL_No: + isFunctionLocal = false; + break; + case FL_Yes: + isFunctionLocal = true; + break; + } + // Coallocate space for the node and Operands together, then placement new. void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand)); N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal); @@ -149,6 +169,15 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, return N; } +MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { + return getMDNode(Context, Vals, NumVals, FL_Unknown); +} + +MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context, Value*const* Vals, + unsigned NumVals, bool isFunctionLocal) { + return getMDNode(Context, Vals, NumVals, isFunctionLocal ? FL_Yes : FL_No); +} + /// getOperand - Return specified operand. Value *MDNode::getOperand(unsigned i) const { return *getOperandPtr(const_cast(this), i); -- 2.34.1