1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[DAG] Fold FrameIndex offset into BaseIndexOffset analysis. NFCI.

Relanding after restricting equalBaseIndex to not erroneuosly consider
a FrameIndices stemming from alloca from being comparable as its
offset is set post-selectionDAG.

Pull FrameIndex comparision reasoning from DAGCombiner::isAlias to
general BaseIndexOffset.

llvm-svn: 306688
This commit is contained in:
Nirav Dave 2017-06-29 15:48:11 +00:00
parent 4c22824d3e
commit c314f34707
3 changed files with 36 additions and 22 deletions

View File

@ -57,7 +57,7 @@ public:
int64_t &Off); int64_t &Off);
/// Parses tree in Ptr for base, index, offset addresses. /// Parses tree in Ptr for base, index, offset addresses.
static BaseIndexOffset match(SDValue Ptr); static BaseIndexOffset match(SDValue Ptr, const SelectionDAG &DAG);
}; };
} // namespace llvm } // namespace llvm

View File

@ -4915,7 +4915,7 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
return SDValue(); return SDValue();
// Loads must share the same base address // Loads must share the same base address
BaseIndexOffset Ptr = BaseIndexOffset::match(L->getBasePtr()); BaseIndexOffset Ptr = BaseIndexOffset::match(L->getBasePtr(), DAG);
int64_t ByteOffsetFromBase = 0; int64_t ByteOffsetFromBase = 0;
if (!Base) if (!Base)
Base = Ptr; Base = Ptr;
@ -12442,7 +12442,7 @@ void DAGCombiner::getStoreMergeCandidates(
StoreSDNode *St, SmallVectorImpl<MemOpLink> &StoreNodes) { StoreSDNode *St, SmallVectorImpl<MemOpLink> &StoreNodes) {
// This holds the base pointer, index, and the offset in bytes from the base // This holds the base pointer, index, and the offset in bytes from the base
// pointer. // pointer.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr()); BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG);
EVT MemVT = St->getMemoryVT(); EVT MemVT = St->getMemoryVT();
// We must have a base and an offset. // We must have a base and an offset.
@ -12462,8 +12462,8 @@ void DAGCombiner::getStoreMergeCandidates(
BaseIndexOffset LBasePtr; BaseIndexOffset LBasePtr;
// Match on loadbaseptr if relevant. // Match on loadbaseptr if relevant.
if (IsLoadSrc) if (IsLoadSrc)
LBasePtr = LBasePtr = BaseIndexOffset::match(
BaseIndexOffset::match(cast<LoadSDNode>(St->getValue())->getBasePtr()); cast<LoadSDNode>(St->getValue())->getBasePtr(), DAG);
auto CandidateMatch = [&](StoreSDNode *Other, BaseIndexOffset &Ptr, auto CandidateMatch = [&](StoreSDNode *Other, BaseIndexOffset &Ptr,
int64_t &Offset) -> bool { int64_t &Offset) -> bool {
@ -12477,7 +12477,7 @@ void DAGCombiner::getStoreMergeCandidates(
if (IsLoadSrc) { if (IsLoadSrc) {
// The Load's Base Ptr must also match // The Load's Base Ptr must also match
if (LoadSDNode *OtherLd = dyn_cast<LoadSDNode>(Other->getValue())) { if (LoadSDNode *OtherLd = dyn_cast<LoadSDNode>(Other->getValue())) {
auto LPtr = BaseIndexOffset::match(OtherLd->getBasePtr()); auto LPtr = BaseIndexOffset::match(OtherLd->getBasePtr(), DAG);
if (!(LBasePtr.equalBaseIndex(LPtr, DAG))) if (!(LBasePtr.equalBaseIndex(LPtr, DAG)))
return false; return false;
} else } else
@ -12491,7 +12491,7 @@ void DAGCombiner::getStoreMergeCandidates(
if (!(Other->getValue().getOpcode() == ISD::EXTRACT_VECTOR_ELT || if (!(Other->getValue().getOpcode() == ISD::EXTRACT_VECTOR_ELT ||
Other->getValue().getOpcode() == ISD::EXTRACT_SUBVECTOR)) Other->getValue().getOpcode() == ISD::EXTRACT_SUBVECTOR))
return false; return false;
Ptr = BaseIndexOffset::match(Other->getBasePtr()); Ptr = BaseIndexOffset::match(Other->getBasePtr(), DAG);
return (BasePtr.equalBaseIndex(Ptr, DAG, Offset)); return (BasePtr.equalBaseIndex(Ptr, DAG, Offset));
}; };
// We looking for a root node which is an ancestor to all mergable // We looking for a root node which is an ancestor to all mergable
@ -12834,7 +12834,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
if (Ld->getMemoryVT() != MemVT) if (Ld->getMemoryVT() != MemVT)
break; break;
BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr()); BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr(), DAG);
// If this is not the first ptr that we check. // If this is not the first ptr that we check.
int64_t LdOffset = 0; int64_t LdOffset = 0;
if (LdBasePtr.getBase().getNode()) { if (LdBasePtr.getBase().getNode()) {
@ -16602,8 +16602,8 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const {
unsigned NumBytes1 = Op1->getMemoryVT().getSizeInBits() >> 3; unsigned NumBytes1 = Op1->getMemoryVT().getSizeInBits() >> 3;
// Check for BaseIndexOffset matching. // Check for BaseIndexOffset matching.
BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0->getBasePtr()); BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0->getBasePtr(), DAG);
BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1->getBasePtr()); BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1->getBasePtr(), DAG);
int64_t PtrDiff; int64_t PtrDiff;
if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)) if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff))
return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0)); return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0));
@ -16813,7 +16813,7 @@ SDValue DAGCombiner::FindBetterChain(SDNode *N, SDValue OldChain) {
bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) { bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) {
// This holds the base pointer, index, and the offset in bytes from the base // This holds the base pointer, index, and the offset in bytes from the base
// pointer. // pointer.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr()); BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG);
// We must have a base and an offset. // We must have a base and an offset.
if (!BasePtr.getBase().getNode()) if (!BasePtr.getBase().getNode())
@ -16839,7 +16839,7 @@ bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) {
break; break;
// Find the base pointer and offset for this memory node. // Find the base pointer and offset for this memory node.
BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr()); BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr(), DAG);
// Check that the base pointer is the same as the original one. // Check that the base pointer is the same as the original one.
if (!BasePtr.equalBaseIndex(Ptr, DAG)) if (!BasePtr.equalBaseIndex(Ptr, DAG))

