Skip to content

Commit be4bf81

Browse files
committed
Update some comments and rename runIterativeDF -> runIterativeDSE,
mergeSuccessorStates -> mergeSuccessorLiveIns in DSE. Also fix some includes.
1 parent 1515567 commit be4bf81

File tree

1 file changed

+64
-60
lines changed

1 file changed

+64
-60
lines changed

lib/SILOptimizer/Transforms/DeadStoreElimination.cpp

Lines changed: 64 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
///
2828
/// 2. Performing a post-order walk over the control flow graph, tracking any
2929
/// LSLocations that are read from or stored into in each basic block. After
30-
/// eliminating any dead stores in single blocks, it computes a kill set for
31-
/// each block. The kill set tracks what LSLocations are stored into by this
32-
/// basic block and its successors.
30+
/// eliminating any dead stores in single blocks, it computes a genset and
31+
/// killset for each block. The genset keeps a list of upward visible stores
32+
/// and the killset keeps a list of LSLocation this basic block reads (kills).
3333
///
34-
/// 3. An optimistic iterative dataflow is performed on the gen sets and kill
35-
/// sets until convergence.
34+
/// 3. An optimistic iterative dataflow is performed on the genset and killset
35+
/// until convergence.
3636
///
3737
/// At the core of DSE, there is the LSLocation class. a LSLocation is an
3838
/// abstraction of an object field in program. It consists of a base and a
@@ -67,27 +67,25 @@
6767
#include "swift/SILOptimizer/Analysis/ValueTracking.h"
6868
#include "swift/SILOptimizer/PassManager/Passes.h"
6969
#include "swift/SILOptimizer/PassManager/Transforms.h"
70-
#include "swift/SILOptimizer/Utils/Local.h"
7170
#include "swift/SILOptimizer/Utils/CFG.h"
71+
#include "swift/SILOptimizer/Utils/Local.h"
7272
#include "llvm/ADT/Statistic.h"
7373
#include "llvm/ADT/DenseSet.h"
7474
#include "llvm/ADT/BitVector.h"
7575
#include "llvm/Support/Allocator.h"
7676
#include "llvm/Support/CommandLine.h"
7777
#include "llvm/Support/Debug.h"
78-
#include <algorithm>
7978

8079
using namespace swift;
81-
using swift::LSLocation;
8280

8381
STATISTIC(NumDeadStores, "Number of dead stores removed");
8482
STATISTIC(NumPartialDeadStores, "Number of partial dead stores removed");
8583

8684
/// ComputeMaxStoreSet - If we ignore all reads, what is the max store set that
87-
/// can reach the beginning of a basic block. This helps generating the genset
88-
/// and killset. i.e. if there is no upward visible store that can reach the
89-
/// beginning of a basic block, then we know that the genset and killset for
90-
/// the stored location need not be set.
85+
/// can reach a particular point in a basic block. This helps in generating
86+
/// the genset and killset. i.e. if there is no upward visible store that can
87+
/// reach the beginning of a basic block, then we know that the genset and
88+
/// killset for the stored location need not be set for the basic block.
9189
///
9290
/// BuildGenKillSet - Build the genset and killset of the basic block.
9391
///
@@ -114,8 +112,8 @@ static inline bool isPerformingDSE(DSEKind Kind) {
114112
return Kind == DSEKind::PerformDSE;
115113
}
116114

