diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-08-02 18:34:31 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-08-02 18:34:31 +0000 |
commit | a4e94ebbb2e2d3f220dca37a09a409a5c98f12d4 (patch) | |
tree | 4eb3b3d378274da5c0da06c30e3abec15ecc321f /lib | |
parent | c37e7b92f8f38665202f28706203aa757ce922cd (diff) |
[Hexagon] Improvements to address mode checks in TargetLowering
- Implement getOptimalMemOpType.
- Check BaseOffset in isLegalAddressingMode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277494 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Hexagon/HexagonISelLowering.cpp | 37 | ||||
-rw-r--r-- | lib/Target/Hexagon/HexagonISelLowering.h | 4 |
2 files changed, 39 insertions, 2 deletions
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 0f614ddf58a..692e13af789 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -3055,8 +3055,12 @@ bool HexagonTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { bool HexagonTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS) const { - // Allows a signed-extended 11-bit immediate field. - if (AM.BaseOffs <= -(1LL << 13) || AM.BaseOffs >= (1LL << 13)-1) + unsigned A = DL.getABITypeAlignment(Ty); + // The base offset must be a multiple of the alignment. + if ((AM.BaseOffs % A) != 0) + return false; + // The shifted offset must fit in 11 bits. + if (!isInt<11>(AM.BaseOffs >> Log2_32(A))) return false; // No global is ever allowed as a base. @@ -3139,6 +3143,35 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization( return true; } +/// Returns the target specific optimal type for load and store operations as +/// a result of memset, memcpy, and memmove lowering. +/// +/// If DstAlign is zero that means it's safe to destination alignment can +/// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't +/// a need to check it against alignment requirement, probably because the +/// source does not need to be loaded. If 'IsMemset' is true, that means it's +/// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of +/// 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. +EVT HexagonTargetLowering::getOptimalMemOpType(uint64_t Size, + unsigned DstAlign, unsigned SrcAlign, bool IsMemset, bool ZeroMemset, + bool MemcpyStrSrc, MachineFunction &MF) const { + + auto Aligned = [](unsigned GivenA, unsigned MinA) -> bool { + return (GivenA % MinA) == 0; + }; + + if (Size >= 8 && Aligned(DstAlign, 8) && (IsMemset || Aligned(SrcAlign, 8))) + return MVT::i64; + if (Size >= 4 && Aligned(DstAlign, 4) && (IsMemset || Aligned(SrcAlign, 4))) + return MVT::i32; + if (Size >= 2 && Aligned(DstAlign, 2) && (IsMemset || Aligned(SrcAlign, 2))) + return MVT::i16; + + return MVT::Other; +} + // Return true when the given node fits in a positive half word. bool llvm::isPositiveHalfWord(SDNode *N) { ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h index 5291a8737e2..e940a37076b 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.h +++ b/lib/Target/Hexagon/HexagonISelLowering.h @@ -247,6 +247,10 @@ bool isPositiveHalfWord(SDNode *N); /// the immediate into a register. bool isLegalICmpImmediate(int64_t Imm) const override; + EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, + unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc, + MachineFunction &MF) const override; + bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align, bool *Fast) const override; |