Skip to content

Commit aba0903

Browse files
committed
Use new API in Projection.cpp(getFirstLevelProjection) to enumerate individual
fields in SILType in dead store elimination. Swift SVN r32423
1 parent d78c964 commit aba0903

File tree

3 files changed

+68
-60
lines changed

3 files changed

+68
-60
lines changed

include/swift/SIL/Projection.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,11 @@ class Projection {
304304
static void getFirstLevelProjections(SILValue V, SILModule &Mod,
305305
llvm::SmallVectorImpl<Projection> &Out);
306306

307+
/// Given a specific SILType, return all first level projections if it is an
308+
/// aggregate.
309+
static void getFirstLevelProjections(SILType V, SILModule &Mod,
310+
llvm::SmallVectorImpl<Projection> &Out);
311+
307312
/// Form an aggregate of type BaseType using the SILValue Values. Returns the
308313
/// aggregate on success if this is a case we handle or an empty SILValue
309314
/// otherwise.
@@ -383,6 +388,12 @@ class ProjectionPath {
383388
/// the append function.
384389
ProjectionPath(ProjectionPath &&Other) : Path(Other.Path) {}
385390

391+
/// Append the projection P onto this.
392+
ProjectionPath &append(const Projection &P) {
393+
push_back(P);
394+
return *this;
395+
}
396+
386397
/// Append the projections in Other onto this.
387398
ProjectionPath &append(const ProjectionPath &Other) {
388399
for (auto &X : Other.Path) {
@@ -431,6 +442,9 @@ class ProjectionPath {
431442

432443
/// Returns the last element of the path.
433444
const Projection &back() const { return Path.back(); }
445+
446+
/// Returns the first element of the path.
447+
const Projection &front() const { return Path.front(); }
434448

435449
/// Returns true if LHS and RHS have all the same projections in the same
436450
/// order.

lib/SIL/Projection.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ SILValue Projection::getOperandForAggregate(SILInstruction *I) const {
316316
}
317317

318318
void Projection::getFirstLevelProjections(
319-
SILValue V, SILModule &Mod, llvm::SmallVectorImpl<Projection> &Out) {
320-
SILType Ty = V.getType();
319+
SILType Ty, SILModule &Mod, llvm::SmallVectorImpl<Projection> &Out) {
321320
if (auto *S = Ty.getStructOrBoundGenericStruct()) {
322321
for (auto *V : S->getStoredProperties()) {
323322
Out.push_back(Projection(ProjectionKind::Struct, Ty.getFieldType(V, Mod),
@@ -342,6 +341,11 @@ void Projection::getFirstLevelProjections(
342341
return;
343342
}
344343
}
344+
345+
void Projection::getFirstLevelProjections(
346+
SILValue V, SILModule &Mod, llvm::SmallVectorImpl<Projection> &Out) {
347+
getFirstLevelProjections(V.getType(), Mod, Out);
348+
}
345349

346350
NullablePtr<SILInstruction>
347351
Projection::

lib/SILPasses/GlobalDeadStoreElimination.cpp

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,21 @@ static bool isDeadStoreInertInstruction(SILInstruction *Inst) {
100100

101101
namespace {
102102

103+
/// Forward declaration of classes.
104+
class Location;
105+
103106
using ProjectionTreeNodeList = llvm::ArrayRef<ProjectionTreeNode *>;
104107
using ProjectionPathList = llvm::SmallVector<ProjectionPath, 8>;
108+
using LocationList = llvm::SmallVector<Location, 8>;
105109
using hash_code = llvm::hash_code;
106110

107111
/// A Location is an abstraction of an object field in program. It consists of a
108112
/// base that is the tracked SILValue. In a subsequent commit this will be
109113
/// expanded to include a path.
114+
///
115+
/// TODO: move Location class into separate file so that LoadForwarding pass can
116+
/// use it as well.
117+
///
110118
class Location {
111119
public:
112120
enum KeyKind : uint8_t { EmptyKey = 0, TombstoneKey, NormalKey };
@@ -166,6 +174,13 @@ class Location {
166174
return HC;
167175
}
168176

177+
/// Returns the type of the Location.
178+
SILType getType() const {
179+
if (Path.getValue().empty())
180+
return Base.getType();
181+
return Path.getValue().front().getType();
182+
}
183+
169184
/// Return false if one projection path is a prefix of another. false
170185
/// otherwise.
171186
bool hasNonEmptySymmetricPathDifference(const Location &RHS) const {
@@ -215,24 +230,12 @@ class Location {
215230
/// construct the projection path to the field accessed.
216231
void initialize(SILValue val);
217232

218-
/// Expand this location to its individual fields by performing a DFS on the
219-
/// Projection Tree to find all the fields.
233+
/// Expand this location to all individual fields it contains.
220234
///
221235
/// In SIL, we can have a store to an aggregate and loads from its individual
222236
/// fields. Therefore, we expand all the operations on aggregates onto
223237
/// individual fields.
224-
void enumerateAggProjection(ProjectionPathList &Paths, ProjectionPath &Path,
225-
ProjectionTreeNode *Root,
226-
ProjectionTreeNodeList Nodes);
227-
228-
/// Given a type, return a list of ProjectionPaths to its individual
229-
/// fields.
230-
void enumerateAgg(SILModule *M, SILType Ty, ProjectionPathList &P,
231-
llvm::BumpPtrAllocator &BPA);
232-
233-
/// Expand this location to all individual fields it contains.
234-
void expand(SILModule *Mod, llvm::SmallVector<Location, 8> &F,
235-
llvm::BumpPtrAllocator &BPA, SILType Ty);
238+
void expand(SILModule *Mod, LocationList &F);
236239
};
237240

238241
} // end anonymous namespace
@@ -242,50 +245,37 @@ void Location::initialize(SILValue Dest) {
242245
Path = ProjectionPath::getAddrProjectionPath(Base, Dest);
243246
}
244247

245-
void Location::expand(SILModule *Mod, llvm::SmallVector<Location, 8> &Locs,
246-
llvm::BumpPtrAllocator &BPA, SILType Ty) {
248+
void Location::expand(SILModule *Mod, LocationList &Locs) {
247249
// Expands the given type into locations each of which contains 1 field from
248250
// the type.
249-
ProjectionPathList Paths;
250-
enumerateAgg(Mod, Ty, Paths, BPA);
251-
for (auto &P : Paths) {
252-
ProjectionPath X;
253-
X.append(Path.getValue());
254-
Locs.push_back(Location(Base, X.append(P)));
255-
}
256-
}
257-
258-
void Location::enumerateAggProjection(ProjectionPathList &Paths,
259-
ProjectionPath &Path,
260-
ProjectionTreeNode *Root,
261-
ProjectionTreeNodeList Nodes) {
262-
// If this is the field. keep its projection tree.
263-
if (Root->getChildProjections().empty()) {
264-
ProjectionPath X;
265-
X.append(Path);
266-
Paths.push_back(std::move(X));
267-
return;
268-
}
251+
LocationList Worklist;
252+
llvm::SmallVector<Projection, 8> Projections;
253+
254+
Worklist.push_back(*this);
255+
while (!Worklist.empty()) {
256+
// Get the next level projections based on current location's type.
257+
Location L = Worklist.pop_back_val();
258+
Projections.clear();
259+
Projection::getFirstLevelProjections(L.getType(), *Mod, Projections);
260+
261+
// Reached the end of the projection tree, this field can not be expanded
262+
// anymore.
263+
if (Projections.empty()) {
264+
Locs.push_back(L);
265+
continue;
266+
}
269267

270-
for (auto &I : Root->getChildProjections()) {
271-
Path.push_back(*Nodes[I]->getProjection().getPointer());
272-
enumerateAggProjection(Paths, Path, Nodes[I], Nodes);
273-
Path.pop_back(); // Backtrack.
268+
// Keep expanding the location.
269+
for (auto &P : Projections) {
270+
ProjectionPath X;
271+
X.append(P);
272+
X.append(L.Path.getValue());
273+
Location LL(Base, X);
274+
Worklist.push_back(LL);
275+
}
274276
}
275277
}
276278

277-
void Location::enumerateAgg(SILModule *M, SILType Ty, ProjectionPathList &Paths,
278-
llvm::BumpPtrAllocator &Allocator) {
279-
// Get the projection tree.
280-
ProjectionTree PT(*M, Allocator, Ty);
281-
282-
// Start a depth first search on the projection tree to enumerate
283-
// each field of the type.
284-
ProjectionPath Path;
285-
ProjectionTreeNode *Root = PT.getRoot();
286-
enumerateAggProjection(Paths, Path, Root, PT.getProjectionTreeNodes());
287-
}
288-
289279
//===----------------------------------------------------------------------===//
290280
// Basic Block Location State
291281
//===----------------------------------------------------------------------===//
@@ -705,8 +695,8 @@ void GlobalDeadStoreEliminationImpl::processRead(SILInstruction *I, BBState *S,
705695

706696
// Expand the given Mem into individual fields and process them as
707697
// separate reads.
708-
llvm::SmallVector<Location, 8> Locs;
709-
L.expand(&I->getModule(), Locs, BPA, Mem.getType().getObjectType());
698+
LocationList Locs;
699+
L.expand(&I->getModule(), Locs);
710700
for (auto &E : Locs) {
711701
updateWriteSetForRead(I, S, getLocationBit(E));
712702
}
@@ -724,8 +714,8 @@ void GlobalDeadStoreEliminationImpl::processWrite(SILInstruction *I, BBState *S,
724714

725715
// Expand the given Mem into individual fields and process them as separate writes.
726716
bool Dead = true;
727-
llvm::SmallVector<Location, 8> Locs;
728-
L.expand(&I->getModule(), Locs, BPA, Mem.getType().getObjectType());
717+
LocationList Locs;
718+
L.expand(&I->getModule(), Locs);
729719
for (auto &E : Locs) {
730720
Dead &= updateWriteSetForWrite(I, S, getLocationBit(E));
731721
}
@@ -752,8 +742,8 @@ void GlobalDeadStoreEliminationImpl::enumerateLocation(SILModule *M,
752742

753743
// Expand the given Mem into individual fields and add them to the
754744
// locationvault.
755-
llvm::SmallVector<Location, 8> Locs;
756-
L.expand(M, Locs, BPA, Mem.getType().getObjectType());
745+
LocationList Locs;
746+
L.expand(M, Locs);
757747
for (auto &E : Locs) {
758748
addLocation(E);
759749
}

0 commit comments

Comments
 (0)