68
68
#include " swift/SILOptimizer/Utils/CFGOptUtils.h"
69
69
#include " swift/SILOptimizer/Utils/InstOptUtils.h"
70
70
#include " swift/SILOptimizer/Utils/LoadStoreOptUtils.h"
71
+ #include " swift/SIL/BasicBlockData.h"
71
72
#include " llvm/ADT/BitVector.h"
72
73
#include " llvm/ADT/DenseSet.h"
73
74
#include " llvm/ADT/Statistic.h"
@@ -215,10 +216,10 @@ class DSEContext;
215
216
class BlockState {
216
217
public:
217
218
// / The basic block this BlockState represents.
218
- SILBasicBlock *BB;
219
+ SILBasicBlock *BB = nullptr ;
219
220
220
221
// / Keep the number of LSLocations in the LocationVault.
221
- unsigned LocationNum;
222
+ unsigned LocationNum = 0 ;
222
223
223
224
// / A bit vector for which the ith bit represents the ith LSLocation in
224
225
// / LocationVault. If the bit is set, then the location currently has an
@@ -267,15 +268,12 @@ class BlockState {
267
268
llvm::DenseMap<SILValue, SILValue> LiveStores;
268
269
269
270
// / Constructors.
270
- BlockState (SILBasicBlock *B, unsigned LocationNum, bool Optimistic)
271
- : BB(B), LocationNum(LocationNum) {
272
- init (LocationNum, Optimistic);
273
- }
271
+ BlockState () = default ;
274
272
275
273
void dump ();
276
274
277
275
// / Initialize the bitvectors for the current basic block.
278
- void init (unsigned LocationNum, bool Optimistic);
276
+ void init (SILBasicBlock *BB, unsigned LocationNum, bool Optimistic);
279
277
280
278
// / Check whether the BBWriteSetIn has changed. If it does, we need to rerun
281
279
// / the data flow on this block's predecessors to reach fixed point.
@@ -345,11 +343,8 @@ enum class ProcessKind {
345
343
// / Epilogue release analysis.
346
344
EpilogueARCFunctionInfo *EAFI;
347
345
348
- // / The allocator we are using.
349
- llvm::SpecificBumpPtrAllocator<BlockState> &BPA;
350
-
351
346
// / Map every basic block to its location state.
352
- llvm::SmallDenseMap<SILBasicBlock *, BlockState * > BBToLocState;
347
+ BasicBlockData< BlockState> BBToLocState;
353
348
354
349
// / Keeps all the locations for the current function. The BitVector in each
355
350
// / BlockState is then laid on top of it to keep track of which LSLocation
@@ -374,7 +369,7 @@ enum class ProcessKind {
374
369
LSLocationBaseMap BaseToLocIndex;
375
370
376
371
// / Return the BlockState for the basic block this basic block belongs to.
377
- BlockState *getBlockState (SILBasicBlock *B) { return BBToLocState[B]; }
372
+ BlockState *getBlockState (SILBasicBlock *B) { return & BBToLocState[B]; }
378
373
379
374
// / Return the BlockState for the basic block this instruction belongs to.
380
375
BlockState *getBlockState (SILInstruction *I) {
@@ -451,7 +446,7 @@ enum class ProcessKind {
451
446
AliasAnalysis *AA, TypeExpansionAnalysis *TE,
452
447
EpilogueARCFunctionInfo *EAFI,
453
448
llvm::SpecificBumpPtrAllocator<BlockState> &BPA)
454
- : Mod(M), F(F), PM(PM), AA(AA), TE(TE), EAFI(EAFI), BPA(BPA ) {}
449
+ : Mod(M), F(F), PM(PM), AA(AA), TE(TE), EAFI(EAFI), BBToLocState(F ) {}
455
450
456
451
void dump ();
457
452
@@ -494,7 +489,10 @@ void BlockState::dump() {
494
489
<< " , gen=" << BBGenSet << " , kill=" << BBKillSet << ' \n ' ;
495
490
}
496
491
497
- void BlockState::init (unsigned LocationNum, bool Optimistic) {
492
+ void BlockState::init (SILBasicBlock *BB, unsigned LocationNum, bool Optimistic) {
493
+ this ->BB = BB;
494
+ this ->LocationNum = LocationNum;
495
+
498
496
// For function that requires just 1 iteration of the data flow to converge
499
497
// we set the initial state of BBWriteSetIn to 0.
500
498
//
@@ -1209,10 +1207,9 @@ bool DSEContext::run() {
1209
1207
//
1210
1208
// Initialize the BBToLocState mapping.
1211
1209
unsigned LocationNum = this ->getLocationVault ().size ();
1212
- for (auto &B : *F) {
1213
- auto *State = new (BPA.Allocate ()) BlockState (&B, LocationNum, Optimistic);
1214
- BBToLocState[&B] = State;
1215
- State->initStoreSetAtEndOfBlock (*this );
1210
+ for (auto bs : BBToLocState) {
1211
+ bs.data .init (&bs.block , LocationNum, Optimistic);
1212
+ bs.data .initStoreSetAtEndOfBlock (*this );
1216
1213
}
1217
1214
1218
1215
// We perform dead store elimination in the following phases.
@@ -1247,20 +1244,19 @@ bool DSEContext::run() {
1247
1244
1248
1245
// Finally, delete the dead stores and create the live stores.
1249
1246
bool Changed = false ;
1250
- for (SILBasicBlock &BB : *F ) {
1247
+ for (auto bs : BBToLocState ) {
1251
1248
// Create the stores that are alive due to partial dead stores.
1252
- auto *S = getBlockState (&BB);
1253
- for (auto &X : S->LiveAddr ) {
1249
+ for (auto &X : bs.data .LiveAddr ) {
1254
1250
Changed = true ;
1255
- auto I = S-> LiveStores .find (X);
1251
+ auto I = bs. data . LiveStores .find (X);
1256
1252
SILInstruction *Inst = I->first ->getDefiningInstruction ();
1257
1253
auto *IT = &*std::next (Inst->getIterator ());
1258
1254
SILBuilderWithScope Builder (IT);
1259
1255
Builder.createStore (Inst->getLoc (), I->second , I->first ,
1260
1256
StoreOwnershipQualifier::Unqualified);
1261
1257
}
1262
1258
// Delete the dead stores.
1263
- for (auto &I : getBlockState (&BB )->DeadStores ) {
1259
+ for (auto &I : getBlockState (&bs. block )->DeadStores ) {
1264
1260
Changed = true ;
1265
1261
LLVM_DEBUG (llvm::dbgs () << " *** Removing: " << *I << " ***\n " );
1266
1262
// This way, we get rid of pass dependence on DCE.
0 commit comments