X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstructions.cpp;h=800eb9cd1d866850315993ded9d946c57f5c26b6;hb=b83eb6447ba155342598f0fabe1f08f5baa9164a;hp=5c88c5428ddb15169e95491df7a43af3f0bca735;hpb=f818cfe0969d74ca356f87947b651230fdad6ed0;p=oota-llvm.git diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 5c88c5428dd..800eb9cd1d8 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -20,6 +20,22 @@ #include "llvm/Support/CallSite.h" using namespace llvm; +unsigned CallSite::getCallingConv() const { + if (CallInst *CI = dyn_cast(I)) + return CI->getCallingConv(); + else + return cast(I)->getCallingConv(); +} +void CallSite::setCallingConv(unsigned CC) { + if (CallInst *CI = dyn_cast(I)) + CI->setCallingConv(CC); + else + cast(I)->setCallingConv(CC); +} + + + + //===----------------------------------------------------------------------===// // TerminatorInst Class //===----------------------------------------------------------------------===// @@ -34,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() { +} //===----------------------------------------------------------------------===// @@ -118,6 +141,52 @@ void PHINode::resizeOperands(unsigned NumOps) { 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(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(InVal)) + // If it's in the entry block, it dominates everything. + if (IV->getParent() != &IV->getParent()->getParent()->front() || + isa(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 @@ -137,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) { @@ -153,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) { @@ -169,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) { @@ -249,6 +331,7 @@ CallInst::CallInst(Value *Func, const std::string &Name, 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) @@ -278,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, @@ -305,6 +393,7 @@ 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); @@ -424,32 +513,41 @@ 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; } 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(getOperand(0))) - return CUI->getValue() != 1; + if (ConstantInt *CUI = dyn_cast(getOperand(0))) + return CUI->getZExtValue() != 1; return true; } @@ -459,12 +557,12 @@ const Type *AllocationInst::getAllocatedType() const { 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()) { } //===----------------------------------------------------------------------===// @@ -582,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; } @@ -731,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 //===----------------------------------------------------------------------===// @@ -747,16 +1026,17 @@ void BinaryOperator::init(BinaryOps iType) case Rem: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); - assert((getType()->isInteger() || - getType()->isFloatingPoint() || - isa(getType()) ) && + assert((getType()->isInteger() || getType()->isFloatingPoint() || + isa(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(getType()) && + cast(getType())->getElementType()->isIntegral())) && "Tried to create a logical operation on a non-integral type!"); break; case SetLT: case SetGT: case SetLE: @@ -818,15 +1098,31 @@ 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); } 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(Op->getType())) { + // Create a vector of all ones values. + Constant *Elt = ConstantIntegral::getAllOnesValue(PTy->getElementType()); + AllOnes = + ConstantPacked::get(std::vector(PTy->getNumElements(), Elt)); + } else { + AllOnes = ConstantIntegral::getAllOnesValue(Op->getType()); + } + + return new BinaryOperator(Instruction::Xor, Op, AllOnes, Op->getType(), Name, InsertAtEnd); } @@ -898,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 //===----------------------------------------------------------------------===// @@ -1080,8 +1403,16 @@ CastInst *CastInst::clone() const { return new CastInst(*this); } 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); }