Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
- void destroyConstantImpl();
void replaceUsesOfWithOnConstantImpl(Constant *Replacement);
public:
/// vector of constant integers, all equal, and the common value is returned.
const APInt &getUniqueInteger() const;
- /// destroyConstant - Called if some element of this constant is no longer
- /// valid. At this point only other constants may be on the use_list for this
+ /// Called if some element of this constant is no longer valid.
+ /// At this point only other constants may be on the use_list for this
/// constant. Any constants on our Use list must also be destroy'd. The
/// implementation must be sure to remove the constant from the list of
- /// available cached constants. Implementations should call
- /// destroyConstantImpl as the last thing they do, to destroy all users and
- /// delete this.
- virtual void destroyConstant() { llvm_unreachable("Not reached!"); }
+ /// available cached constants. Implementations should implement
+ /// destroyConstantImpl to remove constants from any pools/maps they are
+ /// contained it.
+ void destroyConstant();
//// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
ConstantInt(const ConstantInt &) = delete;
ConstantInt(IntegerType *Ty, const APInt& V);
APInt Val;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
// allocate space for exactly zero operands
void *operator new(size_t s) {
void *operator new(size_t, unsigned) = delete;
ConstantFP(const ConstantFP &) = delete;
friend class LLVMContextImpl;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
ConstantFP(Type *Ty, const APFloat& V);
protected:
class ConstantAggregateZero : public Constant {
void *operator new(size_t, unsigned) = delete;
ConstantAggregateZero(const ConstantAggregateZero &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
explicit ConstantAggregateZero(Type *ty)
: Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
public:
static ConstantAggregateZero *get(Type *Ty);
- void destroyConstant() override;
-
/// getSequentialElement - If this CAZ has array or vector type, return a zero
/// with the right element type.
Constant *getSequentialElement() const;
class ConstantArray : public Constant {
friend struct ConstantAggrKeyType<ConstantArray>;
ConstantArray(const ConstantArray &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
public:
return cast<ArrayType>(Value::getType());
}
- void destroyConstant() override;
void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
class ConstantStruct : public Constant {
friend struct ConstantAggrKeyType<ConstantStruct>;
ConstantStruct(const ConstantStruct &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
public:
return cast<StructType>(Value::getType());
}
- void destroyConstant() override;
void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
class ConstantVector : public Constant {
friend struct ConstantAggrKeyType<ConstantVector>;
ConstantVector(const ConstantVector &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
public:
/// elements have the same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
- void destroyConstant() override;
void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
class ConstantPointerNull : public Constant {
void *operator new(size_t, unsigned) = delete;
ConstantPointerNull(const ConstantPointerNull &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
explicit ConstantPointerNull(PointerType *T)
: Constant(T,
/// get() - Static factory methods - Return objects of the specified value
static ConstantPointerNull *get(PointerType *T);
- void destroyConstant() override;
-
/// getType - Specialize the getType() method to always return an PointerType,
/// which reduces the amount of casting needed in parts of the compiler.
///
ConstantDataSequential *Next;
void *operator new(size_t, unsigned) = delete;
ConstantDataSequential(const ConstantDataSequential &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
/// host endianness of the data elements.
StringRef getRawDataValues() const;
- void destroyConstant() override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
static bool classof(const Value *V) {
void *operator new(size_t, unsigned) = delete;
void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
+
+ friend class Constant;
+ void destroyConstantImpl();
+
public:
/// get - Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
Function *getFunction() const { return (Function*)Op<0>().get(); }
BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
- void destroyConstant() override;
void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
class ConstantExpr : public Constant {
friend struct ConstantExprKeyType;
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
: Constant(ty, ConstantExprVal, Ops, NumOps) {
/// would make it harder to remove ConstantExprs altogether.
Instruction *getAsInstruction();
- void destroyConstant() override;
void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
class UndefValue : public Constant {
void *operator new(size_t, unsigned) = delete;
UndefValue(const UndefValue &) = delete;
+
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
protected:
/// \brief Return the number of elements in the array, vector, or struct.
unsigned getNumElements() const;
- void destroyConstant() override;
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == UndefValueVal;
// (19 + 3 + 2 + 1 + 2 + 5) == 32.
unsigned SubClassData : GlobalValueSubClassDataBits;
+ friend class Constant;
+ void destroyConstantImpl();
+
protected:
/// \brief The intrinsic ID for this subclass (which must be a Function).
///
/// @}
- /// Override from Constant class.
- void destroyConstant() override;
-
/// Return true if the primary definition of this global value is outside of
/// the current translation unit.
bool isDeclaration() const;
return nullptr;
}
+void Constant::destroyConstant() {
+ /// First call destroyConstantImpl on the subclass. This gives the subclass
+ /// a chance to remove the constant from any maps/pools it's contained in.
+ switch (getValueID()) {
+ default:
+ llvm_unreachable("Not a constant!");
+#define HANDLE_CONSTANT(Name) \
+ case Value::Name##Val: \
+ cast<Name>(this)->destroyConstantImpl(); \
+ break;
+#include "llvm/IR/Value.def"
+ }
-void Constant::destroyConstantImpl() {
// When a Constant is destroyed, there may be lingering
// references to the constant by other constants in the constant pool. These
// constants are implicitly dependent on the module that is being deleted,
//
while (!use_empty()) {
Value *V = user_back();
-#ifndef NDEBUG // Only in -g mode...
+#ifndef NDEBUG // Only in -g mode...
if (!isa<Constant>(V)) {
dbgs() << "While deleting: " << *this
- << "\n\nUse still stuck around after Def is destroyed: "
- << *V << "\n\n";
+ << "\n\nUse still stuck around after Def is destroyed: " << *V
+ << "\n\n";
}
#endif
assert(isa<Constant>(V) && "References remain to Constant being destroyed");
return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix));
}
+/// Remove the constant from the constant table.
+void ConstantInt::destroyConstantImpl() {
+ llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!");
+}
+
//===----------------------------------------------------------------------===//
// ConstantFP
//===----------------------------------------------------------------------===//
return Val.bitwiseIsEqual(V);
}
+/// Remove the constant from the constant table.
+void ConstantFP::destroyConstantImpl() {
+ llvm_unreachable("You can't ConstantInt->destroyConstantImpl()!");
+}
+
//===----------------------------------------------------------------------===//
// ConstantAggregateZero Implementation
//===----------------------------------------------------------------------===//
/// destroyConstant - Remove the constant from the constant table.
///
-void ConstantAggregateZero::destroyConstant() {
+void ConstantAggregateZero::destroyConstantImpl() {
getContext().pImpl->CAZConstants.erase(getType());
- destroyConstantImpl();
}
/// destroyConstant - Remove the constant from the constant table...
///
-void ConstantArray::destroyConstant() {
+void ConstantArray::destroyConstantImpl() {
getType()->getContext().pImpl->ArrayConstants.remove(this);
- destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
-void ConstantStruct::destroyConstant() {
+void ConstantStruct::destroyConstantImpl() {
getType()->getContext().pImpl->StructConstants.remove(this);
- destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
-void ConstantVector::destroyConstant() {
+void ConstantVector::destroyConstantImpl() {
getType()->getContext().pImpl->VectorConstants.remove(this);
- destroyConstantImpl();
}
/// getSplatValue - If this is a splat vector constant, meaning that all of
return cast<ConstantInt>(C)->getValue();
}
-
//---- ConstantPointerNull::get() implementation.
//
// destroyConstant - Remove the constant from the constant table...
//
-void ConstantPointerNull::destroyConstant() {
+void ConstantPointerNull::destroyConstantImpl() {
getContext().pImpl->CPNConstants.erase(getType());
- // Free the constant and any dangling references to it.
- destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table.
//
-void UndefValue::destroyConstant() {
+void UndefValue::destroyConstantImpl() {
// Free the constant and any dangling references to it.
getContext().pImpl->UVConstants.erase(getType());
- destroyConstantImpl();
}
//---- BlockAddress::get() implementation.
// destroyConstant - Remove the constant from the constant table.
//
-void BlockAddress::destroyConstant() {
+void BlockAddress::destroyConstantImpl() {
getFunction()->getType()->getContext().pImpl
->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
getBasicBlock()->AdjustBlockAddressRefCount(-1);
- destroyConstantImpl();
}
void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
// destroyConstant - Remove the constant from the constant table...
//
-void ConstantExpr::destroyConstant() {
+void ConstantExpr::destroyConstantImpl() {
getType()->getContext().pImpl->ExprConstants.remove(this);
- destroyConstantImpl();
}
const char *ConstantExpr::getOpcodeName() const {
return *Entry = new ConstantDataVector(Ty, Slot.first().data());
}
-void ConstantDataSequential::destroyConstant() {
+void ConstantDataSequential::destroyConstantImpl() {
// Remove the constant from the StringMap.
StringMap<ConstantDataSequential*> &CDSConstants =
getType()->getContext().pImpl->CDSConstants;
// If we were part of a list, make sure that we don't delete the list that is
// still owned by the uniquing map.
Next = nullptr;
-
- // Finally, actually delete it.
- destroyConstantImpl();
}
/// get() constructors - Return a constant with array type with an element
getParent()->dematerialize(this);
}
-/// Override destroyConstant to make sure it doesn't get called on
+/// Override destroyConstantImpl to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
-void GlobalValue::destroyConstant() {
- llvm_unreachable("You can't GV->destroyConstant()!");
+void GlobalValue::destroyConstantImpl() {
+ llvm_unreachable("You can't GV->destroyConstantImpl()!");
}
/// copyAttributesFrom - copy all additional attributes (those not needed to