X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstructions.cpp;h=800eb9cd1d866850315993ded9d946c57f5c26b6;hb=b83eb6447ba155342598f0fabe1f08f5baa9164a;hp=e936fafa229b8cd578d8cd17d40f40fbec0acfbe;hpb=b12261ac698bf9c8dd118bb94d87aae266dac98a;p=oota-llvm.git diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index e936fafa229..800eb9cd1d8 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1,10 +1,10 @@ //===-- Instructions.cpp - Implement the LLVM instructions ----------------===// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file implements all of the non-inline methods for the LLVM instruction @@ -20,12 +20,28 @@ #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 //===----------------------------------------------------------------------===// TerminatorInst::TerminatorInst(Instruction::TermOps iType, - Use *Ops, unsigned NumOps, Instruction *IB) + Use *Ops, unsigned NumOps, Instruction *IB) : Instruction(Type::VoidTy, iType, Ops, NumOps, "", IB) { } @@ -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() { +} //===----------------------------------------------------------------------===// @@ -104,7 +127,7 @@ void PHINode::resizeOperands(unsigned NumOps) { } else if (NumOps == NumOperands) { if (ReservedSpace == NumOps) return; } else { - return; + return; } ReservedSpace = NumOps; @@ -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 @@ -132,14 +201,18 @@ void CallInst::init(Value *Func, const std::vector &Params) { Use *OL = OperandList = new Use[Params.size()+1]; OL[0].init(Func, this); - const FunctionType *FTy = + const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); - assert((Params.size() == FTy->getNumParams() || + 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) { @@ -148,13 +221,19 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { OL[0].init(Func, this); OL[1].init(Actual1, this); OL[2].init(Actual2, this); - - const FunctionType *FTy = + + const FunctionType *FTy = 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) { @@ -162,36 +241,39 @@ void CallInst::init(Value *Func, Value *Actual) { Use *OL = OperandList = new Use[2]; OL[0].init(Func, this); OL[1].init(Actual, this); - - const FunctionType *FTy = + + const FunctionType *FTy = cast(cast(Func->getType())->getElementType()); 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) { NumOperands = 1; Use *OL = OperandList = new Use[1]; OL[0].init(Func, this); - - const FunctionType *MTy = + + const FunctionType *MTy = cast(cast(Func->getType())->getElementType()); assert(MTy->getNumParams() == 0 && "Calling a function with bad signature"); } -CallInst::CallInst(Value *Func, const std::vector &Params, - const std::string &Name, Instruction *InsertBefore) +CallInst::CallInst(Value *Func, const std::vector &Params, + const std::string &Name, Instruction *InsertBefore) : Instruction(cast(cast(Func->getType()) ->getElementType())->getReturnType(), Instruction::Call, 0, 0, Name, InsertBefore) { init(Func, Params); } -CallInst::CallInst(Value *Func, const std::vector &Params, - const std::string &Name, BasicBlock *InsertAtEnd) +CallInst::CallInst(Value *Func, const std::vector &Params, + const std::string &Name, BasicBlock *InsertAtEnd) : Instruction(cast(cast(Func->getType()) ->getElementType())->getReturnType(), Instruction::Call, 0, 0, Name, InsertAtEnd) { @@ -246,9 +328,10 @@ CallInst::CallInst(Value *Func, const std::string &Name, init(Func); } -CallInst::CallInst(const CallInst &CI) +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) @@ -271,15 +354,20 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, OL[0].init(Fn, this); OL[1].init(IfNormal, this); OL[2].init(IfException, this); - const FunctionType *FTy = + const FunctionType *FTy = cast(cast(Fn->getType())->getElementType()); - - assert((Params.size() == FTy->getNumParams()) || + + 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++) + + 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, @@ -302,9 +390,10 @@ InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal, init(Fn, IfNormal, IfException, Params); } -InvokeInst::InvokeInst(const InvokeInst &II) +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); @@ -327,7 +416,7 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { void ReturnInst::init(Value *retVal) { if (retVal && retVal->getType() != Type::VoidTy) { - assert(!isa(retVal) && + assert(!isa(retVal) && "Cannot return basic block. Probably using the incorrect ctor"); NumOperands = 1; RetVal.init(retVal, this); @@ -393,7 +482,7 @@ BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const { void BranchInst::AssertOK() { if (isConditional()) - assert(getCondition()->getType() == Type::BoolTy && + assert(getCondition()->getType() == Type::BoolTy && "May only branch on boolean predicates!"); } @@ -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; + } + return Amt; } -AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name, +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + 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, +AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + 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()) { } //===----------------------------------------------------------------------===// @@ -492,33 +590,37 @@ FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) //===----------------------------------------------------------------------===// void LoadInst::AssertOK() { - assert(isa(getOperand(0)->getType()) && + assert(isa(getOperand(0)->getType()) && "Ptr must have pointer type."); } LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, Name, InsertBef), Volatile(false) { + Load, Ptr, Name, InsertBef) { + setVolatile(false); AssertOK(); } LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE) : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, Name, InsertAE), Volatile(false) { + Load, Ptr, Name, InsertAE) { + setVolatile(false); AssertOK(); } LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, Instruction *InsertBef) : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, Name, InsertBef), Volatile(isVolatile) { + Load, Ptr, Name, InsertBef) { + setVolatile(isVolatile); AssertOK(); } LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, BasicBlock *InsertAE) : UnaryInstruction(cast(Ptr->getType())->getElementType(), - Load, Ptr, Name, InsertAE), Volatile(isVolatile) { + Load, Ptr, Name, InsertAE) { + setVolatile(isVolatile); AssertOK(); } @@ -537,35 +639,36 @@ void StoreInst::AssertOK() { StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertBefore), - Volatile(false) { + : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertBefore) { Ops[0].init(val, this); Ops[1].init(addr, this); + setVolatile(false); AssertOK(); } StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd) - : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertAtEnd), Volatile(false) { + : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertAtEnd) { Ops[0].init(val, this); Ops[1].init(addr, this); + setVolatile(false); AssertOK(); } -StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, +StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertBefore), - Volatile(isVolatile) { + : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertBefore) { Ops[0].init(val, this); Ops[1].init(addr, this); + setVolatile(isVolatile); AssertOK(); } -StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, +StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, BasicBlock *InsertAtEnd) - : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertAtEnd), - Volatile(isVolatile) { + : Instruction(Type::VoidTy, Store, Ops, 2, "", InsertAtEnd) { Ops[0].init(val, this); Ops[1].init(addr, this); + setVolatile(isVolatile); AssertOK(); } @@ -577,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; } @@ -598,8 +701,15 @@ void GetElementPtrInst::init(Value *Ptr, Value *Idx0, Value *Idx1) { 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 &Idx, - const std::string &Name, Instruction *InBe) + const std::string &Name, Instruction *InBe) : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), Idx, true))), GetElementPtr, 0, 0, Name, InBe) { @@ -607,13 +717,27 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, } GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name, BasicBlock *IAE) + const std::string &Name, BasicBlock *IAE) : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), Idx, true))), GetElementPtr, 0, 0, Name, IAE) { 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(), @@ -623,7 +747,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, } GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1, - const std::string &Name, BasicBlock *IAE) + const std::string &Name, BasicBlock *IAE) : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), Idx0, Idx1, true))), GetElementPtr, 0, 0, Name, IAE) { @@ -637,10 +761,10 @@ GetElementPtrInst::~GetElementPtrInst() { // getIndexedType - Returns the type of the element that would be loaded with // a load instruction with the specified parameters. // -// A null type is returned if the indices are invalid for the specified +// A null type is returned if the indices are invalid for the specified // pointer type. // -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, const std::vector &Idx, bool AllowCompositeLeaf) { if (!isa(Ptr)) return 0; // Type isn't a pointer type! @@ -652,7 +776,7 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, return cast(Ptr)->getElementType(); else return 0; - + unsigned CurIdx = 0; while (const CompositeType *CT = dyn_cast(Ptr)) { if (Idx.size() == CurIdx) { @@ -677,7 +801,7 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, return CurIdx == Idx.size() ? Ptr : 0; } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1, bool AllowCompositeLeaf) { const PointerType *PTy = dyn_cast(Ptr); @@ -695,6 +819,197 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, return 0; } +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { + const PointerType *PTy = dyn_cast(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(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 //===----------------------------------------------------------------------===// @@ -711,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: @@ -733,7 +1049,7 @@ void BinaryOperator::init(BinaryOps iType) } BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, + const std::string &Name, Instruction *InsertBefore) { assert(S1->getType() == S2->getType() && "Cannot create binary operator with two operands of differing type!"); @@ -749,7 +1065,7 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, } BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, + const std::string &Name, BasicBlock *InsertAtEnd) { BinaryOperator *Res = create(Op, S1, S2, Name); InsertAtEnd->getInstList().push_back(Res); @@ -782,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); } @@ -818,27 +1150,28 @@ bool BinaryOperator::isNot(const Value *V) { 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(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(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(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(BinOp)); } @@ -861,11 +1194,38 @@ 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 //===----------------------------------------------------------------------===// -SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, +SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, const std::string &Name, Instruction *InsertBefore) : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) { @@ -873,7 +1233,7 @@ SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, assert(getInverseCondition(Opcode)); } -SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, +SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, const std::string &Name, BasicBlock *InsertAtEnd) : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) { @@ -926,7 +1286,7 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) { OperandList[1].init(Default, this); } -SwitchInst::SwitchInst(const SwitchInst &SI) +SwitchInst::SwitchInst(const SwitchInst &SI) : TerminatorInst(Instruction::Switch, new Use[SI.getNumOperands()], SI.getNumOperands()) { Use *OL = OperandList, *InOL = SI.OperandList; @@ -943,11 +1303,12 @@ SwitchInst::~SwitchInst() { /// addCase - Add an entry to the switch instruction... /// -void SwitchInst::addCase(Constant *OnVal, BasicBlock *Dest) { +void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) resizeOperands(0); // Get more space! // Initialize some new operands. + assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+2; OperandList[OpNo].init(OnVal, this); OperandList[OpNo+1].init(Dest, this); @@ -989,14 +1350,14 @@ void SwitchInst::removeCase(unsigned idx) { /// void SwitchInst::resizeOperands(unsigned NumOps) { if (NumOps == 0) { - NumOps = (getNumOperands())*3/2; + NumOps = getNumOperands()/2*6; } else if (NumOps*2 > NumOperands) { // No resize needed. if (ReservedSpace >= NumOps) return; } else if (NumOps == NumOperands) { if (ReservedSpace == NumOps) return; } else { - return; + return; } ReservedSpace = NumOps; @@ -1042,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); }