@@ -130,7 +130,7 @@ void diagnoseRequiredCopyOfMoveOnly(Operand *use,
130
130
// /
131
131
// / This result remains valid during copy rewriting. The only instructions
132
132
// / referenced it contains are consumes that cannot be deleted.
133
- class CanonicalOSSAConsumeInfo {
133
+ class CanonicalOSSAConsumeInfo final {
134
134
// / Map blocks on the lifetime boundary to the last consuming instruction.
135
135
llvm::SmallDenseMap<SILBasicBlock *, SILInstruction *, 4 > finalBlockConsumes;
136
136
@@ -159,6 +159,10 @@ class CanonicalOSSAConsumeInfo {
159
159
return false ;
160
160
}
161
161
162
+ CanonicalOSSAConsumeInfo () {}
163
+ CanonicalOSSAConsumeInfo (CanonicalOSSAConsumeInfo const &) = delete ;
164
+ CanonicalOSSAConsumeInfo &
165
+ operator =(CanonicalOSSAConsumeInfo const &) = delete ;
162
166
SWIFT_ASSERT_ONLY_DECL (void dump () const LLVM_ATTRIBUTE_USED);
163
167
};
164
168
@@ -169,7 +173,7 @@ class CanonicalOSSAConsumeInfo {
169
173
// /
170
174
// / TODO: Move all the private per-definition members into an implementation
171
175
// / class in the .cpp file.
172
- class CanonicalizeOSSALifetime {
176
+ class CanonicalizeOSSALifetime final {
173
177
public:
174
178
// / Find the original definition of a potentially copied value. \p copiedValue
175
179
// / must be an owned value. It is usually a copy but may also be a destroy.
@@ -205,6 +209,10 @@ class CanonicalizeOSSALifetime {
205
209
// / liveness may be pruned during canonicalization.
206
210
bool pruneDebugMode;
207
211
212
+ // / If true, lifetimes will not be shortened except when necessary to avoid
213
+ // / copies.
214
+ bool maximizeLifetime;
215
+
208
216
// / If true and we are processing a value of move_only type, emit a diagnostic
209
217
// / when-ever we need to insert a copy_value.
210
218
std::function<void (Operand *)> moveOnlyCopyValueNotification;
@@ -240,8 +248,8 @@ class CanonicalizeOSSALifetime {
240
248
// / Visited set for general def-use traversal that prevents revisiting values.
241
249
GraphNodeWorklist<SILValue, 8 > defUseWorklist;
242
250
243
- // / Visited set general CFG traversal that prevents revisiting blocks .
244
- GraphNodeWorklist <SILBasicBlock *, 8 > blockWorklist ;
251
+ // / The blocks that were discovered by PrunedLiveness .
252
+ SmallVector <SILBasicBlock *, 32 > discoveredBlocks ;
245
253
246
254
// / Pruned liveness for the extended live range including copies. For this
247
255
// / purpose, only consuming instructions are considered "lifetime
@@ -251,7 +259,7 @@ class CanonicalizeOSSALifetime {
251
259
// / The destroys of the value. These are not uses, but need to be recorded so
252
260
// / that we know when the last use in a consuming block is (without having to
253
261
// / repeatedly do use-def walks from destroys).
254
- SmallPtrSet <SILInstruction *, 8 > destroys;
262
+ SmallPtrSetVector <SILInstruction *, 8 > destroys;
255
263
256
264
// / Information about consuming instructions discovered in this canonical OSSA
257
265
// / lifetime.
@@ -289,15 +297,17 @@ class CanonicalizeOSSALifetime {
289
297
}
290
298
291
299
CanonicalizeOSSALifetime (
292
- bool pruneDebugMode, NonLocalAccessBlockAnalysis *accessBlockAnalysis,
293
- DominanceInfo *domTree, InstructionDeleter &deleter,
300
+ bool pruneDebugMode, bool maximizeLifetime,
301
+ NonLocalAccessBlockAnalysis *accessBlockAnalysis, DominanceInfo *domTree,
302
+ InstructionDeleter &deleter,
294
303
std::function<void (Operand *)> moveOnlyCopyValueNotification = nullptr ,
295
304
std::function<void (Operand *)> moveOnlyFinalConsumingUse = nullptr )
296
- : pruneDebugMode(pruneDebugMode),
305
+ : pruneDebugMode(pruneDebugMode), maximizeLifetime(maximizeLifetime),
297
306
moveOnlyCopyValueNotification (moveOnlyCopyValueNotification),
298
307
moveOnlyFinalConsumingUse(moveOnlyFinalConsumingUse),
299
308
accessBlockAnalysis(accessBlockAnalysis), domTree(domTree),
300
- deleter(deleter) {}
309
+ deleter(deleter),
310
+ liveness(maximizeLifetime ? &discoveredBlocks : nullptr ) {}
301
311
302
312
SILValue getCurrentDef () const { return liveness.getDef (); }
303
313
@@ -307,6 +317,7 @@ class CanonicalizeOSSALifetime {
307
317
// analysis, freeing its memory.
308
318
accessBlocks = nullptr ;
309
319
consumes.clear ();
320
+ destroys.clear ();
310
321
311
322
liveness.initializeDef (def);
312
323
}
@@ -315,6 +326,7 @@ class CanonicalizeOSSALifetime {
315
326
consumingBlocks.clear ();
316
327
debugValues.clear ();
317
328
liveness.clear ();
329
+ discoveredBlocks.clear ();
318
330
}
319
331
320
332
// / Top-Level API: rewrites copies and destroys within \p def's extended
@@ -333,7 +345,7 @@ class CanonicalizeOSSALifetime {
333
345
334
346
InstModCallbacks &getCallbacks () { return deleter.getCallbacks (); }
335
347
336
- protected :
348
+ private :
337
349
void recordDebugValue (DebugValueInst *dvi) { debugValues.insert (dvi); }
338
350
339
351
void recordConsumingUse (Operand *use) {
@@ -345,9 +357,14 @@ class CanonicalizeOSSALifetime {
345
357
346
358
void extendLivenessThroughOverlappingAccess ();
347
359
348
- void findExtendedBoundary (PrunedLivenessBoundary &boundary);
360
+ void findOriginalBoundary (PrunedLivenessBoundary &boundary);
361
+
362
+ void findExtendedBoundary (PrunedLivenessBoundary const &originalBoundary,
363
+ PrunedLivenessBoundary &boundary);
364
+
365
+ void extendUnconsumedLiveness (PrunedLivenessBoundary const &boundary);
349
366
350
- void insertDestroysOnBoundary (PrunedLivenessBoundary &boundary);
367
+ void insertDestroysOnBoundary (PrunedLivenessBoundary const &boundary);
351
368
352
369
void rewriteCopies ();
353
370
};
0 commit comments