#include "llvm/Support/CallSite.h"
using namespace llvm;
+unsigned CallSite::getCallingConv() const {
+ if (CallInst *CI = dyn_cast<CallInst>(I))
+ return CI->getCallingConv();
+ else
+ return cast<InvokeInst>(I)->getCallingConv();
+}
+void CallSite::setCallingConv(unsigned CC) {
+ if (CallInst *CI = dyn_cast<CallInst>(I))
+ CI->setCallingConv(CC);
+ else
+ cast<InvokeInst>(I)->setCallingConv(CC);
+}
+
+
+
+
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
: Instruction(Type::VoidTy, iType, Ops, NumOps, "", IAE) {
}
+// Out of line virtual method, so the vtable, etc has a home.
+TerminatorInst::~TerminatorInst() {
+}
+
+// Out of line virtual method, so the vtable, etc has a home.
+UnaryInstruction::~UnaryInstruction() {
+}
//===----------------------------------------------------------------------===//
OperandList = NewOps;
}
+/// hasConstantValue - If the specified PHI node always merges together the same
+/// value, return the value, otherwise return null.
+///
+Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
+ // If the PHI node only has one incoming value, eliminate the PHI node...
+ 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)))
+ HasUndefInput = true;
+ 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
+ // loop, so kill the PHI.
+ //
+ if (InVal == 0) InVal = UndefValue::get(getType());
+
+ // If we have a PHI node like phi(X, undef, X), where X is defined by some
+ // instruction, we cannot always return X as the result of the PHI node. Only
+ // do this if X is not an instruction (thus it must dominate the PHI block),
+ // or if the client is prepared to deal with this possibility.
+ if (HasUndefInput && !AllowNonDominatingInstruction)
+ if (Instruction *IV = dyn_cast<Instruction>(InVal))
+ // If it's in the entry block, it dominates everything.
+ if (IV->getParent() != &IV->getParent()->getParent()->front() ||
+ isa<InvokeInst>(IV))
+ return 0; // Cannot guarantee that InVal dominates this PHINode.
+
+ // All of the incoming values are the same, return the value now.
+ return InVal;
+}
+
//===----------------------------------------------------------------------===//
// CallInst Implementation
assert((Params.size() == FTy->getNumParams() ||
(FTy->isVarArg() && Params.size() > FTy->getNumParams())) &&
- "Calling a function with bad signature");
- for (unsigned i = 0, e = Params.size(); i != e; ++i)
+ "Calling a function with bad signature!");
+ for (unsigned i = 0, e = Params.size(); i != e; ++i) {
+ assert((i >= FTy->getNumParams() ||
+ FTy->getParamType(i) == Params[i]->getType()) &&
+ "Calling a function with a bad signature!");
OL[i+1].init(Params[i], this);
+ }
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
assert((FTy->getNumParams() == 2 ||
- (FTy->isVarArg() && FTy->getNumParams() == 0)) &&
+ (FTy->isVarArg() && FTy->getNumParams() < 2)) &&
"Calling a function with bad signature");
+ assert((0 >= FTy->getNumParams() ||
+ FTy->getParamType(0) == Actual1->getType()) &&
+ "Calling a function with a bad signature!");
+ assert((1 >= FTy->getNumParams() ||
+ FTy->getParamType(1) == Actual2->getType()) &&
+ "Calling a function with a bad signature!");
}
void CallInst::init(Value *Func, Value *Actual) {
assert((FTy->getNumParams() == 1 ||
(FTy->isVarArg() && FTy->getNumParams() == 0)) &&
"Calling a function with bad signature");
+ assert((0 == FTy->getNumParams() ||
+ FTy->getParamType(0) == Actual->getType()) &&
+ "Calling a function with a bad signature!");
}
void CallInst::init(Value *Func) {
CallInst::CallInst(const CallInst &CI)
: Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
CI.getNumOperands()) {
+ SubclassData = CI.SubclassData;
Use *OL = OperandList;
Use *InOL = CI.OperandList;
for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
(FTy->isVarArg() && Params.size() > FTy->getNumParams()) &&
"Calling a function with bad signature");
- for (unsigned i = 0, e = Params.size(); i != e; i++)
+ for (unsigned i = 0, e = Params.size(); i != e; i++) {
+ assert((i >= FTy->getNumParams() ||
+ FTy->getParamType(i) == Params[i]->getType()) &&
+ "Invoking a function with a bad signature!");
+
OL[i+3].init(Params[i], this);
+ }
}
InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal,
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
new Use[II.getNumOperands()], II.getNumOperands()) {
+ SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
OL[i].init(InOL[i], this);
static Value *getAISize(Value *Amt) {
if (!Amt)
- Amt = ConstantUInt::get(Type::UIntTy, 1);
- else
+ Amt = ConstantInt::get(Type::UIntTy, 1);
+ else {
+ assert(!isa<BasicBlock>(Amt) &&
+ "Passed basic block into allocation size parameter! Ue other ctor");
assert(Amt->getType() == Type::UIntTy &&
"Malloc/Allocation array size != UIntTy!");
+ }
return Amt;
}
AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
- const std::string &Name,
+ unsigned Align, const std::string &Name,
Instruction *InsertBefore)
: UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
- Name, InsertBefore) {
+ Name, InsertBefore), Alignment(Align) {
+ assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
assert(Ty != Type::VoidTy && "Cannot allocate void!");
}
AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
- const std::string &Name,
+ unsigned Align, const std::string &Name,
BasicBlock *InsertAtEnd)
: UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
- Name, InsertAtEnd) {
+ Name, InsertAtEnd), Alignment(Align) {
+ assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
assert(Ty != Type::VoidTy && "Cannot allocate void!");
}
+// Out of line virtual method, so the vtable, etc has a home.
+AllocationInst::~AllocationInst() {
+}
+
bool AllocationInst::isArrayAllocation() const {
- if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(getOperand(0)))
- return CUI->getValue() != 1;
+ if (ConstantInt *CUI = dyn_cast<ConstantInt>(getOperand(0)))
+ return CUI->getZExtValue() != 1;
return true;
}
AllocaInst::AllocaInst(const AllocaInst &AI)
: AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
- Instruction::Alloca) {
+ Instruction::Alloca, AI.getAlignment()) {
}
MallocInst::MallocInst(const MallocInst &MI)
: AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
- Instruction::Malloc) {
+ Instruction::Malloc, MI.getAlignment()) {
}
//===----------------------------------------------------------------------===//
// message on bad indexes for a gep instruction.
//
static inline const Type *checkType(const Type *Ty) {
- assert(Ty && "Invalid indices for type!");
+ assert(Ty && "Invalid GetElementPtrInst indices for type!");
return Ty;
}
OL[2].init(Idx1, this);
}
+void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
+ NumOperands = 2;
+ Use *OL = OperandList = new Use[2];
+ OL[0].init(Ptr, this);
+ OL[1].init(Idx, this);
+}
+
GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
const std::string &Name, Instruction *InBe)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
init(Ptr, Idx);
}
+GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
+ const std::string &Name, Instruction *InBe)
+ : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
+ GetElementPtr, 0, 0, Name, InBe) {
+ init(Ptr, Idx);
+}
+
+GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
+ const std::string &Name, BasicBlock *IAE)
+ : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx))),
+ GetElementPtr, 0, 0, Name, IAE) {
+ init(Ptr, Idx);
+}
+
GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
const std::string &Name, Instruction *InBe)
: Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
return 0;
}
+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!
+
+ // Check the pointer index.
+ if (!PTy->indexValid(Idx)) return 0;
+
+ return PTy->getElementType();
+}
+
+//===----------------------------------------------------------------------===//
+// ExtractElementInst Implementation
+//===----------------------------------------------------------------------===//
+
+ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
+ const std::string &Name,
+ Instruction *InsertBef)
+ : Instruction(cast<PackedType>(Val->getType())->getElementType(),
+ ExtractElement, Ops, 2, Name, InsertBef) {
+ assert(isValidOperands(Val, Index) &&
+ "Invalid extractelement instruction operands!");
+ Ops[0].init(Val, this);
+ Ops[1].init(Index, this);
+}
+
+ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
+ const std::string &Name,
+ Instruction *InsertBef)
+ : Instruction(cast<PackedType>(Val->getType())->getElementType(),
+ ExtractElement, Ops, 2, Name, InsertBef) {
+ Constant *Index = ConstantInt::get(Type::UIntTy, IndexV);
+ assert(isValidOperands(Val, Index) &&
+ "Invalid extractelement instruction operands!");
+ Ops[0].init(Val, this);
+ Ops[1].init(Index, this);
+}
+
+
+ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
+ const std::string &Name,
+ BasicBlock *InsertAE)
+ : Instruction(cast<PackedType>(Val->getType())->getElementType(),
+ ExtractElement, Ops, 2, Name, InsertAE) {
+ assert(isValidOperands(Val, Index) &&
+ "Invalid extractelement instruction operands!");
+
+ Ops[0].init(Val, this);
+ Ops[1].init(Index, this);
+}
+
+ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
+ const std::string &Name,
+ BasicBlock *InsertAE)
+ : Instruction(cast<PackedType>(Val->getType())->getElementType(),
+ ExtractElement, Ops, 2, Name, InsertAE) {
+ Constant *Index = ConstantInt::get(Type::UIntTy, IndexV);
+ assert(isValidOperands(Val, Index) &&
+ "Invalid extractelement instruction operands!");
+
+ Ops[0].init(Val, this);
+ Ops[1].init(Index, this);
+}
+
+
+bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
+ if (!isa<PackedType>(Val->getType()) || Index->getType() != Type::UIntTy)
+ return false;
+ return true;
+}
+
+
+//===----------------------------------------------------------------------===//
+// InsertElementInst Implementation
+//===----------------------------------------------------------------------===//
+
+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);
+}
+InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
+ const std::string &Name,
+ Instruction *InsertBef)
+ : Instruction(Vec->getType(), InsertElement, Ops, 3, Name, 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);
+}
+
+InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
+ const std::string &Name,
+ Instruction *InsertBef)
+ : Instruction(Vec->getType(), InsertElement, Ops, 3, Name, InsertBef) {
+ Constant *Index = ConstantInt::get(Type::UIntTy, 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);
+}
+
+
+InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
+ const std::string &Name,
+ BasicBlock *InsertAE)
+ : Instruction(Vec->getType(), InsertElement, Ops, 3, Name, 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);
+}
+
+InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
+ const std::string &Name,
+ BasicBlock *InsertAE)
+: Instruction(Vec->getType(), InsertElement, Ops, 3, Name, InsertAE) {
+ Constant *Index = ConstantInt::get(Type::UIntTy, 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);
+}
+
+bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
+ const Value *Index) {
+ if (!isa<PackedType>(Vec->getType()))
+ return false; // First operand of insertelement must be packed type.
+
+ if (Elt->getType() != cast<PackedType>(Vec->getType())->getElementType())
+ return false;// Second operand of insertelement must be packed element type.
+
+ if (Index->getType() != Type::UIntTy)
+ return false; // Third operand of insertelement must be uint.
+ return true;
+}
+
+
+//===----------------------------------------------------------------------===//
+// ShuffleVectorInst Implementation
+//===----------------------------------------------------------------------===//
+
+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);
+}
+
+ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const std::string &Name,
+ Instruction *InsertBefore)
+ : Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, 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);
+}
+
+ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd)
+ : Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, 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);
+}
+
+bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
+ const Value *Mask) {
+ if (!isa<PackedType>(V1->getType())) return false;
+ if (V1->getType() != V2->getType()) return false;
+ if (!isa<PackedType>(Mask->getType()) ||
+ cast<PackedType>(Mask->getType())->getElementType() != Type::UIntTy ||
+ cast<PackedType>(Mask->getType())->getNumElements() !=
+ cast<PackedType>(V1->getType())->getNumElements())
+ return false;
+ return true;
+}
+
+
//===----------------------------------------------------------------------===//
// BinaryOperator Class
//===----------------------------------------------------------------------===//
case Rem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() ||
- getType()->isFloatingPoint() ||
- isa<PackedType>(getType()) ) &&
+ assert((getType()->isInteger() || getType()->isFloatingPoint() ||
+ isa<PackedType>(getType())) &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case And: case Or:
case Xor:
assert(getType() == LHS->getType() &&
"Logical operation should return same type as operands!");
- assert(getType()->isIntegral() &&
+ assert((getType()->isIntegral() ||
+ (isa<PackedType>(getType()) &&
+ cast<PackedType>(getType())->getElementType()->isIntegral())) &&
"Tried to create a logical operation on a non-integral type!");
break;
case SetLT: case SetGT: case SetLE:
BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
Instruction *InsertBefore) {
- return new BinaryOperator(Instruction::Xor, Op,
- ConstantIntegral::getAllOnesValue(Op->getType()),
+ Constant *C;
+ if (const PackedType *PTy = dyn_cast<PackedType>(Op->getType())) {
+ C = ConstantIntegral::getAllOnesValue(PTy->getElementType());
+ C = ConstantPacked::get(std::vector<Constant*>(PTy->getNumElements(), C));
+ } else {
+ C = ConstantIntegral::getAllOnesValue(Op->getType());
+ }
+
+ return new BinaryOperator(Instruction::Xor, Op, C,
Op->getType(), Name, InsertBefore);
}
BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd) {
- return new BinaryOperator(Instruction::Xor, Op,
- ConstantIntegral::getAllOnesValue(Op->getType()),
+ Constant *AllOnes;
+ if (const PackedType *PTy = dyn_cast<PackedType>(Op->getType())) {
+ // Create a vector of all ones values.
+ Constant *Elt = ConstantIntegral::getAllOnesValue(PTy->getElementType());
+ AllOnes =
+ ConstantPacked::get(std::vector<Constant*>(PTy->getNumElements(), Elt));
+ } else {
+ AllOnes = ConstantIntegral::getAllOnesValue(Op->getType());
+ }
+
+ return new BinaryOperator(Instruction::Xor, Op, AllOnes,
Op->getType(), Name, InsertAtEnd);
}
return false;
}
-Value *BinaryOperator::getNegArgument(BinaryOperator *Bop) {
- assert(isNeg(Bop) && "getNegArgument from non-'neg' instruction!");
- return Bop->getOperand(1);
+Value *BinaryOperator::getNegArgument(Value *BinOp) {
+ assert(isNeg(BinOp) && "getNegArgument from non-'neg' instruction!");
+ return cast<BinaryOperator>(BinOp)->getOperand(1);
}
-const Value *BinaryOperator::getNegArgument(const BinaryOperator *Bop) {
- return getNegArgument((BinaryOperator*)Bop);
+const Value *BinaryOperator::getNegArgument(const Value *BinOp) {
+ return getNegArgument(const_cast<Value*>(BinOp));
}
-Value *BinaryOperator::getNotArgument(BinaryOperator *Bop) {
- assert(isNot(Bop) && "getNotArgument on non-'not' instruction!");
- Value *Op0 = Bop->getOperand(0);
- Value *Op1 = Bop->getOperand(1);
+Value *BinaryOperator::getNotArgument(Value *BinOp) {
+ assert(isNot(BinOp) && "getNotArgument on non-'not' instruction!");
+ BinaryOperator *BO = cast<BinaryOperator>(BinOp);
+ Value *Op0 = BO->getOperand(0);
+ Value *Op1 = BO->getOperand(1);
if (isConstantAllOnes(Op0)) return Op1;
assert(isConstantAllOnes(Op1));
return Op0;
}
-const Value *BinaryOperator::getNotArgument(const BinaryOperator *Bop) {
- return getNotArgument((BinaryOperator*)Bop);
+const Value *BinaryOperator::getNotArgument(const Value *BinOp) {
+ return getNotArgument(const_cast<Value*>(BinOp));
}
}
+//===----------------------------------------------------------------------===//
+// ShiftInst Class
+//===----------------------------------------------------------------------===//
+
+/// isLogicalShift - Return true if this is a logical shift left or a logical
+/// shift right.
+bool ShiftInst::isLogicalShift() const {
+ return getOpcode() == Instruction::Shl || getType()->isUnsigned();
+}
+
+//===----------------------------------------------------------------------===//
+// CastInst Class
+//===----------------------------------------------------------------------===//
+
+/// isTruncIntCast - Return true if this is a truncating integer cast
+/// instruction, e.g. a cast from long to uint.
+bool CastInst::isTruncIntCast() const {
+ // The dest type has to be integral, the input has to be integer.
+ if (!getType()->isIntegral() || !getOperand(0)->getType()->isInteger())
+ return false;
+
+ // Has to be large to smaller.
+ return getOperand(0)->getType()->getPrimitiveSizeInBits() >
+ getType()->getPrimitiveSizeInBits();
+}
+
+
//===----------------------------------------------------------------------===//
// SetCondInst Class
//===----------------------------------------------------------------------===//
CallInst *CallInst::clone() const { return new CallInst(*this); }
ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); }
SelectInst *SelectInst::clone() const { return new SelectInst(*this); }
-VANextInst *VANextInst::clone() const { return new VANextInst(*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);
+}
+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); }