117-
/// Return true if all basic blocks have their successors processed if
118-
/// they are iterated in post order.
115+
/// Return true if all basic blocks will have their successors processed if
116+
/// the basic blocks in the functions are iterated in post order.
119117
static bool isOneIterationFunction(PostOrderFunctionInfo *PO) {
120118
llvm::DenseSet<SILBasicBlock *> HandledBBs;
121119
for (SILBasicBlock *B : PO->getPostOrder()) {
@@ -165,9 +163,12 @@ class DSEContext;
165163
/// is initialized to the intersection of BBWriteSetIns of all successors of the
166164
/// basic block.
167165
///
166+
/// BBWriteSetMid is initialized to BBWriteSetOut of the current basic block
167+
/// before instructions in the basic block is processed.
168+
///
168169
/// Initially BBWriteSetIn is set to true. After the basic block is processed,
169170
/// if its BBWriteSetMid is different from BBWriteSetIn, BBWriteSetIn is
170-
/// initialized to the value of BBWriteSetMid and the data flow is rerun on the
171+
/// assigned the value of BBWriteSetMid and the data flow is rerun on the
171172
/// current basic block's predecessors.
172173
///
173174
/// Instructions in each basic block are processed in post-order as follows:
@@ -214,10 +215,10 @@ class BlockState {
214215
/// kills an upward visible store.
215216
llvm::SmallBitVector BBKillSet;
216217

217-
/// A bit vector to keep the maximum number of stores that can reach the
218-
/// beginning of the basic block. If a bit is set, that means there is
219-
/// potentially an upward visible store to the location at the beginning
220-
/// of the basic block.
218+
/// A bit vector to keep the maximum number of stores that can reach a
219+
/// certain point of the basic block. If a bit is set, that means there is
220+
/// potentially an upward visible store to the location at the particular
221+
/// point of the basic block.
221222
llvm::SmallBitVector BBMaxStoreSet;
222223

223224
/// The dead stores in the current basic block.
@@ -231,7 +232,6 @@ class BlockState {
231232
llvm::DenseMap<SILValue, SILValue> LiveStores;
232233

233234
/// Constructors.
234-
BlockState() : BB(nullptr) {}
235235
BlockState(SILBasicBlock *B) : BB(B) {}
236236

237237
/// Return the current basic block.
@@ -240,7 +240,7 @@ class BlockState {
240240
/// Initialize the bitvectors for the return basic block.
241241
void initReturnBlock(DSEContext &Ctx);
242242

243-
/// Initialize the bitvectors for the basic block.
243+
/// Initialize the bitvectors for the current basic block.
244244
void init(DSEContext &Ctx, bool OneIterationFunction);
245245

246246
/// Check whether the BBWriteSetIn has changed. If it does, we need to rerun
@@ -256,11 +256,10 @@ class BlockState {
256256
} // end anonymous namespace
257257

258258
bool BlockState::updateBBWriteSetIn(llvm::SmallBitVector &X) {
259-
bool Changed = (BBWriteSetIn != X);
260-
if (!Changed)
261-
return Changed;
259+
if (BBWriteSetIn == X)
260+
return false;
262261
BBWriteSetIn = X;
263-
return Changed;
262+
return true;
264263
}
265264

266265
void BlockState::startTrackingLocation(llvm::SmallBitVector &BV, unsigned i) {
@@ -294,7 +293,7 @@ class DSEContext {
294293
/// Alias Analysis.
295294
AliasAnalysis *AA;
296295

297-
/// Escape analysis.
296+
/// Escape Analysis.
298297
EscapeAnalysis *EA;
299298

300299
/// Type Expansion Analysis.
@@ -344,20 +343,20 @@ class DSEContext {
344343
void processWriteForGenKillSet(BlockState *S, unsigned bit);
345344
bool processWriteForDSE(BlockState *S, unsigned bit);
346345

347-
/// Process Instructions. Extract locations from SIL LoadInst.
346+
/// Process instructions. Extract locations from SIL LoadInst.
348347
void processLoadInst(SILInstruction *Inst, DSEKind Kind);
349348

350-
/// Process Instructions. Extract locations from SIL StoreInst.
349+
/// Process instructions. Extract locations from SIL StoreInst.
351350
void processStoreInst(SILInstruction *Inst, DSEKind Kind);
352351

353-
/// Process Instructions. Extract locations from SIL DebugValueAddrInst.
352+
/// Process instructions. Extract locations from SIL DebugValueAddrInst.
354353
/// DebugValueAddrInst maybe promoted to DebugValue, when this is done,
355354
/// DebugValueAddrInst is effectively a read on the location.
356355
void processDebugValueAddrInst(SILInstruction *I, DSEKind Kind);
357356
void processDebugValueAddrInstForGenKillSet(SILInstruction *I);
358357
void processDebugValueAddrInstForDSE(SILInstruction *I);
359358

360-
/// Process Instructions. Extract locations from unknown memory inst.
359+
/// Process instructions. Extract locations from unknown memory inst.
361360
void processUnknownReadInst(SILInstruction *Inst, DSEKind Kind);
362361
void processUnknownReadInstForGenKillSet(SILInstruction *Inst);
363362
void processUnknownReadInstForDSE(SILInstruction *Inst);
@@ -388,8 +387,6 @@ class DSEContext {
388387
void invalidateLSLocationBaseForDSE(SILInstruction *Inst);
389388

390389
/// Get the bit representing the location in the LocationVault.
391-
///
392-
/// NOTE: Adds the location to the location vault if necessary.
393390
unsigned getLocationBit(const LSLocation &L);
394391

395392
public:
@@ -402,7 +399,7 @@ class DSEContext {
402399
bool run();
403400

404401
/// Run the iterative DF to converge the BBWriteSetIn.
405-
void runIterativeDF();
402+
void runIterativeDSE();
406403

407404
/// Returns the escape analysis we use.
408405
EscapeAnalysis *getEA() { return EA; }
@@ -424,8 +421,8 @@ class DSEContext {
424421
/// block with the generated gen and kill set.
425422
bool processBasicBlockWithGenKillSet(SILBasicBlock *BB);
426423

427-
/// Intersect the successor live-ins.
428-
void mergeSuccessorStates(SILBasicBlock *BB);
424+
/// Intersect the successors' BBWriteSetIns.
425+
void mergeSuccessorLiveIns(SILBasicBlock *BB);
429426

430427
/// Update the BlockState based on the given instruction.
431428
void processInstruction(SILInstruction *I, DSEKind Kind);
@@ -450,10 +447,13 @@ void BlockState::initReturnBlock(DSEContext &Ctx) {
450447
void BlockState::init(DSEContext &Ctx, bool OneIterationFunction) {
451448
std::vector<LSLocation> &LV = Ctx.getLocationVault();
452449
LocationNum = LV.size();
453-
// The initial state of BBWriteSetIn should be all 1's. Otherwise the
454-
// dataflow solution could be too conservative.
450+
// For function that requires just 1 iteration of the data flow to converge
451+
// we set the initiali state of BBWriteSetIn to 0.
452+
//
453+
// For other functions, the initial state of BBWriteSetIn should be all 1's.
454+
// Otherwise the dataflow solution could be too conservative.
455455
//
456-
// consider this case, the dead store by var a = 10 before the loop will not
456+
// Consider this case, the dead store by var a = 10 before the loop will not
457457
// be eliminated if the BBWriteSetIn is set to 0 initially.
458458
//
459459
// var a = 10
@@ -528,7 +528,7 @@ void DSEContext::processBasicBlockForGenKillSet(SILBasicBlock *BB) {
528528

529529
bool DSEContext::processBasicBlockWithGenKillSet(SILBasicBlock *BB) {
530530
// Compute the BBWriteSetOut at the end of the basic block.
531-
mergeSuccessorStates(BB);
531+
mergeSuccessorLiveIns(BB);
532532

533533
// Compute the BBWriteSet at the beginning of the basic block.
534534
BlockState *S = getBlockState(BB);
@@ -543,7 +543,7 @@ bool DSEContext::processBasicBlockWithGenKillSet(SILBasicBlock *BB) {
543543
void DSEContext::processBasicBlockForDSE(SILBasicBlock *BB) {
544544
// Intersect in the successor WriteSetIns. A store is dead if it is not read
545545
// from any path to the end of the program. Thus an intersection.
546-
mergeSuccessorStates(BB);
546+
mergeSuccessorLiveIns(BB);
547547

548548
// Initialize the BBWriteSetMid to BBWriteSetOut to get started.
549549
BlockState *S = getBlockState(BB);
@@ -557,7 +557,7 @@ void DSEContext::processBasicBlockForDSE(SILBasicBlock *BB) {
557557
S->BBWriteSetIn = S->BBWriteSetMid;
558558
}
559559

560-
void DSEContext::mergeSuccessorStates(SILBasicBlock *BB) {
560+
void DSEContext::mergeSuccessorLiveIns(SILBasicBlock *BB) {
561561
// If basic block has no successor, then all local writes can be considered
562562
// dead for block with no successor.
563563
if (BB->succ_empty())
@@ -609,7 +609,7 @@ void DSEContext::invalidateLSLocationBaseForDSE(SILInstruction *I) {
609609
void DSEContext::invalidateLSLocationBase(SILInstruction *I, DSEKind Kind) {
610610
// If this instruction defines the base of a location, then we need to
611611
// invalidate any locations with the same base.
612-
612+
//
613613
// Are we building genset and killset.
614614
if (isBuildingGenKillSet(Kind)) {
615615
invalidateLSLocationBaseForGenKillSet(I);
@@ -711,7 +711,7 @@ void DSEContext::processRead(SILInstruction *I, BlockState *S, SILValue Mem,
711711

712712
bool DSEContext::processWriteForDSE(BlockState *S, unsigned bit) {
713713
// If a tracked store must aliases with this store, then this store is dead.
714-
bool IsDead = false;
714+
bool StoreDead = false;
715715
LSLocation &R = LocationVault[bit];
716716
for (unsigned i = 0; i < S->LocationNum; ++i) {
717717
if (!S->isTrackingLocation(S->BBWriteSetMid, i))
@@ -721,13 +721,13 @@ bool DSEContext::processWriteForDSE(BlockState *S, unsigned bit) {
721721
if (!L.isMustAliasLSLocation(R, AA))
722722
continue;
723723
// There is a must alias store. No need to check further.
724-
IsDead = true;
724+
StoreDead = true;
725725
break;
726726
}
727727

728728
// Track this new store.
729729
S->startTrackingLocation(S->BBWriteSetMid, bit);
730-
return IsDead;
730+
return StoreDead;
731731
}
732732

733733
void DSEContext::processWriteForGenKillSet(BlockState *S, unsigned bit) {
@@ -967,20 +967,7 @@ void DSEContext::processInstruction(SILInstruction *I, DSEKind Kind) {
967967
invalidateLSLocationBase(I, Kind);
968968
}
969969

970-
void DSEContext::runIterativeDF() {
971-
// We perform dead store elimination in the following phases.
972-
//
973-
// Phase 1. we compute the max store set at the beginning of the basic block.
974-
//
975-
// Phase 2. we compute the genset and killset for every basic block.
976-
//
977-
// Phase 3. we run the data flow with the genset and killset until
978-
// BBWriteSetIns stop changing.
979-
//
980-
// Phase 4. we run the data flow for the last iteration and perform the DSE.
981-
//
982-
// Phase 5. we remove the dead stores.
983-
970+
void DSEContext::runIterativeDSE() {
984971
// Generate the genset and killset for each basic block. We can process the
985972
// basic blocks in any order.
986973
//
@@ -1045,9 +1032,26 @@ bool DSEContext::run() {
10451032
BBToLocState[S.getBB()] = &S;
10461033
}
10471034

1035+
// We perform dead store elimination in the following phases.
1036+
//
1037+
// Phase 1. we compute the max store set at the beginning of the basic block.
1038+
//
1039+
// Phase 2. we compute the genset and killset for every basic block.
1040+
//
1041+
// Phase 3. we run the data flow with the genset and killset until
1042+
// BBWriteSetIns stop changing.
1043+
//
1044+
// Phase 4. we run the data flow for the last iteration and perform the DSE.
1045+
//
1046+
// Phase 5. we remove the dead stores.
1047+
//
1048+
// Phase 1 - 3 are only performed when we know the data flow will not
1049+
// converge in a single iteration. Otherwise, we only run phase 4 and 5
1050+
// on the function.
1051+
10481052
// We need to run the iterative data flow on the function.
10491053
if (!OneIterationFunction) {
1050-
runIterativeDF();
1054+
runIterativeDSE();
10511055
}
10521056

10531057
// The data flow has stabilized, run one last iteration over all the basic

0 commit comments

Comments
 (0)