X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FInstructions.cpp;h=1b5cfb150137d29bd97dbc8614eca8e4674736f3;hb=b5bd026a756d8650f2a94607c9b1dc34cf1c024a;hp=bedf74cd9ccfc0b006bc3bd0a3e4ea39a1f185a7;hpb=e2afdedec5f876b88384e21a3e18f48444989346;p=oota-llvm.git diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index bedf74cd9cc..1b5cfb15013 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -25,94 +25,65 @@ using namespace llvm; // CallSite Class //===----------------------------------------------------------------------===// +#define CALLSITE_DELEGATE_GETTER(METHOD) \ + Instruction *II(getInstruction()); \ + return isCall() \ + ? cast(II)->METHOD \ + : cast(II)->METHOD + +#define CALLSITE_DELEGATE_SETTER(METHOD) \ + Instruction *II(getInstruction()); \ + if (isCall()) \ + cast(II)->METHOD; \ + else \ + cast(II)->METHOD + CallSite::CallSite(Instruction *C) { assert((isa(C) || isa(C)) && "Not a call!"); - I = C; + I.setPointer(C); + I.setInt(isa(C)); } unsigned CallSite::getCallingConv() const { - if (CallInst *CI = dyn_cast(I)) - return CI->getCallingConv(); - else - return cast(I)->getCallingConv(); + CALLSITE_DELEGATE_GETTER(getCallingConv()); } void CallSite::setCallingConv(unsigned CC) { - if (CallInst *CI = dyn_cast(I)) - CI->setCallingConv(CC); - else - cast(I)->setCallingConv(CC); + CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); } -const PAListPtr &CallSite::getParamAttrs() const { - if (CallInst *CI = dyn_cast(I)) - return CI->getParamAttrs(); - else - return cast(I)->getParamAttrs(); +const AttrListPtr &CallSite::getAttributes() const { + CALLSITE_DELEGATE_GETTER(getAttributes()); } -void CallSite::setParamAttrs(const PAListPtr &PAL) { - if (CallInst *CI = dyn_cast(I)) - CI->setParamAttrs(PAL); - else - cast(I)->setParamAttrs(PAL); +void CallSite::setAttributes(const AttrListPtr &PAL) { + CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); } -bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - if (CallInst *CI = dyn_cast(I)) - return CI->paramHasAttr(i, attr); - else - return cast(I)->paramHasAttr(i, attr); +bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const { + CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr)); } uint16_t CallSite::getParamAlignment(uint16_t i) const { - if (CallInst *CI = dyn_cast(I)) - return CI->getParamAlignment(i); - else - return cast(I)->getParamAlignment(i); + CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); } - bool CallSite::doesNotAccessMemory() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotAccessMemory(); - else - return cast(I)->doesNotAccessMemory(); + CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); } void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotAccessMemory(doesNotAccessMemory); - else - cast(I)->setDoesNotAccessMemory(doesNotAccessMemory); + CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory)); } bool CallSite::onlyReadsMemory() const { - if (CallInst *CI = dyn_cast(I)) - return CI->onlyReadsMemory(); - else - return cast(I)->onlyReadsMemory(); + CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); } void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) { - if (CallInst *CI = dyn_cast(I)) - CI->setOnlyReadsMemory(onlyReadsMemory); - else - cast(I)->setOnlyReadsMemory(onlyReadsMemory); + CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory)); } bool CallSite::doesNotReturn() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotReturn(); - else - return cast(I)->doesNotReturn(); + CALLSITE_DELEGATE_GETTER(doesNotReturn()); } void CallSite::setDoesNotReturn(bool doesNotReturn) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotReturn(doesNotReturn); - else - cast(I)->setDoesNotReturn(doesNotReturn); + CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn)); } bool CallSite::doesNotThrow() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotThrow(); - else - return cast(I)->doesNotThrow(); + CALLSITE_DELEGATE_GETTER(doesNotThrow()); } void CallSite::setDoesNotThrow(bool doesNotThrow) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotThrow(doesNotThrow); - else - cast(I)->setDoesNotThrow(doesNotThrow); + CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow)); } bool CallSite::hasArgument(const Value *Arg) const { @@ -122,6 +93,9 @@ bool CallSite::hasArgument(const Value *Arg) const { return false; } +#undef CALLSITE_DELEGATE_GETTER +#undef CALLSITE_DELEGATE_SETTER + //===----------------------------------------------------------------------===// // TerminatorInst Class //===----------------------------------------------------------------------===// @@ -138,6 +112,33 @@ TerminatorInst::~TerminatorInst() { UnaryInstruction::~UnaryInstruction() { } +//===----------------------------------------------------------------------===// +// SelectInst Class +//===----------------------------------------------------------------------===// + +/// areInvalidOperands - Return a string if the specified operands are invalid +/// for a select operation, otherwise return null. +const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { + if (Op1->getType() != Op2->getType()) + return "both values to select must have same type"; + + if (const VectorType *VT = dyn_cast(Op0->getType())) { + // Vector select. + if (VT->getElementType() != Type::Int1Ty) + return "vector select condition element type must be i1"; + const VectorType *ET = dyn_cast(Op1->getType()); + if (ET == 0) + return "selected values for vector select must be vectors"; + if (ET->getNumElements() != VT->getNumElements()) + return "vector select requires selected vectors to have " + "the same vector length as select condition"; + } else if (Op0->getType() != Type::Int1Ty) { + return "select condition must be i1 or "; + } + return 0; +} + + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// @@ -394,7 +395,7 @@ CallInst::CallInst(const CallInst &CI) : Instruction(CI.getType(), Instruction::Call, OperandTraits::op_end(this) - CI.getNumOperands(), CI.getNumOperands()) { - setParamAttrs(CI.getParamAttrs()); + setAttributes(CI.getAttributes()); SubclassData = CI.SubclassData; Use *OL = OperandList; Use *InOL = CI.OperandList; @@ -402,20 +403,20 @@ CallInst::CallInst(const CallInst &CI) OL[i] = InOL[i]; } -void CallInst::addParamAttr(unsigned i, ParameterAttributes attr) { - PAListPtr PAL = getParamAttrs(); +void CallInst::addAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.addAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } -void CallInst::removeParamAttr(unsigned i, ParameterAttributes attr) { - PAListPtr PAL = getParamAttrs(); +void CallInst::removeAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.removeAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } -bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const { - if (ParamAttrs.paramHasAttr(i, attr)) +bool CallInst::paramHasAttr(unsigned i, Attributes attr) const { + if (AttributeList.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); @@ -456,7 +457,7 @@ InvokeInst::InvokeInst(const InvokeInst &II) OperandTraits::op_end(this) - II.getNumOperands(), II.getNumOperands()) { - setParamAttrs(II.getParamAttrs()); + setAttributes(II.getAttributes()); SubclassData = II.SubclassData; Use *OL = OperandList, *InOL = II.OperandList; for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i) @@ -473,24 +474,24 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } -bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const { - if (ParamAttrs.paramHasAttr(i, attr)) +bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const { + if (AttributeList.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); return false; } -void InvokeInst::addParamAttr(unsigned i, ParameterAttributes attr) { - PAListPtr PAL = getParamAttrs(); +void InvokeInst::addAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.addAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } -void InvokeInst::removeParamAttr(unsigned i, ParameterAttributes attr) { - PAListPtr PAL = getParamAttrs(); +void InvokeInst::removeAttribute(unsigned i, Attributes attr) { + AttrListPtr PAL = getAttributes(); PAL = PAL.removeAttr(i, attr); - setParamAttrs(PAL); + setAttributes(PAL); } @@ -732,6 +733,18 @@ AllocaInst::AllocaInst(const AllocaInst &AI) Instruction::Alloca, AI.getAlignment()) { } +/// isStaticAlloca - Return true if this alloca is in the entry block of the +/// function and is a constant size. If so, the code generator will fold it +/// into the prolog/epilog code, so it is basically free. +bool AllocaInst::isStaticAlloca() const { + // Must be constant size. + if (!isa(getArraySize())) return false; + + // Must be in the entry block. + const BasicBlock *Parent = getParent(); + return Parent == &Parent->getParent()->front(); +} + MallocInst::MallocInst(const MallocInst &MI) : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0), Instruction::Malloc, MI.getAlignment()) { @@ -874,6 +887,7 @@ void LoadInst::setAlignment(unsigned Align) { //===----------------------------------------------------------------------===// void StoreInst::AssertOK() { + assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!"); assert(isa(getOperand(1)->getType()) && "Ptr must have pointer type!"); assert(getOperand(0)->getType() == @@ -1286,10 +1300,12 @@ ShuffleVectorInst::ShuffleVectorInst(const ShuffleVectorInst &SV) ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const std::string &Name, Instruction *InsertBefore) - : Instruction(V1->getType(), ShuffleVector, - OperandTraits::op_begin(this), - OperandTraits::operands(this), - InsertBefore) { +: Instruction(VectorType::get(cast(V1->getType())->getElementType(), + cast(Mask->getType())->getNumElements()), + ShuffleVector, + OperandTraits::op_begin(this), + OperandTraits::operands(this), + InsertBefore) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); Op<0>() = V1; @@ -1299,7 +1315,7 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, } ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, - const std::string &Name, + const std::string &Name, BasicBlock *InsertAtEnd) : Instruction(V1->getType(), ShuffleVector, OperandTraits::op_begin(this), @@ -1314,17 +1330,14 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, setName(Name); } -bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, +bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, const Value *Mask) { - if (!isa(V1->getType()) || - V1->getType() != V2->getType()) + if (!isa(V1->getType()) || V1->getType() != V2->getType()) return false; const VectorType *MaskTy = dyn_cast(Mask->getType()); if (!isa(Mask) || MaskTy == 0 || - MaskTy->getElementType() != Type::Int32Ty || - MaskTy->getNumElements() != - cast(V1->getType())->getNumElements()) + MaskTy->getElementType() != Type::Int32Ty) return false; return true; } @@ -1403,7 +1416,7 @@ InsertValueInst::InsertValueInst(Value *Agg, //===----------------------------------------------------------------------===// void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx, - const std::string &Name) { + const std::string &Name) { assert(NumOperands == 1 && "NumOperands not initialized?"); Indices.insert(Indices.end(), Idx, Idx + NumIdx); @@ -1535,8 +1548,10 @@ void BinaryOperator::init(BinaryOps iType) { case AShr: assert(getType() == LHS->getType() && "Shift operation should return same type as operands!"); - assert(getType()->isInteger() && - "Shift operation requires integer operands"); + assert((getType()->isInteger() || + (isa(getType()) && + cast(getType())->getElementType()->isInteger())) && + "Tried to create a shift operation on a non-integral type!"); break; case And: case Or: case Xor: @@ -2169,6 +2184,7 @@ CastInst::getCastOpcode( } else if (const VectorType *PTy = dyn_cast(SrcTy)) { assert(DestBits == PTy->getBitWidth() && "Casting vector to integer of different width"); + PTy = NULL; return BitCast; // Same size, no-op cast } else { assert(isa(SrcTy) && @@ -2192,7 +2208,8 @@ CastInst::getCastOpcode( } else if (const VectorType *PTy = dyn_cast(SrcTy)) { assert(DestBits == PTy->getBitWidth() && "Casting vector to floating point of different width"); - return BitCast; // same size, no-op cast + PTy = NULL; + return BitCast; // same size, no-op cast } else { assert(0 && "Casting pointer or non-first class to float"); } @@ -2200,6 +2217,7 @@ CastInst::getCastOpcode( if (const VectorType *SrcPTy = dyn_cast(SrcTy)) { assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() && "Casting vector to vector of different widths"); + SrcPTy = NULL; return BitCast; // vector -> vector } else if (DestPTy->getBitWidth() == SrcBits) { return BitCast; // float/int -> vector @@ -2248,37 +2266,42 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { switch (op) { default: return false; // This is an input error case Instruction::Trunc: - return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize > DstBitSize; + return SrcTy->isIntOrIntVector() && + DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize; case Instruction::ZExt: - return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVector() && + DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize; case Instruction::SExt: - return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize; + return SrcTy->isIntOrIntVector() && + DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize; case Instruction::FPTrunc: - return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && - SrcBitSize > DstBitSize; + return SrcTy->isFPOrFPVector() && + DstTy->isFPOrFPVector() && + SrcBitSize > DstBitSize; case Instruction::FPExt: - return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && - SrcBitSize < DstBitSize; + return SrcTy->isFPOrFPVector() && + DstTy->isFPOrFPVector() && + SrcBitSize < DstBitSize; case Instruction::UIToFP: case Instruction::SIToFP: if (const VectorType *SVTy = dyn_cast(SrcTy)) { if (const VectorType *DVTy = dyn_cast(DstTy)) { - return SVTy->getElementType()->isInteger() && - DVTy->getElementType()->isFloatingPoint() && + return SVTy->getElementType()->isIntOrIntVector() && + DVTy->getElementType()->isFPOrFPVector() && SVTy->getNumElements() == DVTy->getNumElements(); } } - return SrcTy->isInteger() && DstTy->isFloatingPoint(); + return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector(); case Instruction::FPToUI: case Instruction::FPToSI: if (const VectorType *SVTy = dyn_cast(SrcTy)) { if (const VectorType *DVTy = dyn_cast(DstTy)) { - return SVTy->getElementType()->isFloatingPoint() && - DVTy->getElementType()->isInteger() && + return SVTy->getElementType()->isFPOrFPVector() && + DVTy->getElementType()->isIntOrIntVector() && SVTy->getNumElements() == DVTy->getNumElements(); } } - return SrcTy->isFloatingPoint() && DstTy->isInteger(); + return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector(); case Instruction::PtrToInt: return isa(SrcTy) && DstTy->isInteger(); case Instruction::IntToPtr: