[TargetLowering] Change getOptimalMemOpType and findOptimalMemOpLowering to take LLVM Context (#147664)
Add LLVM Context to getOptimalMemOpType and findOptimalMemOpLowering. So that we can use EVT::getVectorVT to generate EVT type in getOptimalMemOpType. Related to [#146673](https://github.com/llvm/llvm-project/pull/146673).
This commit is contained in:
parent
c86c815fc5
commit
697beb3f17
@ -2017,7 +2017,7 @@ public:
|
||||
/// It returns EVT::Other if the type should be determined using generic
|
||||
/// target-independent logic.
|
||||
virtual EVT
|
||||
getOptimalMemOpType(const MemOp &Op,
|
||||
getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList & /*FuncAttributes*/) const {
|
||||
return MVT::Other;
|
||||
}
|
||||
@ -4109,8 +4109,9 @@ public:
|
||||
/// It returns the types of the sequence of memory ops to perform
|
||||
/// memset / memcpy by reference.
|
||||
virtual bool
|
||||
findOptimalMemOpLowering(std::vector<EVT> &MemOps, unsigned Limit,
|
||||
const MemOp &Op, unsigned DstAS, unsigned SrcAS,
|
||||
findOptimalMemOpLowering(LLVMContext &Context, std::vector<EVT> &MemOps,
|
||||
unsigned Limit, const MemOp &Op, unsigned DstAS,
|
||||
unsigned SrcAS,
|
||||
const AttributeList &FuncAttributes) const;
|
||||
|
||||
/// Check to see if the specified operand of the specified instruction is a
|
||||
|
@ -8410,7 +8410,7 @@ static SDValue getMemcpyLoadsAndStores(
|
||||
: MemOp::Copy(Size, DstAlignCanChange, Alignment,
|
||||
*SrcAlign, isVol, CopyFromConstant);
|
||||
if (!TLI.findOptimalMemOpLowering(
|
||||
MemOps, Limit, Op, DstPtrInfo.getAddrSpace(),
|
||||
C, MemOps, Limit, Op, DstPtrInfo.getAddrSpace(),
|
||||
SrcPtrInfo.getAddrSpace(), MF.getFunction().getAttributes()))
|
||||
return SDValue();
|
||||
|
||||
@ -8602,7 +8602,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, const SDLoc &dl,
|
||||
assert(SrcAlign && "SrcAlign must be set");
|
||||
unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemmove(OptSize);
|
||||
if (!TLI.findOptimalMemOpLowering(
|
||||
MemOps, Limit,
|
||||
C, MemOps, Limit,
|
||||
MemOp::Copy(Size, DstAlignCanChange, Alignment, *SrcAlign,
|
||||
/*IsVolatile*/ true),
|
||||
DstPtrInfo.getAddrSpace(), SrcPtrInfo.getAddrSpace(),
|
||||
@ -8711,6 +8711,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl,
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
std::vector<EVT> MemOps;
|
||||
bool DstAlignCanChange = false;
|
||||
LLVMContext &C = *DAG.getContext();
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
bool OptSize = shouldLowerMemFuncForSize(MF, DAG);
|
||||
@ -8721,7 +8722,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, const SDLoc &dl,
|
||||
unsigned Limit = AlwaysInline ? ~0 : TLI.getMaxStoresPerMemset(OptSize);
|
||||
|
||||
if (!TLI.findOptimalMemOpLowering(
|
||||
MemOps, Limit,
|
||||
C, MemOps, Limit,
|
||||
MemOp::Set(Size, DstAlignCanChange, Alignment, IsZeroVal, isVol),
|
||||
DstPtrInfo.getAddrSpace(), ~0u, MF.getFunction().getAttributes()))
|
||||
return SDValue();
|
||||
|
@ -210,13 +210,14 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
|
||||
}
|
||||
|
||||
bool TargetLowering::findOptimalMemOpLowering(
|
||||
std::vector<EVT> &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS,
|
||||
unsigned SrcAS, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, std::vector<EVT> &MemOps, unsigned Limit,
|
||||
const MemOp &Op, unsigned DstAS, unsigned SrcAS,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (Limit != ~unsigned(0) && Op.isMemcpyWithFixedDstAlign() &&
|
||||
Op.getSrcAlign() < Op.getDstAlign())
|
||||
return false;
|
||||
|
||||
EVT VT = getOptimalMemOpType(Op, FuncAttributes);
|
||||
EVT VT = getOptimalMemOpType(Context, Op, FuncAttributes);
|
||||
|
||||
if (VT == MVT::Other) {
|
||||
// Use the largest integer type whose alignment constraints are satisfied.
|
||||
|
@ -17599,7 +17599,8 @@ bool AArch64TargetLowering::lowerInterleaveIntrinsicToStore(
|
||||
}
|
||||
|
||||
EVT AArch64TargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
bool CanImplicitFloat = !FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat);
|
||||
bool CanUseNEON = Subtarget->hasNEON() && CanImplicitFloat;
|
||||
bool CanUseFP = Subtarget->hasFPARMv8() && CanImplicitFloat;
|
||||
|
@ -233,7 +233,7 @@ public:
|
||||
|
||||
bool shouldConsiderGEPOffsetSplit() const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
LLT getOptimalMemOpLLT(const MemOp &Op,
|
||||
|
@ -1983,7 +1983,8 @@ bool SITargetLowering::allowsMisalignedMemoryAccesses(
|
||||
}
|
||||
|
||||
EVT SITargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
// FIXME: Should account for address space here.
|
||||
|
||||
// The default fallback uses the private pointer size as a guess for a type to
|
||||
|
@ -357,7 +357,7 @@ public:
|
||||
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
|
||||
unsigned *IsFast = nullptr) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool isMemOpHasNoClobberedMemOperand(const SDNode *N) const;
|
||||
|
@ -19219,9 +19219,9 @@ bool ARMTargetLowering::allowsMisalignedMemoryAccesses(EVT VT, unsigned,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EVT ARMTargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
// See if we can use NEON instructions for this...
|
||||
if ((Op.isMemcpy() || Op.isZeroMemset()) && Subtarget->hasNEON() &&
|
||||
!FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
|
||||
|
@ -472,7 +472,7 @@ class VectorType;
|
||||
MachineMemOperand::Flags Flags,
|
||||
unsigned *Fast) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
|
||||
|
@ -1213,9 +1213,9 @@ int ARMTTIImpl::getNumMemOps(const IntrinsicInst *I) const {
|
||||
// loaded and stored. That's why we multiply the number of elements by 2 to
|
||||
// get the cost for this memcpy.
|
||||
std::vector<EVT> MemOps;
|
||||
if (getTLI()->findOptimalMemOpLowering(
|
||||
MemOps, Limit, MOp, DstAddrSpace,
|
||||
SrcAddrSpace, F->getAttributes()))
|
||||
LLVMContext &C = F->getContext();
|
||||
if (getTLI()->findOptimalMemOpLowering(C, MemOps, Limit, MOp, DstAddrSpace,
|
||||
SrcAddrSpace, F->getAttributes()))
|
||||
return MemOps.size() * Factor;
|
||||
|
||||
// If we can't find an optimal memop lowering, return the default cost
|
||||
|
@ -114,7 +114,7 @@ private:
|
||||
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
||||
SelectionDAG &DAG) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override {
|
||||
return Op.size() >= 8 ? MVT::i64 : MVT::i32;
|
||||
}
|
||||
|
@ -3814,7 +3814,8 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
|
||||
/// does not need to be loaded. It returns EVT::Other if the type should be
|
||||
/// determined using generic target-independent logic.
|
||||
EVT HexagonTargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (Op.size() >= 8 && Op.isAligned(Align(8)))
|
||||
return MVT::i64;
|
||||
if (Op.size() >= 4 && Op.isAligned(Align(4)))
|
||||
|
@ -336,7 +336,7 @@ public:
|
||||
/// the immediate into a register.
|
||||
bool isLegalICmpImmediate(int64_t Imm) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
|
||||
|
@ -4519,7 +4519,8 @@ MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
}
|
||||
|
||||
EVT MipsTargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (Subtarget.hasMips64())
|
||||
return MVT::i64;
|
||||
|
||||
|
@ -698,7 +698,7 @@ class TargetRegisterClass;
|
||||
|
||||
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// isFPImmLegal - Returns true if the target can instruction select the
|
||||
|
@ -18239,7 +18239,8 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
|
||||
/// It returns EVT::Other if the type should be determined using generic
|
||||
/// target-independent logic.
|
||||
EVT PPCTargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (getTargetMachine().getOptLevel() != CodeGenOptLevel::None) {
|
||||
// We should use Altivec/VSX loads and stores when available. For unaligned
|
||||
// addresses, unaligned VSX loads are only fast starting with the P8.
|
||||
|
@ -1088,7 +1088,7 @@ namespace llvm {
|
||||
|
||||
/// It returns EVT::Other if the type should be determined using generic
|
||||
/// target-independent logic.
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// Is unaligned memory access allowed for the given type, and is it fast
|
||||
|
@ -23817,9 +23817,9 @@ bool RISCVTargetLowering::allowsMisalignedMemoryAccesses(
|
||||
return Subtarget.enableUnalignedVectorMem();
|
||||
}
|
||||
|
||||
|
||||
EVT RISCVTargetLowering::getOptimalMemOpType(const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
EVT RISCVTargetLowering::getOptimalMemOpType(
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (!Subtarget.hasVInstructions())
|
||||
return MVT::Other;
|
||||
|
||||
|
@ -331,7 +331,7 @@ public:
|
||||
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
|
||||
unsigned *Fast = nullptr) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool splitValueIntoRegisterParts(
|
||||
|
@ -1423,8 +1423,9 @@ bool SystemZTargetLowering::isLegalAddressingMode(const DataLayout &DL,
|
||||
}
|
||||
|
||||
bool SystemZTargetLowering::findOptimalMemOpLowering(
|
||||
std::vector<EVT> &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS,
|
||||
unsigned SrcAS, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, std::vector<EVT> &MemOps, unsigned Limit,
|
||||
const MemOp &Op, unsigned DstAS, unsigned SrcAS,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
const int MVCFastLen = 16;
|
||||
|
||||
if (Limit != ~unsigned(0)) {
|
||||
@ -1437,12 +1438,13 @@ bool SystemZTargetLowering::findOptimalMemOpLowering(
|
||||
return false; // Memset zero: Use XC
|
||||
}
|
||||
|
||||
return TargetLowering::findOptimalMemOpLowering(MemOps, Limit, Op, DstAS,
|
||||
SrcAS, FuncAttributes);
|
||||
return TargetLowering::findOptimalMemOpLowering(Context, MemOps, Limit, Op,
|
||||
DstAS, SrcAS, FuncAttributes);
|
||||
}
|
||||
|
||||
EVT SystemZTargetLowering::getOptimalMemOpType(const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
EVT SystemZTargetLowering::getOptimalMemOpType(
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
|
||||
}
|
||||
|
||||
|
@ -510,10 +510,11 @@ public:
|
||||
MachineMemOperand::Flags Flags,
|
||||
unsigned *Fast) const override;
|
||||
bool
|
||||
findOptimalMemOpLowering(std::vector<EVT> &MemOps, unsigned Limit,
|
||||
const MemOp &Op, unsigned DstAS, unsigned SrcAS,
|
||||
findOptimalMemOpLowering(LLVMContext &Context, std::vector<EVT> &MemOps,
|
||||
unsigned Limit, const MemOp &Op, unsigned DstAS,
|
||||
unsigned SrcAS,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
bool isTruncateFree(Type *, Type *) const override;
|
||||
bool isTruncateFree(EVT, EVT) const override;
|
||||
|
@ -1095,7 +1095,7 @@ namespace llvm {
|
||||
/// 4-byte boundaries.
|
||||
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override;
|
||||
|
||||
EVT getOptimalMemOpType(const MemOp &Op,
|
||||
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// Returns true if it's safe to use load / store of the
|
||||
|
@ -287,7 +287,8 @@ Align X86TargetLowering::getByValTypeAlignment(Type *Ty,
|
||||
/// For vector ops we check that the overall size isn't larger than our
|
||||
/// preferred vector width.
|
||||
EVT X86TargetLowering::getOptimalMemOpType(
|
||||
const MemOp &Op, const AttributeList &FuncAttributes) const {
|
||||
LLVMContext &Context, const MemOp &Op,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (!FuncAttributes.hasFnAttr(Attribute::NoImplicitFloat)) {
|
||||
if (Op.size() >= 16 &&
|
||||
(!Subtarget.isUnalignedMem16Slow() || Op.isAligned(Align(16)))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user