View File

@ -11,6 +11,7 @@
#include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
#include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/SelectionDAGNodes.h"
@ -18,28 +19,41 @@ namespace llvm {
bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other, bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,
const SelectionDAG &DAG, int64_t &Off) { const SelectionDAG &DAG, int64_t &Off) {
// Obvious equivalent // Initial Offset difference.
Off = Other.Offset - Offset; Off = Other.Offset - Offset;
if (Other.Base == Base && Other.Index == Index &&
Other.IsIndexSignExt == IsIndexSignExt) if ((Other.Index == Index) && (Other.IsIndexSignExt == IsIndexSignExt)) {
// Trivial match.
if (Other.Base == Base)
return true; return true;
// Match GlobalAddresses // Match GlobalAddresses
if (Index == Other.Index) if (auto *A = dyn_cast<GlobalAddressSDNode>(Base))
if (GlobalAddressSDNode *A = dyn_cast<GlobalAddressSDNode>(Base)) if (auto *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
if (GlobalAddressSDNode *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
if (A->getGlobal() == B->getGlobal()) { if (A->getGlobal() == B->getGlobal()) {
Off += B->getOffset() - A->getOffset(); Off += B->getOffset() - A->getOffset();
return true; return true;
} }
// TODO: we should be able to add FrameIndex analysis improvements here. const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
// Match non-equal FrameIndexes - a FrameIndex stemming from an
// alloca will not have it's ObjectOffset set until post-DAG and
// as such we must assume the two framesIndices are incomparable.
if (auto *A = dyn_cast<FrameIndexSDNode>(Base))
if (auto *B = dyn_cast<FrameIndexSDNode>(Other.Base))
if (!MFI.getObjectAllocation(A->getIndex()) &&
!MFI.getObjectAllocation(B->getIndex())) {
Off += MFI.getObjectOffset(B->getIndex()) -
MFI.getObjectOffset(A->getIndex());
return true;
}
}
return false; return false;
} }
/// Parses tree in Ptr for base, index, offset addresses. /// Parses tree in Ptr for base, index, offset addresses.
BaseIndexOffset BaseIndexOffset::match(SDValue Ptr) { BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) {
// (((B + I*M) + c)) + c ... // (((B + I*M) + c)) + c ...
SDValue Base = Ptr; SDValue Base = Ptr;
SDValue Index = SDValue(); SDValue Index = SDValue();