From 5d9f5f40885da16ed6f4e9ee7c96a3547500d900 Mon Sep 17 00:00:00 2001 From: Nirav Dave Date: Fri, 22 Dec 2017 21:20:55 +0000 Subject: [PATCH] Integrate findBaseOffset address analyses to BaseIndexOffset. NFCI. BaseIndexOffset supercedes findBaseOffset analysis save only Constant Pool addresses. Migrate analysis to BaseIndexOffset. Relanding after correcting base address matching check. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321389 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 80 +++------------------- .../SelectionDAG/SelectionDAGAddressAnalysis.cpp | 17 +++++ 2 files changed, 27 insertions(+), 70 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 58a4ca61e6c..5bab282cb09 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -17405,43 +17405,6 @@ SDValue DAGCombiner::buildSqrtEstimate(SDValue Op, SDNodeFlags Flags) { return buildSqrtEstimateImpl(Op, Flags, false); } -/// Return true if base is a frame index, which is known not to alias with -/// anything but itself. Provides base object and offset as results. -static bool findBaseOffset(SDValue Ptr, SDValue &Base, int64_t &Offset, - const GlobalValue *&GV, const void *&CV) { - // Assume it is a primitive operation. - Base = Ptr; Offset = 0; GV = nullptr; CV = nullptr; - - // If it's an adding a simple constant then integrate the offset. - if (Base.getOpcode() == ISD::ADD) { - if (ConstantSDNode *C = dyn_cast(Base.getOperand(1))) { - Base = Base.getOperand(0); - Offset += C->getSExtValue(); - } - } - - // Return the underlying GlobalValue, and update the Offset. Return false - // for GlobalAddressSDNode since the same GlobalAddress may be represented - // by multiple nodes with different offsets. - if (GlobalAddressSDNode *G = dyn_cast(Base)) { - GV = G->getGlobal(); - Offset += G->getOffset(); - return false; - } - - // Return the underlying Constant value, and update the Offset. Return false - // for ConstantSDNodes since the same constant pool entry may be represented - // by multiple nodes with different offsets. - if (ConstantPoolSDNode *C = dyn_cast(Base)) { - CV = C->isMachineConstantPoolEntry() ? (const void *)C->getMachineCPVal() - : (const void *)C->getConstVal(); - Offset += C->getOffset(); - return false; - } - // If it's any of the following then it can't alias with anything but itself. - return isa(Base); -} - /// Return true if there is any possibility that the two addresses overlap. bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const { // If they are the same then they must be aliases. @@ -17483,39 +17446,16 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const { return false; } - // FIXME: findBaseOffset and ConstantValue/GlobalValue/FrameIndex analysis - // modified to use BaseIndexOffset. - - // Gather base node and offset information. - SDValue Base0, Base1; - int64_t Offset0, Offset1; - const GlobalValue *GV0, *GV1; - const void *CV0, *CV1; - bool IsFrameIndex0 = findBaseOffset(Op0->getBasePtr(), - Base0, Offset0, GV0, CV0); - bool IsFrameIndex1 = findBaseOffset(Op1->getBasePtr(), - Base1, Offset1, GV1, CV1); - - // If they have the same base address, then check to see if they overlap. - if (Base0 == Base1 || (GV0 && (GV0 == GV1)) || (CV0 && (CV0 == CV1))) - return !((Offset0 + NumBytes0) <= Offset1 || - (Offset1 + NumBytes1) <= Offset0); - - // It is possible for different frame indices to alias each other, mostly - // when tail call optimization reuses return address slots for arguments. - // To catch this case, look up the actual index of frame indices to compute - // the real alias relationship. - if (IsFrameIndex0 && IsFrameIndex1) { - MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); - Offset0 += MFI.getObjectOffset(cast(Base0)->getIndex()); - Offset1 += MFI.getObjectOffset(cast(Base1)->getIndex()); - return !((Offset0 + NumBytes0) <= Offset1 || - (Offset1 + NumBytes1) <= Offset0); - } - - // Otherwise, if we know what the bases are, and they aren't identical, then - // we know they cannot alias. - if ((IsFrameIndex0 || CV0 || GV0) && (IsFrameIndex1 || CV1 || GV1)) + bool IsFI0 = isa(BasePtr0.getBase()); + bool IsFI1 = isa(BasePtr1.getBase()); + bool IsGV0 = isa(BasePtr0.getBase()); + bool IsGV1 = isa(BasePtr1.getBase()); + bool IsCV0 = isa(BasePtr0.getBase()); + bool IsCV1 = isa(BasePtr1.getBase()); + + // If of mismatched base types they do not alias. + if (((IsFI0 != IsFI1) || (IsGV0 != IsGV1) || (IsCV0 != IsCV1)) && + (IsFI0 || IsGV0 || IsCV0) && (IsFI1 || IsGV1 || IsCV1)) return false; // If we know required SrcValue1 and SrcValue2 have relatively large alignment diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp index 544da362be6..d5980919d03 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp @@ -37,6 +37,23 @@ bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other, return true; } + // Match Constants + if (auto *A = dyn_cast(Base)) + if (auto *B = dyn_cast(Other.Base)) { + bool IsMatch = + A->isMachineConstantPoolEntry() == B->isMachineConstantPoolEntry(); + if (IsMatch) { + if (A->isMachineConstantPoolEntry()) + IsMatch = A->getMachineCPVal() == B->getMachineCPVal(); + else + IsMatch = A->getConstVal() == B->getConstVal(); + } + if (IsMatch) { + Off += B->getOffset() - A->getOffset(); + return true; + } + } + const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); // Match non-equal FrameIndexes - If both frame indices are fixed -- 2.11.0