IR: Split MDNode into GenericMDNode and MDNodeFwdDecl

Split `MDNode` into two classes:

  - `GenericMDNode`, which is uniquable (and for now, always starts
    uniqued).  Once `Metadata` is split from the `Value` hierarchy, this
    class will lose the ability to RAUW itself.

  - `MDNodeFwdDecl`, which is used for the "temporary" interface, is
    never uniqued, and isn't managed by `LLVMContext` at all.

I've left most of the guts in `MDNode` for now, but I'll incrementally
move things to the right places (or delete the functionality, as
appropriate).

Part of PR21532.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222205 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2014-11-18 00:37:17 +00:00
parent 8ce35351f8
commit 2c38b004d9
5 changed files with 128 additions and 56 deletions

View File

@@ -45,7 +45,9 @@ protected:
public:
static bool classof(const Value *V) {
return V->getValueID() == MDNodeVal || V->getValueID() == MDStringVal;
return V->getValueID() == GenericMDNodeVal ||
V->getValueID() == MDNodeFwdDeclVal ||
V->getValueID() == MDStringVal;
}
};
@@ -137,14 +139,16 @@ struct DenseMapInfo<AAMDNodes> {
class MDNodeOperand;
//===----------------------------------------------------------------------===//
/// \brief Generic tuple of metadata.
/// \brief Tuple of metadata.
class MDNode : public Metadata {
MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
friend class MDNodeOperand;
friend class LLVMContextImpl;
/// \brief If the MDNode is uniqued cache the hash to speed up lookup.
protected:
// TODO: Sink this into GenericMDNode. Can't do this until operands are
// allocated at the front (currently they're at the back).
unsigned Hash;
/// \brief Subclass data enums.
@@ -174,7 +178,8 @@ class MDNode : public Metadata {
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
~MDNode();
MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);
MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
bool isFunctionLocal);
static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
FunctionLocalness FL, bool Insert = true);
@@ -223,12 +228,10 @@ public:
/// code because it recursively visits all the MDNode's operands.
const Function *getFunction() const;
/// \brief Get the hash, if any.
unsigned getHash() const { return Hash; }
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == MDNodeVal;
return V->getValueID() == GenericMDNodeVal ||
V->getValueID() == MDNodeFwdDeclVal;
}
/// \brief Check whether MDNode is a vtable access.
@@ -241,10 +244,8 @@ public:
static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
private:
/// \brief Delete this node. Only when there are no uses.
void destroy();
protected:
bool isNotUniqued() const {
return (getSubclassDataFromValue() & NotUniquedBit) != 0;
}
@@ -257,6 +258,61 @@ private:
}
};
/// \brief Generic metadata node.
///
/// Generic metadata nodes, with opt-out support for uniquing.
///
/// Although nodes are uniqued by default, \a GenericMDNode has no support for
/// RAUW. If an operand change (due to RAUW or otherwise) causes a uniquing
/// collision, the uniquing bit is dropped.
///
/// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped).
/// TODO: Drop support for RAUW.
class GenericMDNode : public MDNode {
friend class MDNode;
GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
: MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal) {}
~GenericMDNode();
public:
/// \brief Get the hash, if any.
unsigned getHash() const { return Hash; }
static bool classof(const Value *V) {
return V->getValueID() == GenericMDNodeVal;
}
private:
/// \brief Delete this node. Only when there are no uses.
void destroy();
friend class MDNode;
friend class LLVMContextImpl;
};
/// \brief Forward declaration of metadata.
///
/// Forward declaration of metadata, in the form of a metadata node. Unlike \a
/// GenericMDNode, this class has support for RAUW and is suitable for forward
/// references.
class MDNodeFwdDecl : public MDNode {
friend class MDNode;
MDNodeFwdDecl(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
: MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {}
~MDNodeFwdDecl() {}
public:
static bool classof(const Value *V) {
return V->getValueID() == MDNodeFwdDeclVal;
}
private:
/// \brief Delete this node. Only when there are no uses.
void destroy();
friend class MDNode;
};
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///

View File

@@ -345,7 +345,8 @@ public:
ConstantStructVal, // This is an instance of ConstantStruct
ConstantVectorVal, // This is an instance of ConstantVector
ConstantPointerNullVal, // This is an instance of ConstantPointerNull
MDNodeVal, // This is an instance of MDNode
GenericMDNodeVal, // This is an instance of GenericMDNode
MDNodeFwdDeclVal, // This is an instance of MDNodeFwdDecl
MDStringVal, // This is an instance of MDString
InlineAsmVal, // This is an instance of InlineAsm
InstructionVal, // This is an instance of Instruction
@@ -681,7 +682,8 @@ template <> struct isa_impl<GlobalObject, Value> {
template <> struct isa_impl<MDNode, Value> {
static inline bool doit(const Value &Val) {
return Val.getValueID() == Value::MDNodeVal;
return Val.getValueID() == Value::GenericMDNodeVal ||
Val.getValueID() == Value::MDNodeFwdDeclVal;
}
};