#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
-#include "llvm/ParamAttrsList.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/MathExtras.h"
else
cast<InvokeInst>(I)->setCallingConv(CC);
}
-const ParamAttrsList* CallSite::getParamAttrs() const {
+const PAListPtr &CallSite::getParamAttrs() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getParamAttrs();
else
return cast<InvokeInst>(I)->getParamAttrs();
}
-void CallSite::setParamAttrs(const ParamAttrsList *PAL) {
+void CallSite::setParamAttrs(const PAListPtr &PAL) {
if (CallInst *CI = dyn_cast<CallInst>(I))
CI->setParamAttrs(PAL);
else
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) {
}
PHINode::~PHINode() {
- delete [] OperandList;
+ dropHungoffUses(OperandList);
}
// removeIncomingValue - Remove an incoming value. This is useful if a
/// 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.
}
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
//===----------------------------------------------------------------------===//
CallInst::~CallInst() {
- delete [] OperandList;
- if (ParamAttrs)
- ParamAttrs->dropRef();
}
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
- ParamAttrs = 0;
- 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 =
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
- ParamAttrs = 0;
- 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);
}
void CallInst::init(Value *Func, Value *Actual) {
- ParamAttrs = 0;
- 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);
}
void CallInst::init(Value *Func) {
- ParamAttrs = 0;
- 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 =
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);
}
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);
}
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);
}
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()],
- CI.getNumOperands()),
- ParamAttrs(0) {
+ : Instruction(CI.getType(), Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
+ CI.getNumOperands()) {
setParamAttrs(CI.getParamAttrs());
SubclassData = CI.SubclassData;
Use *OL = OperandList;
OL[i].init(InOL[i], this);
}
-void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
- if (ParamAttrs == newAttrs)
- return;
-
- if (ParamAttrs)
- ParamAttrs->dropRef();
-
- if (newAttrs)
- newAttrs->addRef();
-
- ParamAttrs = newAttrs;
-}
-
-bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
- if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+ if (ParamAttrs.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
return false;
}
-uint16_t CallInst::getParamAlignment(uint16_t i) const {
- if (ParamAttrs && ParamAttrs->getParamAlignment(i))
- return ParamAttrs->getParamAlignment(i);
- if (const Function *F = getCalledFunction())
- return F->getParamAlignment(i);
- return 0;
-}
-
-/// @brief Determine if the call does not access memory.
-bool CallInst::doesNotAccessMemory() const {
- return paramHasAttr(0, ParamAttr::ReadNone);
-}
-
-/// @brief Determine if the call does not access or only reads memory.
-bool CallInst::onlyReadsMemory() const {
- return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
-}
-
-/// @brief Determine if the call cannot return.
-bool CallInst::doesNotReturn() const {
- return paramHasAttr(0, ParamAttr::NoReturn);
-}
-
-/// @brief Determine if the call cannot unwind.
-bool CallInst::doesNotThrow() const {
- return paramHasAttr(0, ParamAttr::NoUnwind);
-}
-
-/// @brief Determine if the call returns a structure.
-bool CallInst::isStructReturn() const {
- // Be friendly and also check the callee.
- return paramHasAttr(1, ParamAttr::StructRet);
-}
-
-/// @brief Determine if any call argument is an aggregate passed by value.
-bool CallInst::hasByValArgument() const {
- if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal))
- return true;
- // Be consistent with other methods and check the callee too.
- if (const Function *F = getCalledFunction())
- if (const ParamAttrsList *PAL = F->getParamAttrs())
- return PAL->hasAttrSomewhere(ParamAttr::ByVal);
- return false;
-}
-
void CallInst::setDoesNotThrow(bool doesNotThrow) {
- const ParamAttrsList *PAL = getParamAttrs();
+ PAListPtr PAL = getParamAttrs();
if (doesNotThrow)
- PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+ PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
else
- PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+ PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
// InvokeInst Implementation
//===----------------------------------------------------------------------===//
-InvokeInst::~InvokeInst() {
- delete [] OperandList;
- if (ParamAttrs)
- ParamAttrs->dropRef();
-}
-
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
- ParamAttrs = 0;
- 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);
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
- new Use[II.getNumOperands()], II.getNumOperands()),
- ParamAttrs(0) {
+ OperandTraits<InvokeInst>::op_end(this) - II.getNumOperands(),
+ II.getNumOperands()) {
setParamAttrs(II.getParamAttrs());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
return setSuccessor(idx, B);
}
-void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
- if (ParamAttrs == newAttrs)
- return;
-
- if (ParamAttrs)
- ParamAttrs->dropRef();
-
- if (newAttrs)
- newAttrs->addRef();
-
- ParamAttrs = newAttrs;
-}
-
-bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
- if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+ if (ParamAttrs.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
return false;
}
-uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
- if (ParamAttrs && ParamAttrs->getParamAlignment(i))
- return ParamAttrs->getParamAlignment(i);
- if (const Function *F = getCalledFunction())
- return F->getParamAlignment(i);
- return 0;
-}
-
-/// @brief Determine if the call does not access memory.
-bool InvokeInst::doesNotAccessMemory() const {
- return paramHasAttr(0, ParamAttr::ReadNone);
-}
-
-/// @brief Determine if the call does not access or only reads memory.
-bool InvokeInst::onlyReadsMemory() const {
- return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
-}
-
-/// @brief Determine if the call cannot return.
-bool InvokeInst::doesNotReturn() const {
- return paramHasAttr(0, ParamAttr::NoReturn);
-}
-
-/// @brief Determine if the call cannot unwind.
-bool InvokeInst::doesNotThrow() const {
- return paramHasAttr(0, ParamAttr::NoUnwind);
-}
-
void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
- const ParamAttrsList *PAL = getParamAttrs();
+ PAListPtr PAL = getParamAttrs();
if (doesNotThrow)
- PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+ PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
else
- PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+ PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
-/// @brief Determine if the call returns a structure.
-bool InvokeInst::isStructReturn() const {
- // Be friendly and also check the callee.
- return paramHasAttr(1, ParamAttr::StructRet);
-}
-
//===----------------------------------------------------------------------===//
// ReturnInst Implementation
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(const std::vector<Value *> &retVals,
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
Instruction *InsertBefore)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(),
- InsertBefore) {
- if (!retVals.empty())
- init(&retVals[0], retVals.size());
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - N,
+ N, InsertBefore) {
+ if (N != 0)
+ init(retVals, N);
}
-ReturnInst::ReturnInst(const std::vector<Value *> &retVals,
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size(),
- InsertAtEnd) {
- if (!retVals.empty())
- init(&retVals[0], retVals.size());
-}
-ReturnInst::ReturnInst(const std::vector<Value *> &retVals)
- : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, retVals.size()) {
- if (!retVals.empty())
- init(&retVals[0], retVals.size());
+ : TerminatorInst(Type::VoidTy, Instruction::Ret,
+ OperandTraits<ReturnInst>::op_end(this) - N,
+ N, InsertAtEnd) {
+ if (N != 0)
+ init(retVals, N);
}
void ReturnInst::init(Value * const* retVals, unsigned N) {
-
assert (N > 0 && "Invalid operands numbers in ReturnInst init");
NumOperands = 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) &&
}
ReturnInst::~ReturnInst() {
- if (NumOperands > 1)
- delete [] OperandList;
}
//===----------------------------------------------------------------------===//
}
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
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!");
unsigned Align, const std::string &Name,
Instruction *InsertBefore)
: UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
- InsertBefore), Alignment(Align) {
- assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ InsertBefore) {
+ setAlignment(Align);
assert(Ty != Type::VoidTy && "Cannot allocate void!");
setName(Name);
}
unsigned Align, const std::string &Name,
BasicBlock *InsertAtEnd)
: UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
- InsertAtEnd), Alignment(Align) {
- assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ InsertAtEnd) {
+ setAlignment(Align);
assert(Ty != Type::VoidTy && "Cannot allocate void!");
setName(Name);
}
AllocationInst::~AllocationInst() {
}
+void AllocationInst::setAlignment(unsigned Align) {
+ assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ SubclassData = Log2_32(Align) + 1;
+ assert(getAlignment() == Align && "Alignment representation error!");
+}
+
bool AllocationInst::isArrayAllocation() const {
if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
return CI->getZExtValue() != 1;
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();
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();
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();
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();
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();
}
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)
}
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);
}
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.
//
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);
}
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);
}
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);
}
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);
}
//===----------------------------------------------------------------------===//
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);
}
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);
}
//===----------------------------------------------------------------------===//
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);
}
bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
const Value *Mask) {
- if (!isa<VectorType>(V1->getType())) return false;
- if (V1->getType() != V2->getType()) return false;
- if (!isa<VectorType>(Mask->getType()) ||
- cast<VectorType>(Mask->getType())->getElementType() != Type::Int32Ty ||
- cast<VectorType>(Mask->getType())->getNumElements() !=
- cast<VectorType>(V1->getType())->getNumElements())
+ if (!isa<VectorType>(V1->getType()) ||
+ V1->getType() != V2->getType())
+ return false;
+
+ const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
+ if (!isa<Constant>(Mask) || MaskTy == 0 ||
+ MaskTy->getElementType() != Type::Int32Ty ||
+ MaskTy->getNumElements() !=
+ cast<VectorType>(V1->getType())->getNumElements())
return false;
return true;
}
+/// getMaskValue - Return the index from the shuffle mask for the specified
+/// output result. This is either -1 if the element is undef or a number less
+/// than 2*numelements.
+int ShuffleVectorInst::getMaskValue(unsigned i) const {
+ const Constant *Mask = cast<Constant>(getOperand(2));
+ if (isa<UndefValue>(Mask)) return -1;
+ if (isa<ConstantAggregateZero>(Mask)) return 0;
+ const ConstantVector *MaskCV = cast<ConstantVector>(Mask);
+ assert(i < MaskCV->getNumOperands() && "Index out of range");
+
+ if (isa<UndefValue>(MaskCV->getOperand(i)))
+ return -1;
+ return cast<ConstantInt>(MaskCV->getOperand(i))->getZExtValue();
+}
+
//===----------------------------------------------------------------------===//
// BinaryOperator Class
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);
}
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);
}
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;
}
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) {
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) {
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);
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);
}
SwitchInst::~SwitchInst() {
- delete [] OperandList;
+ dropHungoffUses(OperandList);
}
/// 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;
}
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);
}
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);
}
if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
unsigned NumElements = STy->getNumElements();
- if (Index >= NumElements)
+ if (Index >= NumElements || NumElements == 0)
return false;
// getresult aggregate value's element types are restricted to
// unit that uses these classes.
GetElementPtrInst *GetElementPtrInst::clone() const {
- return new GetElementPtrInst(*this);
+ return new(getNumOperands()) GetElementPtrInst(*this);
}
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); }
CastInst *PtrToIntInst::clone() const { return new PtrToIntInst(*this); }
CastInst *IntToPtrInst::clone() const { return new IntToPtrInst(*this); }
CastInst *BitCastInst::clone() const { return new BitCastInst(*this); }
-CallInst *CallInst::clone() const { return new CallInst(*this); }
-SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
+CallInst *CallInst::clone() const { return new(getNumOperands()) CallInst(*this); }
+SelectInst *SelectInst::clone() const { return new(getNumOperands()) SelectInst(*this); }
VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
ExtractElementInst *ExtractElementInst::clone() const {
return new ExtractElementInst(*this);
}
InsertElementInst *InsertElementInst::clone() const {
- return new InsertElementInst(*this);
+ return InsertElementInst::Create(*this);
}
ShuffleVectorInst *ShuffleVectorInst::clone() const {
return new ShuffleVectorInst(*this);
}
PHINode *PHINode::clone() const { return new PHINode(*this); }
-ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
-BranchInst *BranchInst::clone() const { return new BranchInst(*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 SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const { return new InvokeInst(*this); }
+InvokeInst *InvokeInst::clone() const { return new(getNumOperands()) InvokeInst(*this); }
UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }