mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
Introduce a new MemTransferInst pseudo class, which is a common
parent between MemCpyInst and MemMoveInst, simplify some code to use it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66361 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ff9dcee534
commit
3ce5e887ae
@ -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<Value*>(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<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(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<Value*>(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<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(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<Value*>(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<Value*>(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<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
};
|
||||
|
||||
/// EHSelectorInst - This represents the llvm.eh.selector instruction.
|
||||
///
|
||||
struct EHSelectorInst : public IntrinsicInst {
|
||||
|
@ -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<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
|
||||
if (isa<MemTransferInst>(MI)) {
|
||||
if (Instruction *I = SimplifyMemTransfer(MI))
|
||||
return I;
|
||||
} else if (MemSetInst *MSI = dyn_cast<MemSetInst>(MI)) {
|
||||
|
@ -605,7 +605,7 @@ void SROA::isSafeMemIntrinsicOnAllocation(MemIntrinsic *MI, AllocationInst *AI,
|
||||
return MarkUnsafe(Info);
|
||||
|
||||
// We only know about memcpy/memset/memmove.
|
||||
if (!isa<MemCpyInst>(MI) && !isa<MemSetInst>(MI) && !isa<MemMoveInst>(MI))
|
||||
if (!isa<MemIntrinsic>(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<MemCpyInst>(MI)) {
|
||||
if (BCInst == MCI->getRawDest())
|
||||
OtherPtr = MCI->getRawSource();
|
||||
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { // memmove/memcopy
|
||||
if (BCInst == MTI->getRawDest())
|
||||
OtherPtr = MTI->getRawSource();
|
||||
else {
|
||||
assert(BCInst == MCI->getRawSource());
|
||||
OtherPtr = MCI->getRawDest();
|
||||
}
|
||||
} else if (MemMoveInst *MMI = dyn_cast<MemMoveInst>(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<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
|
||||
if (isa<MemTransferInst>(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<MemCpyInst>(MI) || isa<MemMoveInst>(MI)) {
|
||||
if (isa<MemTransferInst>(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<MemSetInst>(User) &&
|
||||
// Store of constant value.
|
||||
isa<ConstantInt>(User->getOperand(2)) &&
|
||||
// Store with constant size.
|
||||
isa<ConstantInt>(User->getOperand(3))) {
|
||||
VecTy = Type::VoidTy;
|
||||
IsNotTrivial = true;
|
||||
continue;
|
||||
if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
|
||||
// Store of constant value and constant size.
|
||||
if (isa<ConstantInt>(MSI->getValue()) &&
|
||||
isa<ConstantInt>(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<MemCpyInst>(*UI) && !isa<MemMoveInst>(*UI))
|
||||
if (!isa<MemTransferInst>(*UI))
|
||||
return false;
|
||||
|
||||
// If we already have seen a copy, reject the second one.
|
||||
|
Loading…
Reference in New Issue
Block a user