X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstructions.cpp;h=e807edc5126a83a23409b3131c4a9bca56e35751;hb=fd8d62c0b449b9070dc18355ac243c7fa78d40d6;hp=abee7b741a55a697fce11f8e5d9ae19c0018c8fd;hpb=ff03048c1350fcc4fda1ef6d6c57252f3a950854;p=oota-llvm.git diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index abee7b741a5..e807edc5126 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -161,8 +161,14 @@ Value *PHINode::hasConstantValue() const { // Exploit the fact that phi nodes always have at least one entry. Value *ConstantValue = getIncomingValue(0); for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i) - if (getIncomingValue(i) != ConstantValue) - return 0; // Incoming values not all the same. + if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) { + if (ConstantValue != this) + return 0; // Incoming values not all the same. + // The case where the first value is this PHI. + ConstantValue = getIncomingValue(i); + } + if (ConstantValue == this) + return UndefValue::get(getType()); return ConstantValue; } @@ -170,13 +176,18 @@ Value *PHINode::hasConstantValue() const { // LandingPadInst Implementation //===----------------------------------------------------------------------===// -void LandingPadInst::init(Function *PersFn, unsigned NumReservedValues, - const Twine &NameStr) { - ReservedSpace = NumReservedValues; - NumOperands = 1; - OperandList = allocHungoffUses(ReservedSpace); - OperandList[0] = (Value*)PersFn; - setName(NameStr); +LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + Instruction *InsertBefore) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); +} + +LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); } LandingPadInst::LandingPadInst(const LandingPadInst &LP) @@ -187,37 +198,45 @@ LandingPadInst::LandingPadInst(const LandingPadInst &LP) for (unsigned I = 0, E = ReservedSpace; I != E; ++I) OL[I] = InOL[I]; - for (SmallVectorImpl::const_iterator - I = LP.ClauseIdxs.begin(), E = LP.ClauseIdxs.end(); I != E; ++I) - ClauseIdxs.push_back(*I); - - IsCleanup = LP.IsCleanup; - SubclassOptionalData = LP.SubclassOptionalData; + setCleanup(LP.isCleanup()); } LandingPadInst::~LandingPadInst() { dropHungoffUses(); } -/// growOperands - grow operands - This grows the operand list in response to a -/// push_back style of operation. This grows the number of ops by 2 times. -void LandingPadInst::growOperands() { - unsigned e = getNumOperands(); - ReservedSpace = e * 2; +LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr, + Instruction *InsertBefore) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, + InsertBefore); +} - Use *NewOps = allocHungoffUses(ReservedSpace); - Use *OldOps = OperandList; - for (unsigned i = 0; i != e; ++i) - NewOps[i] = OldOps[i]; +LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr, + BasicBlock *InsertAtEnd) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, + InsertAtEnd); +} - OperandList = NewOps; - Use::zap(OldOps, OldOps + e, true); +void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues, + const Twine &NameStr) { + ReservedSpace = NumReservedValues; + NumOperands = 1; + OperandList = allocHungoffUses(ReservedSpace); + OperandList[0] = PersFn; + setName(NameStr); + setCleanup(false); } -void LandingPadInst::reserveClauses(unsigned Size) { +/// growOperands - grow operands - This grows the operand list in response to a +/// push_back style of operation. This grows the number of ops by 2 times. +void LandingPadInst::growOperands(unsigned Size) { unsigned e = getNumOperands(); if (ReservedSpace >= e + Size) return; - ReservedSpace = e + Size; + ReservedSpace = (e + Size / 2) * 2; Use *NewOps = allocHungoffUses(ReservedSpace); Use *OldOps = OperandList; @@ -228,14 +247,12 @@ void LandingPadInst::reserveClauses(unsigned Size) { Use::zap(OldOps, OldOps + e, true); } -void LandingPadInst::addClause(ClauseType CT, Constant *ClauseVal) { +void LandingPadInst::addClause(Value *Val) { unsigned OpNo = getNumOperands(); - if (OpNo + 1 > ReservedSpace) - growOperands(); + growOperands(1); assert(OpNo < ReservedSpace && "Growing didn't work!"); - ClauseIdxs.push_back(CT); ++NumOperands; - OperandList[OpNo] = (Value*)ClauseVal; + OperandList[OpNo] = Val; } //===----------------------------------------------------------------------===// @@ -315,21 +332,29 @@ CallInst::CallInst(const CallInst &CI) void CallInst::addAttribute(unsigned i, Attributes attr) { AttrListPtr PAL = getAttributes(); - PAL = PAL.addAttr(i, attr); + PAL = PAL.addAttr(getContext(), i, attr); setAttributes(PAL); } void CallInst::removeAttribute(unsigned i, Attributes attr) { AttrListPtr PAL = getAttributes(); - PAL = PAL.removeAttr(i, attr); + PAL = PAL.removeAttr(getContext(), i, attr); setAttributes(PAL); } -bool CallInst::paramHasAttr(unsigned i, Attributes attr) const { - if (AttributeList.paramHasAttr(i, attr)) +bool CallInst::hasFnAttr(Attributes::AttrVal A) const { + if (AttributeList.getParamAttributes(~0U).hasAttribute(A)) return true; if (const Function *F = getCalledFunction()) - return F->paramHasAttr(i, attr); + return F->getParamAttributes(~0U).hasAttribute(A); + return false; +} + +bool CallInst::paramHasAttr(unsigned i, Attributes::AttrVal A) const { + if (AttributeList.getParamAttributes(i).hasAttribute(A)) + return true; + if (const Function *F = getCalledFunction()) + return F->getParamAttributes(i).hasAttribute(A); return false; } @@ -545,27 +570,35 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } -bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const { - if (AttributeList.paramHasAttr(i, attr)) +bool InvokeInst::hasFnAttr(Attributes::AttrVal A) const { + if (AttributeList.getParamAttributes(~0U).hasAttribute(A)) return true; if (const Function *F = getCalledFunction()) - return F->paramHasAttr(i, attr); + return F->getParamAttributes(~0U).hasAttribute(A); + return false; +} + +bool InvokeInst::paramHasAttr(unsigned i, Attributes::AttrVal A) const { + if (AttributeList.getParamAttributes(i).hasAttribute(A)) + return true; + if (const Function *F = getCalledFunction()) + return F->getParamAttributes(i).hasAttribute(A); return false; } void InvokeInst::addAttribute(unsigned i, Attributes attr) { AttrListPtr PAL = getAttributes(); - PAL = PAL.addAttr(i, attr); + PAL = PAL.addAttr(getContext(), i, attr); setAttributes(PAL); } void InvokeInst::removeAttribute(unsigned i, Attributes attr) { AttrListPtr PAL = getAttributes(); - PAL = PAL.removeAttr(i, attr); + PAL = PAL.removeAttr(getContext(), i, attr); setAttributes(PAL); } -LandingPadInst *InvokeInst::getLandingPad() const { +LandingPadInst *InvokeInst::getLandingPadInst() const { return cast(getUnwindDest()->getFirstNonPHI()); } @@ -614,39 +647,11 @@ void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const { llvm_unreachable("ReturnInst has no successors!"); - return 0; } ReturnInst::~ReturnInst() { } -//===----------------------------------------------------------------------===// -// UnwindInst Implementation -//===----------------------------------------------------------------------===// - -UnwindInst::UnwindInst(LLVMContext &Context, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, - 0, 0, InsertBefore) { -} -UnwindInst::UnwindInst(LLVMContext &Context, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, - 0, 0, InsertAtEnd) { -} - - -unsigned UnwindInst::getNumSuccessorsV() const { - return getNumSuccessors(); -} - -void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - llvm_unreachable("UnwindInst has no successors!"); -} - -BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const { - llvm_unreachable("UnwindInst has no successors!"); - return 0; -} - //===----------------------------------------------------------------------===// // ResumeInst Implementation //===----------------------------------------------------------------------===// @@ -655,17 +660,16 @@ ResumeInst::ResumeInst(const ResumeInst &RI) : TerminatorInst(Type::getVoidTy(RI.getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1) { Op<0>() = RI.Op<0>(); - SubclassOptionalData = RI.SubclassOptionalData; } -ResumeInst::ResumeInst(LLVMContext &C, Value *Exn, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(C), Instruction::Resume, +ResumeInst::ResumeInst(Value *Exn, Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1, InsertBefore) { Op<0>() = Exn; } -ResumeInst::ResumeInst(LLVMContext &C, Value *Exn, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(C), Instruction::Resume, +ResumeInst::ResumeInst(Value *Exn, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume, OperandTraits::op_begin(this), 1, InsertAtEnd) { Op<0>() = Exn; } @@ -680,7 +684,6 @@ void ResumeInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const { llvm_unreachable("ResumeInst has no successors!"); - return 0; } //===----------------------------------------------------------------------===// @@ -707,7 +710,6 @@ void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const { llvm_unreachable("UnreachableInst has no successors!"); - return 0; } //===----------------------------------------------------------------------===// @@ -775,6 +777,27 @@ BranchInst::BranchInst(const BranchInst &BI) : SubclassOptionalData = BI.SubclassOptionalData; } +void BranchInst::swapSuccessors() { + assert(isConditional() && + "Cannot swap successors of an unconditional branch"); + Op<-1>().swap(Op<-2>()); + + // Update profile metadata if present and it matches our structural + // expectations. + MDNode *ProfileData = getMetadata(LLVMContext::MD_prof); + if (!ProfileData || ProfileData->getNumOperands() != 3) + return; + + // The first operand is the name. Fetch them backwards and build a new one. + Value *Ops[] = { + ProfileData->getOperand(0), + ProfileData->getOperand(2), + ProfileData->getOperand(1) + }; + setMetadata(LLVMContext::MD_prof, + MDNode::get(ProfileData->getContext(), Ops)); +} + BasicBlock *BranchInst::getSuccessorV(unsigned idx) const { return getSuccessor(idx); } @@ -897,6 +920,8 @@ bool AllocaInst::isStaticAlloca() const { void LoadInst::AssertOK() { assert(getOperand(0)->getType()->isPointerTy() && "Ptr must have pointer type."); + assert(!(isAtomic() && getAlignment() == 0) && + "Alignment required for atomic load"); } LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef) @@ -904,6 +929,7 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef) Load, Ptr, InsertBef) { setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); setName(Name); } @@ -913,6 +939,7 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, BasicBlock *InsertAE) Load, Ptr, InsertAE) { setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); setName(Name); } @@ -923,6 +950,18 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, Load, Ptr, InsertBef) { setVolatile(isVolatile); setAlignment(0); + setAtomic(NotAtomic); + AssertOK(); + setName(Name); +} + +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, + BasicBlock *InsertAE) + : UnaryInstruction(cast(Ptr->getType())->getElementType(), + Load, Ptr, InsertAE) { + setVolatile(isVolatile); + setAlignment(0); + setAtomic(NotAtomic); AssertOK(); setName(Name); } @@ -933,6 +972,7 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, Load, Ptr, InsertBef) { setVolatile(isVolatile); setAlignment(Align); + setAtomic(NotAtomic); AssertOK(); setName(Name); } @@ -943,27 +983,43 @@ LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, Load, Ptr, InsertAE) { setVolatile(isVolatile); setAlignment(Align); + setAtomic(NotAtomic); AssertOK(); setName(Name); } -LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, + Instruction *InsertBef) + : UnaryInstruction(cast(Ptr->getType())->getElementType(), + Load, Ptr, InsertBef) { + setVolatile(isVolatile); + setAlignment(Align); + setAtomic(Order, SynchScope); + AssertOK(); + setName(Name); +} + +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, BasicBlock *InsertAE) : UnaryInstruction(cast(Ptr->getType())->getElementType(), Load, Ptr, InsertAE) { setVolatile(isVolatile); - setAlignment(0); + setAlignment(Align); + setAtomic(Order, SynchScope); AssertOK(); setName(Name); } - - LoadInst::LoadInst(Value *Ptr, const char *Name, Instruction *InsertBef) : UnaryInstruction(cast(Ptr->getType())->getElementType(), Load, Ptr, InsertBef) { setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); if (Name && Name[0]) setName(Name); } @@ -973,6 +1029,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAE) Load, Ptr, InsertAE) { setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); if (Name && Name[0]) setName(Name); } @@ -983,6 +1040,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile, Load, Ptr, InsertBef) { setVolatile(isVolatile); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); if (Name && Name[0]) setName(Name); } @@ -993,6 +1051,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile, Load, Ptr, InsertAE) { setVolatile(isVolatile); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); if (Name && Name[0]) setName(Name); } @@ -1001,7 +1060,7 @@ void LoadInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); - setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | ((Log2_32(Align)+1)<<1)); assert(getAlignment() == Align && "Alignment representation error!"); } @@ -1017,6 +1076,8 @@ void StoreInst::AssertOK() { assert(getOperand(0)->getType() == cast(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"); + assert(!(isAtomic() && getAlignment() == 0) && + "Alignment required for atomic load"); } @@ -1029,6 +1090,7 @@ StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) Op<1>() = addr; setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); } @@ -1041,6 +1103,7 @@ StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd) Op<1>() = addr; setVolatile(false); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); } @@ -1054,6 +1117,7 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Op<1>() = addr; setVolatile(isVolatile); setAlignment(0); + setAtomic(NotAtomic); AssertOK(); } @@ -1067,6 +1131,37 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Op<1>() = addr; setVolatile(isVolatile); setAlignment(Align); + setAtomic(NotAtomic); + AssertOK(); +} + +StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, + Instruction *InsertBefore) + : Instruction(Type::getVoidTy(val->getContext()), Store, + OperandTraits::op_begin(this), + OperandTraits::operands(this), + InsertBefore) { + Op<0>() = val; + Op<1>() = addr; + setVolatile(isVolatile); + setAlignment(Align); + setAtomic(Order, SynchScope); + AssertOK(); +} + +StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, + BasicBlock *InsertAtEnd) + : Instruction(Type::getVoidTy(val->getContext()), Store, + OperandTraits::op_begin(this), + OperandTraits::operands(this), + InsertAtEnd) { + Op<0>() = val; + Op<1>() = addr; + setVolatile(isVolatile); + setAlignment(0); + setAtomic(NotAtomic); AssertOK(); } @@ -1080,10 +1175,13 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Op<1>() = addr; setVolatile(isVolatile); setAlignment(Align); + setAtomic(NotAtomic); AssertOK(); } StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits::op_begin(this), @@ -1092,7 +1190,8 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Op<0>() = val; Op<1>() = addr; setVolatile(isVolatile); - setAlignment(0); + setAlignment(Align); + setAtomic(Order, SynchScope); AssertOK(); } @@ -1100,7 +1199,7 @@ void StoreInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); - setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(31 << 1)) | ((Log2_32(Align)+1) << 1)); assert(getAlignment() == Align && "Alignment representation error!"); } @@ -1252,6 +1351,15 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) /// template static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef IdxList) { + if (Ptr->isVectorTy()) { + assert(IdxList.size() == 1 && + "GEP with vector pointers must have a single index"); + PointerType *PTy = dyn_cast( + cast(Ptr)->getElementType()); + assert(PTy && "Gep with invalid vector pointer found"); + return PTy->getElementType(); + } + PointerType *PTy = dyn_cast(Ptr); if (!PTy) return 0; // Type isn't a pointer type! Type *Agg = PTy->getElementType(); @@ -1259,7 +1367,7 @@ static Type *getIndexedTypeInternal(Type *Ptr, ArrayRef IdxList) { // Handle the special case of the empty set index set, which is always valid. if (IdxList.empty()) return Agg; - + // If there is at least one index, the top level type must be sized, otherwise // it cannot be 'stepped over'. if (!Agg->isSized()) @@ -1289,6 +1397,18 @@ Type *GetElementPtrInst::getIndexedType(Type *Ptr, ArrayRef IdxList) { return getIndexedTypeInternal(Ptr, IdxList); } +unsigned GetElementPtrInst::getAddressSpace(Value *Ptr) { + Type *Ty = Ptr->getType(); + + if (VectorType *VTy = dyn_cast(Ty)) + Ty = VTy->getElementType(); + + if (PointerType *PTy = dyn_cast(Ty)) + return PTy->getAddressSpace(); + + llvm_unreachable("Invalid GEP pointer type"); +} + /// hasAllZeroIndices - Return true if all of the indices of this GEP are /// zeros. If so, the result pointer and the first operand have the same /// value, just potentially different types. @@ -1451,46 +1571,84 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, const Value *Mask) { + // V1 and V2 must be vectors of the same type. if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType()) return false; + // Mask must be vector of i32. VectorType *MaskTy = dyn_cast(Mask->getType()); if (MaskTy == 0 || !MaskTy->getElementType()->isIntegerTy(32)) return false; // Check to see if Mask is valid. + if (isa(Mask) || isa(Mask)) + return true; + if (const ConstantVector *MV = dyn_cast(Mask)) { - VectorType *VTy = cast(V1->getType()); + unsigned V1Size = cast(V1->getType())->getNumElements(); for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) { - if (ConstantInt* CI = dyn_cast(MV->getOperand(i))) { - if (CI->uge(VTy->getNumElements()*2)) + if (ConstantInt *CI = dyn_cast(MV->getOperand(i))) { + if (CI->uge(V1Size*2)) return false; } else if (!isa(MV->getOperand(i))) { return false; } } + return true; } - else if (!isa(Mask) && !isa(Mask)) - return false; - return true; + if (const ConstantDataSequential *CDS = + dyn_cast(Mask)) { + unsigned V1Size = cast(V1->getType())->getNumElements(); + for (unsigned i = 0, e = MaskTy->getNumElements(); i != e; ++i) + if (CDS->getElementAsInteger(i) >= V1Size*2) + return false; + return true; + } + + // The bitcode reader can create a place holder for a forward reference + // used as the shuffle mask. When this occurs, the shuffle mask will + // fall into this case and fail. To avoid this error, do this bit of + // ugliness to allow such a mask pass. + if (const ConstantExpr *CE = dyn_cast(Mask)) + if (CE->getOpcode() == Instruction::UserOp1) + return true; + + return false; } /// 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(getOperand(2)); - if (isa(Mask)) return -1; - if (isa(Mask)) return 0; - const ConstantVector *MaskCV = cast(Mask); - assert(i < MaskCV->getNumOperands() && "Index out of range"); - - if (isa(MaskCV->getOperand(i))) +int ShuffleVectorInst::getMaskValue(Constant *Mask, unsigned i) { + assert(i < Mask->getType()->getVectorNumElements() && "Index out of range"); + if (ConstantDataSequential *CDS =dyn_cast(Mask)) + return CDS->getElementAsInteger(i); + Constant *C = Mask->getAggregateElement(i); + if (isa(C)) return -1; - return cast(MaskCV->getOperand(i))->getZExtValue(); + return cast(C)->getZExtValue(); +} + +/// getShuffleMask - Return the full mask for this instruction, where each +/// element is the element number and undef's are returned as -1. +void ShuffleVectorInst::getShuffleMask(Constant *Mask, + SmallVectorImpl &Result) { + unsigned NumElts = Mask->getType()->getVectorNumElements(); + + if (ConstantDataSequential *CDS=dyn_cast(Mask)) { + for (unsigned i = 0; i != NumElts; ++i) + Result.push_back(CDS->getElementAsInteger(i)); + return; + } + for (unsigned i = 0; i != NumElts; ++i) { + Constant *C = Mask->getAggregateElement(i); + Result.push_back(isa(C) ? -1 : + cast(C)->getZExtValue()); + } } + //===----------------------------------------------------------------------===// // InsertValueInst Class //===----------------------------------------------------------------------===// @@ -1741,46 +1899,27 @@ BinaryOperator *BinaryOperator::CreateNUWNeg(Value *Op, const Twine &Name, BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); - return new BinaryOperator(Instruction::FSub, - zero, Op, + return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); - return new BinaryOperator(Instruction::FSub, - zero, Op, + return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertAtEnd); } BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, Instruction *InsertBefore) { - Constant *C; - if (VectorType *PTy = dyn_cast(Op->getType())) { - C = Constant::getAllOnesValue(PTy->getElementType()); - C = ConstantVector::get( - std::vector(PTy->getNumElements(), C)); - } else { - C = Constant::getAllOnesValue(Op->getType()); - } - + Constant *C = Constant::getAllOnesValue(Op->getType()); return new BinaryOperator(Instruction::Xor, Op, C, Op->getType(), Name, InsertBefore); } BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { - Constant *AllOnes; - if (VectorType *PTy = dyn_cast(Op->getType())) { - // Create a vector of all ones values. - Constant *Elt = Constant::getAllOnesValue(PTy->getElementType()); - AllOnes = ConstantVector::get( - std::vector(PTy->getNumElements(), Elt)); - } else { - AllOnes = Constant::getAllOnesValue(Op->getType()); - } - + Constant *AllOnes = Constant::getAllOnesValue(Op->getType()); return new BinaryOperator(Instruction::Xor, Op, AllOnes, Op->getType(), Name, InsertAtEnd); } @@ -1788,10 +1927,8 @@ BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, // isConstantAllOnes - Helper function for several functions below static inline bool isConstantAllOnes(const Value *V) { - if (const ConstantInt *CI = dyn_cast(V)) - return CI->isAllOnesValue(); - if (const ConstantVector *CV = dyn_cast(V)) - return CV->isAllOnesValue(); + if (const Constant *C = dyn_cast(V)) + return C->isAllOnesValue(); return false; } @@ -1887,10 +2024,29 @@ bool BinaryOperator::isExact() const { return cast(this)->isExact(); } +//===----------------------------------------------------------------------===// +// FPMathOperator Class +//===----------------------------------------------------------------------===// + +/// getFPAccuracy - Get the maximum error permitted by this operation in ULPs. +/// An accuracy of 0.0 means that the operation should be performed with the +/// default precision. +float FPMathOperator::getFPAccuracy() const { + const MDNode *MD = + cast(this)->getMetadata(LLVMContext::MD_fpmath); + if (!MD) + return 0.0; + ConstantFP *Accuracy = cast(MD->getOperand(0)); + return Accuracy->getValueAPF().convertToFloat(); +} + + //===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// +void CastInst::anchor() {} + // Just determine if this cast only deals with integral->integral conversion. bool CastInst::isIntegerCast() const { switch (getOpcode()) { @@ -1935,8 +2091,7 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode, Type *DestTy, Type *IntPtrTy) { switch (Opcode) { - default: - assert(!"Invalid CastOp"); + default: llvm_unreachable("Invalid CastOp"); case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: @@ -1973,8 +2128,7 @@ bool CastInst::isNoopCast(Type *IntPtrTy) const { /// If no such cast is permited, the function returns 0. unsigned CastInst::isEliminableCastPair( Instruction::CastOps firstOp, Instruction::CastOps secondOp, - Type *SrcTy, Type *MidTy, Type *DstTy, Type *IntPtrTy) -{ + Type *SrcTy, Type *MidTy, Type *DstTy, Type *IntPtrTy) { // Define the 144 possibilities for these two cast instructions. The values // in this matrix determine what to do in a given situation and select the // case in the switch below. The rows correspond to firstOp, the columns @@ -2027,12 +2181,16 @@ unsigned CastInst::isEliminableCastPair( }; // If either of the casts are a bitcast from scalar to vector, disallow the - // merging. - if ((firstOp == Instruction::BitCast && - isa(SrcTy) != isa(MidTy)) || - (secondOp == Instruction::BitCast && - isa(MidTy) != isa(DstTy))) - return 0; // Disallowed + // merging. However, bitcast of A->B->A are allowed. + bool isFirstBitcast = (firstOp == Instruction::BitCast); + bool isSecondBitcast = (secondOp == Instruction::BitCast); + bool chainedBitcast = (SrcTy == DstTy && isFirstBitcast && isSecondBitcast); + + // Check if any of the bitcasts convert scalars<->vectors. + if ((isFirstBitcast && isa(SrcTy) != isa(MidTy)) || + (isSecondBitcast && isa(MidTy) != isa(DstTy))) + // Unless we are bitcasing to the original type, disallow optimizations. + if (!chainedBitcast) return 0; int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin] [secondOp-Instruction::CastOpsBegin]; @@ -2126,13 +2284,10 @@ unsigned CastInst::isEliminableCastPair( case 99: // cast combination can't happen (error in input). This is for all cases // where the MidTy is not the same for the two cast instructions. - assert(!"Invalid Cast Combination"); - return 0; + llvm_unreachable("Invalid Cast Combination"); default: - assert(!"Error in CastResults table!!!"); - return 0; + llvm_unreachable("Error in CastResults table!!!"); } - return 0; } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, @@ -2152,10 +2307,8 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); case BitCast: return new BitCastInst (S, Ty, Name, InsertBefore); - default: - assert(!"Invalid opcode provided"); + default: llvm_unreachable("Invalid opcode provided"); } - return 0; } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, @@ -2175,10 +2328,8 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty, case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); case BitCast: return new BitCastInst (S, Ty, Name, InsertAtEnd); - default: - assert(!"Invalid opcode provided"); + default: llvm_unreachable("Invalid opcode provided"); } - return 0; } CastInst *CastInst::CreateZExtOrBitCast(Value *S, Type *Ty, @@ -2447,9 +2598,8 @@ CastInst::getCastOpcode( assert(DestBits == SrcBits && "Casting vector to floating point of different width"); return BitCast; // same size, no-op cast - } else { - llvm_unreachable("Casting pointer or non-first class to float"); } + llvm_unreachable("Casting pointer or non-first class to float"); } else if (DestTy->isVectorTy()) { assert(DestBits == SrcBits && "Illegal cast to vector (wrong type or size)"); @@ -2459,24 +2609,16 @@ CastInst::getCastOpcode( return BitCast; // ptr -> ptr } else if (SrcTy->isIntegerTy()) { return IntToPtr; // int -> ptr - } else { - assert(!"Casting pointer to other than pointer or int"); } + llvm_unreachable("Casting pointer to other than pointer or int"); } else if (DestTy->isX86_MMXTy()) { if (SrcTy->isVectorTy()) { assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); return BitCast; // 64-bit vector to MMX - } else { - assert(!"Illegal cast to X86_MMX"); } - } else { - assert(!"Casting to type that is not first-class"); + llvm_unreachable("Illegal cast to X86_MMX"); } - - // If we fall through to here we probably hit an assertion cast above - // and assertions are not turned on. Anything we return is an error, so - // BitCast is as good a choice as any. - return BitCast; + llvm_unreachable("Casting to type that is not first-class"); } //===----------------------------------------------------------------------===// @@ -2535,9 +2677,21 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) { return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() && SrcLength == DstLength; case Instruction::PtrToInt: - return SrcTy->isPointerTy() && DstTy->isIntegerTy(); + if (isa(SrcTy) != isa(DstTy)) + return false; + if (VectorType *VT = dyn_cast(SrcTy)) + if (VT->getNumElements() != cast(DstTy)->getNumElements()) + return false; + return SrcTy->getScalarType()->isPointerTy() && + DstTy->getScalarType()->isIntegerTy(); case Instruction::IntToPtr: - return SrcTy->isIntegerTy() && DstTy->isPointerTy(); + if (isa(SrcTy) != isa(DstTy)) + return false; + if (VectorType *VT = dyn_cast(SrcTy)) + if (VT->getNumElements() != cast(DstTy)->getNumElements()) + return false; + return SrcTy->getScalarType()->isIntegerTy() && + DstTy->getScalarType()->isPointerTy(); case Instruction::BitCast: // BitCast implies a no-op cast of type only. No bits change. // However, you can't cast pointers to anything but pointers. @@ -2698,7 +2852,7 @@ BitCastInst::BitCastInst( // CmpInst Classes //===----------------------------------------------------------------------===// -void CmpInst::Anchor() const {} +void CmpInst::anchor() {} CmpInst::CmpInst(Type *ty, OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, const Twine &Name, @@ -2780,7 +2934,7 @@ bool CmpInst::isEquality() const { CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) { switch (pred) { - default: assert(!"Unknown cmp predicate!"); + default: llvm_unreachable("Unknown cmp predicate!"); case ICMP_EQ: return ICMP_NE; case ICMP_NE: return ICMP_EQ; case ICMP_UGT: return ICMP_ULE; @@ -2813,7 +2967,7 @@ CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) { ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) { switch (pred) { - default: assert(! "Unknown icmp predicate!"); + default: llvm_unreachable("Unknown icmp predicate!"); case ICMP_EQ: case ICMP_NE: case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE: return pred; @@ -2826,7 +2980,7 @@ ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) { ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) { switch (pred) { - default: assert(! "Unknown icmp predicate!"); + default: llvm_unreachable("Unknown icmp predicate!"); case ICMP_EQ: case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE: return pred; @@ -2902,7 +3056,7 @@ ICmpInst::makeConstantRange(Predicate pred, const APInt &C) { CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { switch (pred) { - default: assert(!"Unknown cmp predicate!"); + default: llvm_unreachable("Unknown cmp predicate!"); case ICMP_EQ: case ICMP_NE: return pred; case ICMP_SGT: return ICMP_SLT; @@ -3026,6 +3180,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI) OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } + TheSubsets = SI.TheSubsets; SubclassOptionalData = SI.SubclassOptionalData; } @@ -3037,36 +3192,60 @@ SwitchInst::~SwitchInst() { /// addCase - Add an entry to the switch instruction... /// void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) { + IntegersSubsetToBB Mapping; + + // FIXME: Currently we work with ConstantInt based cases. + // So inititalize IntItem container directly from ConstantInt. + Mapping.add(IntItem::fromConstantInt(OnVal)); + IntegersSubset CaseRanges = Mapping.getCase(); + addCase(CaseRanges, Dest); +} + +void SwitchInst::addCase(IntegersSubset& OnVal, BasicBlock *Dest) { + unsigned NewCaseIdx = getNumCases(); unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) growOperands(); // Get more space! // Initialize some new operands. assert(OpNo+1 < ReservedSpace && "Growing didn't work!"); NumOperands = OpNo+2; - OperandList[OpNo] = OnVal; - OperandList[OpNo+1] = Dest; + + SubsetsIt TheSubsetsIt = TheSubsets.insert(TheSubsets.end(), OnVal); + + CaseIt Case(this, NewCaseIdx, TheSubsetsIt); + Case.updateCaseValueOperand(OnVal); + Case.setSuccessor(Dest); } -/// removeCase - This method removes the specified successor from the switch -/// instruction. Note that this cannot be used to remove the default -/// destination (successor #0). -/// -void SwitchInst::removeCase(unsigned idx) { - assert(idx != 0 && "Cannot remove the default case!"); - assert(idx*2 < getNumOperands() && "Successor index out of range!!!"); +/// removeCase - This method removes the specified case and its successor +/// from the switch instruction. +void SwitchInst::removeCase(CaseIt& i) { + unsigned idx = i.getCaseIndex(); + + assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!"); unsigned NumOps = getNumOperands(); Use *OL = OperandList; // Overwrite this case with the end of the list. - if ((idx + 1) * 2 != NumOps) { - OL[idx * 2] = OL[NumOps - 2]; - OL[idx * 2 + 1] = OL[NumOps - 1]; + if (2 + (idx + 1) * 2 != NumOps) { + OL[2 + idx * 2] = OL[NumOps - 2]; + OL[2 + idx * 2 + 1] = OL[NumOps - 1]; } // Nuke the last value. OL[NumOps-2].set(0); OL[NumOps-2+1].set(0); + + // Do the same with TheCases collection: + if (i.SubsetIt != --TheSubsets.end()) { + *i.SubsetIt = TheSubsets.back(); + TheSubsets.pop_back(); + } else { + TheSubsets.pop_back(); + i.SubsetIt = TheSubsets.end(); + } + NumOperands = NumOps-2; } @@ -3233,14 +3412,14 @@ AllocaInst *AllocaInst::clone_impl() const { } LoadInst *LoadInst::clone_impl() const { - return new LoadInst(getOperand(0), - Twine(), isVolatile(), - getAlignment()); + return new LoadInst(getOperand(0), Twine(), isVolatile(), + getAlignment(), getOrdering(), getSynchScope()); } StoreInst *StoreInst::clone_impl() const { - return new StoreInst(getOperand(0), getOperand(1), - isVolatile(), getAlignment()); + return new StoreInst(getOperand(0), getOperand(1), isVolatile(), + getAlignment(), getOrdering(), getSynchScope()); + } AtomicCmpXchgInst *AtomicCmpXchgInst::clone_impl() const { @@ -3328,15 +3507,11 @@ ExtractElementInst *ExtractElementInst::clone_impl() const { } InsertElementInst *InsertElementInst::clone_impl() const { - return InsertElementInst::Create(getOperand(0), - getOperand(1), - getOperand(2)); + return InsertElementInst::Create(getOperand(0), getOperand(1), getOperand(2)); } ShuffleVectorInst *ShuffleVectorInst::clone_impl() const { - return new ShuffleVectorInst(getOperand(0), - getOperand(1), - getOperand(2)); + return new ShuffleVectorInst(getOperand(0), getOperand(1), getOperand(2)); } PHINode *PHINode::clone_impl() const { @@ -3372,11 +3547,6 @@ ResumeInst *ResumeInst::clone_impl() const { return new(1) ResumeInst(*this); } -UnwindInst *UnwindInst::clone_impl() const { - LLVMContext &Context = getContext(); - return new UnwindInst(Context); -} - UnreachableInst *UnreachableInst::clone_impl() const { LLVMContext &Context = getContext(); return new UnreachableInst(Context);