Skip to content

Commit 03d0acc

Browse files
committed
[DSE] Use helper for unwind check (NFCI)
This should be no functional change, as the cases supported by the helper and the cases supported by DSE are currently the same, the code structure is just slightly different.
1 parent e30525b commit 03d0acc

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -756,9 +756,8 @@ struct DSEState {
756756
SmallVector<MemoryDef *, 64> MemDefs;
757757
// Any that should be skipped as they are already deleted
758758
SmallPtrSet<MemoryAccess *, 4> SkipStores;
759-
// Keep track of all of the objects that are invisible to the caller before
760-
// the function returns.
761-
DenseMap<const Value *, bool> InvisibleToCallerBeforeRet;
759+
// Keep track whether a given object is captured before return or not.
760+
DenseMap<const Value *, bool> CapturedBeforeReturn;
762761
// Keep track of all of the objects that are invisible to the caller after
763762
// the function returns.
764763
DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
@@ -801,12 +800,8 @@ struct DSEState {
801800
// Treat byval or inalloca arguments the same as Allocas, stores to them are
802801
// dead at the end of the function.
803802
for (Argument &AI : F.args())
804-
if (AI.hasPassPointeeByValueCopyAttr()) {
805-
// For byval, the caller doesn't know the address of the allocation.
806-
if (AI.hasByValAttr())
807-
InvisibleToCallerBeforeRet.insert({&AI, true});
803+
if (AI.hasPassPointeeByValueCopyAttr())
808804
InvisibleToCallerAfterRet.insert({&AI, true});
809-
}
810805

811806
// Collect whether there is any irreducible control flow in the function.
812807
ContainsIrreducibleLoops = mayContainIrreducibleControl(F, &LI);
@@ -953,7 +948,7 @@ struct DSEState {
953948
return true;
954949
auto I = InvisibleToCallerAfterRet.insert({V, false});
955950
if (I.second) {
956-
if (!isInvisibleToCallerBeforeRet(V)) {
951+
if (!isInvisibleToCallerOnUnwind(V)) {
957952
I.first->second = false;
958953
} else if (isNoAliasCall(V)) {
959954
I.first->second = !PointerMayBeCaptured(V, true, false);
@@ -962,17 +957,21 @@ struct DSEState {
962957
return I.first->second;
963958
}
964959

965-
bool isInvisibleToCallerBeforeRet(const Value *V) {
966-
if (isa<AllocaInst>(V))
960+
bool isInvisibleToCallerOnUnwind(const Value *V) {
961+
bool RequiresNoCaptureBeforeUnwind;
962+
if (!isNotVisibleOnUnwind(V, RequiresNoCaptureBeforeUnwind))
963+
return false;
964+
if (!RequiresNoCaptureBeforeUnwind)
967965
return true;
968-
auto I = InvisibleToCallerBeforeRet.insert({V, false});
969-
if (I.second && isNoAliasCall(V))
966+
967+
auto I = CapturedBeforeReturn.insert({V, true});
968+
if (I.second)
970969
// NOTE: This could be made more precise by PointerMayBeCapturedBefore
971970
// with the killing MemoryDef. But we refrain from doing so for now to
972971
// limit compile-time and this does not cause any changes to the number
973972
// of stores removed on a large test set in practice.
974-
I.first->second = !PointerMayBeCaptured(V, false, true);
975-
return I.first->second;
973+
I.first->second = PointerMayBeCaptured(V, false, true);
974+
return !I.first->second;
976975
}
977976

978977
Optional<MemoryLocation> getLocForWrite(Instruction *I) const {
@@ -1260,8 +1259,7 @@ struct DSEState {
12601259
MemoryDef *CurrentDef = cast<MemoryDef>(Current);
12611260
Instruction *CurrentI = CurrentDef->getMemoryInst();
12621261

1263-
if (canSkipDef(CurrentDef,
1264-
!isInvisibleToCallerBeforeRet(KillingUndObj))) {
1262+
if (canSkipDef(CurrentDef, !isInvisibleToCallerOnUnwind(KillingUndObj))) {
12651263
CanOptimize = false;
12661264
continue;
12671265
}
@@ -1433,7 +1431,7 @@ struct DSEState {
14331431
continue;
14341432
}
14351433

1436-
if (UseInst->mayThrow() && !isInvisibleToCallerBeforeRet(KillingUndObj)) {
1434+
if (UseInst->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj)) {
14371435
LLVM_DEBUG(dbgs() << " ... found throwing instruction\n");
14381436
return None;
14391437
}
@@ -1614,7 +1612,7 @@ struct DSEState {
16141612
// First see if we can ignore it by using the fact that KillingI is an
16151613
// alloca/alloca like object that is not visible to the caller during
16161614
// execution of the function.
1617-
if (KillingUndObj && isInvisibleToCallerBeforeRet(KillingUndObj))
1615+
if (KillingUndObj && isInvisibleToCallerOnUnwind(KillingUndObj))
16181616
return false;
16191617

16201618
if (KillingI->getParent() == DeadI->getParent())
@@ -1630,7 +1628,7 @@ struct DSEState {
16301628
bool isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI) {
16311629
// If DeadI may throw it acts as a barrier, unless we are to an
16321630
// alloca/alloca like object that does not escape.
1633-
if (DeadI->mayThrow() && !isInvisibleToCallerBeforeRet(KillingUndObj))
1631+
if (DeadI->mayThrow() && !isInvisibleToCallerOnUnwind(KillingUndObj))
16341632
return true;
16351633

16361634
// If DeadI is an atomic load/store stronger than monotonic, do not try to

0 commit comments

Comments
 (0)