summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp125
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);
OpenPOWER on IntegriCloud