aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorGabor Greif <ggreif@gmail.com>2008-05-10 08:32:32 +0000
committerGabor Greif <ggreif@gmail.com>2008-05-10 08:32:32 +0000
commit25bc3228e76ff4e1278ecc3272ed61b5aa3af428 (patch)
treebd2fa60ec2238187a780f4f72f8b77e892cb7e4d /lib/VMCore
parentea280bb4035e10f690b96e26e7cfdd73bb063fe5 (diff)
downloadexternal_llvm-25bc3228e76ff4e1278ecc3272ed61b5aa3af428.zip
external_llvm-25bc3228e76ff4e1278ecc3272ed61b5aa3af428.tar.gz
external_llvm-25bc3228e76ff4e1278ecc3272ed61b5aa3af428.tar.bz2
merge of use-diet branch to trunk
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50943 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/ConstantFold.cpp16
-rw-r--r--lib/VMCore/Constants.cpp182
-rw-r--r--lib/VMCore/Globals.cpp18
-rw-r--r--lib/VMCore/Instructions.cpp412
-rw-r--r--lib/VMCore/Use.cpp131
5 files changed, 524 insertions, 235 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 9f31bcd..5138031 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -332,10 +332,10 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
- return const_cast<Constant*>(CVal->getOperand(CIdx->getZExtValue()));
+ return CVal->getOperand(CIdx->getZExtValue());
} else if (isa<UndefValue>(Idx)) {
// ee({w,x,y,z}, undef) -> w (an arbitrary value).
- return const_cast<Constant*>(CVal->getOperand(0));
+ return CVal->getOperand(0);
}
}
return 0;
@@ -401,7 +401,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
/// return the specified element value. Otherwise return null.
static Constant *GetVectorElement(const Constant *C, unsigned EltNo) {
if (const ConstantVector *CV = dyn_cast<ConstantVector>(C))
- return const_cast<Constant*>(CV->getOperand(EltNo));
+ return CV->getOperand(EltNo);
const Type *EltTy = cast<VectorType>(C->getType())->getElementType();
if (isa<ConstantAggregateZero>(C))
@@ -1222,9 +1222,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2)) {
if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
- Constant *C= ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
- const_cast<Constant*>(CP1->getOperand(i)),
- const_cast<Constant*>(CP2->getOperand(i)));
+ Constant *C = ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
+ CP1->getOperand(i),
+ CP2->getOperand(i));
if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
return CB;
}
@@ -1233,8 +1233,8 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
} else if (pred == ICmpInst::ICMP_EQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ,
- const_cast<Constant*>(CP1->getOperand(i)),
- const_cast<Constant*>(CP2->getOperand(i)));
+ CP1->getOperand(i),
+ CP2->getOperand(i));
if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
return CB;
}
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 0b8fcc4..d0c8373 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -354,7 +354,9 @@ ConstantFP *ConstantFP::get(const Type *Ty, double V) {
ConstantArray::ConstantArray(const ArrayType *T,
const std::vector<Constant*> &V)
- : Constant(T, ConstantArrayVal, new Use[V.size()], V.size()) {
+ : Constant(T, ConstantArrayVal,
+ OperandTraits<ConstantArray>::op_end(this) - V.size(),
+ V.size()) {
assert(V.size() == T->getNumElements() &&
"Invalid initializer vector for constant array");
Use *OL = OperandList;
@@ -369,13 +371,12 @@ ConstantArray::ConstantArray(const ArrayType *T,
}
}
-ConstantArray::~ConstantArray() {
- delete [] OperandList;
-}
ConstantStruct::ConstantStruct(const StructType *T,
const std::vector<Constant*> &V)
- : Constant(T, ConstantStructVal, new Use[V.size()], V.size()) {
+ : Constant(T, ConstantStructVal,
+ OperandTraits<ConstantStruct>::op_end(this) - V.size(),
+ V.size()) {
assert(V.size() == T->getNumElements() &&
"Invalid initializer vector for constant structure");
Use *OL = OperandList;
@@ -392,14 +393,12 @@ ConstantStruct::ConstantStruct(const StructType *T,
}
}
-ConstantStruct::~ConstantStruct() {
- delete [] OperandList;
-}
-
ConstantVector::ConstantVector(const VectorType *T,
const std::vector<Constant*> &V)
- : Constant(T, ConstantVectorVal, new Use[V.size()], V.size()) {
+ : Constant(T, ConstantVectorVal,
+ OperandTraits<ConstantVector>::op_end(this) - V.size(),
+ V.size()) {
Use *OL = OperandList;
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
@@ -412,10 +411,8 @@ ConstantVector::ConstantVector(const VectorType *T,
}
}
-ConstantVector::~ConstantVector() {
- delete [] OperandList;
-}
+namespace llvm {
// We declare several classes private to this file, so use an anonymous
// namespace
namespace {
@@ -424,49 +421,54 @@ namespace {
/// behind the scenes to implement unary constant exprs.
class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Op;
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
return User::operator new(s, 1);
}
UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
- : ConstantExpr(Ty, Opcode, &Op, 1), Op(C, this) {}
+ : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
+ Op<0>() = C;
+ }
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement binary constant exprs.
class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Ops[2];
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
return User::operator new(s, 2);
}
BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
- : ConstantExpr(C1->getType(), Opcode, Ops, 2) {
- Ops[0].init(C1, this);
- Ops[1].init(C2, this);
+ : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
+ Op<0>().init(C1, this);
+ Op<1>().init(C2, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// SelectConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement select constant exprs.
class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Ops[3];
public:
// allocate space for exactly three operands
void *operator new(size_t s) {
return User::operator new(s, 3);
}
SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
- : ConstantExpr(C2->getType(), Instruction::Select, Ops, 3) {
- Ops[0].init(C1, this);
- Ops[1].init(C2, this);
- Ops[2].init(C3, this);
+ : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
+ Op<0>().init(C1, this);
+ Op<1>().init(C2, this);
+ Op<2>().init(C3, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// ExtractElementConstantExpr - This class is private to
@@ -474,7 +476,6 @@ public:
/// extractelement constant exprs.
class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Ops[2];
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
@@ -482,10 +483,12 @@ public:
}
ExtractElementConstantExpr(Constant *C1, Constant *C2)
: ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
- Instruction::ExtractElement, Ops, 2) {
- Ops[0].init(C1, this);
- Ops[1].init(C2, this);
+ Instruction::ExtractElement, &Op<0>(), 2) {
+ Op<0>().init(C1, this);
+ Op<1>().init(C2, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// InsertElementConstantExpr - This class is private to
@@ -493,7 +496,6 @@ public:
/// insertelement constant exprs.
class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Ops[3];
public:
// allocate space for exactly three operands
void *operator new(size_t s) {
@@ -501,11 +503,13 @@ public:
}
InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
: ConstantExpr(C1->getType(), Instruction::InsertElement,
- Ops, 3) {
- Ops[0].init(C1, this);
- Ops[1].init(C2, this);
- Ops[2].init(C3, this);
+ &Op<0>(), 3) {
+ Op<0>().init(C1, this);
+ Op<1>().init(C2, this);
+ Op<2>().init(C3, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// ShuffleVectorConstantExpr - This class is private to
@@ -513,7 +517,6 @@ public:
/// shufflevector constant exprs.
class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
- Use Ops[3];
public:
// allocate space for exactly three operands
void *operator new(size_t s) {
@@ -521,32 +524,27 @@ public:
}
ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
: ConstantExpr(C1->getType(), Instruction::ShuffleVector,
- Ops, 3) {
- Ops[0].init(C1, this);
- Ops[1].init(C2, this);
- Ops[2].init(C3, this);
+ &Op<0>(), 3) {
+ Op<0>().init(C1, this);
+ Op<1>().init(C2, this);
+ Op<2>().init(C3, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
/// used behind the scenes to implement getelementpr constant exprs.
class VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr {
GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
- const Type *DestTy)
- : ConstantExpr(DestTy, Instruction::GetElementPtr,
- new Use[IdxList.size()+1], IdxList.size()+1) {
- OperandList[0].init(C, this);
- for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
- OperandList[i+1].init(IdxList[i], this);
- }
+ const Type *DestTy);
public:
static GetElementPtrConstantExpr *Create(Constant *C, const std::vector<Constant*> &IdxList,
- const Type *DestTy) {
- return new(IdxList.size() + 1/*FIXME*/) GetElementPtrConstantExpr(C, IdxList, DestTy);
- }
- ~GetElementPtrConstantExpr() {
- delete [] OperandList;
+ const Type *DestTy) {
+ return new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
// CompareConstantExpr - This class is private to Constants.cpp, and is used
@@ -559,17 +557,77 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
return User::operator new(s, 2);
}
unsigned short predicate;
- Use Ops[2];
CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred,
Constant* LHS, Constant* RHS)
- : ConstantExpr(Type::Int1Ty, opc, Ops, 2), predicate(pred) {
- OperandList[0].init(LHS, this);
- OperandList[1].init(RHS, this);
+ : ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) {
+ Op<0>().init(LHS, this);
+ Op<1>().init(RHS, this);
}
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
} // end anonymous namespace
+template <>
+struct OperandTraits<UnaryConstantExpr> : FixedNumOperandTraits<1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
+
+template <>
+struct OperandTraits<BinaryConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
+
+template <>
+struct OperandTraits<SelectConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
+
+template <>
+struct OperandTraits<ExtractElementConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
+
+template <>
+struct OperandTraits<InsertElementConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
+
+template <>
+struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
+
+
+template <>
+struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> {
+};
+
+GetElementPtrConstantExpr::GetElementPtrConstantExpr
+ (Constant *C,
+ const std::vector<Constant*> &IdxList,
+ const Type *DestTy)
+ : ConstantExpr(DestTy, Instruction::GetElementPtr,
+ OperandTraits<GetElementPtrConstantExpr>::op_end(this)
+ - (IdxList.size()+1),
+ IdxList.size()+1) {
+ OperandList[0].init(C, this);
+ for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+ OperandList[i+1].init(IdxList[i], this);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
+
+
+template <>
+struct OperandTraits<CompareConstantExpr> : FixedNumOperandTraits<2> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
+
+
+} // End llvm namespace
+
// Utility function for determining if a ConstantExpr is a CastOp or not. This
// can't be inline because we don't want to #include Instruction.h into
@@ -815,17 +873,29 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
//===----------------------------------------------------------------------===//
// Factory Function Implementation
+
+// The number of operands for each ConstantCreator::create method is
+// determined by the ConstantTraits template.
// ConstantCreator - A class that is used to create constants by
// ValueMap*. This class should be partially specialized if there is
// something strange that needs to be done to interface to the ctor for the
// constant.
//
namespace llvm {
+ template<class ValType>
+ struct ConstantTraits;
+
+ template<typename T, typename Alloc>
+ struct VISIBILITY_HIDDEN ConstantTraits< std::vector<T, Alloc> > {
+ static unsigned uses(const std::vector<T, Alloc>& v) {
+ return v.size();
+ }
+ };
+
template<class ConstantClass, class TypeClass, class ValType>
struct VISIBILITY_HIDDEN ConstantCreator {
static ConstantClass *create(const TypeClass *Ty, const ValType &V) {
- unsigned FIXME = 0; // = traits<ValType>::uses(V)
- return new(FIXME) ConstantClass(Ty, V);
+ return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
}
};
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index e75b186..1a328d8 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -89,14 +89,13 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
Module *ParentModule, bool ThreadLocal,
unsigned AddressSpace)
: GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
- &Initializer, InitVal != 0, Link, Name),
+ OperandTraits<GlobalVariable>::op_begin(this),
+ InitVal != 0, Link, Name),
isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) {
assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!");
- Initializer.init(InitVal, this);
- } else {
- Initializer.init(0, this);
+ Op<0>().init(InitVal, this);
}
LeakDetector::addGarbageObject(this);
@@ -110,14 +109,13 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
GlobalVariable *Before, bool ThreadLocal,
unsigned AddressSpace)
: GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal,
- &Initializer, InitVal != 0, Link, Name),
+ OperandTraits<GlobalVariable>::op_begin(this),
+ InitVal != 0, Link, Name),
isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) {
if (InitVal) {
assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!");
- Initializer.init(InitVal, this);
- } else {
- Initializer.init(0, this);
+ Op<0>().init(InitVal, this);
}
LeakDetector::addGarbageObject(this);
@@ -169,12 +167,12 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link,
const std::string &Name, Constant* aliasee,
Module *ParentModule)
- : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) {
+ : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
LeakDetector::addGarbageObject(this);
if (aliasee)
assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
- Aliasee.init(aliasee, this);
+ Op<0>().init(aliasee, this);
if (ParentModule)
ParentModule->getAliasList().push_back(this);
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 56bc8167..78e7b17 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -100,18 +100,21 @@ void CallSite::setDoesNotThrow(bool doesNotThrow) {
TerminatorInst::~TerminatorInst() {
}
+//===----------------------------------------------------------------------===//
+// UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
// Out of line virtual method, so the vtable, etc has a home.
UnaryInstruction::~UnaryInstruction() {
}
-
//===----------------------------------------------------------------------===//
// PHINode Class
//===----------------------------------------------------------------------===//
PHINode::PHINode(const PHINode &PN)
: Instruction(PN.getType(), Instruction::PHI,
- new Use[PN.getNumOperands()], PN.getNumOperands()),
+ allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
Use *OL = OperandList;
for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
@@ -121,7 +124,7 @@ PHINode::PHINode(const PHINode &PN)
}
PHINode::~PHINode() {
- delete [] OperandList;
+ dropHungoffUses(OperandList);
}
// removeIncomingValue - Remove an incoming value. This is useful if a
@@ -164,8 +167,9 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
/// 3. If NumOps == NumOperands, trim the reserved space.
///
void PHINode::resizeOperands(unsigned NumOps) {
+ unsigned e = getNumOperands();
if (NumOps == 0) {
- NumOps = (getNumOperands())*3/2;
+ NumOps = e*3/2;
if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common.
} else if (NumOps*2 > NumOperands) {
// No resize needed.
@@ -177,14 +181,13 @@ void PHINode::resizeOperands(unsigned NumOps) {
}
ReservedSpace = NumOps;
- Use *NewOps = new Use[NumOps];
Use *OldOps = OperandList;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ Use *NewOps = allocHungoffUses(NumOps);
+ for (unsigned i = 0; i != e; ++i) {
NewOps[i].init(OldOps[i], this);
- OldOps[i].set(0);
}
- delete [] OldOps;
OperandList = NewOps;
+ if (OldOps) Use::zap(OldOps, OldOps + e, true);
}
/// hasConstantValue - If the specified PHI node always merges together the same
@@ -241,12 +244,11 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
//===----------------------------------------------------------------------===//
CallInst::~CallInst() {
- delete [] OperandList;
}
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
- NumOperands = NumParams+1;
- Use *OL = OperandList = new Use[NumParams+1];
+ assert(NumOperands == NumParams+1 && "NumOperands not set up?");
+ Use *OL = OperandList;
OL[0].init(Func, this);
const FunctionType *FTy =
@@ -265,8 +267,8 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
- NumOperands = 3;
- Use *OL = OperandList = new Use[3];
+ assert(NumOperands == 3 && "NumOperands not set up?");
+ Use *OL = OperandList;
OL[0].init(Func, this);
OL[1].init(Actual1, this);
OL[2].init(Actual2, this);
@@ -287,8 +289,8 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
}
void CallInst::init(Value *Func, Value *Actual) {
- NumOperands = 2;
- Use *OL = OperandList = new Use[2];
+ assert(NumOperands == 2 && "NumOperands not set up?");
+ Use *OL = OperandList;
OL[0].init(Func, this);
OL[1].init(Actual, this);
@@ -305,8 +307,8 @@ void CallInst::init(Value *Func, Value *Actual) {
}
void CallInst::init(Value *Func) {
- NumOperands = 1;
- Use *OL = OperandList = new Use[1];
+ assert(NumOperands == 1 && "NumOperands not set up?");
+ Use *OL = OperandList;
OL[0].init(Func, this);
const FunctionType *FTy =
@@ -320,7 +322,9 @@ CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
- Instruction::Call, 0, 0, InsertBefore) {
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - 2,
+ 2, InsertBefore) {
init(Func, Actual);
setName(Name);
}
@@ -329,7 +333,9 @@ CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
- Instruction::Call, 0, 0, InsertAtEnd) {
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - 2,
+ 2, InsertAtEnd) {
init(Func, Actual);
setName(Name);
}
@@ -337,7 +343,9 @@ CallInst::CallInst(Value *Func, const std::string &Name,
Instruction *InsertBefore)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
- Instruction::Call, 0, 0, InsertBefore) {
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - 1,
+ 1, InsertBefore) {
init(Func);
setName(Name);
}
@@ -346,13 +354,16 @@ CallInst::CallInst(Value *Func, const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
->getElementType())->getReturnType(),
- Instruction::Call, 0, 0, InsertAtEnd) {
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - 1,
+ 1, InsertAtEnd) {
init(Func);
setName(Name);
}
CallInst::CallInst(const CallInst &CI)
- : Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
+ : Instruction(CI.getType(), Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
CI.getNumOperands()) {
setParamAttrs(CI.getParamAttrs());
SubclassData = CI.SubclassData;
@@ -384,14 +395,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) {
// InvokeInst Implementation
//===----------------------------------------------------------------------===//
-InvokeInst::~InvokeInst() {
- delete [] OperandList;
-}
-
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
- NumOperands = 3+NumArgs;
- Use *OL = OperandList = new Use[3+NumArgs];
+ assert(NumOperands == 3+NumArgs && "NumOperands not set up?");
+ Use *OL = OperandList;
OL[0].init(Fn, this);
OL[1].init(IfNormal, this);
OL[2].init(IfException, this);
@@ -414,7 +421,8 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
- new Use[II.getNumOperands()], II.getNumOperands()) {
+ OperandTraits<InvokeInst>::op_end(this) - II.getNumOperands(),
+ II.getNumOperands()) {
setParamAttrs(II.getParamAttrs());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
@@ -456,45 +464,51 @@ void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
- &RetVal, RI.getNumOperands()) {
+ OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(),
+ RI.getNumOperands()) {
unsigned N = RI.getNumOperands();
- if (N == 1)
- RetVal.init(RI.RetVal, this);
+ if (N == 1)
+ Op<0>().init(RI.Op<0>(), this);
else if (N) {
- Use *OL = OperandList = new Use[N];
+ Use *OL = OperandList;
for (unsigned i = 0; i < N; ++i)
OL[i].init(RI.getOperand(i), this);
}
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
+ retVal != 0, InsertBefore) {
if (retVal)
init(&retVal, 1);
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
+ retVal != 0, InsertAtEnd) {
if (retVal)
init(&retVal, 1);
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this),
+ 0, InsertAtEnd) {
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
Instruction *InsertBefore)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertBefore) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - N,
+ N, InsertBefore) {
if (N != 0)
init(retVals, N);
}
ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertAtEnd) {
- if (N != 0)
- init(retVals, N);
-}
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N) {
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - N,
+ N, InsertAtEnd) {
if (N != 0)
init(retVals, N);
}
@@ -507,11 +521,11 @@ void ReturnInst::init(Value * const* retVals, unsigned N) {
Value *V = *retVals;
if (V->getType() == Type::VoidTy)
return;
- RetVal.init(V, this);
+ Op<0>().init(V, this);
return;
}
- Use *OL = OperandList = new Use[NumOperands];
+ Use *OL = OperandList;
for (unsigned i = 0; i < NumOperands; ++i) {
Value *V = *retVals++;
assert(!isa<BasicBlock>(V) &&
@@ -537,8 +551,6 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
}
ReturnInst::~ReturnInst() {
- if (NumOperands > 1)
- delete [] OperandList;
}
//===----------------------------------------------------------------------===//
@@ -603,33 +615,41 @@ void BranchInst::AssertOK() {
}
BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore)
- : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertBefore) {
+ : TerminatorInst(Type::VoidTy, Instruction::Br,
+ OperandTraits<BranchInst>::op_end(this) - 1,
+ 1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
+ Op<0>().init(reinterpret_cast<Value*>(IfTrue), this);
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
-: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertBefore) {
- Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
- Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
- Ops[2].init(Cond, this);
+ : TerminatorInst(Type::VoidTy, Instruction::Br,
+ OperandTraits<BranchInst>::op_end(this) - 3,
+ 3, InsertBefore) {
+ Op<0>().init(reinterpret_cast<Value*>(IfTrue), this);
+ Op<1>().init(reinterpret_cast<Value*>(IfFalse), this);
+ Op<2>().init(Cond, this);
#ifndef NDEBUG
AssertOK();
#endif
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertAtEnd) {
+ : TerminatorInst(Type::VoidTy, Instruction::Br,
+ OperandTraits<BranchInst>::op_end(this) - 1,
+ 1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
+ Op<0>().init(reinterpret_cast<Value*>(IfTrue), this);
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertAtEnd) {
- Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
- Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
- Ops[2].init(Cond, this);
+ : TerminatorInst(Type::VoidTy, Instruction::Br,
+ OperandTraits<BranchInst>::op_end(this) - 3,
+ 3, InsertAtEnd) {
+ Op<0>().init(reinterpret_cast<Value*>(IfTrue), this);
+ Op<1>().init(reinterpret_cast<Value*>(IfFalse), this);
+ Op<2>().init(Cond, this);
#ifndef NDEBUG
AssertOK();
#endif
@@ -637,7 +657,9 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BranchInst::BranchInst(const BranchInst &BI) :
- TerminatorInst(Type::VoidTy, Instruction::Br, Ops, BI.getNumOperands()) {
+ TerminatorInst(Type::VoidTy, Instruction::Br,
+ OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
+ BI.getNumOperands()) {
OperandList[0].init(BI.getOperand(0), this);
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
@@ -869,18 +891,24 @@ void StoreInst::AssertOK() {
StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertBefore) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(false);
setAlignment(0);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertAtEnd) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(false);
setAlignment(0);
AssertOK();
@@ -888,9 +916,12 @@ StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
Instruction *InsertBefore)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertBefore) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(isVolatile);
setAlignment(0);
AssertOK();
@@ -898,9 +929,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, Instruction *InsertBefore)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertBefore) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(isVolatile);
setAlignment(Align);
AssertOK();
@@ -908,9 +942,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertAtEnd) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(isVolatile);
setAlignment(Align);
AssertOK();
@@ -918,9 +955,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
BasicBlock *InsertAtEnd)
- : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
- Ops[0].init(val, this);
- Ops[1].init(addr, this);
+ : Instruction(Type::VoidTy, Store,
+ OperandTraits<StoreInst>::op_begin(this),
+ OperandTraits<StoreInst>::operands(this),
+ InsertAtEnd) {
+ Op<0>().init(val, this);
+ Op<1>().init(addr, this);
setVolatile(isVolatile);
setAlignment(0);
AssertOK();
@@ -940,8 +980,8 @@ static unsigned retrieveAddrSpace(const Value *Val) {
}
void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
- NumOperands = 1+NumIdx;
- Use *OL = OperandList = new Use[NumOperands];
+ assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
+ Use *OL = OperandList;
OL[0].init(Ptr, this);
for (unsigned i = 0; i != NumIdx; ++i)
@@ -949,17 +989,29 @@ void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
}
void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
- NumOperands = 2;
- Use *OL = OperandList = new Use[2];
+ assert(NumOperands == 2 && "NumOperands not initialized?");
+ Use *OL = OperandList;
OL[0].init(Ptr, this);
OL[1].init(Idx, this);
}
+GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
+ : Instruction(reinterpret_cast<const Type*>(GEPI.getType()), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - GEPI.getNumOperands(),
+ GEPI.getNumOperands()) {
+ Use *OL = OperandList;
+ Use *GEPIOL = GEPI.OperandList;
+ for (unsigned i = 0, E = NumOperands; i != E; ++i)
+ OL[i].init(GEPIOL[i], this);
+}
+
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, Instruction *InBe)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
retrieveAddrSpace(Ptr)),
- GetElementPtr, 0, 0, InBe) {
+ GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+ 2, InBe) {
init(Ptr, Idx);
setName(Name);
}
@@ -968,15 +1020,13 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
const std::string &Name, BasicBlock *IAE)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
retrieveAddrSpace(Ptr)),
- GetElementPtr, 0, 0, IAE) {
+ GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+ 2, IAE) {
init(Ptr, Idx);
setName(Name);
}
-GetElementPtrInst::~GetElementPtrInst() {
- delete[] OperandList;
-}
-
// getIndexedType - Returns the type of the element that would be loaded with
// a load instruction with the specified parameters.
//
@@ -1067,11 +1117,13 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
const std::string &Name,
Instruction *InsertBef)
: Instruction(cast<VectorType>(Val->getType())->getElementType(),
- ExtractElement, Ops, 2, InsertBef) {
+ ExtractElement,
+ OperandTraits<ExtractElementInst>::op_begin(this),
+ 2, InsertBef) {
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
- Ops[0].init(Val, this);
- Ops[1].init(Index, this);
+ Op<0>().init(Val, this);
+ Op<1>().init(Index, this);
setName(Name);
}
@@ -1079,12 +1131,14 @@ ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
const std::string &Name,
Instruction *InsertBef)
: Instruction(cast<VectorType>(Val->getType())->getElementType(),
- ExtractElement, Ops, 2, InsertBef) {
+ ExtractElement,
+ OperandTraits<ExtractElementInst>::op_begin(this),
+ 2, InsertBef) {
Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
- Ops[0].init(Val, this);
- Ops[1].init(Index, this);
+ Op<0>().init(Val, this);
+ Op<1>().init(Index, this);
setName(Name);
}
@@ -1093,12 +1147,14 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
const std::string &Name,
BasicBlock *InsertAE)
: Instruction(cast<VectorType>(Val->getType())->getElementType(),
- ExtractElement, Ops, 2, InsertAE) {
+ ExtractElement,
+ OperandTraits<ExtractElementInst>::op_begin(this),
+ 2, InsertAE) {
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
- Ops[0].init(Val, this);
- Ops[1].init(Index, this);
+ Op<0>().init(Val, this);
+ Op<1>().init(Index, this);
setName(Name);
}
@@ -1106,13 +1162,15 @@ ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
const std::string &Name,
BasicBlock *InsertAE)
: Instruction(cast<VectorType>(Val->getType())->getElementType(),
- ExtractElement, Ops, 2, InsertAE) {
+ ExtractElement,
+ OperandTraits<ExtractElementInst>::op_begin(this),
+ 2, InsertAE) {
Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
- Ops[0].init(Val, this);
- Ops[1].init(Index, this);
+ Op<0>().init(Val, this);
+ Op<1>().init(Index, this);
setName(Name);
}
@@ -1129,33 +1187,38 @@ bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
//===----------------------------------------------------------------------===//
InsertElementInst::InsertElementInst(const InsertElementInst &IE)
- : Instruction(IE.getType(), InsertElement, Ops, 3) {
- Ops[0].init(IE.Ops[0], this);
- Ops[1].init(IE.Ops[1], this);
- Ops[2].init(IE.Ops[2], this);
+ : Instruction(IE.getType(), InsertElement,
+ OperandTraits<InsertElementInst>::op_begin(this), 3) {
+ Op<0>().init(IE.Op<0>(), this);
+ Op<1>().init(IE.Op<1>(), this);
+ Op<2>().init(IE.Op<2>(), this);
}
InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
const std::string &Name,
Instruction *InsertBef)
- : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
+ : Instruction(Vec->getType(), InsertElement,
+ OperandTraits<InsertElementInst>::op_begin(this),
+ 3, InsertBef) {
assert(isValidOperands(Vec, Elt, Index) &&
"Invalid insertelement instruction operands!");
- Ops[0].init(Vec, this);
- Ops[1].init(Elt, this);
- Ops[2].init(Index, this);
+ Op<0>().init(Vec, this);
+ Op<1>().init(Elt, this);
+ Op<2>().init(Index, this);
setName(Name);
}
InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
const std::string &Name,
Instruction *InsertBef)
- : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
+ : Instruction(Vec->getType(), InsertElement,
+ OperandTraits<InsertElementInst>::op_begin(this),
+ 3, InsertBef) {
Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
assert(isValidOperands(Vec, Elt, Index) &&
"Invalid insertelement instruction operands!");
- Ops[0].init(Vec, this);
- Ops[1].init(Elt, this);
- Ops[2].init(Index, this);
+ Op<0>().init(Vec, this);
+ Op<1>().init(Elt, this);
+ Op<2>().init(Index, this);
setName(Name);
}
@@ -1163,27 +1226,31 @@ InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
const std::string &Name,
BasicBlock *InsertAE)
- : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertAE) {
+ : Instruction(Vec->getType(), InsertElement,
+ OperandTraits<InsertElementInst>::op_begin(this),
+ 3, InsertAE) {
assert(isValidOperands(Vec, Elt, Index) &&
"Invalid insertelement instruction operands!");
- Ops[0].init(Vec, this);
- Ops[1].init(Elt, this);
- Ops[2].init(Index, this);
+ Op<0>().init(Vec, this);
+ Op<1>().init(Elt, this);
+ Op<2>().init(Index, this);
setName(Name);
}
InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
const std::string &Name,
BasicBlock *InsertAE)
-: Instruction(Vec->getType(), InsertElement, Ops, 3, InsertAE) {
+: Instruction(Vec->getType(), InsertElement,
+ OperandTraits<InsertElementInst>::op_begin(this),
+ 3, InsertAE) {
Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
assert(isValidOperands(Vec, Elt, Index) &&
"Invalid insertelement instruction operands!");
- Ops[0].init(Vec, this);
- Ops[1].init(Elt, this);
- Ops[2].init(Index, this);
+ Op<0>().init(Vec, this);
+ Op<1>().init(Elt, this);
+ Op<2>().init(Index, this);
setName(Name);
}
@@ -1206,34 +1273,42 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
//===----------------------------------------------------------------------===//
ShuffleVectorInst::ShuffleVectorInst(const ShuffleVectorInst &SV)
- : Instruction(SV.getType(), ShuffleVector, Ops, 3) {
- Ops[0].init(SV.Ops[0], this);
- Ops[1].init(SV.Ops[1], this);
- Ops[2].init(SV.Ops[2], this);
+ : Instruction(SV.getType(), ShuffleVector,
+ OperandTraits<ShuffleVectorInst>::op_begin(this),
+ OperandTraits<ShuffleVectorInst>::operands(this)) {
+ Op<0>().init(SV.Op<0>(), this);
+ Op<1>().init(SV.Op<1>(), this);
+ Op<2>().init(SV.Op<2>(), this);
}
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const std::string &Name,
Instruction *InsertBefore)
- : Instruction(V1->getType(), ShuffleVector, Ops, 3, InsertBefore) {
+ : Instruction(V1->getType(), ShuffleVector,
+ OperandTraits<ShuffleVectorInst>::op_begin(this),
+ OperandTraits<ShuffleVectorInst>::operands(this),
+ InsertBefore) {
assert(isValidOperands(V1, V2, Mask) &&
"Invalid shuffle vector instruction operands!");
- Ops[0].init(V1, this);
- Ops[1].init(V2, this);
- Ops[2].init(Mask, this);
+ Op<0>().init(V1, this);
+ Op<1>().init(V2, this);
+ Op<2>().init(Mask, this);
setName(Name);
}
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const std::string &Name,
BasicBlock *InsertAtEnd)
- : Instruction(V1->getType(), ShuffleVector, Ops, 3, InsertAtEnd) {
+ : Instruction(V1->getType(), ShuffleVector,
+ OperandTraits<ShuffleVectorInst>::op_begin(this),
+ OperandTraits<ShuffleVectorInst>::operands(this),
+ InsertAtEnd) {
assert(isValidOperands(V1, V2, Mask) &&
"Invalid shuffle vector instruction operands!");
- Ops[0].init(V1, this);
- Ops[1].init(V2, this);
- Ops[2].init(Mask, this);
+ Op<0>().init(V1, this);
+ Op<1>().init(V2, this);
+ Op<2>().init(Mask, this);
setName(Name);
}
@@ -1275,9 +1350,12 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const {
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
Instruction *InsertBefore)
- : Instruction(Ty, iType, Ops, 2, InsertBefore) {
- Ops[0].init(S1, this);
- Ops[1].init(S2, this);
+ : Instruction(Ty, iType,
+ OperandTraits<BinaryOperator>::op_begin(this),
+ OperandTraits<BinaryOperator>::operands(this),
+ InsertBefore) {
+ Op<0>().init(S1, this);
+ Op<1>().init(S2, this);
init(iType);
setName(Name);
}
@@ -1285,9 +1363,12 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
BasicBlock *InsertAtEnd)
- : Instruction(Ty, iType, Ops, 2, InsertAtEnd) {
- Ops[0].init(S1, this);
- Ops[1].init(S2, this);
+ : Instruction(Ty, iType,
+ OperandTraits<BinaryOperator>::op_begin(this),
+ OperandTraits<BinaryOperator>::operands(this),
+ InsertAtEnd) {
+ Op<0>().init(S1, this);
+ Op<1>().init(S2, this);
init(iType);
setName(Name);
}
@@ -1482,7 +1563,7 @@ const Value *BinaryOperator::getNotArgument(const Value *BinOp) {
bool BinaryOperator::swapOperands() {
if (!isCommutative())
return true; // Can't commute operands
- std::swap(Ops[0], Ops[1]);
+ std::swap(Op<0>(), Op<1>());
return false;
}
@@ -2254,9 +2335,12 @@ BitCastInst::BitCastInst(
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
const std::string &Name, Instruction *InsertBefore)
- : Instruction(Type::Int1Ty, op, Ops, 2, InsertBefore) {
- Ops[0].init(LHS, this);
- Ops[1].init(RHS, this);
+ : Instruction(Type::Int1Ty, op,
+ OperandTraits<CmpInst>::op_begin(this),
+ OperandTraits<CmpInst>::operands(this),
+ InsertBefore) {
+ Op<0>().init(LHS, this);
+ Op<1>().init(RHS, this);
SubclassData = predicate;
setName(Name);
if (op == Instruction::ICmp) {
@@ -2283,12 +2367,15 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
assert(Op0Ty->isFloatingPoint() &&
"Invalid operand types for FCmp instruction");
}
-
+
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
const std::string &Name, BasicBlock *InsertAtEnd)
- : Instruction(Type::Int1Ty, op, Ops, 2, InsertAtEnd) {
- Ops[0].init(LHS, this);
- Ops[1].init(RHS, this);
+ : Instruction(Type::Int1Ty, op,
+ OperandTraits<CmpInst>::op_begin(this),
+ OperandTraits<CmpInst>::operands(this),
+ InsertAtEnd) {
+ Op<0>().init(LHS, this);
+ Op<1>().init(RHS, this);
SubclassData = predicate;
setName(Name);
if (op == Instruction::ICmp) {
@@ -2548,7 +2635,7 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) {
assert(Value && Default);
ReservedSpace = 2+NumCases*2;
NumOperands = 2;
- OperandList = new Use[ReservedSpace];
+ OperandList = allocHungoffUses(ReservedSpace);
OperandList[0].init(Value, this);
OperandList[1].init(Default, this);
@@ -2576,7 +2663,7 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
SwitchInst::SwitchInst(const SwitchInst &SI)
: TerminatorInst(Type::VoidTy, Instruction::Switch,
- new Use[SI.getNumOperands()], SI.getNumOperands()) {
+ allocHungoffUses(SI.getNumOperands()), SI.getNumOperands()) {
Use *OL = OperandList, *InOL = SI.OperandList;
for (unsigned i = 0, E = SI.getNumOperands(); i != E; i+=2) {
OL[i].init(InOL[i], this);
@@ -2585,7 +2672,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI)
}
SwitchInst::~SwitchInst() {
- delete [] OperandList;
+ dropHungoffUses(OperandList);
}
@@ -2632,13 +2719,14 @@ void SwitchInst::removeCase(unsigned idx) {
/// resizeOperands - resize operands - This adjusts the length of the operands
/// list according to the following behavior:
/// 1. If NumOps == 0, grow the operand list in response to a push_back style
-/// of operation. This grows the number of ops by 1.5 times.
+/// of operation. This grows the number of ops by 3 times.
/// 2. If NumOps > NumOperands, reserve space for NumOps operands.
/// 3. If NumOps == NumOperands, trim the reserved space.
///
void SwitchInst::resizeOperands(unsigned NumOps) {
+ unsigned e = getNumOperands();
if (NumOps == 0) {
- NumOps = getNumOperands()/2*6;
+ NumOps = e*3;
} else if (NumOps*2 > NumOperands) {
// No resize needed.
if (ReservedSpace >= NumOps) return;
@@ -2649,14 +2737,13 @@ void SwitchInst::resizeOperands(unsigned NumOps) {
}
ReservedSpace = NumOps;
- Use *NewOps = new Use[NumOps];
+ Use *NewOps = allocHungoffUses(NumOps);
Use *OldOps = OperandList;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ for (unsigned i = 0; i != e; ++i) {
NewOps[i].init(OldOps[i], this);
- OldOps[i].set(0);
}
- delete [] OldOps;
OperandList = NewOps;
+ if (OldOps) Use::zap(OldOps, OldOps + e, true);
}
@@ -2678,9 +2765,12 @@ GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
const std::string &Name,
Instruction *InsertBef)
: Instruction(cast<StructType>(Aggregate->getType())->getElementType(Index),
- GetResult, &Aggr, 1, InsertBef) {
+ GetResult,
+ OperandTraits<GetResultInst>::op_begin(this),
+ OperandTraits<GetResultInst>::operands(this),
+ InsertBef) {
assert(isValidOperands(Aggregate, Index) && "Invalid GetResultInst operands!");
- Aggr.init(Aggregate, this);
+ Op<0>().init(Aggregate, this);
Idx = Index;
setName(Name);
}
@@ -2714,14 +2804,14 @@ GetElementPtrInst *GetElementPtrInst::clone() const {
}
BinaryOperator *BinaryOperator::clone() const {
- return create(getOpcode(), Ops[0], Ops[1]);
+ return create(getOpcode(), Op<0>(), Op<1>());
}
FCmpInst* FCmpInst::clone() const {
- return new FCmpInst(getPredicate(), Ops[0], Ops[1]);
+ return new FCmpInst(getPredicate(), Op<0>(), Op<1>());
}
ICmpInst* ICmpInst::clone() const {
- return new ICmpInst(getPredicate(), Ops[0], Ops[1]);
+ return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
}
MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
@@ -2757,7 +2847,7 @@ ShuffleVectorInst *ShuffleVectorInst::clone() const {
PHINode *PHINode::clone() const { return new PHINode(*this); }
ReturnInst *ReturnInst::clone() const { return new(getNumOperands()) ReturnInst(*this); }
BranchInst *BranchInst::clone() const { return new(getNumOperands()) BranchInst(*this); }
-SwitchInst *SwitchInst::clone() const { return new(getNumOperands()) SwitchInst(*this); }
+SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
InvokeInst *InvokeInst::clone() const { return new(getNumOperands()) InvokeInst(*this); }
UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp
new file mode 100644
index 0000000..a510d1a
--- /dev/null
+++ b/lib/VMCore/Use.cpp
@@ -0,0 +1,131 @@
+//===-- Use.cpp - Implement the Use class -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the algorithm for finding the User of a Use.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/User.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Use getImpliedUser Implementation
+//===----------------------------------------------------------------------===//
+
+const Use *Use::getImpliedUser() const {
+ const Use *Current = this;
+
+ while (true) {
+ unsigned Tag = extractTag<PrevPtrTag, fullStopTag>((Current++)->Prev);
+ switch (Tag) {
+ case zeroDigitTag:
+ case oneDigitTag:
+ continue;
+
+ case stopTag: {
+ ++Current;
+ ptrdiff_t Offset = 1;
+ while (true) {
+ unsigned Tag = extractTag<PrevPtrTag, fullStopTag>(Current->Prev);
+ switch (Tag) {
+ case zeroDigitTag:
+ case oneDigitTag:
+ ++Current;
+ Offset = (Offset << 1) + Tag;
+ continue;
+ default:
+ return Current + Offset;
+ }
+ }
+ }
+
+ case fullStopTag:
+ return Current;
+ }
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Use initTags Implementation
+//===----------------------------------------------------------------------===//
+
+Use *Use::initTags(Use * const Start, Use *Stop, ptrdiff_t Done) {
+ ptrdiff_t Count = Done;
+ while (Start != Stop) {
+ --Stop;
+ Stop->Val = 0;
+ if (!Count) {
+ Stop->Prev = reinterpret_cast<Use**>(Done == 0 ? fullStopTag : stopTag);
+ ++Done;
+ Count = Done;
+ } else {
+ Stop->Prev = reinterpret_cast<Use**>(Count & 1);
+ Count >>= 1;
+ ++Done;
+ }
+ }
+
+ return Start;
+}
+
+//===----------------------------------------------------------------------===//
+// Use zap Implementation
+//===----------------------------------------------------------------------===//
+
+void Use::zap(Use *Start, const Use *Stop, bool del) {
+ if (del) {
+ while (Start != Stop) {
+ (--Stop)->~Use();
+ }
+ ::operator delete(Start);
+ return;
+ }
+
+ while (Start != Stop) {
+ (Start++)->set(0);
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// AugmentedUse layout struct
+//===----------------------------------------------------------------------===//
+
+struct AugmentedUse : Use {
+ User *ref;
+ AugmentedUse(); // not implemented
+};
+
+
+//===----------------------------------------------------------------------===//
+// Use getUser Implementation
+//===----------------------------------------------------------------------===//
+
+User *Use::getUser() const {
+ const Use *End = getImpliedUser();
+ User *She = static_cast<const AugmentedUse*>(End - 1)->ref;
+ She = extractTag<Tag, tagOne>(She)
+ ? llvm::stripTag<tagOne>(She)
+ : reinterpret_cast<User*>(const_cast<Use*>(End));
+
+ return She;
+}
+
+//===----------------------------------------------------------------------===//
+// User allocHungoffUses Implementation
+//===----------------------------------------------------------------------===//
+
+Use *User::allocHungoffUses(unsigned N) const {
+ Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N + sizeof(AugmentedUse) - sizeof(Use)));
+ Use *End = Begin + N;
+ static_cast<AugmentedUse&>(End[-1]).ref = addTag(this, tagOne);
+ return Use::initTags(Begin, End);
+}
+
+} // End llvm namespace