Skip to content

Commit 4bccbfb

Browse files
authored
Merge pull request #19648 from eeckstein/fix-rle
2 parents dca7035 + 643f98f commit 4bccbfb

File tree

5 files changed

+60
-37
lines changed

5 files changed

+60
-37
lines changed

include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ static inline llvm::hash_code hash_value(const LSValue &V) {
289289
//===----------------------------------------------------------------------===//
290290
// Load Store Location
291291
//===----------------------------------------------------------------------===//
292-
using LSLocationSet = llvm::DenseSet<LSLocation>;
293292
using LSLocationList = llvm::SmallVector<LSLocation, 8>;
294293
using LSLocationIndexMap = llvm::SmallDenseMap<LSLocation, unsigned, 32>;
295294
using LSLocationBaseMap = llvm::DenseMap<SILValue, LSLocation>;
@@ -357,7 +356,7 @@ class LSLocation : public LSBase {
357356

358357
/// Given a set of locations derived from the same base, try to merge/reduce
359358
/// them into smallest number of LSLocations possible.
360-
static bool reduce(LSLocation Base, SILModule *Mod, LSLocationSet &Locs);
359+
static void reduce(LSLocation Base, SILModule *Mod, LSLocationList &Locs);
361360

362361
/// Enumerate the given Mem LSLocation.
363362
static void enumerateLSLocation(SILModule *M, SILValue Mem,

lib/SILOptimizer/Transforms/DeadStoreElimination.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class BlockState {
251251
SmallBitVector BBDeallocateLocation;
252252

253253
/// The dead stores in the current basic block.
254-
llvm::DenseSet<SILInstruction *> DeadStores;
254+
llvm::SmallVector<SILInstruction *, 2> DeadStores;
255255

256256
/// Keeps track of what stores to generate after the data flow stabilizes.
257257
/// these stores come from partial dead stores.
@@ -946,22 +946,22 @@ void DSEContext::processWrite(SILInstruction *I, SILValue Val, SILValue Mem,
946946
// instruction is dead.
947947
if (Dead) {
948948
LLVM_DEBUG(llvm::dbgs() << "Instruction Dead: " << *I << "\n");
949-
S->DeadStores.insert(I);
949+
S->DeadStores.push_back(I);
950950
++NumDeadStores;
951951
return;
952952
}
953953

954954
// Partial dead store - stores to some locations are dead, but not all. This
955955
// is a partially dead store. Also at this point we know what locations are
956956
// dead.
957-
llvm::DenseSet<LSLocation> Alives;
957+
LSLocationList Alives;
958958
if (V.any()) {
959959
// Take out locations that are dead.
960960
for (unsigned i = 0; i < V.size(); ++i) {
961961
if (V.test(i))
962962
continue;
963963
// This location is alive.
964-
Alives.insert(Locs[i]);
964+
Alives.push_back(Locs[i]);
965965
}
966966

967967
// Try to create as few aggregated stores as possible out of the locations.
@@ -994,7 +994,7 @@ void DSEContext::processWrite(SILInstruction *I, SILValue Val, SILValue Mem,
994994

995995
// Lastly, mark the old store as dead.
996996
LLVM_DEBUG(llvm::dbgs() << "Instruction Partially Dead: " << *I << "\n");
997-
S->DeadStores.insert(I);
997+
S->DeadStores.push_back(I);
998998
++NumPartialDeadStores;
999999
}
10001000
}

lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,6 @@ class BlockState {
416416

417417
namespace {
418418

419-
using BBValueMap = llvm::DenseMap<SILBasicBlock *, SILValue>;
420-
421419
/// This class stores global state that we use when computing redundant load and
422420
/// their replacement in each basic block.
423421
class RLEContext {
@@ -1248,7 +1246,7 @@ BlockState::ValueState BlockState::getValueStateAtEndOfBlock(RLEContext &Ctx,
12481246

12491247
SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
12501248
LSLocation &L) {
1251-
BBValueMap Values;
1249+
llvm::SmallVector<std::pair<SILBasicBlock *, SILValue>, 8> Values;
12521250
llvm::DenseSet<SILBasicBlock *> HandledBBs;
12531251
llvm::SmallVector<SILBasicBlock *, 8> WorkList;
12541252

@@ -1277,7 +1275,7 @@ SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
12771275
// locations, collect and reduce them into a single value in the current
12781276
// basic block.
12791277
if (Forwarder.isConcreteValues(*this, L)) {
1280-
Values[CurBB] = Forwarder.reduceValuesAtEndOfBlock(*this, L);
1278+
Values.push_back({CurBB, Forwarder.reduceValuesAtEndOfBlock(*this, L)});
12811279
continue;
12821280
}
12831281

@@ -1301,7 +1299,7 @@ SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
13011299

13021300
// Reduce the available values into a single SILValue we can use to forward
13031301
SILInstruction *IPt = CurBB->getTerminator();
1304-
Values[CurBB] = LSValue::reduce(L, &BB->getModule(), LSValues, IPt);
1302+
Values.push_back({CurBB, LSValue::reduce(L, &BB->getModule(), LSValues, IPt)});
13051303
}
13061304

13071305
// Finally, collect all the values for the SILArgument, materialize it using
@@ -1317,7 +1315,7 @@ SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB,
13171315
bool RLEContext::collectLocationValues(SILBasicBlock *BB, LSLocation &L,
13181316
LSLocationValueMap &Values,
13191317
ValueTableMap &VM) {
1320-
LSLocationSet CSLocs;
1318+
LSLocationList CSLocs;
13211319
LSLocationList Locs;
13221320
LSLocation::expand(L, &BB->getModule(), Locs, TE);
13231321

@@ -1328,7 +1326,7 @@ bool RLEContext::collectLocationValues(SILBasicBlock *BB, LSLocation &L,
13281326
Values[X] = getValue(VM[getLocationBit(X)]);
13291327
if (!Values[X].isCoveringValue())
13301328
continue;
1331-
CSLocs.insert(X);
1329+
CSLocs.push_back(X);
13321330
}
13331331

13341332
// For locations which we do not have concrete values for in this basic
@@ -1563,7 +1561,7 @@ bool RLEContext::run() {
15631561
processBasicBlocksForRLE(Optimistic);
15641562

15651563
// Finally, perform the redundant load replacements.
1566-
llvm::DenseSet<SILInstruction *> InstsToDelete;
1564+
llvm::SmallVector<SILInstruction *, 16> InstsToDelete;
15671565
bool SILChanged = false;
15681566
for (auto &B : *Fn) {
15691567
auto &State = BBToLocState[&B];
@@ -1587,7 +1585,7 @@ bool RLEContext::run() {
15871585
<< "With " << Iter->second);
15881586
SILChanged = true;
15891587
Iter->first->replaceAllUsesWith(Iter->second);
1590-
InstsToDelete.insert(Iter->first);
1588+
InstsToDelete.push_back(Iter->first);
15911589
++NumForwardedLoads;
15921590
}
15931591
}

lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class LSLocationPrinter : public SILModuleTransform {
181181
void printMemReduction(SILFunction &Fn) {
182182
LSLocation L;
183183
LSLocationList Locs;
184-
llvm::DenseSet<LSLocation> SLocs;
184+
LSLocationList SLocs;
185185
unsigned Counter = 0;
186186
for (auto &BB : Fn) {
187187
for (auto &II : BB) {
@@ -212,7 +212,7 @@ class LSLocationPrinter : public SILModuleTransform {
212212
// Reduction should not care about the order of the memory locations in
213213
// the set.
214214
for (auto I = Locs.begin(); I != Locs.end(); ++I) {
215-
SLocs.insert(*I);
215+
SLocs.push_back(*I);
216216
}
217217

218218
// This should get the original (unexpanded) location back.

lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -185,36 +185,62 @@ LSLocation::expand(LSLocation Base, SILModule *M, LSLocationList &Locs,
185185
}
186186
}
187187

188-
bool
189-
LSLocation::reduce(LSLocation Base, SILModule *M, LSLocationSet &Locs) {
188+
/// Gets the sub-locations of \p Base in \p SubLocations.
189+
/// Returns false if this is not possible or too complex.
190+
static bool
191+
getSubLocations(LSLocationList &SubLocations, LSLocation Base, SILModule *M,
192+
const LSLocationList &Locs) {
190193
// If this is a class reference type, we have reached end of the type tree.
191194
if (Base.getType(M).getClassOrBoundGenericClass())
192-
return Locs.find(Base) != Locs.end();
195+
return false;
193196

194-
// This a don't expand node.
195-
if (!shouldExpand(*M, Base.getType(M))) {
196-
return Locs.find(Base) != Locs.end();
197+
// Don't expand if it would be too complex. As Locs is a list (and not a set)
198+
// we want to avoid quadratic complexity in replaceInner().
199+
// Usually Locs is small anyway, because we limit expansion to 6 members.
200+
// But with deeply nested types we could run in a corner case where Locs is
201+
// large.
202+
if (!shouldExpand(*M, Base.getType(M)) || Locs.size() >= 8) {
203+
return false;
197204
}
198205

199206
// This is a leaf node.
200-
LSLocationList NextLevel;
201-
Base.getNextLevelLSLocations(NextLevel, M);
202-
if (NextLevel.empty())
203-
return Locs.find(Base) != Locs.end();
207+
Base.getNextLevelLSLocations(SubLocations, M);
208+
return !SubLocations.empty();
209+
}
204210

205-
// This is not a leaf node, try to find whether all its children are alive.
211+
/// Replaces \p SubLocations with \p Base in \p Locs if all sub-locations are
212+
/// alive, i.e. present in \p Locs.
213+
static bool
214+
replaceSubLocations(LSLocation Base, SILModule *M, LSLocationList &Locs,
215+
const LSLocationList &SubLocations) {
216+
// Find whether all its children of Base are alive.
206217
bool Alive = true;
207-
for (auto &X : NextLevel) {
208-
Alive &= LSLocation::reduce(X, M, Locs);
218+
for (auto &X : SubLocations) {
219+
// Recurse into the next level.
220+
LSLocationList NextInnerLevel;
221+
if (getSubLocations(NextInnerLevel, X, M, Locs)) {
222+
Alive &= replaceSubLocations(X, M, Locs, NextInnerLevel);
223+
} else {
224+
Alive &= is_contained(Locs, X);
225+
}
209226
}
210227

211228
// All next level locations are alive, create the new aggregated location.
212-
if (Alive) {
213-
for (auto &X : NextLevel)
214-
Locs.erase(X);
215-
Locs.insert(Base);
216-
}
217-
return Alive;
229+
if (!Alive)
230+
return false;
231+
232+
auto newEnd = std::remove_if(Locs.begin(), Locs.end(), [&](const LSLocation &L) {
233+
return is_contained(SubLocations, L);
234+
});
235+
Locs.erase(newEnd, Locs.end());
236+
Locs.push_back(Base);
237+
return true;
238+
}
239+
240+
void LSLocation::reduce(LSLocation Base, SILModule *M, LSLocationList &Locs) {
241+
LSLocationList SubLocations;
242+
if (getSubLocations(SubLocations, Base, M, Locs))
243+
replaceSubLocations(Base, M, Locs, SubLocations);
218244
}
219245

220246
void

0 commit comments

Comments
 (0)