// CallSite Class
//===----------------------------------------------------------------------===//
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ return isCall() \
+ ? cast<CallInst>(II)->METHOD \
+ : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ if (isCall()) \
+ cast<CallInst>(II)->METHOD; \
+ else \
+ cast<InvokeInst>(II)->METHOD
+
CallSite::CallSite(Instruction *C) {
assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
- I = C;
+ I.setPointer(C);
+ I.setInt(isa<CallInst>(C));
}
unsigned CallSite::getCallingConv() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getCallingConv();
- else
- return cast<InvokeInst>(I)->getCallingConv();
+ CALLSITE_DELEGATE_GETTER(getCallingConv());
}
void CallSite::setCallingConv(unsigned CC) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setCallingConv(CC);
- else
- cast<InvokeInst>(I)->setCallingConv(CC);
+ CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
}
-const PAListPtr &CallSite::getParamAttrs() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getParamAttrs();
- else
- return cast<InvokeInst>(I)->getParamAttrs();
+const AttrListPtr &CallSite::getAttributes() const {
+ CALLSITE_DELEGATE_GETTER(getAttributes());
}
-void CallSite::setParamAttrs(const PAListPtr &PAL) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setParamAttrs(PAL);
- else
- cast<InvokeInst>(I)->setParamAttrs(PAL);
+void CallSite::setAttributes(const AttrListPtr &PAL) {
+ CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
-bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->paramHasAttr(i, attr);
- else
- return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
+ CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
}
uint16_t CallSite::getParamAlignment(uint16_t i) const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getParamAlignment(i);
- else
- return cast<InvokeInst>(I)->getParamAlignment(i);
+ CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
}
-
bool CallSite::doesNotAccessMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotAccessMemory();
- else
- return cast<InvokeInst>(I)->doesNotAccessMemory();
+ CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
+}
+void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
+ CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
}
bool CallSite::onlyReadsMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->onlyReadsMemory();
- else
- return cast<InvokeInst>(I)->onlyReadsMemory();
+ CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
+}
+void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
+ CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
+}
+bool CallSite::doesNotReturn() const {
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
+}
+void CallSite::setDoesNotReturn(bool doesNotReturn) {
+ CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
}
bool CallSite::doesNotThrow() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotThrow();
- else
- return cast<InvokeInst>(I)->doesNotThrow();
+ CALLSITE_DELEGATE_GETTER(doesNotThrow());
}
void CallSite::setDoesNotThrow(bool doesNotThrow) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotThrow(doesNotThrow);
- else
- cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
+ CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
}
bool CallSite::hasArgument(const Value *Arg) const {
return false;
}
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
UnaryInstruction::~UnaryInstruction() {
}
+//===----------------------------------------------------------------------===//
+// SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// areInvalidOperands - Return a string if the specified operands are invalid
+/// for a select operation, otherwise return null.
+const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
+ if (Op1->getType() != Op2->getType())
+ return "both values to select must have same type";
+
+ if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
+ // Vector select.
+ if (VT->getElementType() != Type::Int1Ty)
+ return "vector select condition element type must be i1";
+ const VectorType *ET = dyn_cast<VectorType>(Op1->getType());
+ if (ET == 0)
+ return "selected values for vector select must be vectors";
+ if (ET->getNumElements() != VT->getNumElements())
+ return "vector select requires selected vectors to have "
+ "the same vector length as select condition";
+ } else if (Op0->getType() != Type::Int1Ty) {
+ return "select condition must be i1 or <n x i1>";
+ }
+ return 0;
+}
+
+
//===----------------------------------------------------------------------===//
// PHINode Class
//===----------------------------------------------------------------------===//
ReservedSpace = NumOps;
Use *OldOps = OperandList;
Use *NewOps = allocHungoffUses(NumOps);
- for (unsigned i = 0; i != e; ++i) {
- NewOps[i] = OldOps[i];
- }
+ std::copy(OldOps, OldOps + e, NewOps);
OperandList = NewOps;
if (OldOps) Use::zap(OldOps, OldOps + e, true);
}
: Instruction(CI.getType(), Instruction::Call,
OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
CI.getNumOperands()) {
- setParamAttrs(CI.getParamAttrs());
+ setAttributes(CI.getAttributes());
SubclassData = CI.SubclassData;
Use *OL = OperandList;
Use *InOL = CI.OperandList;
OL[i] = InOL[i];
}
-void CallInst::addParamAttr(unsigned i, ParameterAttributes attr) {
- PAListPtr PAL = getParamAttrs();
+void CallInst::addAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
PAL = PAL.addAttr(i, attr);
- setParamAttrs(PAL);
+ setAttributes(PAL);
+}
+
+void CallInst::removeAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.removeAttr(i, attr);
+ setAttributes(PAL);
}
-bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
- if (ParamAttrs.paramHasAttr(i, attr))
+bool CallInst::paramHasAttr(unsigned i, Attributes attr) const {
+ if (AttributeList.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
return false;
}
-void CallInst::setDoesNotThrow(bool doesNotThrow) {
- PAListPtr PAL = getParamAttrs();
- if (doesNotThrow)
- PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
- else
- PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
- setParamAttrs(PAL);
-}
-
//===----------------------------------------------------------------------===//
// InvokeInst Implementation
OperandTraits<InvokeInst>::op_end(this)
- II.getNumOperands(),
II.getNumOperands()) {
- setParamAttrs(II.getParamAttrs());
+ setAttributes(II.getAttributes());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
return setSuccessor(idx, B);
}
-bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
- if (ParamAttrs.paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const {
+ if (AttributeList.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
return false;
}
-void InvokeInst::addParamAttr(unsigned i, ParameterAttributes attr) {
- PAListPtr PAL = getParamAttrs();
+void InvokeInst::addAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
PAL = PAL.addAttr(i, attr);
- setParamAttrs(PAL);
+ setAttributes(PAL);
}
-void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
- PAListPtr PAL = getParamAttrs();
- if (doesNotThrow)
- PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
- else
- PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
- setParamAttrs(PAL);
+void InvokeInst::removeAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.removeAttr(i, attr);
+ setAttributes(PAL);
}
ReturnInst::ReturnInst(const ReturnInst &RI)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
- OperandTraits<ReturnInst>::op_end(this)
- - RI.getNumOperands(),
+ OperandTraits<ReturnInst>::op_end(this) -
+ RI.getNumOperands(),
RI.getNumOperands()) {
- unsigned N = RI.getNumOperands();
- if (N == 1)
+ if (RI.getNumOperands())
Op<0>() = RI.Op<0>();
- else if (N) {
- Use *OL = OperandList;
- for (unsigned i = 0; i < N; ++i)
- OL[i] = RI.getOperand(i);
- }
}
ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
- OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
- retVal != 0, InsertBefore) {
+ OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+ InsertBefore) {
if (retVal)
- init(&retVal, 1);
+ Op<0>() = retVal;
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret,
- OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
- retVal != 0, InsertAtEnd) {
+ OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+ InsertAtEnd) {
if (retVal)
- init(&retVal, 1);
+ Op<0>() = retVal;
}
ReturnInst::ReturnInst(BasicBlock *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,
- 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,
- 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;
- if (NumOperands == 1) {
- Value *V = *retVals;
- if (V->getType() == Type::VoidTy)
- return;
- Op<0>() = V;
- return;
- }
-
- Use *OL = OperandList;
- for (unsigned i = 0; i < NumOperands; ++i) {
- Value *V = *retVals++;
- assert(!isa<BasicBlock>(V) &&
- "Cannot return basic block. Probably using the incorrect ctor");
- OL[i] = V;
- }
+ OperandTraits<ReturnInst>::op_end(this), 0, InsertAtEnd) {
}
unsigned ReturnInst::getNumSuccessorsV() const {
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertBefore) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertAtEnd) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
BI.getNumOperands()) {
- OperandList[0] = BI.getOperand(0);
+ Op<-1>() = BI.Op<-1>();
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
- OperandList[1] = BI.getOperand(1);
- OperandList[2] = BI.getOperand(2);
+ Op<-3>() = BI.Op<-3>();
+ Op<-2>() = BI.Op<-2>();
+ }
+}
+
+
+Use* Use::getPrefix() {
+ PointerIntPair<Use**, 2, PrevPtrTag> &PotentialPrefix(this[-1].Prev);
+ if (PotentialPrefix.getOpaqueValue())
+ return 0;
+
+ return reinterpret_cast<Use*>((char*)&PotentialPrefix + 1);
+}
+
+BranchInst::~BranchInst() {
+ if (NumOperands == 1) {
+ if (Use *Prefix = OperandList->getPrefix()) {
+ Op<-1>() = 0;
+ //
+ // mark OperandList to have a special value for scrutiny
+ // by baseclass destructors and operator delete
+ OperandList = Prefix;
+ } else {
+ NumOperands = 3;
+ OperandList = op_begin();
+ }
}
}
+
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
Instruction::Alloca, AI.getAlignment()) {
}
+/// isStaticAlloca - Return true if this alloca is in the entry block of the
+/// function and is a constant size. If so, the code generator will fold it
+/// into the prolog/epilog code, so it is basically free.
+bool AllocaInst::isStaticAlloca() const {
+ // Must be constant size.
+ if (!isa<ConstantInt>(getArraySize())) return false;
+
+ // Must be in the entry block.
+ const BasicBlock *Parent = getParent();
+ return Parent == &Parent->getParent()->front();
+}
+
MallocInst::MallocInst(const MallocInst &MI)
: AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
Instruction::Malloc, MI.getAlignment()) {
//===----------------------------------------------------------------------===//
void StoreInst::AssertOK() {
+ assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
assert(isa<PointerType>(getOperand(1)->getType()) &&
"Ptr must have pointer type!");
assert(getOperand(0)->getType() ==
}
void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx,
- const std::string &Name) {
+ const std::string &Name) {
assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
Use *OL = OperandList;
OL[0] = Ptr;
init(Ptr, Idx, Name);
}
-// getIndexedType - Returns the type of the element that would be loaded with
-// a load instruction with the specified parameters.
-//
-// A null type is returned if the indices are invalid for the specified
-// pointer type.
-//
-const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
- Value* const *Idxs,
- unsigned NumIdx) {
+/// getIndexedType - Returns the type of the element that would be accessed with
+/// a gep instruction with the specified parameters.
+///
+/// The Idxs pointer should point to a continuous piece of memory containing the
+/// indices, either as Value* or uint64_t.
+///
+/// A null type is returned if the indices are invalid for the specified
+/// pointer type.
+///
+template <typename IndexTy>
+static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs,
+ unsigned NumIdx) {
const PointerType *PTy = dyn_cast<PointerType>(Ptr);
if (!PTy) return 0; // Type isn't a pointer type!
const Type *Agg = PTy->getElementType();
- // Handle the special case of the empty set index set...
+ // Handle the special case of the empty set index set, which is always valid.
if (NumIdx == 0)
return Agg;
+
+ // If there is at least one index, the top level type must be sized, otherwise
+ // it cannot be 'stepped over'. We explicitly allow abstract types (those
+ // that contain opaque types) under the assumption that it will be resolved to
+ // a sane type later.
+ if (!Agg->isSized() && !Agg->isAbstract())
+ return 0;
unsigned CurIdx = 1;
for (; CurIdx != NumIdx; ++CurIdx) {
const CompositeType *CT = dyn_cast<CompositeType>(Agg);
if (!CT || isa<PointerType>(CT)) return 0;
- Value *Index = Idxs[CurIdx];
+ IndexTy Index = Idxs[CurIdx];
if (!CT->indexValid(Index)) return 0;
Agg = CT->getTypeAtIndex(Index);
return CurIdx == NumIdx ? Agg : 0;
}
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+ Value* const *Idxs,
+ unsigned NumIdx) {
+ return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
+}
+
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+ uint64_t const *Idxs,
+ unsigned NumIdx) {
+ return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
+}
+
const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
const PointerType *PTy = dyn_cast<PointerType>(Ptr);
if (!PTy) return 0; // Type isn't a pointer type!
return false;// Second operand of insertelement must be vector element type.
if (Index->getType() != Type::Int32Ty)
- return false; // Third operand of insertelement must be uint.
+ return false; // Third operand of insertelement must be i32.
return true;
}
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const std::string &Name,
Instruction *InsertBefore)
- : Instruction(V1->getType(), ShuffleVector,
- OperandTraits<ShuffleVectorInst>::op_begin(this),
- OperandTraits<ShuffleVectorInst>::operands(this),
- InsertBefore) {
+: Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
+ cast<VectorType>(Mask->getType())->getNumElements()),
+ ShuffleVector,
+ OperandTraits<ShuffleVectorInst>::op_begin(this),
+ OperandTraits<ShuffleVectorInst>::operands(this),
+ InsertBefore) {
assert(isValidOperands(V1, V2, Mask) &&
"Invalid shuffle vector instruction operands!");
Op<0>() = V1;
}
ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
- const std::string &Name,
+ const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(V1->getType(), ShuffleVector,
OperandTraits<ShuffleVectorInst>::op_begin(this),
setName(Name);
}
-bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
+bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
const Value *Mask) {
- if (!isa<VectorType>(V1->getType()) ||
- V1->getType() != V2->getType())
+ 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())
+ MaskTy->getElementType() != Type::Int32Ty)
return false;
return true;
}
//===----------------------------------------------------------------------===//
void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
- const std::string &Name) {
+ const std::string &Name) {
assert(NumOperands == 1 && "NumOperands not initialized?");
Indices.insert(Indices.end(), Idx, Idx + NumIdx);
return getIndexedType(Agg, &Idx, 1);
}
-ExtractValueInst::ExtractValueInst(Value *Agg,
- unsigned Idx,
- const std::string &Name,
- BasicBlock *InsertAtEnd)
- : UnaryInstruction(checkType(getIndexedType(Agg->getType(), &Idx, 1)),
- ExtractValue, Agg, InsertAtEnd) {
- init(Idx, Name);
-}
-
-ExtractValueInst::ExtractValueInst(Value *Agg,
- unsigned Idx,
- const std::string &Name,
- Instruction *InsertBefore)
- : UnaryInstruction(checkType(getIndexedType(Agg->getType(), &Idx, 1)),
- ExtractValue, Agg, InsertBefore) {
- init(Idx, Name);
-}
-
//===----------------------------------------------------------------------===//
// BinaryOperator Class
//===----------------------------------------------------------------------===//
+/// AdjustIType - Map Add, Sub, and Mul to FAdd, FSub, and FMul when the
+/// type is floating-point, to help provide compatibility with an older API.
+///
+static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType,
+ const Type *Ty) {
+ // API compatibility: Adjust integer opcodes to floating-point opcodes.
+ if (Ty->isFPOrFPVector()) {
+ if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd;
+ else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub;
+ else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul;
+ }
+ return iType;
+}
+
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
Instruction *InsertBefore)
- : Instruction(Ty, iType,
+ : Instruction(Ty, AdjustIType(iType, Ty),
OperandTraits<BinaryOperator>::op_begin(this),
OperandTraits<BinaryOperator>::operands(this),
InsertBefore) {
Op<0>() = S1;
Op<1>() = S2;
- init(iType);
+ init(AdjustIType(iType, Ty));
setName(Name);
}
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
const Type *Ty, const std::string &Name,
BasicBlock *InsertAtEnd)
- : Instruction(Ty, iType,
+ : Instruction(Ty, AdjustIType(iType, Ty),
OperandTraits<BinaryOperator>::op_begin(this),
OperandTraits<BinaryOperator>::operands(this),
InsertAtEnd) {
Op<0>() = S1;
Op<1>() = S2;
- init(iType);
+ init(AdjustIType(iType, Ty));
setName(Name);
}
#ifndef NDEBUG
switch (iType) {
case Add: case Sub:
- case Mul:
+ case Mul:
+ assert(getType() == LHS->getType() &&
+ "Arithmetic operation should return same type as operands!");
+ assert(getType()->isIntOrIntVector() &&
+ "Tried to create an integer operation on a non-integer type!");
+ break;
+ case FAdd: case FSub:
+ case FMul:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() || getType()->isFloatingPoint() ||
- isa<VectorType>(getType())) &&
- "Tried to create an arithmetic operation on a non-arithmetic type!");
+ assert(getType()->isFPOrFPVector() &&
+ "Tried to create a floating-point operation on a "
+ "non-floating-point type!");
break;
case UDiv:
case SDiv:
case FDiv:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isFloatingPoint()))
- && "Incorrect operand type (not floating point) for FDIV");
+ assert(getType()->isFPOrFPVector() &&
+ "Incorrect operand type (not floating point) for FDIV");
break;
case URem:
case SRem:
case FRem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
- cast<VectorType>(getType())->getElementType()->isFloatingPoint()))
- && "Incorrect operand type (not floating point) for FREM");
+ assert(getType()->isFPOrFPVector() &&
+ "Incorrect operand type (not floating point) for FREM");
break;
case Shl:
case LShr:
case AShr:
assert(getType() == LHS->getType() &&
"Shift operation should return same type as operands!");
- assert(getType()->isInteger() &&
- "Shift operation requires integer operands");
+ assert((getType()->isInteger() ||
+ (isa<VectorType>(getType()) &&
+ cast<VectorType>(getType())->getElementType()->isInteger())) &&
+ "Tried to create a shift operation on a non-integral type!");
break;
case And: case Or:
case Xor:
Op->getType(), Name, InsertAtEnd);
}
+BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name,
+ Instruction *InsertBefore) {
+ Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+ return new BinaryOperator(Instruction::FSub,
+ zero, Op,
+ Op->getType(), Name, InsertBefore);
+}
+
+BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name,
+ BasicBlock *InsertAtEnd) {
+ Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+ return new BinaryOperator(Instruction::FSub,
+ zero, Op,
+ Op->getType(), Name, InsertAtEnd);
+}
+
BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name,
Instruction *InsertBefore) {
Constant *C;
return false;
}
+bool BinaryOperator::isFNeg(const Value *V) {
+ if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
+ if (Bop->getOpcode() == Instruction::FSub)
+ return Bop->getOperand(0) ==
+ ConstantExpr::getZeroValueForNegationExpr(Bop->getType());
+ return false;
+}
+
bool BinaryOperator::isNot(const Value *V) {
if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
return (Bop->getOpcode() == Instruction::Xor &&
return getNegArgument(const_cast<Value*>(BinOp));
}
+Value *BinaryOperator::getFNegArgument(Value *BinOp) {
+ assert(isFNeg(BinOp) && "getFNegArgument from non-'fneg' instruction!");
+ return cast<BinaryOperator>(BinOp)->getOperand(1);
+}
+
+const Value *BinaryOperator::getFNegArgument(const Value *BinOp) {
+ return getFNegArgument(const_cast<Value*>(BinOp));
+}
+
Value *BinaryOperator::getNotArgument(Value *BinOp) {
assert(isNot(BinOp) && "getNotArgument on non-'not' instruction!");
BinaryOperator *BO = cast<BinaryOperator>(BinOp);
case Instruction::BitCast:
return true; // BitCast never modifies bits.
case Instruction::PtrToInt:
- return IntPtrTy->getPrimitiveSizeInBits() ==
- getType()->getPrimitiveSizeInBits();
+ return IntPtrTy->getScalarSizeInBits() ==
+ getType()->getScalarSizeInBits();
case Instruction::IntToPtr:
- return IntPtrTy->getPrimitiveSizeInBits() ==
- getOperand(0)->getType()->getPrimitiveSizeInBits();
+ return IntPtrTy->getScalarSizeInBits() ==
+ getOperand(0)->getType()->getScalarSizeInBits();
}
}
// BITCONVERT = FirstClass n/a FirstClass n/a
//
// NOTE: some transforms are safe, but we consider them to be non-profitable.
- // For example, we could merge "fptoui double to uint" + "zext uint to ulong",
- // into "fptoui double to ulong", but this loses information about the range
+ // For example, we could merge "fptoui double to i32" + "zext i32 to i64",
+ // into "fptoui double to i64", but this loses information about the range
// of the produced value (we no longer know the top-part is all zeros).
// Further this conversion is often much more expensive for typical hardware,
// and causes issues when building libgcc. We disallow fptosi+sext for the
return 0;
case 7: {
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
- unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
- unsigned MidSize = MidTy->getPrimitiveSizeInBits();
+ unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+ unsigned MidSize = MidTy->getScalarSizeInBits();
if (MidSize >= PtrSize)
return Instruction::BitCast;
return 0;
// ext, trunc -> bitcast, if the SrcTy and DstTy are same size
// ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy)
// ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy)
- unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ unsigned SrcSize = SrcTy->getScalarSizeInBits();
+ unsigned DstSize = DstTy->getScalarSizeInBits();
if (SrcSize == DstSize)
return Instruction::BitCast;
else if (SrcSize < DstSize)
return 0;
case 13: {
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
- unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
- unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+ unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+ unsigned SrcSize = SrcTy->getScalarSizeInBits();
+ unsigned DstSize = DstTy->getScalarSizeInBits();
if (SrcSize <= PtrSize && SrcSize == DstSize)
return Instruction::BitCast;
return 0;
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::ZExt, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
}
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::SExt, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
}
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
return Create(Instruction::Trunc, S, Ty, Name, InsertBefore);
}
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
}
bool isSigned, const std::string &Name,
Instruction *InsertBefore) {
assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::Trunc :
CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
bool isSigned, const std::string &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+ "Invalid cast");
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::Trunc :
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const std::string &Name,
Instruction *InsertBefore) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
"Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
const std::string &Name,
BasicBlock *InsertAtEnd) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
"Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
return true;
// Get the bit sizes, we'll need these
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
- unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
// Run through the possibilities ...
if (DestTy->isInteger()) { // Casting to integral
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
// Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
- unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+ unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
"Only first class types are castable!");
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestBits == PTy->getBitWidth() &&
"Casting vector to integer of different width");
+ PTy = NULL;
return BitCast; // Same size, no-op cast
} else {
assert(isa<PointerType>(SrcTy) &&
} else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestBits == PTy->getBitWidth() &&
"Casting vector to floating point of different width");
- return BitCast; // same size, no-op cast
+ PTy = NULL;
+ return BitCast; // same size, no-op cast
} else {
assert(0 && "Casting pointer or non-first class to float");
}
if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
"Casting vector to vector of different widths");
+ SrcPTy = NULL;
return BitCast; // vector -> vector
} else if (DestPTy->getBitWidth() == SrcBits) {
return BitCast; // float/int -> vector
return false;
// Get the size of the types in bits, we'll need this later
- unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+ unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
+ unsigned DstBitSize = DstTy->getScalarSizeInBits();
// Switch on the opcode provided
switch (op) {
default: return false; // This is an input error
case Instruction::Trunc:
- return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize > DstBitSize;
+ return SrcTy->isIntOrIntVector() &&
+ DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize;
case Instruction::ZExt:
- return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVector() &&
+ DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
case Instruction::SExt:
- return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVector() &&
+ DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
case Instruction::FPTrunc:
- return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() &&
- SrcBitSize > DstBitSize;
+ return SrcTy->isFPOrFPVector() &&
+ DstTy->isFPOrFPVector() &&
+ SrcBitSize > DstBitSize;
case Instruction::FPExt:
- return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() &&
- SrcBitSize < DstBitSize;
+ return SrcTy->isFPOrFPVector() &&
+ DstTy->isFPOrFPVector() &&
+ SrcBitSize < DstBitSize;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isInteger() &&
- DVTy->getElementType()->isFloatingPoint() &&
+ return SVTy->getElementType()->isIntOrIntVector() &&
+ DVTy->getElementType()->isFPOrFPVector() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isInteger() && DstTy->isFloatingPoint();
+ return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector();
case Instruction::FPToUI:
case Instruction::FPToSI:
if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isFloatingPoint() &&
- DVTy->getElementType()->isInteger() &&
+ return SVTy->getElementType()->isFPOrFPVector() &&
+ DVTy->getElementType()->isIntOrIntVector() &&
SVTy->getNumElements() == DVTy->getNumElements();
}
}
- return SrcTy->isFloatingPoint() && DstTy->isInteger();
+ return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector();
case Instruction::PtrToInt:
return isa<PointerType>(SrcTy) && DstTy->isInteger();
case Instruction::IntToPtr:
// Now we know we're not dealing with a pointer/non-pointer mismatch. In all
// these cases, the cast is okay if the source and destination bit widths
// are identical.
- return SrcBitSize == DstBitSize;
+ return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
}
}
setSuccessor(idx, B);
}
-//===----------------------------------------------------------------------===//
-// GetResultInst Implementation
-//===----------------------------------------------------------------------===//
-
-GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
- const std::string &Name,
- Instruction *InsertBef)
- : UnaryInstruction(cast<StructType>(Aggregate->getType())
- ->getElementType(Index),
- GetResult, Aggregate, InsertBef),
- Idx(Index) {
- assert(isValidOperands(Aggregate, Index)
- && "Invalid GetResultInst operands!");
- setName(Name);
-}
-
-bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
- if (!Aggregate)
- return false;
-
- if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
- unsigned NumElements = STy->getNumElements();
- if (Index >= NumElements || NumElements == 0)
- return false;
-
- // getresult aggregate value's element types are restricted to
- // avoid nested aggregates.
- for (unsigned i = 0; i < NumElements; ++i)
- if (!STy->getElementType(i)->isFirstClassType())
- return false;
-
- // Otherwise, Aggregate is valid.
- return true;
- }
- return false;
-}
-
// Define these methods here so vtables don't get emitted into every translation
// unit that uses these classes.
return new(getNumOperands()) ReturnInst(*this);
}
BranchInst *BranchInst::clone() const {
- return new(getNumOperands()) BranchInst(*this);
+ unsigned Ops(getNumOperands());
+ return new(Ops, Ops == 1) BranchInst(*this);
}
SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
InvokeInst *InvokeInst::clone() const {
}
UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
-GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }