[DAG] Remove Node csonstruction from BaseIndexOffset match. NFCI.

Move GlobalAddress Offset decomposition from initial match into
comparision check and removing the possibility of constructing a new
offseted global address when examining addresses.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305917 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nirav Dave 2017-06-21 15:07:30 +00:00
parent a110a35ffd
commit 24058c71a9

View File

@ -4708,33 +4708,58 @@ namespace {
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (i32 add (i32 signextend (i8 load %index))
/// (i32 1)))))
struct BaseIndexOffset {
class BaseIndexOffset {
private:
SDValue Base;
SDValue Index;
int64_t Offset;
bool IsIndexSignExt;
public:
BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {}
BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
bool IsIndexSignExt) :
Base(Base), Index(Index), Offset(Offset), IsIndexSignExt(IsIndexSignExt) {}
bool equalBaseIndex(const BaseIndexOffset &Other) {
return Other.Base == Base && Other.Index == Index &&
Other.IsIndexSignExt == IsIndexSignExt;
SDValue getBase() { return Base; }
SDValue getIndex() { return Index; }
bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) {
int64_t Off;
return equalBaseIndex(Other, DAG, Off);
}
bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG,
int64_t &Off) {
// Obvious equivalent
Off = Other.Offset - Offset;
if (Other.Base == Base && Other.Index == Index &&
Other.IsIndexSignExt == IsIndexSignExt)
return true;
// Match GlobalAddresses
if (Index == Other.Index)
if (GlobalAddressSDNode *A = dyn_cast<GlobalAddressSDNode>(Base))
if (GlobalAddressSDNode *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
if (A->getGlobal() == B->getGlobal()) {
Off += B->getOffset() - A->getOffset();
return true;
}
// TODO: we should be able to add FrameIndex analysis improvements here.
return false;
}
/// Parses tree in Ptr for base, index, offset addresses.
static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) {
static BaseIndexOffset match(SDValue Ptr) {
// (((B + I*M) + c)) + c ...
SDValue Base = Ptr;
SDValue Index = SDValue();
int64_t Offset = 0;
bool IsIndexSignExt = false;
// (((B + I*M) + O)) + O ...
//Consume constant adds
while (Base->getOpcode() == ISD::ADD &&
isa<ConstantSDNode>(Base->getOperand(1))) {
@ -4743,19 +4768,6 @@ struct BaseIndexOffset {
Base = Base->getOperand(0);
}
// Split up a folded GlobalAddress+Offset into its component parts.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Base))
if (GA->getOpcode() == ISD::GlobalAddress && GA->getOffset() != 0) {
Base = DAG.getGlobalAddress(GA->getGlobal(),
SDLoc(GA),
GA->getValueType(0),
/*Offset*/ 0,
/*isTargetGA=*/false,
GA->getTargetFlags());
Offset += GA->getOffset();
return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
}
if (Base->getOpcode() == ISD::ADD) {
// TODO: The following code appears to be needless as it just
// bails on some Ptrs early, reducing the cases where we
@ -5016,14 +5028,15 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
return SDValue();
// Loads must share the same base address
BaseIndexOffset Ptr = BaseIndexOffset::match(L->getBasePtr(), DAG);
BaseIndexOffset Ptr = BaseIndexOffset::match(L->getBasePtr());
int64_t ByteOffsetFromBase = 0;
if (!Base)
Base = Ptr;
else if (!Base->equalBaseIndex(Ptr))
else if (!Base->equalBaseIndex(Ptr, DAG, ByteOffsetFromBase))
return SDValue();
// Calculate the offset of the current byte from the base address
int64_t ByteOffsetFromBase = Ptr.Offset + MemoryByteOffset(*P);
ByteOffsetFromBase += MemoryByteOffset(*P);
ByteOffsets[i] = ByteOffsetFromBase;
// Remember the first byte load
@ -12494,15 +12507,15 @@ void DAGCombiner::getStoreMergeCandidates(
StoreSDNode *St, SmallVectorImpl<MemOpLink> &StoreNodes) {
// This holds the base pointer, index, and the offset in bytes from the base
// pointer.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG);
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr());
EVT MemVT = St->getMemoryVT();
// We must have a base and an offset.
if (!BasePtr.Base.getNode())
if (!BasePtr.getBase().getNode())
return;
// Do not handle stores to undef base pointers.
if (BasePtr.Base.isUndef())
if (BasePtr.getBase().isUndef())
return;
bool IsConstantSrc = isa<ConstantSDNode>(St->getValue()) ||
@ -12514,10 +12527,11 @@ void DAGCombiner::getStoreMergeCandidates(
BaseIndexOffset LBasePtr;
// Match on loadbaseptr if relevant.
if (IsLoadSrc)
LBasePtr = BaseIndexOffset::match(
cast<LoadSDNode>(St->getValue())->getBasePtr(), DAG);
LBasePtr =
BaseIndexOffset::match(cast<LoadSDNode>(St->getValue())->getBasePtr());
auto CandidateMatch = [&](StoreSDNode *Other, BaseIndexOffset &Ptr) -> bool {
auto CandidateMatch = [&](StoreSDNode *Other, BaseIndexOffset &Ptr,
int64_t &Offset) -> bool {
if (Other->isVolatile() || Other->isIndexed())
return false;
// We can merge constant floats to equivalent integers
@ -12528,8 +12542,8 @@ void DAGCombiner::getStoreMergeCandidates(
if (IsLoadSrc) {
// The Load's Base Ptr must also match
if (LoadSDNode *OtherLd = dyn_cast<LoadSDNode>(Other->getValue())) {
auto LPtr = BaseIndexOffset::match(OtherLd->getBasePtr(), DAG);
if (!(LBasePtr.equalBaseIndex(LPtr)))
auto LPtr = BaseIndexOffset::match(OtherLd->getBasePtr());
if (!(LBasePtr.equalBaseIndex(LPtr, DAG)))
return false;
} else
return false;
@ -12542,8 +12556,8 @@ void DAGCombiner::getStoreMergeCandidates(
if (!(Other->getValue().getOpcode() == ISD::EXTRACT_VECTOR_ELT ||
Other->getValue().getOpcode() == ISD::EXTRACT_SUBVECTOR))
return false;
Ptr = BaseIndexOffset::match(Other->getBasePtr(), DAG);
return (Ptr.equalBaseIndex(BasePtr));
Ptr = BaseIndexOffset::match(Other->getBasePtr());
return (BasePtr.equalBaseIndex(Ptr, DAG, Offset));
};
// We looking for a root node which is an ancestor to all mergable
// stores. We search up through a load, to our root and then down
@ -12571,16 +12585,18 @@ void DAGCombiner::getStoreMergeCandidates(
if (I2.getOperandNo() == 0)
if (StoreSDNode *OtherST = dyn_cast<StoreSDNode>(*I2)) {
BaseIndexOffset Ptr;
if (CandidateMatch(OtherST, Ptr))
StoreNodes.push_back(MemOpLink(OtherST, Ptr.Offset));
int64_t PtrDiff;
if (CandidateMatch(OtherST, Ptr, PtrDiff))
StoreNodes.push_back(MemOpLink(OtherST, PtrDiff));
}
} else
for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E; ++I)
if (I.getOperandNo() == 0)
if (StoreSDNode *OtherST = dyn_cast<StoreSDNode>(*I)) {
BaseIndexOffset Ptr;
if (CandidateMatch(OtherST, Ptr))
StoreNodes.push_back(MemOpLink(OtherST, Ptr.Offset));
int64_t PtrDiff;
if (CandidateMatch(OtherST, Ptr, PtrDiff))
StoreNodes.push_back(MemOpLink(OtherST, PtrDiff));
}
}
@ -12883,11 +12899,12 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
if (Ld->getMemoryVT() != MemVT)
break;
BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr(), DAG);
BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr());
// If this is not the first ptr that we check.
if (LdBasePtr.Base.getNode()) {
int64_t LdOffset = 0;
if (LdBasePtr.getBase().getNode()) {
// The base ptr must be the same.
if (!LdPtr.equalBaseIndex(LdBasePtr))
if (!LdBasePtr.equalBaseIndex(LdPtr, DAG, LdOffset))
break;
} else {
// Check that all other base pointers are the same as this one.
@ -12895,7 +12912,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode *St) {
}
// We found a potential memory operand to merge.
LoadNodes.push_back(MemOpLink(Ld, LdPtr.Offset));
LoadNodes.push_back(MemOpLink(Ld, LdOffset));
}
if (LoadNodes.size() < 2) {
@ -16635,11 +16652,11 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const {
unsigned NumBytes1 = Op1->getMemoryVT().getSizeInBits() >> 3;
// Check for BaseIndexOffset matching.
BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0->getBasePtr(), DAG);
BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1->getBasePtr(), DAG);
if (BasePtr0.equalBaseIndex(BasePtr1))
return !((BasePtr0.Offset + NumBytes0 <= BasePtr1.Offset) ||
(BasePtr1.Offset + NumBytes1 <= BasePtr0.Offset));
BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0->getBasePtr());
BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1->getBasePtr());
int64_t PtrDiff;
if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff))
return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0));
// FIXME: findBaseOffset and ConstantValue/GlobalValue/FrameIndex analysis
// modified to use BaseIndexOffset.
@ -16846,14 +16863,14 @@ SDValue DAGCombiner::FindBetterChain(SDNode *N, SDValue OldChain) {
bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) {
// This holds the base pointer, index, and the offset in bytes from the base
// pointer.
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG);
BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr());
// We must have a base and an offset.
if (!BasePtr.Base.getNode())
if (!BasePtr.getBase().getNode())
return false;
// Do not handle stores to undef base pointers.
if (BasePtr.Base.isUndef())
if (BasePtr.getBase().isUndef())
return false;
SmallVector<StoreSDNode *, 8> ChainedStores;
@ -16872,10 +16889,10 @@ bool DAGCombiner::findBetterNeighborChains(StoreSDNode *St) {
break;
// Find the base pointer and offset for this memory node.
BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr(), DAG);
BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr());
// Check that the base pointer is the same as the original one.
if (!Ptr.equalBaseIndex(BasePtr))
if (!BasePtr.equalBaseIndex(Ptr, DAG))
break;
// Walk up the chain to find the next store node, ignoring any