#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
-#include "llvm/ParameterAttributes.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
else
return cast<InvokeInst>(I)->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);
+}
+
bool CallSite::doesNotAccessMemory() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->doesNotAccessMemory();
///
Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
// If the PHI node only has one incoming value, eliminate the PHI node...
- if (getNumIncomingValues() == 1)
+ if (getNumIncomingValues() == 1) {
if (getIncomingValue(0) != this) // not X = phi X
return getIncomingValue(0);
else
return UndefValue::get(getType()); // Self cycle is dead.
+ }
// Otherwise if all of the incoming values are the same for the PHI, replace
// the PHI node with the incoming value.
Value *InVal = 0;
bool HasUndefInput = false;
for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
- if (isa<UndefValue>(getIncomingValue(i)))
+ if (isa<UndefValue>(getIncomingValue(i))) {
HasUndefInput = true;
- else if (getIncomingValue(i) != this) // Not the PHI node itself...
+ } else if (getIncomingValue(i) != this) { // Not the PHI node itself...
if (InVal && getIncomingValue(i) != InVal)
return 0; // Not the same, bail out.
else
InVal = getIncomingValue(i);
+ }
// The only case that could cause InVal to be null is if we have a PHI node
// that only has entries for itself. In this case, there is no entry into the
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];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
- ParamAttrs = 0;
NumOperands = 3;
Use *OL = OperandList = new Use[3];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func, Value *Actual) {
- ParamAttrs = 0;
NumOperands = 2;
Use *OL = OperandList = new Use[2];
OL[0].init(Func, this);
}
void CallInst::init(Value *Func) {
- ParamAttrs = 0;
NumOperands = 1;
Use *OL = OperandList = new Use[1];
OL[0].init(Func, this);
CallInst::CallInst(const CallInst &CI)
: Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
- CI.getNumOperands()),
- ParamAttrs(0) {
+ 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;
}
-/// @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::~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];
OL[0].init(Fn, this);
cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
FTy = FTy; // silence warning.
- assert((NumArgs == FTy->getNumParams()) ||
- (FTy->isVarArg() && NumArgs > FTy->getNumParams()) &&
+ assert(((NumArgs == FTy->getNumParams()) ||
+ (FTy->isVarArg() && NumArgs > FTy->getNumParams())) &&
"Calling a function with bad signature");
for (unsigned i = 0, e = NumArgs; i != e; i++) {
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
- new Use[II.getNumOperands()], II.getNumOperands()),
- ParamAttrs(0) {
+ new Use[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;
}
-
-/// @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()) {
- if (RI.getNumOperands())
+ unsigned N = RI.getNumOperands();
+ if (N == 1)
RetVal.init(RI.RetVal, this);
+ else if (N) {
+ Use *OL = OperandList = new Use[N];
+ 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) {
- init(retVal);
+ if (retVal)
+ init(&retVal, 1);
}
ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
- init(retVal);
+ if (retVal)
+ init(&retVal, 1);
}
ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
: TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+ Instruction *InsertBefore)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertBefore) {
+ if (N != 0)
+ init(retVals, N);
+}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+ BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertAtEnd) {
+ if (N != 0)
+ init(retVals, N);
+}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N)
+ : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N) {
+ 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;
+ RetVal.init(V, this);
+ return;
+ }
-void ReturnInst::init(Value *retVal) {
- if (retVal && retVal->getType() != Type::VoidTy) {
- assert(!isa<BasicBlock>(retVal) &&
+ Use *OL = OperandList = new Use[NumOperands];
+ for (unsigned i = 0; i < NumOperands; ++i) {
+ Value *V = *retVals++;
+ assert(!isa<BasicBlock>(V) &&
"Cannot return basic block. Probably using the incorrect ctor");
- NumOperands = 1;
- RetVal.init(retVal, this);
+ OL[i].init(V, this);
}
}
return getNumSuccessors();
}
-// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
-// emit the vtable for the class in this translation unit.
+/// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
+/// emit the vtable for the class in this translation unit.
void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
assert(0 && "ReturnInst has no successors!");
}
return 0;
}
+ReturnInst::~ReturnInst() {
+ if (NumOperands > 1)
+ delete [] OperandList;
+}
//===----------------------------------------------------------------------===//
// UnwindInst Implementation
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;
if (!isa<PointerType>(Ptr)) return 0; // Type isn't a pointer type!
// Handle the special case of the empty set index set...
- if (NumIdx == 0)
+ if (NumIdx == 0) {
if (AllowCompositeLeaf ||
cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
return cast<PointerType>(Ptr)->getElementType();
else
return 0;
+ }
unsigned CurIdx = 0;
while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
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
assert(Op0Ty == Op1Ty &&
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
- assert(Op0Ty->isInteger() || isa<PointerType>(Op0Ty) &&
+ assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
"Invalid operand types for ICmp instruction");
return;
}
// GetResultInst Implementation
//===----------------------------------------------------------------------===//
-GetResultInst::GetResultInst(Value *Aggr, Value *Index,
+GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
const std::string &Name,
Instruction *InsertBef)
- : Instruction(Aggr->getType(),
- GetResult, Ops, 2, InsertBef) {
- assert(isValidOperands(Aggr, Index) && "Invalid GetResultInst operands!");
- Ops[0].init(Aggr, this);
- Ops[1].init(Index, this);
+ : Instruction(cast<StructType>(Aggregate->getType())->getElementType(Index),
+ GetResult, &Aggr, 1, InsertBef) {
+ assert(isValidOperands(Aggregate, Index) && "Invalid GetResultInst operands!");
+ Aggr.init(Aggregate, this);
+ Idx = Index;
setName(Name);
}
-bool GetResultInst::isValidOperands(const Value *Aggr, const Value *Index) {
- if (!Aggr || !Index)
+bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
+ if (!Aggregate)
return false;
- if (!isa<StructType>(Aggr->getType()) || Index->getType() != Type::Int32Ty)
- return false;
- return true;
-}
+ if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
+ unsigned NumElements = STy->getNumElements();
+ if (Index >= NumElements)
+ 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.
GetElementPtrInst *GetElementPtrInst::clone() const {
- return new GetElementPtrInst(*this);
+ return new(getNumOperands()) GetElementPtrInst(*this);
}
BinaryOperator *BinaryOperator::clone() const {
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); }
-SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const { return new InvokeInst(*this); }
+ReturnInst *ReturnInst::clone() const { return new(getNumOperands()) ReturnInst(*this); }
+BranchInst *BranchInst::clone() const { return new(getNumOperands()) BranchInst(*this); }
+SwitchInst *SwitchInst::clone() const { return new(getNumOperands()) SwitchInst(*this); }
+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); }