mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
[TargetLowering] Change getOptimalMemOpType to take a function attribute list
The MachineFunction wasn't used in getOptimalMemOpType, but more importantly, this allows reuse of findOptimalMemOpLowering that is calling getOptimalMemOpType. This is the groundwork for the changes in D59766 and D59787, that allows implementation of TTI::getMemcpyCost. Differential Revision: https://reviews.llvm.org/D59785 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359537 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1406,12 +1406,11 @@ public:
|
||||
/// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
|
||||
/// does not need to be loaded. It returns EVT::Other if the type should be
|
||||
/// determined using generic target-independent logic.
|
||||
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
|
||||
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
|
||||
bool /*IsMemset*/,
|
||||
bool /*ZeroMemset*/,
|
||||
bool /*MemcpyStrSrc*/,
|
||||
MachineFunction &/*MF*/) const {
|
||||
virtual EVT
|
||||
getOptimalMemOpType(uint64_t /*Size*/, unsigned /*DstAlign*/,
|
||||
unsigned /*SrcAlign*/, bool /*IsMemset*/,
|
||||
bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/,
|
||||
const AttributeList & /*FuncAttributes*/) const {
|
||||
return MVT::Other;
|
||||
}
|
||||
|
||||
|
||||
@@ -5586,9 +5586,10 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
|
||||
// means it's possible to change the alignment of the destination.
|
||||
// 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
|
||||
// not need to be loaded.
|
||||
const Function &F = DAG.getMachineFunction().getFunction();
|
||||
EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
|
||||
IsMemset, ZeroMemset, MemcpyStrSrc,
|
||||
DAG.getMachineFunction());
|
||||
F.getAttributes());
|
||||
|
||||
if (VT == MVT::Other) {
|
||||
// Use the largest integer type whose alignment constraints are satisfied.
|
||||
|
||||
@@ -8634,13 +8634,12 @@ static bool memOpAlign(unsigned DstAlign, unsigned SrcAlign,
|
||||
(DstAlign == 0 || DstAlign % AlignCheck == 0));
|
||||
}
|
||||
|
||||
EVT AArch64TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
|
||||
unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
const Function &F = MF.getFunction();
|
||||
bool CanImplicitFloat = !F.hasFnAttribute(Attribute::NoImplicitFloat);
|
||||
EVT AArch64TargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
bool CanImplicitFloat =
|
||||
!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat);
|
||||
bool CanUseNEON = Subtarget->hasNEON() && CanImplicitFloat;
|
||||
bool CanUseFP = Subtarget->hasFPARMv8() && CanImplicitFloat;
|
||||
// Only use AdvSIMD to implement memset of 32-byte and above. It would have
|
||||
|
||||
@@ -349,7 +349,7 @@ public:
|
||||
|
||||
EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// Return true if the addressing mode represented by AM is legal for this
|
||||
/// target, for a load/store of the specified type.
|
||||
|
||||
@@ -1222,11 +1222,10 @@ bool SITargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
|
||||
return VT.bitsGT(MVT::i32) && Align % 4 == 0;
|
||||
}
|
||||
|
||||
EVT SITargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
|
||||
unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
EVT SITargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
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
|
||||
|
||||
@@ -241,7 +241,7 @@ public:
|
||||
unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool isMemOpUniform(const SDNode *N) const;
|
||||
bool isMemOpHasNoClobberedMemOperand(const SDNode *N) const;
|
||||
|
||||
@@ -13093,16 +13093,13 @@ static bool memOpAlign(unsigned DstAlign, unsigned SrcAlign,
|
||||
(DstAlign == 0 || DstAlign % AlignCheck == 0));
|
||||
}
|
||||
|
||||
EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
|
||||
unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
const Function &F = MF.getFunction();
|
||||
|
||||
EVT ARMTargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
// See if we can use NEON instructions for this...
|
||||
if ((!IsMemset || ZeroMemset) && Subtarget->hasNEON() &&
|
||||
!F.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
bool Fast;
|
||||
if (Size >= 16 &&
|
||||
(memOpAlign(SrcAlign, DstAlign, 16) ||
|
||||
|
||||
@@ -327,7 +327,7 @@ class VectorType;
|
||||
unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
|
||||
bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
|
||||
|
||||
@@ -101,7 +101,7 @@ private:
|
||||
|
||||
EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override {
|
||||
const AttributeList &FuncAttributes) const override {
|
||||
return Size >= 8 ? MVT::i64 : MVT::i32;
|
||||
}
|
||||
|
||||
|
||||
@@ -3049,7 +3049,7 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
|
||||
/// determined using generic target-independent logic.
|
||||
EVT HexagonTargetLowering::getOptimalMemOpType(uint64_t Size,
|
||||
unsigned DstAlign, unsigned SrcAlign, bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc, MachineFunction &MF) const {
|
||||
bool MemcpyStrSrc, const AttributeList &FuncAttributes) const {
|
||||
|
||||
auto Aligned = [](unsigned GivenA, unsigned MinA) -> bool {
|
||||
return (GivenA % MinA) == 0;
|
||||
|
||||
@@ -295,7 +295,7 @@ namespace HexagonISD {
|
||||
|
||||
EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
|
||||
unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
|
||||
unsigned Align, bool *Fast) const override;
|
||||
|
||||
@@ -4140,11 +4140,10 @@ MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
|
||||
unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
EVT MipsTargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (Subtarget.hasMips64())
|
||||
return MVT::i64;
|
||||
|
||||
|
||||
@@ -670,7 +670,7 @@ class TargetRegisterClass;
|
||||
unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// isFPImmLegal - Returns true if the target can instruction select the
|
||||
/// specified FP immediate natively. If false, the legalizer will
|
||||
|
||||
@@ -14223,18 +14223,16 @@ bool PPCTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
|
||||
/// source is constant so it does not need to be loaded.
|
||||
/// It returns EVT::Other if the type should be determined using generic
|
||||
/// target-independent logic.
|
||||
EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
|
||||
unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
EVT PPCTargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (getTargetMachine().getOptLevel() != CodeGenOpt::None) {
|
||||
const Function &F = MF.getFunction();
|
||||
// When expanding a memset, require at least two QPX instructions to cover
|
||||
// the cost of loading the value to be stored from the constant pool.
|
||||
if (Subtarget.hasQPX() && Size >= 32 && (!IsMemset || Size >= 64) &&
|
||||
(!SrcAlign || SrcAlign >= 32) && (!DstAlign || DstAlign >= 32) &&
|
||||
!F.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
return MVT::v4f64;
|
||||
}
|
||||
|
||||
|
||||
@@ -832,7 +832,7 @@ namespace llvm {
|
||||
EVT
|
||||
getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// Is unaligned memory access allowed for the given type, and is it fast
|
||||
/// relative to software emulation.
|
||||
|
||||
@@ -2059,13 +2059,11 @@ unsigned X86TargetLowering::getByValTypeAlignment(Type *Ty,
|
||||
/// It returns EVT::Other if the type should be determined using generic
|
||||
/// target-independent logic.
|
||||
EVT
|
||||
X86TargetLowering::getOptimalMemOpType(uint64_t Size,
|
||||
unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset,
|
||||
bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const {
|
||||
const Function &F = MF.getFunction();
|
||||
if (!F.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
X86TargetLowering::getOptimalMemOpType(
|
||||
uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
|
||||
bool ZeroMemset, bool MemcpyStrSrc,
|
||||
const AttributeList &FuncAttributes) const {
|
||||
if (!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
|
||||
if (Size >= 16 &&
|
||||
(!Subtarget.isUnalignedMem16Slow() ||
|
||||
((DstAlign == 0 || DstAlign >= 16) &&
|
||||
|
||||
@@ -713,7 +713,7 @@ namespace llvm {
|
||||
/// target-independent logic.
|
||||
EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
|
||||
bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
|
||||
MachineFunction &MF) const override;
|
||||
const AttributeList &FuncAttributes) const override;
|
||||
|
||||
/// Returns true if it's safe to use load / store of the
|
||||
/// specified type to expand memcpy / memset inline. This is mostly true
|
||||
|
||||
Reference in New Issue
Block a user