/// Get the value of the clause at index Idx. Use isCatch/isFilter to
/// determine what type of clause this is.
Constant *getClause(unsigned Idx) const {
- return cast<Constant>(OperandList[Idx + 1]);
+ return cast<Constant>(getOperandList()[Idx + 1]);
}
/// isCatch - Return 'true' if the clause and index Idx is a catch clause.
bool isCatch(unsigned Idx) const {
- return !isa<ArrayType>(OperandList[Idx + 1]->getType());
+ return !isa<ArrayType>(getOperandList()[Idx + 1]->getType());
}
/// isFilter - Return 'true' if the clause and index Idx is a filter clause.
bool isFilter(unsigned Idx) const {
- return isa<ArrayType>(OperandList[Idx + 1]->getType());
+ return isa<ArrayType>(getOperandList()[Idx + 1]->getType());
}
/// getNumClauses - Get the number of clauses for this landing pad.
template <unsigned MINARITY = 1>
struct HungoffOperandTraits {
static Use *op_begin(User* U) {
- return U->OperandList;
+ return U->getOperandList();
}
static Use *op_end(User* U) {
- return U->OperandList + U->getNumOperands();
+ return U->getOperandList() + U->getNumOperands();
}
static unsigned operands(const User *U) {
return U->getNumOperands();
/// prefixed to some derived class instance. For nodes of resizable variable
/// arity (e.g. PHINodes, SwitchInst etc.), this memory will be dynamically
/// allocated and should be destroyed by the classes' virtual dtor.
- Use *OperandList;
+ Use *LegacyOperandList;
+protected:
void *operator new(size_t s, unsigned Us);
+
User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
- : Value(ty, vty), OperandList(OpList) {
+ : Value(ty, vty) {
+ setOperandList(OpList);
NumOperands = NumOps;
}
public:
~User() override {
// drop the hung off uses.
- Use::zap(OperandList, OperandList + NumOperands, HasHungOffUses);
+ Use::zap(getOperandList(), getOperandList() + NumOperands, HasHungOffUses);
if (HasHungOffUses) {
- OperandList = nullptr;
+ setOperandList(nullptr);
// Reset NumOperands so User::operator delete() does the right thing.
NumOperands = 0;
}
template <int Idx> const Use &Op() const {
return OpFrom<Idx>(this);
}
+private:
+ void setOperandList(Use *NewList) {
+ LegacyOperandList = NewList;
+ }
public:
+ Use *getOperandList() const {
+ return LegacyOperandList;
+ }
Value *getOperand(unsigned i) const {
assert(i < NumOperands && "getOperand() out of range!");
- return OperandList[i];
+ return getOperandList()[i];
}
void setOperand(unsigned i, Value *Val) {
assert(i < NumOperands && "setOperand() out of range!");
assert((!isa<Constant>((const Value*)this) ||
isa<GlobalValue>((const Value*)this)) &&
"Cannot mutate a constant with setOperand!");
- OperandList[i] = Val;
+ getOperandList()[i] = Val;
}
const Use &getOperandUse(unsigned i) const {
assert(i < NumOperands && "getOperandUse() out of range!");
- return OperandList[i];
+ return getOperandList()[i];
}
Use &getOperandUse(unsigned i) {
assert(i < NumOperands && "getOperandUse() out of range!");
- return OperandList[i];
+ return getOperandList()[i];
}
unsigned getNumOperands() const { return NumOperands; }
typedef iterator_range<op_iterator> op_range;
typedef iterator_range<const_op_iterator> const_op_range;
- inline op_iterator op_begin() { return OperandList; }
- inline const_op_iterator op_begin() const { return OperandList; }
- inline op_iterator op_end() { return OperandList+NumOperands; }
- inline const_op_iterator op_end() const { return OperandList+NumOperands; }
+ inline op_iterator op_begin() { return getOperandList(); }
+ inline const_op_iterator op_begin() const { return getOperandList(); }
+ inline op_iterator op_end() {
+ return getOperandList() + NumOperands;
+ }
+ inline const_op_iterator op_end() const {
+ return getOperandList() + NumOperands;
+ }
inline op_range operands() {
return op_range(op_begin(), op_end());
}
IdxList.size() + 1),
SrcElementTy(SrcElementTy) {
Op<0>() = C;
+ Use *OperandList = getOperandList();
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
OperandList[i+1] = IdxList[i];
}
// Keep track of whether all the values in the array are "ToC".
bool AllSame = true;
+ Use *OperandList = getOperandList();
for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
Constant *Val = cast<Constant>(O->get());
if (Val == From) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
+ Use *OperandList = getOperandList();
unsigned OperandToUpdate = U-OperandList;
assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
}
// Update to the new value.
+ Use *OperandList = getOperandList();
if (Constant *C = getContext().pImpl->VectorConstants.replaceOperandsInPlace(
Values, this, From, ToC, NumUpdated, U - OperandList))
replaceUsesOfWithOnConstantImpl(C);
}
// Update to the new value.
+ Use *OperandList = getOperandList();
if (Constant *C = getContext().pImpl->ExprConstants.replaceOperandsInPlace(
NewOps, this, From, To, NumUpdated, U - OperandList))
replaceUsesOfWithOnConstantImpl(C);
LP.getNumOperands()),
ReservedSpace(LP.getNumOperands()) {
allocHungoffUses(LP.getNumOperands());
- Use *OL = OperandList, *InOL = LP.OperandList;
+ Use *OL = getOperandList();
+ const Use *InOL = LP.getOperandList();
for (unsigned I = 0, E = ReservedSpace; I != E; ++I)
OL[I] = InOL[I];
growOperands(1);
assert(OpNo < ReservedSpace && "Growing didn't work!");
++NumOperands;
- OperandList[OpNo] = Val;
+ getOperandList()[OpNo] = Val;
}
//===----------------------------------------------------------------------===//
: TerminatorInst(SI.getType(), Instruction::Switch, nullptr, 0) {
init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
NumOperands = SI.getNumOperands();
- Use *OL = OperandList, *InOL = SI.OperandList;
+ Use *OL = getOperandList();
+ const Use *InOL = SI.getOperandList();
for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) {
OL[i] = InOL[i];
OL[i+1] = InOL[i+1];
assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
unsigned NumOps = getNumOperands();
- Use *OL = OperandList;
+ Use *OL = getOperandList();
// Overwrite this case with the end of the list.
if (2 + (idx + 1) * 2 != NumOps) {
: TerminatorInst(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr,
nullptr, IBI.getNumOperands()) {
allocHungoffUses(IBI.getNumOperands());
- Use *OL = OperandList, *InOL = IBI.OperandList;
+ Use *OL = getOperandList();
+ const Use *InOL = IBI.getOperandList();
for (unsigned i = 0, E = IBI.getNumOperands(); i != E; ++i)
OL[i] = InOL[i];
SubclassOptionalData = IBI.SubclassOptionalData;
// Initialize some new operands.
assert(OpNo < ReservedSpace && "Growing didn't work!");
NumOperands = OpNo+1;
- OperandList[OpNo] = DestBB;
+ getOperandList()[OpNo] = DestBB;
}
/// removeDestination - This method removes the specified successor from the
assert(idx < getNumOperands()-1 && "Successor index out of range!");
unsigned NumOps = getNumOperands();
- Use *OL = OperandList;
+ Use *OL = getOperandList();
// Replace this value with the last one.
OL[idx+1] = OL[NumOps-1];
Use *Begin = static_cast<Use*>(::operator new(size));
Use *End = Begin + N;
(void) new(End) Use::UserRef(const_cast<User*>(this), 1);
- OperandList = Use::initTags(Begin, End);
+ setOperandList(Use::initTags(Begin, End));
// Tag this operand list as being a hung off.
HasHungOffUses = true;
}
// space to copy the old uses in to the new space.
assert(NewNumUses > OldNumUses && "realloc must grow num uses");
- Use *OldOps = OperandList;
+ Use *OldOps = getOperandList();
allocHungoffUses(NewNumUses, IsPhi);
- Use *NewOps = OperandList;
+ Use *NewOps = getOperandList();
// Now copy from the old operands list to the new one.
std::copy(OldOps, OldOps + OldNumUses, NewOps);
Use *Start = static_cast<Use*>(Storage);
Use *End = Start + Us;
User *Obj = reinterpret_cast<User*>(End);
- Obj->OperandList = Start;
+ Obj->setOperandList(Start);
Obj->HasHungOffUses = false;
Obj->NumOperands = Us;
Use::initTags(Start, End);