X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstructions.cpp;h=800eb9cd1d866850315993ded9d946c57f5c26b6;hb=b83eb6447ba155342598f0fabe1f08f5baa9164a;hp=1b8d0387cf9a3e9339c0d4db70c3133dd3c0baaa;hpb=b9d4100f327647debd0936fe403cdef00ab56859;p=oota-llvm.git diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 1b8d0387cf9..800eb9cd1d8 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -34,6 +34,8 @@ void CallSite::setCallingConv(unsigned CC) { } + + //===----------------------------------------------------------------------===// // TerminatorInst Class //===----------------------------------------------------------------------===// @@ -48,6 +50,13 @@ TerminatorInst::TerminatorInst(Instruction::TermOps iType, : 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() { +} //===----------------------------------------------------------------------===// @@ -197,9 +206,13 @@ void CallInst::init(Value *Func, const std::vector &Params) { 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) { @@ -213,8 +226,14 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { cast(cast(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) { @@ -229,6 +248,9 @@ 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) { @@ -339,8 +361,13 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, (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, @@ -486,10 +513,13 @@ void BranchInst::setSuccessorV(unsigned idx, BasicBlock *B) { static Value *getAISize(Value *Amt) { if (!Amt) - Amt = ConstantUInt::get(Type::UIntTy, 1); - else + Amt = ConstantInt::get(Type::UIntTy, 1); + else { + assert(!isa(Amt) && + "Passed basic block into allocation size parameter! Ue other ctor"); assert(Amt->getType() == Type::UIntTy && "Malloc/Allocation array size != UIntTy!"); + } return Amt; } @@ -511,9 +541,13 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 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(getOperand(0))) - return CUI->getValue() != 1; + if (ConstantInt *CUI = dyn_cast(getOperand(0))) + return CUI->getZExtValue() != 1; return true; } @@ -646,7 +680,7 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, // 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; } @@ -795,6 +829,187 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { return PTy->getElementType(); } +//===----------------------------------------------------------------------===// +// ExtractElementInst Implementation +//===----------------------------------------------------------------------===// + +ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, + const std::string &Name, + Instruction *InsertBef) + : Instruction(cast(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(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(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(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(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(Vec->getType())) + return false; // First operand of insertelement must be packed type. + + if (Elt->getType() != cast(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(V1->getType())) return false; + if (V1->getType() != V2->getType()) return false; + if (!isa(Mask->getType()) || + cast(Mask->getType())->getElementType() != Type::UIntTy || + cast(Mask->getType())->getNumElements() != + cast(V1->getType())->getNumElements()) + return false; + return true; +} + + //===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -883,8 +1098,15 @@ BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name, 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(Op->getType())) { + C = ConstantIntegral::getAllOnesValue(PTy->getElementType()); + C = ConstantPacked::get(std::vector(PTy->getNumElements(), C)); + } else { + C = ConstantIntegral::getAllOnesValue(Op->getType()); + } + + return new BinaryOperator(Instruction::Xor, Op, C, Op->getType(), Name, InsertBefore); } @@ -972,6 +1194,33 @@ bool BinaryOperator::swapOperands() { } +//===----------------------------------------------------------------------===// +// 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 //===----------------------------------------------------------------------===// @@ -1155,6 +1404,15 @@ CallInst *CallInst::clone() const { return new CallInst(*this); } ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); } SelectInst *SelectInst::clone() const { return new 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); +} +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); }