@@ -100,13 +100,21 @@ static bool isDeadStoreInertInstruction(SILInstruction *Inst) {
100
100
101
101
namespace {
102
102
103
+ // / Forward declaration of classes.
104
+ class Location ;
105
+
103
106
using ProjectionTreeNodeList = llvm::ArrayRef<ProjectionTreeNode *>;
104
107
using ProjectionPathList = llvm::SmallVector<ProjectionPath, 8 >;
108
+ using LocationList = llvm::SmallVector<Location, 8 >;
105
109
using hash_code = llvm::hash_code;
106
110
107
111
// / A Location is an abstraction of an object field in program. It consists of a
108
112
// / base that is the tracked SILValue. In a subsequent commit this will be
109
113
// / 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
+ // /
110
118
class Location {
111
119
public:
112
120
enum KeyKind : uint8_t { EmptyKey = 0 , TombstoneKey, NormalKey };
@@ -166,6 +174,13 @@ class Location {
166
174
return HC;
167
175
}
168
176
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
+
169
184
// / Return false if one projection path is a prefix of another. false
170
185
// / otherwise.
171
186
bool hasNonEmptySymmetricPathDifference (const Location &RHS) const {
@@ -215,24 +230,12 @@ class Location {
215
230
// / construct the projection path to the field accessed.
216
231
void initialize (SILValue val);
217
232
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.
220
234
// /
221
235
// / In SIL, we can have a store to an aggregate and loads from its individual
222
236
// / fields. Therefore, we expand all the operations on aggregates onto
223
237
// / 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);
236
239
};
237
240
238
241
} // end anonymous namespace
@@ -242,50 +245,37 @@ void Location::initialize(SILValue Dest) {
242
245
Path = ProjectionPath::getAddrProjectionPath (Base, Dest);
243
246
}
244
247
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) {
247
249
// Expands the given type into locations each of which contains 1 field from
248
250
// 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
+ }
269
267
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
+ }
274
276
}
275
277
}
276
278
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
-
289
279
// ===----------------------------------------------------------------------===//
290
280
// Basic Block Location State
291
281
// ===----------------------------------------------------------------------===//
@@ -705,8 +695,8 @@ void GlobalDeadStoreEliminationImpl::processRead(SILInstruction *I, BBState *S,
705
695
706
696
// Expand the given Mem into individual fields and process them as
707
697
// 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);
710
700
for (auto &E : Locs) {
711
701
updateWriteSetForRead (I, S, getLocationBit (E));
712
702
}
@@ -724,8 +714,8 @@ void GlobalDeadStoreEliminationImpl::processWrite(SILInstruction *I, BBState *S,
724
714
725
715
// Expand the given Mem into individual fields and process them as separate writes.
726
716
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);
729
719
for (auto &E : Locs) {
730
720
Dead &= updateWriteSetForWrite (I, S, getLocationBit (E));
731
721
}
@@ -752,8 +742,8 @@ void GlobalDeadStoreEliminationImpl::enumerateLocation(SILModule *M,
752
742
753
743
// Expand the given Mem into individual fields and add them to the
754
744
// locationvault.
755
- llvm::SmallVector<Location, 8 > Locs;
756
- L.expand (M, Locs, BPA, Mem. getType (). getObjectType () );
745
+ LocationList Locs;
746
+ L.expand (M, Locs);
757
747
for (auto &E : Locs) {
758
748
addLocation (E);
759
749
}
0 commit comments