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:
parent
4c22824d3e
commit
c314f34707
@ -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
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user