mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-10 06:25:01 +00:00
Re-land r354244 "[DAGCombiner] Eliminate dead stores to stack."
Always check candidates for hasOtherUses(), not only stores. llvm-svn: 356050
This commit is contained in:
parent
f505cb7adc
commit
b854c089a3
@ -384,6 +384,7 @@ 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);
|
||||
@ -1591,6 +1592,7 @@ 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);
|
||||
case ISD::VECREDUCE_FADD:
|
||||
@ -15561,6 +15563,66 @@ 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();
|
||||
if (!Chain.hasOneUse())
|
||||
continue;
|
||||
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 *Lifetime = cast<LifetimeSDNode>(Chain);
|
||||
if (!Lifetime->hasOffset())
|
||||
break; // Be conservative if we don't know the extents of the object.
|
||||
|
||||
const BaseIndexOffset LifetimeBase(Lifetime->getOperand(1), SDValue(),
|
||||
Lifetime->getOffset(), false);
|
||||
bool IsAlias;
|
||||
if (BaseIndexOffset::computeAliasing(LifetimeEndBase,
|
||||
LifetimeEnd->getSize(), LifetimeBase,
|
||||
Lifetime->getSize(), DAG, IsAlias) &&
|
||||
!IsAlias) {
|
||||
Chains.push_back(Chain.getOperand(0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::STORE: {
|
||||
StoreSDNode *ST = dyn_cast<StoreSDNode>(Chain);
|
||||
if (ST->isVolatile() || 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(DAG, LifetimeEnd->getSize() * 8, StoreBase,
|
||||
ST->getMemoryVT().getStoreSizeInBits())) {
|
||||
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,
|
||||
@ -19394,6 +19456,8 @@ 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);
|
||||
@ -19464,6 +19528,31 @@ 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()) {
|
||||
Aliases.push_back(Chain);
|
||||
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;
|
||||
} else {
|
||||
Aliases.push_back(Chain);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// For all other instructions we will just have to take what we can get.
|
||||
Aliases.push_back(Chain);
|
||||
|
@ -22,7 +22,6 @@ define dso_local void @_Z4SwapP1SS0_(%struct.S* nocapture %a, %struct.S* nocaptu
|
||||
; AA-LABEL: _Z4SwapP1SS0_:
|
||||
; AA: # %bb.0: # %entry
|
||||
; AA-NEXT: vmovups (%rdi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovups (%rsi), %xmm1
|
||||
; AA-NEXT: vmovups %xmm1, (%rdi)
|
||||
; AA-NEXT: vmovups %xmm0, (%rsi)
|
||||
@ -43,18 +42,10 @@ entry:
|
||||
define dso_local void @onealloc_noreadback(i8* nocapture %a, i8* nocapture %b) local_unnamed_addr {
|
||||
; NOAA-LABEL: onealloc_noreadback:
|
||||
; NOAA: # %bb.0: # %entry
|
||||
; NOAA-NEXT: vmovups (%rdi), %xmm0
|
||||
; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; NOAA-NEXT: vmovups (%rsi), %xmm0
|
||||
; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; NOAA-NEXT: retq
|
||||
;
|
||||
; AA-LABEL: onealloc_noreadback:
|
||||
; AA: # %bb.0: # %entry
|
||||
; AA-NEXT: vmovups (%rdi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovups (%rsi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: retq
|
||||
entry:
|
||||
%alloc = alloca [16 x i8], i8 2, align 1
|
||||
@ -73,18 +64,10 @@ entry:
|
||||
define dso_local void @twoallocs_trivial(i8* nocapture %a, i8* nocapture %b) local_unnamed_addr {
|
||||
; NOAA-LABEL: twoallocs_trivial:
|
||||
; NOAA: # %bb.0: # %entry
|
||||
; NOAA-NEXT: vmovups (%rdi), %xmm0
|
||||
; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; NOAA-NEXT: vmovups (%rsi), %xmm0
|
||||
; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; NOAA-NEXT: retq
|
||||
;
|
||||
; AA-LABEL: twoallocs_trivial:
|
||||
; AA: # %bb.0: # %entry
|
||||
; AA-NEXT: vmovups (%rdi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovups (%rsi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: retq
|
||||
entry:
|
||||
%alloc1 = alloca [16 x i8], align 1
|
||||
@ -105,7 +88,6 @@ define dso_local void @twoallocs(i8* nocapture %a, i8* nocapture %b) local_unnam
|
||||
; NOAA: # %bb.0: # %entry
|
||||
; NOAA-NEXT: vmovups (%rdi), %xmm0
|
||||
; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; NOAA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
|
||||
; NOAA-NEXT: vmovups %xmm0, (%rsi)
|
||||
; NOAA-NEXT: retq
|
||||
;
|
||||
@ -113,7 +95,6 @@ define dso_local void @twoallocs(i8* nocapture %a, i8* nocapture %b) local_unnam
|
||||
; AA: # %bb.0: # %entry
|
||||
; AA-NEXT: vmovups (%rdi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
|
||||
; AA-NEXT: vmovups %xmm0, (%rsi)
|
||||
; AA-NEXT: retq
|
||||
entry:
|
||||
@ -148,7 +129,6 @@ define dso_local void @onealloc_readback_1(i8* nocapture %a, i8* nocapture %b) l
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovups (%rsi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
|
||||
; AA-NEXT: vmovups %xmm0, (%rdi)
|
||||
; AA-NEXT: retq
|
||||
entry:
|
||||
@ -182,7 +162,6 @@ define dso_local void @onealloc_readback_2(i8* nocapture %a, i8* nocapture %b) l
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovups (%rsi), %xmm0
|
||||
; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp)
|
||||
; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0
|
||||
; AA-NEXT: vmovups %xmm0, (%rdi)
|
||||
; AA-NEXT: retq
|
||||
entry:
|
||||
|
@ -70,8 +70,12 @@
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localC
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
; CHECK: }
|
||||
; CHECK: BlockSym {
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
@ -80,48 +84,12 @@
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localD
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
; CHECK: }
|
||||
; CHECK: BlockSym {
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localE
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: }
|
||||
; CHECK: BlockSym {
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localF
|
||||
; CHECK: }
|
||||
; CHECK: BlockSym {
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localG
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
; CHECK: }
|
||||
; CHECK: BlockSym {
|
||||
; CHECK: Kind: S_BLOCK32 {{.*}}
|
||||
; CHECK: BlockName:
|
||||
; CHECK: }
|
||||
; CHECK: LocalSym {
|
||||
; CHECK: VarName: localH
|
||||
; CHECK: }
|
||||
; CHECK: ScopeEndSym {
|
||||
; CHECK: Kind: S_END {{.*}}
|
||||
; CHECK: }
|
||||
|
Loading…
x
Reference in New Issue
Block a user