// 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 {
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;
// getIndexedType - Returns the type of the element that would be loaded with
// a load 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.
//
-const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
- Value* const *Idxs,
- unsigned NumIdx) {
+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();
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!
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);
}
const Type* ExtractValueInst::getIndexedType(const Type *Agg,
- const unsigned Idx) {
- const unsigned Idxs[1] = { Idx };
- return getIndexedType(Agg, &Idxs[0], 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);
+ unsigned Idx) {
+ return getIndexedType(Agg, &Idx, 1);
}
//===----------------------------------------------------------------------===//
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:
} 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
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:
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.
}
UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
-GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }