mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Formalize MDNode's function-localness:
- an MDNode is designated as function-local when created, and continues to be even if its operands are modified not to refer to function-local IR - function-localness is designated via lowest bit in SubclassData - getLocalFunction() descends MDNode tree to see if it is consistently function-local Add verification of MDNodes to checks that MDNodes are consistently function-local. Update AsmWriter to use isFunctionLocal(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91708 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1edcafe10f
commit
5d30162150
@ -19,6 +19,7 @@
|
||||
#include "llvm/Value.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
@ -106,21 +107,22 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
Parent->replaceElement(this->operator Value*(), NV);
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned short FunctionLocalBit = 1;
|
||||
|
||||
// Replace each instance of F from the element list of this node with T.
|
||||
void replaceElement(Value *F, Value *T);
|
||||
|
||||
ElementVH *Node;
|
||||
unsigned NodeSize;
|
||||
Function *LocalFunction;
|
||||
|
||||
protected:
|
||||
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
|
||||
Function *LocalFunc = NULL);
|
||||
bool isFunctionLocal);
|
||||
public:
|
||||
// Constructors and destructors.
|
||||
static MDNode *get(LLVMContext &Context,
|
||||
Value *const *Vals, unsigned NumVals,
|
||||
Function *LocalFunction = NULL);
|
||||
static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals,
|
||||
bool isFunctionLocal = false);
|
||||
|
||||
/// ~MDNode - Destroy MDNode.
|
||||
~MDNode();
|
||||
@ -135,7 +137,17 @@ public:
|
||||
unsigned getNumElements() const { return NodeSize; }
|
||||
|
||||
/// isFunctionLocal - Return whether MDNode is local to a function.
|
||||
bool isFunctionLocal() const { return LocalFunction; }
|
||||
/// Note: MDNodes are designated as function-local when created, and keep
|
||||
/// that designation even if their operands are modified to no longer
|
||||
/// refer to function-local IR.
|
||||
bool isFunctionLocal() const { return SubclassData & FunctionLocalBit; }
|
||||
|
||||
/// getLocalFunction - Return false if MDNode's recursive function-localness
|
||||
/// is invalid (local to more than one function). Return true otherwise.
|
||||
/// If MDNode has one function to which it is local, set LocalFunction to that
|
||||
/// function.
|
||||
bool getLocalFunction(Function *LocalFunction,
|
||||
SmallPtrSet<MDNode *, 32> *VisitedMDNodes = NULL);
|
||||
|
||||
/// Profile - calculate a unique identifier for this MDNode to collapse
|
||||
/// duplicates
|
||||
|
@ -813,10 +813,9 @@ void SlotTracker::CreateFunctionSlot(const Value *V) {
|
||||
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
|
||||
assert(N && "Can't insert a null Value into SlotTracker!");
|
||||
|
||||
// Don't insert if N contains an instruction.
|
||||
for (unsigned i = 0, e = N->getNumElements(); i != e; ++i)
|
||||
if (N->getElement(i) && isa<Instruction>(N->getElement(i)))
|
||||
return;
|
||||
// Don't insert if N is a function-local metadata.
|
||||
if (N->isFunctionLocal())
|
||||
return;
|
||||
|
||||
ValueMap::iterator I = mdnMap.find(N);
|
||||
if (I != mdnMap.end())
|
||||
@ -1232,7 +1231,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
|
||||
}
|
||||
|
||||
if (const MDNode *N = dyn_cast<MDNode>(V)) {
|
||||
if (Machine->getMetadataSlot(N) == -1) {
|
||||
if (N->isFunctionLocal()) {
|
||||
// Print metadata inline, not via slot reference number.
|
||||
Out << "!{";
|
||||
for (unsigned mi = 0, me = N->getNumElements(); mi != me; ++mi) {
|
||||
|
@ -50,14 +50,15 @@ MDString *MDString::get(LLVMContext &Context, const char *Str) {
|
||||
// MDNode implementation.
|
||||
//
|
||||
MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
|
||||
Function *LocalFunc)
|
||||
bool isFunctionLocal)
|
||||
: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
|
||||
NodeSize = NumVals;
|
||||
Node = new ElementVH[NodeSize];
|
||||
ElementVH *Ptr = Node;
|
||||
for (unsigned i = 0; i != NumVals; ++i)
|
||||
*Ptr++ = ElementVH(Vals[i], this);
|
||||
LocalFunction = LocalFunc;
|
||||
if (isFunctionLocal)
|
||||
SubclassData |= FunctionLocalBit;
|
||||
}
|
||||
|
||||
void MDNode::Profile(FoldingSetNodeID &ID) const {
|
||||
@ -66,19 +67,17 @@ void MDNode::Profile(FoldingSetNodeID &ID) const {
|
||||
}
|
||||
|
||||
MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
|
||||
Function *LocalFunction) {
|
||||
bool isFunctionLocal) {
|
||||
LLVMContextImpl *pImpl = Context.pImpl;
|
||||
FoldingSetNodeID ID;
|
||||
for (unsigned i = 0; i != NumVals; ++i)
|
||||
ID.AddPointer(Vals[i]);
|
||||
if (LocalFunction)
|
||||
ID.AddPointer(LocalFunction);
|
||||
|
||||
void *InsertPoint;
|
||||
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
|
||||
if (!N) {
|
||||
// InsertPoint will have been set by the FindNodeOrInsertPos call.
|
||||
N = new MDNode(Context, Vals, NumVals, LocalFunction);
|
||||
N = new MDNode(Context, Vals, NumVals, isFunctionLocal);
|
||||
pImpl->MDNodeSet.InsertNode(N, InsertPoint);
|
||||
}
|
||||
return N;
|
||||
@ -146,6 +145,45 @@ void MDNode::replaceElement(Value *From, Value *To) {
|
||||
}
|
||||
}
|
||||
|
||||
// getLocalFunction - Return false if MDNode's recursive function-localness is
|
||||
// invalid (local to more than one function). Return true otherwise. If MDNode
|
||||
// has one function to which it is local, set LocalFunction to that function.
|
||||
bool MDNode::getLocalFunction(Function *LocalFunction,
|
||||
SmallPtrSet<MDNode *, 32> *VisitedMDNodes) {
|
||||
if (!isFunctionLocal())
|
||||
return true;
|
||||
|
||||
if (!VisitedMDNodes)
|
||||
VisitedMDNodes = new SmallPtrSet<MDNode *, 32>();
|
||||
|
||||
if (!VisitedMDNodes->insert(this))
|
||||
// MDNode has already been visited, nothing to do.
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
|
||||
Value *V = getElement(i);
|
||||
if (!V) continue;
|
||||
|
||||
Function *LocalFunctionTemp = NULL;
|
||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||
LocalFunctionTemp = I->getParent()->getParent();
|
||||
else if (MDNode *MD = dyn_cast<MDNode>(V))
|
||||
if (!MD->getLocalFunction(LocalFunctionTemp, VisitedMDNodes))
|
||||
// This MDNode's operand is function-locally invalid or local to a
|
||||
// different function.
|
||||
return false;
|
||||
|
||||
if (LocalFunctionTemp)
|
||||
if (!LocalFunction)
|
||||
LocalFunction = LocalFunctionTemp;
|
||||
else if (LocalFunction != LocalFunctionTemp)
|
||||
// This MDNode contains operands that are local to different functions.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// NamedMDNode implementation.
|
||||
//
|
||||
|
@ -1542,6 +1542,16 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_INTRINSIC_VERIFIER
|
||||
|
||||
for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
|
||||
if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(i))) {
|
||||
Function* LocalFunction = NULL;
|
||||
Assert1(MD && MD->getLocalFunction(LocalFunction),
|
||||
"invalid function-local metadata", &CI);
|
||||
if (LocalFunction)
|
||||
Assert1(LocalFunction == CI.getParent()->getParent(),
|
||||
"function-local metadata used in wrong function", &CI);
|
||||
}
|
||||
|
||||
switch (ID) {
|
||||
default:
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user