[llvm] r316950 - Create instruction classes for identifying any atomicity of memory intrinsic. (NFC)
Daniel Neilson via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 30 12:51:48 PDT 2017
Author: dneilson
Date: Mon Oct 30 12:51:48 2017
New Revision: 316950
URL: http://llvm.org/viewvc/llvm-project?rev=316950&view=rev
Log:
Create instruction classes for identifying any atomicity of memory intrinsic. (NFC)
Summary:
For reference, see: http://lists.llvm.org/pipermail/llvm-dev/2017-August/116589.html
This patch fleshes out the instruction class hierarchy with respect to atomic and
non-atomic memory intrinsics. With this change, the relevant part of the class
hierarchy becomes:
IntrinsicInst
-> MemIntrinsicBase (methods-only class)
-> MemIntrinsic (non-atomic intrinsics)
-> MemSetInst
-> MemTransferInst
-> MemCpyInst
-> MemMoveInst
-> AtomicMemIntrinsic (atomic intrinsics)
-> AtomicMemSetInst
-> AtomicMemTransferInst
-> AtomicMemCpyInst
-> AtomicMemMoveInst
-> AnyMemIntrinsic (both atomicities)
-> AnyMemSetInst
-> AnyMemTransferInst
-> AnyMemCpyInst
-> AnyMemMoveInst
This involves some class renaming:
ElementUnorderedAtomicMemCpyInst -> AtomicMemCpyInst
ElementUnorderedAtomicMemMoveInst -> AtomicMemMoveInst
ElementUnorderedAtomicMemSetInst -> AtomicMemSetInst
A script for doing this renaming in downstream trees is included below.
An example of where the Any* classes should be used in LLVM is when reasoning
about the effects of an instruction (ex: aliasing).
---
Script for renaming AtomicMem* classes:
PREFIXES="[<,([:space:]]"
CLASSES="MemIntrinsic|MemTransferInst|MemSetInst|MemMoveInst|MemCpyInst"
SUFFIXES="[;)>,[:space:]]"
REGEX="(${PREFIXES})ElementUnorderedAtomic(${CLASSES})(${SUFFIXES})"
REGEX2="visitElementUnorderedAtomic(${CLASSES})"
FILES=$( grep -E "(${REGEX}|${REGEX2})" -r . | tr ':' ' ' | awk '{print $1}' | sort | uniq )
SED_SCRIPT="s~${REGEX}~\1Atomic\2\3~g"
SED_SCRIPT2="s~${REGEX2}~visitAtomic\1~g"
for f in $FILES; do
echo "Processing: $f"
sed -i ".bak" -E "${SED_SCRIPT};${SED_SCRIPT2};${EA_SED_SCRIPT};${EA_SED_SCRIPT2}" $f
done
Reviewers: sanjoy, deadalnix, apilipenko, anna, skatkov, mkazantsev
Reviewed By: sanjoy
Subscribers: hfinkel, jholewinski, arsenm, sdardis, nhaehnle, JDevlieghere, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D38419
Modified:
llvm/trunk/include/llvm/IR/IntrinsicInst.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
Modified: llvm/trunk/include/llvm/IR/IntrinsicInst.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=316950&r1=316949&r2=316950&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/IntrinsicInst.h (original)
+++ llvm/trunk/include/llvm/IR/IntrinsicInst.h Mon Oct 30 12:51:48 2017
@@ -213,12 +213,13 @@ namespace llvm {
}
};
- /// This class represents atomic memcpy intrinsic
- /// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
- /// C&P of all methods from that hierarchy
- class ElementUnorderedAtomicMemCpyInst : public IntrinsicInst {
+ /// Common base class for all memory intrinsics. Simply provides
+ /// common methods.
+ /// Written as CRTP to avoid a common base class amongst the
+ /// three atomicity hierarchies.
+ template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
private:
- enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+ enum { ARG_DEST = 0, ARG_LENGTH = 2 };
public:
Value *getRawDest() const {
@@ -227,51 +228,21 @@ namespace llvm {
const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
- /// Return the arguments to the instruction.
- Value *getRawSource() const {
- return const_cast<Value *>(getArgOperand(ARG_SOURCE));
- }
- const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
- Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
-
Value *getLength() const {
return const_cast<Value *>(getArgOperand(ARG_LENGTH));
}
const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
- bool isVolatile() const { return false; }
-
- Value *getRawElementSizeInBytes() const {
- return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
- }
-
- ConstantInt *getElementSizeInBytesCst() const {
- return cast<ConstantInt>(getRawElementSizeInBytes());
- }
-
- uint32_t getElementSizeInBytes() const {
- return getElementSizeInBytesCst()->getZExtValue();
- }
-
/// This is just like getRawDest, but it strips off any cast
- /// instructions that feed it, giving the original input. The returned
- /// value is guaranteed to be a pointer.
+ /// instructions (including addrspacecast) that feed it, giving the
+ /// original input. The returned value is guaranteed to be a pointer.
Value *getDest() const { return getRawDest()->stripPointerCasts(); }
- /// 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(); }
-
unsigned getDestAddressSpace() const {
return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
}
- unsigned getSourceAddressSpace() const {
- return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
- }
-
/// Set the specified arguments of the instruction.
void setDest(Value *Ptr) {
assert(getRawDest()->getType() == Ptr->getType() &&
@@ -279,58 +250,20 @@ namespace llvm {
setArgOperand(ARG_DEST, Ptr);
}
- void setSource(Value *Ptr) {
- assert(getRawSource()->getType() == Ptr->getType() &&
- "setSource called with pointer of wrong type!");
- setArgOperand(ARG_SOURCE, Ptr);
- }
-
void setLength(Value *L) {
assert(getLength()->getType() == L->getType() &&
"setLength called with value of wrong type!");
setArgOperand(ARG_LENGTH, L);
}
-
- void setElementSizeInBytes(Constant *V) {
- assert(V->getType() == Type::getInt8Ty(getContext()) &&
- "setElementSizeInBytes called with value of wrong type!");
- setArgOperand(ARG_ELEMENTSIZE, V);
- }
-
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
};
- class ElementUnorderedAtomicMemMoveInst : public IntrinsicInst {
+ // The common base class for the atomic memset/memmove/memcpy intrinsics
+ // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
+ class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
private:
- enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+ enum { ARG_ELEMENTSIZE = 3 };
public:
- Value *getRawDest() const {
- return const_cast<Value *>(getArgOperand(ARG_DEST));
- }
- const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
- Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
-
- /// Return the arguments to the instruction.
- Value *getRawSource() const {
- return const_cast<Value *>(getArgOperand(ARG_SOURCE));
- }
- const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
- Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
-
- Value *getLength() const {
- return const_cast<Value *>(getArgOperand(ARG_LENGTH));
- }
- const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
- Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
-
- bool isVolatile() const { return false; }
-
Value *getRawElementSizeInBytes() const {
return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
}
@@ -343,150 +276,129 @@ namespace llvm {
return getElementSizeInBytesCst()->getZExtValue();
}
- /// This is just like getRawDest, but it strips off any cast
- /// instructions that feed it, giving the original input. The returned
- /// value is guaranteed to be a pointer.
- Value *getDest() const { return getRawDest()->stripPointerCasts(); }
-
- /// 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(); }
-
- unsigned getDestAddressSpace() const {
- return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
- }
-
- unsigned getSourceAddressSpace() const {
- return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
- }
-
- /// Set the specified arguments of the instruction.
- void setDest(Value *Ptr) {
- assert(getRawDest()->getType() == Ptr->getType() &&
- "setDest called with pointer of wrong type!");
- setArgOperand(ARG_DEST, Ptr);
- }
-
- void setSource(Value *Ptr) {
- assert(getRawSource()->getType() == Ptr->getType() &&
- "setSource called with pointer of wrong type!");
- setArgOperand(ARG_SOURCE, Ptr);
- }
-
- void setLength(Value *L) {
- assert(getLength()->getType() == L->getType() &&
- "setLength called with value of wrong type!");
- setArgOperand(ARG_LENGTH, L);
- }
-
void setElementSizeInBytes(Constant *V) {
assert(V->getType() == Type::getInt8Ty(getContext()) &&
"setElementSizeInBytes called with value of wrong type!");
setArgOperand(ARG_ELEMENTSIZE, V);
}
- static inline bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This class represents atomic memset intrinsic
- /// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
- /// C&P of all methods from that hierarchy
- class ElementUnorderedAtomicMemSetInst : public IntrinsicInst {
+ // i.e. llvm.element.unordered.atomic.memset
+ class AtomicMemSetInst : public AtomicMemIntrinsic {
private:
- enum { ARG_DEST = 0, ARG_VALUE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+ enum { ARG_VALUE = 1 };
public:
- Value *getRawDest() const {
- return const_cast<Value *>(getArgOperand(ARG_DEST));
+ Value *getValue() const {
+ return const_cast<Value *>(getArgOperand(ARG_VALUE));
}
- const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
- Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
-
- Value *getValue() const { return const_cast<Value*>(getArgOperand(ARG_VALUE)); }
const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
- Value *getLength() const {
- return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setValue called with value of wrong type!");
+ setArgOperand(ARG_VALUE, Val);
}
- const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
- Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
-
- bool isVolatile() const { return false; }
- Value *getRawElementSizeInBytes() const {
- return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
}
-
- ConstantInt *getElementSizeInBytesCst() const {
- return cast<ConstantInt>(getRawElementSizeInBytes());
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
+ };
- uint32_t getElementSizeInBytes() const {
- return getElementSizeInBytesCst()->getZExtValue();
+ // This class wraps the atomic memcpy/memmove intrinsics
+ // i.e. llvm.element.unordered.atomic.memcpy/memmove
+ class AtomicMemTransferInst : public AtomicMemIntrinsic {
+ private:
+ enum { ARG_SOURCE = 1 };
+
+ public:
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(getArgOperand(ARG_SOURCE));
}
+ const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
+ Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
- /// This is just like getRawDest, but it strips off any cast
+ /// 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 *getDest() const { return getRawDest()->stripPointerCasts(); }
+ Value *getSource() const { return getRawSource()->stripPointerCasts(); }
- unsigned getDestAddressSpace() const {
- return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
}
- /// Set the specified arguments of the instruction.
- void setDest(Value *Ptr) {
- assert(getRawDest()->getType() == Ptr->getType() &&
- "setDest called with pointer of wrong type!");
- setArgOperand(ARG_DEST, Ptr);
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(ARG_SOURCE, Ptr);
}
- void setValue(Value *Val) {
- assert(getValue()->getType() == Val->getType() &&
- "setValue called with value of wrong type!");
- setArgOperand(ARG_VALUE, Val);
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
}
-
- void setLength(Value *L) {
- assert(getLength()->getType() == L->getType() &&
- "setLength called with value of wrong type!");
- setArgOperand(ARG_LENGTH, L);
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
+ };
- void setElementSizeInBytes(Constant *V) {
- assert(V->getType() == Type::getInt8Ty(getContext()) &&
- "setElementSizeInBytes called with value of wrong type!");
- setArgOperand(ARG_ELEMENTSIZE, V);
+ /// This class represents the atomic memcpy intrinsic
+ /// i.e. llvm.element.unordered.atomic.memcpy
+ class AtomicMemCpyInst : public AtomicMemTransferInst {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
+ };
- static inline bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
+ /// This class represents the atomic memmove intrinsic
+ /// i.e. llvm.element.unordered.atomic.memmove
+ class AtomicMemMoveInst : public AtomicMemTransferInst {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
}
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
/// This is the common base class for memset/memcpy/memmove.
- class MemIntrinsic : public IntrinsicInst {
- public:
- Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); }
- const Use &getRawDestUse() const { return getArgOperandUse(0); }
- Use &getRawDestUse() { return getArgOperandUse(0); }
-
- Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); }
- const Use &getLengthUse() const { return getArgOperandUse(2); }
- Use &getLengthUse() { return getArgOperandUse(2); }
+ class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
+ private:
+ enum { ARG_ALIGN = 3, ARG_VOLATILE = 4 };
+ public:
ConstantInt *getAlignmentCst() const {
- return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_ALIGN)));
}
unsigned getAlignment() const {
@@ -494,45 +406,20 @@ namespace llvm {
}
ConstantInt *getVolatileCst() const {
- return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4)));
+ return cast<ConstantInt>(
+ const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
}
bool isVolatile() const {
return !getVolatileCst()->isZero();
}
- unsigned getDestAddressSpace() const {
- return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
- }
+ void setAlignment(Constant *A) { setArgOperand(ARG_ALIGN, A); }
- /// This is just like getRawDest, but it strips off any cast
- /// instructions that feed it, giving the original input. The returned
- /// value is guaranteed to be a pointer.
- Value *getDest() const { return getRawDest()->stripPointerCasts(); }
-
- /// Set the specified arguments of the instruction.
- void setDest(Value *Ptr) {
- assert(getRawDest()->getType() == Ptr->getType() &&
- "setDest called with pointer of wrong type!");
- setArgOperand(0, Ptr);
- }
-
- void setLength(Value *L) {
- assert(getLength()->getType() == L->getType() &&
- "setLength called with value of wrong type!");
- setArgOperand(2, L);
- }
-
- void setAlignment(Constant* A) {
- setArgOperand(3, A);
- }
-
- void setVolatile(Constant* V) {
- setArgOperand(4, V);
- }
+ void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
Type *getAlignmentType() const {
- return getArgOperand(3)->getType();
+ return getArgOperand(ARG_ALIGN)->getType();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -627,6 +514,155 @@ namespace llvm {
}
static bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ // The common base class for any memset/memmove/memcpy intrinsics;
+ // whether they be atomic or non-atomic.
+ // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
+ // and llvm.memset/memcpy/memmove
+ class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
+ public:
+ bool isVolatile() const {
+ // Only the non-atomic intrinsics can be volatile
+ if (auto *MI = dyn_cast<MemIntrinsic>(this))
+ return MI->isVolatile();
+ return false;
+ }
+
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// This class represents any memset intrinsic
+ // i.e. llvm.element.unordered.atomic.memset
+ // and llvm.memset
+ class AnyMemSetInst : public AnyMemIntrinsic {
+ private:
+ enum { ARG_VALUE = 1 };
+
+ public:
+ Value *getValue() const {
+ return const_cast<Value *>(getArgOperand(ARG_VALUE));
+ }
+ const Use &getValueUse() const { return getArgOperandUse(ARG_VALUE); }
+ Use &getValueUse() { return getArgOperandUse(ARG_VALUE); }
+
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setValue called with value of wrong type!");
+ setArgOperand(ARG_VALUE, Val);
+ }
+
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memset:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ // This class wraps any memcpy/memmove intrinsics
+ // i.e. llvm.element.unordered.atomic.memcpy/memmove
+ // and llvm.memcpy/memmove
+ class AnyMemTransferInst : public AnyMemIntrinsic {
+ private:
+ enum { ARG_SOURCE = 1 };
+
+ public:
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(getArgOperand(ARG_SOURCE));
+ }
+ const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
+ Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
+
+ /// 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(); }
+
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(ARG_SOURCE, Ptr);
+ }
+
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// This class represents any memcpy intrinsic
+ /// i.e. llvm.element.unordered.atomic.memcpy
+ /// and llvm.memcpy
+ class AnyMemCpyInst : public AnyMemTransferInst {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// This class represents any memmove intrinsic
+ /// i.e. llvm.element.unordered.atomic.memmove
+ /// and llvm.memmove
+ class AnyMemMoveInst : public AnyMemTransferInst {
+ public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memmove:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
+ }
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
}
};
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=316950&r1=316949&r2=316950&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Oct 30 12:51:48 2017
@@ -5044,8 +5044,7 @@ SelectionDAGBuilder::visitIntrinsicCall(
return nullptr;
}
case Intrinsic::memcpy_element_unordered_atomic: {
- const ElementUnorderedAtomicMemCpyInst &MI =
- cast<ElementUnorderedAtomicMemCpyInst>(I);
+ const AtomicMemCpyInst &MI = cast<AtomicMemCpyInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Src = getValue(MI.getRawSource());
SDValue Length = getValue(MI.getLength());
@@ -5083,7 +5082,7 @@ SelectionDAGBuilder::visitIntrinsicCall(
return nullptr;
}
case Intrinsic::memmove_element_unordered_atomic: {
- auto &MI = cast<ElementUnorderedAtomicMemMoveInst>(I);
+ auto &MI = cast<AtomicMemMoveInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Src = getValue(MI.getRawSource());
SDValue Length = getValue(MI.getLength());
@@ -5121,7 +5120,7 @@ SelectionDAGBuilder::visitIntrinsicCall(
return nullptr;
}
case Intrinsic::memset_element_unordered_atomic: {
- auto &MI = cast<ElementUnorderedAtomicMemSetInst>(I);
+ auto &MI = cast<AtomicMemSetInst>(I);
SDValue Dst = getValue(MI.getRawDest());
SDValue Val = getValue(MI.getValue());
SDValue Length = getValue(MI.getLength());
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=316950&r1=316949&r2=316950&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon Oct 30 12:51:48 2017
@@ -4029,9 +4029,7 @@ void Verifier::visitIntrinsicCallSite(In
break;
}
case Intrinsic::memcpy_element_unordered_atomic: {
- const ElementUnorderedAtomicMemCpyInst *MI =
- cast<ElementUnorderedAtomicMemCpyInst>(CS.getInstruction());
- ;
+ const AtomicMemCpyInst *MI = cast<AtomicMemCpyInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());
@@ -4066,7 +4064,7 @@ void Verifier::visitIntrinsicCallSite(In
break;
}
case Intrinsic::memmove_element_unordered_atomic: {
- auto *MI = cast<ElementUnorderedAtomicMemMoveInst>(CS.getInstruction());
+ auto *MI = cast<AtomicMemMoveInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());
@@ -4101,7 +4099,7 @@ void Verifier::visitIntrinsicCallSite(In
break;
}
case Intrinsic::memset_element_unordered_atomic: {
- auto *MI = cast<ElementUnorderedAtomicMemSetInst>(CS.getInstruction());
+ auto *MI = cast<AtomicMemSetInst>(CS.getInstruction());
ConstantInt *ElementSizeCI =
dyn_cast<ConstantInt>(MI->getRawElementSizeInBytes());
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=316950&r1=316949&r2=316950&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Oct 30 12:51:48 2017
@@ -106,8 +106,8 @@ static Constant *getNegativeIsTrueBoolVe
return ConstantVector::get(BoolVec);
}
-Instruction *InstCombiner::SimplifyElementUnorderedAtomicMemCpy(
- ElementUnorderedAtomicMemCpyInst *AMI) {
+Instruction *
+InstCombiner::SimplifyElementUnorderedAtomicMemCpy(AtomicMemCpyInst *AMI) {
// Try to unfold this intrinsic into sequence of explicit atomic loads and
// stores.
// First check that number of elements is compile time constant.
@@ -1877,7 +1877,7 @@ Instruction *InstCombiner::visitCallInst
if (Changed) return II;
}
- if (auto *AMI = dyn_cast<ElementUnorderedAtomicMemCpyInst>(II)) {
+ if (auto *AMI = dyn_cast<AtomicMemCpyInst>(II)) {
if (Constant *C = dyn_cast<Constant>(AMI->getLength()))
if (C->isNullValue())
return eraseInstFromFunction(*AMI);
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=316950&r1=316949&r2=316950&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h Mon Oct 30 12:51:48 2017
@@ -789,8 +789,7 @@ private:
Instruction *MatchBSwap(BinaryOperator &I);
bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
- Instruction *
- SimplifyElementUnorderedAtomicMemCpy(ElementUnorderedAtomicMemCpyInst *AMI);
+ Instruction *SimplifyElementUnorderedAtomicMemCpy(AtomicMemCpyInst *AMI);
Instruction *SimplifyMemTransfer(MemIntrinsic *MI);
Instruction *SimplifyMemSet(MemSetInst *MI);
More information about the llvm-commits
mailing list