llvm.org GIT mirror llvm / 67c2691
[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 Sjoerd Meijer 1 year, 4 months ago
17 changed file(s) with 45 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
14051405 /// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
14061406 /// does not need to be loaded. It returns EVT::Other if the type should be
14071407 /// determined using generic target-independent logic.
1408 virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
1409 unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
1410 bool /*IsMemset*/,
1411 bool /*ZeroMemset*/,
1412 bool /*MemcpyStrSrc*/,
1413 MachineFunction &/*MF*/) const {
1408 virtual EVT
1409 getOptimalMemOpType(uint64_t /*Size*/, unsigned /*DstAlign*/,
1410 unsigned /*SrcAlign*/, bool /*IsMemset*/,
1411 bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/,
1412 const AttributeList & /*FuncAttributes*/) const {
14141413 return MVT::Other;
14151414 }
14161415
55855585 // means it's possible to change the alignment of the destination.
55865586 // 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
55875587 // not need to be loaded.
5588 const Function &F = DAG.getMachineFunction().getFunction();
55885589 EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
55895590 IsMemset, ZeroMemset, MemcpyStrSrc,
5590 DAG.getMachineFunction());
5591 F.getAttributes());
55915592
55925593 if (VT == MVT::Other) {
55935594 // Use the largest integer type whose alignment constraints are satisfied.
86338633 (DstAlign == 0 || DstAlign % AlignCheck == 0));
86348634 }
86358635
8636 EVT AArch64TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
8637 unsigned SrcAlign, bool IsMemset,
8638 bool ZeroMemset,
8639 bool MemcpyStrSrc,
8640 MachineFunction &MF) const {
8641 const Function &F = MF.getFunction();
8642 bool CanImplicitFloat = !F.hasFnAttribute(Attribute::NoImplicitFloat);
8636 EVT AArch64TargetLowering::getOptimalMemOpType(
8637 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
8638 bool ZeroMemset, bool MemcpyStrSrc,
8639 const AttributeList &FuncAttributes) const {
8640 bool CanImplicitFloat =
8641 !FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat);
86438642 bool CanUseNEON = Subtarget->hasNEON() && CanImplicitFloat;
86448643 bool CanUseFP = Subtarget->hasFPARMv8() && CanImplicitFloat;
86458644 // Only use AdvSIMD to implement memset of 32-byte and above. It would have
348348
349349 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
350350 bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
351 MachineFunction &MF) const override;
351 const AttributeList &FuncAttributes) const override;
352352
353353 /// Return true if the addressing mode represented by AM is legal for this
354354 /// target, for a load/store of the specified type.
12211221 return VT.bitsGT(MVT::i32) && Align % 4 == 0;
12221222 }
12231223
1224 EVT SITargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
1225 unsigned SrcAlign, bool IsMemset,
1226 bool ZeroMemset,
1227 bool MemcpyStrSrc,
1228 MachineFunction &MF) const {
1224 EVT SITargetLowering::getOptimalMemOpType(
1225 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
1226 bool ZeroMemset, bool MemcpyStrSrc,
1227 const AttributeList &FuncAttributes) const {
12291228 // FIXME: Should account for address space here.
12301229
12311230 // The default fallback uses the private pointer size as a guess for a type to
240240 unsigned SrcAlign, bool IsMemset,
241241 bool ZeroMemset,
242242 bool MemcpyStrSrc,
243 MachineFunction &MF) const override;
243 const AttributeList &FuncAttributes) const override;
244244
245245 bool isMemOpUniform(const SDNode *N) const;
246246 bool isMemOpHasNoClobberedMemOperand(const SDNode *N) const;
1309213092 (DstAlign == 0 || DstAlign % AlignCheck == 0));
1309313093 }
1309413094
13095 EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
13096 unsigned DstAlign, unsigned SrcAlign,
13097 bool IsMemset, bool ZeroMemset,
13098 bool MemcpyStrSrc,
13099 MachineFunction &MF) const {
13100 const Function &F = MF.getFunction();
13101
13095 EVT ARMTargetLowering::getOptimalMemOpType(
13096 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
13097 bool ZeroMemset, bool MemcpyStrSrc,
13098 const AttributeList &FuncAttributes) const {
1310213099 // See if we can use NEON instructions for this...
1310313100 if ((!IsMemset || ZeroMemset) && Subtarget->hasNEON() &&
13104 !F.hasFnAttribute(Attribute::NoImplicitFloat)) {
13101 !FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
1310513102 bool Fast;
1310613103 if (Size >= 16 &&
1310713104 (memOpAlign(SrcAlign, DstAlign, 16) ||
326326 unsigned DstAlign, unsigned SrcAlign,
327327 bool IsMemset, bool ZeroMemset,
328328 bool MemcpyStrSrc,
329 MachineFunction &MF) const override;
329 const AttributeList &FuncAttributes) const override;
330330
331331 bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;
332332 bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
100100
101101 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
102102 bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
103 MachineFunction &MF) const override {
103 const AttributeList &FuncAttributes) const override {
104104 return Size >= 8 ? MVT::i64 : MVT::i32;
105105 }
106106
30483048 /// determined using generic target-independent logic.
30493049 EVT HexagonTargetLowering::getOptimalMemOpType(uint64_t Size,
30503050 unsigned DstAlign, unsigned SrcAlign, bool IsMemset, bool ZeroMemset,
3051 bool MemcpyStrSrc, MachineFunction &MF) const {
3051 bool MemcpyStrSrc, const AttributeList &FuncAttributes) const {
30523052
30533053 auto Aligned = [](unsigned GivenA, unsigned MinA) -> bool {
30543054 return (GivenA % MinA) == 0;
294294
295295 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
296296 unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
297 MachineFunction &MF) const override;
297 const AttributeList &FuncAttributes) const override;
298298
299299 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
300300 unsigned Align, bool *Fast) const override;
41394139 return false;
41404140 }
41414141
4142 EVT MipsTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
4143 unsigned SrcAlign,
4144 bool IsMemset, bool ZeroMemset,
4145 bool MemcpyStrSrc,
4146 MachineFunction &MF) const {
4142 EVT MipsTargetLowering::getOptimalMemOpType(
4143 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
4144 bool ZeroMemset, bool MemcpyStrSrc,
4145 const AttributeList &FuncAttributes) const {
41474146 if (Subtarget.hasMips64())
41484147 return MVT::i64;
41494148
669669 unsigned SrcAlign,
670670 bool IsMemset, bool ZeroMemset,
671671 bool MemcpyStrSrc,
672 MachineFunction &MF) const override;
672 const AttributeList &FuncAttributes) const override;
673673
674674 /// isFPImmLegal - Returns true if the target can instruction select the
675675 /// specified FP immediate natively. If false, the legalizer will
1422214222 /// source is constant so it does not need to be loaded.
1422314223 /// It returns EVT::Other if the type should be determined using generic
1422414224 /// target-independent logic.
14225 EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
14226 unsigned DstAlign, unsigned SrcAlign,
14227 bool IsMemset, bool ZeroMemset,
14228 bool MemcpyStrSrc,
14229 MachineFunction &MF) const {
14225 EVT PPCTargetLowering::getOptimalMemOpType(
14226 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
14227 bool ZeroMemset, bool MemcpyStrSrc,
14228 const AttributeList &FuncAttributes) const {
1423014229 if (getTargetMachine().getOptLevel() != CodeGenOpt::None) {
14231 const Function &F = MF.getFunction();
1423214230 // When expanding a memset, require at least two QPX instructions to cover
1423314231 // the cost of loading the value to be stored from the constant pool.
1423414232 if (Subtarget.hasQPX() && Size >= 32 && (!IsMemset || Size >= 64) &&
1423514233 (!SrcAlign || SrcAlign >= 32) && (!DstAlign || DstAlign >= 32) &&
14236 !F.hasFnAttribute(Attribute::NoImplicitFloat)) {
14234 !FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
1423714235 return MVT::v4f64;
1423814236 }
1423914237
831831 EVT
832832 getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
833833 bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
834 MachineFunction &MF) const override;
834 const AttributeList &FuncAttributes) const override;
835835
836836 /// Is unaligned memory access allowed for the given type, and is it fast
837837 /// relative to software emulation.
20582058 /// It returns EVT::Other if the type should be determined using generic
20592059 /// target-independent logic.
20602060 EVT
2061 X86TargetLowering::getOptimalMemOpType(uint64_t Size,
2062 unsigned DstAlign, unsigned SrcAlign,
2063 bool IsMemset, bool ZeroMemset,
2064 bool MemcpyStrSrc,
2065 MachineFunction &MF) const {
2066 const Function &F = MF.getFunction();
2067 if (!F.hasFnAttribute(Attribute::NoImplicitFloat)) {
2061 X86TargetLowering::getOptimalMemOpType(
2062 uint64_t Size, unsigned DstAlign, unsigned SrcAlign, bool IsMemset,
2063 bool ZeroMemset, bool MemcpyStrSrc,
2064 const AttributeList &FuncAttributes) const {
2065 if (!FuncAttributes.hasFnAttribute(Attribute::NoImplicitFloat)) {
20682066 if (Size >= 16 &&
20692067 (!Subtarget.isUnalignedMem16Slow() ||
20702068 ((DstAlign == 0 || DstAlign >= 16) &&
712712 /// target-independent logic.
713713 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign,
714714 bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
715 MachineFunction &MF) const override;
715 const AttributeList &FuncAttributes) const override;
716716
717717 /// Returns true if it's safe to use load / store of the
718718 /// specified type to expand memcpy / memset inline. This is mostly true