diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 125 |
1 files changed, 35 insertions, 90 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 78a6ea6d4fd..c2404f963ce 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -385,7 +385,6 @@ namespace { SDValue replaceStoreOfFPConstant(StoreSDNode *ST); SDValue visitSTORE(SDNode *N); - SDValue visitLIFETIME_END(SDNode *N); SDValue visitINSERT_VECTOR_ELT(SDNode *N); SDValue visitEXTRACT_VECTOR_ELT(SDNode *N); SDValue visitBUILD_VECTOR(SDNode *N); @@ -1590,7 +1589,6 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::MLOAD: return visitMLOAD(N); case ISD::MSCATTER: return visitMSCATTER(N); case ISD::MSTORE: return visitMSTORE(N); - case ISD::LIFETIME_END: return visitLIFETIME_END(N); case ISD::FP_TO_FP16: return visitFP_TO_FP16(N); case ISD::FP16_TO_FP: return visitFP16_TO_FP(N); } @@ -15486,66 +15484,6 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return ReduceLoadOpStoreWidth(N); } -SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) { - const auto *LifetimeEnd = cast<LifetimeSDNode>(N); - if (!LifetimeEnd->hasOffset()) - return SDValue(); - - const BaseIndexOffset LifetimeEndBase(N->getOperand(1), SDValue(), - LifetimeEnd->getOffset(), false); - - // We walk up the chains to find stores. - SmallVector<SDValue, 8> Chains = {N->getOperand(0)}; - while (!Chains.empty()) { - SDValue Chain = Chains.back(); - Chains.pop_back(); - switch (Chain.getOpcode()) { - case ISD::TokenFactor: - for (unsigned Nops = Chain.getNumOperands(); Nops;) - Chains.push_back(Chain.getOperand(--Nops)); - break; - case ISD::LIFETIME_START: - case ISD::LIFETIME_END: { - // We can forward past any lifetime start/end that can be proven not to - // alias the node. - const auto *LifetimeStart = cast<LifetimeSDNode>(Chain); - if (!LifetimeStart->hasOffset()) - break; // Be conservative if we don't know the extents of the object. - - const BaseIndexOffset LifetimeStartBase( - LifetimeStart->getOperand(1), SDValue(), LifetimeStart->getOffset(), - false); - bool IsAlias; - if (BaseIndexOffset::computeAliasing( - LifetimeEndBase, LifetimeEnd->getSize(), LifetimeStartBase, - LifetimeStart->getSize(), DAG, IsAlias) && - !IsAlias) { - Chains.push_back(Chain.getOperand(0)); - } - break; - } - - case ISD::STORE: { - StoreSDNode *ST = dyn_cast<StoreSDNode>(Chain); - if (ST->isVolatile() || !ST->hasOneUse() || ST->isIndexed()) - continue; - const BaseIndexOffset StoreBase = BaseIndexOffset::match(ST, DAG); - // If we store purely within object bounds just before its lifetime ends, - // we can remove the store. - if (LifetimeEndBase.contains(LifetimeEnd->getSize(), StoreBase, - ST->getMemoryVT().getStoreSize(), DAG)) { - LLVM_DEBUG(dbgs() << "\nRemoving store:"; StoreBase.dump(); - dbgs() << "\nwithin LIFETIME_END of : "; - LifetimeEndBase.dump(); dbgs() << "\n"); - CombineTo(ST, ST->getChain()); - return SDValue(N, 0); - } - } - } - } - return SDValue(); -} - /// For the instruction sequence of store below, F and I values /// are bundled together as an i64 value before being stored into memory. /// Sometimes it is more efficent to generate separate stores for F and I, @@ -19297,11 +19235,41 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const { unsigned NumBytes1 = Op1->getMemoryVT().getStoreSize(); // Check for BaseIndexOffset matching. - bool IsAlias; - if (BaseIndexOffset::computeAliasing( - BaseIndexOffset::match(Op0, DAG), NumBytes0, - BaseIndexOffset::match(Op1, DAG), NumBytes1, DAG, IsAlias)) - return IsAlias; + BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0, DAG); + BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1, DAG); + int64_t PtrDiff; + if (BasePtr0.getBase().getNode() && BasePtr1.getBase().getNode()) { + if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)) + return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0)); + + // If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be + // able to calculate their relative offset if at least one arises + // from an alloca. However, these allocas cannot overlap and we + // can infer there is no alias. + if (auto *A = dyn_cast<FrameIndexSDNode>(BasePtr0.getBase())) + if (auto *B = dyn_cast<FrameIndexSDNode>(BasePtr1.getBase())) { + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + // If the base are the same frame index but the we couldn't find a + // constant offset, (indices are different) be conservative. + if (A != B && (!MFI.isFixedObjectIndex(A->getIndex()) || + !MFI.isFixedObjectIndex(B->getIndex()))) + return false; + } + + bool IsFI0 = isa<FrameIndexSDNode>(BasePtr0.getBase()); + bool IsFI1 = isa<FrameIndexSDNode>(BasePtr1.getBase()); + bool IsGV0 = isa<GlobalAddressSDNode>(BasePtr0.getBase()); + bool IsGV1 = isa<GlobalAddressSDNode>(BasePtr1.getBase()); + bool IsCV0 = isa<ConstantPoolSDNode>(BasePtr0.getBase()); + bool IsCV1 = isa<ConstantPoolSDNode>(BasePtr1.getBase()); + + // If of mismatched base types or checkable indices we can check + // they do not alias. + if ((BasePtr0.getIndex() == BasePtr1.getIndex() || (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 compared to the size and offset of the access, we may be able @@ -19360,8 +19328,6 @@ void DAGCombiner::GatherAllAliases(LSBaseSDNode *N, SDValue OriginalChain, // Get alias information for node. bool IsLoad = isa<LoadSDNode>(N) && !N->isVolatile(); - const BaseIndexOffset LSBasePtr = BaseIndexOffset::match(N, DAG); - const unsigned LSNumBytes = N->getMemoryVT().getStoreSize(); // Starting off. Chains.push_back(OriginalChain); @@ -19432,27 +19398,6 @@ void DAGCombiner::GatherAllAliases(LSBaseSDNode *N, SDValue OriginalChain, ++Depth; break; - case ISD::LIFETIME_START: - case ISD::LIFETIME_END: { - // We can forward past any lifetime start/end that can be proven not to - // alias the memory access. - const auto *Lifetime = cast<LifetimeSDNode>(Chain); - if (!Lifetime->hasOffset()) - break; // Be conservative if we don't know the extents of the object. - - const BaseIndexOffset LifetimePtr(Lifetime->getOperand(1), SDValue(), - Lifetime->getOffset(), false); - bool IsAlias; - if (BaseIndexOffset::computeAliasing(LifetimePtr, Lifetime->getSize(), - LSBasePtr, LSNumBytes, DAG, - IsAlias) && - !IsAlias) { - Chains.push_back(Chain.getOperand(0)); - ++Depth; - } - break; - } - default: // For all other instructions we will just have to take what we can get. Aliases.push_back(Chain); |