1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

Compute isFunctionLocal in MDNode ctor or via argument in new function getWhenValsUnresolved().

Document PFS argument to ParseValID() and ConvertGlobalOrMetadataValIDToValue().

llvm-svn: 93108
This commit is contained in:
Victor Hernandez 2010-01-10 07:14:18 +00:00
parent e86619ca01
commit f4272b50d6
7 changed files with 80 additions and 29 deletions

View File

@ -111,10 +111,11 @@ namespace bitc {
enum MetadataCodes { enum MetadataCodes {
METADATA_STRING = 1, // MDSTRING: [values] METADATA_STRING = 1, // MDSTRING: [values]
METADATA_NODE = 2, // MDNODE: [n x (type num, value num)] METADATA_NODE = 2, // MDNODE: [n x (type num, value num)]
METADATA_NAME = 3, // STRING: [values] METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)]
METADATA_NAMED_NODE = 4, // NAMEDMDNODE: [n x mdnodes] METADATA_NAME = 4, // STRING: [values]
METADATA_KIND = 5, // [n x [id, name]] METADATA_NAMED_NODE = 5, // NAMEDMDNODE: [n x mdnodes]
METADATA_ATTACHMENT = 6 // [m x [value, [n x [id, mdnode]]] 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 // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
// constant and maintains an implicit current type value. // constant and maintains an implicit current type value.

View File

@ -112,6 +112,13 @@ class MDNode : public MetadataBase, public FoldingSetNode {
DestroyFlag = 1 << 2 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. // Replace each instance of F from the operand list of this node with T.
void replaceOperand(MDNodeOperand *Op, Value *NewVal); void replaceOperand(MDNodeOperand *Op, Value *NewVal);
~MDNode(); ~MDNode();
@ -119,10 +126,17 @@ class MDNode : public MetadataBase, public FoldingSetNode {
protected: protected:
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
bool isFunctionLocal); bool isFunctionLocal);
static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
FunctionLocalness FL);
public: public:
// Constructors and destructors. // Constructors and destructors.
static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals, static MDNode *get(LLVMContext &Context, Value *const *Vals,
bool isFunctionLocal = false); 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. /// getOperand - Return specified operand.
Value *getOperand(unsigned i) const; Value *getOperand(unsigned i) const;

View File

@ -548,7 +548,7 @@ bool LLParser::ParseStandaloneMetadata() {
ParseType(Ty, TyLoc) || ParseType(Ty, TyLoc) ||
ParseToken(lltok::exclaim, "Expected '!' here") || ParseToken(lltok::exclaim, "Expected '!' here") ||
ParseToken(lltok::lbrace, "Expected '{' here") || ParseToken(lltok::lbrace, "Expected '{' here") ||
ParseMDNodeVector(Elts, NULL, NULL) || ParseMDNodeVector(Elts, NULL) ||
ParseToken(lltok::rbrace, "expected end of metadata node")) ParseToken(lltok::rbrace, "expected end of metadata node"))
return true; 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 /// 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 /// 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 /// 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) { bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ID.Loc = Lex.getLoc(); ID.Loc = Lex.getLoc();
switch (Lex.getKind()) { switch (Lex.getKind()) {
@ -1911,13 +1913,11 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (EatIfPresent(lltok::lbrace)) { if (EatIfPresent(lltok::lbrace)) {
SmallVector<Value*, 16> Elts; SmallVector<Value*, 16> Elts;
bool isFunctionLocal = false; if (ParseMDNodeVector(Elts, PFS) ||
if (ParseMDNodeVector(Elts, PFS, &isFunctionLocal) ||
ParseToken(lltok::rbrace, "expected end of metadata node")) ParseToken(lltok::rbrace, "expected end of metadata node"))
return true; return true;
ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size(), ID.MDNodeVal = MDNode::get(Context, Elts.data(), Elts.size());
isFunctionLocal);
ID.Kind = ValID::t_MDNode; ID.Kind = ValID::t_MDNode;
return false; 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 /// 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, bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
Value *&V, Value *&V,
PerFunctionState *PFS, PerFunctionState *PFS) {
bool *isFunctionLocal) {
switch (ID.Kind) { switch (ID.Kind) {
case ValID::t_MDNode: case ValID::t_MDNode:
if (!Ty->isMetadataTy()) if (!Ty->isMetadataTy())
@ -2464,10 +2466,9 @@ bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
return false; return false;
case ValID::t_LocalID: case ValID::t_LocalID:
case ValID::t_LocalName: case ValID::t_LocalName:
if (!PFS || !isFunctionLocal) if (!PFS)
return Error(ID.Loc, "invalid use of function-local name"); return Error(ID.Loc, "invalid use of function-local name");
if (ConvertValIDToValue(Ty, ID, V, *PFS)) return true; if (ConvertValIDToValue(Ty, ID, V, *PFS)) return true;
*isFunctionLocal = true;
return false; return false;
default: default:
Constant *C; Constant *C;
@ -2527,7 +2528,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
return false; return false;
} }
default: default:
return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, &PFS, NULL); return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, &PFS);
} }
return V == 0; return V == 0;
@ -3858,7 +3859,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
/// Element /// Element
/// ::= 'null' | TypeAndValue /// ::= 'null' | TypeAndValue
bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
PerFunctionState *PFS, bool *isFunctionLocal) { PerFunctionState *PFS) {
do { do {
// Null is a special case since it is typeless. // Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) { if (EatIfPresent(lltok::kw_null)) {
@ -3870,7 +3871,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
PATypeHolder Ty(Type::getVoidTy(Context)); PATypeHolder Ty(Type::getVoidTy(Context));
ValID ID; ValID ID;
if (ParseType(Ty) || ParseValID(ID, PFS) || if (ParseType(Ty) || ParseValID(ID, PFS) ||
ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, PFS, isFunctionLocal)) ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, PFS))
return true; return true;
Elts.push_back(V); Elts.push_back(V);

View File

@ -294,13 +294,11 @@ namespace llvm {
bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL); bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL);
bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V); bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V);
bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID, bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
Value *&V, PerFunctionState *PFS, Value *&V, PerFunctionState *PFS);
bool *isFunctionLocal);
bool ParseGlobalValue(const Type *Ty, Constant *&V); bool ParseGlobalValue(const Type *Ty, Constant *&V);
bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V);
bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts); bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS, bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
bool *isFunctionLocal);
// Function Parsing. // Function Parsing.
struct ArgInfo { struct ArgInfo {

View File

@ -766,6 +766,7 @@ bool BitcodeReader::ParseMetadata() {
continue; continue;
} }
bool IsFunctionLocal = false;
// Read a record. // Read a record.
Record.clear(); Record.clear();
switch (Stream.ReadRecord(Code, Record)) { switch (Stream.ReadRecord(Code, Record)) {
@ -804,6 +805,9 @@ bool BitcodeReader::ParseMetadata() {
MDValueList.AssignValue(V, NextValueNo++); MDValueList.AssignValue(V, NextValueNo++);
break; break;
} }
case bitc::METADATA_FN_NODE:
IsFunctionLocal = true;
// fall-through
case bitc::METADATA_NODE: { case bitc::METADATA_NODE: {
if (Record.empty() || Record.size() % 2 == 1) if (Record.empty() || Record.size() % 2 == 1)
return Error("Invalid METADATA_NODE record"); return Error("Invalid METADATA_NODE record");
@ -819,7 +823,9 @@ bool BitcodeReader::ParseMetadata() {
else else
Elts.push_back(NULL); 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++); MDValueList.AssignValue(V, NextValueNo++);
break; break;
} }

View File

@ -484,7 +484,9 @@ static void WriteMDNode(const MDNode *N,
Record.push_back(0); 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(); Record.clear();
} }

View File

@ -128,9 +128,8 @@ void MDNode::destroy() {
free(this); free(this);
} }
MDNode *MDNode::getMDNode(LLVMContext &Context, Value *const *Vals,
MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals, unsigned NumVals, FunctionLocalness FL) {
bool isFunctionLocal) {
LLVMContextImpl *pImpl = Context.pImpl; LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID; FoldingSetNodeID ID;
for (unsigned i = 0; i != NumVals; ++i) for (unsigned i = 0; i != NumVals; ++i)
@ -139,6 +138,27 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
void *InsertPoint; void *InsertPoint;
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
if (!N) { 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. // Coallocate space for the node and Operands together, then placement new.
void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand)); void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeOperand));
N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal); N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
@ -149,6 +169,15 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
return N; 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. /// getOperand - Return specified operand.
Value *MDNode::getOperand(unsigned i) const { Value *MDNode::getOperand(unsigned i) const {
return *getOperandPtr(const_cast<MDNode*>(this), i); return *getOperandPtr(const_cast<MDNode*>(this), i);