Skip to content

Commit 8aea34d

Browse files
committed
[RLE-DSE] Refactor and add some comments regarding why ProjectionPath is used in DSE
1 parent 3b9945c commit 8aea34d

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

lib/SILPasses/Scalar/DeadStoreElimination.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@
4747
/// minimum number of stores possible using the reduce function. This is done
4848
/// so that we do not bloat SIL IR.
4949
///
50+
/// Another way to implement the DSE optimization is to keep the instructions
51+
/// that read and/or write memory without breaking the memory read/written
52+
/// using the ProjectionPath. However, this can easily lead to loss of
53+
/// opportunities, e.g. a read that only kills part of a store may need to be
54+
/// treated as killing the entire store. However, using ProjectionPath does
55+
/// lead to more memory uses.
56+
///
5057
/// TODO: Handle same value store in DSE, currently handled in RLE.
5158
///
5259
/// e.g.
@@ -144,7 +151,7 @@ class BBState {
144151
SILBasicBlock *BB;
145152

146153
/// Keep the number of MemLocations in the LocationVault.
147-
unsigned MemLocationCount;
154+
unsigned MemLocationNum;
148155

149156
/// A bit vector for which the ith bit represents the ith MemLocation in
150157
/// MemLocationVault. If the bit is set, then the location currently has an
@@ -180,7 +187,7 @@ class BBState {
180187
SILBasicBlock *getBB() const { return BB; }
181188

182189
void init(unsigned lcnt) {
183-
MemLocationCount = lcnt;
190+
MemLocationNum = lcnt;
184191
// The initial state of WriteSetIn should be all 1's. Otherwise the
185192
// dataflow solution could be too conservative.
186193
//
@@ -194,12 +201,12 @@ class BBState {
194201
// However, by doing so, we can only eliminate the dead stores after the
195202
// data flow stablizes.
196203
//
197-
WriteSetIn.resize(MemLocationCount, true);
198-
WriteSetOut.resize(MemLocationCount, false);
204+
WriteSetIn.resize(MemLocationNum, true);
205+
WriteSetOut.resize(MemLocationNum, false);
199206

200207
// GenSet and KillSet initially empty.
201-
BBGenSet.resize(MemLocationCount, false);
202-
BBKillSet.resize(MemLocationCount, false);
208+
BBGenSet.resize(MemLocationNum, false);
209+
BBKillSet.resize(MemLocationNum, false);
203210
}
204211

205212
/// Check whether the WriteSetIn has changed. If it does, we need to rerun
@@ -474,7 +481,7 @@ void DSEContext::invalidateMemLocationBase(SILInstruction *I,
474481
// invalidate any locations with the same base.
475482
BBState *S = getBBLocState(I);
476483
if (BuildGenKillSet) {
477-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
484+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
478485
if (MemLocationVault[i].getBase().getDef() != I)
479486
continue;
480487
S->BBGenSet.reset(i);
@@ -483,7 +490,7 @@ void DSEContext::invalidateMemLocationBase(SILInstruction *I,
483490
return;
484491
}
485492

486-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
493+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
487494
if (!S->WriteSetOut.test(i))
488495
continue;
489496
if (MemLocationVault[i].getBase().getDef() != I)
@@ -496,7 +503,7 @@ void DSEContext::updateWriteSetForRead(BBState *S, unsigned bit) {
496503
// Remove any may/must-aliasing stores to the MemLocation, as they cant be
497504
// used to kill any upward visible stores due to the intefering load.
498505
MemLocation &R = MemLocationVault[bit];
499-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
506+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
500507
if (!S->isTrackingMemLocation(i))
501508
continue;
502509
MemLocation &L = MemLocationVault[i];
@@ -512,7 +519,7 @@ void DSEContext::updateGenKillSetForRead(BBState *S, unsigned bit) {
512519
// Start tracking the read to this MemLocation in the killset and update
513520
// the genset accordingly.
514521
MemLocation &R = MemLocationVault[bit];
515-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
522+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
516523
MemLocation &L = MemLocationVault[i];
517524
if (!L.isMayAliasMemLocation(R, AA))
518525
continue;
@@ -527,7 +534,7 @@ bool DSEContext::updateWriteSetForWrite(BBState *S, unsigned bit) {
527534
// If a tracked store must aliases with this store, then this store is dead.
528535
bool IsDead = false;
529536
MemLocation &R = MemLocationVault[bit];
530-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
537+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
531538
if (!S->isTrackingMemLocation(i))
532539
continue;
533540
// If 2 locations may alias, we can still keep both stores.
@@ -744,7 +751,7 @@ void DSEContext::processUnknownReadMemInst(SILInstruction *I,
744751
BBState *S = getBBLocState(I);
745752
// Update the gen kill set.
746753
if (BuildGenKillSet) {
747-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
754+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
748755
if (!AA->mayReadFromMemory(I, MemLocationVault[i].getBase()))
749756
continue;
750757
S->BBKillSet.set(i);
@@ -756,7 +763,7 @@ void DSEContext::processUnknownReadMemInst(SILInstruction *I,
756763
// We do not know what this instruction does or the memory that it *may*
757764
// touch. Hand it to alias analysis to see whether we need to invalidate
758765
// any MemLocation.
759-
for (unsigned i = 0; i < S->MemLocationCount; ++i) {
766+
for (unsigned i = 0; i < S->MemLocationNum; ++i) {
760767
if (!S->isTrackingMemLocation(i))
761768
continue;
762769
if (!AA->mayReadFromMemory(I, MemLocationVault[i].getBase()))
@@ -827,10 +834,9 @@ void DSEContext::run() {
827834
// know all the locations accessed in this function, we can resize the bit
828835
// vector to the approproate size.
829836
//
830-
// DenseMap has a minimum size of 64, while many functions do not have over
831-
// 64 basic blocks. Therefore, allocate the BBState in a vector and use
832-
// pointer
833-
// in BBToLocState to access them.
837+
// DenseMap has a minimum size of 64, while many functions do not have more
838+
// than 64 basic blocks. Therefore, allocate the BBState in a vector and use
839+
// pointer in BBToLocState to access them.
834840
for (auto &B : *F) {
835841
BBStates.push_back(BBState(&B));
836842
BBStates.back().init(MemLocationVault.size());
@@ -871,7 +877,7 @@ void DSEContext::run() {
871877

872878
// Finally, delete the dead stores and create the live stores.
873879
for (SILBasicBlock &BB : *F) {
874-
// Create the stores that are alive.
880+
// Create the stores that are alive due to partial dead stores.
875881
for (auto &I : getBBLocState(&BB)->LiveStores) {
876882
SILInstruction *IT = cast<SILInstruction>(I.first)->getNextNode();
877883
SILBuilderWithScope Builder(IT);

0 commit comments

Comments
 (0)