diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 1877eec38f2..924fec26d27 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -220,26 +220,62 @@ namespace llvm { } }; - - /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. + /// MemSetInst - This class wraps the llvm.memset intrinsic. /// - struct MemCpyInst : public MemIntrinsic { + struct MemSetInst : public MemIntrinsic { + /// get* - Return the arguments to the instruction. + /// + Value *getValue() const { return const_cast(getOperand(2)); } + + void setValue(Value *Val) { + assert(getValue()->getType() == Val->getType() && + "setSource called with pointer of wrong type!"); + setOperand(2, Val); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MemSetInst *) { return true; } + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::memset; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + + /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics. + /// + struct MemTransferInst : public MemIntrinsic { /// get* - Return the arguments to the instruction. /// Value *getRawSource() const { return const_cast(getOperand(2)); } - + /// getSource - This is just like getRawSource, but it strips off any cast /// instructions that feed it, giving the original input. The returned /// value is guaranteed to be a pointer. Value *getSource() const { return getRawSource()->stripPointerCasts(); } - - + void setSource(Value *Ptr) { assert(getRawSource()->getType() == Ptr->getType() && "setSource called with pointer of wrong type!"); setOperand(2, Ptr); } - + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const MemTransferInst *) { return true; } + static inline bool classof(const IntrinsicInst *I) { + return I->getIntrinsicID() == Intrinsic::memcpy || + I->getIntrinsicID() == Intrinsic::memmove; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } + }; + + + /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. + /// + struct MemCpyInst : public MemTransferInst { // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemCpyInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { @@ -252,22 +288,7 @@ namespace llvm { /// MemMoveInst - This class wraps the llvm.memmove intrinsic. /// - struct MemMoveInst : public MemIntrinsic { - /// get* - Return the arguments to the instruction. - /// - Value *getRawSource() const { return const_cast(getOperand(2)); } - - /// getSource - This is just like getRawSource, but it strips off any cast - /// instructions that feed it, giving the original input. The returned - /// value is guaranteed to be a pointer. - Value *getSource() const { return getRawSource()->stripPointerCasts(); } - - void setSource(Value *Ptr) { - assert(getRawSource()->getType() == Ptr->getType() && - "setSource called with pointer of wrong type!"); - setOperand(2, Ptr); - } - + struct MemMoveInst : public MemTransferInst { // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const MemMoveInst *) { return true; } static inline bool classof(const IntrinsicInst *I) { @@ -278,29 +299,6 @@ namespace llvm { } }; - /// MemSetInst - This class wraps the llvm.memset intrinsic. - /// - struct MemSetInst : public MemIntrinsic { - /// get* - Return the arguments to the instruction. - /// - Value *getValue() const { return const_cast(getOperand(2)); } - - void setValue(Value *Val) { - assert(getValue()->getType() == Val->getType() && - "setSource called with pointer of wrong type!"); - setOperand(2, Val); - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemSetInst *) { return true; } - static inline bool classof(const IntrinsicInst *I) { - return I->getIntrinsicID() == Intrinsic::memset; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } - }; - /// EHSelectorInst - This represents the llvm.eh.selector instruction. /// struct EHSelectorInst : public IntrinsicInst { diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 86f3256a6ee..09722d9c492 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -9464,7 +9464,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // If we can determine a pointer alignment that is bigger than currently // set, update the alignment. - if (isa(MI) || isa(MI)) { + if (isa(MI)) { if (Instruction *I = SimplifyMemTransfer(MI)) return I; } else if (MemSetInst *MSI = dyn_cast(MI)) { diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index f45d4a4e8e6..351ecea1dd6 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -605,7 +605,7 @@ void SROA::isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocationInst *AI, return MarkUnsafe(Info); // We only know about memcpy/memset/memmove. - if (!isa(MI) && !isa(MI) && !isa(MI)) + if (!isa(MI)) return MarkUnsafe(Info); // Otherwise, we can transform it. Determine whether this is a memcpy/set @@ -726,19 +726,12 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, // memset, this Value* stays null. Value *OtherPtr = 0; unsigned MemAlignment = MI->getAlignment()->getZExtValue(); - if (MemCpyInst *MCI = dyn_cast(MI)) { - if (BCInst == MCI->getRawDest()) - OtherPtr = MCI->getRawSource(); + if (MemTransferInst *MTI = dyn_cast(MI)) { // memmove/memcopy + if (BCInst == MTI->getRawDest()) + OtherPtr = MTI->getRawSource(); else { - assert(BCInst == MCI->getRawSource()); - OtherPtr = MCI->getRawDest(); - } - } else if (MemMoveInst *MMI = dyn_cast(MI)) { - if (BCInst == MMI->getRawDest()) - OtherPtr = MMI->getRawSource(); - else { - assert(BCInst == MMI->getRawSource()); - OtherPtr = MMI->getRawDest(); + assert(BCInst == MTI->getRawSource()); + OtherPtr = MTI->getRawDest(); } } @@ -805,7 +798,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, // If we got down to a scalar, insert a load or store as appropriate. if (EltTy->isSingleValueType()) { - if (isa(MI) || isa(MI)) { + if (isa(MI)) { if (SROADest) { // From Other to Alloca. Value *Elt = new LoadInst(OtherElt, "tmp", false, OtherEltAlign, MI); @@ -875,7 +868,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *BCInst, unsigned EltSize = TD->getTypePaddedSize(EltTy); // Finally, insert the meminst for this element. - if (isa(MI) || isa(MI)) { + if (isa(MI)) { Value *Ops[] = { SROADest ? EltPtr : OtherElt, // Dest ptr SROADest ? OtherElt : EltPtr, // Src ptr @@ -1350,17 +1343,18 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy, IsNotTrivial = true; continue; } - + // If this is a constant sized memset of a constant value (e.g. 0) we can // handle it. - if (isa(User) && - // Store of constant value. - isa(User->getOperand(2)) && - // Store with constant size. - isa(User->getOperand(3))) { - VecTy = Type::VoidTy; - IsNotTrivial = true; - continue; + if (MemSetInst *MSI = dyn_cast(User)) { + // Store of constant value and constant size. + if (isa(MSI->getValue()) && + isa(MSI->getLength())) { + // FIXME (!): Why reset VecTy? + VecTy = Type::VoidTy; + IsNotTrivial = true; + continue; + } } // Ignore dbg intrinsic. @@ -1731,7 +1725,7 @@ static bool isOnlyCopiedFromConstantGlobal(Value *V, Instruction *&TheCopy, // If this is isn't our memcpy/memmove, reject it as something we can't // handle. - if (!isa(*UI) && !isa(*UI)) + if (!isa(*UI)) return false; // If we already have seen a copy, reject the second one.