summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Hernandez <vhernandez@apple.com>2010-01-10 07:14:18 +0000
committerVictor Hernandez <vhernandez@apple.com>2010-01-10 07:14:18 +0000
commit24e64df7ec25b55aa872c2ef33728dfbb8c353c4 (patch)
tree7bd02b0cd86413d8a5202b7356d5670522ec2c93
parentf4fb91181cbd3f63d487a2519c7f7be9d5e51709 (diff)
downloadllvm-24e64df7ec25b55aa872c2ef33728dfbb8c353c4.tar.gz
llvm-24e64df7ec25b55aa872c2ef33728dfbb8c353c4.tar.bz2
llvm-24e64df7ec25b55aa872c2ef33728dfbb8c353c4.tar.xz
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
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h9
-rw-r--r--include/llvm/Metadata.h18
-rw-r--r--lib/AsmParser/LLParser.cpp29
-rw-r--r--lib/AsmParser/LLParser.h6
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp8
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp4
-rw-r--r--lib/VMCore/Metadata.cpp35
7 files changed, 80 insertions, 29 deletions
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index c037399b96..9bb50d4b3b 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 4d4e4999e9..282ee85e58 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 9de1ff940e..b94aaeb748 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<Value*, 16> 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<Value*> &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<Value*> &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 d532081c5b..595267b7ff 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<Constant*> &Elts);
- bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS,
- bool *isFunctionLocal);
+ bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
// Function Parsing.
struct ArgInfo {
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 87c4fd77f3..a417c684de 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 d34e24ccb5..26c922a781 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 87ffaff572..fb1da998ad 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<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
+ isa<MDNode>(V) && cast<MDNode>(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<MDNode*>(this), i);