[llvm] r305917 - [DAG] Remove Node csonstruction from BaseIndexOffset match. NFCI.
Nirav Dave via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 21 08:07:30 PDT 2017
Author: niravd
Date: Wed Jun 21 10:07:30 2017
New Revision: 305917
URL: http://llvm.org/viewvc/llvm-project?rev=305917&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=305917&r1=305916&r2=305917&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Jun 21 10:07:30 2017
@@ -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(SD
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::getStoreMergeCandidate
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::getStoreMergeCandidate
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::getStoreMergeCandidate
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::getStoreMergeCandidate
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::getStoreMergeCandidate
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
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
}
// 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 *
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(SDN
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::findBetterNeighborChai
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
More information about the llvm-commits
mailing list